From c8fc550c0f6dc08765b04319aac7c1d308aeb274 Mon Sep 17 00:00:00 2001 From: Will Xyen Date: Mon, 27 Apr 2020 10:35:19 -0700 Subject: [PATCH] d3d9ex: add cursor confining (ported from sdvxhook1) --- dist/sdvx5/sdvxhook2.conf | 3 ++ src/main/d3d9exhook/config-gfx.c | 20 ++++++++++++ src/main/d3d9exhook/config-gfx.h | 1 + src/main/d3d9exhook/d3d9ex.c | 56 ++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+) diff --git a/dist/sdvx5/sdvxhook2.conf b/dist/sdvx5/sdvxhook2.conf index eb6c4b1..a982aa8 100644 --- a/dist/sdvx5/sdvxhook2.conf +++ b/dist/sdvx5/sdvxhook2.conf @@ -16,6 +16,9 @@ gfx.framed=true # Run the game windowed gfx.windowed=false +# Confine mouse coursor to window +gfx.confined=false + # Windowed width, -1 for default size gfx.window_width=1080 diff --git a/src/main/d3d9exhook/config-gfx.c b/src/main/d3d9exhook/config-gfx.c index e32f256..bfe1137 100644 --- a/src/main/d3d9exhook/config-gfx.c +++ b/src/main/d3d9exhook/config-gfx.c @@ -10,6 +10,7 @@ #define D3D9EXHOOK_CONFIG_GFX_FRAMED_KEY "gfx.framed" #define D3D9EXHOOK_CONFIG_GFX_WINDOWED_KEY "gfx.windowed" +#define D3D9EXHOOK_CONFIG_GFX_CONFINED_KEY "gfx.confined" #define D3D9EXHOOK_CONFIG_GFX_WINDOW_WIDTH_KEY "gfx.window_width" #define D3D9EXHOOK_CONFIG_GFX_WINDOW_HEIGHT_KEY "gfx.window_height" #define D3D9EXHOOK_CONFIG_GFX_FORCED_REFRESHRATE_KEY "gfx.forced_refresh_rate" @@ -18,6 +19,7 @@ #define D3D9EXHOOK_CONFIG_GFX_DEFAULT_FRAMED_VALUE false #define D3D9EXHOOK_CONFIG_GFX_DEFAULT_WINDOWED_VALUE false +#define D3D9EXHOOK_CONFIG_GFX_DEFAULT_CONFINED_VALUE false #define D3D9EXHOOK_CONFIG_GFX_DEFAULT_WINDOW_WIDTH_VALUE -1 #define D3D9EXHOOK_CONFIG_GFX_DEFAULT_WINDOW_HEIGHT_VALUE -1 #define D3D9EXHOOK_CONFIG_GFX_DEFAULT_FORCED_RR_VALUE -1 @@ -38,6 +40,12 @@ void d3d9exhook_config_gfx_init(struct cconfig *config) D3D9EXHOOK_CONFIG_GFX_DEFAULT_WINDOWED_VALUE, "Run the game windowed"); + cconfig_util_set_bool( + config, + D3D9EXHOOK_CONFIG_GFX_CONFINED_KEY, + D3D9EXHOOK_CONFIG_GFX_DEFAULT_CONFINED_VALUE, + "Confine mouse coursor to window"); + cconfig_util_set_int( config, D3D9EXHOOK_CONFIG_GFX_WINDOW_WIDTH_KEY, @@ -99,6 +107,18 @@ void d3d9exhook_config_gfx_get( D3D9EXHOOK_CONFIG_GFX_DEFAULT_WINDOWED_VALUE); } + if (!cconfig_util_get_bool( + config, + D3D9EXHOOK_CONFIG_GFX_CONFINED_KEY, + &config_gfx->confined, + D3D9EXHOOK_CONFIG_GFX_DEFAULT_CONFINED_VALUE)) { + log_warning( + "Invalid value for key '%s' specified, fallback " + "to default '%d'", + D3D9EXHOOK_CONFIG_GFX_CONFINED_KEY, + D3D9EXHOOK_CONFIG_GFX_DEFAULT_CONFINED_VALUE); + } + if (!cconfig_util_get_int( config, D3D9EXHOOK_CONFIG_GFX_WINDOW_WIDTH_KEY, diff --git a/src/main/d3d9exhook/config-gfx.h b/src/main/d3d9exhook/config-gfx.h index cac6cdd..74586c7 100644 --- a/src/main/d3d9exhook/config-gfx.h +++ b/src/main/d3d9exhook/config-gfx.h @@ -12,6 +12,7 @@ struct d3d9exhook_config_gfx { bool framed; bool windowed; + bool confined; int32_t window_width; int32_t window_height; int32_t forced_refresh_rate; diff --git a/src/main/d3d9exhook/d3d9ex.c b/src/main/d3d9exhook/d3d9ex.c index 6b96c1d..d1b6462 100644 --- a/src/main/d3d9exhook/d3d9ex.c +++ b/src/main/d3d9exhook/d3d9ex.c @@ -47,6 +47,8 @@ static HRESULT STDCALL my_CreateDeviceEx( static HRESULT STDCALL my_Direct3DCreate9Ex(UINT sdk_ver, IDirect3D9Ex **api); +static WNDPROC real_WndProc; + static BOOL STDCALL my_EnumDisplayDevicesA( const char *dev_name, DWORD dev_num, DISPLAY_DEVICEA *info, DWORD flags); @@ -82,6 +84,7 @@ static BOOL(STDCALL *real_MoveWindow)( /* ------------------------------------------------------------------------- */ static bool d3d9ex_windowed; +static bool d3d9ex_confined; static int32_t d3d9ex_force_refresh_rate = -1; static int32_t d3d9ex_window_width = -1; static int32_t d3d9ex_window_height = -1; @@ -183,6 +186,52 @@ my_MoveWindow(HWND hWnd, int X, int Y, int nWidth, int nHeight, BOOL bRepaint) return result; } +static LRESULT gfx_confine(HWND hwnd) +{ + POINT p; + RECT r; + + log_misc("Confining mouse (ALT-TAB to release)"); + + p.x = 0; + p.y = 0; + + ClientToScreen(hwnd, &p); + + r.left = p.x; + r.top = p.y; + r.right = p.x + 100; + r.bottom = p.y + 100; + + ClipCursor(&r); + + return TRUE; +} + +static LRESULT gfx_unconfine(HWND hwnd) +{ + log_misc("Un-confining mouse"); + + ClipCursor(NULL); + + return TRUE; +} + +static LRESULT CALLBACK +my_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + switch (msg) { + case WM_SETFOCUS: + return gfx_confine(hwnd); + + case WM_KILLFOCUS: + return gfx_unconfine(hwnd); + + default: + return CallWindowProc(real_WndProc, hwnd, msg, wparam, lparam); + } +} + static HRESULT STDCALL my_CreateDeviceEx( IDirect3D9Ex *self, UINT adapter, @@ -268,6 +317,12 @@ static HRESULT STDCALL my_CreateDeviceEx( hr = IDirect3D9Ex_CreateDeviceEx( real, adapter, type, hwnd, flags, pp, fdm, pdev); + if (SUCCEEDED(hr) && d3d9ex_confined) { + real_WndProc = (void *) GetWindowLongPtr(hwnd, GWLP_WNDPROC); + + SetWindowLongPtr(hwnd, GWLP_WNDPROC, (uintptr_t) my_WndProc); + } + return hr; } @@ -319,6 +374,7 @@ void d3d9ex_hook_init(void) void d3d9ex_configure(struct d3d9exhook_config_gfx *gfx_config) { d3d9ex_windowed = gfx_config->windowed; + d3d9ex_confined = gfx_config->confined; d3d9ex_window_framed = gfx_config->framed; d3d9ex_window_width = gfx_config->window_width; d3d9ex_window_height = gfx_config->window_height;