Core: add ability to apply memory patches during a frame update in the PatchEngine
This commit is contained in:
parent
4743d74985
commit
1f87bcd202
|
@ -11,6 +11,7 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
|
||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
|
#include "Common/Debug/MemoryPatches.h"
|
||||||
#include "Common/IniFile.h"
|
#include "Common/IniFile.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
|
@ -25,6 +27,7 @@
|
||||||
#include "Core/CheatCodes.h"
|
#include "Core/CheatCodes.h"
|
||||||
#include "Core/Config/SessionSettings.h"
|
#include "Core/Config/SessionSettings.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
#include "Core/Debugger/PPCDebugInterface.h"
|
||||||
#include "Core/GeckoCode.h"
|
#include "Core/GeckoCode.h"
|
||||||
#include "Core/GeckoCodeConfig.h"
|
#include "Core/GeckoCodeConfig.h"
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
|
@ -39,6 +42,8 @@ constexpr std::array<const char*, 3> s_patch_type_strings{{
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static std::vector<Patch> s_on_frame;
|
static std::vector<Patch> s_on_frame;
|
||||||
|
static std::vector<std::size_t> s_on_frame_memory;
|
||||||
|
static std::mutex s_on_frame_memory_mutex;
|
||||||
static std::map<u32, int> s_speed_hacks;
|
static std::map<u32, int> s_speed_hacks;
|
||||||
|
|
||||||
const char* PatchTypeAsString(PatchType type)
|
const char* PatchTypeAsString(PatchType type)
|
||||||
|
@ -257,6 +262,15 @@ static void ApplyPatches(const std::vector<Patch>& patches)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ApplyMemoryPatches(const std::vector<std::size_t>& 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
|
// Requires MSR.DR, MSR.IR
|
||||||
// There's no perfect way to do this, it's just a heuristic.
|
// 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.
|
// 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);
|
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()
|
bool ApplyFramePatches()
|
||||||
{
|
{
|
||||||
// Because we're using the VI Interrupt to time this instead of patching the game with a
|
// 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);
|
ApplyPatches(s_on_frame);
|
||||||
|
ApplyMemoryPatches(s_on_frame_memory);
|
||||||
|
|
||||||
// Run the Gecko code handler
|
// Run the Gecko code handler
|
||||||
Gecko::RunCodeHandler();
|
Gecko::RunCodeHandler();
|
||||||
|
|
|
@ -51,6 +51,9 @@ void LoadPatchSection(const std::string& section, std::vector<Patch>* patches,
|
||||||
void SavePatchSection(IniFile* local_ini, const std::vector<Patch>& patches);
|
void SavePatchSection(IniFile* local_ini, const std::vector<Patch>& patches);
|
||||||
void LoadPatches();
|
void LoadPatches();
|
||||||
|
|
||||||
|
void AddMemoryPatch(std::size_t index);
|
||||||
|
void RemoveMemoryPatch(std::size_t index);
|
||||||
|
|
||||||
bool ApplyFramePatches();
|
bool ApplyFramePatches();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Reload();
|
void Reload();
|
||||||
|
|
Loading…
Reference in New Issue