mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-05-09 03:41:10 +08:00

After the release of SDL 1.2.13, a commit for their bug# 611 was applied to enhance ioquake3 mouse input in Windows, particularly to enable dinput in an opengl application and for reliability of mouse input under the windib driver. For example (from their commit): "Googling for this indicates that often this is known to result in "spurious" and/or "missing" mouse movement events...". It also added a dependency on dinput7. The attached patch reverts the above commit and it applies to a recent version of SDL 1.2hg (tested in mingw32 and Vista). This restores the mouse input latency to that of SDL 1.2.13 and fixes specific mouse cursor stuttering issues (limited testing of windib and directx under output=surface and =opengl in games such as SC2000, FS 5.1, and UT99/3dfx). It also fixes other minor mouse issues, such as the major loss of mouse movement events while the 3dfx emulation is active in the opengl or software rasterizer path. The previous workarounds
298 lines
9.5 KiB
Diff
298 lines
9.5 KiB
Diff
diff -rupN SDL-1.2-orig//src/video/wincommon/SDL_lowvideo.h SDL-1.2-mouse//src/video/wincommon/SDL_lowvideo.h
|
|
--- SDL-1.2-orig//src/video/wincommon/SDL_lowvideo.h 2012-01-19 01:30:06 -0500
|
|
+++ SDL-1.2-mouse//src/video/wincommon/SDL_lowvideo.h 2016-10-24 19:53:20 -0400
|
|
@@ -70,13 +70,7 @@
|
|
(SDL_strcmp(this->name, "directx") == 0) \
|
|
)
|
|
|
|
-#define DINPUT_FULLSCREEN() \
|
|
-( \
|
|
- FULLSCREEN() && \
|
|
- (strcmp(this->name, "directx") == 0) \
|
|
-)
|
|
-
|
|
-#define DINPUT() (strcmp(this->name, "directx") == 0)
|
|
+#define DINPUT_FULLSCREEN() DDRAW_FULLSCREEN()
|
|
|
|
/* The main window -- and a function to set it for the audio */
|
|
#ifdef _WIN32_WCE
|
|
diff -rupN SDL-1.2-orig//src/video/wincommon/SDL_sysevents.c SDL-1.2-mouse//src/video/wincommon/SDL_sysevents.c
|
|
--- SDL-1.2-orig//src/video/wincommon/SDL_sysevents.c 2012-01-19 01:30:06 -0500
|
|
+++ SDL-1.2-mouse//src/video/wincommon/SDL_sysevents.c 2016-10-24 20:40:16 -0400
|
|
@@ -251,6 +251,7 @@ DJM: This is no longer static as (DX5/DI
|
|
LRESULT CALLBACK WinMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
SDL_VideoDevice *this = current_video;
|
|
+ static int in_window = 0;
|
|
#ifdef WMMSG_DEBUG
|
|
fprintf(stderr, "Received windows message: ");
|
|
if ( msg > MAX_WMMSG ) {
|
|
@@ -330,36 +331,59 @@ LRESULT CALLBACK WinMessage(HWND hwnd, U
|
|
|
|
case WM_MOUSEMOVE: {
|
|
|
|
-#ifdef WM_MOUSELEAVE
|
|
- if ( SDL_VideoSurface ) {
|
|
- /* mouse has entered the window */
|
|
+ /* Mouse is handled by DirectInput when fullscreen */
|
|
+ if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
|
|
+ Sint16 x, y;
|
|
|
|
- if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
|
|
+ /* mouse has entered the window */
|
|
+ if ( ! in_window ) {
|
|
+#ifdef WM_MOUSELEAVE
|
|
TRACKMOUSEEVENT tme;
|
|
|
|
tme.cbSize = sizeof(tme);
|
|
tme.dwFlags = TME_LEAVE;
|
|
tme.hwndTrack = SDL_Window;
|
|
_TrackMouseEvent(&tme);
|
|
- }
|
|
- }
|
|
#endif /* WM_MOUSELEAVE */
|
|
+ in_window = TRUE;
|
|
|
|
- /* Mouse motion is handled in DIB_PumpEvents or
|
|
- * DX5_PumpEvents, depending on the video driver
|
|
- * in use */
|
|
+ posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
|
|
+ }
|
|
|
|
- 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);
|
|
+ }
|
|
+ }
|
|
}
|
|
return(0);
|
|
|
|
#ifdef WM_MOUSELEAVE
|
|
case WM_MOUSELEAVE: {
|
|
|
|
- if ( SDL_VideoSurface ) {
|
|
+ /* Mouse is handled by DirectInput when fullscreen */
|
|
+ if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
|
|
/* mouse has left the window */
|
|
posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
|
|
}
|
|
+ in_window = FALSE;
|
|
}
|
|
return(0);
|
|
#endif /* WM_MOUSELEAVE */
|
|
@@ -373,7 +397,7 @@ LRESULT CALLBACK WinMessage(HWND hwnd, U
|
|
case WM_XBUTTONDOWN:
|
|
case WM_XBUTTONUP: {
|
|
/* Mouse is handled by DirectInput when fullscreen */
|
|
- if ( SDL_VideoSurface && ! DINPUT() ) {
|
|
+ if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
|
|
WORD xbuttonval = 0;
|
|
Uint8 button, state;
|
|
int x, y;
|
|
@@ -472,7 +496,7 @@ this->hidden->hiresFix, &x, &y);
|
|
|
|
#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
|
|
case WM_MOUSEWHEEL:
|
|
- if ( SDL_VideoSurface && ! DINPUT() ) {
|
|
+ if ( SDL_VideoSurface && ! DINPUT_FULLSCREEN() ) {
|
|
int move = (short)HIWORD(wParam);
|
|
if ( move ) {
|
|
Uint8 button;
|
|
diff -rupN SDL-1.2-ORIG//src/video/wincommon/SDL_sysmouse.c SDL-1.2/src/video/wincommon/SDL_sysmouse.c
|
|
--- SDL-1.2-ORIG//src/video/wincommon/SDL_sysmouse.c 2014-01-14 20:03:09 -0500
|
|
+++ SDL-1.2/src/video/wincommon/SDL_sysmouse.c 2016-10-24 22:05:42 -0400
|
|
@@ -188,7 +188,8 @@ int WIN_ShowWMCursor(_THIS, WMcursor *cu
|
|
{
|
|
POINT mouse_pos;
|
|
|
|
- if ( !this->screen ) {
|
|
+ /* The fullscreen cursor must be done in software with DirectInput */
|
|
+ if ( !this->screen || DDRAW_FULLSCREEN() ) {
|
|
return(0);
|
|
}
|
|
|
|
@@ -207,20 +208,15 @@ int WIN_ShowWMCursor(_THIS, WMcursor *cu
|
|
|
|
void WIN_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
|
|
{
|
|
- if ( mouse_relative) {
|
|
+ if ( DDRAW_FULLSCREEN() ) {
|
|
+ SDL_PrivateMouseMotion(0, 0, x, y);
|
|
+ } else if ( mouse_relative) {
|
|
/* RJR: March 28, 2000
|
|
leave physical cursor at center of screen if
|
|
mouse hidden and grabbed */
|
|
SDL_PrivateMouseMotion(0, 0, x, y);
|
|
} else {
|
|
POINT pt;
|
|
-
|
|
- /* With DirectInput the position doesn't follow
|
|
- * the cursor, so it is set manually */
|
|
- if ( DINPUT() ) {
|
|
- SDL_PrivateMouseMotion(0, 0, x, y);
|
|
- }
|
|
-
|
|
pt.x = x;
|
|
pt.y = y;
|
|
ClientToScreen(SDL_Window, &pt);
|
|
@@ -231,15 +227,20 @@ void WIN_WarpWMCursor(_THIS, Uint16 x, U
|
|
/* Update the current mouse state and position */
|
|
void WIN_UpdateMouse(_THIS)
|
|
{
|
|
+ RECT rect;
|
|
POINT pt;
|
|
|
|
- /* Always unset SDL_APPMOUSEFOCUS to give the WM_MOUSEMOVE event
|
|
- * handler a chance to install a TRACKMOUSEEVENT */
|
|
- SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
|
|
-
|
|
- GetCursorPos(&pt);
|
|
- ScreenToClient(SDL_Window, &pt);
|
|
- SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y);
|
|
+ if ( ! DDRAW_FULLSCREEN() ) {
|
|
+ GetClientRect(SDL_Window, &rect);
|
|
+ GetCursorPos(&pt);
|
|
+ MapWindowPoints(NULL, SDL_Window, &pt, 1);
|
|
+ if (PtInRect(&rect, pt) && (WindowFromPoint(pt) == SDL_Window)){
|
|
+ SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS);
|
|
+ SDL_PrivateMouseMotion(0,0, (Sint16)pt.x, (Sint16)pt.y);
|
|
+ } else {
|
|
+ SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS);
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/* Check to see if we need to enter or leave mouse relative mode */
|
|
diff -rupN SDL-1.2-ORIG//src/video/windx5/SDL_dx5events.c SDL-1.2/src/video/windx5/SDL_dx5events.c
|
|
--- SDL-1.2-ORIG//src/video/windx5/SDL_dx5events.c 2012-01-19 01:30:06 -0500
|
|
+++ SDL-1.2/src/video/windx5/SDL_dx5events.c 2016-10-24 20:24:33 -0400
|
|
@@ -143,12 +143,7 @@ struct {
|
|
(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE),
|
|
(DISCL_FOREGROUND|DISCL_NONEXCLUSIVE), handle_keyboard },
|
|
{ "mouse",
|
|
- &GUID_SysMouse,
|
|
-#if DIRECTINPUT_VERSION >= 0x700
|
|
- &c_dfDIMouse2,
|
|
-#else
|
|
- &c_dfDIMouse,
|
|
-#endif
|
|
+ &GUID_SysMouse, &c_dfDIMouse,
|
|
(DISCL_BACKGROUND|DISCL_NONEXCLUSIVE),
|
|
(DISCL_BACKGROUND|DISCL_NONEXCLUSIVE), handle_mouse },
|
|
{ NULL, NULL, NULL, 0, 0, NULL }
|
|
@@ -370,11 +365,18 @@ static void handle_mouse(const int numev
|
|
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 mouse focus has been lost, make sure we release the cursor. */
|
|
if ( !(SDL_GetAppState() & SDL_APPMOUSEFOCUS) ) {
|
|
mouse_lost = 1;
|
|
ClipCursor(NULL);
|
|
} else {
|
|
+
|
|
/* If the mouse was lost, regain some sense of mouse state */
|
|
if ( mouse_lost ) {
|
|
POINT mouse_pos;
|
|
@@ -390,11 +392,7 @@ static void handle_mouse(const int numev
|
|
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],
|
|
@@ -415,13 +413,14 @@ static void handle_mouse(const int numev
|
|
for ( i=0; i<8; ++i ) {
|
|
if ( (old_state&0x01) != (new_state&0x01) ) {
|
|
button = (Uint8)(i+1);
|
|
- /* 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;
|
|
+ /* 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;
|
|
}
|
|
if ( new_state & 0x01 ) {
|
|
/* Grab mouse so we get mouse-up */
|
|
@@ -499,12 +498,6 @@ static void handle_mouse(const int numev
|
|
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 ) {
|
|
post_mouse_motion(1, xrel, yrel);
|
|
xrel = 0;
|
|
diff -rupN SDL-1.2-ORIG//src/video/windx5/directx.h SDL-1.2/src/video/windx5/directx.h
|
|
--- SDL-1.2-ORIG//src/video/windx5/directx.h 2012-01-19 01:30:06 -0500
|
|
+++ SDL-1.2/src/video/windx5/directx.h 2016-10-24 20:00:54 -0400
|
|
@@ -72,26 +72,10 @@
|
|
/* We need these defines to mark what version of DirectX API we use */
|
|
#define DIRECTDRAW_VERSION 0x0700
|
|
#define DIRECTSOUND_VERSION 0x0500
|
|
-#define DIRECTINPUT_VERSION 0x0700
|
|
+#define DIRECTINPUT_VERSION 0x0500
|
|
|
|
#include <ddraw.h>
|
|
#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 */
|