diff --git a/src/core/host_display.cpp b/src/core/host_display.cpp index b765e27c5..eb9983cfb 100644 --- a/src/core/host_display.cpp +++ b/src/core/host_display.cpp @@ -227,12 +227,39 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, float* apply_aspect_ratio ? (display_aspect_ratio / (static_cast(m_display_width) / static_cast(m_display_height))) : 1.0f; - const float display_width = static_cast(m_display_width) * x_scale; - const float display_height = static_cast(m_display_height); - const float active_left = static_cast(m_display_active_left) * x_scale; - const float active_top = static_cast(m_display_active_top); - const float active_width = static_cast(m_display_active_width) * x_scale; - const float active_height = static_cast(m_display_active_height); + const float display_width_stretched = static_cast(m_display_width) * x_scale; + const float display_width_pre = + (display_width_stretched > static_cast(m_display_width)) ? + display_width_stretched : static_cast(m_display_width); + const float display_width = g_settings.display_always_stretch_horizontally ? display_width_stretched : + display_width_pre; + const float active_left_stretched = static_cast(m_display_active_left) * x_scale; + const float active_left_pre = + (display_width_stretched > static_cast(m_display_width)) ? + active_left_stretched : static_cast(m_display_active_left); + const float active_left = g_settings.display_always_stretch_horizontally ? active_left_stretched : + active_left_pre; + const float active_width_stretched = static_cast(m_display_active_width) * x_scale; + const float active_width_pre = + (display_width_stretched > static_cast(m_display_width)) ? + active_width_stretched : static_cast(m_display_active_width); + const float active_width = g_settings.display_always_stretch_horizontally ? active_width_stretched : + active_width_pre; + const float display_height_pre = + (display_width_stretched < static_cast(m_display_width)) ? + static_cast(m_display_height) / x_scale : static_cast(m_display_height); + const float display_height = g_settings.display_always_stretch_horizontally ? + static_cast(m_display_height) : display_height_pre; + const float active_top_pre = + (display_width_stretched < static_cast(m_display_width)) ? + static_cast(m_display_active_top) / x_scale : static_cast(m_display_active_top); + const float active_top = g_settings.display_always_stretch_horizontally ? + static_cast(m_display_active_top) : active_top_pre; + const float active_height_pre = + (display_width_stretched < static_cast(m_display_width)) ? + static_cast(m_display_active_height) / x_scale : static_cast(m_display_active_height); + const float active_height = g_settings.display_always_stretch_horizontally ? + static_cast(m_display_active_height) : active_height_pre; if (out_x_scale) *out_x_scale = x_scale; @@ -360,8 +387,17 @@ std::tuple HostDisplay::ConvertWindowCoordinatesToDisplayCoordinat const float scaled_display_y = static_cast(window_y) - top_padding; // scale back to internal resolution - const float display_x = scaled_display_x / scale / x_scale; - const float display_y = scaled_display_y / scale; + const float display_x_stretched = scaled_display_x / scale / x_scale; + const float display_x_pre = + (display_x_stretched > (scaled_display_x / scale)) ? + display_x_stretched : (scaled_display_x / scale); + const float display_x = g_settings.display_always_stretch_horizontally ? + display_x_stretched : display_x_pre; + const float display_y_pre = + (display_x_stretched < (scaled_display_x / scale)) ? + scaled_display_y / scale * x_scale : scaled_display_y / scale; + const float display_y = g_settings.display_always_stretch_horizontally ? + scaled_display_y / scale : display_y_pre; return std::make_tuple(display_x, display_y); } @@ -488,7 +524,20 @@ bool HostDisplay::WriteDisplayTextureToFile(std::string filename, bool full_reso const float ss_width_scale = static_cast(m_display_active_width) / static_cast(m_display_width); const float ss_height_scale = static_cast(m_display_active_height) / static_cast(m_display_height); const float ss_aspect_ratio = m_display_aspect_ratio * ss_width_scale / ss_height_scale; - resize_width = static_cast(static_cast(resize_height) * ss_aspect_ratio); + const float resize_width_stretched = static_cast(resize_height) * ss_aspect_ratio; + const float resize_width_pre = + (static_cast(resize_width_stretched) > m_display_texture_view_width) ? + resize_width_stretched : static_cast(m_display_texture_view_width); + resize_width = g_settings.display_always_stretch_horizontally ? + static_cast(resize_width_stretched) : static_cast(resize_width_pre); + if (!g_settings.display_always_stretch_horizontally) + { + resize_height = + (static_cast(resize_width_stretched) < m_display_texture_view_width) ? + static_cast(static_cast(resize_height) / + (m_display_aspect_ratio / (static_cast(m_display_width) / static_cast(m_display_height)))) : + resize_height; + } } else { diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 89b50e158..460c70d2b 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -270,6 +270,7 @@ void Settings::Load(SettingsInterface& si) display_show_enhancements = si.GetBoolValue("Display", "ShowEnhancements", false); display_all_frames = si.GetBoolValue("Display", "DisplayAllFrames", false); display_internal_resolution_screenshots = si.GetBoolValue("Display", "InternalResolutionScreenshots", false); + display_always_stretch_horizontally = si.GetBoolValue("Display", "AlwaysStretchHorizontally", false); video_sync_enabled = si.GetBoolValue("Display", "VSync", DEFAULT_VSYNC_VALUE); display_post_process_chain = si.GetStringValue("Display", "PostProcessChain", ""); display_max_fps = si.GetFloatValue("Display", "MaxFPS", DEFAULT_DISPLAY_MAX_FPS); @@ -487,6 +488,7 @@ void Settings::Save(SettingsInterface& si) const si.SetBoolValue("Display", "ShowEnhancements", display_show_enhancements); si.SetBoolValue("Display", "DisplayAllFrames", display_all_frames); si.SetBoolValue("Display", "InternalResolutionScreenshots", display_internal_resolution_screenshots); + si.SetBoolValue("Display", "AlwaysStretchHorizontally", display_always_stretch_horizontally); si.SetBoolValue("Display", "VSync", video_sync_enabled); if (display_post_process_chain.empty()) si.DeleteValue("Display", "PostProcessChain"); diff --git a/src/core/settings.h b/src/core/settings.h index 1461a9870..27bfbba86 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -143,6 +143,7 @@ struct Settings bool display_show_enhancements = false; bool display_all_frames = false; bool display_internal_resolution_screenshots = false; + bool display_always_stretch_horizontally = false; bool video_sync_enabled = DEFAULT_VSYNC_VALUE; float display_osd_scale = 100.0f; float display_max_fps = DEFAULT_DISPLAY_MAX_FPS; diff --git a/src/duckstation-qt/advancedsettingswidget.cpp b/src/duckstation-qt/advancedsettingswidget.cpp index a21fc5465..5a3f84d62 100644 --- a/src/duckstation-qt/advancedsettingswidget.cpp +++ b/src/duckstation-qt/advancedsettingswidget.cpp @@ -288,6 +288,9 @@ void AdvancedSettingsWidget::addTweakOptions() addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Use Debug Host GPU Device"), "GPU", "UseDebugDevice", false); + addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Always Stretch Display Horizontally"), "Display", + "AlwaysStretchHorizontally", false); + addBooleanTweakOption(m_dialog, m_ui.tweakOptionTable, tr("Increase Timer Resolution"), "Main", "IncreaseTimerResolution", true); @@ -354,6 +357,7 @@ void AdvancedSettingsWidget::onResetToDefaultClicked() sif->DeleteValue("Display", "ActiveEndOffset"); sif->DeleteValue("Display", "LineStartOffset"); sif->DeleteValue("Display", "LineEndOffset"); + sif->DeleteValue("Display", "AlwaysStretchHorizontally"); sif->DeleteValue("GPU", "Multisamples"); sif->DeleteValue("GPU", "PerSampleShading"); sif->DeleteValue("GPU", "PGXPVertexCache"); diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index 3ec2dec5d..d308d0f32 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -4506,6 +4506,9 @@ void FullscreenUI::DrawAdvancedSettingsPage() DrawFloatRangeSetting(bsi, "Display FPS Limit", "Limits how many frames are displayed to the screen. These frames are still rendered.", "Display", "MaxFPS", Settings::DEFAULT_DISPLAY_MAX_FPS, 0.0f, 500.0f, "%.2f FPS"); + DrawToggleSetting(bsi, "Always Stretch Display Horizontally", + "Enables old DuckStation behavior for Integer Scaling, where the display is always stretched horizontally.", + "Display", "AlwaysStretchHorizontally", false); MenuHeading("PGXP Settings");