yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
object_drawer.h
Go to the documentation of this file.
1#ifndef YAZE_APP_ZELDA3_DUNGEON_OBJECT_DRAWER_H
2#define YAZE_APP_ZELDA3_DUNGEON_OBJECT_DRAWER_H
3
4#include <functional>
5#include <unordered_map>
6#include <vector>
7
8#include "absl/status/status.h"
12#include "rom/rom.h"
18
19namespace yaze {
20namespace zelda3 {
21
37 public:
38 explicit ObjectDrawer(Rom* rom, int room_id,
39 const uint8_t* room_gfx_buffer = nullptr);
40
50 absl::Status DrawObject(const RoomObject& object, gfx::BackgroundBuffer& bg1,
52 const gfx::PaletteGroup& palette_group,
53 const DungeonState* state = nullptr,
54 gfx::BackgroundBuffer* layout_bg1 = nullptr);
55
56 struct DoorDef {
59 uint8_t position;
60
61 // Helper to get position coordinates using DoorPositionManager
62 std::pair<int, int> GetTileCoords() const {
64 }
65
66 // Helper to get door dimensions
70 };
71
72 // Chest index tracking for state queries
74 void SetAllowTrackCornerAliases(bool allow) {
76 }
77
84 void DrawDoor(const DoorDef& door, int door_index, gfx::BackgroundBuffer& bg1,
86 const DungeonState* state = nullptr);
87
95 void DrawPotItem(uint8_t item_id, int x, int y, gfx::BackgroundBuffer& bg);
96
108 absl::Status DrawObjectList(const std::vector<RoomObject>& objects,
111 const gfx::PaletteGroup& palette_group,
112 const DungeonState* state = nullptr,
113 gfx::BackgroundBuffer* layout_bg1 = nullptr,
114 bool reset_chest_index = true);
115
121 int GetDrawRoutineId(int16_t object_id) const;
122
127 return static_cast<int>(draw_routines_.size());
128 }
129
135
144 void DrawTileToBitmap(gfx::Bitmap& bitmap, const gfx::TileInfo& tile_info,
145 int pixel_x, int pixel_y, const uint8_t* tiledata);
146
161 absl::Status DrawRoomDrawObjectData2x2(uint16_t object_id, int tile_x,
162 int tile_y,
164 uint16_t room_draw_object_data_offset,
167
173 std::pair<int, int> CalculateObjectDimensions(const RoomObject& object);
174
175 struct TileTrace {
176 uint16_t object_id = 0;
177 uint8_t size = 0;
178 uint8_t layer = 0;
179 int16_t x_tile = 0;
180 int16_t y_tile = 0;
181 uint16_t tile_id = 0;
182 uint8_t flags = 0;
183 };
184
185 void SetTraceCollector(std::vector<TileTrace>* collector,
186 bool trace_only = false);
187 void ClearTraceCollector();
188 bool TraceOnly() const { return trace_only_; }
189
190 protected:
191 // Draw routine function type
192 using DrawRoutine = std::function<void(
194 std::span<const gfx::TileInfo>, const DungeonState*)>;
195
196 // Core draw routines (based on ZScream's subtype1_routines table)
197 void DrawChest(const RoomObject& obj, gfx::BackgroundBuffer& bg,
198 std::span<const gfx::TileInfo> tiles,
199 const DungeonState* state = nullptr);
200
201 void DrawNothing(const RoomObject& obj, gfx::BackgroundBuffer& bg,
202 std::span<const gfx::TileInfo> tiles,
203 const DungeonState* state = nullptr);
204 void CustomDraw(const RoomObject& obj, gfx::BackgroundBuffer& bg,
205 std::span<const gfx::TileInfo> tiles,
206 const DungeonState* state = nullptr);
208 std::span<const gfx::TileInfo> tiles,
209 const DungeonState* state = nullptr);
212 std::span<const gfx::TileInfo> tiles,
213 const DungeonState* state = nullptr);
214
215 // Type 3 / Special Routines
217 std::span<const gfx::TileInfo> tiles, int width,
218 int height);
219
220 // Custom Object Routine
222 std::span<const gfx::TileInfo> tiles,
223 const DungeonState* state = nullptr);
225 int tile_y);
226
227 // Utility methods
228 // Execute a DrawRoutineRegistry routine (pure DrawContext function) but render
229 // via ObjectDrawer::WriteTile8 so output hits the bitmap-backed buffers used
230 // by RoomLayerManager compositing.
231 void DrawUsingRegistryRoutine(int routine_id, const RoomObject& obj,
233 std::span<const gfx::TileInfo> tiles,
234 const DungeonState* state);
235 void WriteTile8(gfx::BackgroundBuffer& bg, int tile_x, int tile_y,
236 const gfx::TileInfo& tile_info);
237 bool IsValidTilePosition(int tile_x, int tile_y) const;
238
239 // Check if a draw routine should render to both BG1 and BG2
240 // Uses metadata instead of hardcoded routine IDs
241 static bool RoutineDrawsToBothBGs(int routine_id);
242
255 void MarkBG1Transparent(gfx::BackgroundBuffer& bg1, int tile_x, int tile_y,
256 int pixel_width, int pixel_height);
257
258 // Pixel-space variant for explicit rectangular transparency writes.
259 void MarkBg1RectTransparent(gfx::BackgroundBuffer& bg1, int start_px,
260 int start_py, int pixel_width, int pixel_height);
261
262 // Door indicator fallback when graphics unavailable
263 void DrawDoorIndicator(gfx::BackgroundBuffer& bg, int tile_x, int tile_y,
264 int width, int height, DoorType type,
265 DoorDirection direction);
266
267 // Draw routine function array (indexed by routine ID from DrawRoutineRegistry)
268 std::vector<DrawRoutine> draw_routines_;
270
272 uint16_t object_id = 0;
273 uint8_t size = 0;
274 uint8_t layer = 0;
275 };
276
277 void SetTraceContext(const RoomObject& object, RoomObject::LayerType layer);
278 void PushTrace(int tile_x, int tile_y, const gfx::TileInfo& tile_info);
279 static void TraceHookThunk(int tile_x, int tile_y,
280 const gfx::TileInfo& tile_info, void* user_data);
281
283 std::vector<TileTrace>* trace_collector_ = nullptr;
284 bool trace_only_ = false;
285
288 mutable int current_chest_index_ = 0;
290 const uint8_t*
291 room_gfx_buffer_; // Room-specific graphics buffer (current_gfx16_)
292
293 // Canvas dimensions in tiles (64x64 = 512x512 pixels)
294 static constexpr int kMaxTilesX = 64;
295 static constexpr int kMaxTilesY = 64;
296};
297
298} // namespace zelda3
299} // namespace yaze
300
301#endif // YAZE_APP_ZELDA3_DUNGEON_OBJECT_DRAWER_H
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
Represents a bitmap image optimized for SNES ROM hacking.
Definition bitmap.h:67
SNES 16-bit tile metadata container.
Definition snes_tile.h:52
static std::pair< int, int > PositionToTileCoords(uint8_t position, DoorDirection direction)
Convert encoded position to tile coordinates.
Interface for accessing dungeon game state.
Draws dungeon objects to background buffers using game patterns.
int GetDrawRoutineId(int16_t object_id) const
Get draw routine ID for an object.
void WriteTile8(gfx::BackgroundBuffer &bg, int tile_x, int tile_y, const gfx::TileInfo &tile_info)
void DrawTileToBitmap(gfx::Bitmap &bitmap, const gfx::TileInfo &tile_info, int pixel_x, int pixel_y, const uint8_t *tiledata)
Draw a single tile directly to bitmap.
void InitializeDrawRoutines()
Initialize draw routine registry Must be called before drawing objects.
void DrawRightwards4x4_1to16(const RoomObject &obj, gfx::BackgroundBuffer &bg, std::span< const gfx::TileInfo > tiles, const DungeonState *state=nullptr)
int GetDrawRoutineCount() const
Get the total number of registered draw routines.
std::vector< TileTrace > * trace_collector_
std::vector< DrawRoutine > draw_routines_
void DrawUsingRegistryRoutine(int routine_id, const RoomObject &obj, gfx::BackgroundBuffer &bg, std::span< const gfx::TileInfo > tiles, const DungeonState *state)
void MarkBg1RectTransparent(gfx::BackgroundBuffer &bg1, int start_px, int start_py, int pixel_width, int pixel_height)
std::pair< int, int > CalculateObjectDimensions(const RoomObject &object)
Calculate the dimensions (width, height) of an object in pixels.
void SetTraceContext(const RoomObject &object, RoomObject::LayerType layer)
const uint8_t * room_gfx_buffer_
static bool RoutineDrawsToBothBGs(int routine_id)
void DrawNothing(const RoomObject &obj, gfx::BackgroundBuffer &bg, std::span< const gfx::TileInfo > tiles, const DungeonState *state=nullptr)
void DrawDoor(const DoorDef &door, int door_index, gfx::BackgroundBuffer &bg1, gfx::BackgroundBuffer &bg2, const DungeonState *state=nullptr)
Draw a door to background buffers.
std::function< void( ObjectDrawer *, const RoomObject &, gfx::BackgroundBuffer &, std::span< const gfx::TileInfo >, const DungeonState *)> DrawRoutine
void DrawPotItem(uint8_t item_id, int x, int y, gfx::BackgroundBuffer &bg)
Draw a pot item visualization.
void DrawDoorIndicator(gfx::BackgroundBuffer &bg, int tile_x, int tile_y, int width, int height, DoorType type, DoorDirection direction)
void DrawLargeCanvasObject(const RoomObject &obj, gfx::BackgroundBuffer &bg, std::span< const gfx::TileInfo > tiles, int width, int height)
void PushTrace(int tile_x, int tile_y, const gfx::TileInfo &tile_info)
static void TraceHookThunk(int tile_x, int tile_y, const gfx::TileInfo &tile_info, void *user_data)
void DrawCustomObject(const RoomObject &obj, gfx::BackgroundBuffer &bg, std::span< const gfx::TileInfo > tiles, const DungeonState *state=nullptr)
void DrawRightwardsDecor4x3spaced4_1to16(const RoomObject &obj, gfx::BackgroundBuffer &bg, std::span< const gfx::TileInfo > tiles, const DungeonState *state=nullptr)
static constexpr int kMaxTilesX
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_chest_index=true)
Draw all objects in a room.
void MarkBG1Transparent(gfx::BackgroundBuffer &bg1, int tile_x, int tile_y, int pixel_width, int pixel_height)
Mark BG1 pixels as transparent where BG2 overlay objects are drawn.
void DrawChest(const RoomObject &obj, gfx::BackgroundBuffer &bg, std::span< const gfx::TileInfo > tiles, const DungeonState *state=nullptr)
void CustomDraw(const RoomObject &obj, gfx::BackgroundBuffer &bg, std::span< const gfx::TileInfo > tiles, const DungeonState *state=nullptr)
void DrawMissingCustomObjectPlaceholder(gfx::BackgroundBuffer &bg, int tile_x, int tile_y)
ObjectDrawer(Rom *rom, int room_id, const uint8_t *room_gfx_buffer=nullptr)
absl::Status DrawObject(const RoomObject &object, gfx::BackgroundBuffer &bg1, gfx::BackgroundBuffer &bg2, const gfx::PaletteGroup &palette_group, const DungeonState *state=nullptr, gfx::BackgroundBuffer *layout_bg1=nullptr)
Draw a room object to background buffers.
static constexpr int kMaxTilesY
absl::Status DrawRoomDrawObjectData2x2(uint16_t object_id, int tile_x, int tile_y, RoomObject::LayerType layer, uint16_t room_draw_object_data_offset, gfx::BackgroundBuffer &bg1, gfx::BackgroundBuffer &bg2)
Draw a fixed 2x2 (16x16) tile pattern from RoomDrawObjectData.
void SetTraceCollector(std::vector< TileTrace > *collector, bool trace_only=false)
void SetAllowTrackCornerAliases(bool allow)
bool IsValidTilePosition(int tile_x, int tile_y) const
constexpr DoorDimensions GetDoorDimensions(DoorDirection dir)
Get door dimensions based on direction.
Definition door_types.h:192
DoorType
Door types from ALTTP.
Definition door_types.h:33
DoorDirection
Door direction on room walls.
Definition door_types.h:18
Represents a group of palettes.
Door dimensions in tiles (8x8 pixel tiles)
Definition door_types.h:178
std::pair< int, int > GetTileCoords() const
DoorDimensions GetDimensions() const