From bfa807ca8b0c6153436f3606690a769bbf51fc1b Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 3 Jan 2026 12:04:51 +0100 Subject: [PATCH] feat: Add data inspector option to reverse bit order --- .../content/views/view_data_inspector.hpp | 4 ++ plugins/builtin/romfs/lang/en_US.json | 3 +- .../content/views/view_data_inspector.cpp | 57 ++++++++++++++----- 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/plugins/builtin/include/content/views/view_data_inspector.hpp b/plugins/builtin/include/content/views/view_data_inspector.hpp index d63d0ce95..00d915a9d 100644 --- a/plugins/builtin/include/content/views/view_data_inspector.hpp +++ b/plugins/builtin/include/content/views/view_data_inspector.hpp @@ -46,10 +46,13 @@ namespace hex::plugin::builtin { void inspectorReadFunction(u64 offset, u8 *buffer, size_t size); + void preprocessBytes(std::span data); + // draw functions void drawEndianSetting(); void drawRadixSetting(); void drawInvertSetting(); + void drawReverseSetting(); void drawInspectorRows(); void drawInspectorRow(InspectorCacheEntry& entry); @@ -61,6 +64,7 @@ namespace hex::plugin::builtin { std::endian m_endian = std::endian::native; ContentRegistry::DataInspector::NumberDisplayStyle m_numberDisplayStyle = ContentRegistry::DataInspector::NumberDisplayStyle::Decimal; bool m_invert = false; + bool m_reverse = false; ui::VisualizerDrawer m_visualizerDrawer; u64 m_startAddress = 0; diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 71831b67a..c597b0482 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -771,7 +771,8 @@ "hex.builtin.view.data_inspector.menu.copy": "Copy Value", "hex.builtin.view.data_inspector.menu.edit": "Edit Value", "hex.builtin.view.data_inspector.execution_error": "Custom row evaluation error", - "hex.builtin.view.data_inspector.invert": "Invert", + "hex.builtin.view.data_inspector.invert": "Bit invert", + "hex.builtin.view.data_inspector.reverse": "Bit reverse", "hex.builtin.view.data_inspector.name": "Data Inspector", "hex.builtin.view.data_inspector.no_data": "No bytes selected", "hex.builtin.view.data_inspector.table.name": "Name", diff --git a/plugins/builtin/source/content/views/view_data_inspector.cpp b/plugins/builtin/source/content/views/view_data_inspector.cpp index e2995775d..291a2bb62 100644 --- a/plugins/builtin/source/content/views/view_data_inspector.cpp +++ b/plugins/builtin/source/content/views/view_data_inspector.cpp @@ -77,6 +77,27 @@ namespace hex::plugin::builtin { }); } + static u8 reverseBits(u8 byte) { + byte = (byte & 0xF0) >> 4 | (byte & 0x0F) << 4; + byte = (byte & 0xCC) >> 2 | (byte & 0x33) << 2; + byte = (byte & 0xAA) >> 1 | (byte & 0x55) << 1; + return byte; + } + + void ViewDataInspector::preprocessBytes(std::span data) { + // Handle invert setting + if (m_invert) { + for (auto &byte : data) + byte ^= 0xFF; + } + + // Handle reverse setting + if (m_reverse) { + for (auto &byte : data) + byte = reverseBits(byte); + } + } + void ViewDataInspector::updateInspectorRowsTask() { m_workData.clear(); @@ -92,11 +113,7 @@ namespace hex::plugin::builtin { std::vector buffer(m_validBytes > entry.maxSize ? entry.maxSize : m_validBytes); m_selectedProvider->read(m_startAddress, buffer.data(), buffer.size()); - // Handle invert setting - if (m_invert) { - for (auto &byte : buffer) - byte ^= 0xFF; - } + preprocessBytes(buffer); // Insert processed data into the inspector list m_workData.emplace_back( @@ -118,11 +135,7 @@ namespace hex::plugin::builtin { void ViewDataInspector::inspectorReadFunction(u64 offset, u8 *buffer, size_t size) { m_selectedProvider->read(offset, buffer, size); - // Handle invert setting - if (m_invert) { - for (auto &byte : std::span(buffer, size)) - byte ^= 0xFF; - } + preprocessBytes({ buffer, size }); } void ViewDataInspector::executeInspectors() { @@ -354,8 +367,12 @@ namespace hex::plugin::builtin { // Draw radix setting this->drawRadixSetting(); - // Draw invert setting + // Draw invert and reverse setting + ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x / 2 - ImGui::GetStyle().ItemSpacing.x / 2); this->drawInvertSetting(); + ImGui::SameLine(); + this->drawReverseSetting(); + ImGui::PopItemWidth(); } ImGui::PopItemWidth(); } @@ -489,8 +506,7 @@ namespace hex::plugin::builtin { // Draw editing widget and capture edited value auto bytes = (*entry.editingFunction)(m_editingValue, m_endian, {}); if (bytes.has_value()) { - if (m_invert) - std::ranges::transform(*bytes, bytes->begin(), [](auto byte) { return byte ^ 0xFF; }); + preprocessBytes(*bytes); // Write those bytes to the selected provider at the current address m_selectedProvider->write(m_startAddress, bytes->data(), bytes->size()); @@ -572,6 +588,21 @@ namespace hex::plugin::builtin { } } + void ViewDataInspector::drawReverseSetting() { + int selection = m_reverse ? 1 : 0; + + std::array options = { + fmt::format("{}: {}", "hex.builtin.view.data_inspector.reverse"_lang, "hex.ui.common.no"_lang), + fmt::format("{}: {}", "hex.builtin.view.data_inspector.reverse"_lang, "hex.ui.common.yes"_lang) + }; + + if (ImGui::SliderInt("##reverse", &selection, 0, options.size() - 1, options[selection].c_str(), ImGuiSliderFlags_NoInput)) { + m_shouldInvalidate = true; + + m_reverse = selection == 1; + } + } + ContentRegistry::DataInspector::impl::DisplayFunction ViewDataInspector::createPatternErrorDisplayFunction() { // Generate error message std::string errorMessage;