From 7a1f46d1beeca7fb8bcdda4095af5d967db54e71 Mon Sep 17 00:00:00 2001 From: bicarus <202771338+bicarus-dev@users.noreply.github.com> Date: Fri, 2 Jan 2026 15:07:32 -0800 Subject: [PATCH] gitadora: (arena model) fix window settings not working (#494) ## Link to GitHub Issue, if one exists #477 ## Description of change F11 menu (window settings) did not work for arena model because the game engine races to create many windows, so our logic of grabbing the first window created doesn't always get the main window. ## Testing --- src/spice2x/cfg/screen_resize.h | 1 + src/spice2x/hooks/graphics/graphics.cpp | 17 ++++++++++ src/spice2x/hooks/graphics/graphics.h | 1 + .../hooks/graphics/graphics_windowed.cpp | 33 ++++++++++++++++--- src/spice2x/overlay/windows/screen_resize.cpp | 5 +++ 5 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/spice2x/cfg/screen_resize.h b/src/spice2x/cfg/screen_resize.h index e1077f1..9204542 100644 --- a/src/spice2x/cfg/screen_resize.h +++ b/src/spice2x/cfg/screen_resize.h @@ -69,6 +69,7 @@ namespace cfg { uint32_t init_client_height = 0; float init_client_aspect_ratio = 1.f; uint32_t init_window_style = 0; + uint32_t init_window_style_ex = 0; uint32_t window_deco_width = 0; uint32_t window_deco_height = 0; diff --git a/src/spice2x/hooks/graphics/graphics.cpp b/src/spice2x/hooks/graphics/graphics.cpp index deda3c0..5b4c488 100644 --- a/src/spice2x/hooks/graphics/graphics.cpp +++ b/src/spice2x/hooks/graphics/graphics.cpp @@ -61,6 +61,7 @@ bool GRAPHICS_SHOW_CURSOR = false; graphics_orientation GRAPHICS_ADJUST_ORIENTATION = ORIENTATION_NORMAL; bool GRAPHICS_WINDOWED = false; std::vector GRAPHICS_WINDOWS; +std::optional GRAPHICS_WINDOW_MAIN; UINT GRAPHICS_FORCE_REFRESH = 0; std::optional GRAPHICS_FORCE_VSYNC_BUFFER; bool GRAPHICS_FORCE_SINGLE_ADAPTER = false; @@ -362,10 +363,12 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC } // gfdm + bool is_gitadora_main_window = false; if (avs::game::is_model({"J32", "J33", "K32", "K33", "L32", "L33", "M32"})) { // set window name if (!lpWindowName) { lpWindowName = "GITADORA"; + is_gitadora_main_window = true; } } @@ -408,6 +411,11 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC hWndParent, hMenu, hInstance, lpParam); GRAPHICS_WINDOWS.push_back(result); + // this is only really needed for arena model, but pre-arena model was single window anyway + if (is_gitadora_main_window) { + GRAPHICS_WINDOW_MAIN = result; + } + if (is_tdj_sub_window) { // TDJ windowed mode: remember the subscreen window handle for later TDJ_SUBSCREEN_WINDOW = result; @@ -430,6 +438,7 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC } disable_touch_indicators(result); + log_misc("graphics", "CreateWindowExA returned {}", fmt::ptr(result)); return result; } @@ -496,6 +505,7 @@ static HWND WINAPI CreateWindowExW_hook(DWORD dwExStyle, LPCWSTR lpClassName, LP hWndParent, hMenu, hInstance, lpParam); GRAPHICS_WINDOWS.push_back(result); + log_misc("graphics", "CreateWindowExW returned {}", fmt::ptr(result)); disable_touch_indicators(result); return result; } @@ -660,6 +670,13 @@ static BOOL WINAPI SetWindowPos_hook(HWND hWnd, HWND hWndInsertAfter, return TRUE; } + // prevent gitadora arena model from shifting windows around if the user has preferences + if (GRAPHICS_WINDOWED && games::gitadora::is_arena_model() && + GRAPHICS_WINDOW_MAIN.has_value() && hWnd == GRAPHICS_WINDOW_MAIN.value() && + cfg::SCREENRESIZE->enable_window_resize) { + return TRUE; + } + // call original return SetWindowPos_orig(hWnd, hWndInsertAfter, X, Y, cx, cy, uFlags); } diff --git a/src/spice2x/hooks/graphics/graphics.h b/src/spice2x/hooks/graphics/graphics.h index 89ef148..e14234a 100644 --- a/src/spice2x/hooks/graphics/graphics.h +++ b/src/spice2x/hooks/graphics/graphics.h @@ -31,6 +31,7 @@ extern bool GRAPHICS_SHOW_CURSOR; extern bool GRAPHICS_WINDOWED; extern graphics_orientation GRAPHICS_ADJUST_ORIENTATION; extern std::vector GRAPHICS_WINDOWS; +extern std::optional GRAPHICS_WINDOW_MAIN; extern UINT GRAPHICS_FORCE_REFRESH; extern std::optional GRAPHICS_FORCE_VSYNC_BUFFER; extern bool GRAPHICS_FORCE_SINGLE_ADAPTER; diff --git a/src/spice2x/hooks/graphics/graphics_windowed.cpp b/src/spice2x/hooks/graphics/graphics_windowed.cpp index 2cb1ec2..8541e34 100644 --- a/src/spice2x/hooks/graphics/graphics_windowed.cpp +++ b/src/spice2x/hooks/graphics/graphics_windowed.cpp @@ -56,8 +56,12 @@ void graphics_capture_initial_window(HWND hWnd) { graphics_load_windowed_parameters(); cfg::SCREENRESIZE->init_window_style = GetWindowLong(hWnd, GWL_STYLE); + cfg::SCREENRESIZE->init_window_style_ex = GetWindowLong(hWnd, GWL_EXSTYLE); - log_debug("graphics-windowed", "graphics_capture_initial_window called"); + log_debug( + "graphics-windowed", + "graphics_capture_initial_window called, hWnd={}", + fmt::ptr(hWnd)); RECT rect; if (!GetClientRect(hWnd, &rect)) { @@ -372,13 +376,19 @@ void graphics_update_window_style(HWND hWnd) { return; } - log_debug("graphics-windowed", "graphics_update_window_style called"); + log_debug( + "graphics-windowed", + "graphics_update_window_style called for hWnd={}", + fmt::ptr(hWnd)); // update frame style auto style = cfg::SCREENRESIZE->init_window_style; + auto style_ex = cfg::SCREENRESIZE->init_window_style_ex; switch (cfg::SCREENRESIZE->window_decoration) { case cfg::WindowDecorationMode::Borderless: style &= ~WS_OVERLAPPEDWINDOW; + style_ex &= ~WS_EX_CLIENTEDGE; + style_ex &= ~WS_EX_WINDOWEDGE; break; case cfg::WindowDecorationMode::ResizableFrame: style |= WS_OVERLAPPEDWINDOW; @@ -393,11 +403,26 @@ void graphics_update_window_style(HWND hWnd) { "graphics_update_window_style - calling SetWindowLong with Mode {}, style 0x{:x}", static_cast(cfg::SCREENRESIZE->window_decoration), style); - SetWindowLong(hWnd, GWL_STYLE, style); + + const auto ret = SetWindowLong(hWnd, GWL_STYLE, style); + (void)ret; + + log_debug( + "graphics-windowed", + "graphics_update_window_style - SetWindowLong(GWL_STYLE) returned {:x}, GLE={}", + ret, + GetLastError()); + + const auto ret2 = SetWindowLong(hWnd, GWL_EXSTYLE, style_ex); + (void)ret2; + log_debug( + "graphics-windowed", + "graphics_update_window_style SetWindowLong(GWL_EXSTYLE) returned {:x}, GLE={}", + ret2, + GetLastError()); // SetWindowPos must be called after SetWindowLong if the frame style changed // this will be done in WM_STYLECHANGED handler - log_debug("graphics-windowed", "graphics_update_window_style returned"); } void graphics_update_z_order(HWND hWnd, bool always_on_top) { diff --git a/src/spice2x/overlay/windows/screen_resize.cpp b/src/spice2x/overlay/windows/screen_resize.cpp index 3e10e75..56643da 100644 --- a/src/spice2x/overlay/windows/screen_resize.cpp +++ b/src/spice2x/overlay/windows/screen_resize.cpp @@ -27,6 +27,11 @@ namespace overlay::windows { } HWND ScreenResize::get_first_window() { + // hack for gitadora arena model which races to create many windows + // so [0] is not always the main one + if (GRAPHICS_WINDOW_MAIN.has_value()) { + return GRAPHICS_WINDOW_MAIN.value(); + } if (GRAPHICS_WINDOWS.size() == 0) { return NULL; }