From 9aa386e96cad6d07d00cdb9f75159ceca294bc4a Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Tue, 1 Jun 2021 21:55:33 +1000 Subject: [PATCH] System: Add option to load/apply image patches --- src/core/system.cpp | 36 +++++++++++++++++--- src/duckstation-qt/consolesettingswidget.cpp | 5 +++ src/duckstation-qt/consolesettingswidget.ui | 7 ++++ src/frontend-common/fullscreen_ui.cpp | 4 +++ 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/core/system.cpp b/src/core/system.cpp index a812b7c43..4e814f4e5 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -68,7 +68,9 @@ static bool LoadEXE(const char* filename); static bool SetExpansionROM(const char* filename); /// Opens CD image, preloading if needed. -static std::unique_ptr OpenCDImage(const char* path, Common::Error* error, bool force_preload); +static std::unique_ptr OpenCDImage(const char* path, Common::Error* error, bool force_preload, + bool check_for_patches); +static bool ShouldCheckForImagePatches(); static bool DoLoadState(ByteStream* stream, bool force_software_renderer, bool update_display); static bool DoState(StateWrapper& sw, HostDisplayTexture** host_texture, bool update_display); @@ -643,7 +645,7 @@ bool RecreateGPU(GPURenderer renderer, bool update_display /* = true*/) return true; } -std::unique_ptr OpenCDImage(const char* path, Common::Error* error, bool force_preload) +std::unique_ptr OpenCDImage(const char* path, Common::Error* error, bool force_preload, bool check_for_patches) { std::unique_ptr media = CDImage::Open(path, error); if (!media) @@ -659,9 +661,33 @@ std::unique_ptr OpenCDImage(const char* path, Common::Error* error, boo Log_WarningPrintf("Failed to preload image '%s' to RAM", path); } + if (check_for_patches) + { + const std::string ppf_filename(FileSystem::BuildRelativePath( + path, FileSystem::ReplaceExtension(FileSystem::GetDisplayNameFromPath(path), "ppf"))); + if (FileSystem::FileExists(ppf_filename.c_str())) + { + media = CDImage::OverlayPPFPatch(ppf_filename.c_str(), std::move(media)); + if (!media) + { + g_host_interface->AddFormattedOSDMessage( + 30.0f, + g_host_interface->TranslateString("OSDMessage", + "Failed to apply ppf patch from '%s', using unpatched image."), + ppf_filename.c_str()); + return OpenCDImage(path, error, force_preload, false); + } + } + } + return media; } +bool ShouldCheckForImagePatches() +{ + return g_host_interface->GetBoolSettingValue("CDROM", "LoadImagePatches", false); +} + bool Boot(const SystemBootParameters& params) { Assert(s_state == State::Shutdown); @@ -708,7 +734,7 @@ bool Boot(const SystemBootParameters& params) else { Log_InfoPrintf("Loading CD image '%s'...", params.filename.c_str()); - media = OpenCDImage(params.filename.c_str(), &error, params.load_image_to_ram); + media = OpenCDImage(params.filename.c_str(), &error, params.load_image_to_ram, ShouldCheckForImagePatches()); if (!media) { g_host_interface->ReportFormattedError("Failed to load CD image '%s': %s", params.filename.c_str(), @@ -1175,7 +1201,7 @@ bool DoLoadState(ByteStream* state, bool force_software_renderer, bool update_di } else { - media = OpenCDImage(media_filename.c_str(), &error, false); + media = OpenCDImage(media_filename.c_str(), &error, false, ShouldCheckForImagePatches()); if (!media) { if (old_media) @@ -1988,7 +2014,7 @@ std::string GetMediaFileName() bool InsertMedia(const char* path) { Common::Error error; - std::unique_ptr image = OpenCDImage(path, &error, false); + std::unique_ptr image = OpenCDImage(path, &error, false, ShouldCheckForImagePatches()); if (!image) { g_host_interface->AddFormattedOSDMessage( diff --git a/src/duckstation-qt/consolesettingswidget.cpp b/src/duckstation-qt/consolesettingswidget.cpp index b9445ef7a..4f405c8e7 100644 --- a/src/duckstation-qt/consolesettingswidget.cpp +++ b/src/duckstation-qt/consolesettingswidget.cpp @@ -41,6 +41,8 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromRegionCheck, "CDROM", "RegionCheck", false); SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromLoadImageToRAM, "CDROM", "LoadImageToRAM", false); + SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromLoadImagePatches, "CDROM", + "LoadImagePatches", false); SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.cdromSeekSpeedup, "CDROM", "SeekSpeedup", 1); SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.multitapMode, "ControllerPorts", "MultitapMode", &Settings::ParseMultitapModeName, &Settings::GetMultitapModeName, @@ -81,6 +83,9 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW m_ui.cdromLoadImageToRAM, tr("Preload Image to RAM"), tr("Unchecked"), tr("Loads the game image into RAM. Useful for network paths that may become unreliable during gameplay. In some " "cases also eliminates stutter when games initiate audio track playback.")); + dialog->registerWidgetHelp(m_ui.cdromLoadImagePatches, tr("Apply Image Patches"), tr("Unchecked"), + tr("Automatically applies patches to disc images when they are present in the same " + "directory. Currently only PPF patches are supported with this option.")); dialog->registerWidgetHelp( m_ui.multitapMode, tr("Multitap"), tr("Disabled"), tr("Enables multitap support on specified controller ports. Leave disabled for games that do " diff --git a/src/duckstation-qt/consolesettingswidget.ui b/src/duckstation-qt/consolesettingswidget.ui index b905e3c54..2727f1abc 100644 --- a/src/duckstation-qt/consolesettingswidget.ui +++ b/src/duckstation-qt/consolesettingswidget.ui @@ -221,6 +221,13 @@ + + + + Apply Image Patches + + + diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp index c20d718e4..b0756aa78 100644 --- a/src/frontend-common/fullscreen_ui.cpp +++ b/src/frontend-common/fullscreen_ui.cpp @@ -1507,6 +1507,10 @@ void DrawSettingsWindow() "Preload Images to RAM", "Loads the game image into RAM. Useful for network paths that may become unreliable during gameplay.", &s_settings_copy.cdrom_load_image_to_ram); + settings_changed |= ToggleButtonForNonSetting( + "Apply Image Patches", + "Automatically applies patches to disc images when they are present, currently only PPF is supported.", + "CDROM", "LoadImagePatches", false); MenuHeading("Controller Ports");