diff options
-rw-r--r-- | README | 20 | ||||
-rw-r--r-- | misc/sdl-win32-mouse-fixes.diff | 271 |
2 files changed, 291 insertions, 0 deletions
@@ -393,6 +393,26 @@ SDL Keyboard Differences annoying to use on many non-US keyboards. In response, an additional toggleConsole bind has been added on the key combination Shift-Esc. +Mouse Input On Windows + ioq3 uses SDL to abstract away as much as possible from platform specific + implementation details. Unfortunately, SDL 1.2 suffers from a number of bugs + and limitations with respect to mouse input on the Windows platform. We + provide a patch against the SDL subversion 1.2 branch which fixes the + following problems: + + * DirectX (and thus DirectInput) driver not functional when using an + OpenGL SDL_Surface. + + * DirectX (and thus DirectInput) driver not functional in windowed mode. + + * Mouse buttons 4-7 unusable with the DirectX driver due to DirectInput 5 + not exposing the required functionality. Use DirectInput 7 instead. + + * Low quality mouse input data when using the windib driver due to use of + WM_MOUSEMOVE events. Use GetCursorPos API call instead. + + The patch can be found in misc/sdl-win32-mouse-fixes.diff. + PNG support ioquake3 supports the use of PNG (Portable Network Graphic) images as textures. It should be noted that the use of such images in a map will diff --git a/misc/sdl-win32-mouse-fixes.diff b/misc/sdl-win32-mouse-fixes.diff new file mode 100644 index 0000000..225e030 --- /dev/null +++ b/misc/sdl-win32-mouse-fixes.diff @@ -0,0 +1,271 @@ +Index: src/video/wincommon/SDL_lowvideo.h +=================================================================== +--- src/video/wincommon/SDL_lowvideo.h (revision 3927) ++++ src/video/wincommon/SDL_lowvideo.h (working copy) +@@ -67,8 +67,14 @@ + (SDL_strcmp(this->name, "directx") == 0) \ + ) + +-#define DINPUT_FULLSCREEN() DDRAW_FULLSCREEN() ++#define DINPUT_FULLSCREEN() \ ++( \ ++ ((SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN) && \ ++ (strcmp(this->name, "directx") == 0) \ ++) + ++#define DINPUT() (strcmp(this->name, "directx") == 0) ++ + /* The main window -- and a function to set it for the audio */ + #ifdef _WIN32_WCE + extern LPWSTR SDL_Appname; +Index: src/video/wincommon/SDL_sysevents.c +=================================================================== +--- src/video/wincommon/SDL_sysevents.c (revision 3927) ++++ src/video/wincommon/SDL_sysevents.c (working copy) +@@ -431,27 +431,9 @@ + posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); + } + +- /* mouse has moved within the window */ +- x = LOWORD(lParam); +- y = HIWORD(lParam); +- if ( mouse_relative ) { +- POINT center; +- center.x = (SDL_VideoSurface->w/2); +- center.y = (SDL_VideoSurface->h/2); +- x -= (Sint16)center.x; +- y -= (Sint16)center.y; +- if ( x || y ) { +- ClientToScreen(SDL_Window, ¢er); +- SetCursorPos(center.x, center.y); +- posted = SDL_PrivateMouseMotion(0, 1, x, y); +- } +- } else { +-#ifdef _WIN32_WCE +- if (SDL_VideoSurface) +- GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y); +-#endif +- posted = SDL_PrivateMouseMotion(0, 0, x, y); +- } ++ /* Mouse motion is handled in DIB_PumpEvents or ++ * DX5_PumpEvents, depending on the video driver ++ * in use */ + } + } + return(0); +@@ -480,7 +462,7 @@ + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: { + /* Mouse is handled by DirectInput when fullscreen */ +- if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) { ++ if ( SDL_VideoSurface && ! DINPUT() ) { + WORD xbuttonval = 0; + Sint16 x, y; + Uint8 button, state; +@@ -544,20 +526,8 @@ + mouse_pressed = 0; + } + } +- if ( mouse_relative ) { +- /* RJR: March 28, 2000 +- report internal mouse position if in relative mode */ +- x = 0; y = 0; +- } else { +- x = (Sint16)LOWORD(lParam); +- y = (Sint16)HIWORD(lParam); +-#ifdef _WIN32_WCE +- if (SDL_VideoSurface) +- GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y); +-#endif +- } + posted = SDL_PrivateMouseButton( +- state, button, x, y); ++ state, button, 0, 0); + + /* + * MSDN says: +@@ -578,7 +548,7 @@ + + #if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400) + case WM_MOUSEWHEEL: +- if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) { ++ if ( SDL_VideoSurface && ! DINPUT() ) { + int move = (short)HIWORD(wParam); + if ( move ) { + Uint8 button; +Index: src/video/windib/SDL_dibevents.c +=================================================================== +--- src/video/windib/SDL_dibevents.c (revision 3927) ++++ src/video/windib/SDL_dibevents.c (working copy) +@@ -262,6 +262,35 @@ + return(DefWindowProc(hwnd, msg, wParam, lParam)); + } + ++static void DIB_GenerateMouseMotionEvent(void) ++{ ++ extern int mouse_relative; ++ extern int posted; ++ ++ POINT mouse; ++ GetCursorPos( &mouse ); ++ ++ if ( mouse_relative ) { ++ POINT center; ++ center.x = (SDL_VideoSurface->w/2); ++ center.y = (SDL_VideoSurface->h/2); ++ ClientToScreen(SDL_Window, ¢er); ++ ++ mouse.x -= (Sint16)center.x; ++ mouse.y -= (Sint16)center.y; ++ if ( mouse.x || mouse.y ) { ++ SetCursorPos(center.x, center.y); ++ posted = SDL_PrivateMouseMotion(0, 1, mouse.x, mouse.y); ++ } ++ } else { ++#ifdef _WIN32_WCE ++ if (SDL_VideoSurface) ++ GapiTransform(this->hidden->userOrientation, this->hidden->hiresFix, &x, &y); ++#endif ++ posted = SDL_PrivateMouseMotion(0, 0, mouse.x, mouse.y); ++ } ++} ++ + void DIB_PumpEvents(_THIS) + { + MSG msg; +@@ -271,6 +300,10 @@ + DispatchMessage(&msg); + } + } ++ ++ if ( SDL_GetAppState() & SDL_APPINPUTFOCUS ) { ++ DIB_GenerateMouseMotionEvent( ); ++ } + } + + static HKL hLayoutUS = NULL; +Index: src/video/windx5/SDL_dx5events.c +=================================================================== +--- src/video/windx5/SDL_dx5events.c (revision 3927) ++++ src/video/windx5/SDL_dx5events.c (working copy) +@@ -143,7 +143,12 @@ + (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), + (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard }, + { "mouse", +- &GUID_SysMouse, &c_dfDIMouse, ++ &GUID_SysMouse, ++#if DIRECTINPUT_VERSION >= 0x700 ++ &c_dfDIMouse2, ++#else ++ &c_dfDIMouse, ++#endif + (DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), + (DISCL_FOREGROUND|DISCL_EXCLUSIVE), handle_mouse }, + { NULL, NULL, NULL, 0, 0, NULL } +@@ -298,12 +303,6 @@ + return; + } + +- /* If we are in windowed mode, Windows is taking care of the mouse */ +- if ( (SDL_PublicSurface->flags & SDL_OPENGL) || +- !(SDL_PublicSurface->flags & SDL_FULLSCREEN) ) { +- return; +- } +- + /* If the mouse was lost, regain some sense of mouse state */ + if ( mouse_lost ) { + POINT mouse_pos; +@@ -320,7 +319,11 @@ + old_state = SDL_GetMouseState(NULL, NULL); + new_state = 0; + { /* Get the new DirectInput button state for the mouse */ ++#if DIRECTINPUT_VERSION >= 0x700 ++ DIMOUSESTATE2 distate; ++#else + DIMOUSESTATE distate; ++#endif + HRESULT result; + + result=IDirectInputDevice2_GetDeviceState(SDL_DIdev[1], +@@ -429,6 +432,12 @@ + case DIMOFS_BUTTON1: + case DIMOFS_BUTTON2: + case DIMOFS_BUTTON3: ++#if DIRECTINPUT_VERSION >= 0x700 ++ case DIMOFS_BUTTON4: ++ case DIMOFS_BUTTON5: ++ case DIMOFS_BUTTON6: ++ case DIMOFS_BUTTON7: ++#endif + if ( xrel || yrel ) { + posted = SDL_PrivateMouseMotion( + 0, 1, xrel, yrel); +@@ -437,14 +446,13 @@ + } + timestamp = 0; + button = (Uint8)(ptrbuf[i].dwOfs-DIMOFS_BUTTON0)+1; +- /* Button #2 on two button mice is button 3 +- (the middle button is button 2) +- */ +- if ( button == 2 ) { +- button = 3; +- } else +- if ( button == 3 ) { +- button = 2; ++ /* Map DI button numbers to SDL */ ++ switch ( button ) { ++ case 2: button = SDL_BUTTON_RIGHT; break; ++ case 3: button = SDL_BUTTON_MIDDLE; break; ++ case 4: button = SDL_BUTTON_X1; break; ++ case 5: button = SDL_BUTTON_X2; break; ++ default: break; + } + if ( ptrbuf[i].dwData & 0x80 ) { + /* Grab mouse so we get mouse-up */ +Index: src/video/windx5/directx.h +=================================================================== +--- src/video/windx5/directx.h (revision 3927) ++++ src/video/windx5/directx.h (working copy) +@@ -72,7 +72,7 @@ + /* We need these defines to mark what version of DirectX API we use */ + #define DIRECTDRAW_VERSION 0x0700 + #define DIRECTSOUND_VERSION 0x0500 +-#define DIRECTINPUT_VERSION 0x0500 ++#define DIRECTINPUT_VERSION 0x0700 + + #ifdef __GNUC__ + #define NONAMELESSUNION +@@ -81,4 +81,20 @@ + #include <dsound.h> + #include <dinput.h> + ++#if DIRECTINPUT_VERSION >= 0x0700 && !defined(DIMOFS_BUTTON4) ++typedef struct _DIMOUSESTATE2 { ++ LONG lX; ++ LONG lY; ++ LONG lZ; ++ BYTE rgbButtons[8]; ++} DIMOUSESTATE2, *LPDIMOUSESTATE2; ++ ++#define DIMOFS_BUTTON4 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 4) ++#define DIMOFS_BUTTON5 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 5) ++#define DIMOFS_BUTTON6 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 6) ++#define DIMOFS_BUTTON7 (FIELD_OFFSET(DIMOUSESTATE2, rgbButtons) + 7) ++ ++extern const DIDATAFORMAT c_dfDIMouse2; ++#endif ++ + #endif /* _directx_h */ +Index: configure.in +=================================================================== +--- configure.in (revision 3927) ++++ configure.in (working copy) +@@ -2442,7 +2442,7 @@ + # Set up the system libraries we need + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -luser32 -lgdi32 -lwinmm" + if test x$have_directx = xyes; then +- EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldxguid" ++ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -ldxguid -ldinput8" + fi + # The Win32 platform requires special setup + SOURCES="$SOURCES $srcdir/src/main/win32/*.rc" |