diff --git a/libultraship/libultraship/ImGuiImpl.cpp b/libultraship/libultraship/ImGuiImpl.cpp index d26d0243c..98678cab1 100644 --- a/libultraship/libultraship/ImGuiImpl.cpp +++ b/libultraship/libultraship/ImGuiImpl.cpp @@ -401,8 +401,11 @@ namespace SohImGui { #endif Ship::RegisterHook([] { - if (Window::GetInstance()->IsFullscreen()) - ShowCursor(CVar_GetS32("gOpenMenuBar", 0), Dialogues::dLoadSettings); + bool menuBarOpen = CVar_GetS32("gOpenMenuBar", 0); + Window::GetInstance()->SetMenuBar(menuBarOpen); + if (Window::GetInstance()->IsFullscreen()) { + SetCursorVisibility(menuBarOpen); + } LoadTexture("Game_Icon", "assets/ship_of_harkinian/icons/gSohIcon.png"); LoadTexture("A-Btn", "assets/ship_of_harkinian/buttons/ABtn.png"); @@ -482,11 +485,13 @@ namespace SohImGui { if (ImGui::IsKeyPressed(TOGGLE_BTN) || (ImGui::IsKeyPressed(TOGGLE_PAD_BTN) && CVar_GetS32("gControlNav", 0))) { - bool menu_bar = CVar_GetS32("gOpenMenuBar", 0); - CVar_SetS32("gOpenMenuBar", !menu_bar); + bool menu_bar = !CVar_GetS32("gOpenMenuBar", 0); + CVar_SetS32("gOpenMenuBar", menu_bar); needs_save = true; Window::GetInstance()->SetMenuBar(menu_bar); - ShowCursor(menu_bar, Dialogues::dMenubar); + if (Window::GetInstance()->IsFullscreen()) { + SetCursorVisibility(menu_bar); + } Window::GetInstance()->GetControlDeck()->SaveControllerSettings(); if (CVar_GetS32("gControlNav", 0) && CVar_GetS32("gOpenMenuBar", 0)) { io->ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; @@ -918,24 +923,8 @@ namespace SohImGui { DefaultAssets[name] = asset; } - void ShowCursor(bool hide, Dialogues d) { - if (d == Dialogues::dLoadSettings) { - Window::GetInstance()->ShowCursor(hide); - return; - } - - if (d == Dialogues::dConsole && CVar_GetS32("gOpenMenuBar", 0)) { - return; - } - if (!Window::GetInstance()->IsFullscreen()) { - oldCursorState = false; - return; - } - - if (oldCursorState != hide) { - oldCursorState = hide; - Window::GetInstance()->ShowCursor(hide); - } + void SetCursorVisibility(bool visible) { + Window::GetInstance()->SetCursorVisibility(visible); } void BeginGroupPanel(const char* name, const ImVec2& size) { diff --git a/libultraship/libultraship/ImGuiImpl.h b/libultraship/libultraship/ImGuiImpl.h index 3de813f76..9c1cd550c 100644 --- a/libultraship/libultraship/ImGuiImpl.h +++ b/libultraship/libultraship/ImGuiImpl.h @@ -110,7 +110,7 @@ namespace SohImGui { ImTextureID GetTextureByName(const std::string& name); void LoadResource(const std::string& name, const std::string& path, const ImVec4& tint = ImVec4(1, 1, 1, 1)); - void ShowCursor(bool hide, Dialogues w); + void SetCursorVisibility(bool visible); void BeginGroupPanel(const char* name, const ImVec2 & size = ImVec2(0.0f, 0.0f)); void EndGroupPanel(float minHeight = 0.0f); } diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp index b0ea8a601..cf2a4d24b 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_dxgi.cpp @@ -352,12 +352,21 @@ static void gfx_dxgi_set_fullscreen_changed_callback(void (*on_fullscreen_change dxgi.on_fullscreen_changed = on_fullscreen_changed; } -static void gfx_dxgi_show_cursor(bool hide) { - /** - * @bug When menubar is open in windowed mode and you toggle fullscreen - * ShowCursor no longer responds. Debugging shows the bool to be correct. - **/ - ShowCursor(hide); +static void gfx_dxgi_set_cursor_visibility(bool visible) { + // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showcursor + // https://devblogs.microsoft.com/oldnewthing/20091217-00/?p=15643 + // ShowCursor uses a counter, not a boolean value, and increments or decrements that value when called + // This means we need to keep calling it until we get the value we want + int cursorVisibilityCounter; + if (visible) { + do { + cursorVisibilityCounter = ShowCursor(true); + } while (cursorVisibilityCounter < 0); + } else { + do { + cursorVisibilityCounter = ShowCursor(false); + } while (cursorVisibilityCounter >= 0); + } } static void gfx_dxgi_set_fullscreen(bool enable) { @@ -730,7 +739,7 @@ extern "C" struct GfxWindowManagerAPI gfx_dxgi_api = { gfx_dxgi_set_keyboard_callbacks, gfx_dxgi_set_fullscreen_changed_callback, gfx_dxgi_set_fullscreen, - gfx_dxgi_show_cursor, + gfx_dxgi_set_cursor_visibility, gfx_dxgi_main_loop, gfx_dxgi_get_dimensions, gfx_dxgi_handle_events, diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp index 9de508a3f..ca3105abb 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp +++ b/libultraship/libultraship/Lib/Fast3D/gfx_sdl2.cpp @@ -219,8 +219,12 @@ static void gfx_sdl_set_fullscreen(bool enable) { set_fullscreen(enable, true); } -static void gfx_sdl_show_cursor(bool hide) { - SDL_ShowCursor(hide); +static void gfx_sdl_set_cursor_visibility(bool visible) { + if (visible) { + SDL_ShowCursor(SDL_ENABLE); + } else { + SDL_ShowCursor(SDL_DISABLE); + } } static void gfx_sdl_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode), void (*on_all_keys_up)(void)) { @@ -394,7 +398,7 @@ struct GfxWindowManagerAPI gfx_sdl = { gfx_sdl_set_keyboard_callbacks, gfx_sdl_set_fullscreen_changed_callback, gfx_sdl_set_fullscreen, - gfx_sdl_show_cursor, + gfx_sdl_set_cursor_visibility, gfx_sdl_main_loop, gfx_sdl_get_dimensions, gfx_sdl_handle_events, diff --git a/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h b/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h index 99344940e..8e9e52dd3 100644 --- a/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h +++ b/libultraship/libultraship/Lib/Fast3D/gfx_window_manager_api.h @@ -9,7 +9,7 @@ struct GfxWindowManagerAPI { void (*set_keyboard_callbacks)(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode), void (*on_all_keys_up)(void)); void (*set_fullscreen_changed_callback)(void (*on_fullscreen_changed)(bool is_now_fullscreen)); void (*set_fullscreen)(bool enable); - void (*show_cursor)(bool hide); + void (*set_cursor_visibility)(bool visible); void (*main_loop)(void (*run_one_game_iter)(void)); void (*get_dimensions)(uint32_t *width, uint32_t *height); void (*handle_events)(void); diff --git a/libultraship/libultraship/Window.cpp b/libultraship/libultraship/Window.cpp index d731b7972..138aaab83 100644 --- a/libultraship/libultraship/Window.cpp +++ b/libultraship/libultraship/Window.cpp @@ -261,7 +261,7 @@ namespace Ship { if (GetConfig()->isNewInstance) { GetConfig()->setInt("Window.Width", 640); GetConfig()->setInt("Window.Height", 480); - GetConfig()->setBool("Window.Options", false); + GetConfig()->setString("Window.GfxBackend", ""); GetConfig()->setString("Window.AudioBackend", ""); @@ -296,8 +296,6 @@ namespace Ship { dwHeight = GetConfig()->getInt("Window.Height", 480); } - dwMenubar = GetConfig()->getBool("Window.Options", false); - gfxBackend = GetConfig()->getString("Window.GfxBackend"); InitializeWindowManager(); @@ -363,13 +361,8 @@ namespace Ship { WmApi->set_fullscreen(bIsFullscreen); } - void Window::ShowCursor(bool hide) { - if (!this->bIsFullscreen || this->dwMenubar) { - WmApi->show_cursor(true); - } - else { - WmApi->show_cursor(hide); - } + void Window::SetCursorVisibility(bool visible) { + WmApi->set_cursor_visibility(visible); } void Window::MainLoop(void (*MainFunction)(void)) { @@ -425,7 +418,12 @@ namespace Ship { Window::GetInstance()->bIsFullscreen = bIsFullscreen; pConf->setBool("Window.Fullscreen.Enabled", bIsFullscreen); - Window::GetInstance()->ShowCursor(!bIsFullscreen); + if (bIsFullscreen) { + bool menuBarOpen = Window::GetInstance()->GetMenuBar(); + Window::GetInstance()->SetCursorVisibility(menuBarOpen); + } else if (!bIsFullscreen) { + Window::GetInstance()->SetCursorVisibility(true); + } } uint32_t Window::GetCurrentWidth() { diff --git a/libultraship/libultraship/Window.h b/libultraship/libultraship/Window.h index 490a1e0c3..ba5c748cf 100644 --- a/libultraship/libultraship/Window.h +++ b/libultraship/libultraship/Window.h @@ -36,7 +36,7 @@ namespace Ship { uint16_t GetPixelDepth(float x, float y); void ToggleFullscreen(); void SetFullscreen(bool bIsFullscreen); - void ShowCursor(bool hide); + void SetCursorVisibility(bool visible); uint32_t GetCurrentWidth(); uint32_t GetCurrentHeight(); bool IsFullscreen();