feat(gui): Enhance CPU panel with state management and GUI improvements

This commit is contained in:
Carlo Pezzotti 2025-07-09 11:51:13 +02:00
parent 2bb666a088
commit 85559e249b
9 changed files with 340 additions and 302 deletions

View file

@ -40,4 +40,9 @@ struct CPU {
LOG_INFO(ARM, "X{} = {}", reg, x(reg)); // X0 = 0... LOG_INFO(ARM, "X{} = {}", reg, x(reg)); // X0 = 0...
} }
} }
void get_state(u64* out_regs, u64& out_pc) const {
std::memcpy(out_regs, regs, sizeof(regs));
out_pc = pc;
}
}; };

View file

@ -14,75 +14,105 @@
#include "gui/panels/CPUPanel.h" #include "gui/panels/CPUPanel.h"
#include "gui/panels/PerformancePanel.h" #include "gui/panels/PerformancePanel.h"
std::shared_ptr<Pound::GUI::ConsolePanel> console_panel;
std::shared_ptr<Pound::GUI::CPUPanel> cpu_panel;
std::shared_ptr<Pound::GUI::PerformancePanel> performance_panel;
// CPU test function // CPU test function
void cpuTest() { void cpuTest()
{
CPU cpu; CPU cpu;
cpu.pc = 0; cpu.pc = 0;
// Simple ARMv8 program in memory (MOVZ X0, #5; ADD X0, X0, #3; RET)
// These are placeholders; real encoding will be parsed later
cpu.write_byte(0, 0x05); // MOVZ placeholder cpu.write_byte(0, 0x05); // MOVZ placeholder
cpu.write_byte(4, 0x03); // ADD placeholder cpu.write_byte(4, 0x03); // ADD placeholder
cpu.write_byte(8, 0xFF); // RET placeholder cpu.write_byte(8, 0xFF); // RET placeholder
LOG_INFO(ARM, "{}", cpu.read_byte(0)); LOG_INFO(ARM, "{}", cpu.read_byte(0));
JIT jit; JIT jit;
jit.translate_and_run(cpu); jit.translate_and_run(cpu);
cpu.print_debug_information(); cpu.print_debug_information();
LOG_INFO(ARM, "X0 = {}", cpu.x(0)); LOG_INFO(ARM, "X0 = {}", cpu.x(0));
if (cpu_panel)
cpu_panel->UpdateState(cpu);
} }
int main() { void initGUI(Pound::GUI::GUIManager *gui_manager)
{
gui_manager->AddPanel(console_panel);
gui_manager->AddPanel(cpu_panel);
gui_manager->AddPanel(performance_panel);
Pound::GUI::TabBar *file_menu = gui_manager->AddTabs("File");
Pound::GUI::TabBar *emulation_menu = gui_manager->AddTabs("Emulation");
Pound::GUI::TabBar *view_menu = gui_manager->AddTabs("View");
Pound::GUI::TabBar *help_menu = gui_manager->AddTabs("Help");
gui_manager->AddSubTab(file_menu, "Open ROM...", []() {});
gui_manager->AddSubTab(file_menu, "Exit", []()
{
LOG_INFO(Render, "Exiting Pound Emulator");
std::exit(0); });
gui_manager->AddSubTab(emulation_menu, "Run CPU Test", []()
{ cpuTest(); });
gui_manager->AddSubTab(emulation_menu, "Pause", []()
{ LOG_INFO(Render, "Pausing emulation (not implemented yet)"); });
gui_manager->AddSubTab(emulation_menu, "Resume", []()
{ LOG_INFO(Render, "Resuming emulation (not implemented yet)"); });
gui_manager->AddSubTab(view_menu, "Console", console_panel->IsVisible(),
[console_panel](bool is_checked)
{
console_panel->SetVisible(is_checked);
});
gui_manager->AddSubTab(view_menu, "CPU State", cpu_panel->IsVisible(),
[cpu_panel](bool is_checked)
{
cpu_panel->SetVisible(is_checked);
});
gui_manager->AddSubTab(view_menu, "Performance", performance_panel->IsVisible(),
[performance_panel](bool is_checked)
{
performance_panel->SetVisible(is_checked);
});
gui_manager->AddSubTab(help_menu, "About", []()
{ LOG_INFO(Render, "Pound Emulator is a pre-alpha project. Visit our GitHub for more information."); });
cpu_panel->SetCPUTestCallback(cpuTest);
console_panel->AddLog("[INFO] Pound Emulator started");
console_panel->AddLog("[INFO] Version: Pre-Alpha");
}
int main()
{
Base::Log::Initialize(); Base::Log::Initialize();
Base::Log::Start(); Base::Log::Start();
const auto config_dir = Base::FS::GetUserPath(Base::FS::PathType::BinaryDir); const auto config_dir = Base::FS::GetUserPath(Base::FS::PathType::BinaryDir);
Config::Load(config_dir / "config.toml"); Config::Load(config_dir / "config.toml");
// Create GUI manager
auto gui_manager = std::make_unique<Pound::GUI::GUIManager>(); auto gui_manager = std::make_unique<Pound::GUI::GUIManager>();
if (!gui_manager->Initialize("Pound Emulator", Config::windowWidth(), Config::windowHeight()))
// Initialize GUI {
if (!gui_manager->Initialize("Pound Emulator", Config::windowWidth(), Config::windowHeight())) {
LOG_ERROR(Render, "Failed to initialize GUI"); LOG_ERROR(Render, "Failed to initialize GUI");
return -1; return -1;
} }
// Create and add panels console_panel = std::make_shared<Pound::GUI::ConsolePanel>();
auto console_panel = std::make_shared<Pound::GUI::ConsolePanel>(); cpu_panel = std::make_shared<Pound::GUI::CPUPanel>();
auto cpu_panel = std::make_shared<Pound::GUI::CPUPanel>(); performance_panel = std::make_shared<Pound::GUI::PerformancePanel>();
auto performance_panel = std::make_shared<Pound::GUI::PerformancePanel>();
gui_manager->AddPanel(console_panel); initGUI(gui_manager.get());
gui_manager->AddPanel(cpu_panel);
gui_manager->AddPanel(performance_panel);
// Set up callbacks while (gui_manager->IsRunning())
auto cpu_test_callback = [console_panel]() { {
console_panel->AddLog("[INFO] Running CPU test...");
cpuTest();
console_panel->AddLog("[INFO] CPU test completed. Check terminal for details.");
};
gui_manager->SetCPUTestCallback(cpu_test_callback);
cpu_panel->SetCPUTestCallback(cpu_test_callback);
// Add initial console message
console_panel->AddLog("[INFO] Pound Emulator started");
console_panel->AddLog("[INFO] Version: Pre-Alpha");
// Main loop
while (gui_manager->IsRunning()) {
gui_manager->RunFrame(); gui_manager->RunFrame();
// Small delay to prevent excessive CPU usage
std::this_thread::sleep_for(std::chrono::milliseconds(5)); std::this_thread::sleep_for(std::chrono::milliseconds(5));
} }
// Cleanup
gui_manager->Shutdown(); gui_manager->Shutdown();
return 0; return 0;

View file

@ -34,6 +34,7 @@ namespace Pound::GUI
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO &io = ImGui::GetIO(); ImGuiIO &io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
// io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
// Setup style // Setup style
ApplyTheme(); ApplyTheme();
@ -69,11 +70,8 @@ namespace Pound::GUI
window->ProcessEvents(); window->ProcessEvents();
BeginFrame(); BeginFrame();
RenderTabBars();
// Render menu bar
RenderMainMenuBar();
// Render all panels
for (auto &panel : panels) for (auto &panel : panels)
{ {
if (panel->IsVisible()) if (panel->IsVisible())
@ -82,7 +80,6 @@ namespace Pound::GUI
} }
} }
// Demo window for debugging
if (show_demo_window) if (show_demo_window)
{ {
ImGui::ShowDemoWindow(&show_demo_window); ImGui::ShowDemoWindow(&show_demo_window);
@ -112,85 +109,6 @@ namespace Pound::GUI
window->SwapBuffers(); window->SwapBuffers();
} }
void GUIManager::RenderMainMenuBar()
{
if (ImGui::BeginMainMenuBar())
{
if (ImGui::BeginMenu("File"))
{
if (ImGui::MenuItem("Load ROM...", "Ctrl+O"))
{
// TODO: Implement ROM loading
}
ImGui::Separator();
if (ImGui::MenuItem("Exit", "Alt+F4"))
{
window->SetShouldClose(true);
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Emulation"))
{
if (ImGui::MenuItem("Run CPU Test"))
{
if (cpu_test_callback)
{
cpu_test_callback();
}
}
ImGui::Separator();
if (ImGui::MenuItem("Pause", "F5"))
{
// TODO: Implement pause
}
if (ImGui::MenuItem("Reset", "F6"))
{
// TODO: Implement reset
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("View"))
{
for (auto &panel : panels)
{
bool visible = panel->IsVisible();
if (ImGui::MenuItem(panel->GetName().c_str(), nullptr, &visible))
{
panel->SetVisible(visible);
}
}
ImGui::Separator();
if (ImGui::MenuItem("ImGui Demo", nullptr, &show_demo_window))
{
// Toggle handled by flag
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Tools"))
{
if (ImGui::MenuItem("Settings", "Ctrl+,"))
{
// TODO: Open settings panel
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help"))
{
if (ImGui::MenuItem("About"))
{
// TODO: Show about dialog
}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
}
}
void GUIManager::ApplyTheme() void GUIManager::ApplyTheme()
{ {
ImGuiStyle &style = ImGui::GetStyle(); ImGuiStyle &style = ImGui::GetStyle();
@ -272,4 +190,114 @@ namespace Pound::GUI
}), }),
panels.end()); panels.end());
} }
TabBar *GUIManager::AddTabs(const std::string &name)
{
auto new_bar = std::make_unique<TabBar>();
new_bar->id = name;
m_tab_bars.push_back(std::move(new_bar));
return m_tab_bars.back().get();
}
void GUIManager::AddSubTab(TabBar *parent_bar, const std::string &name, std::function<void()> callback)
{
if (!parent_bar)
{
LOG_WARNING(Render, "Trying to add a sub-tab to a null TabBar.");
return;
}
TabItem new_item;
new_item.name = name;
new_item.render_callback = std::move(callback);
parent_bar->items.push_back(std::move(new_item));
}
void GUIManager::AddSubTab(TabBar *parent_bar, const std::string &name, const std::string &shortcut, std::function<void()> callback)
{
if (!parent_bar)
{
LOG_WARNING(Render, "Trying to add a sub-tab to a null TabBar.");
return;
}
TabItem new_item;
new_item.name = name;
new_item.shortcut = shortcut;
new_item.render_callback = std::move(callback);
parent_bar->items.push_back(std::move(new_item));
}
void GUIManager::AddSubTab(TabBar *parent_bar, const std::string &name, bool *p_selected, std::function<void(bool)> callback)
{
if (!parent_bar)
{
LOG_WARNING(Render, "Trying to add a sub-tab to a null TabBar.");
return;
}
TabItem new_item;
new_item.name = name;
new_item.p_selected = p_selected;
new_item.checked_callback = std::move(callback);
parent_bar->items.push_back(std::move(new_item));
}
void GUIManager::AddSubTab(TabBar *parent_bar, const std::string &name, bool *p_selected, const std::string &shortcut, std::function<void(bool)> callback)
{
if (!parent_bar)
{
LOG_WARNING(Render, "Trying to add a sub-tab to a null TabBar.");
return;
}
TabItem new_item;
new_item.name = name;
new_item.shortcut = shortcut;
new_item.p_selected = p_selected;
new_item.checked_callback = std::move(callback);
parent_bar->items.push_back(std::move(new_item));
}
void GUIManager::RenderTabBarContents(TabBar &bar)
{
for (const auto &item : bar.items)
{
if (item.nested_tabs)
{
if (ImGui::BeginMenu(item.name.c_str()))
{
RenderTabBarContents(*item.nested_tabs);
ImGui::EndMenu();
}
}
else
{
const char *shortcut = item.shortcut.empty() ? nullptr : item.shortcut.c_str();
if (ImGui::MenuItem(item.name.c_str(), shortcut, item.p_selected))
{
if (item.p_selected && item.checked_callback)
{
item.checked_callback(*item.p_selected);
}
}
}
}
}
void GUIManager::RenderTabBars()
{
if (ImGui::BeginMainMenuBar())
{
for (const auto &bar_ptr : m_tab_bars)
{
if (ImGui::BeginMenu(bar_ptr->id.c_str()))
{
RenderTabBarContents(*bar_ptr);
ImGui::EndMenu();
}
}
ImGui::EndMainMenuBar();
}
}
} }

