* Add SDL bug fix patch to misc/ directory

* Add commentary of said patch to README
This commit is contained in:
Tim Angus 2008-08-09 15:19:59 +00:00
parent 317b953421
commit 60eb261185
2 changed files with 291 additions and 0 deletions

20
README
View File

@ -393,6 +393,26 @@ SDL Keyboard Differences
annoying to use on many non-US keyboards. In response, an additional annoying to use on many non-US keyboards. In response, an additional
toggleConsole bind has been added on the key combination Shift-Esc. 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 PNG support
ioquake3 supports the use of PNG (Portable Network Graphic) images as 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 textures. It should be noted that the use of such images in a map will

View File

@ -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"