From d73271ec0a8bd6288655f89680f6e9314e47eeef Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 26 Sep 2020 15:11:45 +1000 Subject: [PATCH] GPU: Add option to force 4:3 for 24-bit content (e.g. FMVs) --- src/core/gpu.cpp | 11 ++++++++--- src/core/gpu.h | 2 +- src/core/gpu_hw_d3d11.cpp | 2 +- src/core/gpu_hw_opengl.cpp | 2 +- src/core/gpu_hw_vulkan.cpp | 2 +- src/core/gpu_sw.cpp | 2 +- src/core/host_interface.cpp | 5 +++-- src/core/settings.cpp | 2 ++ src/core/settings.h | 1 + src/duckstation-libretro/libretro_host_interface.cpp | 7 ++++++- src/duckstation-qt/enhancementsettingswidget.cpp | 4 ++++ src/duckstation-qt/enhancementsettingswidget.ui | 7 +++++++ src/duckstation-sdl/sdl_host_interface.cpp | 1 + 13 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 535dbf836..719481e4a 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -29,7 +29,6 @@ bool GPU::Initialize(HostDisplay* host_display) m_host_display = host_display; m_force_progressive_scan = g_settings.gpu_disable_interlacing; m_force_ntsc_timings = g_settings.gpu_force_ntsc_timings; - m_crtc_state.display_aspect_ratio = Settings::GetDisplayAspectRatioValue(g_settings.display_aspect_ratio); m_crtc_tick_event = TimingEvents::CreateTimingEvent( "GPU CRTC Tick", 1, 1, std::bind(&GPU::CRTCTickEvent, this, std::placeholders::_1), true); m_command_tick_event = TimingEvents::CreateTimingEvent( @@ -54,8 +53,6 @@ void GPU::UpdateSettings() UpdateCRTCConfig(); } - m_crtc_state.display_aspect_ratio = Settings::GetDisplayAspectRatioValue(g_settings.display_aspect_ratio); - // Crop mode calls this, so recalculate the display area UpdateCRTCDisplayParameters(); } @@ -442,6 +439,14 @@ float GPU::ComputeVerticalFrequency() const static_cast(ticks_per_frame)); } +float GPU::GetDisplayAspectRatio() const +{ + if (g_settings.display_force_4_3_for_24bit && m_GPUSTAT.display_area_color_depth_24) + return 4.0f / 3.0f; + else + return Settings::GetDisplayAspectRatioValue(g_settings.display_aspect_ratio); +} + void GPU::UpdateCRTCConfig() { static constexpr std::array dot_clock_dividers = {{10, 8, 5, 4, 7, 7, 7, 7}}; diff --git a/src/core/gpu.h b/src/core/gpu.h index 54078114b..eb7700319 100644 --- a/src/core/gpu.h +++ b/src/core/gpu.h @@ -375,6 +375,7 @@ protected: // Sets dots per scanline float ComputeHorizontalFrequency() const; float ComputeVerticalFrequency() const; + float GetDisplayAspectRatio() const; void UpdateCRTCConfig(); void UpdateCRTCDisplayParameters(); @@ -700,7 +701,6 @@ protected: TickCount current_tick_in_scanline; u32 current_scanline; - float display_aspect_ratio; bool in_hblank; bool in_vblank; diff --git a/src/core/gpu_hw_d3d11.cpp b/src/core/gpu_hw_d3d11.cpp index 97eb39507..4b051816e 100644 --- a/src/core/gpu_hw_d3d11.cpp +++ b/src/core/gpu_hw_d3d11.cpp @@ -705,7 +705,7 @@ void GPU_HW_D3D11::UpdateDisplay() m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height, m_crtc_state.display_origin_left, m_crtc_state.display_origin_top, m_crtc_state.display_vram_width, m_crtc_state.display_vram_height, - m_crtc_state.display_aspect_ratio); + GetDisplayAspectRatio()); } } diff --git a/src/core/gpu_hw_opengl.cpp b/src/core/gpu_hw_opengl.cpp index 2284815f7..c27ee8d00 100644 --- a/src/core/gpu_hw_opengl.cpp +++ b/src/core/gpu_hw_opengl.cpp @@ -695,7 +695,7 @@ void GPU_HW_OpenGL::UpdateDisplay() m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height, m_crtc_state.display_origin_left, m_crtc_state.display_origin_top, m_crtc_state.display_vram_width, m_crtc_state.display_vram_height, - m_crtc_state.display_aspect_ratio); + GetDisplayAspectRatio()); } } diff --git a/src/core/gpu_hw_vulkan.cpp b/src/core/gpu_hw_vulkan.cpp index 1f82a979e..3074846bd 100644 --- a/src/core/gpu_hw_vulkan.cpp +++ b/src/core/gpu_hw_vulkan.cpp @@ -1031,7 +1031,7 @@ void GPU_HW_Vulkan::UpdateDisplay() m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height, m_crtc_state.display_origin_left, m_crtc_state.display_origin_top, m_crtc_state.display_vram_width, m_crtc_state.display_vram_height, - m_crtc_state.display_aspect_ratio); + GetDisplayAspectRatio()); } } diff --git a/src/core/gpu_sw.cpp b/src/core/gpu_sw.cpp index b602826cc..c0edc3601 100644 --- a/src/core/gpu_sw.cpp +++ b/src/core/gpu_sw.cpp @@ -198,7 +198,7 @@ void GPU_SW::UpdateDisplay() m_host_display->SetDisplayParameters(m_crtc_state.display_width, m_crtc_state.display_height, m_crtc_state.display_origin_left, m_crtc_state.display_origin_top, m_crtc_state.display_vram_width, m_crtc_state.display_vram_height, - m_crtc_state.display_aspect_ratio); + GetDisplayAspectRatio()); } else { diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index 7f4218c37..afacd4bb4 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -436,10 +436,11 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetBoolValue("GPU", "PGXPCPU", false); si.SetStringValue("Display", "CropMode", Settings::GetDisplayCropModeName(Settings::DEFAULT_DISPLAY_CROP_MODE)); - si.SetIntValue("Display", "OverscanActiveStartOffset", 0); - si.SetIntValue("Display", "OverscanActiveEndOffset", 0); + si.SetIntValue("Display", "ActiveStartOffset", 0); + si.SetIntValue("Display", "ActiveEndOffset", 0); si.SetStringValue("Display", "AspectRatio", Settings::GetDisplayAspectRatioName(Settings::DEFAULT_DISPLAY_ASPECT_RATIO)); + si.SetBoolValue("Display", "Force4_3For24Bit", false); si.SetBoolValue("Display", "LinearFiltering", true); si.SetBoolValue("Display", "IntegerScaling", false); si.SetBoolValue("Display", "PostProcessing", false); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 06eb72176..50fb0ce3e 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -126,6 +126,7 @@ void Settings::Load(SettingsInterface& si) ParseDisplayAspectRatio( si.GetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(DEFAULT_DISPLAY_ASPECT_RATIO)).c_str()) .value_or(DEFAULT_DISPLAY_ASPECT_RATIO); + display_force_4_3_for_24bit = si.GetBoolValue("Display", "Force4_3For24Bit", false); display_active_start_offset = static_cast(si.GetIntValue("Display", "ActiveStartOffset", 0)); display_active_end_offset = static_cast(si.GetIntValue("Display", "ActiveEndOffset", 0)); display_linear_filtering = si.GetBoolValue("Display", "LinearFiltering", true); @@ -239,6 +240,7 @@ void Settings::Save(SettingsInterface& si) const si.SetStringValue("Display", "CropMode", GetDisplayCropModeName(display_crop_mode)); si.SetIntValue("Display", "ActiveStartOffset", display_active_start_offset); si.SetIntValue("Display", "ActiveEndOffset", display_active_end_offset); + si.SetBoolValue("Display", "Force4_3For24Bit", display_force_4_3_for_24bit); si.SetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(display_aspect_ratio)); si.SetBoolValue("Display", "LinearFiltering", display_linear_filtering); si.SetBoolValue("Display", "IntegerScaling", display_integer_scaling); diff --git a/src/core/settings.h b/src/core/settings.h index ed2879bbe..690621c53 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -104,6 +104,7 @@ struct Settings s16 display_active_start_offset = 0; s16 display_active_end_offset = 0; DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::R4_3; + bool display_force_4_3_for_24bit = false; bool display_linear_filtering = true; bool display_integer_scaling = false; bool display_post_processing = false; diff --git a/src/duckstation-libretro/libretro_host_interface.cpp b/src/duckstation-libretro/libretro_host_interface.cpp index f9c7c5ab0..8a3fd657a 100644 --- a/src/duckstation-libretro/libretro_host_interface.cpp +++ b/src/duckstation-libretro/libretro_host_interface.cpp @@ -445,7 +445,7 @@ void LibretroHostInterface::OnSystemDestroyed() m_using_hardware_renderer = false; } -static std::array s_option_definitions = {{ +static std::array s_option_definitions = {{ {"duckstation_Console.Region", "Console Region", "Determines which region/hardware to emulate. Auto-Detect will use the region of the disc inserted.", @@ -547,6 +547,11 @@ static std::array s_option_definitions = {{ "others will break.", {{"true", "Enabled"}, {"false", "Disabled"}}, "false"}, + {"duckstation_Display.Force4_3For24Bit", + "Force 4:3 For 24-Bit Display", + "Switches back to 4:3 display aspect ratio when displaying 24-bit content, usually FMVs.", + {{"true", "Enabled"}, {"false", "Disabled"}}, + "false"}, {"duckstation_GPU.TextureFilter", "Texture Filtering", "Smooths out the blockyness of magnified textures on 3D object by using bilinear filtering. Will have a " diff --git a/src/duckstation-qt/enhancementsettingswidget.cpp b/src/duckstation-qt/enhancementsettingswidget.cpp index cdaefc717..0d226906a 100644 --- a/src/duckstation-qt/enhancementsettingswidget.cpp +++ b/src/duckstation-qt/enhancementsettingswidget.cpp @@ -17,6 +17,7 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(QtHostInterface* host_inter SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.scaledDithering, "GPU", "ScaledDithering"); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.disableInterlacing, "GPU", "DisableInterlacing"); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.forceNTSCTimings, "GPU", "ForceNTSCTimings"); + SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.force43For24Bit, "Display", "Force4_3For24Bit"); SettingWidgetBinder::BindWidgetToEnumSetting( m_host_interface, m_ui.textureFiltering, "GPU", "TextureFilter", &Settings::ParseTextureFilterName, &Settings::GetTextureFilterDisplayName, Settings::DEFAULT_GPU_TEXTURE_FILTER); @@ -63,6 +64,9 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(QtHostInterface* host_inter "have a speed tied to the framerate, this will result in the game running " "approximately 17% faster.
For variable " "frame rate games, it may not affect the speed.")); + dialog->registerWidgetHelp( + m_ui.force43For24Bit, tr("Force 4:3 For 24-bit Display"), tr("Unchecked"), + tr("Switches back to 4:3 display aspect ratio when displaying 24-bit content, usually FMVs.")); dialog->registerWidgetHelp( m_ui.textureFiltering, tr("Texture Filtering"), tr("Unchecked"), tr("Smooths out the blockyness of magnified textures on 3D object by using bilinear filtering.
Will have a " diff --git a/src/duckstation-qt/enhancementsettingswidget.ui b/src/duckstation-qt/enhancementsettingswidget.ui index 02b04fa8f..4baec1a8e 100644 --- a/src/duckstation-qt/enhancementsettingswidget.ui +++ b/src/duckstation-qt/enhancementsettingswidget.ui @@ -96,6 +96,13 @@ + + + + Force 4:3 For 24-Bit Display (disable widescreen for FMVs) + + + diff --git a/src/duckstation-sdl/sdl_host_interface.cpp b/src/duckstation-sdl/sdl_host_interface.cpp index 21e18c6ca..d1c306177 100644 --- a/src/duckstation-sdl/sdl_host_interface.cpp +++ b/src/duckstation-sdl/sdl_host_interface.cpp @@ -1432,6 +1432,7 @@ void SDLHostInterface::DrawSettingsWindow() settings_changed |= ImGui::Checkbox("Disable Interlacing", &m_settings_copy.gpu_disable_interlacing); settings_changed |= ImGui::Checkbox("Force NTSC Timings", &m_settings_copy.gpu_force_ntsc_timings); settings_changed |= ImGui::Checkbox("Widescreen Hack", &m_settings_copy.gpu_widescreen_hack); + settings_changed |= ImGui::Checkbox("Force 4:3 For 24-Bit Display", &m_settings_copy.display_force_4_3_for_24bit); settings_changed |= ImGui::Checkbox("PGXP Enabled", &m_settings_copy.gpu_pgxp_enable); settings_changed |= ImGui::Checkbox("PGXP Culling", &m_settings_copy.gpu_pgxp_culling);