From 5c1c467e3812de919514fb11135c26c64ceb63e2 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 18 Jul 2020 00:25:08 +1000 Subject: [PATCH] GTE: Add widescreen hack --- README.md | 1 + src/core/cpu_core.h | 3 +++ src/core/gte.cpp | 5 ++++- src/core/gte.h | 3 +++ src/core/host_interface.cpp | 5 +++++ src/core/settings.cpp | 10 ++++++---- src/core/settings.h | 1 + src/core/system.cpp | 6 +++++- 8 files changed, 28 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e0ee7f745..f7099b747 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ A "BIOS" ROM image is required to to start the emulator and to play games. You c ## Latest News +- 2020/07/18: Widescreen hack enhancement added. - 2020/07/04: Vulkan renderer now available in libretro core. - 2020/07/02: Now available as a libretro core. - 2020/07/01: Lightgun support with custom crosshairs. diff --git a/src/core/cpu_core.h b/src/core/cpu_core.h index ce07632be..b097f4dd4 100644 --- a/src/core/cpu_core.h +++ b/src/core/cpu_core.h @@ -54,6 +54,9 @@ public: ALWAYS_INLINE TickCount GetDowncount() const { return m_downcount; } ALWAYS_INLINE void SetDowncount(TickCount downcount) { m_downcount = downcount; } + ALWAYS_INLINE const GTE::Core& GetCop2() const { return m_cop2; } + ALWAYS_INLINE GTE::Core& GetCop2() { return m_cop2; } + // Sets the PC and flushes the pipeline. void SetPC(u32 new_pc); diff --git a/src/core/gte.cpp b/src/core/gte.cpp index 10c68dbf6..e7fa80c7c 100644 --- a/src/core/gte.cpp +++ b/src/core/gte.cpp @@ -578,7 +578,10 @@ void Core::RTPS(const s16 V[3], u8 shift, bool lm, bool last) // MAC0=(((H*20000h/SZ3)+1)/2)*IR1+OFX, SX2=MAC0/10000h ;ScrX FIFO -400h..+3FFh // MAC0=(((H*20000h/SZ3)+1)/2)*IR2+OFY, SY2=MAC0/10000h ;ScrY FIFO -400h..+3FFh const s64 result = static_cast(ZeroExtend64(UNRDivide(m_regs.H, m_regs.SZ3))); - const s64 Sx = s64(result) * s64(m_regs.IR1) + s64(m_regs.OFX); + + // (4 / 3) / (16 / 9) -> 0.75 -> (3 / 4) + const s64 Sx = m_widescreen_hack ? ((((s64(result) * s64(m_regs.IR1)) * s64(3)) / s64(4)) + s64(m_regs.OFX)) : + (s64(result) * s64(m_regs.IR1) + s64(m_regs.OFX)); const s64 Sy = s64(result) * s64(m_regs.IR2) + s64(m_regs.OFY); CheckMACOverflow<0>(Sx); CheckMACOverflow<0>(Sy); diff --git a/src/core/gte.h b/src/core/gte.h index bd5a91e60..bdc37b295 100644 --- a/src/core/gte.h +++ b/src/core/gte.h @@ -21,6 +21,8 @@ public: Core(); ~Core(); + ALWAYS_INLINE void SetWidescreenHack(bool enabled) { m_widescreen_hack = enabled; } + void Initialize(); void Reset(); bool DoState(StateWrapper& sw); @@ -109,6 +111,7 @@ private: void Execute_GPF(Instruction inst); Regs m_regs = {}; + bool m_widescreen_hack = false; }; #include "gte.inl" diff --git a/src/core/host_interface.cpp b/src/core/host_interface.cpp index 9349448e4..c0ddbdbad 100644 --- a/src/core/host_interface.cpp +++ b/src/core/host_interface.cpp @@ -8,6 +8,7 @@ #include "common/log.h" #include "common/string_util.h" #include "controller.h" +#include "cpu_core.h" #include "dma.h" #include "gpu.h" #include "host_display.h" @@ -345,6 +346,7 @@ void HostInterface::SetDefaultSettings(SettingsInterface& si) si.SetBoolValue("GPU", "TextureFiltering", false); si.SetBoolValue("GPU", "DisableInterlacing", false); si.SetBoolValue("GPU", "ForceNTSCTimings", false); + si.SetBoolValue("GPU", "WidescreenHack", false); si.SetStringValue("Display", "CropMode", Settings::GetDisplayCropModeName(Settings::DEFAULT_DISPLAY_CROP_MODE)); si.SetStringValue("Display", "AspectRatio", @@ -468,6 +470,9 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings) m_system->GetDMA()->SetMaxSliceTicks(m_settings.dma_max_slice_ticks); m_system->GetDMA()->SetHaltTicks(m_settings.dma_halt_ticks); + + if (m_settings.gpu_widescreen_hack != old_settings.gpu_widescreen_hack) + m_system->GetCPU()->GetCop2().SetWidescreenHack(m_settings.gpu_widescreen_hack); } bool controllers_updated = false; diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 03ed63600..afa5e3359 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -98,6 +98,7 @@ void Settings::Load(SettingsInterface& si) gpu_texture_filtering = si.GetBoolValue("GPU", "TextureFiltering", false); gpu_disable_interlacing = si.GetBoolValue("GPU", "DisableInterlacing", false); gpu_force_ntsc_timings = si.GetBoolValue("GPU", "ForceNTSCTimings", false); + gpu_widescreen_hack = si.GetBoolValue("GPU", "WidescreenHack", false); display_crop_mode = ParseDisplayCropMode( @@ -200,6 +201,7 @@ void Settings::Save(SettingsInterface& si) const si.SetBoolValue("GPU", "TextureFiltering", gpu_texture_filtering); si.SetBoolValue("GPU", "DisableInterlacing", gpu_disable_interlacing); si.SetBoolValue("GPU", "ForceNTSCTimings", gpu_force_ntsc_timings); + si.SetBoolValue("GPU", "WidescreenHack", gpu_widescreen_hack); si.SetStringValue("Display", "CropMode", GetDisplayCropModeName(display_crop_mode)); si.SetStringValue("Display", "AspectRatio", GetDisplayAspectRatioName(display_aspect_ratio)); @@ -437,10 +439,10 @@ const char* Settings::GetDisplayCropModeDisplayName(DisplayCropMode crop_mode) return s_display_crop_mode_display_names[static_cast(crop_mode)]; } -static std::array s_display_aspect_ratio_names = - {{"4:3", "16:9", "8:7", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}}; -static constexpr std::array s_display_aspect_ratio_values = - {{4.0f / 3.0f, 16.0f / 9.0f, 8.0f / 7.0f, 2.0f / 1.0f, 1.0f, -1.0f}}; +static std::array s_display_aspect_ratio_names = { + {"4:3", "16:9", "8:7", "2:1 (VRAM 1:1)", "1:1", "PAR 1:1"}}; +static constexpr std::array s_display_aspect_ratio_values = { + {4.0f / 3.0f, 16.0f / 9.0f, 8.0f / 7.0f, 2.0f / 1.0f, 1.0f, -1.0f}}; std::optional Settings::ParseDisplayAspectRatio(const char* str) { diff --git a/src/core/settings.h b/src/core/settings.h index ad9067fcf..f78721989 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -88,6 +88,7 @@ struct Settings bool gpu_texture_filtering = false; bool gpu_disable_interlacing = false; bool gpu_force_ntsc_timings = false; + bool gpu_widescreen_hack = false; DisplayCropMode display_crop_mode = DisplayCropMode::None; DisplayAspectRatio display_aspect_ratio = DisplayAspectRatio::R4_3; bool display_linear_filtering = true; diff --git a/src/core/system.cpp b/src/core/system.cpp index 6f4012353..73ac290ef 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -242,7 +242,8 @@ bool System::Boot(const SystemBootParameters& params) bool System::InitializeComponents(bool force_software_renderer) { - if (!CreateGPU(force_software_renderer ? GPURenderer::Software : GetSettings().gpu_renderer)) + const Settings& settings = GetSettings(); + if (!CreateGPU(force_software_renderer ? GPURenderer::Software : settings.gpu_renderer)) return false; m_cpu->Initialize(m_bus.get()); @@ -261,6 +262,9 @@ bool System::InitializeComponents(bool force_software_renderer) m_spu->Initialize(this, m_dma.get(), m_interrupt_controller.get()); m_mdec->Initialize(this, m_dma.get()); + // load settings + m_cpu->GetCop2().SetWidescreenHack(settings.gpu_widescreen_hack); + UpdateThrottlePeriod(); return true; }