From e4d2b7331bdaf8273b26250e225fe3aaa2a3eb9f Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Wed, 18 Nov 2020 23:14:25 +1000 Subject: [PATCH] CommonHostInterface: Add resize window to scale functions --- src/core/host_display.h | 2 + src/duckstation-sdl/sdl_host_interface.cpp | 39 +++++++++++++++++++ src/duckstation-sdl/sdl_host_interface.h | 2 + src/frontend-common/common_host_interface.cpp | 22 +++++++++++ src/frontend-common/common_host_interface.h | 6 +++ 5 files changed, 71 insertions(+) diff --git a/src/core/host_display.h b/src/core/host_display.h index 7241977b7..ea6666aa0 100644 --- a/src/core/host_display.h +++ b/src/core/host_display.h @@ -92,6 +92,8 @@ public: virtual void SetVSync(bool enabled) = 0; const s32 GetDisplayTopMargin() const { return m_display_top_margin; } + const s32 GetDisplayWidth() const { return m_display_width; } + const s32 GetDisplayHeight() const { return m_display_height; } const float GetDisplayAspectRatio() const { return m_display_aspect_ratio; } void SetDisplayMaxFPS(float max_fps); diff --git a/src/duckstation-sdl/sdl_host_interface.cpp b/src/duckstation-sdl/sdl_host_interface.cpp index d06c08caa..432d378f8 100644 --- a/src/duckstation-sdl/sdl_host_interface.cpp +++ b/src/duckstation-sdl/sdl_host_interface.cpp @@ -442,6 +442,33 @@ float SDLHostInterface::GetFloatSettingValue(const char* section, const char* ke return m_settings_interface->GetFloatValue(section, key, default_value); } +bool SDLHostInterface::RequestRenderWindowSize(s32 new_window_width, s32 new_window_height) +{ + if (new_window_width <= 0 || new_window_height <= 0 || m_fullscreen) + return false; + + // use imgui scale as the dpr + const float dpi_scale = ImGui::GetIO().DisplayFramebufferScale.x; + const s32 scaled_width = + std::max(static_cast(std::ceil(static_cast(new_window_width) * dpi_scale)), 1); + const s32 scaled_height = std::max( + static_cast(std::ceil(static_cast(new_window_height) * dpi_scale)) + m_display->GetDisplayTopMargin(), + 1); + + SDL_SetWindowSize(m_window, scaled_width, scaled_height); + + s32 window_width, window_height; + SDL_GetWindowSize(m_window, &window_width, &window_height); + m_display->ResizeRenderWindow(window_width, window_height); + + UpdateFramebufferScale(); + + if (!System::IsShutdown()) + g_gpu->UpdateResolutionScale(); + + return true; +} + void SDLHostInterface::LoadSettings() { // Settings need to be loaded prior to creating the window for OpenGL bits. @@ -911,6 +938,18 @@ void SDLHostInterface::DrawQuickSettingsMenu() if (ImGui::MenuItem("Fullscreen", nullptr, &fullscreen)) RunLater([this, fullscreen] { SetFullscreen(fullscreen); }); + if (ImGui::BeginMenu("Resize to Game", System::IsValid())) + { + static constexpr auto scales = make_array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + for (const u32 scale : scales) + { + if (ImGui::MenuItem(TinyString::FromFormat("%ux Scale", scale))) + RunLater([this, scale]() { RequestRenderWindowScale(static_cast(scale)); }); + } + + ImGui::EndMenu(); + } + settings_changed |= ImGui::MenuItem("VSync", nullptr, &m_settings_copy.video_sync_enabled); ImGui::Separator(); diff --git a/src/duckstation-sdl/sdl_host_interface.h b/src/duckstation-sdl/sdl_host_interface.h index b88373d79..d77d36768 100644 --- a/src/duckstation-sdl/sdl_host_interface.h +++ b/src/duckstation-sdl/sdl_host_interface.h @@ -38,6 +38,8 @@ public: int GetIntSettingValue(const char* section, const char* key, int default_value = 0) override; float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f) override; + bool RequestRenderWindowSize(s32 new_window_width, s32 new_window_height) override; + void Run(); protected: diff --git a/src/frontend-common/common_host_interface.cpp b/src/frontend-common/common_host_interface.cpp index 75c130c40..7f2f006a2 100644 --- a/src/frontend-common/common_host_interface.cpp +++ b/src/frontend-common/common_host_interface.cpp @@ -2534,6 +2534,28 @@ bool CommonHostInterface::ParseFullscreenMode(const std::string_view& mode, u32* return false; } +bool CommonHostInterface::RequestRenderWindowSize(s32 new_window_width, s32 new_window_height) +{ + return false; +} + +bool CommonHostInterface::RequestRenderWindowScale(float scale) +{ + if (!System::IsValid() || scale == 0) + return false; + + const float y_scale = + (static_cast(m_display->GetDisplayWidth()) / static_cast(m_display->GetDisplayHeight())) / + m_display->GetDisplayAspectRatio(); + + const u32 requested_width = + std::max(static_cast(std::ceil(static_cast(m_display->GetDisplayWidth()) * scale)), 1); + const u32 requested_height = + std::max(static_cast(std::ceil(static_cast(m_display->GetDisplayHeight()) * y_scale * scale)), 1); + + return RequestRenderWindowSize(static_cast(requested_width), static_cast(requested_height)); +} + #ifdef WITH_DISCORD_PRESENCE void CommonHostInterface::SetDiscordPresenceEnabled(bool enabled) diff --git a/src/frontend-common/common_host_interface.h b/src/frontend-common/common_host_interface.h index 4d291dc57..733333591 100644 --- a/src/frontend-common/common_host_interface.h +++ b/src/frontend-common/common_host_interface.h @@ -183,6 +183,12 @@ public: /// Returns true if fast forwarding is currently active. bool IsFastForwardEnabled() const { return m_fast_forward_enabled; } + /// Requests the specified size for the render window. Not guaranteed to succeed (e.g. if in fullscreen). + virtual bool RequestRenderWindowSize(s32 new_window_width, s32 new_window_height); + + /// Requests a resize to a multiple of the render window size. + bool RequestRenderWindowScale(float scale); + protected: enum : u32 {