yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
dungeon_rom_addresses.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ZELDA3_DUNGEON_ROM_ADDRESSES_H
2#define YAZE_APP_ZELDA3_DUNGEON_ROM_ADDRESSES_H
3
4#include <array> // Added for std::array
5#include <cstddef>
6#include <cstdint>
7
8namespace yaze {
9namespace zelda3 {
10
11// ============================================================================
12// Dungeon ROM Address Constants
13// ============================================================================
14// This file contains all ROM addresses for dungeon-related data in ALTTP.
15// Organized by category for readability and maintainability.
16
17// === Room Data Pointers ===
18constexpr int kRoomObjectLayoutPointer = 0x882D; // Layout pointer table
19constexpr int kRoomObjectPointer = 0x874C; // Object data pointer (Long)
20constexpr int kRoomHeaderPointer = 0xB5DD; // Room header pointer (LONG)
21constexpr int kRoomHeaderPointerBank = 0xB5E7; // Room header bank byte
22
24 int begin;
25 int end;
26};
27
28// Half-open ZScream room-object sections. In-place saves may use the containing
29// section's end as a physical boundary when there is no later room pointer.
30constexpr std::array<DungeonObjectDataRegion, 5> kDungeonObjectDataRegions = {{
31 {0x050008, 0x053730},
32 {0x0F878A, 0x100000},
33 {0x01EB90, 0x020000},
34 {0x138000, 0x140000},
35 {0x148000, 0x150000},
36}};
37
38constexpr int GetDungeonObjectDataRegionEnd(int pc_address) {
39 for (const auto& region : kDungeonObjectDataRegions) {
40 if (pc_address >= region.begin && pc_address < region.end) {
41 return region.end;
42 }
43 }
44 return -1;
45}
46
47// === Palette Data ===
48constexpr int kDungeonsMainBgPalettePointers = 0xDEC4B; // JP Same
49constexpr int kDungeonsPalettes = 0xDD734; // Dungeon palette data
50
51// === Item & Sprite Data ===
52constexpr int kRoomItemsPointers = 0xDB69; // JP 0xDB67
53constexpr int kRoomItemsDataEnd = 0xE6B2; // Exclusive PC boundary
54constexpr int kRoomsSpritePointer = 0x4C298; // JP Same (2-byte bank 09D62E)
55constexpr int kSpriteBlocksetPointer = 0x5B57; // Sprite graphics pointer
56// Dungeon IDs index the 144-entry graphics table after its first 64 groups.
57constexpr int kMaxDungeonSpriteset = 0x4F;
58
59// === Graphics Data ===
60constexpr int kGfxGroupsPointer = 0x6237; // Graphics group table
61constexpr int kTileAddress = 0x001B52; // Main tile graphics
62constexpr int kTileAddressFloor = 0x001B5A; // Floor tile graphics
63
64// === Block Data ===
65constexpr int kBlocksLength = 0x8896; // Word value
66constexpr int kBlocksPointer1 = 0x15AFA; // Block data pointer 1
67constexpr int kBlocksPointer2 = 0x15B01; // Block data pointer 2
68constexpr int kBlocksPointer3 = 0x15B08; // Block data pointer 3
69constexpr int kBlocksPointer4 = 0x15B0F; // Block data pointer 4
70
71// === Chests ===
72// The value at kChestsLengthPointer is a byte length, not a record count.
73// Vanilla reserves 0x01F8 bytes: 168 records at 3 bytes per record.
74constexpr int kChestsLengthPointer = 0xEBF6;
75constexpr int kChestsDataPointer1 = 0xEBFB; // Chest data start
76constexpr int kChestTableRecordSize = 3;
77constexpr int kChestTableCapacityRecords = 168;
80
81// === Torches ===
82constexpr int kTorchData = 0x2736A; // JP 0x2704A
83constexpr int kTorchesLengthPointer = 0x88C1; // Torch count pointer
84
85// === RoomsWithPitDamage gating table (legacy "pits" name) ===
86//
87// These constants name two operand slots inside the runtime routine
88// `DetermineConsequencesOfFalling` at bank_07.asm:4193, NOT
89// pit-position data fields. The table they describe is
90// `RoomsWithPitDamage` (SNES $00:990C, PC 0x0190C) — a 57-entry
91// list of room IDs in which falling deals damage instead of
92// transitioning Link to a different floor. Per-pit positions and the
93// per-room pit destination (`Room::pits_`) are stored elsewhere
94// (room collision/layout for positions, room header for destination)
95// and are unrelated to these two symbols.
96//
97// Layout:
98// PC 0x394A5 = 0xA2 (LDX.w opcode)
99// PC 0x394A6..7 = LDX.w immediate; low byte is the **maximum X
100// offset** the CMP loop tests (NOT a byte count).
101// Entries = (kPitCount / 2) + 1 = 57 in vanilla.
102// PC 0x394AA = 0xDF (CMP.l ,X opcode)
103// PC 0x394AB..D = 3-byte SNES long-address operand pointing at
104// the table base.
105constexpr int kPitPointer = 0x394AB; // CMP.l ,X long-address operand
106constexpr int kPitCount = 0x394A6; // LDX.w immediate (max X offset)
107
108// === Doors ===
109constexpr int kDoorPointers = 0xF83C0; // Door data table
110constexpr int kDoorGfxUp = 0x4D9E; // Door graphics (up)
111constexpr int kDoorGfxDown = 0x4E06; // Door graphics (down)
112constexpr int kDoorGfxCaveExitDown = 0x4E06; // Cave exit door
113constexpr int kDoorGfxLeft = 0x4E66; // Door graphics (left)
114constexpr int kDoorGfxRight = 0x4EC6; // Door graphics (right)
115constexpr int kDoorPosUp = 0x197E; // Door position (up)
116constexpr int kDoorPosDown = 0x1996; // Door position (down)
117constexpr int kDoorPosLeft = 0x19AE; // Door position (left)
118constexpr int kDoorPosRight = 0x19C6; // Door position (right)
119
120// === Sprites ===
121constexpr int kSpritesData = 0x4D8B0; // Sprite data start
122constexpr int kSpritesDataEmptyRoom = 0x4D8AE; // Empty room sprite marker
123constexpr int kSpritesEndData = 0x4EC9E; // Last valid data byte
125 kSpritesEndData + 1; // Half-open sprite data boundary
127 0x090000; // Dungeon sprite pointer table
128
129// === Messages ===
130constexpr int kMessagesIdDungeon = 0x3F61D; // Dungeon message IDs
131
132// === Custom Collision (ZScream expanded region) ===
133constexpr int kCustomCollisionRoomPointers = 0x128090; // 296 rooms × 3 bytes
134constexpr int kCustomCollisionDataPosition = 0x128450;
135constexpr int kCustomCollisionDataEnd = 0x130000;
136
137// === Water Fill Zones (Oracle of Secrets) ===
138// Reserve a tail region inside the custom collision bank for editor-authored
139// water fill zone data. This prevents collision writers from ever overwriting
140// the water table.
141//
142// NOTE: This region is intentionally small; the format is compact (room list +
143// offset lists) and should comfortably fit in a few KiB.
144constexpr int kWaterFillTableReservedSize = 0x2000; // 8 KiB
145constexpr int kWaterFillTableStart =
148
149// Soft end of collision data to avoid clobbering the reserved WaterFill table.
151
152// === Room Metadata ===
153constexpr int kNumberOfRooms = 296; // Total dungeon rooms (0x00-0x127)
154
155// Stair objects (special handling)
156constexpr uint16_t kStairsObjects[] = {0x139, 0x138, 0x13B, 0x12E, 0x12D};
157
158// === ROM Region Guardrail Helpers ===
159// These helpers centralize "does this ROM support feature X?" checks so the
160// UI and save pipeline enforce the same boundaries.
161
162constexpr bool HasCustomCollisionPointerTable(std::size_t rom_size) {
163 return static_cast<std::size_t>(kCustomCollisionRoomPointers) +
164 static_cast<std::size_t>(kNumberOfRooms * 3) <=
165 rom_size;
166}
167
168constexpr bool HasCustomCollisionDataRegion(std::size_t rom_size) {
169 return static_cast<std::size_t>(kCustomCollisionDataPosition) < rom_size &&
170 static_cast<std::size_t>(kCustomCollisionDataSoftEnd) <= rom_size;
171}
172
173constexpr bool HasCustomCollisionWriteSupport(std::size_t rom_size) {
174 return HasCustomCollisionPointerTable(rom_size) &&
176}
177
178constexpr bool HasWaterFillReservedRegion(std::size_t rom_size) {
179 return static_cast<std::size_t>(kWaterFillTableEnd) <= rom_size;
180}
181
182// === Layout Pointers (referenced in comments) ===
183// Layout00 ptr: 0x47EF04
184// Layout01 ptr: 0xAFEF04
185// Layout02 ptr: 0xF0EF04
186// Layout03 ptr: 0x4CF004
187// Layout04 ptr: 0xA8F004
188// Layout05 ptr: 0xECF004
189// Layout06 ptr: 0x48F104
190// Layout07 ptr: 0xA4F104
191
192// === Notes ===
193// - Layout arrays are NOT exactly the same as rooms
194// - Object array is terminated by 0xFFFF (no layers)
195// - In normal room, 0xFFFF goes to next layer (layers 0, 1, 2)
196
197// Static pointers for the 8 predefined room layouts
198static const std::array<int, 8> kRoomLayoutPointers = {
199 0x04EF47, 0x04EFAF, 0x04EFF0, 0x04F04C,
200 0x04F0A8, 0x04F0EC, 0x04F148, 0x04F1A4,
201};
202
203// Exclusive end of LayoutData_07; WaterOverlayData starts here (USDASM bank04).
204// The fixed layouts occupy successive spans beginning at the pointers above.
205inline constexpr int kRoomLayoutDataEnd = 0x04F1CD;
206
207} // namespace zelda3
208} // namespace yaze
209
210#endif // YAZE_APP_ZELDA3_DUNGEON_ROM_ADDRESSES_H
constexpr int kBlocksPointer4
constexpr int kSpritesDataEndExclusive
constexpr int kRoomObjectLayoutPointer
constexpr int kDoorPosUp
constexpr int kDoorPointers
constexpr int kWaterFillTableEnd
constexpr int kMaxDungeonSpriteset
constexpr int kDoorGfxDown
constexpr int kSpritesEndData
constexpr int kTorchesLengthPointer
constexpr int kCustomCollisionDataSoftEnd
constexpr int kChestsLengthPointer
constexpr int kWaterFillTableStart
constexpr int kMessagesIdDungeon
constexpr int kRoomLayoutDataEnd
constexpr int kDungeonsMainBgPalettePointers
constexpr int kSpriteBlocksetPointer
constexpr int kPitPointer
constexpr int kSpritesData
constexpr int kRoomItemsDataEnd
constexpr int kDoorPosLeft
constexpr int kTileAddress
constexpr int kWaterFillTableReservedSize
constexpr int kPitCount
constexpr int kRoomsSpritePointer
constexpr int kTileAddressFloor
constexpr int kDoorPosDown
constexpr int GetDungeonObjectDataRegionEnd(int pc_address)
constexpr int kChestsDataPointer1
constexpr int kBlocksLength
constexpr int kBlocksPointer1
constexpr int kChestTableCapacityRecords
constexpr int kCustomCollisionDataEnd
constexpr int kRoomItemsPointers
constexpr int kChestTableRecordSize
constexpr bool HasCustomCollisionPointerTable(std::size_t rom_size)
constexpr int kDoorGfxLeft
constexpr int kDoorGfxCaveExitDown
constexpr int kCustomCollisionDataPosition
constexpr std::array< DungeonObjectDataRegion, 5 > kDungeonObjectDataRegions
constexpr uint16_t kStairsObjects[]
constexpr int kChestTableCapacityBytes
constexpr int kDungeonSpritePointers
constexpr bool HasWaterFillReservedRegion(std::size_t rom_size)
constexpr int kNumberOfRooms
constexpr int kDoorPosRight
constexpr int kRoomHeaderPointer
constexpr bool HasCustomCollisionDataRegion(std::size_t rom_size)
constexpr int kBlocksPointer3
constexpr int kRoomHeaderPointerBank
constexpr int kCustomCollisionRoomPointers
constexpr int kGfxGroupsPointer
constexpr int kDungeonsPalettes
constexpr int kDoorGfxUp
constexpr int kTorchData
constexpr bool HasCustomCollisionWriteSupport(std::size_t rom_size)
constexpr int kDoorGfxRight
constexpr int kSpritesDataEmptyRoom
constexpr int kBlocksPointer2
constexpr int kRoomObjectPointer