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