diff --git a/CMakeLists.txt b/CMakeLists.txt index c0dfbdbc6..147d26a67 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ add_executable(ImHex source/views/view_data_inspector.cpp source/views/view_disassembler.cpp source/views/view_bookmarks.cpp + source/views/view_patches.cpp libs/glad/source/glad.c diff --git a/include/providers/provider.hpp b/include/providers/provider.hpp index 6b086a090..594c9a977 100644 --- a/include/providers/provider.hpp +++ b/include/providers/provider.hpp @@ -32,7 +32,7 @@ namespace hex::prv { virtual void writeRaw(u64 offset, const void *buffer, size_t size) = 0; virtual size_t getActualSize() = 0; - const std::map& getPatches() { return this->m_patches.back(); } + std::map& getPatches() { return this->m_patches.back(); } void applyPatches() { for (auto &[patchAddress, patch] : this->m_patches.back()) this->writeRaw(patchAddress, &patch, 1); diff --git a/include/views/view_patches.hpp b/include/views/view_patches.hpp new file mode 100644 index 000000000..931f20ed0 --- /dev/null +++ b/include/views/view_patches.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +#include "imgui.h" +#include "views/view.hpp" + +#include + +namespace hex { + + namespace prv { class Provider; } + + class ViewPatches : public View { + public: + explicit ViewPatches(prv::Provider* &dataProvider); + ~ViewPatches() override; + + void createView() override; + void createMenu() override; + + private: + prv::Provider* &m_dataProvider; + + + u64 m_selectedPatch; + }; + +} \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 7dcdf19f8..181850257 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -12,6 +12,7 @@ #include "views/view_data_inspector.hpp" #include "views/view_disassembler.hpp" #include "views/view_bookmarks.hpp" +#include "views/view_patches.hpp" #include "providers/provider.hpp" @@ -34,6 +35,7 @@ int main() { window.addView(dataProvider); window.addView(dataProvider); window.addView(dataProvider); + window.addView(dataProvider); window.addView(); window.addView(); diff --git a/source/views/view_patches.cpp b/source/views/view_patches.cpp new file mode 100644 index 000000000..510736f1d --- /dev/null +++ b/source/views/view_patches.cpp @@ -0,0 +1,80 @@ +#include "views/view_patches.hpp" + +#include "providers/provider.hpp" + +#include "helpers/utils.hpp" + +#include + +using namespace std::literals::string_literals; + +namespace hex { + + ViewPatches::ViewPatches(prv::Provider* &dataProvider) : View("Patches"), m_dataProvider(dataProvider) { + + } + + ViewPatches::~ViewPatches() { + + } + + void ViewPatches::createView() { + if (ImGui::Begin("Patches", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + + if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { + + if (ImGui::BeginTable("##patchesTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | + ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { + ImGui::TableSetupScrollFreeze(0, 1); + ImGui::TableSetupColumn("Offset"); + ImGui::TableSetupColumn("Previous Value"); + ImGui::TableSetupColumn("Patched Value"); + + ImGui::TableHeadersRow(); + + auto& patches = this->m_dataProvider->getPatches(); + u32 index = 0; + for (const auto &[address, patch] : patches) { + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::Selectable(("##patchLine" + std::to_string(index)).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { + Region selectRegion = { address, 1 }; + View::postEvent(Events::SelectionChangeRequest, &selectRegion); + } + if (ImGui::IsMouseReleased(1) && ImGui::IsItemHovered()) { + ImGui::OpenPopup("PatchContextMenu"); + this->m_selectedPatch = address; + } + ImGui::SameLine(); + ImGui::Text("0x%08lX", address); + + ImGui::TableNextColumn(); + u8 previousValue = 0x00; + this->m_dataProvider->readRaw(address, &previousValue, sizeof(u8)); + ImGui::Text("0x%02X", previousValue); + + ImGui::TableNextColumn(); + ImGui::Text("0x%02X", patch); + index += 1; + } + + if (ImGui::BeginPopup("PatchContextMenu")) { + if (ImGui::MenuItem("Remove")) { + patches.erase(this->m_selectedPatch); + } + ImGui::EndPopup(); + } + + ImGui::EndTable(); + } + } + } + ImGui::End(); + } + + void ViewPatches::createMenu() { + + } + +} \ No newline at end of file