yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
overworld_entrance.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ZELDA3_OVERWORLD_ENTRANCE_H
2#define YAZE_APP_ZELDA3_OVERWORLD_ENTRANCE_H
3
4#include <array>
5#include <cstddef>
6#include <cstdint>
7#include <cstdlib>
8#include <optional>
9#include <vector>
10
11#include "absl/status/status.h"
12#include "absl/status/statusor.h"
13#include "core/rom_settings.h"
14#include "rom/rom.h"
15#include "util/macro.h"
16#include "zelda3/common.h"
17
18namespace yaze::zelda3 {
19
20// EXPANDED to 0x78000 to 0x7A000
21constexpr int kEntranceRoomEXP = 0x078000;
22constexpr int kEntranceScrollEdgeEXP = 0x078200;
23constexpr int kEntranceCameraYEXP = 0x078A00;
24constexpr int kEntranceCameraXEXP = 0x078C00;
25constexpr int kEntranceYPositionEXP = 0x078E00;
26constexpr int kEntranceXPositionEXP = 0x079000;
27constexpr int kEntranceCameraYTriggerEXP = 0x079200;
28constexpr int kEntranceCameraXTriggerEXP = 0x079400;
29constexpr int kEntranceBlocksetEXP = 0x079600;
30constexpr int kEntranceFloorEXP = 0x079700;
31constexpr int kEntranceDungeonEXP = 0x079800;
32constexpr int kEntranceDoorEXP = 0x079900;
33constexpr int kEntranceLadderBgEXP = 0x079A00;
34constexpr int kEntranceScrollingEXP = 0x079B00;
35constexpr int kEntranceScrollQuadrantEXP = 0x079C00;
36constexpr int kEntranceExitEXP = 0x079D00;
37constexpr int kEntranceMusicEXP = 0x079F00;
38constexpr int kEntranceExtraEXP = 0x07A000;
39constexpr int kEntranceTotalEXP = 0xFF;
40constexpr int kEntranceTotal = 0x84;
41constexpr int kEntranceLinkSpawn = 0x00;
42constexpr int kEntranceNorthTavern = 0x43;
43constexpr int kEntranceEXP = 0x07F000;
44
45constexpr int kEntranceCameraY = 0x014D45; // 0x14AA9 // 2bytes each room
46constexpr int kEntranceCameraX = 0x014E4F; // 0x14BB3 // 2bytes
47
48constexpr int kNumOverworldEntrances = 129;
49constexpr int kNumOverworldHoles = 0x13;
50
51constexpr int kOverworldEntranceMap = 0xDB96F;
52constexpr int kOverworldEntrancePos = 0xDBA71;
53constexpr int kOverworldEntranceEntranceId = 0xDBB73;
54
55constexpr int kOverworldEntranceMapExpanded = 0x0DB55F;
56constexpr int kOverworldEntrancePosExpanded = 0x0DB35F;
57constexpr int kOverworldEntranceEntranceIdExpanded = 0x0DB75F;
58
59constexpr int kOverworldEntranceExpandedFlagPos = 0x0DB895; // 0xB8
60
66
72
78
84
85// (0x13 entries, 2 bytes each) modified(less 0x400)
86// map16 coordinates for each hole
87constexpr int kOverworldHolePos = 0xDB800;
88
89// (0x13 entries, 2 bytes each) corresponding
90// area numbers for each hole
91constexpr int kOverworldHoleArea = 0xDB826;
92
93//(0x13 entries, 1 byte each) corresponding entrance numbers
94constexpr int kOverworldHoleEntrance = 0xDB84C;
95
96// OWEntrances Expansion
97
98// Instructions for editors
99// if byte at (PC) address 0xDB895 == B8 then it is vanilla
100// Load normal overworld entrances data
101// Otherwise load from the expanded space
102// When saving just save in expanded space 256 values for each
103// (PC Addresses) - you can find snes address at the orgs below
104// 0x0DB35F = (short) Map16 tile address (mapPos in ZS)
105// 0x0DB55F = (short) Screen ID (MapID in ZS)
106// 0x0DB75F = (byte) Entrance leading to (EntranceID in ZS)
107
108// *Important* the Screen ID now also require bit 0x8000 (15) being set to tell
109// entrance is a hole
111 public:
112 uint16_t map_pos_ = 0;
113 uint8_t entrance_id_ = 0;
114 bool is_hole_ = false;
115 bool deleted = false;
116
118 OverworldEntrance(int x, int y, uint8_t entrance_id, short map_id,
119 uint16_t map_pos, bool hole)
120 : map_pos_(map_pos), entrance_id_(entrance_id), is_hole_(hole) {
121 x_ = x;
122 y_ = y;
123 map_id_ = map_id; // Store original map_id (no corruption)
124 entity_id_ = entrance_id;
126
127 // Use normalized map_id for coordinate calculations
128 uint8_t normalized_map_id = map_id % 0x40;
129 int mapX = normalized_map_id % 8;
130 int mapY = normalized_map_id / 8;
131
132 // Use base game_x_/game_y_ instead of duplicated area_x_/area_y_
133 game_x_ = static_cast<int>((std::abs(x - (mapX * 512)) / 16));
134 game_y_ = static_cast<int>((std::abs(y - (mapY * 512)) / 16));
135 }
136
137 void UpdateMapProperties(uint16_t map_id,
138 const void* context = nullptr) override {
139 (void)context; // Not used by entrances currently
140 map_id_ = map_id;
141
142 // Use normalized map_id for calculations (don't corrupt stored value)
143 uint8_t normalized_map_id = map_id % 0x40;
144 int mapX = normalized_map_id % 8;
145 int mapY = normalized_map_id / 8;
146
147 // Update game coordinates from world coordinates
148 game_x_ = static_cast<int>((std::abs(x_ - (mapX * 512)) / 16));
149 game_y_ = static_cast<int>((std::abs(y_ - (mapY * 512)) / 16));
150
151 // Calculate map position encoding for ROM save
152 map_pos_ = (uint16_t)((((game_y_) << 6) | (game_x_ & 0x3F)) << 1);
153 }
154
155 // In expanded ROMs these legacy records describe overlapping, inactive
156 // bytes. Keep a load snapshot so Save can reject edits instead of dropping
157 // them, even after a previous expanded Save changed those ROM bytes.
158 void RememberHoleSourceState(size_t row) {
160 hole_source_row_ = row;
161 }
162 bool HasUnchangedHoleSourceState(size_t row) const {
163 return hole_source_state_ && hole_source_row_ == row &&
165 }
166
167 private:
168 std::array<int, 9> HoleState() const {
169 return {map_id_, map_pos_, entrance_id_, x_, y_,
171 }
172 std::optional<std::array<int, 9>> hole_source_state_;
174};
175constexpr int kEntranceTileTypePtrLow = 0xDB8BF;
176constexpr int kEntranceTileTypePtrHigh = 0xDB917;
177constexpr int kNumEntranceTileTypes = 0x2C;
178
180 std::array<uint16_t, kNumEntranceTileTypes> low;
181 std::array<uint16_t, kNumEntranceTileTypes> high;
182};
183
184absl::StatusOr<std::vector<OverworldEntrance>> LoadEntrances(Rom* rom);
185// Background readers supply their captured address settings explicitly.
186absl::StatusOr<std::vector<OverworldEntrance>> LoadEntrances(
187 Rom* rom, const core::RomAddressOverrides& addresses);
188absl::StatusOr<std::vector<OverworldEntrance>> LoadHoles(Rom* rom);
189
190absl::Status SaveEntrances(Rom* rom,
191 const std::vector<OverworldEntrance>& entrances,
192 bool expanded_entrances);
193absl::Status SaveHoles(Rom* rom, const std::vector<OverworldEntrance>& holes);
194
195inline absl::StatusOr<OverworldEntranceTileTypes> LoadEntranceTileTypes(
196 Rom* rom) {
198 for (int i = 0; i < kNumEntranceTileTypes; i++) {
199 ASSIGN_OR_RETURN(auto value_low,
201 tiletypes.low[i] = value_low;
202 ASSIGN_OR_RETURN(auto value_high,
204 tiletypes.high[i] = value_high;
205 }
206 return tiletypes;
207}
208
209} // namespace yaze::zelda3
210
211#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:52
absl::StatusOr< uint16_t > ReadWord(int offset) const
Definition rom.cc:1044
static RomSettings & Get()
uint32_t GetAddressOr(const std::string &key, uint32_t default_value) const
Base class for all overworld and dungeon entities.
Definition common.h:31
enum yaze::zelda3::GameEntity::EntityType entity_type_
std::array< int, 9 > HoleState() const
std::optional< std::array< int, 9 > > hole_source_state_
OverworldEntrance(int x, int y, uint8_t entrance_id, short map_id, uint16_t map_pos, bool hole)
bool HasUnchangedHoleSourceState(size_t row) const
void UpdateMapProperties(uint16_t map_id, const void *context=nullptr) override
Update entity properties based on map position.
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:62
constexpr char kOverworldEntrancePosExpanded[]
constexpr char kOverworldEntranceMapExpanded[]
constexpr char kOverworldEntranceFlagExpanded[]
constexpr char kOverworldEntranceIdExpanded[]
Zelda 3 specific classes and functions.
absl::Status SaveEntrances(Rom *rom, const std::vector< OverworldEntrance > &entrances, bool expanded_entrances)
constexpr int kOverworldHoleArea
constexpr int kOverworldEntrancePos
constexpr int kOverworldHoleEntrance
constexpr int kEntranceFloorEXP
constexpr int kEntranceCameraXTriggerEXP
constexpr int kEntranceTotalEXP
absl::StatusOr< std::vector< OverworldEntrance > > LoadEntrances(Rom *rom)
constexpr int kEntranceScrollEdgeEXP
constexpr int kOverworldEntranceEntranceIdExpanded
constexpr int kEntranceCameraY
constexpr int kNumOverworldHoles
constexpr int kOverworldEntranceEntranceId
constexpr int kOverworldHolePos
constexpr int kOverworldEntranceMap
constexpr int kEntranceLadderBgEXP
constexpr int kEntranceXPositionEXP
constexpr int kNumEntranceTileTypes
constexpr int kEntranceNorthTavern
constexpr int kEntranceCameraYEXP
constexpr int kEntranceRoomEXP
constexpr int kEntranceDungeonEXP
constexpr int kEntranceYPositionEXP
constexpr int kEntranceCameraX
constexpr int kOverworldEntrancePosExpanded
constexpr int kEntranceBlocksetEXP
int GetOverworldEntrancePosExpanded()
constexpr int kEntranceCameraYTriggerEXP
constexpr int kEntranceExitEXP
constexpr int kEntranceTileTypePtrHigh
int GetOverworldEntranceIdExpanded()
constexpr int kOverworldEntranceMapExpanded
int GetOverworldEntranceFlagExpanded()
constexpr int kEntranceTileTypePtrLow
absl::Status SaveHoles(Rom *rom, const std::vector< OverworldEntrance > &holes)
absl::StatusOr< OverworldEntranceTileTypes > LoadEntranceTileTypes(Rom *rom)
absl::StatusOr< std::vector< OverworldEntrance > > LoadHoles(Rom *rom)
constexpr int kEntranceScrollQuadrantEXP
constexpr int kOverworldEntranceExpandedFlagPos
constexpr int kEntranceEXP
constexpr int kEntranceTotal
int GetOverworldEntranceMapExpanded()
constexpr int kEntranceDoorEXP
constexpr int kNumOverworldEntrances
constexpr int kEntranceExtraEXP
constexpr int kEntranceScrollingEXP
constexpr int kEntranceMusicEXP
constexpr int kEntranceCameraXEXP
constexpr int kEntranceLinkSpawn
std::array< uint16_t, kNumEntranceTileTypes > high
std::array< uint16_t, kNumEntranceTileTypes > low