1#ifndef YAZE_APP_ZELDA3_DUNGEON_ROOM_ENTRANCE_H
2#define YAZE_APP_ZELDA3_DUNGEON_ROOM_ENTRANCE_H
11#include "absl/status/status.h"
12#include "absl/strings/str_format.h"
58 std::vector<DungeonEntranceWriteRange> ranges;
59 ranges.reserve(layout.
tables.size());
60 for (
const auto& [table_pc, record_width] : layout.
tables) {
61 const uint32_t begin =
62 table_pc +
static_cast<uint32_t
>(entrance_id) * record_width;
63 ranges.emplace_back(begin, begin + record_width);
68inline absl::StatusOr<std::vector<DungeonEntranceWriteRange>>
72 return absl::OutOfRangeError(
"Regular dungeon entrance ID is out of range");
80 const RoomEntrance& entrance,
125 if (rom ==
nullptr || !rom->
is_loaded()) {
126 load_status_ = absl::FailedPreconditionError(
"ROM not loaded");
135 if (!loaded_spawn.ok()) {
172 : absl::OutOfRangeError(
173 "Regular dungeon entrance ID is out of range");
180 room_ =
static_cast<short>(
187 (entrance_id * 2) + 1]
193 (entrance_id * 2) + 1]
199 (entrance_id * 2) + 1]
205 (entrance_id * 2) + 1]
237 exit_ =
static_cast<short>(
280 return absl::FailedPreconditionError(
"ROM not loaded");
283 return absl::FailedPreconditionError(absl::StrFormat(
284 "Dungeon spawn point 0x%02X cannot be saved: spawn writes are "
285 "disabled through the legacy RoomEntrance model; use the dedicated "
286 "spawn ROM schema in DungeonSpawnPoint",
296 const auto* layout = &resolved_layout;
322 (uint8_t)(
music_ & 0xFF)));
328 (uint8_t)(
door_ & 0xFF)));
331 (uint8_t)(
floor_ & 0xFF)));
366 return absl::OkStatus();
404inline absl::StatusOr<std::vector<DungeonEntranceWriteRange>>
407 const std::array<RoomEntrance, kNumDungeonEntranceSlots>& entrances) {
409 std::vector<DungeonEntranceWriteRange> ranges;
413 if (!entrance.dirty()) {
416 auto entrance_ranges =
418 ranges.insert(ranges.end(), entrance_ranges.begin(), entrance_ranges.end());
426 return absl::OutOfRangeError(
427 absl::StrFormat(
"Regular dungeon entrance ID %d is outside [0, %d)",
431 return absl::InvalidArgumentError(absl::StrFormat(
432 "Regular dungeon entrance 0x%02X is marked as a spawn point",
435 if (entrance.
entrance_id_ !=
static_cast<uint16_t
>(entrance_id)) {
436 return absl::InvalidArgumentError(absl::StrFormat(
437 "Regular dungeon entrance model ID 0x%02X does not match requested "
445 return absl::FailedPreconditionError(
446 "Dungeon entrance layout changed since load; reload entrances");
449 return absl::OutOfRangeError(absl::StrFormat(
450 "Regular dungeon entrance 0x%02X room ID %d is outside [0, %d)",
454 for (
const auto& [begin, end] :
456 if (end > rom.
size()) {
457 return absl::FailedPreconditionError(absl::StrFormat(
458 "Regular dungeon entrance 0x%02X write range "
459 "0x%06X-0x%06X exceeds ROM size 0x%X",
460 entrance_id, begin, end,
static_cast<uint32_t
>(rom.
size())));
463 return absl::OkStatus();
468 const std::array<RoomEntrance, kNumDungeonEntranceSlots>& entrances,
469 bool dirty_only =
true) {
474 if (dirty_only && !entrance.dirty()) {
480 return absl::OkStatus();
484 const std::array<RoomEntrance, kNumDungeonEntranceSlots>& entrances,
485 bool dirty_only =
true) {
487 if (dirty_only && !entrances[spawn_id].dirty()) {
490 return absl::FailedPreconditionError(absl::StrFormat(
491 "Dungeon spawn point 0x%02X is scheduled for save through the legacy "
492 "RoomEntrance model; use the dedicated DungeonSpawnPoint model",
495 return absl::OkStatus();
499 Rom* rom, std::array<RoomEntrance, kNumDungeonEntranceSlots>& entrances,
500 bool dirty_only =
true) {
502 return absl::FailedPreconditionError(
"ROM not loaded");
518 if (dirty_only && !entrance.dirty()) {
524 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)
const auto & vector() const
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
uint16_t horizontal_scroll
uint16_t camera_trigger_y
uint16_t overworld_door_tilemap
static absl::StatusOr< DungeonSpawnPoint > Load(const Rom &rom, int spawn_id)
Dungeon Room Entrance or Spawn Point.
absl::Status Save(Rom *rom, int entrance_id, bool is_spawn_point=false)
uint8_t camera_boundary_fw_
uint8_t camera_boundary_qe_
RoomEntrance(Rom *rom, uint8_t entrance_id, bool is_spawn_point=false)
std::optional< EntranceLayoutKind > loaded_layout_kind_
uint8_t camera_boundary_fe_
uint8_t camera_boundary_fs_
uint8_t camera_boundary_qs_
uint8_t camera_boundary_qw_
uint16_t camera_trigger_y_
absl::Status load_status_
uint8_t camera_boundary_fn_
uint16_t camera_trigger_x_
uint8_t camera_boundary_qn_
bool is_spawn_point() const
std::optional< EntranceLayoutKind > loaded_layout_kind() const
const absl::Status & load_status() const
#define ASSIGN_OR_RETURN(type_variable_name, expression)
constexpr int bedPositionResetXLow
constexpr int bedSheetPositionX
constexpr int kEntranceCameraXTrigger
constexpr int kEntranceRoom
constexpr int dungeons_startrooms
constexpr int kEntranceDoor
constexpr int kEntranceXScroll
constexpr int bedPositionResetXHigh
constexpr int items_data_start
constexpr int bedPositionResetYHigh
absl::Status ValidateRegularDungeonEntranceForSave(const Rom &rom, const RoomEntrance &entrance, int entrance_id)
constexpr int bedPositionResetYLow
absl::StatusOr< std::vector< DungeonEntranceWriteRange > > CollectDirtyRegularDungeonEntranceWriteRanges(const Rom &rom, const std::array< RoomEntrance, kNumDungeonEntranceSlots > &entrances)
constexpr int bedPositionY
constexpr int initial_equipement
constexpr int kEntranceExit
constexpr int kNumRegularDungeonEntrances
constexpr int chests_msgid
constexpr int chests_itemsgfx
constexpr int chests_sramvalue
constexpr int chests_backupitems
constexpr int chests_xoffset
constexpr int kEntranceFloor
constexpr int bedPositionX
std::vector< DungeonEntranceWriteRange > RegularDungeonEntranceWriteRanges(const EntranceLayout &layout, int entrance_id)
constexpr int kEntranceCameraYTrigger
constexpr int kEntranceBlockset
constexpr int kEntranceXPosition
constexpr int kEntranceLadderBG
constexpr int dungeons_endrooms
constexpr int kEntranceMusic
constexpr int chests_itemsproperties
absl::Status RejectUnsupportedDungeonSpawnPointSaves(const std::array< RoomEntrance, kNumDungeonEntranceSlots > &entrances, bool dirty_only=true)
absl::Status SaveAllDungeonEntrances(Rom *rom, std::array< RoomEntrance, kNumDungeonEntranceSlots > &entrances, bool dirty_only=true)
constexpr int kNumDungeonSpawnPoints
absl::Status ValidateRegularDungeonEntrancesForSave(const Rom &rom, const std::array< RoomEntrance, kNumDungeonEntranceSlots > &entrances, bool dirty_only=true)
constexpr int chests_sramaddress
constexpr int kNumberOfRooms
std::pair< uint32_t, uint32_t > DungeonEntranceWriteRange
constexpr int kEntranceScrollEdge
constexpr int kEntranceDungeon
constexpr int dungeons_bossrooms
constexpr int kEntranceScrollQuadrant
constexpr int kEntrancescrolling
constexpr int chests_yoffset
absl::StatusOr< EntranceLayout > ResolveEntranceLayout(std::span< const uint8_t > data)
constexpr int kEntranceYScroll
constexpr int chests_itemswide
constexpr int items_data_end
constexpr int bedSheetPositionY
constexpr int kEntranceYPosition
#define RETURN_IF_ERROR(expr)
std::array< EntranceTable, static_cast< size_t >(EntranceField::kCount)> tables