yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
room_layout.cc
Go to the documentation of this file.
1#include "room_layout.h"
2
3#include "absl/strings/str_format.h"
4#include "rom/snes.h"
5#include "util/log.h"
8
9namespace yaze::zelda3 {
10
11absl::StatusOr<int> RoomLayout::GetLayoutAddress(int layout_id) const {
12 if (!rom_ || !rom_->is_loaded()) {
13 return absl::FailedPreconditionError("ROM not loaded");
14 }
15
16 if (layout_id < 0 ||
17 layout_id >= static_cast<int>(kRoomLayoutPointers.size())) {
18 return absl::InvalidArgumentError(
19 absl::StrFormat("Invalid layout id %d", layout_id));
20 }
21
22 uint32_t snes_addr = kRoomLayoutPointers[layout_id];
23 int pc_addr = SnesToPc(static_cast<int>(snes_addr));
24 if (pc_addr < 0 || pc_addr >= static_cast<int>(rom_->size())) {
25 return absl::OutOfRangeError(
26 absl::StrFormat("Layout pointer %d out of range", layout_id));
27 }
28 return pc_addr;
29}
30
31absl::Status RoomLayout::LoadLayout(int layout_id) {
32 objects_.clear();
33
34 auto addr_result = GetLayoutAddress(layout_id);
35 if (!addr_result.ok()) {
36 return addr_result.status();
37 }
38
39 int pos = addr_result.value();
40 const auto& rom_data = rom_->data();
41 int layer = 0;
42
43 LOG_DEBUG("RoomLayout", "Loading layout %d from PC address 0x%05X", layout_id,
44 pos);
45
46 int obj_index = 0;
47 while (pos + 2 < static_cast<int>(rom_->size())) {
48 uint8_t b1 = rom_data[pos];
49 uint8_t b2 = rom_data[pos + 1];
50
51 if (b1 == 0xFF && b2 == 0xFF) {
52 // $FF $FF is the END terminator for this layout
53 LOG_DEBUG("RoomLayout",
54 "Layout %d terminated at pos=0x%05X after %d objects",
55 layout_id, pos, obj_index);
56 break;
57 }
58
59 if (pos + 2 >= static_cast<int>(rom_->size())) {
60 break;
61 }
62
63 uint8_t b3 = rom_data[pos + 2];
64 pos += 3;
65
67 b1, b2, b3, static_cast<uint8_t>(layer));
68
69 obj.SetRom(rom_);
71 objects_.push_back(obj);
72
73 LOG_DEBUG("RoomLayout",
74 "Layout %d obj[%d]: bytes=[%02X,%02X,%02X] -> id=0x%03X x=%d "
75 "y=%d size=%d tiles=%zu",
76 layout_id, obj_index, b1, b2, b3, obj.id_, obj.x_, obj.y_,
77 obj.size_, obj.tiles().size());
78 obj_index++;
79 }
80
81 LOG_DEBUG("RoomLayout", "Layout %d loaded with %zu objects", layout_id,
82 objects_.size());
83
84 return absl::OkStatus();
85}
86
87absl::Status RoomLayout::Draw(int room_id, const uint8_t* gfx_data,
90 const gfx::PaletteGroup& palette_group,
91 DungeonState* state, uint8_t floor1_graphics,
92 uint8_t floor2_graphics) const {
93 if (!rom_ || !rom_->is_loaded()) {
94 return absl::FailedPreconditionError("ROM not loaded");
95 }
96
97 if (objects_.empty()) {
98 return absl::OkStatus();
99 }
100
101 ObjectDrawer drawer(rom_, room_id, gfx_data);
103 drawer.SetRoomFloorGraphics(floor1_graphics, floor2_graphics);
104
105 std::vector<RoomObject> render_objects = objects_;
106 for (auto& obj : render_objects) {
107 obj.layer_ = RoomObject::LayerType::BG1;
108 }
109
110 // ALTTP enters the room-layout stream with the upper tilemap pointer active.
111 // Object IDs do not reroute the destination tilemap; their draw routines use
112 // the current stream pointer.
113 return drawer.DrawObjectList(render_objects, bg1, bg2, palette_group, state);
114}
115
116} // namespace yaze::zelda3
auto data() const
Definition rom.h:169
auto size() const
Definition rom.h:168
bool is_loaded() const
Definition rom.h:155
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_
Definition room_layout.h:37
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)
static RoomObject DecodeObjectFromBytes(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t layer)
const std::vector< gfx::TileInfo > & tiles() const
Definition room_object.h:99
void SetRom(Rom *rom)
Definition room_object.h:78
#define LOG_DEBUG(category, format,...)
Definition log.h:103
Zelda 3 specific classes and functions.
uint32_t SnesToPc(uint32_t addr) noexcept
Definition snes.h:8
Represents a group of palettes.