Skip to content

Commit

Permalink
Patch: Re-run PPT_ONCE_ON_LOAD patches when enabling them as the game…
Browse files Browse the repository at this point in the history
… is running
  • Loading branch information
CookiePLMonster authored and F0bes committed Jan 8, 2025
1 parent 7ebcca3 commit 3b5b3ff
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 12 deletions.
52 changes: 43 additions & 9 deletions pcsx2/Patch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ namespace Patch
static bool PatchStringHasUnlabelledPatch(const std::string& pnach_data);
static void ExtractPatchInfo(PatchInfoList* dst, const std::string& pnach_data, u32* num_unlabelled_patches);
static void ReloadEnabledLists();
static u32 EnablePatches(const PatchList& patches, const EnablePatchList& enable_list);
static u32 EnablePatches(const PatchList& patches, const EnablePatchList& enable_list, const EnablePatchList& enable_immediately_list);

static void ApplyPatch(const PatchCommand* p);
static void ApplyDynaPatch(const DynamicPatch& patch, u32 address);
Expand All @@ -183,6 +183,8 @@ namespace Patch
static std::vector<DynamicPatch> s_active_pnach_dynamic_patches;
static EnablePatchList s_enabled_cheats;
static EnablePatchList s_enabled_patches;
static EnablePatchList s_just_enabled_cheats;
static EnablePatchList s_just_enabled_patches;
static u32 s_patches_crc;
static std::optional<AspectRatioType> s_override_aspect_ratio;
static std::optional<GSInterlaceMode> s_override_interlace_mode;
Expand Down Expand Up @@ -583,13 +585,13 @@ std::string Patch::GetPnachFilename(const std::string_view serial, u32 crc, bool

void Patch::ReloadEnabledLists()
{
const EnablePatchList prev_enabled_cheats = std::move(s_enabled_cheats);
if (EmuConfig.EnableCheats && !Achievements::IsHardcoreModeActive())
s_enabled_cheats = Host::GetStringListSetting(CHEATS_CONFIG_SECTION, PATCH_ENABLE_CONFIG_KEY);
else
s_enabled_cheats = {};

s_enabled_patches = Host::GetStringListSetting(PATCHES_CONFIG_SECTION, PATCH_ENABLE_CONFIG_KEY);

const EnablePatchList prev_enabled_patches = std::exchange(s_enabled_patches, Host::GetStringListSetting(PATCHES_CONFIG_SECTION, PATCH_ENABLE_CONFIG_KEY));
const EnablePatchList disabled_patches = Host::GetStringListSetting(PATCHES_CONFIG_SECTION, PATCH_DISABLE_CONFIG_KEY);

// Name based matching for widescreen/NI settings.
Expand Down Expand Up @@ -621,10 +623,29 @@ void Patch::ReloadEnabledLists()
++it;
}
}

s_just_enabled_cheats.clear();
s_just_enabled_patches.clear();
for (const auto& p : s_enabled_cheats)
{
if (std::find(prev_enabled_cheats.begin(), prev_enabled_cheats.end(), p) == prev_enabled_cheats.end())
{
s_just_enabled_cheats.emplace_back(p);
}
}
for (const auto& p : s_enabled_patches)
{
if (std::find(prev_enabled_patches.begin(), prev_enabled_patches.end(), p) == prev_enabled_patches.end())
{
s_just_enabled_patches.emplace_back(p);
}
}
}

u32 Patch::EnablePatches(const PatchList& patches, const EnablePatchList& enable_list)
u32 Patch::EnablePatches(const PatchList& patches, const EnablePatchList& enable_list, const EnablePatchList& enable_immediately_list)
{
ActivePatchList patches_to_apply_immediately;

u32 count = 0;
for (const PatchGroup& p : patches)
{
Expand All @@ -636,13 +657,16 @@ u32 Patch::EnablePatches(const PatchList& patches, const EnablePatchList& enable
Console.WriteLn(Color_Green, fmt::format("Enabled patch: {}",
p.name.empty() ? std::string_view("<unknown>") : std::string_view(p.name)));

const bool apply_immediately = std::find(enable_immediately_list.begin(), enable_immediately_list.end(), p.name) != enable_immediately_list.end();
for (const PatchCommand& ip : p.patches)
{
// print the actual patch lines only in verbose mode (even in devel)
if (Log::GetMaxLevel() >= LOGLEVEL_DEV)
DevCon.WriteLnFmt(" {}", ip.ToString());

s_active_patches.push_back(&ip);
if (apply_immediately && ip.placetopatch == PPT_ONCE_ON_LOAD)
patches_to_apply_immediately.push_back(&ip);
}

for (const DynamicPatch& dp : p.dpatches)
Expand All @@ -659,6 +683,16 @@ u32 Patch::EnablePatches(const PatchList& patches, const EnablePatchList& enable
count += p.name.empty() ? (static_cast<u32>(p.patches.size()) + static_cast<u32>(p.dpatches.size())) : 1;
}

if (!patches_to_apply_immediately.empty())
{
Host::RunOnCPUThread([patches = std::move(patches_to_apply_immediately)]() {
for (const PatchCommand* i : patches)
{
ApplyPatch(i);
}
});
}

return count;
}

Expand Down Expand Up @@ -703,10 +737,10 @@ void Patch::ReloadPatches(const std::string& serial, u32 crc, bool reload_files,
});
}

