8namespace draw_routines {
13 if (ctx.
tiles.size() < 6) {
20 const int body_count = (ctx.
object.
size_ & 0x0F) + 10;
21 const int edge_x = ctx.
object.
x_ + (edge_is_left ? 0 : 1);
22 const int fill_x = ctx.
object.
x_ + (edge_is_left ? 1 : 0);
33 for (
int i = 0; i < body_count; ++i, ++y) {
53 for (
int s = 0; s < size; s++) {
54 if (ctx.
tiles.size() >= 4) {
84 for (
int s = 0; s < size; s++) {
85 if (ctx.
tiles.size() >= 8) {
105 }
else if (ctx.
tiles.size() >= 4) {
124 if (ctx.
tiles.size() < 8) {
128 for (
int s = 0; s < count; ++s) {
129 const int y = ctx.
object.
y_ + (s * 2);
155 int count = size + 1;
157 for (
int s = 0; s < count; s++) {
158 if (ctx.
tiles.size() >= 8) {
161 const int base_y = ctx.
object.
y_ + (s * 6);
187 int count = size + 1;
189 for (
int s = 0; s < count; s++) {
190 if (ctx.
tiles.size() >= 4) {
222 int count = size + 2;
224 if (ctx.
tiles.size() < 3)
235 for (
int s = 0; s < count; s++) {
247 int count = size + 1;
249 for (
int s = 0; s < count; s++) {
250 if (ctx.
tiles.size() >= 1) {
259 DrawDownwardsCorners2x1(ctx,
true);
263 DrawDownwardsCorners2x1(ctx,
false);
268 const int count = size + 1;
269 if (ctx.
tiles.size() < 16) {
273 for (
int s = 0; s < count; ++s) {
274 const int base_y = ctx.
object.
y_ + (s * 4);
275 for (
int x = 0; x < 4; ++x) {
276 for (
int y = 0; y < 4; ++y) {
278 base_y + y, ctx.
tiles[x * 4 + y]);
286 const int count = size + 4;
287 if (ctx.
tiles.empty()) {
291 for (
int s = 0; s < count; ++s) {
299 const int count = size + 1;
300 if (ctx.
tiles.size() < 16) {
304 for (
int s = 0; s < count; ++s) {
305 const int base_y = ctx.
object.
y_ + (s * 6);
306 for (
int x = 0; x < 4; ++x) {
307 for (
int y = 0; y < 4; ++y) {
309 base_y + y, ctx.
tiles[x * 4 + y]);
317 const int count = size + 1;
318 if (ctx.
tiles.size() < 8) {
322 for (
int s = 0; s < count; ++s) {
323 const int base_y = ctx.
object.
y_ + (s * 6);
324 for (
int x = 0; x < 2; ++x) {
325 for (
int y = 0; y < 4; ++y) {
327 base_y + y, ctx.
tiles[x * 4 + y]);
335 const int count = size + 1;
336 if (ctx.
tiles.size() < 12) {
340 for (
int s = 0; s < count; ++s) {
341 const int base_y = ctx.
object.
y_ + (s * 8);
342 for (
int x = 0; x < 3; ++x) {
343 for (
int y = 0; y < 4; ++y) {
345 base_y + y, ctx.
tiles[x * 4 + y]);
353 const int count = size + 1;
354 if (ctx.
tiles.size() < 4) {
358 for (
int s = 0; s < count; ++s) {
359 const int base_y = ctx.
object.
y_ + (s * 14);
373 const int count = size + 2;
374 if (ctx.
tiles.empty()) {
378 for (
int s = 0; s < count; ++s) {
386 const int count = size + 1;
387 if (ctx.
tiles.size() < 8) {
391 for (
int s = 0; s < count; ++s) {
392 const int base_y = ctx.
object.
y_ + (s * 12);
393 for (
int x = 0; x < 2; ++x) {
394 for (
int y = 0; y < 4; ++y) {
396 base_y + y, ctx.
tiles[x * 4 + y]);
404 const int count = size + 1;
405 if (ctx.
tiles.size() < 12) {
409 for (
int s = 0; s < count; ++s) {
410 const int base_y = ctx.
object.
y_ + (s * 6);
411 for (
int x = 0; x < 3; ++x) {
412 for (
int y = 0; y < 4; ++y) {
414 base_y + y, ctx.
tiles[x * 4 + y]);
422 const int middle_rows = size + 1;
423 const int total_rows = size + 6;
425 if (ctx.
tiles.size() >= 12) {
440 for (
int row = 0; row < middle_rows; ++row) {
442 base_y + row, ctx.
tiles[4]);
444 base_y + row, ctx.
tiles[5]);
447 const int cap_y = base_y + middle_rows;
463 if (ctx.
tiles.empty() || total_rows <= 0) {
469 for (
int row = 0; row < total_rows; ++row) {
479 const int count = size + 1;
480 if (ctx.
tiles.size() < 4) {
484 for (
int s = 0; s < count; ++s) {
485 const int base_y = ctx.
object.
y_ + (s * 4);
499 const int repeat_count = size + 1;
500 if (ctx.
tiles.size() < 12) {
504 auto draw_segment = [&](
int base_y,
int tile_base) {
506 ctx.
tiles[tile_base + 0]);
508 ctx.
tiles[tile_base + 1]);
510 ctx.
tiles[tile_base + 2]);
512 ctx.
tiles[tile_base + 3]);
514 ctx.
tiles[tile_base + 4]);
516 ctx.
tiles[tile_base + 5]);
522 for (
int s = 0; s < repeat_count; ++s) {
523 draw_segment(ctx.
object.
y_ + (s * 2), 0);
525 draw_segment(ctx.
object.
y_ + (repeat_count * 2), 6);
530 const int middle_rows = (size + 2) * 2;
531 if (ctx.
tiles.size() < 4) {
542 for (
int row = 0; row < middle_rows; ++row) {
552 const int count = size + 1;
553 if (ctx.
tiles.size() < 4) {
557 for (
int s = 0; s < count; ++s) {
558 const int base_y = ctx.
object.
y_ + (s * 2);
576 if (ctx.
tiles.empty()) {
580 for (
int row = 0; row < count; ++row) {
591 .name =
"Downwards2x2_1to15or32",
593 .draws_to_both_bgs =
false,
597 .category = Category::Downwards});
601 .name =
"Downwards4x2_1to15or26",
606 .draws_to_both_bgs =
false,
610 .category = Category::Downwards});
614 .name =
"Downwards4x2_1to16_BothBG",
616 .draws_to_both_bgs =
true,
620 .category = Category::Downwards});
624 .name =
"DownwardsDecor4x2spaced4_1to16",
626 .draws_to_both_bgs =
false,
630 .category = Category::Downwards});
633 .name =
"Downwards2x2_1to16",
635 .draws_to_both_bgs =
false,
639 .category = Category::Downwards});
643 .name =
"DownwardsHasEdge1x1_1to16_plus3",
645 .draws_to_both_bgs =
false,
652 .category = Category::Downwards});
656 .name =
"DownwardsEdge1x1_1to16",
658 .draws_to_both_bgs =
false,
662 .category = Category::Downwards});
666 .name =
"DownwardsLeftCorners2x1_1to16_plus12",
668 .draws_to_both_bgs =
false,
672 .category = Category::Downwards});
676 .name =
"DownwardsRightCorners2x1_1to16_plus12",
678 .draws_to_both_bgs =
false,
682 .category = Category::Downwards});
686 .name =
"DownwardsFloor4x4_1to16",
688 .draws_to_both_bgs =
false,
692 .category = Category::Downwards});
696 .name =
"Downwards1x1Solid_1to16_plus3",
698 .draws_to_both_bgs =
false,
702 .category = Category::Downwards});
706 .name =
"DownwardsDecor4x4spaced2_1to16",
708 .draws_to_both_bgs =
false,
712 .category = Category::Downwards});
716 .name =
"DownwardsPillar2x4spaced2_1to16",
718 .draws_to_both_bgs =
false,
722 .category = Category::Downwards});
726 .name =
"DownwardsDecor3x4spaced4_1to16",
728 .draws_to_both_bgs =
false,
732 .category = Category::Downwards});
736 .name =
"DownwardsDecor2x2spaced12_1to16",
738 .draws_to_both_bgs =
false,
742 .category = Category::Downwards});
746 .name =
"DownwardsLine1x1_1to16plus1",
748 .draws_to_both_bgs =
false,
752 .category = Category::Downwards});
756 .name =
"DownwardsDecor2x4spaced8_1to16",
758 .draws_to_both_bgs =
false,
762 .category = Category::Downwards});
766 .name =
"DownwardsDecor3x4spaced2_1to16",
768 .draws_to_both_bgs =
false,
772 .category = Category::Downwards});
776 .name =
"DownwardsBigRail3x1_1to16plus5",
778 .draws_to_both_bgs =
false,
782 .category = Category::Downwards});
786 .name =
"DownwardsBlock2x2spaced2_1to16",
788 .draws_to_both_bgs =
false,
792 .category = Category::Downwards});
796 .name =
"DownwardsCannonHole3x4_1to16",
798 .draws_to_both_bgs =
false,
802 .category = Category::Downwards});
806 .name =
"DownwardsBar2x5_1to16",
808 .draws_to_both_bgs =
false,
812 .category = Category::Downwards});
816 .name =
"DownwardsPots2x2_1to16",
818 .draws_to_both_bgs =
false,
822 .category = Category::Downwards});
826 .name =
"DownwardsHammerPegs2x2_1to16",
828 .draws_to_both_bgs =
false,
832 .category = Category::Downwards});
836 .name =
"DownwardsEdge1x1_1to16plus7",
838 .draws_to_both_bgs =
false,
842 .category = Category::Downwards});
SNES 16-bit tile metadata container.
constexpr int kDownwardsBigRail3x1_1to16plus5
constexpr int kDownwardsBlock2x2spaced2_1to16
constexpr int kDownwardsDecor3x4spaced4_1to16
constexpr int kDownwardsCannonHole3x4_1to16
constexpr int kDownwardsDecor2x4spaced8_1to16
constexpr int kDownwardsDecor3x4spaced2_1to16
constexpr int kDownwardsEdge1x1_1to16plus7
constexpr int kDownwardsPillar2x4spaced2_1to16
constexpr int kDownwardsFloor4x4_1to16
constexpr int kDownwardsDecor2x2spaced12_1to16
constexpr int kDownwards1x1Solid_1to16_plus3
constexpr int kDownwardsDecor4x4spaced2_1to16
constexpr int kDownwardsHammerPegs2x2_1to16
constexpr int kDownwardsLine1x1_1to16plus1
constexpr int kDownwardsPots2x2_1to16
constexpr int kDownwardsBar2x5_1to16
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 DrawDownwardsCorners2x1(const DrawContext &ctx, bool edge_is_left)
void DrawDownwards1x1Solid_1to16_plus3(const DrawContext &ctx)
Draw downwards 1x1 solid line with +3 extension.
void DrawDownwardsDecor2x4spaced8_1to16(const DrawContext &ctx)
Draw downwards 2x4 decoration with 8-tile spacing.
void DrawDownwards4x2_1to15or26(const DrawContext &ctx)
Draw 4x2 tiles downward pattern (1-15 or 26 iterations)
void DrawDownwardsEdge1x1_1to16(const DrawContext &ctx)
Draw 1x1 edge tiles downward (1-16 iterations)
void DrawDownwardsBar2x5_1to16(const DrawContext &ctx)
Draw downwards 2x5 bar pattern.
void DrawDownwardsDecor2x2spaced12_1to16(const DrawContext &ctx)
Draw downwards 2x2 decoration with 12-tile spacing.
void DrawDownwards2x2_1to15or32(const DrawContext &ctx)
Draw 2x2 tiles downward pattern (1-15 or 32 iterations)
void DrawDownwards2x2_1to16(const DrawContext &ctx)
Draw 2x2 tiles downward pattern (1-16 iterations)
void RegisterDownwardsRoutines(std::vector< DrawRoutineInfo > ®istry)
Register all downwards draw routines to the registry.
void DrawDownwardsDecor4x4spaced2_1to16(const DrawContext &ctx)
Draw downwards 4x4 decoration with 2-tile spacing.
void DrawDownwardsEdge1x1_1to16plus7(const DrawContext &ctx)
Draw a single tile downward for size + 8 rows.
void DrawDownwardsHasEdge1x1_1to16_plus3(const DrawContext &ctx)
Draw 1x1 tiles with edge detection +3 downward.
void DrawDownwardsLine1x1_1to16plus1(const DrawContext &ctx)
Draw downwards 1x1 line with +1 extension.
void DrawDownwardsCannonHole3x4_1to16(const DrawContext &ctx)
Draw downwards cannon-hole 3x4 pattern.
void DrawDownwardsLeftCorners2x1_1to16_plus12(const DrawContext &ctx)
Draw left corner 2x1 tiles with opening and closing caps.
void DrawDownwardsPots2x2_1to16(const DrawContext &ctx)
Draw downwards 2x2 pots pattern.
void DrawDownwardsBlock2x2spaced2_1to16(const DrawContext &ctx)
Draw downwards 2x2 block pattern with 2-tile spacing.
void DrawDownwardsBigRail3x1_1to16plus5(const DrawContext &ctx)
Draw downwards big rail pattern (3x1 family, +5 extension)
void DrawDownwardsFloor4x4_1to16(const DrawContext &ctx)
Draw downwards 4x4 floor blocks.
void DrawDownwardsRightCorners2x1_1to16_plus12(const DrawContext &ctx)
Draw right corner 2x1 tiles with opening and closing caps.
void DrawDownwardsHammerPegs2x2_1to16(const DrawContext &ctx)
Draw downwards 2x2 hammer pegs pattern.
void DrawDownwardsDecor4x2spaced4_1to16(const DrawContext &ctx)
Draw 4x2 decoration downward with spacing (1-16 iterations)
void DrawDownwardsPillar2x4spaced2_1to16(const DrawContext &ctx)
Draw downwards 2x4 pillar with 2-tile spacing.
void DrawDownwardsDecor3x4spaced2_1to16(const DrawContext &ctx)
Draw downwards 3x4 decoration with 2-tile spacing.
void DrawDownwardsDecor3x4spaced4_1to16(const DrawContext &ctx)
Draw downwards 3x4 decoration with 4-tile spacing.
void DrawDownwards4x2_1to16_BothBG(const DrawContext &ctx)
Draw 4x2 tiles downward pattern for both BG layers.
Context passed to draw routines containing all necessary state.
std::span< const gfx::TileInfo > tiles
gfx::BackgroundBuffer & target_bg
const RoomObject & object
Metadata about a draw routine.