From 1f87bcd202697299d6ca9a2e17a6ce633bffbb6d Mon Sep 17 00:00:00 2001 From: iwubcode Date: Thu, 22 Dec 2022 17:35:48 -0600 Subject: [PATCH] Core: add ability to apply memory patches during a frame update in the PatchEngine --- Source/Core/Core/PatchEngine.cpp | 28 ++++++++++++++++++++++++++++ Source/Core/Core/PatchEngine.h | 3 +++ 2 files changed, 31 insertions(+) diff --git a/Source/Core/Core/PatchEngine.cpp b/Source/Core/Core/PatchEngine.cpp index f5fe19b7ef..67f2b4a3d9 100644 --- a/Source/Core/Core/PatchEngine.cpp +++ b/Source/Core/Core/PatchEngine.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include "Common/Assert.h" +#include "Common/Debug/MemoryPatches.h" #include "Common/IniFile.h" #include "Common/StringUtil.h" @@ -25,6 +27,7 @@ #include "Core/CheatCodes.h" #include "Core/Config/SessionSettings.h" #include "Core/ConfigManager.h" +#include "Core/Debugger/PPCDebugInterface.h" #include "Core/GeckoCode.h" #include "Core/GeckoCodeConfig.h" #include "Core/PowerPC/MMU.h" @@ -39,6 +42,8 @@ constexpr std::array s_patch_type_strings{{ }}; static std::vector s_on_frame; +static std::vector s_on_frame_memory; +static std::mutex s_on_frame_memory_mutex; static std::map s_speed_hacks; const char* PatchTypeAsString(PatchType type) @@ -257,6 +262,15 @@ static void ApplyPatches(const std::vector& patches) } } +static void ApplyMemoryPatches(const std::vector& memory_patch_indices) +{ + std::lock_guard lock(s_on_frame_memory_mutex); + for (std::size_t index : memory_patch_indices) + { + PowerPC::debug_interface.ApplyExistingPatch(index); + } +} + // Requires MSR.DR, MSR.IR // There's no perfect way to do this, it's just a heuristic. // We require at least 2 stack frames, if the stack is shallower than that then it won't work. @@ -281,6 +295,19 @@ static bool IsStackSane() 0 != PowerPC::HostRead_Instruction(address); } +void AddMemoryPatch(std::size_t index) +{ + std::lock_guard lock(s_on_frame_memory_mutex); + s_on_frame_memory.push_back(index); +} + +void RemoveMemoryPatch(std::size_t index) +{ + std::lock_guard lock(s_on_frame_memory_mutex); + s_on_frame_memory.erase(std::remove(s_on_frame_memory.begin(), s_on_frame_memory.end(), index), + s_on_frame_memory.end()); +} + bool ApplyFramePatches() { // Because we're using the VI Interrupt to time this instead of patching the game with a @@ -297,6 +324,7 @@ bool ApplyFramePatches() } ApplyPatches(s_on_frame); + ApplyMemoryPatches(s_on_frame_memory); // Run the Gecko code handler Gecko::RunCodeHandler(); diff --git a/Source/Core/Core/PatchEngine.h b/Source/Core/Core/PatchEngine.h index 9c0a7ed9ee..4218e65fcb 100644 --- a/Source/Core/Core/PatchEngine.h +++ b/Source/Core/Core/PatchEngine.h @@ -51,6 +51,9 @@ void LoadPatchSection(const std::string& section, std::vector* patches, void SavePatchSection(IniFile* local_ini, const std::vector& patches); void LoadPatches(); +void AddMemoryPatch(std::size_t index); +void RemoveMemoryPatch(std::size_t index); + bool ApplyFramePatches(); void Shutdown(); void Reload();