yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
room_object.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_OBJECT_H
2#define YAZE_APP_ZELDA3_DUNGEON_ROOM_OBJECT_H
3
4#include <cstdint>
5#include <string>
6#include <vector>
7
8#include "absl/strings/str_format.h"
10#include "rom/rom.h"
12
13namespace yaze {
14namespace zelda3 {
15
17
18enum Sorting {
19 All = 0,
20 Wall = 1,
25 Floors = 32,
26 SortStairs = 64
27};
28
29enum class ObjectOption {
30 Nothing = 0,
31 Door = 1,
32 Chest = 2,
33 Block = 4,
34 Torch = 8,
35 Bgr = 16,
36 Stairs = 32
37};
38
43
44constexpr int kRoomObjectSubtype1 = 0x8000; // JP = Same
45constexpr int kRoomObjectSubtype2 = 0x83F0; // JP = Same
46constexpr int kRoomObjectSubtype3 = 0x84F0; // JP = Same
47constexpr int kRoomObjectTileAddress = 0x1B52; // JP = Same
48constexpr int kRoomObjectTileAddressFloor = 0x1B5A; // JP = Same
49
51 public:
52 enum LayerType { BG1 = 0, BG2 = 1, BG3 = 2 };
53
54 // ROM room object stream index (0=primary, 1=BG2 overlay, 2=BG1 overlay).
55 // Same numeric values as LayerType for encode buckets; use only when the
56 // object came from the room object stream (see `layer_` comment below).
57 enum ListIndex : uint8_t {
61 };
62
63 RoomObject(int16_t id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer = 0)
64 : id_(id),
65 x_(x),
66 y_(y),
67 size_(size),
68 layer_(static_cast<LayerType>(layer)),
69 nx_(x),
70 ny_(y),
71 ox_(x),
72 oy_(y),
73 width_(16),
74 height_(16),
75 rom_(nullptr) {
77 }
78
79 void SetRom(Rom* rom) { rom_ = rom; }
80 Rom* rom() const { return rom_; }
81 auto mutable_rom() { return rom_; }
82
83 // Position setters and getters
84 void set_id(int16_t id);
85 void set_x(uint8_t x) { x_ = x; }
86 void set_y(uint8_t y) { y_ = y; }
87 void set_size(uint8_t size) { size_ = size; }
88 uint8_t x() const { return x_; }
89 uint8_t y() const { return y_; }
90 uint8_t size() const { return size_; }
91
92 // Ensures tiles_ is populated with a basic set based on ROM tables so we can
93 // preview/draw objects without needing full emulator execution.
94 void EnsureTilesLoaded();
95
96 // Load tiles using the new ObjectParser
97 absl::Status LoadTilesWithParser();
98
99 // Getter for tiles
100 const std::vector<gfx::TileInfo>& tiles() const { return tiles_; }
101 std::vector<gfx::TileInfo>& mutable_tiles() { return tiles_; }
102
103 // Get tile data through Arena system - returns references, not copies
104 absl::StatusOr<std::span<const gfx::TileInfo>> GetTiles() const;
105
106 // Get individual tile by index - uses Arena lookup
107 absl::StatusOr<const gfx::TileInfo*> GetTile(int index) const;
108
109 // Get tile count without loading all tiles
110 int GetTileCount() const;
111
112 // ============================================================================
113 // Object Encoding/Decoding (Phase 1, Task 1.1)
114 // ============================================================================
115
116 // 3-byte object encoding structure
117 struct ObjectBytes {
118 uint8_t b1;
119 uint8_t b2;
120 uint8_t b3;
121 };
122
123 // Decode object from 3-byte ROM format
124 // Type1: xxxxxxss yyyyyyss iiiiiiii (ID 0x00-0xFF)
125 // Type2: 111111xx xxxxyyyy yyiiiiii (ID 0x100-0x1FF)
126 // Type3: xxxxxxii yyyyyyii 11111iii (ID 0xF00-0xFFF)
127 static RoomObject DecodeObjectFromBytes(uint8_t b1, uint8_t b2, uint8_t b3,
128 uint8_t layer);
129
130 // Encode object to 3-byte ROM format
132
133 // Determine object type from bytes (1, 2, or 3)
134 static int DetermineObjectType(uint8_t b1, uint8_t b3);
135
136 // Get layer from LayerType enum
137 uint8_t GetLayerValue() const { return static_cast<uint8_t>(layer_); }
138
139 // ============================================================================
140
141 // NOTE: Legacy ZScream methods removed. Modern rendering uses:
142 // - ObjectParser for loading tiles from ROM
143 // - ObjectDrawer for rendering tiles to BackgroundBuffer
144
145 auto options() const { return options_; }
147
148 bool all_bgs_ = false;
149 bool lit_ = false;
150
151 int16_t id_;
152 uint8_t x_;
153 uint8_t y_;
154 uint8_t size_;
155 uint8_t nx_;
156 uint8_t ny_;
157 uint8_t ox_;
158 uint8_t oy_;
159 uint8_t z_ = 0;
160 uint8_t previous_size_ = 0;
161 // Size nibble bits captured from object encoding (0..3 each) for heuristic
162 // orientation and sizing decisions.
163 uint8_t size_x_bits_ = 0;
164 uint8_t size_y_bits_ = 0;
165
168 int offset_x_ = 0;
169 int offset_y_ = 0;
170
171 std::string name_;
172
173 std::vector<uint8_t> preview_object_data_;
174
175 // Tile data storage - using Arena system for efficient memory management
176 // Instead of copying Tile16 vectors, we store references to Arena-managed
177 // data
178 mutable std::vector<gfx::TileInfo> tiles_; // Individual tiles like ZScream
179 mutable bool tiles_loaded_ = false;
180 mutable int tile_count_ = 0;
181 mutable int tile_data_ptr_ = -1; // Pointer to tile data in ROM
182
183 // For ROM-backed rooms this is the object *list* index (0=primary, 1=BG2
184 // overlay, 2=BG1 overlay), matching `Room::EncodeObjects` buckets. The editor
185 // reuses the same 0..2 values; use MapRoomObjectListIndexToDrawLayer() before
186 // passing to ObjectDrawer.
189
191
192 private:
194 void InvalidateTileCache();
195};
196
197// USDASM (LoadAndBuildRoom): three room-object lists separated by $FFFF after the
198// floor/layout header. `RoomObject::layer_` stores that list index (0, 1, 2) for
199// encode round-trip — not the same as “which SNES buffer”. After
200// `RoomDraw_DrawFloors`, the layout pass and the primary room-object list both
201// still target the upper/BG1 tilemap pointers; only the post-$FFFF overlay pass
202// explicitly swaps to lower/BG2, and the final pass swaps back to upper/BG1.
203// Use this when building draw lists.
205 uint8_t list_index) {
206 if (list_index > 2) {
207 list_index = 2;
208 }
209 if (list_index == 1) {
211 }
212 return list_index == 0 ? RoomObject::LayerType::BG1
214}
215
216// NOTE: Legacy Subtype1, Subtype2, Subtype3 classes removed.
217// These were ported from ZScream but are no longer used.
218// Modern code uses: ObjectParser + ObjectDrawer + ObjectRenderer
219
220constexpr static inline const char* Type1RoomObjectNames[] = {
221 "Ceiling ↔",
222 "Wall (top, north) ↔",
223 "Wall (top, south) ↔",
224 "Wall (bottom, north) ↔",
225 "Wall (bottom, south) ↔",
226 "Wall columns (north) ↔",
227 "Wall columns (south) ↔",
228 "Deep wall (north) ↔",
229 "Deep wall (south) ↔",
230 "Diagonal wall A ◤ (top) ↔",
231 "Diagonal wall A ◣ (top) ↔",
232 "Diagonal wall A ◥ (top) ↔",
233 "Diagonal wall A ◢ (top) ↔",
234 "Diagonal wall B ◤ (top) ↔",
235 "Diagonal wall B ◣ (top) ↔",
236 "Diagonal wall B ◥ (top) ↔",
237 "Diagonal wall B ◢ (top) ↔",
238 "Diagonal wall C ◤ (top) ↔",
239 "Diagonal wall C ◣ (top) ↔",
240 "Diagonal wall C ◥ (top) ↔",
241 "Diagonal wall C ◢ (top) ↔",
242 "Diagonal wall A ◤ (bottom) ↔",
243 "Diagonal wall A ◣ (bottom) ↔",
244 "Diagonal wall A ◥ (bottom) ↔",
245 "Diagonal wall A ◢ (bottom) ↔",
246 "Diagonal wall B ◤ (bottom) ↔",
247 "Diagonal wall B ◣ (bottom) ↔",
248 "Diagonal wall B ◥ (bottom) ↔",
249 "Diagonal wall B ◢ (bottom) ↔",
250 "Diagonal wall C ◤ (bottom) ↔",
251 "Diagonal wall C ◣ (bottom) ↔",
252 "Diagonal wall C ◥ (bottom) ↔",
253 "Diagonal wall C ◢ (bottom) ↔",
254 "Platform stairs ↔",
255 "Rail ↔",
256 "Pit edge ┏━┓ A (north) ↔",
257 "Pit edge ┏━┓ B (north) ↔",
258 "Pit edge ┏━┓ C (north) ↔",
259 "Pit edge ┏━┓ D (north) ↔",
260 "Pit edge ┏━┓ E (north) ↔",
261 "Pit edge ┗━┛ (south) ↔",
262 "Pit edge ━━━ (south) ↔",
263 "Pit edge ━━━ (north) ↔",
264 "Pit edge ━━┛ (south) ↔",
265 "Pit edge ┗━━ (south) ↔",
266 "Pit edge ━━┓ (north) ↔",
267 "Pit edge ┏━━ (north) ↔",
268 "Rail wall (north) ↔",
269 "Rail wall (south) ↔",
270 "Nothing",
271 "Nothing",
272 "Carpet ↔",
273 "Carpet trim ↔",
274 "Hole in wall", // Generic opening or doorway
275 "Drapes (north) ↔",
276 "Drapes (west, odd) ↔",
277 "Statues ↔",
278 "Columns ↔",
279 "Wall decors (north) ↔",
280 "Wall decors (south) ↔",
281 "Chairs in pairs ↔",
282 "Tall torches ↔",
283 "Supports (north) ↔",
284 "Water edge ┏━┓ (concave) ↔",
285 "Water edge ┗━┛ (concave) ↔",
286 "Water edge ┏━┓ (convex) ↔",
287 "Water edge ┗━┛ (convex) ↔",
288 "Water edge ┏━┛ (concave) ↔",
289 "Water edge ┗━┓ (concave) ↔",
290 "Water edge ┗━┓ (convex) ↔",
291 "Water edge ┏━┛ (convex) ↔",
292 "Unknown", // TODO: NEEDS IN GAME CHECKING
293 "Unknown", // TODO: NEEDS IN GAME CHECKING
294 "Unknown", // TODO: NEEDS IN GAME CHECKING
295 "Unknown", // TODO: NEEDS IN GAME CHECKING
296 "Supports (south) ↔",
297 "Bar ↔",
298 "Shelf A ↔",
299 "Shelf B ↔",
300 "Shelf C ↔",
301 "Somaria path ↔",
302 "Cannon hole A (north) ↔",
303 "Cannon hole A (south) ↔",
304 "Pipe path ↔",
305 "Nothing",
306 "Wall torches (north) ↔",
307 "Wall torches (south) ↔",
308 "Nothing",
309 "Nothing",
310 "Nothing",
311 "Nothing",
312 "Cannon hole B (north) ↔",
313 "Cannon hole B (south) ↔",
314 "Thick rail ↔",
315 "Blocks ↔",
316 "Long rail ↔",
317 "Ceiling ↕",
318 "Wall (top, west) ↕",
319 "Wall (top, east) ↕",
320 "Wall (bottom, west) ↕",
321 "Wall (bottom, east) ↕",
322 "Wall columns (west) ↕",
323 "Wall columns (east) ↕",
324 "Deep wall (west) ↕",
325 "Deep wall (east) ↕",
326 "Rail ↕",
327 "Pit edge (west) ↕",
328 "Pit edge (east) ↕",
329 "Rail wall (west) ↕",
330 "Rail wall (east) ↕",
331 "Nothing",
332 "Nothing",
333 "Carpet ↕",
334 "Carpet trim ↕",
335 "Nothing",
336 "Drapes (west) ↕",
337 "Drapes (east) ↕",
338 "Columns ↕",
339 "Wall decors (west) ↕",
340 "Wall decors (east) ↕",
341 "Supports (west) ↕",
342 "Water edge (west) ↕",
343 "Water edge (east) ↕",
344 "Supports (east) ↕",
345 "Somaria path ↕",
346 "Pipe path ↕",
347 "Nothing",
348 "Wall torches (west) ↕",
349 "Wall torches (east) ↕",
350 "Wall decors tight A (west) ↕",
351 "Wall decors tight A (east) ↕",
352 "Wall decors tight B (west) ↕",
353 "Wall decors tight B (east) ↕",
354 "Cannon hole (west) ↕",
355 "Cannon hole (east) ↕",
356 "Tall torches ↕",
357 "Thick rail ↕",
358 "Blocks ↕",
359 "Long rail ↕",
360 "Jump ledge (west) ↕",
361 "Jump ledge (east) ↕",
362 "Rug trim (west) ↕",
363 "Rug trim (east) ↕",
364 "Bar ↕",
365 "Wall flair (west) ↕",
366 "Wall flair (east) ↕",
367 "Blue pegs ↕",
368 "Orange pegs ↕",
369 "Invisible floor ↕",
370 "Fake pots ↕",
371 "Hammer pegs ↕",
372 "Nothing",
373 "Nothing",
374 "Nothing",
375 "Nothing",
376 "Nothing",
377 "Nothing",
378 "Nothing",
379 "Nothing",
380 "Nothing",
381 "Diagonal ceiling A ◤",
382 "Diagonal ceiling A ◣",
383 "Diagonal ceiling A ◥",
384 "Diagonal ceiling A ◢",
385 "Pit ⇲",
386 "Diagonal layer 2 mask A ◤",
387 "Diagonal layer 2 mask A ◣",
388 "Diagonal layer 2 mask A ◥",
389 "Diagonal layer 2 mask A ◢",
390 "Diagonal layer 2 mask B ◤", // TODO: VERIFY
391 "Diagonal layer 2 mask B ◣", // TODO: VERIFY
392 "Diagonal layer 2 mask B ◥", // TODO: VERIFY
393 "Diagonal layer 2 mask B ◢", // TODO: VERIFY
394 "Nothing",
395 "Nothing",
396 "Nothing",
397 "Jump ledge (north) ↔",
398 "Jump ledge (south) ↔",
399 "Rug ↔",
400 "Rug trim (north) ↔",
401 "Rug trim (south) ↔",
402 "Archery game curtains ↔",
403 "Wall flair (north) ↔",
404 "Wall flair (south) ↔",
405 "Blue pegs ↔",
406 "Orange pegs ↔",
407 "Invisible floor ↔",
408 "Fake pressure plates ↔",
409 "Fake pots ↔",
410 "Hammer pegs ↔",
411 "Nothing",
412 "Nothing",
413 "Ceiling (large) ⇲",
414 "Chest platform (tall) ⇲",
415 "Layer 2 pit mask (large) ⇲",
416 "Layer 2 pit mask (medium) ⇲",
417 "Floor 1 ⇲",
418 "Floor 3 ⇲",
419 "Layer 2 mask (large) ⇲",
420 "Floor 4 ⇲",
421 "Water floor ⇲ ",
422 "Flood water (medium) ⇲ ",
423 "Conveyor floor ⇲ ",
424 "Nothing",
425 "Nothing",
426 "Moving wall (west) ⇲",
427 "Moving wall (east) ⇲",
428 "Nothing",
429 "Nothing",
430 "Icy floor A ⇲",
431 "Icy floor B ⇲",
432 "Moving wall flag", // TODO: WTF IS THIS?
433 "Moving wall flag", // TODO: WTF IS THIS?
434 "Moving wall flag", // TODO: WTF IS THIS?
435 "Moving wall flag", // TODO: WTF IS THIS?
436 "Layer 2 mask (medium) ⇲",
437 "Flood water (large) ⇲",
438 "Layer 2 swim mask ⇲",
439 "Flood water B (large) ⇲",
440 "Floor 2 ⇲",
441 "Chest platform (short) ⇲",
442 "Table / rock ⇲",
443 "Spike blocks ⇲",
444 "Spiked floor ⇲",
445 "Floor 7 ⇲",
446 "Tiled floor ⇲",
447 "Rupee floor ⇲",
448 "Conveyor upwards ⇲",
449 "Conveyor downwards ⇲",
450 "Conveyor leftwards ⇲",
451 "Conveyor rightwards ⇲",
452 "Heavy current water ⇲",
453 "Floor 10 ⇲",
454 "Nothing",
455 "Nothing",
456 "Nothing",
457 "Nothing",
458 "Nothing",
459 "Nothing",
460 "Nothing",
461 "Nothing",
462 "Nothing",
463 "Nothing",
464 "Nothing",
465 "Nothing",
466 "Nothing",
467 "Nothing",
468 "Nothing",
469};
470
471constexpr static inline const char* Type2RoomObjectNames[] = {
472 "Corner (top, concave) ▛",
473 "Corner (top, concave) ▙",
474 "Corner (top, concave) ▜",
475 "Corner (top, concave) ▟",
476 "Corner (top, convex) ▟",
477 "Corner (top, convex) ▜",
478 "Corner (top, convex) ▙",
479 "Corner (top, convex) ▛",
480 "Corner (bottom, concave) ▛",
481 "Corner (bottom, concave) ▙",
482 "Corner (bottom, concave) ▜",
483 "Corner (bottom, concave) ▟",
484 "Corner (bottom, convex) ▟",
485 "Corner (bottom, convex) ▜",
486 "Corner (bottom, convex) ▙",
487 "Corner (bottom, convex) ▛",
488 "Kinked corner north (bottom) ▜",
489 "Kinked corner south (bottom) ▟",
490 "Kinked corner north (bottom) ▛",
491 "Kinked corner south (bottom) ▙",
492 "Kinked corner west (bottom) ▙",
493 "Kinked corner west (bottom) ▛",
494 "Kinked corner east (bottom) ▟",
495 "Kinked corner east (bottom) ▜",
496 "Deep corner (concave) ▛",
497 "Deep corner (concave) ▙",
498 "Deep corner (concave) ▜",
499 "Deep corner (concave) ▟",
500 "Large brazier",
501 "Statue",
502 "Star tile (disabled)",
503 "Star tile (enabled)",
504 "Small torch (lit)",
505 "Barrel",
506 "Statue (back)",
507 "Table",
508 "Fairy statue",
509 "Potted plant",
510 "Stool",
511 "Chair",
512 "Bed",
513 "Fireplace",
514 "Mario portrait",
515 "Unknown", // TODO: NEEDS IN GAME CHECKING
516 "Unknown", // TODO: NEEDS IN GAME CHECKING
517 "Interroom stairs (up)",
518 "Interroom stairs (down)",
519 "Interroom stairs B (down)",
520 "Intraroom stairs north B", // TODO: VERIFY LAYER HANDLING
521 "Intraroom stairs north (separate layers)",
522 "Intraroom stairs north (merged layers)",
523 "Intraroom stairs north (swim layer)",
524 "Block",
525 "Water ladder (north)",
526 "Water ladder (south)", // TODO: NEEDS IN GAME VERIFICATION
527 "Dam floodgate",
528 "Interroom spiral stairs up (top)",
529 "Interroom spiral stairs down (top)",
530 "Interroom spiral stairs up (bottom)",
531 "Interroom spiral stairs down (bottom)",
532 "Sanctuary wall (north)",
533 "Sanctuary pew (right end)",
534 "Pew",
535 "Magic bat altar",
536};
537
538constexpr static inline const char* Type3RoomObjectNames[] = {
539 "Waterfall face (empty)",
540 "Waterfall face (short)",
541 "Waterfall face (long)",
542 "Somaria path endpoint",
543 "Somaria path intersection ╋",
544 "Somaria path corner ┏",
545 "Somaria path corner ┗",
546 "Somaria path corner ┓",
547 "Somaria path corner ┛",
548 "Somaria path intersection ┳",
549 "Somaria path intersection ┻",
550 "Somaria path intersection ┣",
551 "Somaria path intersection ┫",
552 "Unknown", // TODO: NEEDS IN GAME CHECKING
553 "Somaria path 2-way endpoint",
554 "Somaria path crossover",
555 "Babasu hole (north)",
556 "Babasu hole (south)",
557 "9 blue rupees",
558 "Telepathy tile",
559 "Unused / Warp door",
560 "Kholdstare's shell",
561 "Hammer peg",
562 "Prison cell",
563 "Big key lock",
564 "Chest",
565 "Chest (open)",
566 "Intraroom stairs south", // TODO: VERIFY LAYER HANDLING
567 "Intraroom stairs south (separate layers)",
568 "Intraroom stairs south (merged layers)",
569 "Interroom straight stairs up (north, top)",
570 "Interroom straight stairs down (north, top)",
571 "Interroom straight stairs up (south, top)",
572 "Interroom straight stairs down (south, top)",
573 "Deep corner (convex) ▟",
574 "Deep corner (convex) ▜",
575 "Deep corner (convex) ▙",
576 "Deep corner (convex) ▛",
577 "Interroom straight stairs up (north, bottom)",
578 "Interroom straight stairs down (north, bottom)",
579 "Interroom straight stairs up (south, bottom)",
580 "Interroom straight stairs down (south, bottom)",
581 "Lamp cones",
582 "Unknown", // TODO: NEEDS IN GAME CHECKING
583 "Liftable large block",
584 "Agahnim's altar",
585 "Agahnim's boss room",
586 "Pot",
587 "Unknown", // TODO: NEEDS IN GAME CHECKING
588 "Big chest",
589 "Big chest (open)",
590 "Intraroom stairs south (swim layer)",
591 "Intraroom stairs south (long)",
592 "Ladder (north)",
593 "Ladder (south)",
594 "Object 4B",
595 "Object 4C",
596 "Object 4D",
597 "Pipe end (south)",
598 "Pipe end (north)",
599 "Pipe end (east)",
600 "Pipe end (west)",
601 "Pipe corner ▛",
602 "Pipe corner ▙",
603 "Pipe corner ▜",
604 "Pipe corner ▟",
605 "Pipe-rock intersection ⯊",
606 "Pipe-rock intersection ⯋",
607 "Pipe-rock intersection ◖",
608 "Pipe-rock intersection ◗",
609 "Pipe crossover",
610 "Bombable floor",
611 "Fake bombable floor",
612 "Unknown", // TODO: NEEDS IN GAME CHECKING
613 "Warp tile",
614 "Tool rack",
615 "Furnace",
616 "Tub (wide)",
617 "Anvil",
618 "Warp tile (disabled)",
619 "Pressure plate",
620 "Unknown", // TODO: NEEDS IN GAME CHECKING
621 "Blue peg",
622 "Orange peg",
623 "Fortune teller room",
624 "Unknown", // TODO: NEEDS IN GAME CHECKING
625 "Bar corner ▛",
626 "Bar corner ▙",
627 "Bar corner ▜",
628 "Bar corner ▟",
629 "Decorative bowl",
630 "Tub (tall)",
631 "Bookcase",
632 "Range",
633 "Suitcase",
634 "Bar bottles",
635 "Arrow game hole (west)",
636 "Arrow game hole (east)",
637 "Vitreous goo gfx",
638 "Fake pressure plate",
639 "Medusa head",
640 "4-way shooter block",
641 "Pit",
642 "Wall crack (north)",
643 "Wall crack (south)",
644 "Wall crack (west)",
645 "Wall crack (east)",
646 "Large decor",
647 "Water grate (north)",
648 "Water grate (south)",
649 "Water grate (west)",
650 "Water grate (east)",
651 "Window sunlight",
652 "Floor sunlight",
653 "Trinexx's shell",
654 "Layer 2 mask (full)",
655 "Boss entrance",
656 "Minigame chest",
657 "Ganon door",
658 "Triforce wall ornament",
659 "Triforce floor tiles",
660 "Freezor hole",
661 "Pile of bones",
662 "Vitreous goo damage",
663 "Arrow tile ↑",
664 "Arrow tile ↓",
665 "Arrow tile →",
666 "Nothing",
667};
668
669// Helper function to get object name from ID
670// Works across all three object subtypes
671inline std::string GetObjectName(int object_id) {
672 if (object_id < 0x100) {
673 // Type 1: Subtype 1 objects (0x00-0xFF)
674 constexpr size_t kType1Count =
675 sizeof(Type1RoomObjectNames) / sizeof(Type1RoomObjectNames[0]);
676 if (object_id >= 0 && object_id < static_cast<int>(kType1Count)) {
677 return Type1RoomObjectNames[object_id];
678 }
679 return absl::StrFormat("Unknown Type1 (0x%02X)", object_id);
680 } else if (object_id >= 0x100 && object_id < 0x200) {
681 // Type 2: Subtype 2 objects (0x100-0x1FF)
682 int idx = object_id - 0x100;
683 constexpr size_t kType2Count =
684 sizeof(Type2RoomObjectNames) / sizeof(Type2RoomObjectNames[0]);
685 if (idx >= 0 && idx < static_cast<int>(kType2Count)) {
686 return Type2RoomObjectNames[idx];
687 }
688 return absl::StrFormat("Unknown Type2 (0x%03X)", object_id);
689 } else if (object_id >= 0xF80) {
690 // Type 3: Special objects (0xF80-0xFFF, decoded from ASM 0x200-0x27F)
691 int idx = object_id - 0xF80;
692 constexpr size_t kType3Count =
693 sizeof(Type3RoomObjectNames) / sizeof(Type3RoomObjectNames[0]);
694 if (idx >= 0 && idx < static_cast<int>(kType3Count)) {
695 return Type3RoomObjectNames[idx];
696 }
697 return absl::StrFormat("Unknown Type3 (0x%03X)", object_id);
698 }
699 return absl::StrFormat("Unknown (0x%03X)", object_id);
700}
701
702// Helper to get object type/subtype from ID
703inline int GetObjectSubtype(int object_id) {
704 if (object_id < 0x100)
705 return 1;
706 if (object_id < 0x200)
707 return 2;
708 if (object_id >= 0xF80)
709 return 3;
710 return 0; // Unknown
711}
712
713} // namespace zelda3
714} // namespace yaze
715
716#endif // YAZE_APP_ZELDA3_DUNGEON_ROOM_OBJECT_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
absl::StatusOr< const gfx::TileInfo * > GetTile(int index) const
static RoomObject DecodeObjectFromBytes(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t layer)
std::vector< uint8_t > preview_object_data_
std::vector< gfx::TileInfo > tiles_
void set_size(uint8_t size)
Definition room_object.h:87
std::vector< gfx::TileInfo > & mutable_tiles()
ObjectBytes EncodeObjectToBytes() const
const std::vector< gfx::TileInfo > & tiles() const
void set_x(uint8_t x)
Definition room_object.h:85
void set_id(int16_t id)
static int DetermineObjectType(uint8_t b1, uint8_t b3)
absl::Status LoadTilesWithParser()
void SetRom(Rom *rom)
Definition room_object.h:79
uint8_t size() const
Definition room_object.h:90
absl::StatusOr< std::span< const gfx::TileInfo > > GetTiles() const
RoomObject(int16_t id, uint8_t x, uint8_t y, uint8_t size, uint8_t layer=0)
Definition room_object.h:63
uint8_t GetLayerValue() const
void set_y(uint8_t y)
Definition room_object.h:86
void set_options(ObjectOption options)
constexpr int kRoomObjectSubtype3
Definition room_object.h:46
RoomObject::LayerType MapRoomObjectListIndexToDrawLayer(uint8_t list_index)
ObjectOption operator|(ObjectOption lhs, ObjectOption rhs)
int GetObjectSubtype(int object_id)
ObjectOption operator^(ObjectOption lhs, ObjectOption rhs)
constexpr int kRoomObjectSubtype1
Definition room_object.h:44
constexpr int kRoomObjectSubtype2
Definition room_object.h:45
constexpr int kRoomObjectTileAddress
Definition room_object.h:47
ObjectOption operator~(ObjectOption option)
std::string GetObjectName(int object_id)
ObjectOption operator&(ObjectOption lhs, ObjectOption rhs)
constexpr int kRoomObjectTileAddressFloor
Definition room_object.h:48