14namespace draw_routines {
20 return tiles[index % tiles.size()];
24 int h, std::span<const gfx::TileInfo> tiles,
25 size_t start_index = 0) {
29 size_t index = start_index;
30 for (
int x = 0; x < w; ++x) {
31 for (
int y = 0; y < h; ++y) {
39 int h, std::span<const gfx::TileInfo> tiles,
40 size_t start_index = 0) {
44 size_t index = start_index;
45 for (
int y = 0; y < h; ++y) {
46 for (
int x = 0; x < w; ++x) {
56 columns, 3, ctx.
tiles, start_index);
61 ctx.
tiles, start_index);
66 ctx.
tiles, start_index);
90 if (ctx.
tiles.size() >= 32) {
93 for (
int x = 0; x < 4; ++x) {
94 for (
int y = 0; y < 4; ++y) {
97 ctx.
tiles[16 + x * 4 + y]);
102 if (ctx.
tiles.size() >= 8 && ctx.
tiles.size() < 16) {
119 if (ctx.
tiles.size() >= 16) {
121 for (
int x = 0; x < 4; ++x) {
122 for (
int y = 0; y < 4; ++y) {
127 }
else if (ctx.
tiles.size() >= 4) {
154 if (ctx.
tiles.size() >= 1) {
166 if (!result.ok() || !result.value() || result.value()->IsEmpty()) {
168 if (ctx.
tiles.size() >= 1) {
175 const auto& custom_obj = *result.value();
177 for (
const auto& entry : custom_obj.tiles) {
180 uint8_t lo =
static_cast<uint8_t
>(entry.tile_data & 0xFF);
181 uint8_t hi =
static_cast<uint8_t
>((entry.tile_data >> 8) & 0xFF);
186 int draw_x = ctx.
object.
x_ + entry.rel_x;
187 int draw_y = ctx.
object.
y_ + entry.rel_y;
200 if (ctx.
tiles.size() >= 2) {
205 if (ctx.
tiles.size() >
static_cast<size_t>(tile_index)) {
207 ctx.
tiles[tile_index]);
224 if (ctx.
tiles.empty())
288 for (
int i = 0; i < length; ++i) {
289 size_t tile_idx = i % ctx.
tiles.size();
301 if (ctx.
tiles.size() >= 4) {
318 if (ctx.
tiles.size() >=
static_cast<size_t>(width * height)) {
319 for (
int y = 0; y < height; ++y) {
320 for (
int x = 0; x < width; ++x) {
323 ctx.
tiles[y * width + x]);
337 Draw1x3NRightwards(ctx, 6, 0);
342 Draw1x3NRightwards(ctx, 6, 0);
350 if (ctx.
tiles.empty())
354 for (
int x = 0; x < 3; ++x) {
357 TileAtWrapped(ctx.
tiles,
static_cast<size_t>(x)));
361 for (
int y = 1; y <= 3; ++y) {
362 for (
int x = 0; x < 3; ++x) {
365 TileAtWrapped(ctx.
tiles,
static_cast<size_t>(3 + x)));
370 for (
int x = 0; x < 3; ++x) {
373 TileAtWrapped(ctx.
tiles,
static_cast<size_t>(6 + x)));
380 if (ctx.
tiles.empty())
382 Draw1x3NRightwards(ctx, 4, 0, 0);
383 Draw1x3NRightwards(ctx, 4, 12, 3);
394 if (ctx.
tiles.empty())
396 Draw4x4ColumnMajor(ctx, 0, 0, 0);
397 Draw4x4ColumnMajor(ctx, 0, 2, 16);
398 Draw4x4ColumnMajor(ctx, 0, 6, 32);
405 if (ctx.
tiles.empty())
408 Draw4x4ColumnMajor(ctx, 0, 0, 0);
409 Draw4x4ColumnMajor(ctx, 4, 0, 16);
410 Draw4x4ColumnMajor(ctx, 0, 4, 32);
411 Draw4x4ColumnMajor(ctx, 4, 4, 48);
416 Draw4x4ColumnMajor(ctx, 0, 0, 0);
427 if (ctx.
tiles.empty())
429 Draw1x3NRightwards(ctx, 3, 0, 0);
430 Draw1x3NRightwards(ctx, 3, 9, 3);
436 if (ctx.
tiles.empty())
439 Draw4x4ColumnMajor(ctx, 2, 0, 0);
440 Draw4x4ColumnMajor(ctx, 0, 4, 16);
441 Draw4x4ColumnMajor(ctx, 4, 4, 16);
447 if (ctx.
tiles.size() < 4)
462 if (ctx.
tiles.size() < 16)
466 for (
int x = 0; x < 4; ++x) {
467 for (
int y = 0; y < 4; ++y) {
476 if (ctx.
tiles.size() < 12)
480 for (
int x = 0; x < 4; ++x) {
481 for (
int y = 0; y < 3; ++y) {
491 if (ctx.
tiles.size() < 2)
494 for (
int col = 0; col < 3; ++col) {
533 if (ctx.
tiles.empty())
537 const int middle_columns = (size + 1) * 2;
539 Draw1x5Column(ctx, 0, 0);
540 for (
int i = 0; i < middle_columns; ++i) {
541 Draw1x5Column(ctx, 1 + i, 5);
543 Draw1x5Column(ctx, 1 + middle_columns, 10);
549 if (ctx.
tiles.empty())
553 const int middle_columns = (size + 1) * 2;
557 for (
int i = 0; i < middle_columns; ++i) {
580 "Draw4x4BlocksIn4x4SuperSquare: obj=0x%03X pos=(%d,%d) size=0x%02X "
581 "tiles=%zu size_x=%d size_y=%d",
583 ctx.
tiles.size(), size_x, size_y);
585 if (ctx.
tiles.empty()) {
587 "Draw4x4BlocksIn4x4SuperSquare: SKIPPING - no tiles loaded!");
592 const auto& tile = ctx.
tiles[0];
594 "Draw4x4BlocksIn4x4SuperSquare: tile[0] id=%d palette=%d", tile.id_,
597 for (
int sy = 0; sy < size_y; ++sy) {
598 for (
int sx = 0; sx < size_x; ++sx) {
600 int base_x = ctx.
object.
x_ + (sx * 4);
601 int base_y = ctx.
object.
y_ + (sy * 4);
604 for (
int y = 0; y < 4; ++y) {
605 for (
int x = 0; x < 4; ++x) {
620 if (ctx.
tiles.empty())
623 const auto& tile = ctx.
tiles[0];
624 for (
int sy = 0; sy < size_y; ++sy) {
625 for (
int sx = 0; sx < size_x; ++sx) {
626 int base_x = ctx.
object.
x_ + (sx * 3);
627 int base_y = ctx.
object.
y_ + (sy * 3);
629 for (
int y = 0; y < 3; ++y) {
630 for (
int x = 0; x < 3; ++x) {
646 if (ctx.
tiles.empty())
648 if (ctx.
tiles.size() < 8) {
655 for (
int sy = 0; sy < size_y; ++sy) {
656 for (
int sx = 0; sx < size_x; ++sx) {
657 int base_x = ctx.
object.
x_ + (sx * 4);
658 int base_y = ctx.
object.
y_ + (sy * 4);
662 for (
int x = 0; x < 4; ++x) {
663 const auto& row0 = ctx.
tiles[(x * 2) + 0];
664 const auto& row1 = ctx.
tiles[(x * 2) + 1];
689 if (ctx.
tiles.size() < 8) {
694 for (
int sy = 0; sy < size_y; ++sy) {
695 for (
int sx = 0; sx < size_x; ++sx) {
696 int base_x = ctx.
object.
x_ + (sx * 4);
697 int base_y = ctx.
object.
y_ + (sy * 4);
699 for (
int x = 0; x < 4; ++x) {
700 const auto& row0 = ctx.
tiles[(x * 2) + 0];
701 const auto& row1 = ctx.
tiles[(x * 2) + 1];
722 if (ctx.
tiles.size() < 8) {
727 for (
int sy = 0; sy < size_y; ++sy) {
728 for (
int sx = 0; sx < size_x; ++sx) {
729 int base_x = ctx.
object.
x_ + (sx * 4);
730 int base_y = ctx.
object.
y_ + (sy * 4);
732 for (
int x = 0; x < 4; ++x) {
733 const auto& row0 = ctx.
tiles[(x * 2) + 0];
734 const auto& row1 = ctx.
tiles[(x * 2) + 1];
754 if (ctx.
tiles.size() < 24)
771 for (
int xx = 1; xx < max; ++xx) {
772 for (
int yy = 1; yy < max; ++yy) {
782 for (
int yy = 1; yy < max; ++yy) {
796 if (ctx.
tiles.size() < 4)
799 for (
int sy = 0; sy < size_y; ++sy) {
800 for (
int sx = 0; sx < size_x; ++sx) {
801 int base_x = ctx.
object.
x_ + (sx * 2);
802 int base_y = ctx.
object.
y_ + (sy * 2);
820 if (ctx.
tiles.size() < 16)
823 int right_x = ctx.
object.
x_ + (3 + (size_x * 2));
824 int bottom_y = ctx.
object.
y_ + (3 + (size_y * 2));
827 for (
int xx = 0; xx < size_x + 1; ++xx) {
828 for (
int yy = 0; yy < size_y + 1; ++yy) {
829 int base_x = ctx.
object.
x_ + (xx * 2);
830 int base_y = ctx.
object.
y_ + (yy * 2);
843 for (
int yy = 0; yy < size_y + 1; ++yy) {
844 int base_y = ctx.
object.
y_ + (yy * 2);
857 for (
int xx = 0; xx < size_x + 1; ++xx) {
858 int base_x = ctx.
object.
x_ + (xx * 2);
889 int count_x = size_x + 2;
890 int count_y = size_y + 2;
892 if (ctx.
tiles.empty())
894 if (ctx.
tiles.size() < 8) {
896 for (
int yy = 0; yy < count_y; ++yy) {
897 for (
int xx = 0; xx < count_x; ++xx) {
898 int base_x = ctx.
object.
x_ + (xx * 4);
899 int base_y = ctx.
object.
y_ + (yy * 4);
901 ctx.
tiles[
static_cast<size_t>((xx + yy) % ctx.
tiles.size())];
902 for (
int y = 0; y < 4; ++y) {
903 for (
int x = 0; x < 4; ++x) {
913 for (
int yy = 0; yy < count_y; ++yy) {
914 for (
int xx = 0; xx < count_x; ++xx) {
915 int base_x = ctx.
object.
x_ + (xx * 4);
916 int base_y = ctx.
object.
y_ + (yy * 4);
918 for (
int x = 0; x < 4; ++x) {
942 if (ctx.
tiles.size() < 16)
946 for (
int y = 0; y < 4; ++y) {
947 for (
int x = 0; x < 4; ++x) {
948 size_t tile_idx =
static_cast<size_t>(y * 4 + x);
974 if (ctx.
tiles.size() < 12)
979 for (
int x = 0; x < 4; ++x) {
980 for (
int y = 0; y < 3; ++y) {
990 if (ctx.
tiles.size() < 16)
993 for (
int y = 0; y < 4; ++y) {
994 for (
int x = 0; x < 4; ++x) {
995 size_t tile_idx =
static_cast<size_t>(y * 4 + x);
1005 if (ctx.
tiles.size() < 16)
1008 for (
int y = 0; y < 4; ++y) {
1009 for (
int x = 0; x < 4; ++x) {
1010 size_t tile_idx =
static_cast<size_t>(y * 4 + x);
1027 if (ctx.
tiles.size() < 6)
1039 for (
int col = 0; col < 5; ++col) {
1043 for (
int row = 0; row < 4; ++row) {
1044 size_t tile_idx = (row < static_cast<int>(ctx.
tiles.size())) ? row : 0;
1048 base_y + row, ctx.
tiles[tile_idx]);
1051 auto mirrored_tile = ctx.
tiles[tile_idx];
1052 mirrored_tile.horizontal_mirror_ = !mirrored_tile.horizontal_mirror_;
1054 base_y + row, mirrored_tile);
1061 for (
int col = 0; col < 5; ++col) {
1064 for (
int row = 0; row < 4; ++row) {
1065 size_t tile_idx = (row < static_cast<int>(ctx.
tiles.size())) ? row : 0;
1069 base_y + row, ctx.
tiles[tile_idx]);
1072 auto mirrored_tile = ctx.
tiles[tile_idx];
1073 mirrored_tile.horizontal_mirror_ = !mirrored_tile.horizontal_mirror_;
1075 base_y + row, mirrored_tile);
1086 bool is_opened =
false;
1094 if (ctx.
tiles.size() >= 8) {
1096 for (
int y = 0; y < 2; ++y) {
1097 for (
int x = 0; x < 2; ++x) {
1100 ctx.
tiles[4 + y * 2 + x]);
1108 if (ctx.
tiles.size() >= 4) {
1109 for (
int y = 0; y < 2; ++y) {
1110 for (
int x = 0; x < 2; ++x) {
1122 bool is_bombed =
false;
1129 if (ctx.
tiles.size() >= 8) {
1130 for (
int y = 0; y < 2; ++y) {
1131 for (
int x = 0; x < 2; ++x) {
1134 ctx.
tiles[4 + y * 2 + x]);
1142 if (ctx.
tiles.size() >= 4) {
1143 for (
int y = 0; y < 2; ++y) {
1144 for (
int x = 0; x < 2; ++x) {
1157 bool has_moved =
false;
1166 if (ctx.
tiles.size() < 4)
1169 for (
int s = 0; s < size; ++s) {
1170 int offset = has_moved ? 2 : 0;
1175 for (
int dy = 0; dy < 2; ++dy) {
1176 for (
int dx = 0; dx < 2; ++dx) {
1178 ctx.
tiles[dy * 2 + dx]);
1192 if (row_count <= 0 || tile_offset < 0 || ctx.
tiles.empty()) {
1196 if (tile_offset >=
static_cast<int>(ctx.
tiles.size())) {
1200 const int available_tiles =
static_cast<int>(ctx.
tiles.size()) - tile_offset;
1202 const int rows_to_draw = std::min(row_count, available_rows);
1204 for (
int row = 0; row < rows_to_draw; ++row) {
1209 ctx.
tiles[row_base + col]);
1224 const bool water_active =
1227 const int row_count = water_active ? 5 : 3;
1228 const int tile_offset = water_active ? 12 : 0;
1229 DrawWaterFaceRows(ctx, row_count, tile_offset);
1235 DrawWaterFaceRows(ctx, 5, 0);
1241 DrawWaterFaceRows(ctx, 7, 0);
1253 int size_y = ((ctx.
object.
size_ >> 4) & 0x0F) + 1;
1255 if (ctx.
tiles.size() < 16)
1259 for (
int x = 0; x < size_x; ++x) {
1261 size_t tile_idx = (x == 0) ? 0 : ((x == size_x - 1) ? 2 : 1);
1267 for (
int y = 1; y < size_y + 1; ++y) {
1277 int bottom_y = ctx.
object.
y_ + size_y + 1;
1278 for (
int x = 0; x < size_x; ++x) {
1279 size_t tile_idx = (x == 0) ? 5 : ((x == size_x - 1) ? 7 : 6);
1281 ctx.
tiles[tile_idx]);
1289 if (ctx.
tiles.size() < 3)
1292 for (
int x = 0; x < width; ++x) {
1293 size_t tile_idx = (x == 0) ? 0 : ((x == width - 1) ? 2 : 1);
1303 if (ctx.
tiles.empty())
1306 for (
int y = 0; y < height; ++y) {
1325 .draws_to_both_bgs =
false,
1336 .draws_to_both_bgs =
false,
1344 .name =
"DoorSwitcherer",
1346 .draws_to_both_bgs =
false,
1355 .name =
"SomariaLine",
1357 .draws_to_both_bgs =
false,
1365 .name =
"WaterFace",
1367 .draws_to_both_bgs =
false,
1380 .name =
"4x4BlocksIn4x4SuperSquare",
1382 .draws_to_both_bgs =
false,
1390 .name =
"3x3FloorIn4x4SuperSquare",
1392 .draws_to_both_bgs =
false,
1400 .name =
"4x4FloorIn4x4SuperSquare",
1402 .draws_to_both_bgs =
false,
1410 .name =
"4x4FloorOneIn4x4SuperSquare",
1412 .draws_to_both_bgs =
false,
1420 .name =
"4x4FloorTwoIn4x4SuperSquare",
1422 .draws_to_both_bgs =
false,
1430 .name =
"BigHole4x4_1to16",
1432 .draws_to_both_bgs =
false,
1440 .name =
"Spike2x2In4x4SuperSquare",
1442 .draws_to_both_bgs =
false,
1450 .name =
"TableRock4x4_1to16",
1452 .draws_to_both_bgs =
false,
1460 .name =
"WaterOverlay8x8_1to16",
1462 .draws_to_both_bgs =
false,
1471 .name =
"InterRoomFatStairsUp",
1473 .draws_to_both_bgs =
false,
1482 .name =
"InterRoomFatStairsDownA",
1484 .draws_to_both_bgs =
false,
1493 .name =
"InterRoomFatStairsDownB",
1495 .draws_to_both_bgs =
false,
1504 .name =
"AutoStairs",
1506 .draws_to_both_bgs =
false,
1515 .name =
"StraightInterRoomStairs",
1517 .draws_to_both_bgs =
false,
1527 .name =
"SpiralStairsGoingUpUpper",
1530 .draws_to_both_bgs =
false,
1539 .name =
"SpiralStairsGoingDownUpper",
1542 .draws_to_both_bgs =
false,
1551 .name =
"SpiralStairsGoingUpLower",
1554 .draws_to_both_bgs =
false,
1563 .name =
"SpiralStairsGoingDownLower",
1566 .draws_to_both_bgs =
false,
1576 .name =
"BigKeyLock",
1578 .draws_to_both_bgs =
false,
1587 .name =
"BombableFloor",
1589 .draws_to_both_bgs =
false,
1599 .name =
"EmptyWaterFace",
1601 .draws_to_both_bgs =
false,
1610 .name =
"SpittingWaterFace",
1612 .draws_to_both_bgs =
false,
1621 .name =
"DrenchingWaterFace",
1623 .draws_to_both_bgs =
false,
1633 .name =
"PrisonCell",
1635 .draws_to_both_bgs =
true,
1645 .draws_to_both_bgs =
false,
1653 .name =
"Rightwards3x6",
1655 .draws_to_both_bgs =
false,
1663 .name =
"Utility6x3",
1665 .draws_to_both_bgs =
false,
1673 .name =
"Utility3x5",
1675 .draws_to_both_bgs =
false,
1683 .name =
"VerticalTurtleRockPipe",
1685 .draws_to_both_bgs =
false,
1693 .name =
"HorizontalTurtleRockPipe",
1695 .draws_to_both_bgs =
false,
1703 .name =
"LightBeam",
1705 .draws_to_both_bgs =
false,
1713 .name =
"BigLightBeam",
1715 .draws_to_both_bgs =
false,
1723 .name =
"BossShell4x4",
1725 .draws_to_both_bgs =
false,
1733 .name =
"SolidWallDecor3x4",
1735 .draws_to_both_bgs =
false,
1743 .name =
"ArcheryGameTargetDoor",
1745 .draws_to_both_bgs =
false,
1753 .name =
"GanonTriforceFloorDecor",
1755 .draws_to_both_bgs =
false,
1763 .name =
"Single2x2",
1765 .draws_to_both_bgs =
false,
1774 .name =
"Single4x4",
1776 .draws_to_both_bgs =
false,
1785 .name =
"Single4x3",
1787 .draws_to_both_bgs =
false,
1796 .name =
"RupeeFloor",
1798 .draws_to_both_bgs =
false,
1807 .name =
"Actual4x4",
1809 .draws_to_both_bgs =
false,
1818 .name =
"Waterfall47",
1820 .draws_to_both_bgs =
false,
1828 .name =
"Waterfall48",
1830 .draws_to_both_bgs =
false,
1839 .name =
"ClosedChestPlatform",
1841 .draws_to_both_bgs =
false,
1850 .name =
"MovingWallWest",
1853 .draws_to_both_bgs =
false,
1862 .name =
"MovingWallEast",
1867 .draws_to_both_bgs =
false,
1876 .name =
"OpenChestPlatform",
1881 int width = (ctx.object.size_ & 0x0F) + 1;
1882 int segments = ((ctx.object.size_ >> 4) & 0x0F) * 2 + 5;
1884 for (
int s = 0; s < segments && s < 8; ++s) {
1885 for (
int x = 0; x < width && x < 8; ++x) {
1886 if (ctx.tiles.size() > 0) {
1887 size_t idx = (s * width + x) % ctx.tiles.size();
1895 .draws_to_both_bgs =
false,
1905 .name =
"DownwardsHasEdge1x1_1to16_plus23",
1909 int size = ctx.object.size_ & 0x0F;
1910 int count = size + 21;
1911 if (ctx.tiles.size() < 3)
1914 int tile_y = ctx.object.y_;
1918 ctx.target_bg, ctx.object.x_, tile_y, {0x00E3})) {
1924 for (
int s = 0; s < count; s++) {
1933 .draws_to_both_bgs =
false,
1945 .name =
"CustomObject",
1947 .draws_to_both_bgs =
false,
SNES 16-bit tile metadata container.
static CustomObjectManager & Get()
absl::StatusOr< std::shared_ptr< CustomObject > > GetObjectInternal(int object_id, int subtype)
virtual bool IsWaterFaceActive(int room_id) const
virtual bool IsFloorBombable(int room_id) const =0
virtual bool IsWallMoved(int room_id) const =0
virtual bool IsChestOpen(int room_id, int chest_index) const =0
virtual bool IsDoorSwitchActive(int room_id) const =0
virtual bool IsDoorOpen(int room_id, int door_index) const =0
#define LOG_DEBUG(category, format,...)
constexpr int kGanonTriforceFloorDecor
constexpr int kArcheryGameTargetDoor
constexpr int kRupeeFloor
constexpr int kWaterfall47
constexpr int kClosedChestPlatform
constexpr int kHorizontalTurtleRockPipe
constexpr int kBigLightBeam
constexpr int kSolidWallDecor3x4
constexpr int kVerticalTurtleRockPipe
constexpr int kMovingWallWest
constexpr int kMovingWallEast
constexpr int kUtility6x3
constexpr int kCustomObject
constexpr int kOpenChestPlatform
constexpr int kUtility3x5
constexpr int kRightwards3x6
constexpr int kDownwardsHasEdge1x1_1to16_plus23
constexpr int kBossShell4x4
constexpr int kWaterfall48
bool ExistingTileMatchesAny(const gfx::BackgroundBuffer &bg, int tile_x, int tile_y, std::initializer_list< uint16_t > tile_ids)
void WriteTile8(gfx::BackgroundBuffer &bg, int tile_x, int tile_y, const gfx::TileInfo &tile_info)
Write an 8x8 tile to the background buffer.
void DrawNx4(const DrawContext &ctx, int columns, size_t start_index)
void DrawRowMajor(gfx::BackgroundBuffer &bg, int base_x, int base_y, int w, int h, std::span< const gfx::TileInfo > tiles, size_t start_index=0)
void Draw4x4ColumnMajor(const DrawContext &ctx, int x_offset, int y_offset, size_t start_index)
constexpr int kWaterFaceWidthTiles
void DrawWaterFaceRows(const DrawContext &ctx, int row_count, int tile_offset)
void Draw1x3NRightwards(const DrawContext &ctx, int columns, size_t start_index, int y_offset=0)
const gfx::TileInfo & TileAtWrapped(std::span< const gfx::TileInfo > tiles, size_t index)
void Draw1x5Column(const DrawContext &ctx, int x_offset, size_t start_index)
void DrawColumnMajor(gfx::BackgroundBuffer &bg, int base_x, int base_y, int w, int h, std::span< const gfx::TileInfo > tiles, size_t start_index=0)
void DrawTableRock4x4_1to16(const DrawContext &ctx)
Draw 4x4 table rock pattern.
void DrawInterRoomFatStairsDownA(const DrawContext &ctx)
Draw inter-room fat stairs going down A (Type 2 object 0x12E)
void DrawSingle2x2(const DrawContext &ctx)
Draw a single 2x2 block (column-major order)
void DrawWaterfall47(const DrawContext &ctx)
Draw waterfall object 0x47 pattern.
void DrawHorizontalTurtleRockPipe(const DrawContext &ctx)
Draw horizontal Turtle Rock pipe (6x4)
void DrawAutoStairs(const DrawContext &ctx)
Draw auto stairs (Type 2/3 objects 0x130-0x133, 0x21B-0x21D, 0x233)
void DrawSpittingWaterFace(const DrawContext &ctx)
Draw spitting water face (Type 3 object 0x201)
void DrawLargeCanvasObject(const DrawContext &ctx, int width, int height)
Draw large canvas object with arbitrary dimensions.
void DrawChest(const DrawContext &ctx, int chest_index)
Draw chest object (big or small) with open/closed state support.
void DrawBed4x5(const DrawContext &ctx)
Draw a 4x5 bed pattern (row-major)
void DrawSingle4x4(const DrawContext &ctx)
Draw a single 4x4 block (column-major order)
void DrawUtility3x5(const DrawContext &ctx)
Draw utility 3x5 pattern (special row pattern)
void DrawDoorSwitcherer(const DrawContext &ctx)
Draw door switcher object with state-based graphics.
void Draw4x4BlocksIn4x4SuperSquare(const DrawContext &ctx)
Draw 4x4 solid blocks in a super square grid.
void DrawBigHole4x4_1to16(const DrawContext &ctx)
Draw 4x4 big hole pattern.
void Draw4x4FloorTwoIn4x4SuperSquare(const DrawContext &ctx)
Draw two 4x4 floor pattern variant.
void DrawSolidWallDecor3x4(const DrawContext &ctx)
Draw solid wall decor 3x4.
void DrawLightBeamOnFloor(const DrawContext &ctx)
Draw floor light beam composed of three 4x4 blocks.
void DrawWaterFace(const DrawContext &ctx)
Draw a generic 2x2 water-face helper pattern.
void DrawChestPlatformVerticalWall(const DrawContext &ctx)
Draw chest platform vertical wall section.
void DrawClosedChestPlatform(const DrawContext &ctx)
Draw closed chest platform (Type 1 object 0xC1)
void DrawSpike2x2In4x4SuperSquare(const DrawContext &ctx)
Draw 2x2 spike pattern in super square units.
void DrawSingle4x3(const DrawContext &ctx)
Draw a single 4x3 block (column-major order)
void DrawBigLightBeamOnFloor(const DrawContext &ctx)
Draw big floor light beam (8x8 footprint)
void DrawSpiralStairs(const DrawContext &ctx, bool going_up, bool is_upper)
Draw spiral stairs (Type 2 objects 0x138-0x13B)
void DrawSomariaLine(const DrawContext &ctx)
Draw Somaria line in various directions.
void DrawWaterfall48(const DrawContext &ctx)
Draw waterfall object 0x48 pattern.
void DrawVerticalTurtleRockPipe(const DrawContext &ctx)
Draw vertical Turtle Rock pipe (two stacked 4x3 sections)
void DrawBombableFloor(const DrawContext &ctx)
Draw bombable floor (Type 3 object 0x247)
void DrawDrenchingWaterFace(const DrawContext &ctx)
Draw drenching water face (Type 3 object 0x202)
void DrawEmptyWaterFace(const DrawContext &ctx)
Draw empty water face (Type 3 object 0x200)
void DrawBossShell4x4(const DrawContext &ctx)
Draw boss shell 4x4.
void CustomDraw(const DrawContext &ctx)
Custom draw routine for special objects.
void Draw4x4FloorIn4x4SuperSquare(const DrawContext &ctx)
Draw 4x4 floor pattern in super square units.
void DrawInterRoomFatStairsUp(const DrawContext &ctx)
Draw inter-room fat stairs going up (Type 2 object 0x12D)
void Draw3x3FloorIn4x4SuperSquare(const DrawContext &ctx)
Draw 3x3 floor pattern in super square units.
void DrawArcheryGameTargetDoor(const DrawContext &ctx)
Draw archery game target door (two 3x3 sections)
void DrawStraightInterRoomStairs(const DrawContext &ctx)
Draw straight inter-room stairs (Type 3 objects 0x21E-0x229)
void DrawGanonTriforceFloorDecor(const DrawContext &ctx)
Draw Ganon triforce floor decor (three 4x4 sections)
void RegisterSpecialRoutines(std::vector< DrawRoutineInfo > ®istry)
Register all special/miscellaneous draw routines to the registry.
void DrawInterRoomFatStairsDownB(const DrawContext &ctx)
Draw inter-room fat stairs going down B (Type 2 object 0x12F)
void DrawMovingWall(const DrawContext &ctx, bool is_west)
Draw moving wall (Type 1 objects 0xCD, 0xCE)
void DrawUtility6x3(const DrawContext &ctx)
Draw utility 6x3 pattern via RoomDraw_1x3N_rightwards.
void DrawRightwards3x6(const DrawContext &ctx)
Draw a 6x3 pattern via RoomDraw_1x3N_rightwards semantics.
void DrawChestPlatformHorizontalWall(const DrawContext &ctx)
Draw chest platform horizontal wall section.
void DrawWaterOverlay8x8_1to16(const DrawContext &ctx)
Draw water overlay 8x8 pattern.
void DrawRupeeFloor(const DrawContext &ctx)
Draw the blue rupee floor pattern (6x8 with gaps)
void Draw4x4FloorOneIn4x4SuperSquare(const DrawContext &ctx)
Draw single 4x4 floor pattern variant.
void DrawNothing(const DrawContext &ctx)
Draw nothing - represents invisible logic objects or placeholders.
void DrawActual4x4(const DrawContext &ctx)
Draw an actual 4x4 tile8 pattern (column-major order)
void DrawBigKeyLock(const DrawContext &ctx)
Draw big key lock (Type 3 object 0x218)
void DrawPrisonCell(const DrawContext &ctx)
Draw prison cell with bars (Type 3 objects 0x20D, 0x217)
Context passed to draw routines containing all necessary state.
std::span< const gfx::TileInfo > tiles
gfx::BackgroundBuffer & target_bg
bool HasSecondaryBG() const
const RoomObject & object
gfx::BackgroundBuffer * secondary_bg
const DungeonState * state
Metadata about a draw routine.