mirror of
https://github.com/pound-emu/pound.git
synced 2025-12-12 01:36:57 +00:00
Merge pull request #41 from GloriousTacoo/revert-40-main
Revert "feat(gui): Enhance CPU panel with state management and GUI improvements"
This commit is contained in:
commit
b9adfe0ff0
9 changed files with 307 additions and 345 deletions
|
|
@ -40,9 +40,4 @@ 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;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
108
core/main.cpp
108
core/main.cpp
|
|
@ -14,105 +14,75 @@
|
||||||
#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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void initGUI(Pound::GUI::GUIManager *gui_manager)
|
int main() {
|
||||||
{
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
console_panel = std::make_shared<Pound::GUI::ConsolePanel>();
|
// Create and add panels
|
||||||
cpu_panel = std::make_shared<Pound::GUI::CPUPanel>();
|
auto console_panel = std::make_shared<Pound::GUI::ConsolePanel>();
|
||||||
performance_panel = std::make_shared<Pound::GUI::PerformancePanel>();
|
auto cpu_panel = std::make_shared<Pound::GUI::CPUPanel>();
|
||||||
|
auto performance_panel = std::make_shared<Pound::GUI::PerformancePanel>();
|
||||||
|
|
||||||
initGUI(gui_manager.get());
|
gui_manager->AddPanel(console_panel);
|
||||||
|
gui_manager->AddPanel(cpu_panel);
|
||||||
|
gui_manager->AddPanel(performance_panel);
|
||||||
|
|
||||||
while (gui_manager->IsRunning())
|
// Set up callbacks
|
||||||
{
|
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;
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ 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();
|
||||||
|
|
@ -70,8 +69,11 @@ 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())
|
||||||
|
|
@ -80,6 +82,7 @@ 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);
|
||||||
|
|
@ -109,6 +112,85 @@ 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();
|
||||||
|
|
@ -190,114 +272,4 @@ 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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -7,30 +7,9 @@
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "Panel.h"
|
#include "Panel.h"
|
||||||
|
|
||||||
namespace Pound::GUI
|
namespace Pound::GUI {
|
||||||
{
|
|
||||||
|
|
||||||
struct TabBar;
|
class GUIManager {
|
||||||
|
|
||||||
struct TabItem
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TabBar
|
|
||||||
{
|
|
||||||
std::string id;
|
|
||||||
std::vector<TabItem> items;
|
|
||||||
bool is_visible = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GUIManager
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
GUIManager();
|
GUIManager();
|
||||||
~GUIManager();
|
~GUIManager();
|
||||||
|
|
@ -41,29 +20,25 @@ namespace Pound::GUI
|
||||||
void RunFrame();
|
void RunFrame();
|
||||||
bool IsRunning() const { return running && window && !window->ShouldClose(); }
|
bool IsRunning() const { return running && window && !window->ShouldClose(); }
|
||||||
|
|
||||||
Window *GetWindow() const { return window.get(); }
|
|
||||||
|
|
||||||
void AddPanel(std::shared_ptr<Panel> panel);
|
void AddPanel(std::shared_ptr<Panel> panel);
|
||||||
void RemovePanel(const std::string& name);
|
void RemovePanel(const std::string& name);
|
||||||
|
|
||||||
TabBar *AddTabs(const std::string &name);
|
// Callback for external systems
|
||||||
void AddSubTab(TabBar *parent_bar, const std::string &name, std::function<void()> callback = nullptr);
|
void SetCPUTestCallback(std::function<void()> callback) { cpu_test_callback = callback; }
|
||||||
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:
|
private:
|
||||||
void BeginFrame();
|
void BeginFrame();
|
||||||
void EndFrame();
|
void EndFrame();
|
||||||
|
void RenderMainMenuBar();
|
||||||
void ApplyTheme();
|
void ApplyTheme();
|
||||||
void RenderTabBars();
|
|
||||||
void RenderTabBarContents(TabBar &bar);
|
|
||||||
|
|
||||||
std::unique_ptr<Window> window;
|
std::unique_ptr<Window> window;
|
||||||
std::vector<std::shared_ptr<Panel>> panels;
|
std::vector<std::shared_ptr<Panel>> panels;
|
||||||
bool running = false;
|
bool running = false;
|
||||||
bool show_demo_window = false;
|
bool show_demo_window = false;
|
||||||
std::vector<std::unique_ptr<TabBar>> m_tab_bars;
|
|
||||||
|
// Callbacks
|
||||||
|
std::function<void()> cpu_test_callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Pound::GUI
|
} // namespace Pound::GUI
|
||||||
|
|
@ -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() { return &visible; }
|
bool IsVisible() const { return visible; }
|
||||||
void SetVisible(bool vis) { visible = vis; }
|
void SetVisible(bool vis) { visible = vis; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -1,85 +1,142 @@
|
||||||
// In gui/panels/CPUPanel.cpp
|
// Copyright 2025 Pound Emulator Project. All rights reserved.
|
||||||
|
|
||||||
#include "CPUPanel.h"
|
#include "CPUPanel.h"
|
||||||
#include "../Colors.h"
|
#include "../Colors.h"
|
||||||
#include <imgui.h>
|
#include <iomanip>
|
||||||
#include <cinttypes>
|
#include <sstream>
|
||||||
|
|
||||||
|
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() {
|
||||||
{
|
if (!ImGui::Begin(name.c_str(), &visible, ImGuiWindowFlags_NoCollapse)) {
|
||||||
cpu.get_state(cpu_state.registers.data(), cpu_state.pc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPUPanel::SetCPUTestCallback(std::function<void()> callback)
|
|
||||||
{
|
|
||||||
cpu_test_callback = std::move(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPUPanel::Render()
|
|
||||||
{
|
|
||||||
if (!visible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!ImGui::Begin(name.c_str(), &visible, ImGuiWindowFlags_NoCollapse))
|
|
||||||
{
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Control buttons with custom colors
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, Colors::WithAlpha(Colors::Primary, 0.40f));
|
ImGui::PushStyleColor(ImGuiCol_Button, Colors::WithAlpha(Colors::Primary, 0.40f));
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Colors::PrimaryHover);
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Colors::PrimaryHover);
|
||||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, Colors::PrimaryActive);
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, Colors::PrimaryActive);
|
||||||
if (ImGui::Button("Run CPU Test", ImVec2(120, 0)))
|
|
||||||
{
|
if (ImGui::Button("Run CPU Test", ImVec2(120, 0))) {
|
||||||
if (cpu_test_callback) {
|
if (cpu_test_callback) {
|
||||||
cpu_test_callback();
|
cpu_test_callback();
|
||||||
show_test_result = true;
|
show_test_result = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(3);
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Step", ImVec2(60, 0))) {
|
||||||
|
// TODO: Implement step functionality
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
// Reset button with secondary color
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Button, Colors::WithAlpha(Colors::Secondary, 0.40f));
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Colors::SecondaryHover);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ButtonActive, Colors::SecondaryActive);
|
||||||
|
|
||||||
|
if (ImGui::Button("Reset", ImVec2(60, 0))) {
|
||||||
|
// TODO: Implement reset functionality
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PopStyleColor(6); // Pop all 6 color changes
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::BeginTabBar("CPUTabBar"))
|
|
||||||
{
|
// Tabs for different views
|
||||||
if (ImGui::BeginTabItem("Registers"))
|
if (ImGui::BeginTabBar("CPUTabBar")) {
|
||||||
{
|
if (ImGui::BeginTabItem("Registers")) {
|
||||||
|
// General purpose registers
|
||||||
ImGui::Text("General Purpose Registers:");
|
ImGui::Text("General Purpose Registers:");
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (ImGui::BeginTable("RegisterTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg))
|
|
||||||
{
|
if (ImGui::BeginTable("RegisterTable", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
|
||||||
ImGui::TableSetupColumn("Register"); ImGui::TableSetupColumn("Value");
|
ImGui::TableSetupColumn("Register", ImGuiTableColumnFlags_WidthFixed, 60.0f);
|
||||||
ImGui::TableSetupColumn("Register"); ImGui::TableSetupColumn("Value");
|
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthFixed, 120.0f);
|
||||||
|
ImGui::TableSetupColumn("Register", ImGuiTableColumnFlags_WidthFixed, 60.0f);
|
||||||
|
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthFixed, 120.0f);
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++) {
|
||||||
{
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0); ImGui::Text("X%d", i);
|
|
||||||
ImGui::TableSetColumnIndex(1); ImGui::Text("0x%016" PRIX64, cpu_state.registers[i]);
|
|
||||||
|
|
||||||
if (i + 16 < 31)
|
// Left column
|
||||||
{
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::TableSetColumnIndex(2); ImGui::Text("X%d", i + 16);
|
ImGui::Text("X%d", i);
|
||||||
ImGui::TableSetColumnIndex(3); ImGui::Text("0x%016" PRIX64, cpu_state.registers[i + 16]);
|
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::Spacing();
|
||||||
ImGui::Text("Program Counter: 0x%016" PRIX64, cpu_state.pc);
|
ImGui::Text("Program Counter: 0x%016llX", cpu_state.pc);
|
||||||
ImGui::Text("Flags (PState): 0x%08X", cpu_state.flags);
|
ImGui::Text("Flags: 0x%08X", cpu_state.flags);
|
||||||
|
|
||||||
ImGui::EndTabItem();
|
ImGui::EndTabItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginTabItem("Memory")) { /*...*/ ImGui::EndTabItem(); }
|
if (ImGui::BeginTabItem("Memory")) {
|
||||||
if (ImGui::BeginTabItem("Disassembly")) { /*...*/ ImGui::EndTabItem(); }
|
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();
|
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();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,32 @@
|
||||||
|
// 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);
|
void SetCPUTestCallback(std::function<void()> callback) { cpu_test_callback = callback; }
|
||||||
void UpdateState(const CPU& cpu);
|
void ShowTestResult(bool show = true) { show_test_result = show; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CPUState cpu_state;
|
|
||||||
bool show_test_result = false;
|
|
||||||
std::function<void()> cpu_test_callback;
|
std::function<void()> cpu_test_callback;
|
||||||
|
bool show_test_result = false;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
@ -14,10 +14,6 @@ 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();
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,6 @@ 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();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue