diff --git a/src/core/cheats.cpp b/src/core/cheats.cpp index 3b2388a4a..f96caff56 100644 --- a/src/core/cheats.cpp +++ b/src/core/cheats.cpp @@ -212,10 +212,12 @@ static bool ExtractCodeInfo(CodeInfoList* dst, const std::string_view file_data, static void AppendCheatToList(CodeInfoList* dst, CodeInfo code); static bool ShouldLoadDatabaseCheats(); +static bool WantsWidescreenPatch(); static bool AreAnyPatchesEnabled(); static void ReloadEnabledLists(); -static u32 EnableCheats(const CheatCodeList& patches, const EnableCodeList& enable_list, const char* section, - bool hc_mode_active); +static u32 EnablePatches(const CheatCodeList& patches, const EnableCodeList& enable_list, const char* section, + bool hc_mode_active); +static bool EnableWidescreenPatch(const CheatCodeList& patches, bool hc_mode_active); static void UpdateActiveCodes(bool reload_enabled_list, bool verbose, bool verbose_if_changed, bool show_disabled_codes); @@ -259,6 +261,7 @@ struct Locals u32 active_cheat_count = 0; bool patches_enabled = false; bool cheats_enabled = false; + bool has_widescreen_patch = false; bool database_cheat_codes_enabled = false; }; @@ -811,11 +814,21 @@ bool Cheats::ShouldLoadDatabaseCheats() return (sif && sif->GetBoolValue("Cheats", "LoadCheatsFromDatabase", true)); } +bool Cheats::WantsWidescreenPatch() +{ + return (g_settings.gpu_widescreen_rendering && g_settings.display_aspect_ratio.IsValid() && + g_settings.display_aspect_ratio != DisplayAspectRatio{4, 3}); +} + bool Cheats::AreAnyPatchesEnabled() { if (g_settings.disable_all_enhancements) return false; + // Look for widescreen patches. + if (WantsWidescreenPatch()) + return true; + // Only in the gameini. const SettingsInterface* sif = Host::Internal::GetGameSettingsLayer(); return (sif && sif->ContainsValue("Patches", "Enable")); @@ -840,8 +853,8 @@ void Cheats::ReloadEnabledLists() s_locals.enabled_patches = sif->GetStringList(PATCHES_CONFIG_SECTION, PATCH_ENABLE_CONFIG_KEY); } -u32 Cheats::EnableCheats(const CheatCodeList& patches, const EnableCodeList& enable_list, const char* section, - bool hc_mode_active) +u32 Cheats::EnablePatches(const CheatCodeList& patches, const EnableCodeList& enable_list, const char* section, + bool hc_mode_active) { u32 count = 0; for (const std::unique_ptr& p : patches) @@ -889,6 +902,38 @@ u32 Cheats::EnableCheats(const CheatCodeList& patches, const EnableCodeList& ena return count; } +bool Cheats::EnableWidescreenPatch(const CheatCodeList& patches, bool hc_mode_active) +{ + const DisplayAspectRatio ar = g_settings.display_aspect_ratio; + if (ar.numerator <= 0 || ar.denominator <= 0) + return false; + + for (const std::unique_ptr& p : patches) + { + // don't rely on the name, use the attribute instead + if (!p->GetMetadata().override_aspect_ratio.has_value() || p->GetMetadata().override_aspect_ratio.value() != ar) + continue; + + // don't load banned patches + if (p->GetMetadata().disallow_for_achievements && hc_mode_active) + continue; + + // already enabled? + if (std::find(s_locals.enabled_patches.begin(), s_locals.enabled_patches.end(), p->GetName()) != + s_locals.enabled_patches.end()) + { + return true; + } + + INFO_LOG("Enabling widescreen patch: {}", p->GetName()); + s_locals.enabled_patches.push_back(p->GetName()); + return true; + } + + WARNING_LOG("No widescreen patch found for aspect ratio {}.", Settings::GetDisplayAspectRatioName(ar)); + return false; +} + void Cheats::ReloadCheats(bool reload_files, bool reload_enabled_list, bool verbose, bool verbose_if_changed, bool show_disabled_codes) { @@ -954,6 +999,7 @@ void Cheats::UnloadAll() s_locals.patch_codes = CheatCodeList(); s_locals.patches_enabled = false; s_locals.cheats_enabled = false; + s_locals.has_widescreen_patch = false; s_locals.database_cheat_codes_enabled = false; } @@ -1015,10 +1061,12 @@ void Cheats::UpdateActiveCodes(bool reload_enabled_list, bool verbose, bool verb if (!g_settings.disable_all_enhancements) { + s_locals.has_widescreen_patch = + WantsWidescreenPatch() && EnableWidescreenPatch(s_locals.patch_codes, hc_mode_active); s_locals.active_patch_count = - EnableCheats(s_locals.patch_codes, s_locals.enabled_patches, "Patches", hc_mode_active); + EnablePatches(s_locals.patch_codes, s_locals.enabled_patches, "Patches", hc_mode_active); s_locals.active_cheat_count = - AreCheatsEnabled() ? EnableCheats(s_locals.cheat_codes, s_locals.enabled_cheats, "Cheats", hc_mode_active) : 0; + AreCheatsEnabled() ? EnablePatches(s_locals.cheat_codes, s_locals.enabled_cheats, "Cheats", hc_mode_active) : 0; } // Display message on first boot when we load patches. @@ -1126,6 +1174,11 @@ u32 Cheats::GetActiveCheatCount() return s_locals.active_cheat_count; } +bool Cheats::IsWidescreenPatchActive() +{ + return s_locals.has_widescreen_patch; +} + ////////////////////////////////////////////////////////////////////////// // File Parsing ////////////////////////////////////////////////////////////////////////// diff --git a/src/core/cheats.h b/src/core/cheats.h index 2cd927bc2..fdf568cbf 100644 --- a/src/core/cheats.h +++ b/src/core/cheats.h @@ -158,6 +158,9 @@ extern u32 GetActivePatchCount(); /// Returns the number of active cheats. extern u32 GetActiveCheatCount(); +/// Returns true if the widescreen patch is active. +extern bool IsWidescreenPatchActive(); + // Config sections/keys to use to enable patches. extern const char* PATCHES_CONFIG_SECTION; extern const char* CHEATS_CONFIG_SECTION; diff --git a/src/core/game_database.cpp b/src/core/game_database.cpp index 9f554427c..0adc287f0 100644 --- a/src/core/game_database.cpp +++ b/src/core/game_database.cpp @@ -728,9 +728,10 @@ void GameDatabase::Entry::ApplySettings(Settings& settings, bool display_osd_mes if (HasTrait(Trait::DisableWidescreen)) { - if (display_osd_messages && settings.gpu_widescreen_hack) + if (display_osd_messages && settings.gpu_widescreen_rendering) APPEND_MESSAGE(TRANSLATE_SV("GameDatabase", "Widescreen rendering disabled.")); + settings.gpu_widescreen_rendering = false; settings.gpu_widescreen_hack = false; } diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 808c1a5bb..0c348f979 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -285,7 +285,7 @@ void Settings::Load(const SettingsInterface& si, const SettingsInterface& contro ParseForceVideoTimingName( si.GetStringValue("GPU", "ForceVideoTiming", GetForceVideoTimingName(DEFAULT_FORCE_VIDEO_TIMING_MODE)).c_str()) .value_or(DEFAULT_FORCE_VIDEO_TIMING_MODE); - gpu_widescreen_hack = si.GetBoolValue("GPU", "WidescreenHack", false); + gpu_widescreen_rendering = gpu_widescreen_hack = si.GetBoolValue("GPU", "WidescreenHack", false); gpu_texture_cache = si.GetBoolValue("GPU", "EnableTextureCache", false); display_24bit_chroma_smoothing = si.GetBoolValue("GPU", "ChromaSmoothing24Bit", false); gpu_pgxp_enable = si.GetBoolValue("GPU", "PGXPEnable", false); @@ -643,7 +643,7 @@ void Settings::Save(SettingsInterface& si, bool ignore_base) const si.SetUIntValue("GPU", "DownsampleScale", gpu_downsample_scale); si.SetStringValue("GPU", "WireframeMode", GetGPUWireframeModeName(gpu_wireframe_mode)); si.SetStringValue("GPU", "ForceVideoTiming", GetForceVideoTimingName(gpu_force_video_timing)); - si.SetBoolValue("GPU", "WidescreenHack", gpu_widescreen_hack); + si.SetBoolValue("GPU", "WidescreenHack", gpu_widescreen_rendering); si.SetBoolValue("GPU", "EnableTextureCache", gpu_texture_cache); si.SetBoolValue("GPU", "ChromaSmoothing24Bit", display_24bit_chroma_smoothing); si.SetBoolValue("GPU", "PGXPEnable", gpu_pgxp_enable); @@ -1048,6 +1048,7 @@ void Settings::ApplySettingRestrictions() g_settings.gpu_dithering_mode = GPUDitheringMode::Unscaled; g_settings.gpu_line_detect_mode = GPULineDetectMode::Disabled; g_settings.gpu_force_video_timing = ForceVideoTimingMode::Disabled; + g_settings.gpu_widescreen_rendering = false; g_settings.gpu_widescreen_hack = false; g_settings.gpu_texture_cache = false; g_settings.gpu_pgxp_enable = false; diff --git a/src/core/settings.h b/src/core/settings.h index 3a53f8d8c..6da1c15de 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -113,6 +113,7 @@ struct GPUSettings bool gpu_per_sample_shading : 1 = false; bool gpu_scaled_interlacing : 1 = true; bool gpu_force_round_texcoords : 1 = false; + bool gpu_widescreen_rendering : 1 = false; bool gpu_widescreen_hack : 1 = false; bool gpu_texture_cache : 1 = false; bool gpu_show_vram : 1 = false; diff --git a/src/core/system.cpp b/src/core/system.cpp index 3d33c608e..c44ffaa76 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1395,6 +1395,20 @@ void System::ApplySettings(bool display_osd_messages) LoadSettings(false); } + // Reload patches if widescreen rendering setting changed. + if (IsValid() && + (g_settings.gpu_widescreen_rendering != old_settings.gpu_widescreen_rendering || + (g_settings.gpu_widescreen_rendering && g_settings.display_aspect_ratio != old_settings.display_aspect_ratio))) + { + const bool prev_widescreen_patch = Cheats::IsWidescreenPatchActive(); + Cheats::ReloadCheats(false, true, false, true, true); + if (prev_widescreen_patch != Cheats::IsWidescreenPatchActive() || + g_settings.display_aspect_ratio != old_settings.display_aspect_ratio) + { + LoadSettings(false); + } + } + CheckForSettingsChanges(old_settings); Host::CheckForSettingsChanges(old_settings); } diff --git a/src/core/types.h b/src/core/types.h index cbec6fd0d..ca1a2aa91 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -318,7 +318,7 @@ enum class ForceVideoTimingMode : u8 Disabled, NTSC, PAL, - + Count, }; @@ -346,4 +346,5 @@ struct DisplayAspectRatio { return (std::memcmp(this, &rhs, sizeof(DisplayAspectRatio)) != 0); } + ALWAYS_INLINE bool IsValid() const { return (numerator > 0 && denominator > 0); } };