From ca14e53c4aa719eed23916405aa54dec0b7d35cd Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Wed, 11 Nov 2020 00:14:58 +1000 Subject: [PATCH] GTE: Make widescreen hack use display aspect ratio --- README.md | 1 + src/core/gte.cpp | 98 ++++++++++++++++++- .../libretro_host_interface.cpp | 4 +- .../enhancementsettingswidget.cpp | 12 +-- .../enhancementsettingswidget.ui | 2 +- 5 files changed, 103 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 36807ae73..e1e410bb8 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ A "BIOS" ROM image is required to to start the emulator and to play games. You c ## Latest News +- 2020/11/10: Widescreen hack now renders in the display aspect ratio instead of always 16:9. - 2020/11/01: Exclusive fullscreen option added for Windows D3D11 users. Enjoy buttery smooth PAL games. - 2020/10/31: Multisample antialiasing added as an enhancement. - 2020/10/30: Option to use analog stick as d-pad for analog controller added. diff --git a/src/core/gte.cpp b/src/core/gte.cpp index 006d0aa2c..c9dd2eb5d 100644 --- a/src/core/gte.cpp +++ b/src/core/gte.cpp @@ -613,10 +613,52 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last) // MAC0=(((H*20000h/SZ3)+1)/2)*IR2+OFY, SY2=MAC0/10000h ;ScrY FIFO -400h..+3FFh const s64 result = static_cast(ZeroExtend64(UNRDivide(REGS.H, REGS.SZ3))); - // (4 / 3) / (16 / 9) -> 0.75 -> (3 / 4) - const s64 Sx = g_settings.gpu_widescreen_hack ? - ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(4)) + s64(REGS.OFX)) : - (s64(result) * s64(REGS.IR1) + s64(REGS.OFX)); + s64 Sx; + if (g_settings.gpu_widescreen_hack) + { + const DisplayAspectRatio ar = g_settings.display_aspect_ratio; + switch (ar) + { + case DisplayAspectRatio::R16_9: + Sx = ((((s64(result) * s64(REGS.IR1)) * s64(3)) / s64(4)) + s64(REGS.OFX)); + break; + + case DisplayAspectRatio::R16_10: + Sx = ((((s64(result) * s64(REGS.IR1)) * s64(5)) / s64(6)) + s64(REGS.OFX)); + break; + + case DisplayAspectRatio::R19_9: + Sx = ((((s64(result) * s64(REGS.IR1)) * s64(12)) / s64(19)) + s64(REGS.OFX)); + break; + + case DisplayAspectRatio::R21_9: + Sx = ((((s64(result) * s64(REGS.IR1)) * s64(4)) / s64(7)) + s64(REGS.OFX)); + break; + + case DisplayAspectRatio::R8_7: + Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX)); + break; + + case DisplayAspectRatio::R2_1: + Sx = ((((s64(result) * s64(REGS.IR1)) * s64(2)) / s64(3)) + s64(REGS.OFX)); + break; + + case DisplayAspectRatio::R1_1: + Sx = ((((s64(result) * s64(REGS.IR1)) * s64(7)) / s64(6)) + s64(REGS.OFX)); + break; + + case DisplayAspectRatio::R4_3: + case DisplayAspectRatio::PAR1_1: + default: + Sx = (s64(result) * s64(REGS.IR1) + s64(REGS.OFX)); + break; + } + } + else + { + Sx = (s64(result) * s64(REGS.IR1) + s64(REGS.OFX)); + } + const s64 Sy = s64(result) * s64(REGS.IR2) + s64(REGS.OFY); CheckMACOverflow<0>(Sx); CheckMACOverflow<0>(Sy); @@ -654,7 +696,53 @@ static void RTPS(const s16 V[3], u8 shift, bool lm, bool last) const float precise_h_div_sz = float(REGS.H) / precise_z; const float fofx = float(REGS.OFX) / float(1 << 16); const float fofy = float(REGS.OFY) / float(1 << 16); - float precise_x = fofx + (precise_ir1 * precise_h_div_sz) * ((g_settings.gpu_widescreen_hack) ? 0.75f : 1.00f); + float precise_x; + if (g_settings.gpu_widescreen_hack) + { + precise_x = precise_ir1 * precise_h_div_sz; + const DisplayAspectRatio ar = g_settings.display_aspect_ratio; + switch (ar) + { + case DisplayAspectRatio::R16_9: + precise_x = (precise_x * 3.0f) / 4.0f; + break; + + case DisplayAspectRatio::R16_10: + precise_x = (precise_x * 5.0f) / 6.0f; + break; + + case DisplayAspectRatio::R19_9: + precise_x = (precise_x * 12.0f) / 19.0f; + break; + + case DisplayAspectRatio::R21_9: + precise_x = (precise_x * 4.0f) / 7.0f; + break; + + case DisplayAspectRatio::R8_7: + precise_x = (precise_x * 7.0f) / 6.0f; + break; + + case DisplayAspectRatio::R2_1: + precise_x = (precise_x * 2.0f) / 3.0f; + break; + + case DisplayAspectRatio::R1_1: + precise_x = (precise_x * 7.0f) / 6.0f; + break; + + case DisplayAspectRatio::R4_3: + case DisplayAspectRatio::PAR1_1: + default: + break; + } + precise_x += fofx; + } + else + { + precise_x = fofx + (precise_ir1 * precise_h_div_sz); + } + float precise_y = fofy + (precise_ir2 * precise_h_div_sz); precise_x = std::clamp(precise_x, -1024.0f, 1023.0f); diff --git a/src/duckstation-libretro/libretro_host_interface.cpp b/src/duckstation-libretro/libretro_host_interface.cpp index 76cb40e2f..d47f7981b 100644 --- a/src/duckstation-libretro/libretro_host_interface.cpp +++ b/src/duckstation-libretro/libretro_host_interface.cpp @@ -624,8 +624,8 @@ static std::array s_option_definitions = {{ "Nearest"}, {"duckstation_GPU.WidescreenHack", "Widescreen Hack", - "Increases the field of view from 4:3 to 16:9 in 3D games. For 2D games, or games which use pre-rendered " - "backgrounds, this enhancement will not work as expected.", + "Increases the field of view from 4:3 to the chosen display aspect ratio in 3D games. For 2D games, or games which " + "use pre-rendered backgrounds, this enhancement will not work as expected.", {{"true", "Enabled"}, {"false", "Disabled"}}, "false"}, {"duckstation_GPU.PGXPEnable", diff --git a/src/duckstation-qt/enhancementsettingswidget.cpp b/src/duckstation-qt/enhancementsettingswidget.cpp index 621a1b7bb..e2058b25f 100644 --- a/src/duckstation-qt/enhancementsettingswidget.cpp +++ b/src/duckstation-qt/enhancementsettingswidget.cpp @@ -20,9 +20,9 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(QtHostInterface* host_inter SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.force43For24Bit, "Display", "Force4_3For24Bit"); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.chromaSmoothingFor24Bit, "GPU", "ChromaSmoothing24Bit"); - SettingWidgetBinder::BindWidgetToEnumSetting( - m_host_interface, m_ui.textureFiltering, "GPU", "TextureFilter", &Settings::ParseTextureFilterName, - &Settings::GetTextureFilterName, Settings::DEFAULT_GPU_TEXTURE_FILTER); + SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.textureFiltering, "GPU", "TextureFilter", + &Settings::ParseTextureFilterName, &Settings::GetTextureFilterName, + Settings::DEFAULT_GPU_TEXTURE_FILTER); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.widescreenHack, "GPU", "WidescreenHack"); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.pgxpEnable, "GPU", "PGXPEnable", false); @@ -88,9 +88,9 @@ EnhancementSettingsWidget::EnhancementSettingsWidget(QtHostInterface* host_inter dialog->registerWidgetHelp( m_ui.widescreenHack, tr("Widescreen Hack"), tr("Unchecked"), tr("Scales vertex positions in screen-space to a widescreen aspect ratio, essentially " - "increasing the field of view from 4:3 to 16:9 in 3D games.
For 2D games, or games which " - "use pre-rendered backgrounds, this enhancement will not work as expected.
May not be compatible with " - "all games.")); + "increasing the field of view from 4:3 to the chosen display aspect ratio in 3D games.
For 2D games, or " + "games which use pre-rendered backgrounds, this enhancement will not work as expected.
May not be " + "compatible with all games.")); dialog->registerWidgetHelp( m_ui.pgxpEnable, tr("Geometry Correction"), tr("Unchecked"), tr("Reduces \"wobbly\" polygons and \"warping\" textures that are common in PS1 games.
Only " diff --git a/src/duckstation-qt/enhancementsettingswidget.ui b/src/duckstation-qt/enhancementsettingswidget.ui index 5e3be01ed..2b5359720 100644 --- a/src/duckstation-qt/enhancementsettingswidget.ui +++ b/src/duckstation-qt/enhancementsettingswidget.ui @@ -69,7 +69,7 @@ - Widescreen Hack (render 3D in 16:9) + Widescreen Hack (render 3D in display aspect ratio)