From febc02b50b8ca2ec2f330e20a559b8506251541a Mon Sep 17 00:00:00 2001 From: Azalea Date: Thu, 28 May 2026 09:57:10 +0800 Subject: [PATCH] =?UTF-8?q?[+]=20Hide=20sides=20on=20gitadora=20?= =?UTF-8?q?=F0=9D=9B=BF=20(#705)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description of change Added an option to only disable the left/right screens of gitadora gw delta while exposing the touch panel screen. ## Testing Tested by hand on CachyOS + hyprland + gamescope + wine + vnc + phone + cat 🐈‍⬛ image --- .../graphics/backends/d3d9/d3d9_device.cpp | 28 +++++++++++++++++-- src/spice2x/hooks/graphics/graphics.cpp | 18 ++++++++++++ src/spice2x/hooks/graphics/graphics.h | 3 +- src/spice2x/launcher/launcher.cpp | 23 ++++++++++++--- src/spice2x/launcher/options.cpp | 18 ++++++++++++ src/spice2x/launcher/options.h | 1 + 6 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/spice2x/hooks/graphics/backends/d3d9/d3d9_device.cpp b/src/spice2x/hooks/graphics/backends/d3d9/d3d9_device.cpp index 1d9738f..d2e4a55 100644 --- a/src/spice2x/hooks/graphics/backends/d3d9/d3d9_device.cpp +++ b/src/spice2x/hooks/graphics/backends/d3d9/d3d9_device.cpp @@ -253,15 +253,16 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3DDevice9::CreateAdditionalSwapChain( { WRAP_VERBOSE; - HRESULT hr = pReal->CreateAdditionalSwapChain(pPresentationParameters, ppSwapChain); - int index = 0; bool create_swap_chain = false; + bool create_fake_swap_chain = false; if (avs::game::is_model({"LDJ", "KFC", "M39"})) { create_swap_chain = true; } else if (games::gitadora::is_arena_model() && - (GRAPHICS_FORCE_SINGLE_ADAPTER || GRAPHICS_PREVENT_SECONDARY_WINDOW)) { + (GRAPHICS_FORCE_SINGLE_ADAPTER || + GRAPHICS_PREVENT_SECONDARY_WINDOW || + GRAPHICS_GITADORA_HIDE_SIDE_WINDOWS)) { if (pPresentationParameters->BackBufferWidth == 800) { // SMALL (subscreen) create_swap_chain = true; @@ -273,11 +274,32 @@ HRESULT STDMETHODCALLTYPE WrappedIDirect3DDevice9::CreateAdditionalSwapChain( if (sub_swapchain[index] || fake_sub_swapchain[index]) { index = 2; } + create_fake_swap_chain = GRAPHICS_GITADORA_HIDE_SIDE_WINDOWS && + !GRAPHICS_PREVENT_SECONDARY_WINDOW; } else { log_warning("graphics::d3d9", "unknown swap chain detected in CreateAdditionalSwapChain"); } } + if (create_fake_swap_chain) { + if (!fake_sub_swapchain[index]) { + log_info( + "graphics::d3d9", + "CreateAdditionalSwapChain called for hidden GITADORA side swap chain {}, " + "using fake swap chain", + index); + + fake_sub_swapchain[index] = + new FakeIDirect3DSwapChain9(this, pPresentationParameters, false); + } + fake_sub_swapchain[index]->AddRef(); + *ppSwapChain = static_cast(fake_sub_swapchain[index]); + + return D3D_OK; + } + + HRESULT hr = pReal->CreateAdditionalSwapChain(pPresentationParameters, ppSwapChain); + if (create_swap_chain) { log_misc( "graphics::d3d9", diff --git a/src/spice2x/hooks/graphics/graphics.cpp b/src/spice2x/hooks/graphics/graphics.cpp index da25415..baed618 100644 --- a/src/spice2x/hooks/graphics/graphics.cpp +++ b/src/spice2x/hooks/graphics/graphics.cpp @@ -39,6 +39,8 @@ struct CaptureData { HWND TDJ_SUBSCREEN_WINDOW = nullptr; HWND SDVX_SUBSCREEN_WINDOW = nullptr; HWND GFDM_SUBSCREEN_WINDOW = nullptr; +static HWND GFDM_LEFT_WINDOW = nullptr; +static HWND GFDM_RIGHT_WINDOW = nullptr; HWND POPN_SUBSCREEN_WINDOW = nullptr; bool FAKE_SUBSCREEN_ADAPTER = false; @@ -77,6 +79,7 @@ std::optional GRAPHICS_FORCE_REFRESH_SUB; std::optional GRAPHICS_FORCE_VSYNC_BUFFER; bool GRAPHICS_FORCE_SINGLE_ADAPTER = false; bool GRAPHICS_PREVENT_SECONDARY_WINDOW = false; +bool GRAPHICS_GITADORA_HIDE_SIDE_WINDOWS = false; graphics_dx9on12_state GRAPHICS_9_ON_12_STATE = DX9ON12_AUTO; bool GRAPHICS_9_ON_12_REQUESTED_BY_GAME = false; bool SUBSCREEN_FORCE_REDRAW = false; @@ -356,6 +359,8 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC bool is_sdvx_sub_window = avs::game::is_model("KFC") && window_name.ends_with(" Sub Screen"); bool is_popn_sub_window = avs::game::is_model("M39") && window_name.ends_with("Sub Screen"); bool is_gfdm_sub_window = games::gitadora::is_arena_model() && window_name.ends_with("SMALL"); + bool is_gfdm_left_window = games::gitadora::is_arena_model() && window_name.ends_with("LEFT"); + bool is_gfdm_right_window = games::gitadora::is_arena_model() && window_name.ends_with("RIGHT"); // update style / ex-style if (is_tdj_sub_window || is_sdvx_sub_window || is_gfdm_sub_window || is_popn_sub_window) { @@ -425,6 +430,12 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC GFDM_SUBSCREEN_WINDOW = result; graphics_hook_subscreen_window(GFDM_SUBSCREEN_WINDOW); } + if (is_gfdm_left_window) { + GFDM_LEFT_WINDOW = result; + } + if (is_gfdm_right_window) { + GFDM_RIGHT_WINDOW = result; + } if (is_popn_sub_window) { POPN_SUBSCREEN_WINDOW = result; @@ -708,6 +719,13 @@ static BOOL WINAPI ShowWindow_hook(HWND hWnd, int nCmdShow) { return true; } + if (games::gitadora::is_arena_model() && + GRAPHICS_GITADORA_HIDE_SIDE_WINDOWS && + (hWnd == GFDM_LEFT_WINDOW || hWnd == GFDM_RIGHT_WINDOW)) { + log_info("graphics", "ShowWindow_hook - hiding GITADORA side window {}", fmt::ptr(hWnd)); + return true; + } + if (games::popn::is_pikapika_model() && GRAPHICS_PREVENT_SECONDARY_WINDOW && hWnd == POPN_SUBSCREEN_WINDOW) { diff --git a/src/spice2x/hooks/graphics/graphics.h b/src/spice2x/hooks/graphics/graphics.h index e2beb63..bcaf1bb 100644 --- a/src/spice2x/hooks/graphics/graphics.h +++ b/src/spice2x/hooks/graphics/graphics.h @@ -39,6 +39,7 @@ extern std::optional GRAPHICS_FORCE_REFRESH_SUB; extern std::optional GRAPHICS_FORCE_VSYNC_BUFFER; extern bool GRAPHICS_FORCE_SINGLE_ADAPTER; extern bool GRAPHICS_PREVENT_SECONDARY_WINDOW; +extern bool GRAPHICS_GITADORA_HIDE_SIDE_WINDOWS; extern std::optional> GRAPHICS_FS_CUSTOM_RESOLUTION; extern std::optional> GRAPHICS_FS_CUSTOM_RESOLUTION_SUB; extern bool GRAPHICS_FS_ORIENTATION_SWAP; @@ -123,4 +124,4 @@ void update_monitor_on_boot( std::optional> target_resolution); void update_monitor_at_runtime(); -void reset_monitor_on_exit(); \ No newline at end of file +void reset_monitor_on_exit(); diff --git a/src/spice2x/launcher/launcher.cpp b/src/spice2x/launcher/launcher.cpp index 317db44..9e5137c 100644 --- a/src/spice2x/launcher/launcher.cpp +++ b/src/spice2x/launcher/launcher.cpp @@ -645,11 +645,26 @@ int main_implementation(int argc, char *argv[]) { if (options[launcher::Options::GitaDoraCabinetType].is_active()) { games::gitadora::CAB_TYPE = options[launcher::Options::GitaDoraCabinetType].value_uint32(); } + if (options[launcher::Options::GitaDoraArenaWindowLayout].is_active()) { + if (GRAPHICS_WINDOWED) { + const auto window_count = options[launcher::Options::GitaDoraArenaWindowLayout].value_uint32(); + if (window_count == 1) { + GRAPHICS_PREVENT_SECONDARY_WINDOW = true; + } else if (window_count == 2) { + GRAPHICS_GITADORA_HIDE_SIDE_WINDOWS = true; + } + } else { + log_warning("launcher", "-gdawindows only applies with -w; ignoring GitaDora Arena windowed layout"); + } + } if (options[launcher::Options::GitaDoraArenaSingleWindow].value_bool()) { - // for full screen - GRAPHICS_FORCE_SINGLE_ADAPTER = true; - // for windowed - GRAPHICS_PREVENT_SECONDARY_WINDOW = true; + if (GRAPHICS_WINDOWED) { + GRAPHICS_PREVENT_SECONDARY_WINDOW = true; + GRAPHICS_GITADORA_HIDE_SIDE_WINDOWS = false; + } else { + GRAPHICS_FORCE_SINGLE_ADAPTER = true; + GRAPHICS_PREVENT_SECONDARY_WINDOW = true; + } } if (options[launcher::Options::GitaDoraWailHold].is_active()) { socd::TILT_HOLD_MS = options[launcher::Options::GitaDoraWailHold].value_uint32(); diff --git a/src/spice2x/launcher/options.cpp b/src/spice2x/launcher/options.cpp index c7f13c1..f22ab53 100644 --- a/src/spice2x/launcher/options.cpp +++ b/src/spice2x/launcher/options.cpp @@ -1104,6 +1104,24 @@ static const std::vector OPTION_DEFINITIONS = { .game_name = "GitaDora", .category = "Game Options", }, + { + // GitaDoraArenaWindowLayout + .title = "GitaDora Arena Windowed Layout (EXPERIMENTAL)", + .name = "gdawindows", + .desc = "For Arena Model windowed mode (-w): select how many windows to create.\n\n" + "4 windows: main + LEFT + RIGHT + SMALL.\n\n" + "2 windows: main + SMALL.\n\n" + "1 window: main only; use the subscreen overlay for SMALL.\n\n" + "Ignored in fullscreen mode.", + .type = OptionType::Enum, + .game_name = "GitaDora", + .category = "Game Options", + .elements = { + {"4", "4 windows"}, + {"2", "2 windows"}, + {"1", "1 window"}, + }, + }, { // GitaDoraLefty .title = "GitaDora Lefty Guitar (for Digital Wailing)", diff --git a/src/spice2x/launcher/options.h b/src/spice2x/launcher/options.h index 1b308e0..9a0357b 100644 --- a/src/spice2x/launcher/options.h +++ b/src/spice2x/launcher/options.h @@ -110,6 +110,7 @@ namespace launcher { GitaDoraTwoChannelAudio, GitaDoraCabinetType, GitaDoraArenaSingleWindow, + GitaDoraArenaWindowLayout, GitaDoraLefty, GitaDoraWailHold, GitaDoraPickAlgo,