summaryrefslogtreecommitdiff
path: root/src/GUI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/GUI.cpp')
-rw-r--r--src/GUI.cpp194
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();
+}