yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
debugger_ui.cc
Go to the documentation of this file.
2
3#include "absl/strings/str_format.h"
4#include "app/emu/cpu/cpu.h"
5#include "app/emu/emulator.h"
10#include "imgui/imgui.h"
12#include "util/log.h"
13
14namespace yaze {
15namespace emu {
16namespace ui {
17
18using namespace yaze::gui;
19
20namespace {
21// UI Constants
22constexpr float kStandardSpacing = 8.0f;
23constexpr float kButtonHeight = 30.0f;
24constexpr float kLargeButtonHeight = 35.0f;
25
26void AddSpacing() {
27 ImGui::Spacing();
28 ImGui::Spacing();
29}
31 ImGui::Spacing();
32 ImGui::Separator();
33 ImGui::Spacing();
34}
35
36} // namespace
37
39 if (!emu)
40 return;
41
42 auto& theme_manager = ThemeManager::Get();
43 const auto& theme = theme_manager.GetCurrentTheme();
44
45 ImGui::PushStyleColor(ImGuiCol_ChildBg, ConvertColorToImVec4(theme.child_bg));
46 ImGui::BeginChild("##CPUDebugger", ImVec2(0, 0), true);
47
48 // Title with icon
49 ImGui::TextColored(ConvertColorToImVec4(theme.accent),
50 ICON_MD_DEVELOPER_BOARD " 65816 CPU Debugger");
51 AddSectionSpacing();
52
53 auto& cpu = emu->snes().cpu();
54
55 // Debugger Controls
56 if (ImGui::CollapsingHeader(ICON_MD_SETTINGS " Controls",
57 ImGuiTreeNodeFlags_DefaultOpen)) {
58 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(8, 6));
59
60 if (ImGui::Button(ICON_MD_SKIP_NEXT " Step", ImVec2(100, kButtonHeight))) {
61 cpu.RunOpcode();
62 }
63 if (ImGui::IsItemHovered()) {
64 ImGui::SetTooltip("Execute single instruction (F10)");
65 }
66
67 ImGui::SameLine();
68 if (ImGui::Button(ICON_MD_FAST_FORWARD " Run to BP",
69 ImVec2(120, kButtonHeight))) {
70 // Run until breakpoint
71 emu->set_running(true);
72 }
73 if (ImGui::IsItemHovered()) {
74 ImGui::SetTooltip("Run until next breakpoint (F5)");
75 }
76
77 ImGui::PopStyleVar();
78 }
79
80 AddSpacing();
81
82 // CPU Registers
83 if (ImGui::CollapsingHeader(ICON_MD_MEMORY " Registers",
84 ImGuiTreeNodeFlags_DefaultOpen)) {
85 if (ImGui::BeginTable("CPU_Registers", 4,
86 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
87 ImGui::TableSetupColumn("Reg", ImGuiTableColumnFlags_WidthFixed, 40.0f);
88 ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthFixed, 70.0f);
89 ImGui::TableSetupColumn("Reg", ImGuiTableColumnFlags_WidthFixed, 40.0f);
90 ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthFixed, 70.0f);
91 ImGui::TableHeadersRow();
92
93 // Row 1: A, X
94 ImGui::TableNextRow();
95 ImGui::TableNextColumn();
96 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary), "A:");
97 ImGui::TableNextColumn();
98 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%04X", cpu.A);
99 ImGui::TableNextColumn();
100 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary), "X:");
101 ImGui::TableNextColumn();
102 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%04X", cpu.X);
103
104 // Row 2: Y, D
105 ImGui::TableNextRow();
106 ImGui::TableNextColumn();
107 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary), "Y:");
108 ImGui::TableNextColumn();
109 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%04X", cpu.Y);
110 ImGui::TableNextColumn();
111 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary), "D:");
112 ImGui::TableNextColumn();
113 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%04X", cpu.D);
114
115 // Row 3: DB, PB
116 ImGui::TableNextRow();
117 ImGui::TableNextColumn();
118 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary), "DB:");
119 ImGui::TableNextColumn();
120 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%02X", cpu.DB);
121 ImGui::TableNextColumn();
122 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary), "PB:");
123 ImGui::TableNextColumn();
124 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%02X", cpu.PB);
125
126 // Row 4: PC, SP
127 ImGui::TableNextRow();
128 ImGui::TableNextColumn();
129 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary), "PC:");
130 ImGui::TableNextColumn();
131 ImGui::TextColored(ConvertColorToImVec4(theme.warning), "$%04X", cpu.PC);
132 ImGui::TableNextColumn();
133 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary), "SP:");
134 ImGui::TableNextColumn();
135 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%04X", cpu.SP());
136
137 ImGui::EndTable();
138 }
139
140 AddSpacing();
141
142 // Status Flags (visual checkboxes)
143 ImGui::TextColored(ConvertColorToImVec4(theme.text_secondary),
144 ICON_MD_FLAG " Flags:");
145 ImGui::Indent();
146
147 auto RenderFlag = [&](const char* name, bool value) {
148 ImVec4 color = value ? ConvertColorToImVec4(theme.success)
149 : ConvertColorToImVec4(theme.text_disabled);
150 ImGui::TextColored(
151 color, "%s %s",
153 if (ImGui::IsItemHovered()) {
154 ImGui::SetTooltip("%s: %s", name, value ? "Set" : "Clear");
155 }
156 ImGui::SameLine();
157 };
158
159 RenderFlag("N", cpu.GetNegativeFlag());
160 RenderFlag("V", cpu.GetOverflowFlag());
161 RenderFlag("D", cpu.GetDecimalFlag());
162 RenderFlag("I", cpu.GetInterruptFlag());
163 RenderFlag("Z", cpu.GetZeroFlag());
164 RenderFlag("C", cpu.GetCarryFlag());
165 ImGui::NewLine();
166
167 ImGui::Unindent();
168 }
169
170 AddSpacing();
171
172 // Breakpoint Management
173 if (ImGui::CollapsingHeader(ICON_MD_STOP_CIRCLE " Breakpoints")) {
174 static char bp_input[10] = "";
175
176 ImGui::SetNextItemWidth(150);
177 if (ImGui::InputTextWithHint("##BP", "Address (hex)", bp_input,
178 sizeof(bp_input),
179 ImGuiInputTextFlags_CharsHexadecimal |
180 ImGuiInputTextFlags_EnterReturnsTrue)) {
181 if (strlen(bp_input) > 0) {
182 uint32_t addr = std::stoi(bp_input, nullptr, 16);
183 emu->SetBreakpoint(addr);
184 memset(bp_input, 0, sizeof(bp_input));
185 }
186 }
187
188 ImGui::SameLine();
189 if (ImGui::Button(ICON_MD_ADD " Add", ImVec2(80, 0))) {
190 if (strlen(bp_input) > 0) {
191 uint32_t addr = std::stoi(bp_input, nullptr, 16);
192 emu->SetBreakpoint(addr);
193 memset(bp_input, 0, sizeof(bp_input));
194 }
195 }
196
197 ImGui::SameLine();
198 if (ImGui::Button(ICON_MD_CLEAR_ALL " Clear All", ImVec2(100, 0))) {
199 emu->ClearAllBreakpoints();
200 }
201
202 AddSpacing();
203
204 // List breakpoints
205 auto breakpoints = emu->GetBreakpoints();
206 if (!breakpoints.empty()) {
207 ImGui::BeginChild("##BPList", ImVec2(0, 150), true);
208 for (size_t i = 0; i < breakpoints.size(); ++i) {
209 uint32_t bp = breakpoints[i];
210 ImGui::PushID(i);
211
212 ImGui::TextColored(ConvertColorToImVec4(theme.accent),
213 ICON_MD_STOP " $%06X", bp);
214
215 ImGui::SameLine(200);
216 if (ImGui::SmallButton(ICON_MD_DELETE " Remove")) {
217 cpu.ClearBreakpoint(bp);
218 }
219
220 ImGui::PopID();
221 }
222 ImGui::EndChild();
223 } else {
224 ImGui::TextColored(ConvertColorToImVec4(theme.text_disabled),
225 "No breakpoints set");
226 }
227 }
228
229 ImGui::EndChild();
230 ImGui::PopStyleColor();
231}
232
234 if (!emu)
235 return;
236
237 auto& theme_manager = ThemeManager::Get();
238 const auto& theme = theme_manager.GetCurrentTheme();
239
240 ImGui::PushStyleColor(ImGuiCol_ChildBg, ConvertColorToImVec4(theme.child_bg));
241 ImGui::BeginChild("##BreakpointList", ImVec2(0, 0), true);
242
243 ImGui::TextColored(ConvertColorToImVec4(theme.accent),
244 ICON_MD_STOP_CIRCLE " Breakpoint Manager");
245 AddSectionSpacing();
246
247 // Same content as in RenderModernCpuDebugger but with more detail
248 auto breakpoints = emu->GetBreakpoints();
249
250 ImGui::Text("Active Breakpoints: %zu", breakpoints.size());
251 AddSpacing();
252
253 if (!breakpoints.empty()) {
254 if (ImGui::BeginTable("BreakpointTable", 3,
255 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
256 ImGui::TableSetupColumn(ICON_MD_TAG, ImGuiTableColumnFlags_WidthFixed,
257 40);
258 ImGui::TableSetupColumn("Address", ImGuiTableColumnFlags_WidthFixed, 100);
259 ImGui::TableSetupColumn("Actions", ImGuiTableColumnFlags_WidthStretch);
260 ImGui::TableHeadersRow();
261
262 for (size_t i = 0; i < breakpoints.size(); ++i) {
263 ImGui::TableNextRow();
264 ImGui::TableNextColumn();
265 ImGui::TextColored(ConvertColorToImVec4(theme.error), ICON_MD_STOP);
266
267 ImGui::TableNextColumn();
268 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%06X",
269 breakpoints[i]);
270
271 ImGui::TableNextColumn();
272 ImGui::PushID(i);
273 if (ImGui::SmallButton(ICON_MD_DELETE " Remove")) {
274 emu->snes().cpu().ClearBreakpoint(breakpoints[i]);
275 }
276 ImGui::PopID();
277 }
278
279 ImGui::EndTable();
280 }
281 } else {
282 ImGui::TextColored(ConvertColorToImVec4(theme.text_disabled),
283 ICON_MD_INFO " No breakpoints set");
284 }
285
286 ImGui::EndChild();
287 ImGui::PopStyleColor();
288}
289
291 if (!emu)
292 return;
293
294 auto& theme_manager = ThemeManager::Get();
295 const auto& theme = theme_manager.GetCurrentTheme();
296
297 static yaze::gui::MemoryEditorWidget mem_edit;
298
299 ImGui::PushStyleColor(ImGuiCol_ChildBg, ConvertColorToImVec4(theme.child_bg));
300 ImGui::BeginChild("##MemoryViewer", ImVec2(0, 0), true);
301
302 ImGui::TextColored(ConvertColorToImVec4(theme.accent),
303 ICON_MD_STORAGE " Memory Viewer");
304 AddSectionSpacing();
305
306 // Memory region selector
307 static int region = 0;
308 const char* regions[] = {"RAM ($0000-$1FFF)", "ROM Bank 0",
309 "WRAM ($7E0000-$7FFFFF)", "SRAM"};
310
311 ImGui::SetNextItemWidth(250);
312 if (ImGui::Combo(ICON_MD_MAP " Region", &region, regions,
313 IM_ARRAYSIZE(regions))) {
314 // Region changed
315 }
316
317 AddSpacing();
318
319 // Render memory editor
320 uint8_t* memory_base = emu->snes().get_ram();
321 size_t memory_size = 0x20000;
322
323 mem_edit.DrawContents(memory_base, memory_size, 0x0000);
324
325 ImGui::EndChild();
326 ImGui::PopStyleColor();
327}
328
329void RenderCpuInstructionLog(Emulator* emu, uint32_t log_size) {
330 if (!emu)
331 return;
332
333 auto& theme_manager = ThemeManager::Get();
334 const auto& theme = theme_manager.GetCurrentTheme();
335
336 ImGui::PushStyleColor(ImGuiCol_ChildBg, ConvertColorToImVec4(theme.child_bg));
337 ImGui::BeginChild("##InstructionLog", ImVec2(0, 0), true);
338
339 ImGui::TextColored(ConvertColorToImVec4(theme.warning),
340 ICON_MD_WARNING " Legacy Instruction Log");
341 ImGui::TextColored(ConvertColorToImVec4(theme.text_disabled),
342 "Deprecated - Use Disassembly Viewer instead");
343 AddSectionSpacing();
344
345 // Show DisassemblyViewer stats instead
346 ImGui::Text(ICON_MD_INFO " DisassemblyViewer Active:");
347 ImGui::BulletText("Unique addresses: %zu",
349 ImGui::BulletText("Recording: %s",
350 emu->disassembly_viewer().IsRecording() ? "ON" : "OFF");
351 ImGui::BulletText("Auto-scroll: Available in viewer");
352
353 AddSpacing();
354
355 if (ImGui::Button(ICON_MD_OPEN_IN_NEW " Open Disassembly Viewer",
356 ImVec2(-1, kLargeButtonHeight))) {
357 // TODO: Open disassembly viewer window
358 }
359
360 ImGui::EndChild();
361 ImGui::PopStyleColor();
362}
363
365 if (!emu)
366 return;
367
368 auto& theme_manager = ThemeManager::Get();
369 const auto& theme = theme_manager.GetCurrentTheme();
370
371 ImGui::PushStyleColor(ImGuiCol_ChildBg, ConvertColorToImVec4(theme.child_bg));
372 ImGui::BeginChild("##ApuDebugger", ImVec2(0, 0), true);
373
374 // Title
375 ImGui::TextColored(ConvertColorToImVec4(theme.accent),
376 ICON_MD_MUSIC_NOTE " APU / SPC700 Debugger");
377 AddSectionSpacing();
378
379 auto& tracker = emu->snes().apu_handshake_tracker();
380
381 // Handshake Status with enhanced visuals
382 if (ImGui::CollapsingHeader(ICON_MD_HANDSHAKE " Handshake Status",
383 ImGuiTreeNodeFlags_DefaultOpen)) {
384 // Phase with icon and color
385 auto phase_str = tracker.GetPhaseString();
386 ImVec4 phase_color;
387 const char* phase_icon;
388
389 if (phase_str == "RUNNING") {
390 phase_color = ConvertColorToImVec4(theme.success);
391 phase_icon = ICON_MD_CHECK_CIRCLE;
392 } else if (phase_str == "TRANSFER_ACTIVE") {
393 phase_color = ConvertColorToImVec4(theme.info);
394 phase_icon = ICON_MD_SYNC;
395 } else if (phase_str == "WAITING_BBAA" || phase_str == "IPL_BOOT") {
396 phase_color = ConvertColorToImVec4(theme.warning);
397 phase_icon = ICON_MD_PENDING;
398 } else {
399 phase_color = ConvertColorToImVec4(theme.error);
400 phase_icon = ICON_MD_ERROR;
401 }
402
403 ImGui::Text(ICON_MD_SETTINGS " Phase:");
404 ImGui::SameLine();
405 ImGui::TextColored(phase_color, "%s %s", phase_icon, phase_str.c_str());
406
407 // Handshake complete indicator
408 ImGui::Text(ICON_MD_LINK " Handshake:");
409 ImGui::SameLine();
410 if (tracker.IsHandshakeComplete()) {
411 ImGui::TextColored(ConvertColorToImVec4(theme.success),
412 ICON_MD_CHECK_CIRCLE " Complete");
413 } else {
414 ImGui::TextColored(ConvertColorToImVec4(theme.warning),
415 ICON_MD_HOURGLASS_EMPTY " Waiting");
416 }
417
418 // Transfer progress
419 if (tracker.IsTransferActive() || tracker.GetBytesTransferred() > 0) {
420 AddSpacing();
421 ImGui::Text(ICON_MD_CLOUD_UPLOAD " Transfer Progress:");
422 ImGui::Indent();
423 ImGui::BulletText("Bytes: %d", tracker.GetBytesTransferred());
424 ImGui::BulletText("Blocks: %d", tracker.GetBlockCount());
425
426 auto progress = tracker.GetTransferProgress();
427 if (!progress.empty()) {
428 ImGui::TextColored(ConvertColorToImVec4(theme.info), "%s",
429 progress.c_str());
430 }
431 ImGui::Unindent();
432 }
433
434 // Status summary
435 AddSectionSpacing();
436 ImGui::TextWrapped("%s", tracker.GetStatusSummary().c_str());
437 }
438
439 // Port Activity Log
440 if (ImGui::CollapsingHeader(ICON_MD_LIST " Port Activity Log",
441 ImGuiTreeNodeFlags_DefaultOpen)) {
442 ImGui::BeginChild("##PortLog", ImVec2(0, 200), true);
443
444 const auto& history = tracker.GetPortHistory();
445
446 if (history.empty()) {
447 ImGui::TextColored(ConvertColorToImVec4(theme.text_disabled),
448 ICON_MD_INFO " No port activity yet");
449 } else {
450 // Show last 50 entries
451 int start_idx = std::max(0, static_cast<int>(history.size()) - 50);
452 for (size_t i = start_idx; i < history.size(); ++i) {
453 const auto& entry = history[i];
454
455 ImVec4 color = entry.is_cpu ? ConvertColorToImVec4(theme.accent)
456 : ConvertColorToImVec4(theme.info);
457 const char* icon =
459
460 ImGui::TextColored(color, "[%04llu] %s %s F%d = $%02X @ PC=$%04X %s",
461 entry.timestamp, entry.is_cpu ? "CPU" : "SPC", icon,
462 entry.port + 4, entry.value, entry.pc,
463 entry.description.c_str());
464 }
465
466 // Auto-scroll
467 if (ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) {
468 ImGui::SetScrollHereY(1.0f);
469 }
470 }
471
472 ImGui::EndChild();
473 }
474
475 // Current Port Values
476 if (ImGui::CollapsingHeader(ICON_MD_SETTINGS_INPUT_COMPONENT
477 " Current Port Values",
478 ImGuiTreeNodeFlags_DefaultOpen)) {
479 if (ImGui::BeginTable("APU_Ports", 4,
480 ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) {
481 ImGui::TableSetupColumn("Port", ImGuiTableColumnFlags_WidthFixed, 50);
482 ImGui::TableSetupColumn("CPU → SPC", ImGuiTableColumnFlags_WidthFixed,
483 80);
484 ImGui::TableSetupColumn("SPC → CPU", ImGuiTableColumnFlags_WidthFixed,
485 80);
486 ImGui::TableSetupColumn("Address", ImGuiTableColumnFlags_WidthStretch);
487 ImGui::TableHeadersRow();
488
489 for (int i = 0; i < 4; ++i) {
490 ImGui::TableNextRow();
491 ImGui::TableNextColumn();
492 ImGui::Text(ICON_MD_SETTINGS " F%d", i + 4);
493
494 ImGui::TableNextColumn();
495 ImGui::TextColored(ConvertColorToImVec4(theme.accent), "$%02X",
496 emu->snes().apu().in_ports_[i]);
497
498 ImGui::TableNextColumn();
499 ImGui::TextColored(ConvertColorToImVec4(theme.info), "$%02X",
500 emu->snes().apu().out_ports_[i]);
501
502 ImGui::TableNextColumn();
503 ImGui::TextDisabled("$214%d / $F%d", i, i + 4);
504 }
505
506 ImGui::EndTable();
507 }
508 }
509
510 // Quick Actions
511 if (ImGui::CollapsingHeader(ICON_MD_BUILD " Quick Actions",
512 ImGuiTreeNodeFlags_DefaultOpen)) {
513 ImGui::TextColored(ConvertColorToImVec4(theme.warning),
514 ICON_MD_WARNING " Manual Testing Tools");
515 AddSpacing();
516
517 // Full handshake test
518 if (ImGui::Button(ICON_MD_PLAY_CIRCLE " Full Handshake Test",
519 ImVec2(-1, kLargeButtonHeight))) {
520 LOG_INFO("APU_DEBUG", "=== MANUAL HANDSHAKE TEST ===");
521 emu->snes().Write(0x002140, 0xCC);
522 emu->snes().Write(0x002141, 0x01);
523 emu->snes().Write(0x002142, 0x00);
524 emu->snes().Write(0x002143, 0x02);
525 LOG_INFO("APU_DEBUG", "Handshake sequence executed");
526 }
527 if (ImGui::IsItemHovered()) {
528 ImGui::SetTooltip(
529 "Execute full handshake sequence:\n"
530 "$CC → F4, $01 → F5, $00 → F6, $02 → F7");
531 }
532
533 AddSpacing();
534
535 // Manual port writes
536 if (ImGui::TreeNode(ICON_MD_EDIT " Manual Port Writes")) {
537 static uint8_t port_values[4] = {0xCC, 0x01, 0x00, 0x02};
538
539 for (int i = 0; i < 4; ++i) {
540 ImGui::PushID(i);
541 ImGui::Text("F%d ($214%d):", i + 4, i);
542 ImGui::SameLine();
543 ImGui::SetNextItemWidth(80);
544 ImGui::InputScalar("##val", ImGuiDataType_U8, &port_values[i], NULL,
545 NULL, "%02X", ImGuiInputTextFlags_CharsHexadecimal);
546 ImGui::SameLine();
547 if (ImGui::Button(ICON_MD_SEND " Write", ImVec2(100, 0))) {
548 emu->snes().Write(0x002140 + i, port_values[i]);
549 LOG_INFO("APU_DEBUG", "Wrote $%02X to F%d", port_values[i], i + 4);
550 }
551 ImGui::PopID();
552 }
553
554 ImGui::TreePop();
555 }
556
557 AddSectionSpacing();
558
559 // System controls
560 if (ImGui::Button(ICON_MD_RESTART_ALT " Reset APU",
561 ImVec2(-1, kButtonHeight))) {
562 emu->snes().apu().Reset();
563 LOG_INFO("APU_DEBUG", "APU reset");
564 }
565
566 if (ImGui::Button(ICON_MD_CLEAR_ALL " Clear Port History",
567 ImVec2(-1, kButtonHeight))) {
568 tracker.Reset();
569 LOG_INFO("APU_DEBUG", "Port history cleared");
570 }
571 }
572
573 ImGui::Separator();
574 ImGui::Text("Audio Resampling");
575
576 // Combo box for interpolation type
577 const char* items[] = {"Linear", "Hermite", "Cosine", "Cubic"};
578 int current_item =
579 static_cast<int>(emu->snes().apu().dsp().interpolation_type);
580 if (ImGui::Combo("Interpolation", &current_item, items,
581 IM_ARRAYSIZE(items))) {
582 emu->snes().apu().dsp().interpolation_type =
583 static_cast<InterpolationType>(current_item);
584 }
585
586 ImGui::EndChild();
587 ImGui::PopStyleColor();
588}
589
591 if (!emu)
592 return;
593
594 auto& theme_manager = ThemeManager::Get();
595 const auto& theme = theme_manager.GetCurrentTheme();
596
597 ImGui::PushStyleColor(ImGuiCol_ChildBg, ConvertColorToImVec4(theme.child_bg));
598 ImGui::BeginChild("##AIAgent", ImVec2(0, 0), true);
599
600 ImGui::TextColored(ConvertColorToImVec4(theme.accent),
601 ICON_MD_SMART_TOY " AI Agent Integration");
602 AddSectionSpacing();
603
604 // Agent status
605 bool agent_ready = emu->IsEmulatorReady();
606 ImVec4 status_color = agent_ready ? ConvertColorToImVec4(theme.success)
607 : ConvertColorToImVec4(theme.error);
608
609 ImGui::Text("Status:");
610 ImGui::SameLine();
611 ImGui::TextColored(status_color, "%s %s",
612 agent_ready ? ICON_MD_CHECK_CIRCLE : ICON_MD_ERROR,
613 agent_ready ? "Ready" : "Not Ready");
614
615 AddSpacing();
616
617 // Emulator metrics for agents
618 if (ImGui::CollapsingHeader(ICON_MD_DATA_OBJECT " Metrics",
619 ImGuiTreeNodeFlags_DefaultOpen)) {
620 auto metrics = emu->GetMetrics();
621
622 ImGui::BulletText("FPS: %.2f", metrics.fps);
623 ImGui::BulletText("Cycles: %llu", metrics.cycles);
624 ImGui::BulletText("CPU PC: $%02X:%04X", metrics.cpu_pb, metrics.cpu_pc);
625 ImGui::BulletText("Audio Queued: %u frames", metrics.audio_frames_queued);
626 ImGui::BulletText("Running: %s", metrics.is_running ? "YES" : "NO");
627 }
628
629 // Agent controls
630 if (ImGui::CollapsingHeader(ICON_MD_PLAY_CIRCLE " Agent Controls")) {
631 if (ImGui::Button(ICON_MD_PLAY_ARROW " Start Agent Session",
632 ImVec2(-1, kLargeButtonHeight))) {
633 // TODO: Start agent
634 }
635
636 if (ImGui::Button(ICON_MD_STOP " Stop Agent", ImVec2(-1, kButtonHeight))) {
637 // TODO: Stop agent
638 }
639 }
640
641 ImGui::EndChild();
642 ImGui::PopStyleColor();
643}
644
645} // namespace ui
646} // namespace emu
647} // namespace yaze
A class for emulating and debugging SNES games.
Definition emulator.h:39
bool IsEmulatorReady() const
Definition emulator.h:125
void SetBreakpoint(uint32_t address)
Definition emulator.h:131
debug::DisassemblyViewer & disassembly_viewer()
Definition emulator.h:117
void set_running(bool running)
Definition emulator.h:60
void ClearAllBreakpoints()
Definition emulator.h:132
auto snes() -> Snes &
Definition emulator.h:58
EmulatorMetrics GetMetrics()
Definition emulator.h:146
std::vector< uint32_t > GetBreakpoints()
Definition emulator.h:133
size_t GetInstructionCount() const
Get the number of unique instructions recorded.
static ThemeManager & Get()
#define ICON_MD_SETTINGS
Definition icons.h:1699
#define ICON_MD_DATA_OBJECT
Definition icons.h:521
#define ICON_MD_CHECK_BOX
Definition icons.h:398
#define ICON_MD_LINK
Definition icons.h:1090
#define ICON_MD_INFO
Definition icons.h:993
#define ICON_MD_MEMORY
Definition icons.h:1195
#define ICON_MD_STORAGE
Definition icons.h:1865
#define ICON_MD_WARNING
Definition icons.h:2123
#define ICON_MD_FAST_FORWARD
Definition icons.h:724
#define ICON_MD_ARROW_FORWARD
Definition icons.h:184
#define ICON_MD_PLAY_ARROW
Definition icons.h:1479
#define ICON_MD_HANDSHAKE
Definition icons.h:907
#define ICON_MD_MAP
Definition icons.h:1173
#define ICON_MD_STOP
Definition icons.h:1862
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_ERROR
Definition icons.h:686
#define ICON_MD_MUSIC_NOTE
Definition icons.h:1264
#define ICON_MD_STOP_CIRCLE
Definition icons.h:1863
#define ICON_MD_LIST
Definition icons.h:1094
#define ICON_MD_CLEAR_ALL
Definition icons.h:417
#define ICON_MD_ADD
Definition icons.h:86
#define ICON_MD_PENDING
Definition icons.h:1398
#define ICON_MD_DEVELOPER_BOARD
Definition icons.h:547
#define ICON_MD_SEND
Definition icons.h:1683
#define ICON_MD_PLAY_CIRCLE
Definition icons.h:1480
#define ICON_MD_CHECK_CIRCLE
Definition icons.h:400
#define ICON_MD_SKIP_NEXT
Definition icons.h:1773
#define ICON_MD_FLAG
Definition icons.h:784
#define ICON_MD_BUILD
Definition icons.h:328
#define ICON_MD_ARROW_BACK
Definition icons.h:173
#define ICON_MD_DELETE
Definition icons.h:530
#define ICON_MD_OPEN_IN_NEW
Definition icons.h:1354
#define ICON_MD_SYNC
Definition icons.h:1919
#define ICON_MD_RESTART_ALT
Definition icons.h:1602
#define ICON_MD_CHECK_BOX_OUTLINE_BLANK
Definition icons.h:399
#define ICON_MD_HOURGLASS_EMPTY
Definition icons.h:967
#define ICON_MD_CLOUD_UPLOAD
Definition icons.h:430
#define ICON_MD_TAG
Definition icons.h:1940
#define ICON_MD_SETTINGS_INPUT_COMPONENT
Definition icons.h:1709
#define ICON_MD_SMART_TOY
Definition icons.h:1781
#define LOG_INFO(category, format,...)
Definition log.h:105
void RenderModernCpuDebugger(Emulator *emu)
Modern CPU debugger with registers, flags, and controls.
void RenderAIAgentPanel(Emulator *emu)
AI Agent panel for automated testing/gameplay.
void RenderBreakpointList(Emulator *emu)
Breakpoint list and management.
void RenderApuDebugger(Emulator *emu)
APU/Audio debugger with handshake tracker.
void RenderMemoryViewer(Emulator *emu)
Memory viewer/editor.
void RenderCpuInstructionLog(Emulator *emu, uint32_t log_size)
CPU instruction log (legacy, prefer DisassemblyViewer)
InterpolationType
Definition dsp.h:10
Graphical User Interface (GUI) components for the application.
ImVec4 ConvertColorToImVec4(const Color &color)
Definition color.h:23
void DrawContents(void *mem_data_void, size_t mem_size, size_t base_display_addr=0x0000)