Improve Integer Scaling behavior

...so it always upscales the display from the framebuffer to fit the aspect ratio by stretching either horizontally or vertically instead of always stretching horizontally, which sometimes (actually most of the time) downscales the image
This commit is contained in:
Superstarxalien 2023-01-21 14:51:55 -04:00
parent 9c6c3892e2
commit 51d1587b21
5 changed files with 68 additions and 9 deletions

View file

@ -227,12 +227,39 @@ void HostDisplay::CalculateDrawRect(s32 window_width, s32 window_height, float*
apply_aspect_ratio ?
(display_aspect_ratio / (static_cast<float>(m_display_width) / static_cast<float>(m_display_height))) :
1.0f;
const float display_width = static_cast<float>(m_display_width) * x_scale;
const float display_height = static_cast<float>(m_display_height);
const float active_left = static_cast<float>(m_display_active_left) * x_scale;
const float active_top = static_cast<float>(m_display_active_top);
const float active_width = static_cast<float>(m_display_active_width) * x_scale;
const float active_height = static_cast<float>(m_display_active_height);
const float display_width_stretched = static_cast<float>(m_display_width) * x_scale;
const float display_width_pre =
(display_width_stretched > static_cast<float>(m_display_width)) ?
display_width_stretched : static_cast<float>(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<float>(m_display_active_left) * x_scale;
const float active_left_pre =
(display_width_stretched > static_cast<float>(m_display_width)) ?
active_left_stretched : static_cast<float>(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<float>(m_display_active_width) * x_scale;
const float active_width_pre =
(display_width_stretched > static_cast<float>(m_display_width)) ?
active_width_stretched : static_cast<float>(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<float>(m_display_width)) ?
static_cast<float>(m_display_height) / x_scale : static_cast<float>(m_display_height);
const float display_height = g_settings.display_always_stretch_horizontally ?
static_cast<float>(m_display_height) : display_height_pre;
const float active_top_pre =
(display_width_stretched < static_cast<float>(m_display_width)) ?
static_cast<float>(m_display_active_top) / x_scale : static_cast<float>(m_display_active_top);
const float active_top = g_settings.display_always_stretch_horizontally ?
static_cast<float>(m_display_active_top) : active_top_pre;
const float active_height_pre =
(display_width_stretched < static_cast<float>(m_display_width)) ?
static_cast<float>(m_display_active_height) / x_scale : static_cast<float>(m_display_active_height);
const float active_height = g_settings.display_always_stretch_horizontally ?
static_cast<float>(m_display_active_height) : active_height_pre;
if (out_x_scale)
*out_x_scale = x_scale;
@ -360,8 +387,17 @@ std::tuple<float, float> HostDisplay::ConvertWindowCoordinatesToDisplayCoordinat
const float scaled_display_y = static_cast<float>(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<float>(m_display_active_width) / static_cast<float>(m_display_width);
const float ss_height_scale = static_cast<float>(m_display_active_height) / static_cast<float>(m_display_height);
const float ss_aspect_ratio = m_display_aspect_ratio * ss_width_scale / ss_height_scale;
resize_width = static_cast<s32>(static_cast<float>(resize_height) * ss_aspect_ratio);
const float resize_width_stretched = static_cast<float>(resize_height) * ss_aspect_ratio;
const float resize_width_pre =
(static_cast<s32>(resize_width_stretched) > m_display_texture_view_width) ?
resize_width_stretched : static_cast<float>(m_display_texture_view_width);
resize_width = g_settings.display_always_stretch_horizontally ?
static_cast<s32>(resize_width_stretched) : static_cast<s32>(resize_width_pre);
if (!g_settings.display_always_stretch_horizontally)
{
resize_height =
(static_cast<s32>(resize_width_stretched) < m_display_texture_view_width) ?
static_cast<s32>(static_cast<float>(resize_height) /
(m_display_aspect_ratio / (static_cast<float>(m_display_width) / static_cast<float>(m_display_height)))) :
resize_height;
}
}
else
{

View file

@ -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");

View file

@ -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;

View file

@ -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");

View file

@ -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");