diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 000000000..94a25f7f4
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f10efcfbb..3df06bcd2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,10 +13,15 @@ SET(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -mwindows)
add_executable(ImHex WIN32
source/main.cpp
source/window.cpp
+ source/utils.cpp
source/parser/lexer.cpp
source/parser/parser.cpp
+ source/views/view_hexeditor.cpp
+ source/views/view_pattern.cpp
+ source/views/view_pattern_data.cpp
+
libs/glad/source/glad.c
libs/ImGui/source/imgui.cpp
diff --git a/include/utils.hpp b/include/utils.hpp
index be66814ce..4d056f60f 100644
--- a/include/utils.hpp
+++ b/include/utils.hpp
@@ -10,42 +10,6 @@
namespace hex {
- std::optional openFileDialog() {
- HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
- if (SUCCEEDED(hr)) {
- IFileOpenDialog *pFileOpen;
-
- hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_IFileOpenDialog, reinterpret_cast(&pFileOpen));
-
- if (SUCCEEDED(hr)) {
- hr = pFileOpen->Show(nullptr);
-
- if (SUCCEEDED(hr)) {
- IShellItem *pItem;
- hr = pFileOpen->GetResult(&pItem);
-
- if (SUCCEEDED(hr)) {
- PWSTR pszFilePath;
- hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
-
- if (SUCCEEDED(hr)) {
- std::wstring_convert, wchar_t> converter;
-
- std::string result = converter.to_bytes(pszFilePath);
-
- CoTaskMemFree(pszFilePath);
-
- return result;
- }
- pItem->Release();
- }
- }
- pFileOpen->Release();
- }
- CoUninitialize();
- }
-
- return { };
- }
+ std::optional openFileDialog();
}
\ No newline at end of file
diff --git a/include/views/highlight.hpp b/include/views/highlight.hpp
new file mode 100644
index 000000000..3c21fffb5
--- /dev/null
+++ b/include/views/highlight.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include
+#include
+
+namespace hex {
+
+ struct Highlight {
+ Highlight(u64 offset, size_t size, u32 color, std::string name)
+ : offset(offset), size(size), color(color), name(name) {
+
+ }
+
+ u64 offset;
+ size_t size;
+ u32 color;
+ std::string name;
+ };
+
+}
\ No newline at end of file
diff --git a/include/views/view_hexeditor.hpp b/include/views/view_hexeditor.hpp
index 51740cbf4..4c984f350 100644
--- a/include/views/view_hexeditor.hpp
+++ b/include/views/view_hexeditor.hpp
@@ -12,106 +12,25 @@
#include
#include
+#include "views/highlight.hpp"
+
namespace hex {
class ViewHexEditor : public View {
public:
- ViewHexEditor() : View() {
- this->m_memoryEditor.ReadFn = [](const ImU8* data, size_t off) -> ImU8 {
- ViewHexEditor *_this = (ViewHexEditor*)data;
+ ViewHexEditor(FILE* &file, std::vector &highlights);
+ virtual ~ViewHexEditor();
- if (_this->m_file == nullptr)
- return 0x00;
-
- fseek(_this->m_file, off, SEEK_SET);
-
- ImU8 byte;
- fread(&byte, sizeof(ImU8), 1, _this->m_file);
-
- return byte;
- };
-
- this->m_memoryEditor.WriteFn = [](ImU8* data, size_t off, ImU8 d) -> void {
- ViewHexEditor *_this = (ViewHexEditor*)data;
-
- if (_this->m_file == nullptr)
- return;
-
- fseek(_this->m_file, off, SEEK_SET);
-
- fwrite(&d, sizeof(ImU8), 1, _this->m_file);
-
- };
-
- this->m_memoryEditor.HighlightFn = [](const ImU8* data, size_t off, bool next) -> bool {
- ViewHexEditor *_this = (ViewHexEditor*)data;
-
- for (auto& [offset, size, color] : _this->m_highlights) {
- if (next && off == (offset + size)) {
- return false;
- }
-
- if (off >= offset && off < (offset + size)) {
- _this->m_memoryEditor.HighlightColor = color;
- return true;
- }
- }
-
- _this->m_memoryEditor.HighlightColor = 0x50C08080;
- return false;
- };
- }
- virtual ~ViewHexEditor() { }
-
- virtual void createView() override {
- this->m_memoryEditor.DrawWindow("Hex Editor", this, this->m_file == nullptr ? 0x00 : this->m_fileSize);
- }
-
- virtual void createMenu() override {
- if (ImGui::BeginMenu("File")) {
- if (ImGui::MenuItem("Open File...")) {
- auto filePath = openFileDialog();
- if (filePath.has_value()) {
- if (this->m_file != nullptr)
- fclose(this->m_file);
-
- this->m_file = fopen(filePath->c_str(), "r+b");
-
- fseek(this->m_file, 0, SEEK_END);
- this->m_fileSize = ftell(this->m_file);
- rewind(this->m_file);
- }
-
- }
- ImGui::EndMenu();
- }
-
- if (ImGui::BeginMenu("Window")) {
- ImGui::MenuItem("Hex View", "", &this->m_memoryEditor.Open);
- ImGui::EndMenu();
- }
- }
-
- void setHighlight(u64 offset, size_t size, u32 color = 0) {
- if (color == 0)
- color = std::mt19937(std::random_device()())();
-
- color |= 0xFF00'0000;
-
- this->m_highlights.emplace_back(offset, size, color);
- }
-
- void clearHighlights() {
- this->m_highlights.clear();
- }
+ virtual void createView() override;
+ virtual void createMenu() override;
private:
MemoryEditor m_memoryEditor;
- FILE *m_file = nullptr;
+ FILE* &m_file;
size_t m_fileSize = 0;
- std::vector> m_highlights;
+ std::vector &m_highlights;
};
}
\ No newline at end of file
diff --git a/include/views/view_pattern.hpp b/include/views/view_pattern.hpp
index 7bc7d26ab..2c013b872 100644
--- a/include/views/view_pattern.hpp
+++ b/include/views/view_pattern.hpp
@@ -8,207 +8,30 @@
#include
#include
-#include "views/view_hexeditor.hpp"
+#include "views/highlight.hpp"
namespace hex {
class ViewPattern : public View {
public:
- ViewPattern(ViewHexEditor *hexEditor) : View(), m_hexEditor(hexEditor) {
- this->m_buffer = new char[0xFFFFFF];
- std::memset(this->m_buffer, 0x00, 0xFFFFFF);
- }
- virtual ~ViewPattern() {
- delete[] this->m_buffer;
- }
+ ViewPattern(std::vector &highlights);
+ virtual ~ViewPattern();
- virtual void createMenu() {
- if (ImGui::BeginMenu("File")) {
- if (ImGui::MenuItem("Load pattern...")) {
- auto filePath = openFileDialog();
- if (filePath.has_value()) {
- FILE *file = fopen(filePath->c_str(), "r+b");
-
- fseek(file, 0, SEEK_END);
- size_t size = ftell(file);
- rewind(file);
-
- if (size > 0xFF'FFFF)
- return;
-
- fread(this->m_buffer, size, 1, file);
-
- fclose(file);
-
- this->parsePattern(this->m_buffer);
- }
-
- }
- ImGui::EndMenu();
- }
-
- if (ImGui::BeginMenu("Window")) {
- ImGui::MenuItem("Pattern View", "", &this->m_windowOpen);
- ImGui::EndMenu();
- }
- }
-
- void createView() override {
- if (!this->m_windowOpen)
- return;
-
- ImGui::Begin("Pattern", &this->m_windowOpen, ImGuiWindowFlags_None);
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
- ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
-
- auto size = ImGui::GetWindowSize();
- size.y -= 50;
- ImGui::InputTextMultiline("Pattern", this->m_buffer, 0xFFFF, size, ImGuiInputTextFlags_AllowTabInput | ImGuiInputTextFlags_CallbackEdit,
- [](ImGuiInputTextCallbackData* data) -> int {
- auto _this = static_cast(data->UserData);
-
- _this->parsePattern(data->Buf);
-
- return 0;
- }, this
- );
- ImGui::PopStyleVar(2);
- ImGui::End();
- }
+ virtual void createMenu() override;
+ virtual void createView() override;
private:
char *m_buffer;
- ViewHexEditor *m_hexEditor;
+ std::vector &m_highlights;
bool m_windowOpen = true;
- void parsePattern(char *buffer) {
- static hex::lang::Lexer lexer;
- static hex::lang::Parser parser;
- this->m_hexEditor->clearHighlights();
+ void setHighlight(u64 offset, size_t size, std::string name, u32 color = 0);
+ void parsePattern(char *buffer);
- auto [lexResult, tokens] = lexer.lex(buffer);
-
- if (lexResult.failed()) {
- return;
- }
-
- auto [parseResult, ast] = parser.parse(tokens);
- if (parseResult.failed()) {
- for(auto &node : ast) delete node;
- return;
- }
-
- for (auto &varNode : this->findNodes(lang::ASTNode::Type::VariableDecl, ast)) {
- if (!varNode->getOffset().has_value())
- continue;
-
- u64 offset = varNode->getOffset().value();
- if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
- this->m_hexEditor->setHighlight(offset, static_cast(varNode->getVariableType()) >> 4);
- } else {
- for (auto &structNode : this->findNodes(lang::ASTNode::Type::Struct, ast))
- if (varNode->getCustomVariableTypeName() == structNode->getName())
- if (this->highlightStruct(ast, structNode, offset) == -1)
- this->m_hexEditor->clearHighlights();
-
- for (auto &usingNode : this->findNodes(lang::ASTNode::Type::TypeDecl, ast))
- if (varNode->getCustomVariableTypeName() == usingNode->getTypeName())
- if (this->highlightUsingDecls(ast, usingNode, offset) == -1)
- this->m_hexEditor->clearHighlights();
- }
-
- }
-
- for(auto &node : ast) delete node;
- }
-
- template T>
- std::vector findNodes(const lang::ASTNode::Type type, const std::vector &nodes) const noexcept {
- std::vector result;
-
- for (const auto & node : nodes)
- if (node->getType() == type)
- result.push_back(static_cast(node));
-
- return result;
- }
-
- s32 highlightUsingDecls(std::vector &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, u64 offset) {
- if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) {
- size_t size = static_cast(currTypeDeclNode->getAssignedType()) >> 4;
-
- this->m_hexEditor->setHighlight(offset, size);
- offset += size;
- } else {
- bool foundType = false;
- for (auto &structNode : findNodes(lang::ASTNode::Type::Struct, ast))
- if (structNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
- offset = this->highlightStruct(ast, structNode, offset);
- foundType = true;
- break;
- }
-
- for (auto &typeDeclNode : findNodes(lang::ASTNode::Type::TypeDecl, ast))
- if (typeDeclNode->getTypeName() == currTypeDeclNode->getAssignedCustomTypeName()) {
- offset = this->highlightUsingDecls(ast, typeDeclNode, offset);
- foundType = true;
- break;
- }
-
- if (!foundType)
- return -1;
- }
-
- return offset;
- }
-
- s32 highlightStruct(std::vector &ast, lang::ASTNodeStruct* currStructNode, u64 offset) {
- u64 startOffset = offset;
-
- for (auto &node : currStructNode->getNodes()) {
- auto var = static_cast(node);
-
- if (var->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
- size_t size = static_cast(var->getVariableType()) >> 4;
-
- this->m_hexEditor->setHighlight(offset, size);
- offset += size;
- } else {
- bool foundType = false;
- for (auto &structNode : findNodes(lang::ASTNode::Type::Struct, ast))
- if (structNode->getName() == var->getCustomVariableTypeName()) {
- auto size = this->highlightStruct(ast, structNode, offset);
-
- if (size == -1)
- return -1;
-
- offset += size;
- foundType = true;
- break;
- }
-
- for (auto &typeDeclNode : findNodes(lang::ASTNode::Type::TypeDecl, ast))
- if (typeDeclNode->getTypeName() == var->getCustomVariableTypeName()) {
- auto size = this->highlightUsingDecls(ast, typeDeclNode, offset);
-
- if (size == -1)
- return -1;
-
- offset = size;
- foundType = true;
- break;
- }
-
- if (!foundType)
- return -1;
- }
-
- }
-
- return offset - startOffset;
- }
+ s32 highlightUsingDecls(std::vector &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDec, u64 offset);
+ s32 highlightStruct(std::vector &ast, lang::ASTNodeStruct* currStructNode, u64 offset);
};
}
\ No newline at end of file
diff --git a/include/views/view_pattern_data.hpp b/include/views/view_pattern_data.hpp
new file mode 100644
index 000000000..91294ed0c
--- /dev/null
+++ b/include/views/view_pattern_data.hpp
@@ -0,0 +1,29 @@
+#pragma once
+
+#include
+
+#include "imgui.h"
+#include "views/view.hpp"
+#include "views/highlight.hpp"
+
+#include
+#include
+#include
+
+namespace hex {
+
+ class ViewPatternData : public View {
+ public:
+ ViewPatternData(FILE* &file,std::vector &highlights);
+ virtual ~ViewPatternData();
+
+ virtual void createView() override;
+ virtual void createMenu() override;
+
+ private:
+ FILE* &m_file;
+ std::vector &m_highlights;
+ bool m_windowOpen = true;
+ };
+
+}
\ No newline at end of file
diff --git a/include/window.hpp b/include/window.hpp
index 093caee11..8ade17b98 100644
--- a/include/window.hpp
+++ b/include/window.hpp
@@ -18,8 +18,8 @@ namespace hex {
void loop();
template T, typename ... Args>
- T* addView(Args& ... args) {
- this->m_views.emplace_back(new T(args...));
+ T* addView(Args&& ... args) {
+ this->m_views.emplace_back(new T(std::forward(args)...));
return static_cast(this->m_views.back());
}
diff --git a/source/main.cpp b/source/main.cpp
index 7d387eea0..6cfa41889 100644
--- a/source/main.cpp
+++ b/source/main.cpp
@@ -1,13 +1,24 @@
#include "window.hpp"
+#include "views/highlight.hpp"
#include "views/view_hexeditor.hpp"
#include "views/view_pattern.hpp"
+#include "views/view_pattern_data.hpp"
+
+#include
+#include
int main() {
hex::Window window;
- auto* hexEditor = window.addView();
- window.addView(hexEditor);
+ // Shared Data
+ std::vector highlights;
+ FILE *file = nullptr;
+
+ // Create views
+ window.addView(file, highlights);
+ window.addView(highlights);
+ window.addView(file, highlights);
window.loop();
diff --git a/source/utils.cpp b/source/utils.cpp
new file mode 100644
index 000000000..e5f3d519a
--- /dev/null
+++ b/source/utils.cpp
@@ -0,0 +1,43 @@
+#include "utils.hpp"
+
+namespace hex {
+
+ std::optional openFileDialog() {
+ HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
+ if (SUCCEEDED(hr)) {
+ IFileOpenDialog *pFileOpen;
+
+ hr = CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_ALL, IID_IFileOpenDialog, reinterpret_cast(&pFileOpen));
+
+ if (SUCCEEDED(hr)) {
+ hr = pFileOpen->Show(nullptr);
+
+ if (SUCCEEDED(hr)) {
+ IShellItem *pItem;
+ hr = pFileOpen->GetResult(&pItem);
+
+ if (SUCCEEDED(hr)) {
+ PWSTR pszFilePath;
+ hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
+
+ if (SUCCEEDED(hr)) {
+ std::wstring_convert, wchar_t> converter;
+
+ std::string result = converter.to_bytes(pszFilePath);
+
+ CoTaskMemFree(pszFilePath);
+
+ return result;
+ }
+ pItem->Release();
+ }
+ }
+ pFileOpen->Release();
+ }
+ CoUninitialize();
+ }
+
+ return { };
+ }
+
+}
\ No newline at end of file
diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp
new file mode 100644
index 000000000..01d7aed6d
--- /dev/null
+++ b/source/views/view_hexeditor.cpp
@@ -0,0 +1,85 @@
+#include "views/view_hexeditor.hpp"
+
+namespace hex {
+
+ ViewHexEditor::ViewHexEditor(FILE *&file, std::vector &highlights)
+ : View(), m_file(file), m_highlights(highlights) {
+
+ this->m_memoryEditor.ReadFn = [](const ImU8 *data, size_t off) -> ImU8 {
+ ViewHexEditor *_this = (ViewHexEditor *) data;
+
+ if (_this->m_file == nullptr)
+ return 0x00;
+
+ fseek(_this->m_file, off, SEEK_SET);
+
+ ImU8 byte;
+ fread(&byte, sizeof(ImU8), 1, _this->m_file);
+
+ return byte;
+ };
+
+ this->m_memoryEditor.WriteFn = [](ImU8 *data, size_t off, ImU8 d) -> void {
+ ViewHexEditor *_this = (ViewHexEditor *) data;
+
+ if (_this->m_file == nullptr)
+ return;
+
+ fseek(_this->m_file, off, SEEK_SET);
+
+ fwrite(&d, sizeof(ImU8), 1, _this->m_file);
+
+ };
+
+ this->m_memoryEditor.HighlightFn = [](const ImU8 *data, size_t off, bool next) -> bool {
+ ViewHexEditor *_this = (ViewHexEditor *) data;
+
+ for (auto&[offset, size, color, name] : _this->m_highlights) {
+ if (next && off == (offset + size)) {
+ return false;
+ }
+
+ if (off >= offset && off < (offset + size)) {
+ _this->m_memoryEditor.HighlightColor = color;
+ return true;
+ }
+ }
+
+ _this->m_memoryEditor.HighlightColor = 0x50C08080;
+ return false;
+ };
+ }
+
+ ViewHexEditor::~ViewHexEditor() {}
+
+ void ViewHexEditor::createView() {
+ this->m_memoryEditor.DrawWindow("Hex Editor", this, this->m_file == nullptr ? 0x00 : this->m_fileSize);
+ }
+
+ void ViewHexEditor::createMenu() {
+ if (ImGui::BeginMenu("File")) {
+ if (ImGui::MenuItem("Open File...")) {
+ auto filePath = openFileDialog();
+ if (filePath.has_value()) {
+ if (this->m_file != nullptr)
+ fclose(this->m_file);
+
+ this->m_file = fopen(filePath->c_str(), "r+b");
+
+ fseek(this->m_file, 0, SEEK_END);
+ this->m_fileSize = ftell(this->m_file);
+ rewind(this->m_file);
+ }
+
+ }
+
+ ImGui::EndMenu();
+ }
+
+ if (ImGui::BeginMenu("Window")) {
+ ImGui::MenuItem("Hex View", "", &this->m_memoryEditor.Open);
+ ImGui::EndMenu();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp
new file mode 100644
index 000000000..f3568ee11
--- /dev/null
+++ b/source/views/view_pattern.cpp
@@ -0,0 +1,210 @@
+#include
+#include "views/view_pattern.hpp"
+
+#include "utils.hpp"
+
+namespace hex {
+
+ ViewPattern::ViewPattern(std::vector &highlights) : View(), m_highlights(highlights) {
+ this->m_buffer = new char[0xFFFFFF];
+ std::memset(this->m_buffer, 0x00, 0xFFFFFF);
+ }
+ ViewPattern::~ViewPattern() {
+ delete[] this->m_buffer;
+ }
+
+ void ViewPattern::createMenu() {
+ if (ImGui::BeginMenu("File")) {
+ if (ImGui::MenuItem("Load pattern...")) {
+ auto filePath = openFileDialog();
+ if (filePath.has_value()) {
+ FILE *file = fopen(filePath->c_str(), "r+b");
+
+ fseek(file, 0, SEEK_END);
+ size_t size = ftell(file);
+ rewind(file);
+
+ if (size > 0xFF'FFFF)
+ return;
+
+ fread(this->m_buffer, size, 1, file);
+
+ fclose(file);
+
+ this->parsePattern(this->m_buffer);
+ }
+
+ }
+ ImGui::EndMenu();
+ }
+
+ if (ImGui::BeginMenu("Window")) {
+ ImGui::MenuItem("Pattern View", "", &this->m_windowOpen);
+ ImGui::EndMenu();
+ }
+ }
+
+ void ViewPattern::createView() {
+ if (!this->m_windowOpen)
+ return;
+
+ ImGui::Begin("Pattern", &this->m_windowOpen, ImGuiWindowFlags_None);
+ ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
+ ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
+
+ auto size = ImGui::GetWindowSize();
+ size.y -= 50;
+ ImGui::InputTextMultiline("Pattern", this->m_buffer, 0xFFFF, size, ImGuiInputTextFlags_AllowTabInput | ImGuiInputTextFlags_CallbackEdit,
+ [](ImGuiInputTextCallbackData* data) -> int {
+ auto _this = static_cast(data->UserData);
+
+ _this->parsePattern(data->Buf);
+
+ return 0;
+ }, this
+ );
+
+ ImGui::PopStyleVar(2);
+ ImGui::End();
+ }
+
+
+ void ViewPattern::setHighlight(u64 offset, size_t size, std::string name, u32 color) {
+ if (color == 0)
+ color = std::mt19937(std::random_device()())();
+
+ color &= ~0xFF00'0000;
+ color |= 0x5000'0000;
+
+ this->m_highlights.emplace_back(offset, size, color, name);
+ }
+
+ template T>
+ static std::vector findNodes(const lang::ASTNode::Type type, const std::vector &nodes) {
+ std::vector result;
+
+ for (const auto & node : nodes)
+ if (node->getType() == type)
+ result.push_back(static_cast(node));
+
+ return result;
+ }
+
+ void ViewPattern::parsePattern(char *buffer) {
+ static hex::lang::Lexer lexer;
+ static hex::lang::Parser parser;
+
+ this->m_highlights.clear();
+
+ auto [lexResult, tokens] = lexer.lex(buffer);
+
+ if (lexResult.failed()) {
+ return;
+ }
+
+ auto [parseResult, ast] = parser.parse(tokens);
+ if (parseResult.failed()) {
+ for(auto &node : ast) delete node;
+ return;
+ }
+
+ for (auto &varNode : findNodes(lang::ASTNode::Type::VariableDecl, ast)) {
+ if (!varNode->getOffset().has_value())
+ continue;
+
+ u64 offset = varNode->getOffset().value();
+ if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
+ this->setHighlight(offset, static_cast(varNode->getVariableType()) >> 4, varNode->getVariableName());
+ } else {
+ for (auto &structNode : findNodes(lang::ASTNode::Type::Struct, ast))
+ if (varNode->getCustomVariableTypeName() == structNode->getName())
+ if (this->highlightStruct(ast, structNode, offset) == -1)
+ this->m_highlights.clear();
+
+ for (auto &usingNode : findNodes(lang::ASTNode::Type::TypeDecl, ast))
+ if (varNode->getCustomVariableTypeName() == usingNode->getTypeName())
+ if (this->highlightUsingDecls(ast, usingNode, varNode, offset) == -1)
+ this->m_highlights.clear();
+ }
+
+ }
+
+ for(auto &node : ast) delete node;
+ }
+
+ s32 ViewPattern::highlightUsingDecls(std::vector &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset) {
+ if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) {
+ size_t size = static_cast(currTypeDeclNode->getAssignedType()) >> 4;
+
+ this->setHighlight(offset, size, currVarDecl->getVariableName());
+ offset += size;
+ } else {
+ bool foundType = false;
+ for (auto &structNode : findNodes(lang::ASTNode::Type::Struct, ast))
+ if (structNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
+ offset = this->highlightStruct(ast, structNode, offset);
+ foundType = true;
+ break;
+ }
+
+ for (auto &typeDeclNode : findNodes(lang::ASTNode::Type::TypeDecl, ast))
+ if (typeDeclNode->getTypeName() == currTypeDeclNode->getAssignedCustomTypeName()) {
+ offset = this->highlightUsingDecls(ast, typeDeclNode, currVarDecl, offset);
+ foundType = true;
+ break;
+ }
+
+ if (!foundType)
+ return -1;
+ }
+
+ return offset;
+ }
+
+ s32 ViewPattern::highlightStruct(std::vector &ast, lang::ASTNodeStruct* currStructNode, u64 offset) {
+ u64 startOffset = offset;
+
+ for (auto &node : currStructNode->getNodes()) {
+ auto var = static_cast(node);
+
+ if (var->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
+ size_t size = static_cast(var->getVariableType()) >> 4;
+
+ this->setHighlight(offset, size, var->getVariableName());
+ offset += size;
+ } else {
+ bool foundType = false;
+ for (auto &structNode : findNodes(lang::ASTNode::Type::Struct, ast))
+ if (structNode->getName() == var->getCustomVariableTypeName()) {
+ auto size = this->highlightStruct(ast, structNode, offset);
+
+ if (size == -1)
+ return -1;
+
+ offset += size;
+ foundType = true;
+ break;
+ }
+
+ for (auto &typeDeclNode : findNodes(lang::ASTNode::Type::TypeDecl, ast))
+ if (typeDeclNode->getTypeName() == var->getCustomVariableTypeName()) {
+ auto size = this->highlightUsingDecls(ast, typeDeclNode, var, offset);
+
+ if (size == -1)
+ return -1;
+
+ offset = size;
+ foundType = true;
+ break;
+ }
+
+ if (!foundType)
+ return -1;
+ }
+
+ }
+
+ return offset - startOffset;
+ }
+
+}
\ No newline at end of file
diff --git a/source/views/view_pattern_data.cpp b/source/views/view_pattern_data.cpp
new file mode 100644
index 000000000..b3129bc04
--- /dev/null
+++ b/source/views/view_pattern_data.cpp
@@ -0,0 +1,49 @@
+#include "views/view_pattern_data.hpp"
+
+#include
+
+namespace hex {
+
+ ViewPatternData::ViewPatternData(FILE* &file, std::vector &highlights)
+ : View(), m_file(file), m_highlights(highlights) {
+
+ }
+
+ ViewPatternData::~ViewPatternData() {
+
+ }
+
+
+ void ViewPatternData::createView() {
+ if (!this->m_windowOpen)
+ return;
+
+ if (ImGui::Begin("Pattern Data", &this->m_windowOpen)) {
+ ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav);
+
+ for (auto& [offset, size, color, name] : this->m_highlights) {
+ std::vector buffer(size + 1, 0x00);
+ u64 data = 0;
+ fseek(this->m_file, offset, SEEK_SET);
+ fread(buffer.data(), 1, size, this->m_file);
+ std::memcpy(&data, buffer.data(), size);
+
+ if (size <= 8)
+ ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] %lu (0x%lx) \"%s\"", offset, offset + size, data, data, buffer.data());
+ else
+ ImGui::LabelText(name.c_str(), "[0x%08lx:0x%08lx] [ ARRAY ]", offset, offset + size);
+ }
+
+ ImGui::EndChild();
+ ImGui::End();
+ }
+ }
+
+ void ViewPatternData::createMenu() {
+ if (ImGui::BeginMenu("Window")) {
+ ImGui::MenuItem("Data View", "", &this->m_windowOpen);
+ ImGui::EndMenu();
+ }
+ }
+
+}
\ No newline at end of file