10#include <emscripten/bind.h>
15#include <unordered_map>
33#include "nlohmann/json.hpp"
35using namespace emscripten;
69EM_JS(
void, CallJsAiDriver, (
const char* history_json), {
70 if (window.yaze && window.yaze.ai && window.yaze.ai.processAgentRequest) {
71 window.yaze.ai.processAgentRequest(UTF8ToString(history_json));
73 console.error(
"AI Driver not found in window.yaze.ai.processAgentRequest");
85 j[
"parts"] = nlohmann::json::array({ {{
"text", msg.
message}} });
93 if (!manager)
return "{\"error\":\"EditorManager not available\"}";
95 auto* agent_ui = manager->GetAgentUiController();
96 if (!agent_ui)
return "{\"error\":\"AgentUiController not available\"}";
98#if defined(YAZE_BUILD_AGENT_UI)
99 auto& sessions = agent_ui->GetSessionManager();
107 if (sessions.GetSessionCount() == 0) {
108 return "{\"error\":\"No agent sessions available\"}";
111 auto& all_sessions = sessions.GetAllSessions();
112 if (all_sessions.empty()) {
113 return "{\"error\":\"No agent sessions available\"}";
115 session = &all_sessions[0];
120 auto* agent_editor = manager->GetAgentEditor();
122 return "{\"error\":\"AgentEditor not available\"}";
125 auto* agent_chat = agent_editor->GetAgentChat();
127 return "{\"error\":\"AgentChat not available\"}";
130 auto* agent_service = agent_chat->GetAgentService();
131 if (!agent_service) {
132 return "{\"error\":\"AgentService not available\"}";
135 agent_service->SetExternalDriver([](
const std::vector<yaze::cli::agent::ChatMessage>& history) {
136 nlohmann::json j_history = nlohmann::json::array();
137 for (
const auto& msg : history) {
140 CallJsAiDriver(j_history.dump().c_str());
143 return "{\"success\":true}";
145 return "{\"error\":\"Agent UI disabled in build\"}";
152 if (!manager)
return;
153 auto* agent_ui = manager->GetAgentUiController();
154 if (!agent_ui)
return;
156#if defined(YAZE_BUILD_AGENT_UI)
157 auto& sessions = agent_ui->GetSessionManager();
158 auto* session = sessions.GetSession(
"default");
159 if (!session)
return;
162 auto* agent_editor = manager->GetAgentEditor();
163 if (!agent_editor)
return;
165 auto* agent_chat = agent_editor->GetAgentChat();
166 if (!agent_chat)
return;
168 auto* agent_service = agent_chat->GetAgentService();
169 if (!agent_service)
return;
172 auto j = nlohmann::json::parse(response_json);
175 if (j.contains(
"text")) response.
text_response = j[
"text"].get<std::string>();
178 if (j.contains(
"tool_calls")) {
179 for (
const auto& tc : j[
"tool_calls"]) {
181 call.
tool_name = tc[
"name"].get<std::string>();
182 if (tc.contains(
"args")) {
183 for (
const auto& [k, v] : tc[
"args"].items()) {
184 call.
args[k] = v.is_string() ? v.get<std::string>() : v.dump();
191 agent_service->HandleExternalResponse(response);
193 }
catch (
const std::exception& e) {
194 printf(
"Error parsing AI response: %s\n", e.what());
209 static const std::unordered_map<std::string, yaze::editor::EditorType>
226 auto it = kEditorMap.find(name);
227 return it != kEditorMap.end() ? it->second
238 std::ostringstream json;
242 return "{\"error\":\"EditorManager not available\"}";
245 auto* editor = manager->GetCurrentEditor();
249 json <<
"\"session_id\":" << manager->GetCurrentSessionId() <<
",";
250 json <<
"\"rom_loaded\":" << (manager->GetCurrentRom() && manager->GetCurrentRom()->is_loaded() ?
"true" :
"false");
265 return result ? std::string(result) :
"";
271 return "{\"error\":\"EditorManager not available\"}";
277 return "{\"error\":\"Unknown editor name. Valid names: Assembly, Dungeon, "
278 "Emulator, Graphics, Music, Overworld, Palette, Screen, Sprite, "
279 "Message, Text, Hex, Agent, Settings\"}";
283 auto* rom = manager->GetCurrentRom();
284 if (!rom || !rom->is_loaded()) {
288 return "{\"error\":\"ROM not loaded\",\"editor\":\"" + editor_name +
293 manager->SwitchToEditor(editor_type);
294 return "{\"success\":true,\"editor\":\"" + editor_name +
295 "\",\"note\":\"Action may be deferred to next frame\"}";
317 return "{\"error\":\"EditorManager not available\",\"op_id\":" +
318 std::to_string(op_id) +
"}";
324 return "{\"error\":\"Unknown editor name\",\"op_id\":" +
325 std::to_string(op_id) +
"}";
329 auto* rom = manager->GetCurrentRom();
330 if (!rom || !rom->is_loaded()) {
333 return "{\"error\":\"ROM not loaded\",\"op_id\":" +
334 std::to_string(op_id) +
"}";
342 manager->QueueDeferredAction([op_id, editor_type, editor_name, manager]() {
344 auto* editor_set = manager->GetCurrentEditorSet();
351 manager->SwitchToEditor(editor_type);
355 return "{\"op_id\":" + std::to_string(op_id) +
356 ",\"status\":\"pending\",\"editor\":\"" + editor_name +
"\"}";
368 return "{\"error\":\"Unknown operation ID\",\"op_id\":" +
369 std::to_string(op_id) +
"}";
372 const std::string& status = it->second;
373 std::ostringstream json;
374 json <<
"{\"op_id\":" << op_id <<
",";
376 if (status ==
"pending") {
377 json <<
"\"status\":\"pending\"}";
378 }
else if (status.rfind(
"completed:", 0) == 0) {
380 std::string editor = status.substr(10);
381 json <<
"\"status\":\"completed\",\"editor\":\"" << editor <<
"\"}";
387 }
else if (status.rfind(
"error:", 0) == 0) {
389 std::string error_msg = status.substr(6);
390 json <<
"\"status\":\"error\",\"error\":\"" << error_msg <<
"\"}";
393 json <<
"\"status\":\"" << status <<
"\"}";
406static const std::unordered_map<std::string, std::vector<std::string>>
409 {
"dungeon.room_selector",
"dungeon.object_editor",
410 "dungeon.tile_selector"}},
412 {
"dungeon.room_selector",
"dungeon.palette_debug"}},
413 {
"overworld_editing",
414 {
"overworld.map_selector",
"overworld.tile_selector",
415 "overworld.entity_editor"}},
417 {
"graphics.sheet_viewer",
"graphics.tile_editor",
418 "graphics.palette_editor"}},
430 return "{\"error\":\"EditorManager not available\"}";
435 auto& card_registry = manager->card_registry();
436 bool success = card_registry.ShowPanel(card_id);
439 return "{\"success\":true,\"card\":\"" + card_id +
"\"}";
441 return "{\"error\":\"Panel not found\",\"card\":\"" + card_id +
"\"}";
451 return "{\"error\":\"EditorManager not available\"}";
454 auto& card_registry = manager->card_registry();
455 bool success = card_registry.HidePanel(card_id);
458 return "{\"success\":true,\"card\":\"" + card_id +
"\"}";
460 return "{\"error\":\"Panel not found\",\"card\":\"" + card_id +
"\"}";
470 return "{\"error\":\"EditorManager not available\"}";
473 auto& card_registry = manager->card_registry();
476 bool was_visible = card_registry.IsPanelVisible(card_id);
481 success = card_registry.HidePanel(card_id);
483 success = card_registry.ShowPanel(card_id);
487 return "{\"success\":true,\"card\":\"" + card_id +
488 "\",\"visible\":" + (was_visible ?
"false" :
"true") +
"}";
490 return "{\"error\":\"Panel not found\",\"card\":\"" + card_id +
"\"}";
501 return "{\"error\":\"EditorManager not available\"}";
504 auto& card_registry = manager->card_registry();
505 size_t session_id = manager->GetCurrentSessionId();
507 std::ostringstream json;
508 json <<
"{\"session_id\":" << session_id <<
",";
509 json <<
"\"active_category\":\"" << card_registry.GetActiveCategory() <<
"\",";
510 json <<
"\"cards\":[";
513 auto categories = card_registry.GetAllCategories(session_id);
514 bool first_card =
true;
516 for (
const auto& category : categories) {
517 auto cards = card_registry.GetPanelsInCategory(session_id, category);
518 for (
const auto& card : cards) {
519 if (!first_card) json <<
",";
523 json <<
"\"id\":\"" << card.card_id <<
"\",";
524 json <<
"\"name\":\"" << card.display_name <<
"\",";
525 json <<
"\"category\":\"" << card.category <<
"\",";
526 json <<
"\"visible\":"
527 << (card_registry.IsPanelVisible(session_id, card.card_id) ?
"true"
543 return "{\"error\":\"EditorManager not available\"}";
546 auto& card_registry = manager->card_registry();
547 size_t session_id = manager->GetCurrentSessionId();
548 auto cards = card_registry.GetPanelsInCategory(session_id, category);
550 std::ostringstream json;
551 json <<
"{\"category\":\"" << category <<
"\",\"cards\":[";
554 for (
const auto& card : cards) {
555 if (!first) json <<
",";
559 json <<
"\"id\":\"" << card.card_id <<
"\",";
560 json <<
"\"name\":\"" << card.display_name <<
"\",";
561 json <<
"\"visible\":"
562 << (card_registry.IsPanelVisible(session_id, card.card_id) ?
"true"
577 return "{\"error\":\"EditorManager not available\"}";
580 auto it = kPanelGroups.find(group_name);
581 if (it == kPanelGroups.end()) {
582 std::ostringstream groups;
583 groups <<
"dungeon_editing, dungeon_debug, overworld_editing, "
584 "graphics_editing, minimal";
585 return "{\"error\":\"Unknown group. Available: " + groups.str() +
"\"}";
588 auto& card_registry = manager->card_registry();
589 const auto& card_ids = it->second;
593 for (
const auto& card_id : card_ids) {
594 if (card_registry.ShowPanel(card_id)) {
599 return "{\"success\":true,\"group\":\"" + group_name +
600 "\",\"cards_shown\":" + std::to_string(shown) +
"}";
609 return "{\"error\":\"EditorManager not available\"}";
612 auto it = kPanelGroups.find(group_name);
613 if (it == kPanelGroups.end()) {
614 return "{\"error\":\"Unknown group\"}";
617 auto& card_registry = manager->card_registry();
618 const auto& card_ids = it->second;
621 if (group_name ==
"minimal") {
622 card_registry.HideAll();
623 return "{\"success\":true,\"group\":\"minimal\",\"action\":\"hid_all\"}";
628 for (
const auto& card_id : card_ids) {
629 if (card_registry.HidePanel(card_id)) {
634 return "{\"success\":true,\"group\":\"" + group_name +
635 "\",\"cards_hidden\":" + std::to_string(hidden) +
"}";
642 std::ostringstream json;
643 json <<
"{\"groups\":[";
646 for (
const auto& [name, cards] : kPanelGroups) {
647 if (!first) json <<
",";
650 json <<
"{\"name\":\"" << name <<
"\",\"cards\":[";
651 bool first_card =
true;
652 for (
const auto& card_id : cards) {
653 if (!first_card) json <<
",";
655 json <<
"\"" << card_id <<
"\"";
673 if (!editor_manager)
return false;
675 return editor_manager->card_registry().IsPanelExpanded();
683 if (!editor_manager) {
684 return R
"({"success":false,"error":"Editor manager not available"})";
687 editor_manager->card_registry().SetPanelExpanded(enabled);
688 return enabled ? R
"({"success":true,"mode":"tree"})"
689 : R"({"success":true,"mode":"icon"})";
697 if (!editor_manager) {
698 return R
"({"success":false,"error":"Editor manager not available"})";
700 auto& registry = editor_manager->card_registry();
701 registry.TogglePanelExpanded();
702 bool is_expanded = registry.IsPanelExpanded();
703 return is_expanded ? R
"({"success":true,"mode":"tree"})"
704 : R"({"success":true,"mode":"icon"})";
712 if (!editor_manager) {
713 return R
"({"available":false})";
716 auto& registry = editor_manager->card_registry();
717 bool is_expanded = registry.IsPanelExpanded();
718 bool is_visible = registry.IsSidebarVisible();
728 std::ostringstream json;
729 json <<
"{\"available\":true,";
730 json <<
"\"mode\":\"" << (is_expanded ?
"tree" :
"icon") <<
"\",";
731 json <<
"\"width\":" << width <<
",";
732 json <<
"\"collapsed\":" << (is_visible ?
"false" :
"true") <<
"}";
745 if (!editor_manager) {
746 return R
"({"success":false,"error":"Editor manager not available"})";
749 auto* right_panel = editor_manager->right_panel_manager();
751 return R
"({"success":false,"error":"Right panel manager not available"})";
755 PanelType type = PanelType::kNone;
757 if (panel_name ==
"properties") {
758 type = PanelType::kProperties;
759 }
else if (panel_name ==
"agent" || panel_name ==
"chat") {
760 type = PanelType::kAgentChat;
761 }
else if (panel_name ==
"proposals") {
762 type = PanelType::kProposals;
763 }
else if (panel_name ==
"settings") {
764 type = PanelType::kSettings;
765 }
else if (panel_name ==
"help") {
766 type = PanelType::kHelp;
768 return R
"({"success":false,"error":"Unknown panel type"})";
771 right_panel->OpenPanel(type);
772 return R
"({"success":true,"panel":")" + panel_name + R"("})";
780 if (!editor_manager) {
781 return R
"({"success":false,"error":"Editor manager not available"})";
784 auto* right_panel = editor_manager->right_panel_manager();
786 return R
"({"success":false,"error":"Right panel manager not available"})";
789 right_panel->ClosePanel();
790 return R
"({"success":true})";
798 if (!editor_manager) {
799 return R
"({"success":false,"error":"Editor manager not available"})";
802 auto* right_panel = editor_manager->right_panel_manager();
804 return R
"({"success":false,"error":"Right panel manager not available"})";
808 PanelType type = PanelType::kNone;
810 if (panel_name ==
"properties") {
811 type = PanelType::kProperties;
812 }
else if (panel_name ==
"agent" || panel_name ==
"chat") {
813 type = PanelType::kAgentChat;
814 }
else if (panel_name ==
"proposals") {
815 type = PanelType::kProposals;
816 }
else if (panel_name ==
"settings") {
817 type = PanelType::kSettings;
818 }
else if (panel_name ==
"help") {
819 type = PanelType::kHelp;
821 return R
"({"success":false,"error":"Unknown panel type"})";
824 right_panel->TogglePanel(type);
825 bool is_open = right_panel->IsPanelActive(type);
826 return is_open ? R
"({"success":true,"state":"open","panel":")" + panel_name +
828 : R"({"success":true,"state":"closed"})";
836 if (!editor_manager) {
837 return R
"({"available":false})";
840 auto* right_panel = editor_manager->right_panel_manager();
842 return R
"({"available":false})";
846 auto active = right_panel->GetActivePanel();
848 std::string active_name =
"none";
850 case PanelType::kProperties:
851 active_name =
"properties";
853 case PanelType::kAgentChat:
854 active_name =
"agent";
856 case PanelType::kProposals:
857 active_name =
"proposals";
859 case PanelType::kSettings:
860 active_name =
"settings";
862 case PanelType::kHelp:
863 active_name =
"help";
869 std::ostringstream json;
870 json <<
"{\"available\":true,";
871 json <<
"\"active\":\"" << active_name <<
"\",";
872 json <<
"\"expanded\":" << (right_panel->IsPanelExpanded() ?
"true" :
"false")
874 json <<
"\"width\":" << right_panel->GetPanelWidth() <<
"}";
924 std::ostringstream json;
928 json <<
"\"texture_queue_size\":" << arena.texture_command_queue_size()
932 json <<
"\"gfx_sheets\":[";
934 for (
int i = 0; i < 223; i++) {
935 auto sheet = arena.gfx_sheet(i);
936 if (sheet.is_active()) {
937 if (!first) json <<
",";
938 json <<
"{\"index\":" << i <<
",\"width\":" << sheet.width()
939 <<
",\"height\":" << sheet.height()
940 <<
",\"has_texture\":" << (sheet.texture() !=
nullptr ?
"true" :
"false")
941 <<
",\"has_surface\":" << (sheet.surface() !=
nullptr ?
"true" :
"false")
953 if (index < 0 || index >= 223) {
954 return "{\"error\": \"Invalid sheet index\"}";
957 std::ostringstream json;
959 auto sheet = arena.gfx_sheet(index);
962 json <<
"\"index\":" << index <<
",";
963 json <<
"\"active\":" << (sheet.is_active() ?
"true" :
"false") <<
",";
964 json <<
"\"width\":" << sheet.width() <<
",";
965 json <<
"\"height\":" << sheet.height() <<
",";
966 json <<
"\"has_texture\":" << (sheet.texture() !=
nullptr ?
"true" :
"false")
968 json <<
"\"has_surface\":" << (sheet.surface() !=
nullptr ?
"true" :
"false");
971 if (sheet.surface() && sheet.surface()->format) {
972 auto* fmt = sheet.surface()->format;
973 json <<
",\"surface_format\":" << fmt->format;
975 json <<
",\"palette_colors\":" << fmt->palette->ncolors;
988 std::ostringstream json;
994 json <<
"\"loaded\":false,\"error\":\"No ROM loaded\"";
996 json <<
"\"loaded\":" << (rom->is_loaded() ?
"true" :
"false") <<
",";
997 json <<
"\"size\":" << rom->size() <<
",";
998 json <<
"\"title\":\"" << rom->title() <<
"\"";
1006 std::ostringstream json;
1009 if (!rom || !rom->is_loaded()) {
1010 return "{\"error\":\"No ROM loaded\"}";
1013 if (count > 256) count = 256;
1014 if (count < 1) count = 1;
1016 json <<
"{\"address\":" << address <<
",\"count\":" << count <<
",\"bytes\":[";
1018 for (
int i = 0; i < count; i++) {
1019 if (i > 0) json <<
",";
1020 auto byte_result = rom->ReadByte(address + i);
1021 if (byte_result.ok()) {
1022 json << static_cast<int>(*byte_result);
1033 std::ostringstream json;
1036 if (!rom || !rom->is_loaded()) {
1037 return "{\"error\":\"No ROM loaded\"}";
1040 json <<
"{\"group_name\":\"" << group_name <<
"\",\"palette_index\":" << palette_index;
1046 if (!load_status.ok()) {
1047 return "{\"error\":\"Failed to load game data\"}";
1051 if (palette_index >= 0 && palette_index <
static_cast<int>(group->size())) {
1052 auto palette = (*group)[palette_index];
1053 json <<
",\"size\":" << palette.size();
1054 json <<
",\"colors\":[";
1055 for (
size_t i = 0; i < palette.size(); i++) {
1056 if (i > 0) json <<
",";
1057 auto rgb = palette[i].rgb();
1058 json <<
"{\"r\":" <<
static_cast<int>(rgb.x)
1059 <<
",\"g\":" <<
static_cast<int>(rgb.y)
1060 <<
",\"b\":" <<
static_cast<int>(rgb.z) <<
"}";
1064 json <<
",\"error\":\"Invalid palette index\"";
1067 json <<
",\"error\":\"Invalid group name. Valid names: ow_main, ow_aux, ow_animated, hud, global_sprites, armors, swords, shields, sprites_aux1, sprites_aux2, sprites_aux3, dungeon_main, grass, 3d_object, ow_mini_map\"";
1070 json <<
",\"error\":\"Exception accessing palette\"";
1082 std::ostringstream json;
1085 if (!rom || !rom->is_loaded()) {
1086 return "{\"error\":\"No ROM loaded\"}";
1090 constexpr int kNumOverworldMaps = 160;
1091 if (map_id < 0 || map_id >= kNumOverworldMaps) {
1092 return "{\"error\":\"Invalid map ID (0-159)\"}";
1095 json <<
"{\"map_id\":" << map_id;
1099 auto size_byte = rom->ReadByte(0x12844 + map_id);
1100 if (size_byte.ok()) {
1101 json <<
",\"size_flag\":" <<
static_cast<int>(*size_byte);
1102 json <<
",\"is_large\":" << (*size_byte == 0x20 ?
"true" :
"false");
1106 auto parent_byte = rom->ReadByte(0x125EC + map_id);
1107 if (parent_byte.ok()) {
1108 json <<
",\"parent_id\":" <<
static_cast<int>(*parent_byte);
1113 json <<
",\"world\":\"light\"";
1114 }
else if (map_id < 128) {
1115 json <<
",\"world\":\"dark\"";
1117 json <<
",\"world\":\"special\"";
1125 std::ostringstream json;
1128 if (!rom || !rom->is_loaded()) {
1129 return "{\"error\":\"No ROM loaded\"}";
1132 json <<
"{\"map_id\":" << map_id
1133 <<
",\"tile_x\":" << tile_x
1134 <<
",\"tile_y\":" << tile_y;
1138 json <<
",\"note\":\"Full tile data requires overworld to be loaded in editor\"";
1170 std::ostringstream json;
1176 json <<
"\"initialized\":false,\"error\":\"Emulator not available\"";
1181 bool is_initialized = emulator->is_snes_initialized();
1182 bool is_running = emulator->running();
1184 json <<
"\"initialized\":" << (is_initialized ?
"true" :
"false") <<
",";
1185 json <<
"\"running\":" << (is_running ?
"true" :
"false") <<
",";
1187 if (is_initialized) {
1188 auto& snes = emulator->snes();
1189 auto& cpu = snes.cpu();
1192 json <<
"\"cpu\":{";
1193 json <<
"\"A\":" << cpu.A <<
",";
1194 json <<
"\"X\":" << cpu.X <<
",";
1195 json <<
"\"Y\":" << cpu.Y <<
",";
1196 json <<
"\"SP\":" << cpu.SP() <<
",";
1197 json <<
"\"PC\":" << cpu.PC <<
",";
1198 json <<
"\"D\":" << cpu.D <<
",";
1199 json <<
"\"DB\":" << (int)cpu.DB <<
",";
1200 json <<
"\"PB\":" << (int)cpu.PB <<
",";
1201 json <<
"\"P\":" << (int)cpu.status <<
",";
1202 json <<
"\"E\":" << (int)cpu.E <<
",";
1205 json <<
"\"flags\":{";
1206 json <<
"\"N\":" << (cpu.GetNegativeFlag() ?
"true" :
"false") <<
",";
1207 json <<
"\"V\":" << (cpu.GetOverflowFlag() ?
"true" :
"false") <<
",";
1208 json <<
"\"M\":" << (cpu.GetAccumulatorSize() ?
"true" :
"false") <<
",";
1209 json <<
"\"X\":" << (cpu.GetIndexSize() ?
"true" :
"false") <<
",";
1210 json <<
"\"D\":" << (cpu.GetDecimalFlag() ?
"true" :
"false") <<
",";
1211 json <<
"\"I\":" << (cpu.GetInterruptFlag() ?
"true" :
"false") <<
",";
1212 json <<
"\"Z\":" << (cpu.GetZeroFlag() ?
"true" :
"false") <<
",";
1213 json <<
"\"C\":" << (cpu.GetCarryFlag() ?
"true" :
"false");
1218 uint32_t full_pc = ((uint32_t)cpu.PB << 16) | cpu.PC;
1219 json <<
"\"full_pc\":" << full_pc <<
",";
1220 json <<
"\"full_pc_hex\":\"$" << std::hex << std::uppercase
1221 << std::setfill(
'0') << std::setw(6) << full_pc << std::dec <<
"\",";
1224 json <<
"\"cycles\":" << snes.mutable_cycles() <<
",";
1225 json <<
"\"fps\":" << emulator->GetCurrentFPS();
1245 std::ostringstream json;
1248 if (!emulator || !emulator->is_snes_initialized()) {
1249 return "{\"error\":\"Emulator not initialized\"}";
1253 if (count > 256) count = 256;
1254 if (count < 1) count = 1;
1256 auto& snes = emulator->snes();
1258 json <<
"{\"address\":" << address <<
",";
1259 json <<
"\"address_hex\":\"$" << std::hex << std::uppercase
1260 << std::setfill(
'0') << std::setw(6) << address << std::dec <<
"\",";
1261 json <<
"\"count\":" << count <<
",";
1262 json <<
"\"bytes\":[";
1266 for (
int i = 0; i < count; i++) {
1267 if (i > 0) json <<
",";
1268 uint8_t
byte = snes.Read(address + i);
1269 json << static_cast<int>(
byte);
1272 json <<
"],\"hex\":\"";
1274 for (
int i = 0; i < count; i++) {
1275 uint8_t
byte = snes.Read(address + i);
1276 json << std::hex << std::uppercase << std::setfill(
'0') << std::setw(2)
1277 <<
static_cast<int>(byte);
1279 json << std::dec <<
"\"}";
1297 std::ostringstream json;
1300 if (!emulator || !emulator->is_snes_initialized()) {
1301 return "{\"error\":\"Emulator not initialized\"}";
1304 auto& snes = emulator->snes();
1305 auto& ppu = snes.ppu();
1306 auto& memory = snes.memory();
1311 json <<
"\"h_pos\":" << memory.h_pos() <<
",";
1312 json <<
"\"v_pos\":" << memory.v_pos() <<
",";
1313 json <<
"\"current_scanline\":" << ppu.current_scanline_ <<
",";
1316 json <<
"\"mode\":" << (int)ppu.mode <<
",";
1317 json <<
"\"brightness\":" << (int)ppu.brightness <<
",";
1318 json <<
"\"forced_blank\":" << (ppu.forced_blank_ ?
"true" :
"false") <<
",";
1319 json <<
"\"overscan\":" << (ppu.overscan_ ?
"true" :
"false") <<
",";
1320 json <<
"\"frame_overscan\":" << (ppu.frame_overscan_ ?
"true" :
"false") <<
",";
1321 json <<
"\"interlace\":" << (ppu.interlace ?
"true" :
"false") <<
",";
1322 json <<
"\"frame_interlace\":" << (ppu.frame_interlace ?
"true" :
"false") <<
",";
1323 json <<
"\"pseudo_hires\":" << (ppu.pseudo_hires_ ?
"true" :
"false") <<
",";
1324 json <<
"\"direct_color\":" << (ppu.direct_color_ ?
"true" :
"false") <<
",";
1325 json <<
"\"bg3_priority\":" << (ppu.bg3priority ?
"true" :
"false") <<
",";
1326 json <<
"\"even_frame\":" << (ppu.even_frame ?
"true" :
"false") <<
",";
1329 json <<
"\"vram_pointer\":" << ppu.vram_pointer <<
",";
1330 json <<
"\"vram_increment\":" << ppu.vram_increment_ <<
",";
1331 json <<
"\"vram_increment_on_high\":" << (ppu.vram_increment_on_high_ ?
"true" :
"false");
1346 std::ostringstream json;
1350 return "{\"error\":\"EditorManager not available\",\"sessions\":[]}";
1354 json <<
"\"current_session\":" << manager->GetCurrentSessionId() <<
",";
1357 auto* current_rom = manager->GetCurrentRom();
1358 if (current_rom && current_rom->is_loaded()) {
1359 json <<
"\"current_rom\":{";
1360 json <<
"\"loaded\":true,";
1361 json <<
"\"title\":\"" << current_rom->title() <<
"\",";
1362 json <<
"\"filename\":\"" << current_rom->filename() <<
"\",";
1363 json <<
"\"size\":" << current_rom->size();
1366 json <<
"\"current_rom\":{\"loaded\":false},";
1371 json <<
"\"sessions\":[]";
1378 std::ostringstream json;
1382 json <<
"\"global_rom_ptr\":" << (rom ?
"true" :
"false") <<
",";
1385 json <<
"\"rom_loaded\":" << (rom->is_loaded() ?
"true" :
"false") <<
",";
1386 json <<
"\"rom_size\":" << rom->size() <<
",";
1387 json <<
"\"rom_filename\":\"" << rom->filename() <<
"\",";
1388 json <<
"\"rom_title\":\"" << rom->title() <<
"\",";
1404 json <<
",\"editor_manager\":{";
1405 json <<
"\"session_count\":" << manager->GetActiveSessionCount() <<
",";
1406 json <<
"\"current_session\":" << manager->GetCurrentSessionId() <<
",";
1407 json <<
"\"has_current_rom\":" << (manager->GetCurrentRom() ?
"true" :
"false");
1410 json <<
",\"editor_manager\":null";
1420 emulator->ResumeAudio();
1430 if (!rom || !rom->is_loaded()) {
1431 return "{\"error\":\"No ROM loaded\"}";
1433 return "Not implemented";
1438 std::ostringstream json;
The EditorManager controls the main editor window and manages the various editor classes.
static constexpr float GetSidebarWidth()
static constexpr float GetSidePanelWidth()
A class for emulating and debugging SNES games.
static PaletteDebugger & Get()
#define YAZE_VERSION_STRING
EM_JS(void, CallJsAiDriver,(const char *history_json), { if(window.yaze &&window.yaze.ai &&window.yaze.ai.processAgentRequest) { window.yaze.ai.processAgentRequest(UTF8ToString(history_json));} else { console.error("AI Driver not found in window.yaze.ai.processAgentRequest");} })
std::unordered_map< uint32_t, std::string > g_pending_operations
nlohmann::json MessageToJson(const yaze::cli::agent::ChatMessage &msg)
std::string registerExternalAiDriver()
yaze::editor::EditorManager * GetEditorManager()
std::atomic< uint32_t > g_operation_counter
yaze::editor::EditorType ParseEditorType(const std::string &name)
void onExternalAiResponse(std::string response_json)
yaze::emu::Emulator * GetGlobalEmulator()
yaze::editor::EditorManager * GetGlobalEditorManager()
yaze::emu::Emulator * GetGlobalEmulator()
Namespace for the command line interface.
constexpr std::array< const char *, 14 > kEditorNames
absl::Status LoadGameData(Rom &rom, GameData &data, const LoadOptions &options)
Loads all Zelda3-specific game data from a generic ROM.
std::vector< ToolCall > tool_calls
std::string text_response
Represents a single agent session with its own chat history and config.
PaletteGroup * get_group(const std::string &group_name)
gfx::PaletteGroupMap palette_groups
Yet Another Zelda3 Editor (YAZE) - Public C API.
std::string showPanelGroup(std::string group_name)
Show a predefined group of cards.
std::string getOperationStatus(uint32_t op_id)
Get the status of an async operation.
std::string showPanel(std::string card_id)
Show a card by ID.
std::string hidePanel(std::string card_id)
Hide a card by ID.
std::string hidePanelGroup(std::string group_name)
Hide a predefined group of cards.
std::string toggleRightPanel(std::string panel_name)
Toggle a specific right panel.
std::string togglePanel(std::string card_id)
Toggle a card's visibility.
std::string closeRightPanel()
Close the currently open right panel.
std::string getHypothesisAnalysis()
std::string getDiagnosticSummary()
std::string samplePixelAt(int x, int y)
std::string getArenaStatus()
std::string getPaletteData()
std::string getEmulatorVideoState()
Get PPU (video) state from the emulator.
std::string switchToEditorAsync(std::string editor_name)
Switch to an editor asynchronously with operation tracking.
std::string getRomPaletteGroup(const std::string &group_name, int palette_index)
std::string getGfxSheetInfo(int index)
std::string getPanelState()
Get the visibility state of all cards.
std::string getEmulatorStatus()
Get the current emulator status including CPU state.
std::string getSidebarState()
Get sidebar state including view mode and width.
std::string getPanelsInCategory(std::string category)
Get cards in a specific category.
std::string getYazeVersion()
std::string getOverworldMapInfo(int map_id)
std::string getOverworldTileInfo(int map_id, int tile_x, int tile_y)
std::string getPanelGroups()
Get available card groups.
const char * Z3edProcessCommand(const char *command)
void clearPaletteDebugEvents()
std::string executeCommand(std::string command)
std::string getRightPanelState()
Get the state of the right panel.
std::string getRomStatus()
std::string getFileManagerDebugInfo()
std::string switchToEditor(std::string editor_name)
void resumeAudioContext()
std::string getFullPaletteState()
std::string toggleTreeViewMode()
Toggle tree view mode.
std::string getColorComparisons()
EMSCRIPTEN_BINDINGS(yaze_debug_inspector)
std::string readRomBytes(int address, int count)
std::string openRightPanel(std::string panel_name)
Open a specific right panel.
bool isTreeViewMode()
Check if tree view mode is enabled.
std::string readEmulatorMemory(int address, int count)
Read memory from the emulator's WRAM.
std::string getRomSessions()
std::string setTreeViewMode(bool enabled)
Set tree view mode.
std::string getEditorState()
std::string getGraphicsDiagnostics()
std::string getFullDebugState()
std::string getDungeonPaletteEvents()
std::string getEventTimeline()