diff options
| author | 0x221E <0x221E@0xinfinity.dev> | 2026-04-12 16:59:40 +0200 |
|---|---|---|
| committer | 0x221E <0x221E@0xinfinity.dev> | 2026-04-12 16:59:40 +0200 |
| commit | a66c7433c2c11b8b6c99142277ed4e16b1a2a465 (patch) | |
| tree | e54bcfb59c303acf6118fd11f06d5c0bd5f24e5d /src/GUI.cpp | |
Diffstat (limited to 'src/GUI.cpp')
| -rw-r--r-- | src/GUI.cpp | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/src/GUI.cpp b/src/GUI.cpp new file mode 100644 index 0000000..4601e99 --- /dev/null +++ b/src/GUI.cpp @@ -0,0 +1,194 @@ +#include "GUI.h" + +#include <imgui.h> +#include <imgui_internal.h> +#include <backends/imgui_impl_glfw.h> +#include <backends/imgui_impl_opengl3.h> +#include <imgui_memory_editor.h> +#include <glad/glad.h> +#include <GLFW/glfw3.h> +#include <cstdlib> +#include <iostream> +#include "Userspace.h" + +void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) + { + glfwSetWindowShouldClose(window, true); + return; + } +} + +GUI::GUI(Userspace& user) :m_Userspace(user) { + if(!glfwInit()) + exit(1); + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + + CreateWindow(); +} + +void GUI::CreateWindow() { + m_Window = glfwCreateWindow(1200, 800, "CPUSecX86", NULL, NULL); + if(!m_Window) + { + glfwTerminate(); + return; + } + + glfwMakeContextCurrent(m_Window); + glfwSetKeyCallback(m_Window, key_callback); + ImGui::CreateContext(); + + int version = gladLoadGL(); + std::cout << "OpenGL Version: " << std::dec << version << std::endl; + + ImGui_ImplGlfw_InitForOpenGL(m_Window, true); + ImGui_ImplOpenGL3_Init("#version 460"); + + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + io.FontGlobalScale = 1.5f; +} + +void GUI::Run() { + while (!glfwWindowShouldClose(m_Window)) { + glfwPollEvents(); + + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + DockingSetup(); + + ControlGUI(); + DebugInfoGUI(); + + static MemoryEditor process_mem; + size_t data_size = 0x10000; + process_mem.DrawWindow("Process Memory", m_Userspace.RetrieveMemory(), data_size); + + if(m_Userspace.GetSystemStatus() == SystemStatus::EXCEPTION) + ErrorGUI(); + + glClear(GL_COLOR_BUFFER_BIT); + + ImGui::Render(); + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + + glfwSwapBuffers(m_Window); + } + + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); +} + +void GUI::Terminate() { + glfwDestroyWindow(m_Window); + glfwTerminate(); +} + +void GUI::DockingSetup() { + ImGuiID dockspace_id = ImGui::GetID("Dockspace"); + ImGuiViewport *viewport = ImGui::GetMainViewport(); + + if (ImGui::DockBuilderGetNode(dockspace_id) == nullptr) { + ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace); + ImGui::DockBuilderSetNodeSize(dockspace_id, viewport->Size); + ImGuiID dock_id_left = 0; + ImGuiID dock_id_main = dockspace_id; + ImGui::DockBuilderSplitNode(dock_id_main, ImGuiDir_Left, 0.40f, &dock_id_left, &dock_id_main); + ImGuiID dock_id_right = 0; + ImGui::DockBuilderSplitNode(dock_id_main, ImGuiDir_Right, 0.40f, &dock_id_right, &dock_id_main); + // ImGuiID dock_id_left_top = 0; + // ImGuiID dock_id_left_bottom = 0; + // ImGui::DockBuilderSplitNode(dock_id_left, ImGuiDir_Up, 0.50f, &dock_id_left_top, &dock_id_left_bottom); + ImGui::DockBuilderDockWindow("Process Memory", dock_id_main); + ImGui::DockBuilderDockWindow("Debug Information", dock_id_left); + ImGui::DockBuilderDockWindow("Emulator Control", dock_id_right); + ImGui::DockBuilderFinish(dockspace_id); + } + + ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_NoTabBar; + dockspace_flags |= ImGuiDockNodeFlags_PassthruCentralNode; + + ImGui::DockSpaceOverViewport(dockspace_id, viewport, dockspace_flags); +} + +void GUI::ControlGUI() { + ImGui::Begin("Emulator Control"); + static std::string state = "STOPPED"; + if (m_Userspace.GetSystemStatus() == SystemStatus::STOPPED) + state = "STOPPED"; + else if (m_Userspace.GetSystemStatus() == SystemStatus::RUNNING) + state = "RUNNING"; + else if (m_Userspace.GetSystemStatus() == SystemStatus::EXCEPTION) + state = "EXCEPTION"; + + ImGui::Text("Current State: %s", state.c_str()); + if(ImGui::Button("Start")) + m_Userspace.Start(); + ImGui::SameLine(); + if(ImGui::Button("Stop")) + m_Userspace.Stop(); + ImGui::SameLine(); + if (ImGui::Button("Reset")) + m_Userspace.Reset(); + if(ImGui::Button("Step")) + m_Userspace.Step(); + ImGui::End(); +} + +void GUI::ErrorGUI() { + ImGui::PushStyleColor(ImGuiCol_TitleBg, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_Border, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_TitleBgActive, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); + ImGui::PushStyleColor(ImGuiCol_ResizeGrip, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); + ImGui::Begin("Exception"); + ImGui::Text("An exception was detected! Trace:"); + auto& e = m_Userspace.GetException(); + for (auto i : e) + ImGui::Text("Err: %s", i.c_str()); + ImGui::End(); + ImGui::PopStyleColor(4); +} + +void GUI::DebugInfoGUI() { + ImGuiInputTextFlags flags = ImGuiInputTextFlags_CharsHexadecimal; + if (m_Userspace.GetSystemStatus() == SystemStatus::RUNNING) flags |= ImGuiInputTextFlags_ReadOnly; + CPUStatus status = m_Userspace.GetCPUStatus(); + + ImGui::Begin("Debug Information"); + ImGui::Text("GP Registers"); + ImGui::InputScalar("EAX", ImGuiDataType_U32, &status.m_Registers[0], NULL, NULL, "%08X", flags); + ImGui::InputScalar("ECX", ImGuiDataType_U32, &status.m_Registers[1], NULL, NULL, "%08X", flags); + ImGui::InputScalar("EDX", ImGuiDataType_U32, &status.m_Registers[2], NULL, NULL, "%08X", flags); + ImGui::InputScalar("EBX", ImGuiDataType_U32, &status.m_Registers[3], NULL, NULL, "%08X", flags); + ImGui::InputScalar("ESP", ImGuiDataType_U32, &status.m_Registers[4], NULL, NULL, "%08X", flags); + ImGui::InputScalar("EBP", ImGuiDataType_U32, &status.m_Registers[5], NULL, NULL, "%08X", flags); + ImGui::InputScalar("ESI", ImGuiDataType_U32, &status.m_Registers[6], NULL, NULL, "%08X", flags); + ImGui::InputScalar("EDI", ImGuiDataType_U32, &status.m_Registers[7], NULL, NULL, "%08X", flags); + ImGui::Separator(); + ImGui::Text("Other Registers"); + ImGui::InputScalar("IP", ImGuiDataType_U32, &status.m_IP, NULL, NULL, "%08X", flags); + ImGui::Separator(); + ImGui::Text("Instruction Information"); + ImGui::Text("Instruction Length: %d", status.m_Instruction.m_Length); + ImGui::Text("Opcode: %s", Opcode2Str(status.m_Instruction.m_Opcode).c_str()); + ImGui::Text("Operand1: %x", status.m_Instruction.m_Operand1); + ImGui::Text("Operand2: %x", status.m_Instruction.m_Operand2); + ImGui::Text("ModRM R/M: %d", status.m_Instruction.m_ModRM.m_Rm); + ImGui::Text("ModRM R: %d", status.m_Instruction.m_ModRM.m_Reg); + ImGui::Text("ModRM Status: %d", status.m_Instruction.m_ModRM.m_State); + ImGui::Text("SIB Scale: %x", status.m_Instruction.m_SIB.m_Scale); + ImGui::Text("SIB Index: %x", status.m_Instruction.m_SIB.m_Index); + ImGui::Text("SIB Base: %x", status.m_Instruction.m_SIB.m_Base); + ImGui::End(); +} + +GUI::~GUI() { + Terminate(); +} |
