r1443 - in trunk: . misc
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Sat Aug 9 11:19:59 EDT 2008
Author: tma
Date: 2008-08-09 11:19:59 -0400 (Sat, 09 Aug 2008)
New Revision: 1443
Added:
trunk/misc/sdl-win32-mouse-fixes.diff
Modified:
trunk/README
Log:
* Add SDL bug fix patch to misc/ directory
* Add commentary of said patch to README
Modified: trunk/README
===================================================================
--- trunk/README 2008-08-09 13:25:41 UTC (rev 1442)
+++ trunk/README 2008-08-09 15:19:59 UTC (rev 1443)
@@ -393,6 +393,26 @@
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
Added: trunk/misc/sdl-win32-mouse-fixes.diff
===================================================================
--- trunk/misc/sdl-win32-mouse-fixes.diff (rev 0)
+++ trunk/misc/sdl-win32-mouse-fixes.diff 2008-08-09 15:19:59 UTC (rev 1443)
@@ -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"
More information about the quake3-commits
mailing list