From 6cfeadacedc7e8da04966b56e3758364c79a331f Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Thu, 17 Jun 2021 04:12:05 +0200 Subject: [PATCH] fixes for cursor lock --- inc/dd.h | 2 +- src/config.c | 2 +- src/dd.c | 10 ++++++---- src/directinput.c | 9 +++++++-- src/mouse.c | 16 ++++++++++++---- src/winapi_hooks.c | 39 +++++++++++++++++++++++++++++---------- src/wndproc.c | 2 -- 7 files changed, 56 insertions(+), 24 deletions(-) diff --git a/inc/dd.h b/inc/dd.h index 564567a..d024439 100644 --- a/inc/dd.h +++ b/inc/dd.h @@ -107,8 +107,8 @@ typedef struct CNCDDRAW char shader[MAX_PATH]; BOOL wine; BOOL altenter; - BOOL hidecursor; HCURSOR old_cursor; + int show_cursor_count; BOOL accurate_timers; BOOL resizable; BOOL nonexclusive; diff --git a/src/config.c b/src/config.c index 3660ea9..1513dcd 100644 --- a/src/config.c +++ b/src/config.c @@ -40,7 +40,7 @@ void cfg_load() g_ddraw->border = cfg_get_bool("border", TRUE); g_ddraw->boxing = cfg_get_bool("boxing", FALSE); g_ddraw->maintas = cfg_get_bool("maintas", FALSE); - g_ddraw->adjmouse = cfg_get_bool("adjmouse", TRUE); + g_ddraw->adjmouse = cfg_get_bool("adjmouse", TRUE) || !cfg_get_bool("handlemouse", TRUE); g_ddraw->devmode = cfg_get_bool("devmode", FALSE); g_ddraw->vsync = cfg_get_bool("vsync", FALSE); g_ddraw->noactivateapp = cfg_get_bool("noactivateapp", FALSE); diff --git a/src/dd.c b/src/dd.c index 4ece9b5..4826bd9 100644 --- a/src/dd.c +++ b/src/dd.c @@ -819,13 +819,15 @@ HRESULT dd_SetCooperativeLevel(HWND hwnd, DWORD dwFlags) SetPixelFormat(g_ddraw->render.hdc, ChoosePixelFormat(g_ddraw->render.hdc, &pfd), &pfd); } + int cursor_count = real_ShowCursor(TRUE) - 1; + InterlockedExchange(&g_ddraw->show_cursor_count, cursor_count); + real_ShowCursor(FALSE); + /* Make sure the cursor is visible in windowed mode initially */ - if (g_ddraw->windowed) + if (g_ddraw->windowed && !g_ddraw->fullscreen) { - CURSORINFO ci = { .cbSize = sizeof(CURSORINFO) }; - if (real_GetCursorInfo(&ci) && ci.flags == 0) + if (cursor_count < 0) { - g_ddraw->hidecursor = TRUE; while (real_ShowCursor(TRUE) < 0); } diff --git a/src/directinput.c b/src/directinput.c index 01547a3..5733e0e 100644 --- a/src/directinput.c +++ b/src/directinput.c @@ -97,9 +97,14 @@ static HRESULT WINAPI fake_di_CreateDevice( if (SUCCEEDED(result) && !real_did_SetCooperativeLevel) { - if (rguid && IsEqualGUID(&GUID_SysMouse, rguid)) + if (rguid && IsEqualGUID(&GUID_SysMouse, rguid) && g_ddraw) { - while (real_ShowCursor(FALSE) >= 0); + if (g_ddraw->locked || g_ddraw->devmode) + { + while (real_ShowCursor(FALSE) >= 0); + } + + InterlockedExchange(&g_ddraw->show_cursor_count, -1); } real_did_SetCooperativeLevel = diff --git a/src/mouse.c b/src/mouse.c index 6fc82ea..e7c26ee 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -55,10 +55,19 @@ void mouse_lock() real_SetCursor(g_ddraw->old_cursor); - if (g_ddraw->hidecursor) + int cur_count = real_ShowCursor(TRUE) - 1; + real_ShowCursor(FALSE); + + int game_count = InterlockedExchangeAdd(&g_ddraw->show_cursor_count, 0); + + if (cur_count > game_count) { - g_ddraw->hidecursor = FALSE; - real_ShowCursor(FALSE); + while (real_ShowCursor(FALSE) > game_count); + } + + if (cur_count < game_count) + { + while (real_ShowCursor(TRUE) < game_count); } real_ClipCursor(&rc); @@ -96,7 +105,6 @@ void mouse_unlock() CURSORINFO ci = { .cbSize = sizeof(CURSORINFO) }; if (real_GetCursorInfo(&ci) && ci.flags == 0) { - g_ddraw->hidecursor = TRUE; while (real_ShowCursor(TRUE) < 0); } diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index 15fc67c..d15f611 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -114,21 +114,34 @@ BOOL WINAPI fake_ClipCursor(const RECT* lpRect) int WINAPI fake_ShowCursor(BOOL bShow) { - static int count; + if (g_ddraw) + { + if (g_ddraw->locked || g_ddraw->devmode) + { + int count = real_ShowCursor(bShow); + InterlockedExchange(&g_ddraw->show_cursor_count, count); + return count; + } + else + { + return bShow ? + InterlockedIncrement(&g_ddraw->show_cursor_count) : + InterlockedDecrement(&g_ddraw->show_cursor_count); + } + } - //if (g_ddraw) - return real_ShowCursor(bShow); - - return bShow ? ++count : --count; + return real_ShowCursor(bShow); } HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor) { if (g_ddraw) + { g_ddraw->old_cursor = hCursor; - if (g_ddraw && (g_ddraw->locked || g_ddraw->devmode)) - return real_SetCursor(hCursor); + if (g_ddraw->locked || g_ddraw->devmode) + return real_SetCursor(hCursor); + } return NULL; } @@ -206,10 +219,16 @@ BOOL WINAPI fake_SetCursorPos(int X, int Y) POINT pt = { X, Y }; - if (g_ddraw && g_ddraw->adjmouse) + if (g_ddraw) { - pt.x = (LONG)(pt.x * g_ddraw->render.scale_w); - pt.y = (LONG)(pt.y * g_ddraw->render.scale_h); + if (g_ddraw->adjmouse) + { + pt.x = (LONG)(pt.x * g_ddraw->render.scale_w); + pt.y = (LONG)(pt.y * g_ddraw->render.scale_h); + } + + pt.x += g_ddraw->render.viewport.x; + pt.y += g_ddraw->render.viewport.y; } return g_ddraw && real_ClientToScreen(g_ddraw->hwnd, &pt) && real_SetCursorPos(pt.x, pt.y); diff --git a/src/wndproc.c b/src/wndproc.c index 902b96d..779f6aa 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -737,8 +737,6 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam g_ddraw->cursor.x = (DWORD)((x - g_ddraw->render.viewport.x) * g_ddraw->render.unscale_w); g_ddraw->cursor.y = (DWORD)((y - g_ddraw->render.viewport.y) * g_ddraw->render.unscale_h); - g_ddraw->hidecursor = FALSE; - mouse_lock(); } break;