yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
room.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_H
2#define YAZE_APP_ZELDA3_DUNGEON_ROOM_H
3
4#include <yaze.h>
5
6#include <array>
7#include <cstdint>
8#include <functional>
9#include <memory>
10#include <optional>
11#include <string_view>
12#include <tuple>
13#include <utility>
14#include <vector>
15
16#include "absl/status/statusor.h"
17#include "absl/types/span.h"
18
20#include "rom/rom.h"
28#include "zelda3/game_data.h"
30
31namespace yaze {
32namespace zelda3 {
33
34class DungeonState;
35class RoomLayerManager;
36struct DungeonStreamLayout;
37
38std::vector<SDL_Color> BuildDungeonRenderPalette(
39 const gfx::SnesPalette& dungeon_palette,
40 const gfx::SnesPalette* hud_palette = nullptr);
41
43 std::span<uint16_t> cgram, const gfx::SnesPalette& dungeon_palette,
44 const gfx::SnesPalette* hud_palette = nullptr);
45
46// ROM addresses defined in dungeon_rom_addresses.h (use kPrefixed names)
47
49 uint8_t ID;
50 std::string Name;
54 LayerMergeType() = default;
55 LayerMergeType(uint8_t id, std::string name, bool see, bool top, bool trans) {
56 ID = id;
57 Name = name;
58 Layer2OnTop = top;
59 Layer2Translucent = trans;
60 Layer2Visible = see;
61 }
62 bool operator==(const LayerMergeType&) const = default;
63};
64
65// LayerMergeType(id, name, Layer2Visible, Layer2OnTop, Layer2Translucent)
66//
67// SNES Mode 1 Layer Priority: BG1 is ALWAYS rendered on top of BG2 by default.
68// The flags control COLOR MATH effects, not Z-order:
69// - Layer2Visible: Whether BG2 is enabled on main screen
70// - Layer2OnTop: Whether BG2 participates in sub-screen color math effects
71// (transparency, additive blending) - does NOT change draw order
72// - Layer2Translucent: Whether color math creates transparency effect
73const static LayerMergeType LayerMerge00{0x00, "Off", true, false, false};
74const static LayerMergeType LayerMerge01{0x01, "Parallax", true, false, false};
75const static LayerMergeType LayerMerge02{0x02, "Dark", true, true, true};
76const static LayerMergeType LayerMerge03{0x03, "On top", false, true, false};
77const static LayerMergeType LayerMerge04{0x04, "Translucent", true, true, true};
78const static LayerMergeType LayerMerge05{0x05, "Addition", true, true, true};
79const static LayerMergeType LayerMerge06{0x06, "Normal", true, false, false};
80const static LayerMergeType LayerMerge07{0x07, "Transparent", true, true, true};
81const static LayerMergeType LayerMerge08{0x08, "Dark room", true, true, true};
82
83const static LayerMergeType kLayerMergeTypeList[] = {
84 LayerMerge00, LayerMerge01, LayerMerge02, LayerMerge03, LayerMerge04,
85 LayerMerge05, LayerMerge06, LayerMerge07, LayerMerge08};
86
94
105
106// Pot item - items hidden under pots, rocks, skulls etc.
107// Each item has its own position from ROM data
108struct PotItem {
109 uint16_t position = 0; // Raw position word from ROM
110 uint8_t item = 0; // Item type (0 = nothing)
111
112 // Decode pixel coordinates from position word
113 // Format: high byte * 16 = Y, low byte * 4 = X
114 int GetPixelX() const { return (position & 0xFF) * 4; }
115 int GetPixelY() const { return ((position >> 8) & 0xFF) * 16; }
116
117 // Get tile coordinates (8-pixel tiles)
118 int GetTileX() const { return GetPixelX() / 8; }
119 int GetTileY() const { return GetPixelY() / 8; }
120};
121
122enum TagKey {
188
189// Editor-authored water fill zones (Oracle of Secrets).
190// Stored as a 64x64 boolean map (0/1 per 8x8 tile). At runtime, the hack
191// consumes a compact offset list derived from these tiles.
193 std::array<uint8_t, 64 * 64> tiles{};
194 bool has_data = false;
195 uint8_t sram_bit_mask = 0; // Bit in $7EF411 (e.g. 0x01)
196};
197
198class Room {
199 public:
205
206 bool header = false;
207 bool object_stream = false;
209 bool sprites = false;
210 bool chests = false;
211 bool pot_items = false;
212 bool torches = false;
213 bool blocks = false;
214 bool custom_collision = false;
215 bool water_fill = false;
217 std::vector<BlockLoadOrder> block_load_orders;
218 };
219
221 Room(int room_id, Rom* rom, GameData* game_data = nullptr);
223
224 // Move-only type due to unique_ptr
227 Room(const Room&) = delete;
228 Room& operator=(const Room&) = delete;
229
230 void LoadRoomGraphics(
231 std::optional<uint8_t> entrance_blockset = std::nullopt);
233 // LoadGraphicsSheetsIntoArena() removed - per-room graphics instead
234 void RenderRoomGraphics();
237 void LoadObjects();
238 void EnsureObjectsLoaded();
239 void LoadSprites();
240 void EnsureSpritesLoaded();
241 void LoadChests();
242 void LoadPotItems();
244 void LoadDoors();
245 void LoadTorches();
246 void LoadBlocks();
247 void LoadPits();
249 void ReloadGraphics(std::optional<uint8_t> entrance_blockset = std::nullopt);
250 void PrepareForRender(
251 std::optional<uint8_t> entrance_blockset = std::nullopt);
252
253 // Public getters and manipulators for sprites
254 const std::vector<zelda3::Sprite>& GetSprites() const { return sprites_; }
255 std::vector<zelda3::Sprite>& GetSprites() { return sprites_; }
256 bool sprites_dirty() const { return save_dirty_state_.sprites; }
259
260 // Public getters and manipulators for chests
261 const std::vector<chest_data>& GetChests() const { return chests_in_room_; }
262 std::vector<chest_data>& GetChests() { return chests_in_room_; }
263 bool chests_dirty() const { return save_dirty_state_.chests; }
266
267 // Public getters and manipulators for stairs
268 const std::vector<staircase>& GetStairs() const { return z3_staircases_; }
269 std::vector<staircase>& GetStairs() { return z3_staircases_; }
270
277 struct Door {
278 uint8_t position;
281
282 uint8_t byte1;
283 uint8_t byte2;
284
286 std::pair<int, int> GetTileCoords() const {
288 }
289
291 std::pair<int, int> GetPixelCoords() const {
293 }
294
299
304
306 std::tuple<int, int, int, int> GetBounds() const {
308 }
309
311 std::tuple<int, int, int, int> GetEditorBounds() const {
313 type);
314 }
315
317 std::string_view GetTypeName() const {
319 }
320
322 std::string_view GetDirectionName() const {
324 }
325
327 std::pair<uint8_t, uint8_t> EncodeBytes() const {
329 }
330
335 static Door FromRomBytes(uint8_t b1, uint8_t b2) {
336 Door door;
337 door.byte1 = b1;
338 door.byte2 = b2;
339 // Position index is in bits 4-7 of b1
340 // ASM does: (b1 & 0xF0) >> 3 which gives index * 2 for table lookup
341 // We store the raw index (0-15, typically 0-5)
342 door.position = (b1 >> 4) & 0x0F;
343 // Direction is in bits 0-1 of b1
344 door.direction = DoorDirectionFromRaw(b1 & 0x03);
345 // Door type is the full second byte
346 door.type = DoorTypeFromRaw(b2);
347 return door;
348 }
349 };
350
351 const std::vector<Door>& GetDoors() const { return doors_; }
352 std::vector<Door>& GetDoors() { return doors_; }
353 void AddDoor(const Door& door) {
354 doors_.push_back(door);
355 objects_loaded_ = true;
357 }
358 void RemoveDoor(size_t index) {
359 if (index < doors_.size()) {
360 doors_.erase(doors_.begin() + index);
361 objects_loaded_ = true;
363 }
364 }
365
366 // Public getters for pot items (items hidden under pots/bushes)
367 const std::vector<PotItem>& GetPotItems() const { return pot_items_; }
368 std::vector<PotItem>& GetPotItems() { return pot_items_; }
372
373 bool torches_dirty() const { return save_dirty_state_.torches; }
376 bool blocks_dirty() const { return save_dirty_state_.blocks; }
379
380 const RoomLayout& GetLayout() const { return layout_; }
381
382 // Public getters and manipulators for tile objects
383 const std::vector<RoomObject>& GetTileObjects() const {
384 return tile_objects_;
385 }
386 std::vector<RoomObject>& GetTileObjects() { return tile_objects_; }
387
388 // Methods for modifying tile objects
395 void AddTileObject(const RoomObject& object) {
396 tile_objects_.push_back(object);
397 objects_loaded_ = true;
399 }
400
401 // Enhanced object manipulation (Phase 3)
402 absl::Status AddObject(const RoomObject& object);
403 absl::Status RemoveObject(size_t index);
404 absl::Status UpdateObject(size_t index, const RoomObject& object);
405 absl::StatusOr<size_t> FindObjectAt(int x, int y, int layer) const;
406 bool ValidateObject(const RoomObject& object) const;
407
408 // Performance optimization: Mark objects as dirty when modified
410 dirty_state_.objects = true;
411 dirty_state_.textures = true;
412 dirty_state_.composite = true;
413 }
419 bool is_special_table_object = false;
420 if ((object.options() & ObjectOption::Torch) != ObjectOption::Nothing) {
422 is_special_table_object = true;
423 }
424 if ((object.options() & ObjectOption::Block) != ObjectOption::Nothing) {
426 is_special_table_object = true;
427 }
428 if (!is_special_table_object) {
430 }
432 }
434 const std::vector<RoomObject>& objects) {
435 for (const auto& object : objects) {
437 }
438 }
451 dirty_state_.graphics = true;
452 dirty_state_.textures = true;
453 dirty_state_.composite = true;
454 }
456 dirty_state_.layout = true;
457 dirty_state_.textures = true;
458 dirty_state_.composite = true;
459 }
460 void RemoveTileObject(size_t index) {
461 if (index < tile_objects_.size()) {
463 tile_objects_.erase(tile_objects_.begin() + index);
464 objects_loaded_ = true;
466 }
467 }
468 size_t GetTileObjectCount() const { return tile_objects_.size(); }
469 RoomObject& GetTileObject(size_t index) { return tile_objects_[index]; }
470 const RoomObject& GetTileObject(size_t index) const {
471 return tile_objects_[index];
472 }
473
474 // =========================================================================
475 // Object Limit Tracking (ZScream Feature Parity)
476 // =========================================================================
477
484 std::map<DungeonLimit, int> GetLimitedObjectCounts() const;
485
489 bool HasExceededLimits() const;
490
494 std::vector<DungeonLimitInfo> GetExceededLimitDetails() const;
495
496 // Custom Collision access
498 return custom_collision_;
499 }
503 if (custom_collision_.has_data != has) {
506 }
507 }
508
509 uint8_t GetCollisionTile(int x, int y) const {
510 if (x < 0 || x >= 64 || y < 0 || y >= 64)
511 return 0;
512 return custom_collision_.tiles[y * 64 + x];
513 }
514
515 void SetCollisionTile(int x, int y, uint8_t tile) {
516 if (x < 0 || x >= 64 || y < 0 || y >= 64)
517 return;
518 custom_collision_.tiles[y * 64 + x] = tile;
521 }
522
526
527 // Water fill zones (Oracle of Secrets)
531
532 bool GetWaterFillTile(int x, int y) const {
533 if (x < 0 || x >= 64 || y < 0 || y >= 64)
534 return false;
535 return water_fill_zone_.tiles[y * 64 + x] != 0;
536 }
537
538 void SetWaterFillTile(int x, int y, bool filled) {
539 if (x < 0 || x >= 64 || y < 0 || y >= 64)
540 return;
541 const uint8_t val = filled ? 1 : 0;
542 const size_t idx = static_cast<size_t>(y * 64 + x);
543 const uint8_t prev = water_fill_zone_.tiles[idx];
544 if (prev == val)
545 return;
546 water_fill_zone_.tiles[idx] = val;
547 if (val) {
550 } else {
551 if (water_fill_tile_count_ > 0) {
553 }
554 if (water_fill_tile_count_ == 0) {
556 }
557 }
558 water_fill_dirty_ = true;
559 }
560
568
570
571 uint8_t water_fill_sram_bit_mask() const {
573 }
574 void set_water_fill_sram_bit_mask(uint8_t mask) {
575 if (water_fill_zone_.sram_bit_mask != mask) {
577 water_fill_dirty_ = true;
578 }
579 }
580
581 bool water_fill_dirty() const { return water_fill_dirty_; }
584
585 bool header_dirty() const { return save_dirty_state_.header; }
588
597
599
601 SaveDirtySnapshot snapshot{
603 .object_stream = save_dirty_state_.object_stream,
604 .object_stream_header = save_dirty_state_.object_stream_header,
605 .sprites = save_dirty_state_.sprites,
606 .chests = save_dirty_state_.chests,
607 .pot_items = save_dirty_state_.pot_items,
608 .torches = save_dirty_state_.torches,
609 .blocks = save_dirty_state_.blocks,
610 .custom_collision = custom_collision_dirty_,
611 .water_fill = water_fill_dirty_,
612 .water_fill_sram_bit_mask = water_fill_zone_.sram_bit_mask,
613 };
614 for (size_t index = 0; index < tile_objects_.size(); ++index) {
615 const auto& object = tile_objects_[index];
616 if ((object.options() & ObjectOption::Block) != ObjectOption::Nothing) {
617 snapshot.block_load_orders.push_back(
618 {.tile_object_index = index,
619 .load_order = object.block_load_order()});
620 }
621 }
622 return snapshot;
623 }
624
635 water_fill_dirty_ = snapshot.water_fill;
637 for (const auto& block : snapshot.block_load_orders) {
638 if (block.tile_object_index >= tile_objects_.size())
639 continue;
640 auto& object = tile_objects_[block.tile_object_index];
641 if ((object.options() & ObjectOption::Block) != ObjectOption::Nothing) {
642 object.set_block_load_order(block.load_order);
643 }
644 }
645 }
646
647 // For undo/redo functionality
648 void SetTileObjects(const std::vector<RoomObject>& objects) {
650 tile_objects_ = objects;
651 objects_loaded_ = true;
654 }
655
656 // Public setters for LoadRoomFromRom function
658 if (bg2_ != bg2) {
659 bg2_ = bg2;
661 }
662 }
669 void SetIsLight(bool is_light) {
670 if (is_light_ != is_light) {
671 is_light_ = is_light;
673 }
674 }
675 void SetPalette(uint8_t pal) {
676 if (palette_ != pal) {
677 palette_ = pal;
680 }
681 }
682 void SetBlockset(uint8_t bs) {
683 if (blockset_ != bs) {
684 blockset_ = bs;
688 }
689 }
690 void SetSpriteset(uint8_t ss) {
691 if (spriteset_ != ss) {
692 spriteset_ = ss;
695 }
696 }
697 void SetRenderEntranceBlockset(uint8_t entrance_blockset) {
698 if (render_entrance_blockset_ != entrance_blockset) {
699 render_entrance_blockset_ = entrance_blockset;
702 }
703 }
705 if (effect_ != effect) {
706 effect_ = effect;
709 }
710 }
712 if (tag1_ != tag1) {
713 tag1_ = tag1;
716 }
717 }
719 if (tag2_ != tag2) {
720 tag2_ = tag2;
723 }
724 }
725 void SetStaircasePlane(int index, uint8_t plane) {
726 if (index >= 0 && index < 4 && staircase_plane_[index] != plane) {
727 staircase_plane_[index] = plane;
729 }
730 }
731 void SetHolewarp(uint8_t hw) {
732 if (holewarp_ != hw) {
733 holewarp_ = hw;
735 }
736 }
737 void SetStaircaseRoom(int index, uint8_t room) {
738 if (index >= 0 && index < 4 && staircase_rooms_[index] != room) {
739 staircase_rooms_[index] = room;
741 }
742 }
743 // SetFloor1/SetFloor2 removed - use set_floor1()/set_floor2() instead
744 // (defined above)
745 void SetMessageId(uint16_t mid) {
746 if (message_id_ != mid) {
747 message_id_ = mid;
749 }
750 }
751
752 // Getters for LoadRoomFromRom function
753 bool IsLight() const { return is_light_; }
754
755 // Additional setters for LoadRoomFromRom function
756 void SetMessageIdDirect(uint16_t mid) {
757 if (message_id_ != mid) {
758 message_id_ = mid;
760 }
761 }
762 void SetLayer2Mode(uint8_t mode) {
763 if (layer2_mode_ != mode) {
764 layer2_mode_ = mode;
766 }
767 }
769 if (layer_merging_ != merging) {
770 layer_merging_ = merging;
772 }
773 }
774 void SetIsDark(bool is_dark) {
775 if (is_dark_ != is_dark) {
776 is_dark_ = is_dark;
778 }
779 }
780 void SetBackgroundTileset(uint8_t tileset) {
781 if (background_tileset_ != tileset) {
782 background_tileset_ = tileset;
784 }
785 }
786 void SetSpriteTileset(uint8_t tileset) {
787 if (sprite_tileset_ != tileset) {
788 sprite_tileset_ = tileset;
790 }
791 }
792 void SetLayer2Behavior(uint8_t behavior) {
793 if (layer2_behavior_ != behavior) {
794 layer2_behavior_ = behavior;
796 }
797 }
799 if (tag1_ != tag1) {
800 tag1_ = tag1;
802 }
803 }
805 if (tag2_ != tag2) {
806 tag2_ = tag2;
808 }
809 }
810 void SetPitsTargetLayer(uint8_t layer) {
811 if (pits_.target_layer != layer) {
812 pits_.target_layer = layer;
814 }
815 }
816 void SetStair1TargetLayer(uint8_t layer) {
817 if (stair1_.target_layer != layer) {
818 stair1_.target_layer = layer;
820 }
821 }
822 void SetStair2TargetLayer(uint8_t layer) {
823 if (stair2_.target_layer != layer) {
824 stair2_.target_layer = layer;
826 }
827 }
828 void SetStair3TargetLayer(uint8_t layer) {
829 if (stair3_.target_layer != layer) {
830 stair3_.target_layer = layer;
832 }
833 }
834 void SetStair4TargetLayer(uint8_t layer) {
835 if (stair4_.target_layer != layer) {
836 stair4_.target_layer = layer;
838 }
839 }
840 void SetPitsTarget(uint8_t target) {
841 if (pits_.target != target) {
842 pits_.target = target;
844 }
845 }
846 void SetStair1Target(uint8_t target) {
847 if (stair1_.target != target) {
848 stair1_.target = target;
850 }
851 }
852 void SetStair2Target(uint8_t target) {
853 if (stair2_.target != target) {
854 stair2_.target = target;
856 }
857 }
858 void SetStair3Target(uint8_t target) {
859 if (stair3_.target != target) {
860 stair3_.target = target;
862 }
863 }
864 void SetStair4Target(uint8_t target) {
865 if (stair4_.target != target) {
866 stair4_.target = target;
868 }
869 }
870
871 // Loaded state
872 bool IsLoaded() const { return is_loaded_; }
873 void SetLoaded(bool loaded) { is_loaded_ = loaded; }
874 bool AreObjectsLoaded() const { return objects_loaded_; }
875 bool AreSpritesLoaded() const { return sprites_loaded_; }
876 bool AreChestsLoaded() const { return chests_loaded_; }
877 bool ArePotItemsLoaded() const { return pot_items_loaded_; }
878 bool AreTorchesLoaded() const { return torches_loaded_; }
879 // True once `LoadBlocks` has populated `tile_objects_` for this room.
880 // The `SaveAllBlocks` encoder uses this to distinguish header-only
881 // rooms (preserve their existing ROM block bytes) from rooms whose
882 // blocks have been fully materialized (encode from in-memory state,
883 // which may include edits/additions/deletions).
884 bool AreBlocksLoaded() const { return blocks_loaded_; }
885
886 // Read-only accessors for metadata
887 background2 bg2() const { return bg2_; }
888 EffectKey effect() const { return effect_; }
889 TagKey tag1() const { return tag1_; }
890 TagKey tag2() const { return tag2_; }
892 const LayerMergeType& layer_merging() const { return layer_merging_; }
893 uint8_t staircase_plane(int index) const {
894 return (index >= 0 && index < 4) ? staircase_plane_[index] : 0;
895 }
896 uint8_t staircase_room(int index) const {
897 return (index >= 0 && index < 4) ? staircase_rooms_[index] : 0;
898 }
899
900 int id() const { return room_id_; }
901
902 // Room header property accessors
903 uint8_t blockset() const { return blockset_; }
905 uint8_t spriteset() const { return spriteset_; }
906 uint8_t palette() const { return palette_; }
907
908 // Resolves the room's palette-set ID to the concrete dungeon_main palette
909 // index (0-19) via the two-level ROM lookup. Returns 0 when game data is
910 // missing or the resolved index is out of range. See palette_structure.md
911 // "Dungeon Main" section for the lookup algorithm.
912 int ResolveDungeonPaletteId() const;
913 uint8_t layout_id() const { return layout_id_; }
914 uint8_t holewarp() const { return holewarp_; }
915 uint16_t message_id() const { return message_id_; }
916
917 // Layout ID setter (marks dirty)
918 void SetLayoutId(uint8_t id) {
919 if (layout_id_ != id) {
920 layout_id_ = id;
923 }
924 }
925
926 // Floor graphics accessors
927 uint8_t floor1() const { return floor1_graphics_; }
928 uint8_t floor2() const { return floor2_graphics_; }
929 void set_floor1(uint8_t value) {
930 if (floor1_graphics_ != value) {
931 floor1_graphics_ = value;
934 }
935 }
936 void set_floor2(uint8_t value) {
937 if (floor2_graphics_ != value) {
938 floor2_graphics_ = value;
941 }
942 }
943 // Enhanced object parsing methods
944 void ParseObjectsFromLocation(int objects_location);
945 void HandleSpecialObjects(short oid, uint8_t posX, uint8_t posY,
946 int& nbr_of_staircase);
947
948 // Object saving (Phase 1, Task 1.3)
949 absl::Status SaveObjects(const DungeonStreamLayout* layout = nullptr);
950 absl::Status SaveObjectStreamHeader(
951 const DungeonStreamLayout* layout = nullptr);
952 std::vector<uint8_t> EncodeObjects() const;
953 absl::Status SaveSprites(const DungeonStreamLayout* layout = nullptr);
954 std::vector<uint8_t> EncodeSprites() const;
955 absl::Status SaveRoomHeader();
956
957 auto blocks() const { return blocks_; }
958 auto& mutable_blocks() { return blocks_; }
959 auto rom() const { return rom_; }
960 auto rom() { return rom_; }
961 auto mutable_rom() { return rom_; }
962 void SetRom(Rom* rom) { rom_ = rom; }
963 auto game_data() { return game_data_; }
964 void SetGameData(GameData* data) { game_data_ = data; }
965
966 // Helper to get version constants from game_data or default to US
968 return kVersionConstantsMap.at(game_data_ ? game_data_->version
969 : zelda3_version::US);
970 }
971 const std::array<uint8_t, 0x10000>& get_gfx_buffer() const {
972 return current_gfx16_;
973 }
974
975 // Per-room background buffers (not shared via arena!)
976 auto& bg1_buffer() { return bg1_buffer_; }
977 auto& bg2_buffer() { return bg2_buffer_; }
978 const auto& bg1_buffer() const { return bg1_buffer_; }
979 const auto& bg2_buffer() const { return bg2_buffer_; }
981 const auto& object_bg1_buffer() const { return object_bg1_buffer_; }
983 const auto& object_bg2_buffer() const { return object_bg2_buffer_; }
984
988
991 bool IsCompositeDirty() const { return dirty_state_.composite; }
992
994
995 private:
998
999 std::array<uint8_t, 0x10000> current_gfx16_;
1000
1001 // Each room has its OWN background buffers and bitmaps
1002 // Each room has its OWN background buffers and bitmaps
1007
1008 struct DirtyState {
1009 bool graphics = true;
1010 bool objects = true;
1011 bool layout = true;
1012 bool textures = true;
1013 bool composite = true;
1014 };
1015
1017 bool header = false;
1018 bool object_stream = false;
1020 bool sprites = false;
1021 bool chests = false;
1022 bool pot_items = false;
1023 bool torches = false;
1024 bool blocks = false;
1025 };
1026
1027 static constexpr uint8_t kObjectHeaderFloor1Dirty = 1u << 0;
1028 static constexpr uint8_t kObjectHeaderFloor2Dirty = 1u << 1;
1029 static constexpr uint8_t kObjectHeaderLayoutDirty = 1u << 2;
1030
1031 // Composite bitmap for merged layer output
1033 mutable uint64_t composite_signature_ = 0;
1034 mutable bool has_composite_signature_ = false;
1037
1038 bool is_light_ = false;
1039 bool is_loaded_ = false;
1040 bool objects_loaded_ = false;
1041 bool sprites_loaded_ = false;
1042 bool chests_loaded_ = false;
1043 bool pot_items_loaded_ = false;
1044 bool torches_loaded_ = false;
1045 bool blocks_loaded_ = false;
1046 bool is_dark_ = false;
1047 bool is_floor_ = true;
1048
1049 // Performance optimization: Cache room properties to avoid unnecessary
1050 // re-renders
1051 uint8_t cached_blockset_ = 0xFF;
1052 uint8_t cached_spriteset_ = 0xFF;
1053 uint8_t cached_palette_ = 0xFF;
1054 uint8_t cached_layout_ = 0xFF;
1057 uint8_t cached_effect_ = 0xFF;
1060
1061 int room_id_ = 0;
1063
1066
1067 // Room header properties (formerly public)
1068 uint8_t blockset_ = 0;
1071 uint8_t spriteset_ = 0;
1072 uint8_t palette_ = 0;
1073 uint8_t layout_id_ = 0;
1074 uint8_t holewarp_ = 0;
1075 uint16_t message_id_ = 0;
1076
1078 uint8_t sprite_tileset_ = 0;
1079 uint8_t layer2_behavior_ = 0;
1080 uint8_t floor1_graphics_ = 0;
1081 uint8_t floor2_graphics_ = 0;
1082 uint8_t layer2_mode_ = 0;
1083
1084 std::array<uint8_t, 16> blocks_;
1085 std::array<chest, 16> chest_list_;
1086
1087 std::vector<RoomObject> tile_objects_;
1088 // TODO: add separate door objects list when door section (F0 FF) is parsed
1089 std::vector<zelda3::Sprite> sprites_;
1090 std::vector<staircase> z3_staircases_;
1091 std::vector<chest_data> chests_in_room_;
1092 std::vector<Door> doors_;
1093 std::vector<PotItem> pot_items_;
1095
1101
1108
1111
1113 bool water_fill_dirty_ = false;
1115 std::unique_ptr<DungeonState> dungeon_state_;
1116};
1117
1118// Loads a room from the ROM.
1119Room LoadRoomFromRom(Rom* rom, int room_id);
1120
1121// Loads only the room header (metadata) from the ROM.
1122Room LoadRoomHeaderFromRom(Rom* rom, int room_id);
1123
1124struct RoomSize {
1126 int64_t room_size;
1127};
1128
1129// Calculates the size of a room in the ROM.
1130RoomSize CalculateRoomSize(Rom* rom, int room_id);
1131
1132// Dungeon-level save: aggregate torches from all rooms and write to ROM.
1133absl::Status SaveAllTorches(Rom* rom, absl::Span<const Room> rooms);
1134absl::Status SaveAllTorches(Rom* rom, int room_count,
1135 const std::function<const Room*(int)>& room_lookup);
1136
1137// Preserve pit count/pointer and table bytes, or encode an explicitly supplied
1138// dirty RoomsWithPitDamage table through the overload below.
1139absl::Status SaveAllPits(Rom* rom);
1140absl::Status SaveAllPits(Rom* rom, PitDamageTable* pit_damage_table);
1141
1142// Preserve blocks length and the four block regions (read from ROM,
1143// write back). No edit support; legacy callers without per-room state
1144// keep this path. New callers should use the room-aware overload below.
1145absl::Status SaveAllBlocks(Rom* rom);
1146
1147// Encode pushable blocks from loaded rooms back into the four
1148// pointer-dereferenced data regions while preserving unmaterialized entries.
1149// Existing blocks retain their committed `block_load_order_`; user-added
1150// blocks tail the buffer in creation order. After every ROM write succeeds,
1151// loaded objects are rebased to their emitted slots and encoded rooms become
1152// clean. Returns FailedPrecondition before mutation if a dirty room's blocks
1153// are not loaded, the final buffer is empty (the vanilla do-while scan requires
1154// one entry), or it exceeds the 128-entry vanilla cap (4 regions × 0x80 bytes /
1155// 4 bytes per entry).
1156absl::Status SaveAllBlocks(Rom* rom, int room_count,
1157 const std::function<const Room*(int)>& room_lookup);
1158
1159// Save custom collision maps for any rooms marked dirty.
1160//
1161// This writes into the ZScream expanded collision region and updates the room
1162// pointer table. Rooms not loaded (or not dirty) are preserved.
1163absl::Status SaveAllCollision(Rom* rom, absl::Span<Room> rooms);
1164absl::Status SaveAllCollision(Rom* rom, int room_count,
1165 const std::function<Room*(int)>& room_lookup);
1166
1167// Scan all room sprite pointers and return the highest used PC address end.
1169
1170// Legacy compatibility helper: relocate a room's sprite payload into free tail
1171// space and update its pointer. The old stream is deliberately preserved;
1172// manifest-backed saves should use DungeonStreamAllocator instead.
1173absl::Status RelocateSpriteData(Rom* rom, int room_id,
1174 const std::vector<uint8_t>& encoded_bytes);
1175
1176// Returns the complete set of PC ranges that the global chest serializer may
1177// write: the two-byte runtime length operand and the live pointer target's
1178// fixed-capacity data region. The three-byte pointer operand itself is read
1179// only and is deliberately excluded.
1180absl::StatusOr<std::vector<std::pair<uint32_t, uint32_t>>>
1181GetChestTableWriteRanges(const Rom* rom);
1182
1184 uint32_t pc = 0;
1185 std::vector<uint8_t> expected_bytes;
1186 std::vector<uint8_t> replacement_bytes;
1187
1188 bool operator==(const ChestWriteRun&) const = default;
1189
1190 uint32_t end() const {
1191 return pc + static_cast<uint32_t>(replacement_bytes.size());
1192 }
1193};
1194
1196 int room_id = 0;
1197 std::vector<uint8_t> encoded_chests;
1198
1199 bool operator==(const ChestDirtyRoomState&) const = default;
1200};
1201
1202// Chest serialization snapshot. It captures both the exact byte runs presented
1203// to manifest preflight and the source state required to apply those runs
1204// safely after other save domains have run. ApplyChestSavePlan reconstructs
1205// and compares the canonical plan before permitting any write.
1207 bool any_dirty = false;
1208 int room_limit = 0;
1209 uint32_t data_pc = 0;
1210 std::array<uint8_t, 3> pointer_operand{};
1212 std::vector<uint8_t> original_capacity_bytes;
1213 std::vector<ChestWriteRun> writes;
1214 std::vector<ChestDirtyRoomState> dirty_rooms;
1215
1216 bool operator==(const ChestSavePlan&) const = default;
1217
1218 std::vector<std::pair<uint32_t, uint32_t>> write_ranges() const {
1219 std::vector<std::pair<uint32_t, uint32_t>> ranges;
1220 ranges.reserve(writes.size());
1221 for (const ChestWriteRun& write : writes) {
1222 ranges.emplace_back(write.pc, write.end());
1223 }
1224 return ranges;
1225 }
1226};
1227
1228absl::StatusOr<ChestSavePlan> BuildChestSavePlan(
1229 const Rom* rom, int room_count,
1230 const std::function<const Room*(int)>& room_lookup);
1231absl::Status ApplyChestSavePlan(
1232 Rom* rom, const ChestSavePlan& plan,
1233 const std::function<const Room*(int)>& room_lookup);
1234
1235// Plan the exact PC ranges changed by the current dirty-room chest state.
1236// One-for-one edits return only the affected record bytes; growth/removal may
1237// return wider runs plus the two-byte runtime length operand. The same plan is
1238// used by manifest preflight and SaveAllChests so protected bytes that are not
1239// actually changing do not block an otherwise safe edit.
1240absl::StatusOr<std::vector<std::pair<uint32_t, uint32_t>>>
1241GetDirtyChestWriteRanges(const Rom* rom, int room_count,
1242 const std::function<const Room*(int)>& room_lookup);
1243
1244// Aggregate chests from all rooms and write to ROM. Dirty rooms replace their
1245// existing occurrences one-for-one in physical-table order. Untouched and
1246// unknown-room records retain their exact bytes and relative order; surplus
1247// occurrences are removed and additional records are appended by room ID.
1248absl::Status SaveAllChests(Rom* rom, absl::Span<const Room> rooms);
1249absl::Status SaveAllChests(Rom* rom, int room_count,
1250 const std::function<const Room*(int)>& room_lookup);
1251
1252// Save pot items for all rooms. Preserves ROM data for rooms not loaded.
1253absl::Status SaveAllPotItems(Rom* rom, absl::Span<const Room> rooms);
1254absl::Status SaveAllPotItems(Rom* rom, absl::Span<const Room> rooms,
1255 const DungeonStreamLayout* repack_layout);
1256absl::Status SaveAllPotItems(
1257 Rom* rom, int room_count,
1258 const std::function<const Room*(int)>& room_lookup);
1259absl::Status SaveAllPotItems(Rom* rom, int room_count,
1260 const std::function<const Room*(int)>& room_lookup,
1261 const DungeonStreamLayout* repack_layout);
1262
1263// RoomEffect names defined in room.cc to avoid static initialization order issues
1264extern const std::string RoomEffect[8];
1265
1266constexpr std::array<std::string_view, 297> kRoomNames = {
1267 "Ganon",
1268 "Hyrule Castle (North Corridor)",
1269 "Behind Sanctuary (Switch)",
1270 "Houlihan",
1271 "Turtle Rock (Crysta-Roller)",
1272 "Empty",
1273 "Swamp Palace (Arrghus[Boss])",
1274 "Tower of Hera (Moldorm[Boss])",
1275 "Cave (Healing Fairy)",
1276 "Palace of Darkness",
1277 "Palace of Darkness (Stalfos Trap)",
1278 "Palace of Darkness (Turtle)",
1279 "Ganon's Tower (Entrance)",
1280 "Ganon's Tower (Agahnim2[Boss])",
1281 "Ice Palace (Entrance )",
1282 "Empty Clone ",
1283 "Ganon Evacuation Route",
1284 "Hyrule Castle (Bombable Stock )",
1285 "Sanctuary",
1286 "Turtle Rock (Hokku-Bokku Key 2)",
1287 "Turtle Rock (Big Key )",
1288 "Turtle Rock",
1289 "Swamp Palace (Swimming Treadmill)",
1290 "Tower of Hera (Moldorm Fall )",
1291 "Cave",
1292 "Palace of Darkness (Dark Maze)",
1293 "Palace of Darkness (Big Chest )",
1294 "Palace of Darkness (Mimics / Moving Wall )",
1295 "Ganon's Tower (Ice Armos)",
1296 "Ganon's Tower (Final Hallway)",
1297 "Ice Palace (Bomb Floor / Bari )",
1298 "Ice Palace (Pengator / Big Key )",
1299 "Agahnim's Tower (Agahnim[Boss])",
1300 "Hyrule Castle (Key-rat )",
1301 "Hyrule Castle (Sewer Text Trigger )",
1302 "Turtle Rock (West Exit to Balcony)",
1303 "Turtle Rock (Double Hokku-Bokku / Big chest )",
1304 "Empty Clone ",
1305 "Swamp Palace (Statue )",
1306 "Tower of Hera (Big Chest)",
1307 "Swamp Palace (Entrance )",
1308 "Skull Woods (Mothula[Boss])",
1309 "Palace of Darkness (Big Hub )",
1310 "Palace of Darkness (Map Chest / Fairy )",
1311 "Cave",
1312 "Empty Clone ",
1313 "Ice Palace (Compass )",
1314 "Cave (Kakariko Well HP)",
1315 "Agahnim's Tower (Maiden Sacrifice Chamber)",
1316 "Tower of Hera (Hardhat Beetles )",
1317 "Hyrule Castle (Sewer Key Chest )",
1318 "Desert Palace (Lanmolas[Boss])",
1319 "Swamp Palace (Push Block Puzzle / Pre-Big Key )",
1320 "Swamp Palace (Big Key / BS )",
1321 "Swamp Palace (Big Chest )",
1322 "Swamp Palace (Map Chest / Water Fill )",
1323 "Swamp Palace (Key Pot )",
1324 "Skull Woods (Gibdo Key / Mothula Hole )",
1325 "Palace of Darkness (Bombable Floor )",
1326 "Palace of Darkness (Spike Block / Conveyor )",
1327 "Cave",
1328 "Ganon's Tower (Torch 2)",
1329 "Ice Palace (Stalfos Knights / Conveyor Hellway)",
1330 "Ice Palace (Map Chest )",
1331 "Agahnim's Tower (Final Bridge )",
1332 "Hyrule Castle (First Dark )",
1333 "Hyrule Castle (6 Ropes )",
1334 "Desert Palace (Torch Puzzle / Moving Wall )",
1335 "Thieves Town (Big Chest )",
1336 "Thieves Town (Jail Cells )",
1337 "Swamp Palace (Compass Chest )",
1338 "Empty Clone ",
1339 "Empty Clone ",
1340 "Skull Woods (Gibdo Torch Puzzle )",
1341 "Palace of Darkness (Entrance )",
1342 "Palace of Darkness (Warps / South Mimics )",
1343 "Ganon's Tower (Mini-Helmasaur Conveyor )",
1344 "Ganon's Tower (Moldorm )",
1345 "Ice Palace (Bomb-Jump )",
1346 "Ice Palace Clone (Fairy )",
1347 "Hyrule Castle (West Corridor)",
1348 "Hyrule Castle (Throne )",
1349 "Hyrule Castle (East Corridor)",
1350 "Desert Palace (Popos 2 / Beamos Hellway )",
1351 "Swamp Palace (Upstairs Pits )",
1352 "Castle Secret Entrance / Uncle Death ",
1353 "Skull Woods (Key Pot / Trap )",
1354 "Skull Woods (Big Key )",
1355 "Skull Woods (Big Chest )",
1356 "Skull Woods (Final Section Entrance )",
1357 "Palace of Darkness (Helmasaur King[Boss])",
1358 "Ganon's Tower (Spike Pit )",
1359 "Ganon's Tower (Ganon-Ball Z)",
1360 "Ganon's Tower (Gauntlet 1/2/3)",
1361 "Ice Palace (Lonely Firebar)",
1362 "Ice Palace (Hidden Chest / Spike Floor )",
1363 "Hyrule Castle (West Entrance )",
1364 "Hyrule Castle (Main Entrance )",
1365 "Hyrule Castle (East Entrance )",
1366 "Desert Palace (Final Section Entrance )",
1367 "Thieves Town (West Attic )",
1368 "Thieves Town (East Attic )",
1369 "Swamp Palace (Hidden Chest / Hidden Door )",
1370 "Skull Woods (Compass Chest )",
1371 "Skull Woods (Key Chest / Trap )",
1372 "Empty Clone ",
1373 "Palace of Darkness (Rupee )",
1374 "Ganon's Tower (Mimics s)",
1375 "Ganon's Tower (Lanmolas )",
1376 "Ganon's Tower (Gauntlet 4/5)",
1377 "Ice Palace (Pengators )",
1378 "Empty Clone ",
1379 "Hyrule Castle (Small Corridor to Jail Cells)",
1380 "Hyrule Castle (Boomerang Chest )",
1381 "Hyrule Castle (Map Chest )",
1382 "Desert Palace (Big Chest )",
1383 "Desert Palace (Map Chest )",
1384 "Desert Palace (Big Key Chest )",
1385 "Swamp Palace (Water Drain )",
1386 "Tower of Hera (Entrance )",
1387 "Empty Clone ",
1388 "Empty Clone ",
1389 "Empty Clone ",
1390 "Ganon's Tower",
1391 "Ganon's Tower (East Side Collapsing Bridge / Exploding Wall )",
1392 "Ganon's Tower (Winder / Warp Maze )",
1393 "Ice Palace (Hidden Chest / Bombable Floor )",
1394 "Ice Palace ( Big Spike Traps )",
1395 "Hyrule Castle (Jail Cell )",
1396 "Hyrule Castle",
1397 "Hyrule Castle (Basement Chasm )",
1398 "Desert Palace (West Entrance )",
1399 "Desert Palace (Main Entrance )",
1400 "Desert Palace (East Entrance )",
1401 "Empty Clone ",
1402 "Tower of Hera (Tile )",
1403 "Empty Clone ",
1404 "Eastern Palace (Fairy )",
1405 "Empty Clone ",
1406 "Ganon's Tower (Block Puzzle / Spike Skip / Map Chest )",
1407 "Ganon's Tower (East and West Downstairs / Big Chest )",
1408 "Ganon's Tower (Tile / Torch Puzzle )",
1409 "Ice Palace",
1410 "Empty Clone ",
1411 "Misery Mire (Vitreous[Boss])",
1412 "Misery Mire (Final Switch )",
1413 "Misery Mire (Dark Bomb Wall / Switches )",
1414 "Misery Mire (Dark Cane Floor Switch Puzzle )",
1415 "Empty Clone ",
1416 "Ganon's Tower (Final Collapsing Bridge )",
1417 "Ganon's Tower (Torches 1 )",
1418 "Misery Mire (Torch Puzzle / Moving Wall )",
1419 "Misery Mire (Entrance )",
1420 "Eastern Palace (Eyegore Key )",
1421 "Empty Clone ",
1422 "Ganon's Tower (Many Spikes / Warp Maze )",
1423 "Ganon's Tower (Invisible Floor Maze )",
1424 "Ganon's Tower (Compass Chest / Invisible Floor )",
1425 "Ice Palace (Big Chest )",
1426 "Ice Palace",
1427 "Misery Mire (Pre-Vitreous )",
1428 "Misery Mire (Fish )",
1429 "Misery Mire (Bridge Key Chest )",
1430 "Misery Mire",
1431 "Turtle Rock (Trinexx[Boss])",
1432 "Ganon's Tower (Wizzrobes s)",
1433 "Ganon's Tower (Moldorm Fall )",
1434 "Tower of Hera (Fairy )",
1435 "Eastern Palace (Stalfos Spawn )",
1436 "Eastern Palace (Big Chest )",
1437 "Eastern Palace (Map Chest )",
1438 "Thieves Town (Moving Spikes / Key Pot )",
1439 "Thieves Town (Blind The Thief[Boss])",
1440 "Empty Clone ",
1441 "Ice Palace",
1442 "Ice Palace (Ice Bridge )",
1443 "Agahnim's Tower (Circle of Pots)",
1444 "Misery Mire (Hourglass )",
1445 "Misery Mire (Slug )",
1446 "Misery Mire (Spike Key Chest )",
1447 "Turtle Rock (Pre-Trinexx )",
1448 "Turtle Rock (Dark Maze)",
1449 "Turtle Rock (Chain Chomps )",
1450 "Turtle Rock (Map Chest / Key Chest / Roller )",
1451 "Eastern Palace (Big Key )",
1452 "Eastern Palace (Lobby Cannonballs )",
1453 "Eastern Palace (Dark Antifairy / Key Pot )",
1454 "Thieves Town (Hellway)",
1455 "Thieves Town (Conveyor Toilet)",
1456 "Empty Clone ",
1457 "Ice Palace (Block Puzzle )",
1458 "Ice Palace Clone (Switch )",
1459 "Agahnim's Tower (Dark Bridge )",
1460 "Misery Mire (Compass Chest / Tile )",
1461 "Misery Mire (Big Hub )",
1462 "Misery Mire (Big Chest )",
1463 "Turtle Rock (Final Crystal Switch Puzzle )",
1464 "Turtle Rock (Laser Bridge)",
1465 "Turtle Rock",
1466 "Turtle Rock (Torch Puzzle)",
1467 "Eastern Palace (Armos Knights[Boss])",
1468 "Eastern Palace (Entrance )",
1469 "??",
1470 "Thieves Town (North West Entrance )",
1471 "Thieves Town (North East Entrance )",
1472 "Empty Clone ",
1473 "Ice Palace (Hole to Kholdstare )",
1474 "Empty Clone ",
1475 "Agahnim's Tower (Dark Maze)",
1476 "Misery Mire (Conveyor Slug / Big Key )",
1477 "Misery Mire (Mire02 / Wizzrobes )",
1478 "Empty Clone ",
1479 "Empty Clone ",
1480 "Turtle Rock (Laser Key )",
1481 "Turtle Rock (Entrance )",
1482 "Empty Clone ",
1483 "Eastern Palace (Zeldagamer / Pre-Armos Knights )",
1484 "Eastern Palace (Canonball ",
1485 "Eastern Palace",
1486 "Thieves Town (Main (South West) Entrance )",
1487 "Thieves Town (South East Entrance )",
1488 "Empty Clone ",
1489 "Ice Palace (Kholdstare[Boss])",
1490 "Cave",
1491 "Agahnim's Tower (Entrance )",
1492 "Cave (Lost Woods HP)",
1493 "Cave (Lumberjack's Tree HP)",
1494 "Cave (1/2 Magic)",
1495 "Cave (Lost Old Man Final Cave)",
1496 "Cave (Lost Old Man Final Cave)",
1497 "Cave",
1498 "Cave",
1499 "Cave",
1500 "Empty Clone ",
1501 "Cave (Spectacle Rock HP)",
1502 "Cave",
1503 "Empty Clone ",
1504 "Cave",
1505 "Cave (Spiral Cave)",
1506 "Cave (Crystal Switch / 5 Chests )",
1507 "Cave (Lost Old Man Starting Cave)",
1508 "Cave (Lost Old Man Starting Cave)",
1509 "House",
1510 "House (Old Woman (Sahasrahla's Wife?))",
1511 "House (Angry Brothers)",
1512 "House (Angry Brothers)",
1513 "Empty Clone ",
1514 "Empty Clone ",
1515 "Cave",
1516 "Cave",
1517 "Cave",
1518 "Cave",
1519 "Empty Clone ",
1520 "Cave",
1521 "Cave",
1522 "Cave",
1523
1524 "Chest Minigame",
1525 "Houses",
1526 "Sick Boy house",
1527 "Tavern",
1528 "Link's House",
1529 "Sarashrala Hut",
1530 "Chest Minigame",
1531 "Library",
1532 "Chicken House",
1533 "Witch Shop",
1534 "A Aginah's Cave",
1535 "Dam",
1536 "Mimic Cave",
1537 "Mire Shed",
1538 "Cave",
1539 "Shop",
1540 "Shop",
1541 "Archery Minigame",
1542 "DW Church/Shop",
1543 "Grave Cave",
1544 "Fairy Fountain",
1545 "Fairy Upgrade",
1546 "Pyramid Fairy",
1547 "Spike Cave",
1548 "Chest Minigame",
1549 "Blind Hut",
1550 "Bonzai Cave",
1551 "Circle of bush Cave",
1552 "Big Bomb Shop, C-House",
1553 "Blind Hut 2",
1554 "Hype Cave",
1555 "Shop",
1556 "Ice Cave",
1557 "Smith",
1558 "Fortune Teller",
1559 "MiniMoldorm Cave",
1560 "Under Rock Caves",
1561 "Smith",
1562 "Cave",
1563 "Mazeblock Cave",
1564 "Smith Peg Cave"};
1565
1566// RoomTag names defined in room.cc to avoid static initialization order issues
1567extern const std::string RoomTag[65];
1568
1569} // namespace zelda3
1570} // namespace yaze
1571
1572#endif
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
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
static std::pair< uint8_t, uint8_t > EncodeDoorBytes(uint8_t position, DoorType type, DoorDirection direction)
Encode door data for ROM storage.
static std::pair< int, int > PositionToPixelCoords(uint8_t position, DoorDirection direction)
Convert encoded position to pixel coordinates.
static std::tuple< int, int, int, int > GetDoorEditorBounds(uint8_t position, DoorDirection direction, DoorType type)
Get the editor interaction bounds for a typed door.
static std::tuple< int, int, int, int > GetDoorBounds(uint8_t position, DoorDirection direction)
Get the bounding rectangle for a door.
static std::pair< int, int > PositionToTileCoords(uint8_t position, DoorDirection direction)
Convert encoded position to tile coordinates.
Interface for accessing dungeon game state.
RoomLayerManager - Manages layer visibility and compositing.
uint8_t holewarp() const
Definition room.h:914
bool ValidateObject(const RoomObject &object) const
Definition room.cc:2435
const std::array< uint8_t, 0x10000 > & get_gfx_buffer() const
Definition room.h:971
SaveDirtyState save_dirty_state_
Definition room.h:1036
destination pits_
Definition room.h:1103
std::vector< RoomObject > tile_objects_
Definition room.h:1087
void MarkPotItemsDirty()
Definition room.h:370
uint8_t cached_blockset_
Definition room.h:1051
EffectKey effect_
Definition room.h:1098
gfx::BackgroundBuffer object_bg1_buffer_
Definition room.h:1005
uint8_t palette_
Definition room.h:1072
void SetTag2Direct(TagKey tag2)
Definition room.h:804
bool HasExceededLimits() const
Check if any object limits are exceeded.
Definition room.cc:4286
void ClearObjectStreamHeaderDirty()
Definition room.h:447
uint8_t render_entrance_blockset_
Definition room.h:1069
uint8_t cached_layout_
Definition room.h:1054
const CustomCollisionMap & custom_collision() const
Definition room.h:497
uint8_t staircase_plane_[4]
Definition room.h:1064
absl::Status UpdateObject(size_t index, const RoomObject &object)
Definition room.cc:2408
void ClearSaveDirtyState()
Definition room.h:598
TagKey cached_tag2_
Definition room.h:1059
WaterFillZoneMap & water_fill_zone()
Definition room.h:529
void AddTileObject(const RoomObject &object)
Definition room.h:395
void MarkLayoutDirty()
Definition room.h:455
bool ArePotItemsLoaded() const
Definition room.h:877
void SetStair4Target(uint8_t target)
Definition room.h:864
void SetPitsTarget(uint8_t target)
Definition room.h:840
void SetIsLight(bool is_light)
Definition room.h:669
void LoadChests()
Definition room.cc:2554
void EnsureSpritesLoaded()
Definition room.cc:828
void MarkObjectsDirty()
Definition room.h:409
gfx::BackgroundBuffer bg2_buffer_
Definition room.h:1004
uint8_t resolved_main_blockset_
Definition room.h:1070
void ClearTileObjects()
Definition room.h:389
void MarkChestsDirty()
Definition room.h:264
const std::vector< chest_data > & GetChests() const
Definition room.h:261
uint8_t cached_floor2_graphics_
Definition room.h:1056
std::vector< zelda3::Sprite > sprites_
Definition room.h:1089
auto mutable_rom()
Definition room.h:961
CustomCollisionMap custom_collision_
Definition room.h:1109
GameData * game_data_
Definition room.h:997
void MarkSaveDirtyForTileObject(const RoomObject &object)
Definition room.h:418
void SetLoaded(bool loaded)
Definition room.h:873
uint8_t GetCollisionTile(int x, int y) const
Definition room.h:509
void ClearObjectStreamDirty()
Definition room.h:443
void ClearCustomCollisionDirty()
Definition room.h:524
void CopyRoomGraphicsToBuffer()
Definition room.cc:877
destination stair2_
Definition room.h:1105
void set_water_fill_sram_bit_mask(uint8_t mask)
Definition room.h:574
uint16_t message_id() const
Definition room.h:915
bool custom_collision_dirty() const
Definition room.h:523
uint8_t cached_palette_
Definition room.h:1053
void ClearHeaderDirty()
Definition room.h:587
uint8_t blockset() const
Definition room.h:903
std::vector< staircase > & GetStairs()
Definition room.h:269
zelda3_version_pointers version_constants() const
Definition room.h:967
void set_floor2(uint8_t value)
Definition room.h:936
void ClearPotItemsDirty()
Definition room.h:371
const WaterFillZoneMap & water_fill_zone() const
Definition room.h:528
uint8_t cached_effect_
Definition room.h:1057
std::vector< Door > doors_
Definition room.h:1092
bool HasUnsavedChanges() const
Definition room.h:589
auto game_data()
Definition room.h:963
void SetStaircaseRoom(int index, uint8_t room)
Definition room.h:737
static constexpr uint8_t kObjectHeaderFloor1Dirty
Definition room.h:1027
uint8_t layer2_behavior_
Definition room.h:1079
const gfx::Bitmap & composite_bitmap() const
Definition room.h:987
int WaterFillTileCount() const
Definition room.h:569
absl::Status RemoveObject(size_t index)
Definition room.cc:2395
void SetStair1TargetLayer(uint8_t layer)
Definition room.h:816
void set_floor1(uint8_t value)
Definition room.h:929
void MarkGraphicsDirty()
Definition room.h:450
void LoadBlocks()
Definition room.cc:4004
void SetLayer2Mode(uint8_t mode)
Definition room.h:762
RoomLayout layout_
Definition room.h:1094
uint8_t layer2_mode_
Definition room.h:1082
void LoadLayoutTilesToBuffer()
Definition room.cc:1245
uint8_t staircase_room(int index) const
Definition room.h:896
void MarkTileObjectCollectionDirty()
Definition room.h:439
auto & mutable_blocks()
Definition room.h:958
bool sprites_loaded_
Definition room.h:1041
void SetTag2(TagKey tag2)
Definition room.h:718
const std::vector< Door > & GetDoors() const
Definition room.h:351
std::vector< DungeonLimitInfo > GetExceededLimitDetails() const
Get list of exceeded limits with details.
Definition room.cc:4291
bool IsLoaded() const
Definition room.h:872
auto & object_bg2_buffer()
Definition room.h:982
void ParseObjectsFromLocation(int objects_location)
Definition room.cc:1692
void MarkBlocksDirty()
Definition room.h:377
uint8_t cached_floor1_graphics_
Definition room.h:1055
bool custom_collision_dirty_
Definition room.h:1110
static constexpr uint8_t kObjectHeaderFloor2Dirty
Definition room.h:1028
void ReloadGraphics(std::optional< uint8_t > entrance_blockset=std::nullopt)
Definition room.cc:842
bool pot_items_dirty() const
Definition room.h:369
void set_has_custom_collision(bool has)
Definition room.h:502
void ClearWaterFillZone()
Definition room.h:561
const auto & object_bg1_buffer() const
Definition room.h:981
std::vector< zelda3::Sprite > & GetSprites()
Definition room.h:255
void SetTag1Direct(TagKey tag1)
Definition room.h:798
void LoadTorches()
Definition room.cc:2614
bool IsCompositeDirty() const
Definition room.h:991
void SetLayoutId(uint8_t id)
Definition room.h:918
void SetHolewarp(uint8_t hw)
Definition room.h:731
std::vector< Door > & GetDoors()
Definition room.h:352
TagKey tag2() const
Definition room.h:890
destination stair4_
Definition room.h:1107
void SetStair2Target(uint8_t target)
Definition room.h:852
bool object_stream_dirty() const
Definition room.h:442
size_t GetTileObjectCount() const
Definition room.h:468
const auto & object_bg2_buffer() const
Definition room.h:983
bool sprites_dirty() const
Definition room.h:256
uint8_t floor2() const
Definition room.h:928
bool header_dirty() const
Definition room.h:585
CustomCollisionMap & custom_collision()
Definition room.h:500
void SetCollision(CollisionKey collision)
Definition room.h:663
bool object_stream_header_dirty() const
Definition room.h:444
const std::vector< staircase > & GetStairs() const
Definition room.h:268
void ClearChestsDirty()
Definition room.h:265
gfx::BackgroundBuffer bg1_buffer_
Definition room.h:1003
bool torches_loaded_
Definition room.h:1044
void MarkSpritesDirty()
Definition room.h:257
bool has_water_fill_zone() const
Definition room.h:530
uint8_t palette() const
Definition room.h:906
RoomObject & GetTileObject(size_t index)
Definition room.h:469
void SetStaircasePlane(int index, uint8_t plane)
Definition room.h:725
absl::Status SaveObjects(const DungeonStreamLayout *layout=nullptr)
Definition room.cc:2023
void SetIsDark(bool is_dark)
Definition room.h:774
void MarkTorchesDirty()
Definition room.h:374
bool objects_loaded_
Definition room.h:1040
WaterFillZoneMap water_fill_zone_
Definition room.h:1112
auto rom() const
Definition room.h:959
std::map< DungeonLimit, int > GetLimitedObjectCounts() const
Count limited objects in this room.
Definition room.cc:4188
void RenderRoomGraphics()
Definition room.cc:990
void RestoreSaveDirtySnapshot(const SaveDirtySnapshot &snapshot)
Definition room.h:625
absl::Status SaveRoomHeader()
Definition room.cc:2290
gfx::Bitmap composite_bitmap_
Definition room.h:1032
Room & operator=(Room &&)
bool chests_dirty() const
Definition room.h:263
uint8_t sprite_tileset_
Definition room.h:1078
uint64_t composite_signature_
Definition room.h:1033
std::vector< RoomObject > & GetTileObjects()
Definition room.h:386
uint16_t message_id_
Definition room.h:1075
TagKey tag1() const
Definition room.h:889
std::vector< PotItem > & GetPotItems()
Definition room.h:368
CollisionKey collision() const
Definition room.h:891
const RoomLayout & GetLayout() const
Definition room.h:380
void MarkTileObjectDomainsDirtyForSnapshot(const std::vector< RoomObject > &objects)
Definition room.h:433
void SetMessageIdDirect(uint16_t mid)
Definition room.h:756
void AddDoor(const Door &door)
Definition room.h:353
void LoadRoomGraphics(std::optional< uint8_t > entrance_blockset=std::nullopt)
Definition room.cc:749
uint8_t staircase_rooms_[4]
Definition room.h:1065
const auto & bg1_buffer() const
Definition room.h:978
bool water_fill_dirty_
Definition room.h:1113
gfx::Bitmap & GetCompositeBitmap(RoomLayerManager &layer_mgr)
Get a composite bitmap of all layers merged.
Definition room.cc:977
std::vector< uint8_t > EncodeObjects() const
Definition room.cc:1798
void SetEffect(EffectKey effect)
Definition room.h:704
absl::Status SaveObjectStreamHeader(const DungeonStreamLayout *layout=nullptr)
Definition room.cc:2119
gfx::BackgroundBuffer object_bg2_buffer_
Definition room.h:1006
uint8_t spriteset() const
Definition room.h:905
void ClearWaterFillDirty()
Definition room.h:582
Room & operator=(const Room &)=delete
uint8_t holewarp_
Definition room.h:1074
uint8_t layout_id_
Definition room.h:1073
std::array< uint8_t, 16 > blocks_
Definition room.h:1084
void SetTag1(TagKey tag1)
Definition room.h:711
void SetBackgroundTileset(uint8_t tileset)
Definition room.h:780
void SetStair3TargetLayer(uint8_t layer)
Definition room.h:828
void SetRenderEntranceBlockset(uint8_t entrance_blockset)
Definition room.h:697
const std::vector< zelda3::Sprite > & GetSprites() const
Definition room.h:254
uint8_t floor2_graphics_
Definition room.h:1081
background2 bg2_
Definition room.h:1102
std::array< chest, 16 > chest_list_
Definition room.h:1085
absl::Status SaveSprites(const DungeonStreamLayout *layout=nullptr)
Definition room.cc:2217
auto & bg1_buffer()
Definition room.h:976
void PrepareForRender(std::optional< uint8_t > entrance_blockset=std::nullopt)
Definition room.cc:853
const std::vector< RoomObject > & GetTileObjects() const
Definition room.h:383
bool IsLight() const
Definition room.h:753
uint8_t floor1_graphics_
Definition room.h:1080
DungeonState * GetDungeonState()
Definition room.h:993
const LayerMergeType & layer_merging() const
Definition room.h:892
void ClearBlocksDirty()
Definition room.h:378
auto blocks() const
Definition room.h:957
void MarkWaterFillDirty()
Definition room.h:583
void SetLayerMerging(LayerMergeType merging)
Definition room.h:768
void SetPitsTargetLayer(uint8_t layer)
Definition room.h:810
void LoadObjects()
Definition room.cc:1626
void ClearTorchesDirty()
Definition room.h:375
void LoadPotItems()
Definition room.cc:4100
void MarkObjectStreamDirty()
Definition room.h:414
void ClearSpritesDirty()
Definition room.h:258
bool blocks_dirty() const
Definition room.h:376
bool GetWaterFillTile(int x, int y) const
Definition room.h:532
uint8_t blockset_
Definition room.h:1068
EffectKey effect() const
Definition room.h:888
void SetSpriteTileset(uint8_t tileset)
Definition room.h:786
void SetStair1Target(uint8_t target)
Definition room.h:846
bool pot_items_loaded_
Definition room.h:1043
destination stair3_
Definition room.h:1106
void SetBg2(background2 bg2)
Definition room.h:657
std::vector< chest_data > & GetChests()
Definition room.h:262
static constexpr uint8_t kObjectHeaderLayoutDirty
Definition room.h:1029
bool torches_dirty() const
Definition room.h:373
void EnsureObjectsLoaded()
Definition room.cc:821
void MarkHeaderDirty()
Definition room.h:586
bool AreObjectsLoaded() const
Definition room.h:874
void SetSpriteset(uint8_t ss)
Definition room.h:690
uint8_t floor1() const
Definition room.h:927
void SetTileObjects(const std::vector< RoomObject > &objects)
Definition room.h:648
void MarkCompositeDirty()
Mark composite bitmap as needing regeneration.
Definition room.h:990
int ResolveDungeonPaletteId() const
Definition room.cc:727
std::unique_ptr< DungeonState > dungeon_state_
Definition room.h:1115
void LoadAnimatedGraphics()
Definition room.cc:1556
std::vector< uint8_t > EncodeSprites() const
Definition room.cc:1886
void SetCollisionTile(int x, int y, uint8_t tile)
Definition room.h:515
std::vector< chest_data > chests_in_room_
Definition room.h:1091
void SetBlockset(uint8_t bs)
Definition room.h:682
uint8_t spriteset_
Definition room.h:1071
LayerMergeType layer_merging_
Definition room.h:1096
SaveDirtySnapshot CaptureSaveDirtySnapshot() const
Definition room.h:600
background2 bg2() const
Definition room.h:887
bool water_fill_dirty() const
Definition room.h:581
bool chests_loaded_
Definition room.h:1042
void EnsurePotItemsLoaded()
Definition room.cc:835
uint8_t staircase_plane(int index) const
Definition room.h:893
bool has_composite_signature_
Definition room.h:1034
void MarkCustomCollisionDirty()
Definition room.h:525
const RoomObject & GetTileObject(size_t index) const
Definition room.h:470
bool AreTorchesLoaded() const
Definition room.h:878
uint8_t cached_spriteset_
Definition room.h:1052
std::array< uint8_t, 0x10000 > current_gfx16_
Definition room.h:999
std::vector< staircase > z3_staircases_
Definition room.h:1090
uint8_t render_entrance_blockset() const
Definition room.h:904
std::vector< PotItem > pot_items_
Definition room.h:1093
bool blocks_loaded_
Definition room.h:1045
void LoadSprites()
Definition room.cc:2494
bool AreBlocksLoaded() const
Definition room.h:884
TagKey cached_tag1_
Definition room.h:1058
destination stair1_
Definition room.h:1104
int water_fill_tile_count_
Definition room.h:1114
bool AreSpritesLoaded() const
Definition room.h:875
uint8_t background_tileset_
Definition room.h:1077
void SetStair3Target(uint8_t target)
Definition room.h:858
DirtyState dirty_state_
Definition room.h:1035
void HandleSpecialObjects(short oid, uint8_t posX, uint8_t posY, int &nbr_of_staircase)
Definition room.cc:2457
void SetStair4TargetLayer(uint8_t layer)
Definition room.h:834
absl::Status AddObject(const RoomObject &object)
Definition room.cc:2381
absl::StatusOr< size_t > FindObjectAt(int x, int y, int layer) const
Definition room.cc:2425
void RemoveTileObject(size_t index)
Definition room.h:460
void SetPalette(uint8_t pal)
Definition room.h:675
uint8_t layout_id() const
Definition room.h:913
bool has_custom_collision() const
Definition room.h:501
const std::vector< PotItem > & GetPotItems() const
Definition room.h:367
void SetRom(Rom *rom)
Definition room.h:962
uint8_t water_fill_sram_bit_mask() const
Definition room.h:571
void RemoveDoor(size_t index)
Definition room.h:358
void SetStair2TargetLayer(uint8_t layer)
Definition room.h:822
Room(const Room &)=delete
const auto & bg2_buffer() const
Definition room.h:979
void RenderObjectsToBackground()
Definition room.cc:1310
CollisionKey collision_
Definition room.h:1097
bool AreChestsLoaded() const
Definition room.h:876
void SetGameData(GameData *data)
Definition room.h:964
auto & object_bg1_buffer()
Definition room.h:980
auto & bg2_buffer()
Definition room.h:977
void SetLayer2Behavior(uint8_t behavior)
Definition room.h:792
void SetWaterFillTile(int x, int y, bool filled)
Definition room.h:538
void SetMessageId(uint16_t mid)
Definition room.h:745
int id() const
Definition room.h:900
zelda3_bg2_effect
Background layer 2 effects.
Definition zelda.h:369
absl::Status SaveAllChests(Rom *rom, absl::Span< const Room > rooms)
Definition room.cc:3855
constexpr DoorDirection DoorDirectionFromRaw(uint8_t raw_dir)
Convert raw direction byte to DoorDirection enum.
Definition door_types.h:277
const std::string RoomTag[65]
Definition room.cc:145
constexpr DoorDimensions GetDoorDimensions(DoorDirection dir)
Get door dimensions based on direction.
Definition door_types.h:235
DoorType
Door types from ALTTP.
Definition door_types.h:33
Room LoadRoomHeaderFromRom(Rom *rom, int room_id)
Definition room.cc:546
absl::StatusOr< ChestSavePlan > BuildChestSavePlan(const Rom *rom, int room_count, const std::function< const Room *(int)> &room_lookup)
Definition room.cc:3758
int FindMaxUsedSpriteAddress(Rom *rom)
Definition room.cc:1924
@ Ganon_Room
Definition room.h:103
@ Moving_Floor
Definition room.h:98
@ Effect_Nothing
Definition room.h:96
@ Red_Flashes
Definition room.h:101
@ Moving_Water
Definition room.h:99
@ Torch_Show_Floor
Definition room.h:102
absl::Status RelocateSpriteData(Rom *rom, int room_id, const std::vector< uint8_t > &encoded_bytes)
Definition room.cc:1964
absl::Status SaveAllPotItems(Rom *rom, absl::Span< const Room > rooms)
Definition room.cc:3980
RoomSize CalculateRoomSize(Rom *rom, int room_id)
Definition room.cc:496
@ Kill_boss_Again
Definition room.h:186
@ Secret_Wall_Right
Definition room.h:151
@ Kill_Enemy_to_clear_level
Definition room.h:160
@ NE_Kill_Enemy_to_Open
Definition room.h:125
@ S_Kill_Enemy_for_Chest
Definition room.h:171
@ N_Push_Block_to_Open
Definition room.h:140
@ E_Kill_Enemy_to_Open
Definition room.h:129
@ Light_Torches_to_Open
Definition room.h:174
@ N_Kill_Enemy_to_Open
Definition room.h:130
@ W_Kill_Enemy_for_Chest
Definition room.h:168
@ Water_Twin
Definition room.h:150
@ N_Kill_Enemy_for_Chest
Definition room.h:170
@ Clear_Level_to_Open
Definition room.h:144
@ Push_Block_to_Open
Definition room.h:142
@ E_Kill_Enemy_for_Chest
Definition room.h:169
@ Secret_Wall_Left
Definition room.h:152
@ NE_Push_Block_to_Open
Definition room.h:135
@ Open_Chest_for_Holes_8
Definition room.h:182
@ S_Kill_Enemy_to_Open
Definition room.h:131
@ S_Push_Block_to_Open
Definition room.h:141
@ Trigger_activated_Chest
Definition room.h:162
@ SW_Kill_Enemy_for_Chest
Definition room.h:166
@ SE_Kill_Enemy_for_Chest
Definition room.h:167
@ Pull_lever_to_Bomb_Wall
Definition room.h:163
@ Pull_Switch_to_bomb_Wall
Definition room.h:155
@ Agahnim_Room
Definition room.h:179
@ Water_Gate
Definition room.h:149
@ SE_Kill_Enemy_to_Move_Block
Definition room.h:161
@ NE_Kill_Enemy_for_Chest
Definition room.h:165
@ SE_Push_Block_to_Open
Definition room.h:137
@ Pull_Lever_to_Open
Definition room.h:143
@ W_Push_Block_to_Open
Definition room.h:138
@ E_Push_Block_to_Open
Definition room.h:139
@ Kill_to_open_Ganon_Door
Definition room.h:184
@ SW_Push_Block_to_Open
Definition room.h:136
@ Turn_on_Water
Definition room.h:148
@ W_Kill_Enemy_to_Open
Definition room.h:128
@ Open_Chest_Activate_Holes_0
Definition room.h:157
@ Clear_Room_for_Chest
Definition room.h:173
@ Clear_Room_to_Open
Definition room.h:133
@ NW_Push_Block_to_Open
Definition room.h:134
@ Switch_Open_Door_Toggle
Definition room.h:146
@ SW_Kill_Enemy_to_Open
Definition room.h:126
@ Clear_Quadrant_for_Chest
Definition room.h:172
@ NW_Kill_Enemy_to_Open
Definition room.h:124
@ Switch_Open_Door_Hold
Definition room.h:145
@ SE_Kill_Enemy_to_Open
Definition room.h:127
@ Turn_off_Water
Definition room.h:147
@ Clear_Quadrant_to_Open
Definition room.h:132
@ Push_Block_for_Chest
Definition room.h:183
@ NW_Kill_Enemy_for_Chest
Definition room.h:164
@ Light_Torches_to_get_Chest
Definition room.h:185
void LoadDungeonRenderPaletteToCgram(std::span< uint16_t > cgram, const gfx::SnesPalette &dungeon_palette, const gfx::SnesPalette *hud_palette)
Definition room.cc:121
absl::StatusOr< std::vector< std::pair< uint32_t, uint32_t > > > GetChestTableWriteRanges(const Rom *rom)
Definition room.cc:3434
absl::Status SaveAllTorches(Rom *rom, absl::Span< const Room > rooms)
Definition room.cc:2911
std::vector< SDL_Color > BuildDungeonRenderPalette(const gfx::SnesPalette &dungeon_palette, const gfx::SnesPalette *hud_palette)
Definition room.cc:102
constexpr std::string_view GetDoorDirectionName(DoorDirection dir)
Get human-readable name for door direction.
Definition door_types.h:204
absl::Status SaveAllPits(Rom *rom)
Definition room.cc:2925
absl::Status SaveAllBlocks(Rom *rom)
Definition room.cc:3069
absl::StatusOr< std::vector< std::pair< uint32_t, uint32_t > > > GetDirtyChestWriteRanges(const Rom *rom, int room_count, const std::function< const Room *(int)> &room_lookup)
Definition room.cc:3765
Room LoadRoomFromRom(Rom *rom, int room_id)
Definition room.cc:521
constexpr DoorType DoorTypeFromRaw(uint8_t raw_type)
Convert raw type byte to DoorType enum.
Definition door_types.h:269
constexpr std::array< std::string_view, 297 > kRoomNames
Definition room.h:1266
constexpr std::string_view GetDoorTypeName(DoorType type)
Get human-readable name for door type.
Definition door_types.h:110
absl::Status ApplyChestSavePlan(Rom *rom, const ChestSavePlan &plan, const std::function< const Room *(int)> &room_lookup)
Definition room.cc:3772
const std::string RoomEffect[8]
Definition room.cc:135
DoorDirection
Door direction on room walls.
Definition door_types.h:18
absl::Status SaveAllCollision(Rom *rom, absl::Span< Room > rooms)
Definition room.cc:3422
constexpr DoorDimensions GetEditorDoorDimensions(DoorDirection dir, DoorType type)
Get editor interaction dimensions for a door.
Definition door_types.h:257
@ Moving_Water_Collision
Definition room.h:92
@ One_Collision
Definition room.h:88
@ Moving_Floor_Collision
Definition room.h:91
@ Both_With_Scroll
Definition room.h:90
Room transition destination.
Definition zelda.h:448
uint8_t target_layer
Definition zelda.h:451
uint8_t target
Definition zelda.h:450
bool operator==(const ChestDirtyRoomState &) const =default
std::vector< uint8_t > encoded_chests
Definition room.h:1197
std::vector< uint8_t > original_capacity_bytes
Definition room.h:1212
bool operator==(const ChestSavePlan &) const =default
std::vector< std::pair< uint32_t, uint32_t > > write_ranges() const
Definition room.h:1218
uint16_t original_byte_length
Definition room.h:1211
std::vector< ChestWriteRun > writes
Definition room.h:1213
std::array< uint8_t, 3 > pointer_operand
Definition room.h:1210
std::vector< ChestDirtyRoomState > dirty_rooms
Definition room.h:1214
std::vector< uint8_t > expected_bytes
Definition room.h:1185
std::vector< uint8_t > replacement_bytes
Definition room.h:1186
bool operator==(const ChestWriteRun &) const =default
uint32_t end() const
Definition room.h:1190
std::array< uint8_t, 64 *64 > tiles
Door dimensions in tiles (8x8 pixel tiles)
Definition door_types.h:221
zelda3_version version
Definition game_data.h:80
LayerMergeType(uint8_t id, std::string name, bool see, bool top, bool trans)
Definition room.h:55
bool operator==(const LayerMergeType &) const =default
int GetPixelX() const
Definition room.h:114
int GetPixelY() const
Definition room.h:115
int GetTileY() const
Definition room.h:119
int GetTileX() const
Definition room.h:118
uint16_t position
Definition room.h:109
int64_t room_size_pointer
Definition room.h:1125
Represents a door in a dungeon room.
Definition room.h:277
std::tuple< int, int, int, int > GetEditorBounds() const
Get editor interaction bounds (x, y, width, height in pixels)
Definition room.h:311
std::tuple< int, int, int, int > GetBounds() const
Get bounding rectangle (x, y, width, height in pixels)
Definition room.h:306
std::string_view GetTypeName() const
Get human-readable type name.
Definition room.h:317
uint8_t byte1
Original ROM byte 1 (position data)
Definition room.h:282
DoorDimensions GetDimensions() const
Get door dimensions in tiles.
Definition room.h:296
DoorType type
Door type (determines appearance/behavior)
Definition room.h:279
static Door FromRomBytes(uint8_t b1, uint8_t b2)
Definition room.h:335
std::pair< uint8_t, uint8_t > EncodeBytes() const
Encode door data for ROM storage.
Definition room.h:327
DoorDirection direction
Which wall the door is on.
Definition room.h:280
DoorDimensions GetEditorDimensions() const
Get editor interaction dimensions in tiles.
Definition room.h:301
uint8_t position
Encoded position (5-bit, 0-31)
Definition room.h:278
std::string_view GetDirectionName() const
Get human-readable direction name.
Definition room.h:322
std::pair< int, int > GetPixelCoords() const
Get pixel coordinates for this door.
Definition room.h:291
uint8_t byte2
Original ROM byte 2 (type + direction)
Definition room.h:283
std::pair< int, int > GetTileCoords() const
Get tile coordinates for this door.
Definition room.h:286
std::vector< BlockLoadOrder > block_load_orders
Definition room.h:217
std::array< uint8_t, 64 *64 > tiles
Definition room.h:193
ROM data pointers for different game versions.
Definition zelda.h:71
Public YAZE API umbrella header.