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; }