summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Debug/MemoryPatches.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/Common/Debug/MemoryPatches.cpp')
-rw-r--r--Source/Core/Common/Debug/MemoryPatches.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/Source/Core/Common/Debug/MemoryPatches.cpp b/Source/Core/Common/Debug/MemoryPatches.cpp
new file mode 100644
index 0000000000..db7a40c58b
--- /dev/null
+++ b/Source/Core/Common/Debug/MemoryPatches.cpp
@@ -0,0 +1,99 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "Common/Debug/MemoryPatches.h"
+
+#include <algorithm>
+#include <sstream>
+
+namespace Common::Debug
+{
+MemoryPatch::MemoryPatch(u32 address_, std::vector<u8> value_)
+ : address(address_), value(value_), is_enabled(State::Enabled)
+{
+}
+
+MemoryPatch::MemoryPatch(u32 address, u32 value)
+ : MemoryPatch(address, {static_cast<u8>(value >> 24), static_cast<u8>(value >> 16),
+ static_cast<u8>(value >> 8), static_cast<u8>(value)})
+{
+}
+
+MemoryPatches::MemoryPatches() = default;
+MemoryPatches::~MemoryPatches() = default;
+
+void MemoryPatches::SetPatch(u32 address, u32 value)
+{
+ const std::size_t index = m_patches.size();
+ m_patches.emplace_back(address, value);
+ Patch(index);
+}
+
+void MemoryPatches::SetPatch(u32 address, std::vector<u8> value)
+{
+ const std::size_t index = m_patches.size();
+ m_patches.emplace_back(address, std::move(value));
+ Patch(index);
+}
+
+const std::vector<MemoryPatch>& MemoryPatches::GetPatches() const
+{
+ return m_patches;
+}
+
+void MemoryPatches::UnsetPatch(u32 address)
+{
+ const auto it = std::remove_if(m_patches.begin(), m_patches.end(),
+ [address](const auto& patch) { return patch.address == address; });
+
+ if (it == m_patches.end())
+ return;
+
+ const std::size_t size = m_patches.size();
+ std::size_t index = size - std::distance(it, m_patches.end());
+ while (index < size)
+ {
+ DisablePatch(index);
+ ++index;
+ }
+ m_patches.erase(it, m_patches.end());
+}
+
+void MemoryPatches::EnablePatch(std::size_t index)
+{
+ if (m_patches[index].is_enabled == MemoryPatch::State::Enabled)
+ return;
+ m_patches[index].is_enabled = MemoryPatch::State::Enabled;
+ Patch(index);
+}
+
+void MemoryPatches::DisablePatch(std::size_t index)
+{
+ if (m_patches[index].is_enabled == MemoryPatch::State::Disabled)
+ return;
+ m_patches[index].is_enabled = MemoryPatch::State::Disabled;
+ Patch(index);
+}
+
+bool MemoryPatches::HasEnabledPatch(u32 address) const
+{
+ return std::any_of(m_patches.begin(), m_patches.end(), [address](const MemoryPatch& patch) {
+ return patch.address == address && patch.is_enabled == MemoryPatch::State::Enabled;
+ });
+}
+
+void MemoryPatches::RemovePatch(std::size_t index)
+{
+ DisablePatch(index);
+ m_patches.erase(m_patches.begin() + index);
+}
+
+void MemoryPatches::ClearPatches()
+{
+ const std::size_t size = m_patches.size();
+ for (std::size_t index = 0; index < size; ++index)
+ DisablePatch(index);
+ m_patches.clear();
+}
+} // namespace Common::Debug