yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
semantic_introspection.cc
Go to the documentation of this file.
2
3#include <nlohmann/json.hpp>
4#include <sstream>
5
6#include "absl/status/status.h"
7
8namespace yaze {
9namespace emu {
10namespace debug {
11
12using json = nlohmann::json;
13
15 : memory_(memory) {
16 if (!memory_) {
17 // Handle null pointer gracefully - this should be caught at construction
18 }
19}
20
21absl::StatusOr<SemanticGameState> SemanticIntrospectionEngine::GetSemanticState() {
22 if (!memory_) {
23 return absl::InvalidArgumentError("Memory pointer is null");
24 }
25
27
28 // Get game mode state
29 auto game_mode = GetGameModeState();
30 if (!game_mode.ok()) {
31 return game_mode.status();
32 }
33 state.game_mode = *game_mode;
34
35 // Get player state
36 auto player = GetPlayerState();
37 if (!player.ok()) {
38 return player.status();
39 }
40 state.player = *player;
41
42 // Get location context
43 auto location = GetLocationContext();
44 if (!location.ok()) {
45 return location.status();
46 }
47 state.location = *location;
48
49 // Get sprite states
50 auto sprites = GetSpriteStates();
51 if (!sprites.ok()) {
52 return sprites.status();
53 }
54 state.sprites = *sprites;
55
56 // Get frame info
58 state.frame.is_lag_frame = false; // TODO: Implement lag frame detection
59
60 return state;
61}
62
63absl::StatusOr<std::string> SemanticIntrospectionEngine::GetStateAsJson() {
64 auto state = GetSemanticState();
65 if (!state.ok()) {
66 return state.status();
67 }
68
69 json j;
70
71 // Game mode
72 j["game_mode"]["main_mode"] = state->game_mode.main_mode;
73 j["game_mode"]["submodule"] = state->game_mode.submodule;
74 j["game_mode"]["mode_name"] = state->game_mode.mode_name;
75 j["game_mode"]["in_game"] = state->game_mode.in_game;
76 j["game_mode"]["in_transition"] = state->game_mode.in_transition;
77
78 // Player
79 j["player"]["x"] = state->player.x;
80 j["player"]["y"] = state->player.y;
81 j["player"]["state"] = state->player.state_name;
82 j["player"]["direction"] = state->player.direction_name;
83 j["player"]["layer"] = state->player.layer;
84 j["player"]["health"] = state->player.health;
85 j["player"]["max_health"] = state->player.max_health;
86
87 // Location
88 j["location"]["indoors"] = state->location.indoors;
89 if (state->location.indoors) {
90 j["location"]["dungeon_room"] = state->location.dungeon_room;
91 j["location"]["room_name"] = state->location.room_name;
92 } else {
93 j["location"]["overworld_area"] = state->location.overworld_area;
94 j["location"]["area_name"] = state->location.area_name;
95 }
96
97 // Sprites
98 j["sprites"] = json::array();
99 for (const auto& sprite : state->sprites) {
100 json sprite_json;
101 sprite_json["id"] = sprite.id;
102 sprite_json["type"] = sprite.type_name;
103 sprite_json["x"] = sprite.x;
104 sprite_json["y"] = sprite.y;
105 sprite_json["state"] = sprite.state_name;
106 j["sprites"].push_back(sprite_json);
107 }
108
109 // Frame
110 j["frame"]["counter"] = state->frame.frame_counter;
111 j["frame"]["is_lag"] = state->frame.is_lag_frame;
112
113 return j.dump(2); // Pretty print with 2-space indentation
114}
115
116absl::StatusOr<PlayerState> SemanticIntrospectionEngine::GetPlayerState() {
117 if (!memory_) {
118 return absl::InvalidArgumentError("Memory pointer is null");
119 }
120
121 PlayerState player;
122
123 // Read player coordinates
124 uint8_t x_low = memory_->ReadByte(alttp::kLinkXLow);
125 uint8_t x_high = memory_->ReadByte(alttp::kLinkXHigh);
126 player.x = (x_high << 8) | x_low;
127
128 uint8_t y_low = memory_->ReadByte(alttp::kLinkYLow);
129 uint8_t y_high = memory_->ReadByte(alttp::kLinkYHigh);
130 player.y = (y_high << 8) | y_low;
131
132 // Read player state
134 player.state_name = GetPlayerStateName(player.state);
135
136 // Read direction
139
140 // Read layer
142
143 // Read health
146
147 return player;
148}
149
150absl::StatusOr<std::vector<SpriteState>> SemanticIntrospectionEngine::GetSpriteStates() {
151 if (!memory_) {
152 return absl::InvalidArgumentError("Memory pointer is null");
153 }
154
155 std::vector<SpriteState> sprites;
156
157 // Check up to 16 sprite slots
158 for (uint8_t i = 0; i < 16; ++i) {
159 uint8_t state = memory_->ReadByte(alttp::kSpriteState + i);
160
161 // Skip inactive sprites (state 0 typically means inactive)
162 if (state == 0) {
163 continue;
164 }
165
166 SpriteState sprite;
167 sprite.id = i;
168
169 // Read sprite coordinates
170 uint8_t x_low = memory_->ReadByte(alttp::kSpriteXLow + i);
171 uint8_t x_high = memory_->ReadByte(alttp::kSpriteXHigh + i);
172 sprite.x = (x_high << 8) | x_low;
173
174 uint8_t y_low = memory_->ReadByte(alttp::kSpriteYLow + i);
175 uint8_t y_high = memory_->ReadByte(alttp::kSpriteYHigh + i);
176 sprite.y = (y_high << 8) | y_low;
177
178 // Read sprite type and state
180 sprite.type_name = GetSpriteTypeName(sprite.type);
181 sprite.state = state;
182 sprite.state_name = GetSpriteStateName(state);
183
184 sprites.push_back(sprite);
185 }
186
187 return sprites;
188}
189
190absl::StatusOr<LocationContext> SemanticIntrospectionEngine::GetLocationContext() {
191 if (!memory_) {
192 return absl::InvalidArgumentError("Memory pointer is null");
193 }
194
195 LocationContext location;
196
197 // Check if indoors
198 location.indoors = memory_->ReadByte(alttp::kIndoorFlag) != 0;
199
200 if (location.indoors) {
201 // Read dungeon room (16-bit)
202 uint8_t room_low = memory_->ReadByte(alttp::kDungeonRoomLow);
203 uint8_t room_high = memory_->ReadByte(alttp::kDungeonRoomHigh);
204 location.dungeon_room = (room_high << 8) | room_low;
205 location.room_name = GetDungeonRoomName(location.dungeon_room);
206 location.area_name = ""; // Not applicable for dungeons
207 } else {
208 // Read overworld area
210 location.area_name = GetOverworldAreaName(location.overworld_area);
211 location.room_name = ""; // Not applicable for overworld
212 }
213
214 return location;
215}
216
217absl::StatusOr<GameModeState> SemanticIntrospectionEngine::GetGameModeState() {
218 if (!memory_) {
219 return absl::InvalidArgumentError("Memory pointer is null");
220 }
221
222 GameModeState mode;
223
226 mode.mode_name = GetGameModeName(mode.main_mode, mode.submodule);
227
228 // Determine if in-game (modes 0x07-0x18 are generally gameplay)
229 mode.in_game = (mode.main_mode >= 0x07 && mode.main_mode <= 0x18);
230
231 // Check for transition states (modes that involve screen transitions)
232 mode.in_transition = (mode.main_mode == 0x0F || mode.main_mode == 0x10 ||
233 mode.main_mode == 0x11 || mode.main_mode == 0x12);
234
235 return mode;
236}
237
238// Helper method implementations
239
240std::string SemanticIntrospectionEngine::GetGameModeName(uint8_t mode, uint8_t submodule) {
241 switch (mode) {
242 case 0x00: return "Startup/Initial";
243 case 0x01: return "Title Screen";
244 case 0x02: return "File Select";
245 case 0x03: return "Name Entry";
246 case 0x04: return "Delete Save";
247 case 0x05: return "Load Game";
248 case 0x06: return "Pre-Dungeon";
249 case 0x07: return "Dungeon";
250 case 0x08: return "Pre-Overworld";
251 case 0x09: return "Overworld";
252 case 0x0A: return "Pre-Overworld (Special)";
253 case 0x0B: return "Overworld (Special)";
254 case 0x0C: return "Unknown Mode";
255 case 0x0D: return "Blank Screen";
256 case 0x0E: return "Text/Dialog";
257 case 0x0F: return "Screen Transition";
258 case 0x10: return "Room Transition";
259 case 0x11: return "Overworld Transition";
260 case 0x12: return "Message";
261 case 0x13: return "Death Sequence";
262 case 0x14: return "Attract Mode";
263 case 0x15: return "Mirror Warp";
264 case 0x16: return "Refill Stats";
265 case 0x17: return "Game Over";
266 case 0x18: return "Triforce Room";
267 case 0x19: return "Victory";
268 case 0x1A: return "Ending Sequence";
269 case 0x1B: return "Credits";
270 default: return "Unknown (" + std::to_string(mode) + ")";
271 }
272}
273
275 switch (state) {
276 case 0x00: return "Standing";
277 case 0x01: return "Walking";
278 case 0x02: return "Turning";
279 case 0x03: return "Pushing";
280 case 0x04: return "Swimming";
281 case 0x05: return "Attacking";
282 case 0x06: return "Spin Attack";
283 case 0x07: return "Item Use";
284 case 0x08: return "Lifting";
285 case 0x09: return "Throwing";
286 case 0x0A: return "Stunned";
287 case 0x0B: return "Jumping";
288 case 0x0C: return "Falling";
289 case 0x0D: return "Dashing";
290 case 0x0E: return "Hookshot";
291 case 0x0F: return "Carrying";
292 case 0x10: return "Sitting";
293 case 0x11: return "Telepathy";
294 case 0x12: return "Bunny";
295 case 0x13: return "Sleep";
296 case 0x14: return "Cape";
297 case 0x15: return "Dying";
298 case 0x16: return "Tree Pull";
299 case 0x17: return "Spin Jump";
300 default: return "Unknown (" + std::to_string(state) + ")";
301 }
302}
303
305 switch (direction) {
306 case 0: return "North";
307 case 2: return "South";
308 case 4: return "West";
309 case 6: return "East";
310 default: return "Unknown (" + std::to_string(direction) + ")";
311 }
312}
313
315 // Common ALTTP sprite types (subset for demonstration)
316 switch (type) {
317 case 0x00: return "Raven";
318 case 0x01: return "Vulture";
319 case 0x02: return "Flying Stalfos Head";
320 case 0x03: return "Empty";
321 case 0x04: return "Pull Switch";
322 case 0x05: return "Pull Switch (unused)";
323 case 0x06: return "Pull Switch (wrong)";
324 case 0x07: return "Pull Switch (unused)";
325 case 0x08: return "Octorok (one way)";
326 case 0x09: return "Moldorm (boss)";
327 case 0x0A: return "Octorok (four way)";
328 case 0x0B: return "Chicken";
329 case 0x0C: return "Octorok (stone)";
330 case 0x0D: return "Buzzblob";
331 case 0x0E: return "Snapdragon";
332 case 0x0F: return "Octoballoon";
333 case 0x10: return "Octoballoon Hatchlings";
334 case 0x11: return "Hinox";
335 case 0x12: return "Moblin";
336 case 0x13: return "Mini Helmasaur";
337 case 0x14: return "Thieves' Town Grate";
338 case 0x15: return "Antifairy";
339 case 0x16: return "Sahasrahla";
340 case 0x17: return "Bush Hoarder";
341 case 0x18: return "Mini Moldorm";
342 case 0x19: return "Poe";
343 case 0x1A: return "Smithy";
344 case 0x1B: return "Arrow";
345 case 0x1C: return "Statue";
346 case 0x1D: return "Flutequest";
347 case 0x1E: return "Crystal Switch";
348 case 0x1F: return "Sick Kid";
349 case 0x20: return "Sluggula";
350 case 0x21: return "Water Switch";
351 case 0x22: return "Ropa";
352 case 0x23: return "Red Bari";
353 case 0x24: return "Blue Bari";
354 case 0x25: return "Talking Tree";
355 case 0x26: return "Hardhat Beetle";
356 case 0x27: return "Deadrock";
357 case 0x28: return "Dark World Hint NPC";
358 case 0x29: return "Adult";
359 case 0x2A: return "Sweeping Lady";
360 case 0x2B: return "Hobo";
361 case 0x2C: return "Lumberjacks";
362 case 0x2D: return "Neckless Man";
363 case 0x2E: return "Flute Kid";
364 case 0x2F: return "Race Game Lady";
365 case 0x30: return "Race Game Guy";
366 case 0x31: return "Fortune Teller";
367 case 0x32: return "Angry Brothers";
368 case 0x33: return "Pull For Rupees";
369 case 0x34: return "Young Snitch";
370 case 0x35: return "Innkeeper";
371 case 0x36: return "Witch";
372 case 0x37: return "Waterfall";
373 case 0x38: return "Eye Statue";
374 case 0x39: return "Locksmith";
375 case 0x3A: return "Magic Bat";
376 case 0x3B: return "Bonk Item";
377 case 0x3C: return "Kid In KakTree";
378 case 0x3D: return "Old Snitch Lady";
379 case 0x3E: return "Hoarder";
380 case 0x3F: return "Tutorial Guard";
381 case 0x40: return "Lightning Lock";
382 case 0x41: return "Blue Guard";
383 case 0x42: return "Green Guard";
384 case 0x43: return "Red Spear Guard";
385 case 0x44: return "Bluesain Bolt";
386 case 0x45: return "Usain Bolt";
387 case 0x46: return "Blue Archer";
388 case 0x47: return "Green Bush Guard";
389 case 0x48: return "Red Javelin Guard";
390 case 0x49: return "Red Bush Guard";
391 case 0x4A: return "Bomb Guard";
392 case 0x4B: return "Green Knife Guard";
393 case 0x4C: return "Geldman";
394 case 0x4D: return "Toppo";
395 case 0x4E: return "Popo";
396 case 0x4F: return "Popo2";
397 case 0x50: return "Cannonball";
398 case 0x51: return "Armos";
399 case 0x52: return "King Zora";
400 case 0x53: return "Armos Knight (boss)";
401 case 0x54: return "Lanmolas (boss)";
402 case 0x55: return "Fireball Zora";
403 case 0x56: return "Walking Zora";
404 case 0x57: return "Desert Statue";
405 case 0x58: return "Crab";
406 case 0x59: return "Lost Woods Bird";
407 case 0x5A: return "Lost Woods Squirrel";
408 case 0x5B: return "Spark (Left to Right)";
409 case 0x5C: return "Spark (Right to Left)";
410 case 0x5D: return "Roller (vertical moving)";
411 case 0x5E: return "Roller (vertical moving)";
412 case 0x5F: return "Roller";
413 case 0x60: return "Roller (horizontal moving)";
414 case 0x61: return "Beamos";
415 case 0x62: return "Master Sword";
416 case 0x63: return "Debirando Pit";
417 case 0x64: return "Debirando";
418 case 0x65: return "Archery Guy";
419 case 0x66: return "Wall Cannon (vertical left)";
420 case 0x67: return "Wall Cannon (vertical right)";
421 case 0x68: return "Wall Cannon (horizontal top)";
422 case 0x69: return "Wall Cannon (horizontal bottom)";
423 case 0x6A: return "Ball N' Chain";
424 case 0x6B: return "Cannon Soldier";
425 case 0x6C: return "Cannon Soldier";
426 case 0x6D: return "Mirror Portal";
427 case 0x6E: return "Rat";
428 case 0x6F: return "Rope";
429 case 0x70: return "Keese";
430 case 0x71: return "Helmasaur King Fireball";
431 case 0x72: return "Leever";
432 case 0x73: return "Pond Trigger";
433 case 0x74: return "Uncle Priest";
434 case 0x75: return "Running Man";
435 case 0x76: return "Bottle Salesman";
436 case 0x77: return "Princess Zelda";
437 case 0x78: return "Antifairy (alternate)";
438 case 0x79: return "Village Elder";
439 case 0x7A: return "Bee";
440 case 0x7B: return "Agahnim";
441 case 0x7C: return "Agahnim Ball";
442 case 0x7D: return "Green Stalfos";
443 case 0x7E: return "Big Spike";
444 case 0x7F: return "Firebar (clockwise)";
445 case 0x80: return "Firebar (counterclockwise)";
446 case 0x81: return "Firesnake";
447 case 0x82: return "Hover";
448 case 0x83: return "Green Eyegore";
449 case 0x84: return "Red Eyegore";
450 case 0x85: return "Yellow Stalfos";
451 case 0x86: return "Kodongo";
452 case 0x87: return "Flames";
453 case 0x88: return "Mothula (boss)";
454 case 0x89: return "Mothula Beam";
455 case 0x8A: return "Spike Block";
456 case 0x8B: return "Gibdo";
457 case 0x8C: return "Arrghus (boss)";
458 case 0x8D: return "Arrghus spawn";
459 case 0x8E: return "Terrorpin";
460 case 0x8F: return "Slime";
461 case 0x90: return "Wallmaster";
462 case 0x91: return "Stalfos Knight";
463 case 0x92: return "Helmasaur King";
464 case 0x93: return "Bumper";
465 case 0x94: return "Pirogusu";
466 case 0x95: return "Laser Eye (left)";
467 case 0x96: return "Laser Eye (right)";
468 case 0x97: return "Laser Eye (top)";
469 case 0x98: return "Laser Eye (bottom)";
470 case 0x99: return "Pengator";
471 case 0x9A: return "Kyameron";
472 case 0x9B: return "Wizzrobe";
473 case 0x9C: return "Zoro";
474 case 0x9D: return "Babasu";
475 case 0x9E: return "Haunted Grove Ostritch";
476 case 0x9F: return "Haunted Grove Rabbit";
477 case 0xA0: return "Haunted Grove Bird";
478 case 0xA1: return "Freezor";
479 case 0xA2: return "Kholdstare";
480 case 0xA3: return "Kholdstare Shell";
481 case 0xA4: return "Falling Ice";
482 case 0xA5: return "Zazak (blue)";
483 case 0xA6: return "Zazak (red)";
484 case 0xA7: return "Stalfos";
485 case 0xA8: return "Bomber Flying Creatures from Darkworld";
486 case 0xA9: return "Bomber Flying Creatures from Darkworld";
487 case 0xAA: return "Pikit";
488 case 0xAB: return "Maiden";
489 case 0xAC: return "Apple";
490 case 0xAD: return "Lost Old Man";
491 case 0xAE: return "Down Pipe";
492 case 0xAF: return "Up Pipe";
493 case 0xB0: return "Right Pip";
494 case 0xB1: return "Left Pipe";
495 case 0xB2: return "Good Bee Again";
496 case 0xB3: return "Hylian Inscription";
497 case 0xB4: return "Thief's chest";
498 case 0xB5: return "Bomb Salesman";
499 case 0xB6: return "Kiki";
500 case 0xB7: return "Blind Maiden";
501 case 0xB8: return "Dialogue Tester";
502 case 0xB9: return "Bully / Pink Ball";
503 case 0xBA: return "Whirlpool";
504 case 0xBB: return "Shopkeeper";
505 case 0xBC: return "Drunk in the Inn";
506 case 0xBD: return "Vitreous (boss)";
507 case 0xBE: return "Vitreous small eye";
508 case 0xBF: return "Vitreous' lightning";
509 case 0xC0: return "Monster in Lake of Ill Omen";
510 case 0xC1: return "Quicksand";
511 case 0xC2: return "Gibo";
512 case 0xC3: return "Thief";
513 case 0xC4: return "Medusa";
514 case 0xC5: return "4-Way Shooter";
515 case 0xC6: return "Pokey";
516 case 0xC7: return "Big Fairy";
517 case 0xC8: return "Tektite";
518 case 0xC9: return "Chain Chomp";
519 case 0xCA: return "Trinexx Rock Head";
520 case 0xCB: return "Trinexx Fire Head";
521 case 0xCC: return "Trinexx Ice Head";
522 case 0xCD: return "Blind (boss)";
523 case 0xCE: return "Blind Laser";
524 case 0xCF: return "Running Stalfos Head";
525 case 0xD0: return "Lynel";
526 case 0xD1: return "Bunny Beam";
527 case 0xD2: return "Flopping Fish";
528 case 0xD3: return "Stal";
529 case 0xD4: return "Landmine";
530 case 0xD5: return "Digging Game Guy";
531 case 0xD6: return "Ganon";
532 case 0xD7: return "Ganon Fire";
533 case 0xD8: return "Heart";
534 case 0xD9: return "Green Rupee";
535 case 0xDA: return "Blue Rupee";
536 case 0xDB: return "Red Rupee";
537 case 0xDC: return "Bomb Refill (1)";
538 case 0xDD: return "Bomb Refill (4)";
539 case 0xDE: return "Bomb Refill (8)";
540 case 0xDF: return "Small Magic Refill";
541 case 0xE0: return "Full Magic Refill";
542 case 0xE1: return "Arrow Refill (5)";
543 case 0xE2: return "Arrow Refill (10)";
544 case 0xE3: return "Fairy";
545 case 0xE4: return "Small Key";
546 case 0xE5: return "Big Key";
547 case 0xE6: return "Shield";
548 case 0xE7: return "Mushroom";
549 case 0xE8: return "Fake Master Sword";
550 case 0xE9: return "Magic Shop Assistant";
551 case 0xEA: return "Heart Container";
552 case 0xEB: return "Heart Piece";
553 case 0xEC: return "Thrown Item";
554 case 0xED: return "Somaria Platform";
555 case 0xEE: return "Castle Mantle";
556 case 0xEF: return "Somaria Platform (unused)";
557 case 0xF0: return "Somaria Platform (unused)";
558 case 0xF1: return "Somaria Platform (unused)";
559 case 0xF2: return "Medallion Tablet";
560 default: return "Unknown Sprite (" + std::to_string(type) + ")";
561 }
562}
563
565 // Generic sprite state names (actual states vary by sprite type)
566 switch (state) {
567 case 0x00: return "Inactive";
568 case 0x01: return "Spawning";
569 case 0x02: return "Normal";
570 case 0x03: return "Held";
571 case 0x04: return "Stunned";
572 case 0x05: return "Falling";
573 case 0x06: return "Dead";
574 case 0x07: return "Unused1";
575 case 0x08: return "Active";
576 case 0x09: return "Recoil";
577 case 0x0A: return "Carried";
578 case 0x0B: return "Frozen";
579 default: return "State " + std::to_string(state);
580 }
581}
582
584 // ALTTP overworld areas
585 switch (area) {
586 case 0x00: return "Lost Woods";
587 case 0x02: return "Lumberjack Tree";
588 case 0x03: case 0x04: case 0x05: case 0x06:
589 return "West Death Mountain";
590 case 0x07: return "East Death Mountain";
591 case 0x0A: return "Mountain Entry";
592 case 0x0F: return "Waterfall of Wishing";
593 case 0x10: return "Lost Woods Alcove";
594 case 0x11: return "North of Kakariko";
595 case 0x12: case 0x13: case 0x14: return "Northwest Pond";
596 case 0x15: return "Desert Area";
597 case 0x16: case 0x17: return "Desert Palace Entrance";
598 case 0x18: return "Kakariko Village";
599 case 0x1A: return "Pond of Happiness";
600 case 0x1B: case 0x1C: return "West Hyrule";
601 case 0x1D: return "Link's House";
602 case 0x1E: return "East Hyrule";
603 case 0x22: return "Smithy House";
604 case 0x25: return "Zora's Domain";
605 case 0x28: return "Haunted Grove Entrance";
606 case 0x29: case 0x2A: return "West Hyrule";
607 case 0x2B: return "Hyrule Castle";
608 case 0x2C: return "East Hyrule";
609 case 0x2D: case 0x2E: return "Eastern Palace";
610 case 0x2F: return "Marsh";
611 case 0x30: return "Desert of Mystery";
612 case 0x32: return "Haunted Grove";
613 case 0x33: case 0x34: return "West Hyrule";
614 case 0x35: return "Graveyard";
615 case 0x37: return "Waterfall Lake";
616 case 0x39: case 0x3A: return "South Hyrule";
617 case 0x3B: return "Pyramid";
618 case 0x3C: return "East Dark World";
619 case 0x3F: return "Marsh";
620 case 0x40: return "Skull Woods";
621 case 0x42: return "Dark Lumberjack Tree";
622 case 0x43: case 0x44: case 0x45: return "West Death Mountain";
623 case 0x47: return "Turtle Rock";
624 case 0x4A: return "Bumper Cave Entry";
625 case 0x4F: return "Dark Waterfall";
626 case 0x50: return "Skull Woods Alcove";
627 case 0x51: return "North of Outcasts";
628 case 0x52: case 0x53: case 0x54: return "Northwest Dark World";
629 case 0x55: return "Dark Desert";
630 case 0x56: case 0x57: return "Misery Mire";
631 case 0x58: return "Village of Outcasts";
632 case 0x5A: return "Dark Pond of Happiness";
633 case 0x5B: return "West Dark World";
634 case 0x5D: return "Dark Link's House";
635 case 0x5E: return "East Dark World";
636 case 0x62: return "Haunted Grove";
637 case 0x65: return "Dig Game";
638 case 0x68: return "Dark Haunted Grove Entrance";
639 case 0x69: case 0x6A: return "West Dark World";
640 case 0x6B: return "Pyramid of Power";
641 case 0x6C: return "East Dark World";
642 case 0x6D: case 0x6E: return "Shield Shop";
643 case 0x6F: return "Dark Marsh";
644 case 0x70: return "Misery Mire";
645 case 0x72: return "Dark Haunted Grove";
646 case 0x73: case 0x74: return "West Dark World";
647 case 0x75: return "Dark Graveyard";
648 case 0x77: return "Palace of Darkness";
649 case 0x7A: return "South Dark World";
650 case 0x7B: return "Pyramid of Power";
651 case 0x7C: return "East Dark World";
652 case 0x7F: return "Swamp Palace";
653 case 0x80: return "Master Sword Grove";
654 case 0x81: return "Zora's Domain";
655 default: return "Area " + std::to_string(area);
656 }
657}
658
660 // Simplified dungeon room naming - actual names depend on extensive lookup
661 // This is a small subset for demonstration
662 if (room < 0x100) {
663 // Light World dungeons
664 if (room >= 0x00 && room <= 0x0F) {
665 return "Sewer/Escape Room " + std::to_string(room);
666 } else if (room >= 0x20 && room <= 0x3F) {
667 return "Hyrule Castle Room " + std::to_string(room - 0x20);
668 } else if (room >= 0x50 && room <= 0x5F) {
669 return "Castle Tower Room " + std::to_string(room - 0x50);
670 } else if (room >= 0x60 && room <= 0x6F) {
671 return "Agahnim Tower Room " + std::to_string(room - 0x60);
672 } else if (room >= 0x70 && room <= 0x7F) {
673 return "Swamp Palace Room " + std::to_string(room - 0x70);
674 } else if (room >= 0x80 && room <= 0x8F) {
675 return "Skull Woods Room " + std::to_string(room - 0x80);
676 } else if (room >= 0x90 && room <= 0x9F) {
677 return "Thieves' Town Room " + std::to_string(room - 0x90);
678 } else if (room >= 0xA0 && room <= 0xAF) {
679 return "Ice Palace Room " + std::to_string(room - 0xA0);
680 } else if (room >= 0xB0 && room <= 0xBF) {
681 return "Misery Mire Room " + std::to_string(room - 0xB0);
682 } else if (room >= 0xC0 && room <= 0xCF) {
683 return "Turtle Rock Room " + std::to_string(room - 0xC0);
684 } else if (room >= 0xD0 && room <= 0xDF) {
685 return "Palace of Darkness Room " + std::to_string(room - 0xD0);
686 } else if (room >= 0xE0 && room <= 0xEF) {
687 return "Desert Palace Room " + std::to_string(room - 0xE0);
688 } else if (room >= 0xF0 && room <= 0xFF) {
689 return "Eastern Palace Room " + std::to_string(room - 0xF0);
690 }
691 }
692
693 // Special rooms
694 switch (room) {
695 case 0x00: return "Sewer Entrance";
696 case 0x01: return "Hyrule Castle North Corridor";
697 case 0x02: return "Switch Room (Escape)";
698 case 0x10: return "Ganon Tower Entrance";
699 case 0x11: return "Ganon Tower Stairs";
700 case 0x20: return "Ganon Tower Big Chest";
701 case 0x30: return "Ganon Tower Final Approach";
702 case 0x40: return "Ganon Tower Top";
703 case 0x41: return "Ganon Arena";
704 default: return "Room " + std::to_string(room);
705 }
706}
707
708} // namespace debug
709} // namespace emu
710} // namespace yaze
Memory interface.
Definition memory.h:64
virtual uint8_t ReadByte(uint32_t address) const =0
absl::StatusOr< LocationContext > GetLocationContext()
Get the current location context.
absl::StatusOr< GameModeState > GetGameModeState()
Get the current game mode state.
SemanticIntrospectionEngine(Memory *memory)
Construct a new Semantic Introspection Engine.
absl::StatusOr< std::string > GetStateAsJson()
Get the semantic state as JSON string.
absl::StatusOr< SemanticGameState > GetSemanticState()
Get the complete semantic game state.
absl::StatusOr< PlayerState > GetPlayerState()
Get only the player state.
absl::StatusOr< std::vector< SpriteState > > GetSpriteStates()
Get all active sprite states.
std::string GetGameModeName(uint8_t mode, uint8_t submodule)
constexpr uint32_t kLinkDirection
constexpr uint32_t kOverworldArea
constexpr uint32_t kDungeonRoomHigh
constexpr uint32_t kDungeonRoomLow
constexpr uint32_t kLinkMaxHealth
Semantic representation of the game mode.
Semantic representation of the current location.
Semantic representation of the player state.
Semantic representation of a sprite entity.