diff --git a/src/core/host_display.h b/src/core/host_display.h index 4aef14aef..7b4510616 100644 --- a/src/core/host_display.h +++ b/src/core/host_display.h @@ -39,6 +39,7 @@ public: virtual void SetDisplayTexture(void* texture_handle, s32 offset_x, s32 offset_y, s32 width, s32 height, u32 texture_width, u32 texture_height, float aspect_ratio) = 0; virtual void SetDisplayLinearFiltering(bool enabled) = 0; + virtual void SetDisplayTopMargin(int height) = 0; virtual void Render() = 0; diff --git a/src/duckstation/d3d11_host_display.cpp b/src/duckstation/d3d11_host_display.cpp index f659f154f..c05c4c020 100644 --- a/src/duckstation/d3d11_host_display.cpp +++ b/src/duckstation/d3d11_host_display.cpp @@ -149,6 +149,11 @@ void D3D11HostDisplay::SetDisplayLinearFiltering(bool enabled) m_display_linear_filtering = enabled; } +void D3D11HostDisplay::SetDisplayTopMargin(int height) +{ + m_display_top_margin = height; +} + void D3D11HostDisplay::SetVSync(bool enabled) { m_vsync = enabled; @@ -364,8 +369,8 @@ void D3D11HostDisplay::RenderDisplay() // - 20 for main menu padding auto [vp_left, vp_top, vp_width, vp_height] = - CalculateDrawRect(m_window_width, std::max(m_window_height - 20, 1), m_display_aspect_ratio); - vp_top += 20; + CalculateDrawRect(m_window_width, std::max(m_window_height - m_display_top_margin, 1), m_display_aspect_ratio); + vp_top += m_display_top_margin; m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->VSSetShader(m_display_vertex_shader.Get(), nullptr, 0); diff --git a/src/duckstation/d3d11_host_display.h b/src/duckstation/d3d11_host_display.h index 712dfcc7a..0a4319c4d 100644 --- a/src/duckstation/d3d11_host_display.h +++ b/src/duckstation/d3d11_host_display.h @@ -31,6 +31,7 @@ public: void SetDisplayTexture(void* texture, s32 offset_x, s32 offset_y, s32 width, s32 height, u32 texture_width, u32 texture_height, float aspect_ratio) override; void SetDisplayLinearFiltering(bool enabled) override; + void SetDisplayTopMargin(int height) override; void SetVSync(bool enabled) override; @@ -76,6 +77,7 @@ private: s32 m_display_height = 0; u32 m_display_texture_width = 0; u32 m_display_texture_height = 0; + int m_display_top_margin = 0; float m_display_aspect_ratio = 1.0f; bool m_display_texture_changed = false; diff --git a/src/duckstation/opengl_host_display.cpp b/src/duckstation/opengl_host_display.cpp index 81d7b106a..96b2368bd 100644 --- a/src/duckstation/opengl_host_display.cpp +++ b/src/duckstation/opengl_host_display.cpp @@ -130,6 +130,11 @@ void OpenGLHostDisplay::SetDisplayLinearFiltering(bool enabled) m_display_linear_filtering = enabled; } +void OpenGLHostDisplay::SetDisplayTopMargin(int height) +{ + m_display_top_margin = height; +} + void OpenGLHostDisplay::SetVSync(bool enabled) { // Window framebuffer has to be bound to call SetSwapInterval. @@ -373,9 +378,9 @@ void OpenGLHostDisplay::RenderDisplay() // - 20 for main menu padding const auto [vp_left, vp_top, vp_width, vp_height] = - CalculateDrawRect(m_window_width, std::max(m_window_height - 20, 1), m_display_aspect_ratio); + CalculateDrawRect(m_window_width, std::max(m_window_height - m_display_top_margin, 1), m_display_aspect_ratio); - glViewport(vp_left, m_window_height - (20 + vp_top) - vp_height, vp_width, vp_height); + glViewport(vp_left, m_window_height - (m_display_top_margin + vp_top) - vp_height, vp_width, vp_height); glDisable(GL_BLEND); glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); diff --git a/src/duckstation/opengl_host_display.h b/src/duckstation/opengl_host_display.h index bbea2bd90..f915ac08f 100644 --- a/src/duckstation/opengl_host_display.h +++ b/src/duckstation/opengl_host_display.h @@ -26,6 +26,7 @@ public: void SetDisplayTexture(void* texture, s32 offset_x, s32 offset_y, s32 width, s32 height, u32 texture_width, u32 texture_height, float aspect_ratio) override; void SetDisplayLinearFiltering(bool enabled) override; + void SetDisplayTopMargin(int height) override; void SetVSync(bool enabled) override; @@ -59,6 +60,7 @@ private: s32 m_display_height = 0; u32 m_display_texture_width = 0; u32 m_display_texture_height = 0; + int m_display_top_margin = 0; float m_display_aspect_ratio = 1.0f; GLuint m_display_nearest_sampler = 0; GLuint m_display_linear_sampler = 0; diff --git a/src/duckstation/sdl_host_interface.cpp b/src/duckstation/sdl_host_interface.cpp index 6fb1db0f9..f6f8c6505 100644 --- a/src/duckstation/sdl_host_interface.cpp +++ b/src/duckstation/sdl_host_interface.cpp @@ -172,6 +172,15 @@ void SDLHostInterface::ResetPerformanceCounters() void SDLHostInterface::SwitchGPURenderer() {} +void SDLHostInterface::UpdateFullscreen() +{ + SDL_SetWindowFullscreen(m_window, m_settings.display_fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); + + // We set the margin only in windowed mode, the menu bar is drawn on top in fullscreen. + m_display->SetDisplayTopMargin( + m_settings.display_fullscreen ? 0 : static_cast(20.0f * ImGui::GetIO().DisplayFramebufferScale.x)); +} + std::unique_ptr SDLHostInterface::Create(const char* filename /* = nullptr */, const char* exp1_filename /* = nullptr */, const char* save_state_filename /* = nullptr */) @@ -216,6 +225,8 @@ std::unique_ptr SDLHostInterface::Create(const char* filename intf->UpdateAudioVisualSync(); + intf->UpdateFullscreen(); + return intf; } @@ -229,11 +240,6 @@ void SDLHostInterface::ReportMessage(const char* message) AddOSDMessage(message, 3.0f); } -bool SDLHostInterface::IsWindowFullscreen() const -{ - return ((SDL_GetWindowFlags(m_window) & SDL_WINDOW_FULLSCREEN) != 0); -} - static inline u32 SDLButtonToHostButton(u32 button) { // SDL left = 1, middle = 2, right = 3 :/ @@ -488,6 +494,13 @@ void SDLHostInterface::HandleSDLKeyEvent(const SDL_Event* event) } break; + case SDL_SCANCODE_F11: + { + if (!pressed) + DoToggleFullscreen(); + } + break; + case SDL_SCANCODE_TAB: { if (!repeat) @@ -570,6 +583,15 @@ void SDLHostInterface::DrawImGui() void SDLHostInterface::DrawMainMenuBar() { + // We skip drawing the menu bar if we're in fullscreen and the mouse pointer isn't in range. + const float SHOW_THRESHOLD = 20.0f; + if (m_settings.display_fullscreen && + ImGui::GetIO().MousePos.y >= (SHOW_THRESHOLD * ImGui::GetIO().DisplayFramebufferScale.x) && + !ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow)) + { + return; + } + if (!ImGui::BeginMainMenuBar()) return; @@ -730,8 +752,8 @@ void SDLHostInterface::DrawQuickSettingsMenu() ImGui::EndMenu(); } - if (ImGui::MenuItem("Fullscreen", nullptr, IsWindowFullscreen())) - SDL_SetWindowFullscreen(m_window, IsWindowFullscreen() ? 0 : SDL_WINDOW_FULLSCREEN_DESKTOP); + if (ImGui::MenuItem("Fullscreen", nullptr, &m_settings.display_fullscreen)) + UpdateFullscreen(); if (ImGui::MenuItem("VSync", nullptr, &m_settings.gpu_vsync)) { @@ -977,7 +999,9 @@ void SDLHostInterface::DrawSettingsWindow() if (DrawSettingsSectionHeader("Display Output")) { - ImGui::Checkbox("Fullscreen", &m_settings.display_fullscreen); + if (ImGui::Checkbox("Fullscreen", &m_settings.display_fullscreen)) + UpdateFullscreen(); + if (ImGui::Checkbox("VSync", &m_settings.gpu_vsync)) { UpdateAudioVisualSync(); @@ -1132,10 +1156,11 @@ void SDLHostInterface::DrawOSDMessages() ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing; std::unique_lock lock(m_osd_messages_lock); + const float scale = ImGui::GetIO().DisplayFramebufferScale.x; auto iter = m_osd_messages.begin(); - float position_x = 10.0f; - float position_y = 10.0f + 20.0f; + float position_x = 10.0f * scale; + float position_y = (10.0f + (m_settings.display_fullscreen ? 0.0f : 20.0f)) * scale; u32 index = 0; while (iter != m_osd_messages.end()) { @@ -1156,7 +1181,7 @@ void SDLHostInterface::DrawOSDMessages() if (ImGui::Begin(SmallString::FromFormat("osd_%u", index++), nullptr, window_flags)) { ImGui::TextUnformatted(msg.text); - position_y += ImGui::GetWindowSize().y + (4.0f * ImGui::GetIO().DisplayFramebufferScale.x); + position_y += ImGui::GetWindowSize().y + (4.0f * scale); } ImGui::End(); @@ -1299,6 +1324,12 @@ void SDLHostInterface::DoToggleSoftwareRendering() m_system->RecreateGPU(); } +void SDLHostInterface::DoToggleFullscreen() +{ + m_settings.display_fullscreen = !m_settings.display_fullscreen; + UpdateFullscreen(); +} + void SDLHostInterface::DoModifyInternalResolution(s32 increment) { const u32 new_resolution_scale = diff --git a/src/duckstation/sdl_host_interface.h b/src/duckstation/sdl_host_interface.h index 330f80544..d9402f596 100644 --- a/src/duckstation/sdl_host_interface.h +++ b/src/duckstation/sdl_host_interface.h @@ -68,9 +68,9 @@ private: void ConnectDevices(); void ResetPerformanceCounters(); void SwitchGPURenderer(); + void UpdateFullscreen(); // We only pass mouse input through if it's grabbed - bool IsWindowFullscreen() const; void DrawImGui(); void DoReset(); void DoPowerOff(); @@ -83,6 +83,7 @@ private: void DoTogglePause(); void DoFrameStep(); void DoToggleSoftwareRendering(); + void DoToggleFullscreen(); void DoModifyInternalResolution(s32 increment); void HandleSDLEvent(const SDL_Event* event);