1#ifndef YAZE_ZELDA3_DUNGEON_DUNGEON_SPAWN_POINT_H
2#define YAZE_ZELDA3_DUNGEON_DUNGEON_SPAWN_POINT_H
10#include "absl/status/status.h"
11#include "absl/status/statusor.h"
12#include "absl/strings/str_format.h"
77inline constexpr std::array<std::pair<uint32_t, uint32_t>, 17>
104 std::vector<DungeonSpawnPointWriteRange> ranges;
107 const uint32_t begin =
108 table_pc +
static_cast<uint32_t
>(spawn_id) * record_width;
109 ranges.emplace_back(begin, begin + record_width);
114class DungeonSpawnPoint;
117 const DungeonSpawnPoint& spawn,
126 return absl::FailedPreconditionError(
"ROM not loaded");
129 return absl::OutOfRangeError(
130 absl::StrFormat(
"Dungeon spawn point ID %d is outside [0, %d)",
134 if (end > rom.
size()) {
135 return absl::FailedPreconditionError(absl::StrFormat(
136 "Dungeon spawn point 0x%02X read range 0x%06X-0x%06X exceeds "
138 spawn_id, begin, end,
static_cast<uint32_t
>(rom.
size())));
142 const auto read_word = [&rom](uint32_t pc) {
143 return static_cast<uint16_t
>(
144 rom.
data()[pc] | (
static_cast<uint16_t
>(rom.
data()[pc + 1]) << 8));
211 return absl::OutOfRangeError(
212 absl::StrFormat(
"Dungeon spawn point ID %d is outside [0, %d)",
216 return absl::InvalidArgumentError(absl::StrFormat(
217 "Dungeon spawn point model ID %d does not match requested save ID %d",
221 return absl::OutOfRangeError(absl::StrFormat(
222 "Dungeon spawn point 0x%02X room ID 0x%04X exceeds the 9-bit "
227 return absl::OutOfRangeError(absl::StrFormat(
228 "Dungeon spawn point 0x%02X entrance ID 0x%04X is outside [0, "
233 if (end > rom.
size()) {
234 return absl::FailedPreconditionError(absl::StrFormat(
235 "Dungeon spawn point 0x%02X write range 0x%06X-0x%06X exceeds "
237 spawn_id, begin, end,
static_cast<uint32_t
>(rom.
size())));
240 return absl::OkStatus();
244 if (rom ==
nullptr || !rom->
is_loaded()) {
245 return absl::FailedPreconditionError(
"ROM not loaded");
283 return absl::OkStatus();
286inline std::vector<DungeonSpawnPointWriteRange>
288 const std::array<DungeonSpawnPoint, kNumDungeonSpawnPoints>& spawn_points) {
289 std::vector<DungeonSpawnPointWriteRange> ranges;
291 if (!spawn_points[spawn_id].dirty()) {
295 ranges.insert(ranges.end(), spawn_ranges.begin(), spawn_ranges.end());
302 const std::array<DungeonSpawnPoint, kNumDungeonSpawnPoints>& spawn_points,
303 bool dirty_only =
true) {
305 const auto& spawn = spawn_points[spawn_id];
306 if (dirty_only && !spawn.dirty()) {
311 return absl::OkStatus();
316 std::array<DungeonSpawnPoint, kNumDungeonSpawnPoints>& spawn_points,
317 bool dirty_only =
true) {
318 if (rom ==
nullptr || !rom->
is_loaded()) {
319 return absl::FailedPreconditionError(
"ROM not loaded");
327 auto& spawn = spawn_points[spawn_id];
328 if (dirty_only && !spawn.dirty()) {
333 return absl::OkStatus();
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
absl::Status WriteByte(int addr, uint8_t value)
absl::Status WriteShort(int addr, uint16_t value)
uint8_t camera_scroll_controller
uint16_t camera_trigger_x
std::array< uint8_t, 8 > camera_scroll_boundaries
DungeonSpawnPoint()=default
uint16_t horizontal_scroll
uint16_t camera_trigger_y
uint16_t overworld_door_tilemap
absl::Status Save(Rom *rom, int spawn_id)
static absl::StatusOr< DungeonSpawnPoint > Load(const Rom &rom, int spawn_id)
Zelda 3 specific classes and functions.
constexpr uint32_t kDungeonSpawnCameraScrollBoundaries
constexpr uint32_t kDungeonSpawnMainGfx
constexpr uint32_t kDungeonSpawnVerticalScroll
constexpr int kStartingEntranceLadderBG
constexpr uint32_t kDungeonSpawnSong
constexpr int kStartingEntranceXScroll
constexpr std::array< std::pair< uint32_t, uint32_t >, 17 > kDungeonSpawnPointTableLayout
constexpr int kStartingEntranceentrance
constexpr uint32_t kDungeonSpawnRoom
std::pair< uint32_t, uint32_t > DungeonSpawnPointWriteRange
constexpr uint32_t kDungeonSpawnLayer
constexpr int kStartingEntranceScrollQuadrant
constexpr int kStartingEntrancescrolling
constexpr int kNumRegularDungeonEntrances
constexpr uint32_t kDungeonSpawnHorizontalScroll
absl::Status SaveAllDungeonSpawnPoints(Rom *rom, std::array< DungeonSpawnPoint, kNumDungeonSpawnPoints > &spawn_points, bool dirty_only=true)
constexpr int kStartingEntranceBlockset
constexpr uint32_t kDungeonSpawnCameraScrollController
constexpr uint32_t kDungeonSpawnCameraTriggerY
constexpr uint32_t kDungeonSpawnDungeonId
constexpr int kStartingEntrancemusic
constexpr int kStartingEntranceCameraYTrigger
constexpr uint32_t kDungeonSpawnQuadrant
constexpr int kStartingEntranceFloor
constexpr int kStartingEntranceYPosition
constexpr int kStartingEntranceXPosition
std::vector< DungeonSpawnPointWriteRange > DungeonSpawnPointWriteRanges(int spawn_id)
constexpr uint16_t kDungeonSpawnRoomIdMask
constexpr uint32_t kDungeonSpawnXCoordinate
constexpr int kStartingEntranceCameraXTrigger
constexpr int kStartingEntranceroom
constexpr uint32_t kDungeonSpawnCameraTriggerX
constexpr int kStartingEntranceScrollEdge
absl::Status ValidateDungeonSpawnPointForSave(const Rom &rom, const DungeonSpawnPoint &spawn, int spawn_id)
constexpr int kNumDungeonSpawnPoints
constexpr int kStartingEntranceDoor
constexpr uint32_t kDungeonSpawnOverworldDoorTilemap
constexpr int kStartingEntranceDungeon
absl::Status ValidateDungeonSpawnPointsForSave(const Rom &rom, const std::array< DungeonSpawnPoint, kNumDungeonSpawnPoints > &spawn_points, bool dirty_only=true)
constexpr uint32_t kDungeonSpawnYCoordinate
constexpr int kStartingEntranceexit
constexpr uint32_t kDungeonSpawnEntranceId
constexpr int kNumDungeonEntranceSlots
constexpr uint32_t kDungeonSpawnFloor
constexpr int kStartingEntranceYScroll
std::vector< DungeonSpawnPointWriteRange > CollectDirtyDungeonSpawnPointWriteRanges(const std::array< DungeonSpawnPoint, kNumDungeonSpawnPoints > &spawn_points)
#define RETURN_IF_ERROR(expr)