diff --git a/Source/Core/Common/Debug/MemoryPatches.cpp b/Source/Core/Common/Debug/MemoryPatches.cpp index 8dd9b5716d..f48e6e5bb5 100644 --- a/Source/Core/Common/Debug/MemoryPatches.cpp +++ b/Source/Core/Common/Debug/MemoryPatches.cpp @@ -38,6 +38,23 @@ void MemoryPatches::SetPatch(u32 address, std::vector value) Patch(index); } +void MemoryPatches::SetFramePatch(u32 address, u32 value) +{ + const std::size_t index = m_patches.size(); + m_patches.emplace_back(address, value); + m_patches.back().type = MemoryPatch::ApplyType::EachFrame; + Patch(index); +} + +void MemoryPatches::SetFramePatch(u32 address, std::vector value) +{ + UnsetPatch(address); + const std::size_t index = m_patches.size(); + m_patches.emplace_back(address, std::move(value)); + m_patches.back().type = MemoryPatch::ApplyType::EachFrame; + Patch(index); +} + const std::vector& MemoryPatches::GetPatches() const { return m_patches; @@ -81,6 +98,7 @@ bool MemoryPatches::HasEnabledPatch(u32 address) const void MemoryPatches::RemovePatch(std::size_t index) { DisablePatch(index); + UnPatch(index); m_patches.erase(m_patches.begin() + index); } @@ -88,7 +106,10 @@ void MemoryPatches::ClearPatches() { const std::size_t size = m_patches.size(); for (std::size_t index = 0; index < size; ++index) + { DisablePatch(index); + UnPatch(index); + } m_patches.clear(); } } // namespace Common::Debug diff --git a/Source/Core/Common/Debug/MemoryPatches.h b/Source/Core/Common/Debug/MemoryPatches.h index 634382f3b3..2a4f902dcd 100644 --- a/Source/Core/Common/Debug/MemoryPatches.h +++ b/Source/Core/Common/Debug/MemoryPatches.h @@ -19,12 +19,19 @@ struct MemoryPatch Disabled }; + enum class ApplyType + { + Once, + EachFrame + }; + MemoryPatch(u32 address_, std::vector value_); MemoryPatch(u32 address_, u32 value_); u32 address; std::vector value; State is_enabled = State::Enabled; + ApplyType type = ApplyType::Once; }; class MemoryPatches @@ -35,6 +42,8 @@ public: void SetPatch(u32 address, u32 value); void SetPatch(u32 address, std::vector value); + void SetFramePatch(u32 address, u32 value); + void SetFramePatch(u32 address, std::vector value); const std::vector& GetPatches() const; void UnsetPatch(u32 address); void EnablePatch(std::size_t index); @@ -46,6 +55,7 @@ public: protected: virtual void Patch(std::size_t index) = 0; + virtual void UnPatch(std::size_t index) = 0; std::vector m_patches; }; diff --git a/Source/Core/Common/DebugInterface.h b/Source/Core/Common/DebugInterface.h index 90ff647bec..8949fd3276 100644 --- a/Source/Core/Common/DebugInterface.h +++ b/Source/Core/Common/DebugInterface.h @@ -43,6 +43,8 @@ public: // Memory Patches virtual void SetPatch(u32 address, u32 value) = 0; virtual void SetPatch(u32 address, std::vector value) = 0; + virtual void SetFramePatch(u32 address, u32 value) = 0; + virtual void SetFramePatch(u32 address, std::vector value) = 0; virtual const std::vector& GetPatches() const = 0; virtual void UnsetPatch(u32 address) = 0; virtual void EnablePatch(std::size_t index) = 0; diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Debugger/PPCDebugInterface.cpp index 6161cd304b..1cb3c0c42b 100644 --- a/Source/Core/Core/Debugger/PPCDebugInterface.cpp +++ b/Source/Core/Core/Debugger/PPCDebugInterface.cpp @@ -19,6 +19,7 @@ #include "Core/Core.h" #include "Core/Debugger/OSThread.h" #include "Core/HW/DSP.h" +#include "Core/PatchEngine.h" #include "Core/PowerPC/MMU.h" #include "Core/PowerPC/PPCSymbolDB.h" #include "Core/PowerPC/PowerPC.h" @@ -58,7 +59,19 @@ void PPCPatches::ApplyExistingPatch(std::size_t index) void PPCPatches::Patch(std::size_t index) { auto& patch = m_patches[index]; - ApplyMemoryPatch(patch); + if (patch.type == Common::Debug::MemoryPatch::ApplyType::Once) + ApplyMemoryPatch(patch); + else + PatchEngine::AddMemoryPatch(index); +} + +void PPCPatches::UnPatch(std::size_t index) +{ + auto& patch = m_patches[index]; + if (patch.type == Common::Debug::MemoryPatch::ApplyType::Once) + return; + + PatchEngine::RemoveMemoryPatch(index); } PPCDebugInterface::PPCDebugInterface() = default; @@ -144,6 +157,16 @@ void PPCDebugInterface::SetPatch(u32 address, std::vector value) m_patches.SetPatch(address, std::move(value)); } +void PPCDebugInterface::SetFramePatch(u32 address, u32 value) +{ + m_patches.SetFramePatch(address, value); +} + +void PPCDebugInterface::SetFramePatch(u32 address, std::vector value) +{ + m_patches.SetFramePatch(address, std::move(value)); +} + const std::vector& PPCDebugInterface::GetPatches() const { return m_patches.GetPatches(); diff --git a/Source/Core/Core/Debugger/PPCDebugInterface.h b/Source/Core/Core/Debugger/PPCDebugInterface.h index 533863fa14..8afc1dddab 100644 --- a/Source/Core/Core/Debugger/PPCDebugInterface.h +++ b/Source/Core/Core/Debugger/PPCDebugInterface.h @@ -21,6 +21,7 @@ public: private: void Patch(std::size_t index) override; + void UnPatch(std::size_t index) override; }; // wrapper between disasm control and Dolphin debugger @@ -50,6 +51,8 @@ public: // Memory Patches void SetPatch(u32 address, u32 value) override; void SetPatch(u32 address, std::vector value) override; + void SetFramePatch(u32 address, u32 value) override; + void SetFramePatch(u32 address, std::vector value) override; const std::vector& GetPatches() const override; void UnsetPatch(u32 address) override; void EnablePatch(std::size_t index) override;