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