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, &center);
+-						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, &center);
++
++		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