Use zeml for emulator cpu state layout and emulator menu bar

This commit is contained in:
scawful
2024-04-17 20:12:51 -04:00
parent 6c330eabd8
commit a01e963efb

View File

@@ -10,6 +10,7 @@
#include "app/emu/snes.h" #include "app/emu/snes.h"
#include "app/gui/icons.h" #include "app/gui/icons.h"
#include "app/gui/input.h" #include "app/gui/input.h"
#include "app/gui/zeml.h"
#include "app/rom.h" #include "app/rom.h"
namespace yaze { namespace yaze {
@@ -51,14 +52,17 @@ void Emulator::Run() {
} }
void Emulator::RenderNavBar() { void Emulator::RenderNavBar() {
MENU_BAR() std::string navbar_layout = R"(
if (ImGui::BeginMenu("Options")) { BeginMenuBar {
MENU_ITEM("Input") {} BeginMenu title="Options" {
MENU_ITEM("Audio") {} MenuItem title="Input" {}
MENU_ITEM("Video") {} MenuItem title="Audio" {}
ImGui::EndMenu(); MenuItem title="Video" {}
} }
END_MENU_BAR() }
)";
auto navbar_node = gui::zeml::Parse(navbar_layout);
gui::zeml::Render(navbar_node);
if (ImGui::Button(ICON_MD_PLAY_ARROW)) { if (ImGui::Button(ICON_MD_PLAY_ARROW)) {
loading_ = true; loading_ = true;
@@ -155,27 +159,35 @@ void Emulator::HandleEvents() {
} }
void Emulator::RenderEmulator() { void Emulator::RenderEmulator() {
if (ImGui::BeginTable("##Emulator", 3, std::string emulator_layout = R"(
ImGuiTableFlags_Resizable | ImGuiTableFlags_ScrollY)) { Table id="Emulator" count="3" flags="Resizable|ScrollY" {
ImGui::TableSetupColumn("CPU"); TableSetupColumn title="CPU",
ImGui::TableSetupColumn("PPU"); TableSetupColumn title="PPU",
ImGui::TableHeadersRow(); TableHeadersRow,
TableNextColumn {
Function id="CpuInstructionLog"
}
TableNextColumn {
Function id="SnesPpu",
Function id="BreakpointList"
}
TableNextColumn {
BeginChild id="##" size="0,0" flags="NoMove|NoScrollbar" {
Function id="CpuState"
}
}
}
)";
auto emulator_node = gui::zeml::Parse(emulator_layout);
Bind(emulator_node.GetNode("CpuInstructionLog"),
[&]() { RenderCpuInstructionLog(snes_.cpu().instruction_log_); });
Bind(emulator_node.GetNode("SnesPpu"), [&]() { RenderSnesPpu(); });
Bind(emulator_node.GetNode("BreakpointList"),
[&]() { RenderBreakpointList(); });
Bind(emulator_node.GetNode("CpuState"),
[&]() { RenderCpuState(snes_.cpu()); });
TableNextColumn(); gui::zeml::Render(emulator_node);
RenderCpuInstructionLog(snes_.cpu().instruction_log_);
TableNextColumn();
RenderSnesPpu();
RenderBreakpointList();
TableNextColumn();
ImGui::BeginChild("##", ImVec2(0, 0), true,
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar);
RenderCpuState(snes_.cpu());
ImGui::EndChild();
ImGui::EndTable();
}
} }
void Emulator::RenderSnesPpu() { void Emulator::RenderSnesPpu() {
@@ -251,7 +263,7 @@ void Emulator::RenderBreakpointList() {
ImGui::EndChild(); ImGui::EndChild();
} }
Separator(); Separator();
gui::InputHexByte("PB", &manual_pb_, 1, 25.f); gui::InputHexByte("PB", &manual_pb_, 25.f);
gui::InputHexWord("PC", &manual_pc_, 25.f); gui::InputHexWord("PC", &manual_pc_, 25.f);
if (ImGui::Button("Set Current Address")) { if (ImGui::Button("Set Current Address")) {
snes_.cpu().PC = manual_pc_; snes_.cpu().PC = manual_pc_;
@@ -260,29 +272,27 @@ void Emulator::RenderBreakpointList() {
} }
void Emulator::RenderCpuState(Cpu& cpu) { void Emulator::RenderCpuState(Cpu& cpu) {
if (ImGui::CollapsingHeader("Register Values", std::string cpu_state_layout = R"(
ImGuiTreeNodeFlags_DefaultOpen)) { CollapsingHeader id="cpuState" title="Register Values" open=true {
ImGui::Columns(2, "RegistersColumns"); Columns id="registersColumns" count="2" {
Separator(); Text text="A: 0x%04X" data="cpu.A",
Text("A: 0x%04X", cpu.A); Text text="D: 0x%04X" data="cpu.D",
NextColumn(); Text text="X: 0x%04X" data="cpu.X",
Text("D: 0x%04X", cpu.D); Text text="DB: 0x%02X" data="cpu.DB",
NextColumn(); Text text="Y: 0x%04X" data="cpu.Y",
Text("X: 0x%04X", cpu.X); Text text="PB: 0x%02X" data="cpu.PB",
NextColumn(); Text text="PC: 0x%04X" data="cpu.PC",
Text("DB: 0x%02X", cpu.DB); Text text="E: %d" data="cpu.E"
NextColumn(); }
Text("Y: 0x%04X", cpu.Y); }
NextColumn(); )";
Text("PB: 0x%02X", cpu.PB); const std::map<std::string, void*> data_bindings = {
NextColumn(); {"cpu.A", &cpu.A}, {"cpu.D", &cpu.D}, {"cpu.X", &cpu.X},
Text("PC: 0x%04X", cpu.PC); {"cpu.DB", &cpu.DB}, {"cpu.Y", &cpu.Y}, {"cpu.PB", &cpu.PB},
NextColumn(); {"cpu.PC", &cpu.PC}, {"cpu.E", &cpu.E}};
Text("E: %d", cpu.E); gui::zeml::Node cpu_state_node =
NextColumn(); gui::zeml::Parse(cpu_state_layout, data_bindings);
ImGui::Columns(1); gui::zeml::Render(cpu_state_node);
Separator();
}
// Call Stack // Call Stack
if (ImGui::CollapsingHeader("Call Stack", ImGuiTreeNodeFlags_DefaultOpen)) { if (ImGui::CollapsingHeader("Call Stack", ImGuiTreeNodeFlags_DefaultOpen)) {
@@ -365,8 +375,7 @@ void Emulator::RenderCpuInstructionLog(
ImGui::Checkbox("Show All Opcodes", &showAllOpcodes); ImGui::Checkbox("Show All Opcodes", &showAllOpcodes);
// Instruction list // Instruction list
ImGui::BeginChild("InstructionList", ImVec2(0, 0), ImGui::BeginChild("InstructionList", ImVec2(0, 0), ImGuiChildFlags_None);
ImGuiChildFlags_None);
for (const auto& entry : instructionLog) { for (const auto& entry : instructionLog) {
if (ShouldDisplay(entry, filterBuf, showAllOpcodes)) { if (ShouldDisplay(entry, filterBuf, showAllOpcodes)) {
if (ImGui::Selectable( if (ImGui::Selectable(