From 04d7f2060e900c66c3c8a5e285a078c1d8d20509 Mon Sep 17 00:00:00 2001 From: FunkyFr3sh Date: Mon, 9 Sep 2024 14:12:25 +0200 Subject: [PATCH] fix window resize/move issues --- src/mouse.c | 66 +------------------------------- src/winapi_hooks.c | 94 +++++++++++++++++++++++++++++++++++++++++++++- src/wndproc.c | 37 ++++++++++++++++++ 3 files changed, 130 insertions(+), 67 deletions(-) diff --git a/src/mouse.c b/src/mouse.c index cbb976b..df05989 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -115,74 +115,16 @@ void mouse_unlock() LRESULT CALLBACK mouse_gm_hook_proc(int code, WPARAM wParam, LPARAM lParam) { - if (code < 0 || !lParam || !g_ddraw.width) - return CallNextHookEx(g_mouse_gm_hook, code, wParam, lParam); - MSG* msg = (MSG*)lParam; - if (!g_config.windowed || real_ScreenToClient(g_ddraw.hwnd, &msg->pt)) - { - int x = max(msg->pt.x - g_ddraw.mouse.x_adjust, 0); - int y = max(msg->pt.y - g_ddraw.mouse.y_adjust, 0); - - if (g_config.adjmouse) - { - x = (DWORD)(roundf(x * g_ddraw.mouse.unscale_x)); - y = (DWORD)(roundf(y * g_ddraw.mouse.unscale_y)); - } - - msg->pt.x = min(x, g_ddraw.width - 1); - msg->pt.y = min(y, g_ddraw.height - 1); - } - else - { - msg->pt.x = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.x, 0); - msg->pt.y = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.y, 0); - } - - if (msg->hwnd != g_ddraw.hwnd) + if (code < 0 || !g_ddraw.width || !msg || msg->hwnd != g_ddraw.hwnd) return CallNextHookEx(g_mouse_gm_hook, code, wParam, lParam); switch (LOWORD(msg->message)) { - /* button up messages reactivate cursor lock */ case WM_LBUTTONUP: case WM_RBUTTONUP: case WM_MBUTTONUP: - { - if (!g_config.devmode && !g_mouse_locked) - { - int x = GET_X_LPARAM(msg->lParam); - int y = GET_Y_LPARAM(msg->lParam); - - if (x > g_ddraw.render.viewport.x + g_ddraw.render.viewport.width || - x < g_ddraw.render.viewport.x || - y > g_ddraw.render.viewport.y + g_ddraw.render.viewport.height || - y < g_ddraw.render.viewport.y) - { - x = g_ddraw.width / 2; - y = g_ddraw.height / 2; - } - else - { - x = (DWORD)((x - g_ddraw.render.viewport.x) * g_ddraw.mouse.unscale_x); - y = (DWORD)((y - g_ddraw.render.viewport.y) * g_ddraw.mouse.unscale_y); - } - - x = min(x, g_ddraw.width - 1); - y = min(y, g_ddraw.height - 1); - - InterlockedExchange((LONG*)&g_ddraw.cursor.x, x); - InterlockedExchange((LONG*)&g_ddraw.cursor.y, y); - - mouse_lock(); - - msg->message = MAKELONG(WM_NULL, HIWORD(msg->message)); - return 0; - } - /* fall through for lParam */ - } - /* down messages are ignored if we have no cursor lock */ case WM_XBUTTONDBLCLK: case WM_XBUTTONDOWN: case WM_XBUTTONUP: @@ -196,12 +138,6 @@ LRESULT CALLBACK mouse_gm_hook_proc(int code, WPARAM wParam, LPARAM lParam) case WM_MBUTTONDOWN: case WM_MOUSEMOVE: { - if (!g_config.devmode && !g_mouse_locked) - { - msg->message = MAKELONG(WM_NULL, HIWORD(msg->message)); - return 0; - } - if (LOWORD(msg->message) == WM_MOUSEWHEEL) { POINT pt = { GET_X_LPARAM(msg->lParam), GET_Y_LPARAM(msg->lParam) }; diff --git a/src/winapi_hooks.c b/src/winapi_hooks.c index b51731b..33ee191 100644 --- a/src/winapi_hooks.c +++ b/src/winapi_hooks.c @@ -612,12 +612,96 @@ HHOOK WINAPI fake_SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, D return result; } +BOOL HandleMessage(LPMSG lpMsg, HWND hWnd) +{ + if (lpMsg && g_ddraw.ref && g_ddraw.hwnd && g_ddraw.width) + { + if (!g_config.windowed || real_ScreenToClient(g_ddraw.hwnd, &lpMsg->pt)) + { + int x = max(lpMsg->pt.x - g_ddraw.mouse.x_adjust, 0); + int y = max(lpMsg->pt.y - g_ddraw.mouse.y_adjust, 0); + + if (g_config.adjmouse) + { + x = (DWORD)(roundf(x * g_ddraw.mouse.unscale_x)); + y = (DWORD)(roundf(y * g_ddraw.mouse.unscale_y)); + } + + lpMsg->pt.x = min(x, g_ddraw.width - 1); + lpMsg->pt.y = min(y, g_ddraw.height - 1); + } + else + { + lpMsg->pt.x = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.x, 0); + lpMsg->pt.y = InterlockedExchangeAdd((LONG*)&g_ddraw.cursor.y, 0); + } + + if (lpMsg->hwnd != g_ddraw.hwnd) + return TRUE; + + switch (LOWORD(lpMsg->message)) + { + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + { + if (!g_config.devmode && !g_mouse_locked) + { + TRACE("HandleMessage %s hWnd=%p, lpMsg->hWnd=%p\n", dbg_mes_to_str(lpMsg->message), hWnd, lpMsg->hwnd); + + InterlockedExchange((LONG*)&g_ddraw.cursor.x, GET_X_LPARAM(lpMsg->lParam)); + InterlockedExchange((LONG*)&g_ddraw.cursor.y, GET_Y_LPARAM(lpMsg->lParam)); + + mouse_lock(); + + lpMsg->message = (UINT)MAKELONG(WM_NULL, HIWORD(lpMsg->message)); + return FALSE; + } + + break; + } + /* down messages are ignored if we have no cursor lock */ + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + case WM_MOUSEWHEEL: + case WM_MOUSEHOVER: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_MOUSEMOVE: + { + if (!g_config.devmode && !g_mouse_locked) + { + // Does not work with 'New Robinson' + lpMsg->message = (UINT)MAKELONG(WM_NULL, HIWORD(lpMsg->message)); + return FALSE; + } + + break; + } + + } + } + + return TRUE; +} + BOOL WINAPI fake_GetMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax) { if (g_ddraw.ref && (!hWnd || hWnd == g_ddraw.hwnd)) g_ddraw.last_msg_pull_tick = timeGetTime(); - return real_GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + BOOL result = real_GetMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax); + if (result) + { + HandleMessage(lpMsg, hWnd); + } + + return result; } BOOL WINAPI fake_PeekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg) @@ -625,7 +709,13 @@ BOOL WINAPI fake_PeekMessageA(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT w if (g_ddraw.ref && (!hWnd || hWnd == g_ddraw.hwnd)) g_ddraw.last_msg_pull_tick = timeGetTime(); - return real_PeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); + BOOL result = real_PeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); + if (result) + { + return HandleMessage(lpMsg, hWnd); + } + + return result; } BOOL WINAPI fake_GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT* lpwndpl) diff --git a/src/wndproc.c b/src/wndproc.c index 030751e..cc87bd2 100644 --- a/src/wndproc.c +++ b/src/wndproc.c @@ -781,6 +781,43 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam { break; } + /* button up messages reactivate cursor lock */ + case WM_LBUTTONUP: + case WM_RBUTTONUP: + case WM_MBUTTONUP: + { + if (!g_config.devmode && !g_mouse_locked) + { + InterlockedExchange((LONG*)&g_ddraw.cursor.x, GET_X_LPARAM(lParam)); + InterlockedExchange((LONG*)&g_ddraw.cursor.y, GET_Y_LPARAM(lParam)); + + mouse_lock(); + return 0; + } + + break; + } + /* down messages are ignored if we have no cursor lock */ + case WM_XBUTTONDBLCLK: + case WM_XBUTTONDOWN: + case WM_XBUTTONUP: + case WM_MOUSEWHEEL: + case WM_MOUSEHOVER: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_MOUSEMOVE: + { + if (!g_config.devmode && !g_mouse_locked) + { + return 0; + } + + break; + } case WM_PARENTNOTIFY: { switch (LOWORD(wParam))