6#include "absl/strings/str_format.h"
16 return absl::FailedPreconditionError(
"ROM not loaded");
20 layout_id >=
static_cast<int>(kRoomLayoutPointers.size())) {
21 return absl::InvalidArgumentError(
22 absl::StrFormat(
"Invalid layout id %d", layout_id));
25 uint32_t snes_addr = kRoomLayoutPointers[layout_id];
26 int pc_addr =
SnesToPc(
static_cast<int>(snes_addr));
27 if (pc_addr < 0 || pc_addr >=
static_cast<int>(
rom_->
vector().size())) {
28 return absl::OutOfRangeError(
29 absl::StrFormat(
"Layout pointer %d out of range", layout_id));
37 return absl::CancelledError(
"Room layout load cancelled");
41 if (!addr_result.ok()) {
42 return addr_result.status();
45 int pos = addr_result.value();
46 const int next = layout_id + 1 <
static_cast<int>(kRoomLayoutPointers.size())
47 ? kRoomLayoutPointers[layout_id + 1]
49 const int end = std::min(
static_cast<int>(
SnesToPc(next)),
53 std::vector<RoomObject> decoded;
55 LOG_DEBUG(
"RoomLayout",
"Loading layout %d from PC address 0x%05X", layout_id,
61 return absl::CancelledError(
"Room layout load cancelled");
64 return absl::DataLossError(absl::StrFormat(
65 "Layout %d has a truncated terminator at PC 0x%05X", layout_id, pos));
67 uint8_t b1 = rom_data[pos];
68 uint8_t b2 = rom_data[pos + 1];
70 if (b1 == 0xFF && b2 == 0xFF) {
73 "Layout %d terminated at pos=0x%05X after %d objects",
74 layout_id, pos, obj_index);
76 return absl::OkStatus();
80 return absl::DataLossError(absl::StrFormat(
81 "Layout %d has a truncated object at PC 0x%05X", layout_id, pos));
84 uint8_t b3 = rom_data[pos + 2];
88 b1, b2, b3,
static_cast<uint8_t
>(layer));
93 return absl::CancelledError(
"Room layout load cancelled");
95 decoded.push_back(obj);
98 "Layout %d obj[%d]: bytes=[%02X,%02X,%02X] -> id=0x%03X x=%d "
99 "y=%d size=%d tiles=%zu",
100 layout_id, obj_index, b1, b2, b3, obj.
id_, obj.
x_, obj.
y_,
105 return absl::DataLossError(absl::StrFormat(
106 "Layout %d has no FF FF terminator within its fixed stream", layout_id));
114 uint8_t floor2_graphics)
const {
116 return absl::FailedPreconditionError(
"ROM not loaded");
120 return absl::OkStatus();
127 std::vector<RoomObject> render_objects =
objects_;
128 for (
auto& obj : render_objects) {
135 return drawer.
DrawObjectList(render_objects, bg1, bg2, palette_group, state);
const auto & vector() const
bool stop_requested() const noexcept
Interface for accessing dungeon game state.
Draws dungeon objects to background buffers using game patterns.
void SetRoomFloorGraphics(uint8_t floor1, uint8_t floor2)
void SetBG1RevealMaskSource(gfx::BG1RevealMaskSource source)
absl::Status DrawObjectList(const std::vector< RoomObject > &objects, gfx::BackgroundBuffer &bg1, gfx::BackgroundBuffer &bg2, const gfx::PaletteGroup &palette_group, const DungeonState *state=nullptr, gfx::BackgroundBuffer *layout_bg1=nullptr, bool reset_room_event_indices=true, gfx::BackgroundBuffer *layout_bg2=nullptr)
Draw all objects in a room.
std::vector< RoomObject > objects_
absl::Status Draw(int room_id, const uint8_t *gfx_data, gfx::BackgroundBuffer &bg1, gfx::BackgroundBuffer &bg2, const gfx::PaletteGroup &palette_group, DungeonState *state, uint8_t floor1_graphics, uint8_t floor2_graphics) const
absl::StatusOr< int > GetLayoutAddress(int layout_id) const
absl::Status LoadLayout(int layout_id, util::StopToken stop_token={})
static RoomObject DecodeObjectFromBytes(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t layer)
const std::vector< gfx::TileInfo > & tiles() const
#define LOG_DEBUG(category, format,...)
Zelda 3 specific classes and functions.
constexpr int kRoomLayoutDataEnd
uint32_t SnesToPc(uint32_t addr) noexcept
Represents a group of palettes.