diff --git a/plugins/builtin/romfs/lang/base.json b/plugins/builtin/romfs/lang/base.json index 145794154..f058658d5 100644 --- a/plugins/builtin/romfs/lang/base.json +++ b/plugins/builtin/romfs/lang/base.json @@ -187,9 +187,13 @@ "hex.builtin.nodes.bitwise.not.header", "hex.builtin.nodes.bitwise.or", "hex.builtin.nodes.bitwise.or.header", + "hex.builtin.nodes.bitwise.swap", + "hex.builtin.nodes.bitwise.swap.header", "hex.builtin.nodes.bitwise.xor", "hex.builtin.nodes.bitwise.xor.header", "hex.builtin.nodes.buffer", + "hex.builtin.nodes.buffer.byte_swap", + "hex.builtin.nodes.buffer.byte_swap.header", "hex.builtin.nodes.buffer.combine", "hex.builtin.nodes.buffer.combine.header", "hex.builtin.nodes.buffer.patch", @@ -290,6 +294,8 @@ "hex.builtin.nodes.display", "hex.builtin.nodes.display.buffer", "hex.builtin.nodes.display.buffer.header", + "hex.builtin.nodes.display.bits", + "hex.builtin.nodes.display.bits.header", "hex.builtin.nodes.display.float", "hex.builtin.nodes.display.float.header", "hex.builtin.nodes.display.int", diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index acb970191..ca4e06bcf 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -217,9 +217,13 @@ "hex.builtin.nodes.bitwise.not.header": "Bitwise NOT", "hex.builtin.nodes.bitwise.or": "OR", "hex.builtin.nodes.bitwise.or.header": "Bitwise OR", + "hex.builtin.nodes.bitwise.swap": "Reverse", + "hex.builtin.nodes.bitwise.swap.header": "Reverse bits", "hex.builtin.nodes.bitwise.xor": "XOR", "hex.builtin.nodes.bitwise.xor.header": "Bitwise XOR", "hex.builtin.nodes.buffer": "Buffer", + "hex.builtin.nodes.buffer.byte_swap": "Reverse", + "hex.builtin.nodes.buffer.byte_swap.header": "Reverse bytes", "hex.builtin.nodes.buffer.combine": "Combine", "hex.builtin.nodes.buffer.combine.header": "Combine buffers", "hex.builtin.nodes.buffer.patch": "Patch", @@ -332,6 +336,8 @@ "hex.builtin.nodes.display": "Display", "hex.builtin.nodes.display.buffer": "Buffer", "hex.builtin.nodes.display.buffer.header": "Buffer display", + "hex.builtin.nodes.display.bits": "Bits", + "hex.builtin.nodes.display.bits.header": "Bits display", "hex.builtin.nodes.display.float": "Float", "hex.builtin.nodes.display.float.header": "Float display", "hex.builtin.nodes.display.int": "Integer", diff --git a/plugins/builtin/source/content/data_processor_nodes.cpp b/plugins/builtin/source/content/data_processor_nodes.cpp index 787d32636..23a46300b 100644 --- a/plugins/builtin/source/content/data_processor_nodes.cpp +++ b/plugins/builtin/source/content/data_processor_nodes.cpp @@ -1202,6 +1202,68 @@ namespace hex::plugin::builtin { std::string m_name; }; + class NodeBufferByteSwap : public dp::Node { + public: + NodeBufferByteSwap() : Node("hex.builtin.nodes.buffer.byte_swap.header", {dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.output") }) { } + + void process() override { + auto data = this->getBufferOnInput(0); + std::reverse(data.begin(), data.end()); + this->setBufferOnOutput(1, data); + } + + }; + + class NodeBitwiseSwap : public dp::Node { + public: + NodeBitwiseSwap() : Node("hex.builtin.nodes.bitwise.swap.header", {dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input"), dp::Attribute(dp::Attribute::IOType::Out, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.output") }) { } + + void process() override { + // Table contains reversed nibble entries + static constexpr std::array BitFlipLookup = { + 0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, + 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF, }; + auto data = this->getBufferOnInput(0); + + for(u8 &b : data) + b = BitFlipLookup[b & 0xf] << 4 | BitFlipLookup[b >> 4]; + + std::reverse(data.begin(), data.end()); + this->setBufferOnOutput(1, data); + } + + }; + + class NodeDisplayBits : public dp::Node { + public: + NodeDisplayBits() : Node("hex.builtin.nodes.display.bits.header", { dp::Attribute(dp::Attribute::IOType::In, dp::Attribute::Type::Buffer, "hex.builtin.nodes.common.input") }) { } + + void drawNode() override { + ImGui::PushItemWidth(100_scaled); + ImGui::Text("%s", this->m_display.c_str()); + ImGui::PopItemWidth(); + } + + void process() override { + const auto &buffer = this->getBufferOnInput(0); + // Display bits in groups of 4 bits + std::string display; + display.reserve(buffer.size() * 9 + 2); // 8 bits + 1 space at beginning + 1 space every 4 bits + for (const auto &byte : buffer) { + for (size_t i = 0; i < 8; i++) { + if (i % 4 == 0) { + display += ' '; + } + display += (byte & (1 << i)) != 0 ? '1' : '0'; + } + } + this->m_display = wolv::util::trim(display); + } + + private: + std::string m_display = "???"; + }; + void registerDataProcessorNodes() { ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants", "hex.builtin.nodes.constants.int"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.constants", "hex.builtin.nodes.constants.float"); @@ -1215,6 +1277,7 @@ namespace hex::plugin::builtin { ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.display", "hex.builtin.nodes.display.float"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.display", "hex.builtin.nodes.display.buffer"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.display", "hex.builtin.nodes.display.string"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.display", "hex.builtin.nodes.display.bits"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.data_access", "hex.builtin.nodes.data_access.read"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.data_access", "hex.builtin.nodes.data_access.write"); @@ -1242,6 +1305,7 @@ namespace hex::plugin::builtin { ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.buffer", "hex.builtin.nodes.buffer.repeat"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.buffer", "hex.builtin.nodes.buffer.patch"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.buffer", "hex.builtin.nodes.buffer.size"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.buffer", "hex.builtin.nodes.buffer.byte_swap"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow", "hex.builtin.nodes.control_flow.if"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.control_flow", "hex.builtin.nodes.control_flow.equals"); @@ -1256,6 +1320,7 @@ namespace hex::plugin::builtin { ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.bitwise", "hex.builtin.nodes.bitwise.or"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.bitwise", "hex.builtin.nodes.bitwise.xor"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.bitwise", "hex.builtin.nodes.bitwise.not"); + ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.bitwise", "hex.builtin.nodes.bitwise.swap"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.decoding", "hex.builtin.nodes.decoding.base64"); ContentRegistry::DataProcessorNode::add("hex.builtin.nodes.decoding", "hex.builtin.nodes.decoding.hex");