System: Add option to load/apply image patches

This commit is contained in:
Connor McLaughlin 2021-06-01 21:55:33 +10:00
parent 77984035d2
commit 9aa386e96c
4 changed files with 47 additions and 5 deletions

View file

@ -68,7 +68,9 @@ static bool LoadEXE(const char* filename);
static bool SetExpansionROM(const char* filename); static bool SetExpansionROM(const char* filename);
/// Opens CD image, preloading if needed. /// Opens CD image, preloading if needed.
static std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, bool force_preload); static std::unique_ptr<CDImage> 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 DoLoadState(ByteStream* stream, bool force_software_renderer, bool update_display);
static bool DoState(StateWrapper& sw, HostDisplayTexture** host_texture, 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; return true;
} }
std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, bool force_preload) std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, bool force_preload, bool check_for_patches)
{ {
std::unique_ptr<CDImage> media = CDImage::Open(path, error); std::unique_ptr<CDImage> media = CDImage::Open(path, error);
if (!media) if (!media)
@ -659,9 +661,33 @@ std::unique_ptr<CDImage> OpenCDImage(const char* path, Common::Error* error, boo
Log_WarningPrintf("Failed to preload image '%s' to RAM", path); 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; return media;
} }
bool ShouldCheckForImagePatches()
{
return g_host_interface->GetBoolSettingValue("CDROM", "LoadImagePatches", false);
}
bool Boot(const SystemBootParameters& params) bool Boot(const SystemBootParameters& params)
{ {
Assert(s_state == State::Shutdown); Assert(s_state == State::Shutdown);
@ -708,7 +734,7 @@ bool Boot(const SystemBootParameters& params)
else else
{ {
Log_InfoPrintf("Loading CD image '%s'...", params.filename.c_str()); 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) if (!media)
{ {
g_host_interface->ReportFormattedError("Failed to load CD image '%s': %s", params.filename.c_str(), 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 else
{ {
media = OpenCDImage(media_filename.c_str(), &error, false); media = OpenCDImage(media_filename.c_str(), &error, false, ShouldCheckForImagePatches());
if (!media) if (!media)
{ {
if (old_media) if (old_media)
@ -1988,7 +2014,7 @@ std::string GetMediaFileName()
bool InsertMedia(const char* path) bool InsertMedia(const char* path)
{ {
Common::Error error; Common::Error error;
std::unique_ptr<CDImage> image = OpenCDImage(path, &error, false); std::unique_ptr<CDImage> image = OpenCDImage(path, &error, false, ShouldCheckForImagePatches());
if (!image) if (!image)
{ {
g_host_interface->AddFormattedOSDMessage( g_host_interface->AddFormattedOSDMessage(

View file

@ -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.cdromRegionCheck, "CDROM", "RegionCheck", false);
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromLoadImageToRAM, "CDROM", "LoadImageToRAM", SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromLoadImageToRAM, "CDROM", "LoadImageToRAM",
false); false);
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.cdromLoadImagePatches, "CDROM",
"LoadImagePatches", false);
SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.cdromSeekSpeedup, "CDROM", "SeekSpeedup", 1); SettingWidgetBinder::BindWidgetToIntSetting(m_host_interface, m_ui.cdromSeekSpeedup, "CDROM", "SeekSpeedup", 1);
SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.multitapMode, "ControllerPorts", "MultitapMode", SettingWidgetBinder::BindWidgetToEnumSetting(m_host_interface, m_ui.multitapMode, "ControllerPorts", "MultitapMode",
&Settings::ParseMultitapModeName, &Settings::GetMultitapModeName, &Settings::ParseMultitapModeName, &Settings::GetMultitapModeName,
@ -81,6 +83,9 @@ ConsoleSettingsWidget::ConsoleSettingsWidget(QtHostInterface* host_interface, QW
m_ui.cdromLoadImageToRAM, tr("Preload Image to RAM"), tr("Unchecked"), 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 " 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.")); "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( dialog->registerWidgetHelp(
m_ui.multitapMode, tr("Multitap"), tr("Disabled"), m_ui.multitapMode, tr("Multitap"), tr("Disabled"),
tr("Enables multitap support on specified controller ports. Leave disabled for games that do " tr("Enables multitap support on specified controller ports. Leave disabled for games that do "

View file

@ -221,6 +221,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QCheckBox" name="cdromLoadImagePatches">
<property name="text">
<string>Apply Image Patches</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item row="1" column="0"> <item row="1" column="0">

View file

@ -1507,6 +1507,10 @@ void DrawSettingsWindow()
"Preload Images to RAM", "Preload Images to RAM",
"Loads the game image into RAM. Useful for network paths that may become unreliable during gameplay.", "Loads the game image into RAM. Useful for network paths that may become unreliable during gameplay.",
&s_settings_copy.cdrom_load_image_to_ram); &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"); MenuHeading("Controller Ports");