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