UpdateActivePatches(reload_enabled_list, verbose, verbose_if_changed);
UpdateActivePatches(reload_enabled_list, verbose, verbose_if_changed, false);
}

void Patch::UpdateActivePatches(bool reload_enabled_list, bool verbose, bool verbose_if_changed)
void Patch::UpdateActivePatches(bool reload_enabled_list, bool verbose, bool verbose_if_changed, bool apply_new_patches)
{
if (reload_enabled_list)
ReloadEnabledLists();
Expand All @@ -721,19 +755,19 @@ void Patch::UpdateActivePatches(bool reload_enabled_list, bool verbose, bool ver
u32 gp_count = 0;
if (EmuConfig.EnablePatches)
{
gp_count = EnablePatches(s_gamedb_patches, EnablePatchList());
gp_count = EnablePatches(s_gamedb_patches, EnablePatchList(), EnablePatchList());
if (gp_count > 0)
message.append(TRANSLATE_PLURAL_STR("Patch", "%n GameDB patches are active.", "OSD Message", gp_count));
}

const u32 p_count = EnablePatches(s_game_patches, s_enabled_patches);
const u32 p_count = EnablePatches(s_game_patches, s_enabled_patches, apply_new_patches ? s_just_enabled_patches : EnablePatchList());
if (p_count > 0)
{
message.append_format("{}{}", message.empty() ? "" : "\n",
TRANSLATE_PLURAL_STR("Patch", "%n game patches are active.", "OSD Message", p_count));
}

const u32 c_count = EmuConfig.EnableCheats ? EnablePatches(s_cheat_patches, s_enabled_cheats) : 0;
const u32 c_count = EmuConfig.EnableCheats ? EnablePatches(s_cheat_patches, s_enabled_cheats, apply_new_patches ? s_just_enabled_cheats : EnablePatchList()) : 0;
if (c_count > 0)
{
message.append_format("{}{}", message.empty() ? "" : "\n",
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/Patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ namespace Patch
/// Reloads cheats/patches. If verbose is set, the number of patches loaded will be shown in the OSD.
extern void ReloadPatches(const std::string& serial, u32 crc, bool reload_files, bool reload_enabled_list, bool verbose, bool verbose_if_changed);

extern void UpdateActivePatches(bool reload_enabled_list, bool verbose, bool verbose_if_changed);
extern void UpdateActivePatches(bool reload_enabled_list, bool verbose, bool verbose_if_changed, bool apply_new_patches);
extern void ApplyPatchSettingOverrides();
extern bool ReloadPatchAffectingOptions();
extern void UnloadPatches();
Expand Down
4 changes: 2 additions & 2 deletions pcsx2/VMManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ bool VMManager::ReloadGameSettings()
return false;

// Patches must come first, because they can affect aspect ratio/interlacing.
Patch::UpdateActivePatches(true, false, true);
Patch::UpdateActivePatches(true, false, true, HasValidVM());
ApplySettings();
return true;
}
Expand Down Expand Up @@ -2899,7 +2899,7 @@ void VMManager::CheckForPatchConfigChanges(const Pcsx2Config& old_config)
return;
}

Patch::UpdateActivePatches(true, false, true);
Patch::UpdateActivePatches(true, false, true, HasValidVM());

// This is a bit messy, because the patch config update happens after the settings are loaded,
// if we disable widescreen patches, we have to reload the original settings again.
Expand Down

0 comments on commit 3b5b3ff

Please sign in to comment.