View file

@ -7,38 +7,63 @@
#include "Window.h" #include "Window.h"
#include "Panel.h" #include "Panel.h"
namespace Pound::GUI { namespace Pound::GUI
{
class GUIManager { struct TabBar;
public:
GUIManager();
~GUIManager();
bool Initialize(const std::string& title, int width, int height); struct TabItem
void Shutdown(); {
std::string name;
std::string shortcut;
bool *p_selected = nullptr;
std::function<void()> render_callback;
std::function<void(bool)> checked_callback;
std::unique_ptr<TabBar> nested_tabs = nullptr;
};
void RunFrame(); struct TabBar
bool IsRunning() const { return running && window && !window->ShouldClose(); } {
std::string id;
std::vector<TabItem> items;
bool is_visible = true;
};
void AddPanel(std::shared_ptr<Panel> panel); class GUIManager
void RemovePanel(const std::string& name); {
public:
GUIManager();
~GUIManager();
// Callback for external systems bool Initialize(const std::string &title, int width, int height);
void SetCPUTestCallback(std::function<void()> callback) { cpu_test_callback = callback; } void Shutdown();
private: void RunFrame();
void BeginFrame(); bool IsRunning() const { return running && window && !window->ShouldClose(); }
void EndFrame();
void RenderMainMenuBar();
void ApplyTheme();
std::unique_ptr<Window> window; Window *GetWindow() const { return window.get(); }
std::vector<std::shared_ptr<Panel>> panels;
bool running = false;
bool show_demo_window = false;
// Callbacks void AddPanel(std::shared_ptr<Panel> panel);
std::function<void()> cpu_test_callback; void RemovePanel(const std::string &name);
};
TabBar *AddTabs(const std::string &name);
void AddSubTab(TabBar *parent_bar, const std::string &name, std::function<void()> callback = nullptr);
void AddSubTab(TabBar *parent_bar, const std::string &name, const std::string &shortcut, std::function<void()> callback);
void AddSubTab(TabBar *parent_bar, const std::string &name, bool *p_selected, std::function<void(bool)> callback = nullptr);
void AddSubTab(TabBar *parent_bar, const std::string &name, bool *p_selected, const std::string &shortcut, std::function<void(bool)> callback = nullptr);
private:
void BeginFrame();
void EndFrame();
void ApplyTheme();
void RenderTabBars();
void RenderTabBarContents(TabBar &bar);
std::unique_ptr<Window> window;
std::vector<std::shared_ptr<Panel>> panels;
bool running = false;
bool show_demo_window = false;
std::vector<std::unique_ptr<TabBar>> m_tab_bars;
};
} // namespace Pound::GUI } // namespace Pound::GUI

View file

@ -16,7 +16,7 @@ namespace Pound::GUI
virtual void Render() = 0; virtual void Render() = 0;
const std::string &GetName() const { return name; } const std::string &GetName() const { return name; }
bool IsVisible() const { return visible; } bool* IsVisible() { return &visible; }
void SetVisible(bool vis) { visible = vis; } void SetVisible(bool vis) { visible = vis; }
protected: protected:

View file

@ -1,143 +1,86 @@
// Copyright 2025 Pound Emulator Project. All rights reserved. // In gui/panels/CPUPanel.cpp
#include "CPUPanel.h" #include "CPUPanel.h"
#include "../Colors.h" #include "../Colors.h"
#include <iomanip> #include <imgui.h>
#include <sstream> #include <cinttypes>
namespace Pound::GUI { namespace Pound::GUI
{
CPUPanel::CPUPanel() : Panel("CPU Debug") {}
CPUPanel::CPUPanel() : Panel("CPU Debug") {} void CPUPanel::UpdateState(const CPU& cpu)
{
void CPUPanel::Render() { cpu.get_state(cpu_state.registers.data(), cpu_state.pc);
if (!ImGui::Begin(name.c_str(), &visible, ImGuiWindowFlags_NoCollapse)) {
ImGui::End();
return;
} }
// Control buttons with custom colors void CPUPanel::SetCPUTestCallback(std::function<void()> callback)
ImGui::PushStyleColor(ImGuiCol_Button, Colors::WithAlpha(Colors::Primary, 0.40f)); {
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Colors::PrimaryHover); cpu_test_callback = std::move(callback);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, Colors::PrimaryActive); }
if (ImGui::Button("Run CPU Test", ImVec2(120, 0))) { void CPUPanel::Render()
if (cpu_test_callback) { {
cpu_test_callback(); if (!visible) {
show_test_result = true; return;
}
if (!ImGui::Begin(name.c_str(), &visible, ImGuiWindowFlags_NoCollapse))
{
ImGui::End();
return;
} }
}
ImGui::SameLine(); ImGui::PushStyleColor(ImGuiCol_Button, Colors::WithAlpha(Colors::Primary, 0.40f));
if (ImGui::Button("Step", ImVec2(60, 0))) { ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Colors::PrimaryHover);
// TODO: Implement step functionality ImGui::PushStyleColor(ImGuiCol_ButtonActive, Colors::PrimaryActive);
} if (ImGui::Button("Run CPU Test", ImVec2(120, 0)))
{
if (cpu_test_callback) {
cpu_test_callback();
show_test_result = true;
}
}
ImGui::PopStyleColor(3);
ImGui::Separator();
if (ImGui::BeginTabBar("CPUTabBar"))
{
if (ImGui::BeginTabItem("Registers"))
{
ImGui::Text("General Purpose Registers:");
ImGui::Separator();
if (ImGui::BeginTable("RegisterTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
{
ImGui::TableSetupColumn("Register"); ImGui::TableSetupColumn("Value");
ImGui::TableSetupColumn("Register"); ImGui::TableSetupColumn("Value");
ImGui::TableHeadersRow();
ImGui::SameLine(); for (int i = 0; i < 16; i++)
{
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0); ImGui::Text("X%d", i);
ImGui::TableSetColumnIndex(1); ImGui::Text("0x%016" PRIX64, cpu_state.registers[i]);
// Reset button with secondary color if (i + 16 < 31)
ImGui::PushStyleColor(ImGuiCol_Button, Colors::WithAlpha(Colors::Secondary, 0.40f)); {
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Colors::SecondaryHover); ImGui::TableSetColumnIndex(2); ImGui::Text("X%d", i + 16);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, Colors::SecondaryActive); ImGui::TableSetColumnIndex(3); ImGui::Text("0x%016" PRIX64, cpu_state.registers[i + 16]);
}
if (ImGui::Button("Reset", ImVec2(60, 0))) {
// TODO: Implement reset functionality
}
ImGui::PopStyleColor(6); // Pop all 6 color changes
ImGui::Separator();
// Tabs for different views
if (ImGui::BeginTabBar("CPUTabBar")) {
if (ImGui::BeginTabItem("Registers")) {
// General purpose registers
ImGui::Text("General Purpose Registers:");
ImGui::Separator();
if (ImGui::BeginTable("RegisterTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Register", ImGuiTableColumnFlags_WidthFixed, 60.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthFixed, 120.0f);
ImGui::TableSetupColumn("Register", ImGuiTableColumnFlags_WidthFixed, 60.0f);
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthFixed, 120.0f);
ImGui::TableHeadersRow();
for (int i = 0; i < 16; i++) {
ImGui::TableNextRow();
// Left column
ImGui::TableSetColumnIndex(0);
ImGui::Text("X%d", i);
ImGui::TableSetColumnIndex(1);
ImGui::Text("0x%016llX", cpu_state.registers[i]);
// Right column
if (i + 16 < 32) {
ImGui::TableSetColumnIndex(2);
ImGui::Text("X%d", i + 16);
ImGui::TableSetColumnIndex(3);
ImGui::Text("0x%016llX", cpu_state.registers[i + 16]);
} }
ImGui::EndTable();
} }
ImGui::EndTable(); ImGui::Spacing();
ImGui::Text("Program Counter: 0x%016" PRIX64, cpu_state.pc);
ImGui::Text("Flags (PState): 0x%08X", cpu_state.flags);
ImGui::EndTabItem();
} }
ImGui::Spacing(); if (ImGui::BeginTabItem("Memory")) { /*...*/ ImGui::EndTabItem(); }
ImGui::Text("Program Counter: 0x%016llX", cpu_state.pc); if (ImGui::BeginTabItem("Disassembly")) { /*...*/ ImGui::EndTabItem(); }
ImGui::Text("Flags: 0x%08X", cpu_state.flags);
ImGui::EndTabItem(); ImGui::EndTabBar();
} }
ImGui::End();
if (ImGui::BeginTabItem("Memory")) {
static char addr_input[17] = "0000000000000000";
ImGui::Text("Memory Viewer");
ImGui::Separator();
ImGui::InputText("Address", addr_input, sizeof(addr_input),
ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase);
// TODO: Implement memory viewer
ImGui::Text("Memory viewer will be implemented here");
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Disassembly")) {
ImGui::Text("Disassembly View");
ImGui::Separator();
// TODO: Implement disassembly view
ImGui::Text("Disassembly will be shown here");
ImGui::EndTabItem();
}
ImGui::EndTabBar();
} }
// Test result popup
if (show_test_result) {
ImGui::OpenPopup("CPU Test Result");
}
if (ImGui::BeginPopupModal("CPU Test Result", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::Text("The CPU test has been executed successfully!");
ImGui::Text("Check the console for detailed output.");
ImGui::Separator();
ImGui::Text("Note: Pound is still in pre-alpha state.");
ImGui::Spacing();
if (ImGui::Button("OK", ImVec2(120, 0))) {
show_test_result = false;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
ImGui::End();
}
} // namespace Pound::GUI } // namespace Pound::GUI

View file

@ -1,32 +1,31 @@
// Copyright 2025 Pound Emulator Project. All rights reserved.
#pragma once #pragma once
#include "../Panel.h" #include "../Panel.h"
#include "ARM/cpu.h"
#include <functional> #include <functional>
#include <array>
#include <cstdint>
namespace Pound::GUI namespace Pound::GUI
{ {
struct CPUState
{
std::array<uint64_t, 32> registers{};
uint64_t pc = 0;
uint32_t flags = 0;
};
class CPUPanel : public Panel class CPUPanel : public Panel
{ {
public: public:
CPUPanel(); CPUPanel();
void Render() override; void Render() override;
void SetCPUTestCallback(std::function<void()> callback) { cpu_test_callback = callback; } void SetCPUTestCallback(std::function<void()> callback);
void ShowTestResult(bool show = true) { show_test_result = show; } void UpdateState(const CPU& cpu);
private: private:
std::function<void()> cpu_test_callback; CPUState cpu_state;
bool show_test_result = false; bool show_test_result = false;
std::function<void()> cpu_test_callback;
// CPU state display (placeholder for future integration)
struct CPUState
{
uint64_t registers[32] = {0};
uint64_t pc = 0;
uint32_t flags = 0;
} cpu_state;
}; };
}
} // namespace Pound::GUI

View file

@ -14,6 +14,10 @@ namespace Pound::GUI
void ConsolePanel::Render() void ConsolePanel::Render()
{ {
if (!visible) {
return;
}
if (!ImGui::Begin(name.c_str(), &visible)) if (!ImGui::Begin(name.c_str(), &visible))
{ {
ImGui::End(); ImGui::End();

View file

@ -13,6 +13,10 @@ namespace Pound::GUI
void PerformancePanel::Render() void PerformancePanel::Render()
{ {
if (!visible) {
return;
}
if (!ImGui::Begin(name.c_str(), &visible)) if (!ImGui::Begin(name.c_str(), &visible))
{ {
ImGui::End(); ImGui::End();