diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-15 23:18:32 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-15 23:18:32 +0200 |
commit | 11f0ac686707000900f6ef4f7ce4e8047d623c7e (patch) | |
tree | 587b995dcc3628448c89a6fc17ec442e6a49eeaf | |
parent | 85bff5e057c62b82f9cfc39f0ded555ed2533bd4 (diff) | |
download | gba-renderers-11f0ac686707000900f6ef4f7ce4e8047d623c7e.tar.gz gba-renderers-11f0ac686707000900f6ef4f7ce4e8047d623c7e.zip |
Add icn and chr drawing functions
-rw-r--r-- | src/main.c | 25 | ||||
-rw-r--r-- | src/renderer_m0.c | 205 |
2 files changed, 114 insertions, 116 deletions
@@ -120,8 +120,6 @@ int main(void) { | |||
120 | irq_init(); | 120 | irq_init(); |
121 | irs_set(IRQ_VBLANK, irs_stub); | 121 | irs_set(IRQ_VBLANK, irs_stub); |
122 | 122 | ||
123 | // draw_filled_rect(0, 0, 7, 7, 1); | ||
124 | // flip_buffer(); | ||
125 | // draw_filled_rect(0, 0, 7, 7, 2); | 123 | // draw_filled_rect(0, 0, 7, 7, 2); |
126 | // draw_filled_rect(8, 0, 15, 7, 3); | 124 | // draw_filled_rect(8, 0, 15, 7, 3); |
127 | // BG_H_SCROLL_0 = 240; | 125 | // BG_H_SCROLL_0 = 240; |
@@ -133,28 +131,27 @@ int main(void) { | |||
133 | int inc = 1; | 131 | int inc = 1; |
134 | while (true) { | 132 | while (true) { |
135 | bios_vblank_wait(); | 133 | bios_vblank_wait(); |
136 | flip_buffer(); | ||
137 | 134 | ||
138 | PROF(test_clear(), test_clear_cycles); | 135 | PROF(test_clear(), test_clear_cycles); |
139 | // PROF(test_lines(), test_lines_cycles); | 136 | // PROF(test_lines(), test_lines_cycles); |
140 | 137 | ||
141 | // ANIMATION EXAMPLE | 138 | // ANIMATION EXAMPLE |
142 | draw_rect(0 + x, 0, 100 + x, 100, 2); | 139 | // draw_rect(0 + x, 0, 100 + x, 100, 2); |
143 | x += inc; | 140 | // x += inc; |
144 | if (x >= 50) { | 141 | // if (x >= 50) { |
145 | inc = -1; | 142 | // inc = -1; |
146 | } else if (x <= 0) { | 143 | // } else if (x <= 0) { |
147 | inc = 1; | 144 | // inc = 1; |
148 | } | 145 | // } |
149 | 146 | ||
150 | // draw_rect(50, 10, 200, 110, 1); | 147 | // draw_rect(50, 10, 200, 110, 1); |
151 | PROF(test_rect(), test_rect_cycles); | 148 | // PROF(test_rect(), test_rect_cycles); |
152 | // PROF(test_fill_rect(), test_fill_rect_cycles); | 149 | // PROF(test_fill_rect(), test_fill_rect_cycles); |
153 | // PROF(test_chr(), test_chr_cycles); | 150 | // PROF(test_chr(), test_chr_cycles); |
154 | // PROF(test_icn(), test_icn_cycles); | 151 | // PROF(test_icn(), test_icn_cycles); |
155 | // draw_filled_rect(0, 0, 140, 60, 0); | 152 | draw_filled_rect(0, 0, 140, 60, 0); |
156 | // PROF_SHOW(); | 153 | PROF_SHOW(); |
157 | // PROF(flip_buffer(), flip_cycles); | 154 | PROF(flip_buffer(), flip_cycles); |
158 | } | 155 | } |
159 | 156 | ||
160 | return 0; | 157 | return 0; |
diff --git a/src/renderer_m0.c b/src/renderer_m0.c index b187903..3d1a4d0 100644 --- a/src/renderer_m0.c +++ b/src/renderer_m0.c | |||
@@ -75,14 +75,15 @@ static u32 *backbuf = BUF_0; | |||
75 | 75 | ||
76 | IWRAM_CODE | 76 | IWRAM_CODE |
77 | void screen_fill(u8 clr) { | 77 | void screen_fill(u8 clr) { |
78 | // TODO: revise this with updated renderer. | 78 | // We have to make sure we leave the last tile blank to use as alpha channel |
79 | #if 1 | 79 | // when moving the BG during double buffering. |
80 | #if 0 | ||
80 | u32 *dst = backbuf; | 81 | u32 *dst = backbuf; |
81 | for(int i = 0; i < KB(20) / 4; i++) { | 82 | for(int i = 0; i < KB(20) / 4 - 8; i++) { |
82 | *dst++ = 0x11111111 * clr; | 83 | *dst++ = 0x11111111 * clr; |
83 | } | 84 | } |
84 | #else | 85 | #else |
85 | dma_fill(backbuf, 0x11111111 * clr, KB(20), 3); | 86 | dma_fill(backbuf, 0x11111111 * clr, KB(20) - 32, 3); |
86 | #endif | 87 | #endif |
87 | } | 88 | } |
88 | 89 | ||
@@ -475,65 +476,65 @@ flip_buffer(void) { | |||
475 | // } | 476 | // } |
476 | } | 477 | } |
477 | 478 | ||
478 | static u32 dec_nibble[] = { | 479 | static u16 dec_nibble[] = { |
479 | 0x00000000, 0x01000000, 0x00010000, 0x01010000, | 480 | 0x0000, 0x1000, 0x0100, 0x1100, |
480 | 0x00000100, 0x01000100, 0x00010100, 0x01010100, | 481 | 0x0010, 0x1010, 0x0110, 0x1110, |
481 | 0x00000001, 0x01000001, 0x00010001, 0x01010001, | 482 | 0x0001, 0x1001, 0x0101, 0x1101, |
482 | 0x00000101, 0x01000101, 0x00010101, 0x01010101, | 483 | 0x0011, 0x1011, 0x0111, 0x1111, |
483 | }; | 484 | }; |
484 | 485 | ||
485 | static u32 dec_nibble_flip_x[] = { | 486 | static u16 dec_nibble_flip_x[] = { |
486 | 0x00000000, 0x00000001, 0x00000100, 0x00000101, | 487 | 0x0000, 0x0001, 0x0010, 0x0011, |
487 | 0x00010000, 0x00010001, 0x00010100, 0x00010101, | 488 | 0x0100, 0x0101, 0x0110, 0x0111, |
488 | 0x01000000, 0x01000001, 0x01000100, 0x01000101, | 489 | 0x1000, 0x1001, 0x1010, 0x1011, |
489 | 0x01010000, 0x01010001, 0x01010100, 0x01010101, | 490 | 0x1100, 0x1101, 0x1110, 0x1111, |
490 | }; | 491 | }; |
491 | 492 | ||
492 | IWRAM_CODE | 493 | IWRAM_CODE |
493 | static inline | 494 | static inline |
494 | u64 | 495 | u32 |
495 | decode_1bpp(u8 row, u8 flip_x) { | 496 | decode_1bpp(u8 row, u8 flip_x) { |
496 | if (flip_x) { | 497 | if (flip_x) { |
497 | u32 *lut = dec_nibble_flip_x; | 498 | u16 *lut = dec_nibble_flip_x; |
498 | return (u64)lut[(row >> 4) & 0xF] << 32 | (u64)lut[(row >> 0) & 0xF]; | 499 | return (u32)lut[(row >> 4) & 0xF] << 16 | (u32)lut[(row >> 0) & 0xF]; |
499 | } | 500 | } |
500 | u32 *lut = dec_nibble; | 501 | u16 *lut = dec_nibble; |
501 | return (u64)lut[(row >> 0) & 0xF] << 32 | (u64)lut[(row >> 4) & 0xF]; | 502 | return (u32)lut[(row >> 0) & 0xF] << 16 | (u32)lut[(row >> 4) & 0xF]; |
502 | } | 503 | } |
503 | 504 | ||
504 | IWRAM_CODE | 505 | IWRAM_CODE |
505 | static inline | 506 | static inline |
506 | void | 507 | void |
507 | draw_2bpp_row(size_t x, size_t y, u8 a, u8 b, u8 flip_x) { | 508 | draw_2bpp_row(size_t x, size_t y, u8 a, u8 b, u8 flip_x) { |
508 | // BOUNDCHECK_SCREEN(x, y); | 509 | BOUNDCHECK_SCREEN(x, y); |
509 | 510 | ||
510 | // size_t tile_x = x / 8; | 511 | size_t tile_x = x / 8; |
511 | // size_t start_col = x % 8; | 512 | size_t tile_y = y / 8; |
512 | // size_t shift_left = start_col * 8; | 513 | size_t start_col = x % 8; |
513 | // size_t shift_right = (8 - start_col) * 8; | 514 | size_t start_row = y % 8; |
514 | 515 | size_t shift_left = start_col * 4; | |
515 | // u64 *dst = &backbuf[(y * 30 + tile_x) * 8 / 2]; | 516 | size_t shift_right = (8 - start_col) * 4; |
516 | // if (start_col == 0) { | 517 | |
517 | // u64 clr_a = decode_1bpp(a, flip_x); | 518 | u32 *dst = &backbuf[tile_x * 8 + tile_y * 8 * 32]; |
518 | // u64 clr_b = decode_1bpp(b, flip_x); | 519 | dst += start_row; |
519 | // u64 mask_a = (clr_a * 0xF); | 520 | if (start_col == 0) { |
520 | // u64 mask_b = (clr_b * 0xF); | 521 | u32 clr_a = decode_1bpp(a, flip_x); |
521 | // u64 mask = (mask_a | mask_b); | 522 | u32 clr_b = decode_1bpp(b, flip_x); |
522 | // u64 color = clr_a + (clr_b << 1); | 523 | u32 mask_a = (clr_a * 0xF); |
523 | // dst[0] = (dst[0] & ~mask) | color; | 524 | u32 mask_b = (clr_b * 0xF); |
524 | // } else { | 525 | u32 mask = (mask_a | mask_b); |
525 | // u64 clr_a = decode_1bpp(a, flip_x); | 526 | u32 color = clr_a + (clr_b << 1); |
526 | // u64 clr_b = decode_1bpp(b, flip_x); | 527 | dst[0] = (dst[0] & ~mask) | color; |
527 | // u64 mask_a = (clr_a * 0xF); | 528 | } else { |
528 | // u64 mask_b = (clr_b * 0xF); | 529 | u32 clr_a = decode_1bpp(a, flip_x); |
529 | // u64 mask = (mask_a | mask_b); | 530 | u32 clr_b = decode_1bpp(b, flip_x); |
530 | // u64 color = clr_a + (clr_b << 1); | 531 | u32 mask_a = (clr_a * 0xF); |
531 | // dst[0] = (dst[0] & ~(mask << shift_left)) | (color << shift_left); | 532 | u32 mask_b = (clr_b * 0xF); |
532 | // if ((x + 7) > (SCREEN_WIDTH)) { | 533 | u32 mask = (mask_a | mask_b); |
533 | // return; | 534 | u32 color = clr_a + (clr_b << 1); |
534 | // } | 535 | dst[0] = (dst[0] & ~(mask << shift_left)) | (color << shift_left); |
535 | // dst[1] = (dst[1] & ~(mask >> shift_right)) | (color >> shift_right); | 536 | dst[8] = (dst[8] & ~(mask >> shift_right)) | (color >> shift_right); |
536 | // } | 537 | } |
537 | 538 | ||
538 | // TODO: different blend modes? | 539 | // TODO: different blend modes? |
539 | } | 540 | } |
@@ -542,29 +543,29 @@ IWRAM_CODE | |||
542 | static inline | 543 | static inline |
543 | void | 544 | void |
544 | draw_1bpp_row(size_t x, size_t y, u8 a, u8 clr, u8 flip_x) { | 545 | draw_1bpp_row(size_t x, size_t y, u8 a, u8 clr, u8 flip_x) { |
545 | // BOUNDCHECK_SCREEN(x, y); | 546 | BOUNDCHECK_SCREEN(x, y); |
546 | 547 | ||
547 | // size_t tile_x = x / 8; | 548 | size_t tile_x = x / 8; |
548 | // size_t start_col = x % 8; | 549 | size_t tile_y = y / 8; |
549 | // size_t shift_left = start_col * 8; | 550 | size_t start_col = x % 8; |
550 | // size_t shift_right = (8 - start_col) * 8; | 551 | size_t start_row = y % 8; |
551 | 552 | size_t shift_left = start_col * 4; | |
552 | // u64 *dst = &backbuf[(y * 30 + tile_x) * 8 / 2]; | 553 | size_t shift_right = (8 - start_col) * 4; |
553 | // if (start_col == 0) { | 554 | |
554 | // u64 color = decode_1bpp(a, flip_x); | 555 | u32 *dst = &backbuf[tile_x * 8 + tile_y * 8 * 32]; |
555 | // u64 mask = (color * 0xF); | 556 | dst += start_row; |
556 | // color *= clr; | 557 | if (start_col == 0) { |
557 | // dst[0] = (dst[0] & ~mask) | color; | 558 | u32 color = decode_1bpp(a, flip_x); |
558 | // } else { | 559 | u32 mask = (color * 0xF); |
559 | // u64 color = decode_1bpp(a, flip_x); | 560 | color *= clr; |
560 | // u64 mask = (color * 0xF); | 561 | dst[0] = (dst[0] & ~mask) | color; |
561 | // color *= clr; | 562 | } else { |
562 | // dst[0] = (dst[0] & ~(mask << shift_left)) | (color << shift_left); | 563 | u32 color = decode_1bpp(a, flip_x); |
563 | // if ((x + 7) > (SCREEN_WIDTH)) { | 564 | u32 mask = (color * 0xF); |
564 | // return; | 565 | color *= clr; |
565 | // } | 566 | dst[0] = (dst[0] & ~(mask << shift_left)) | (color << shift_left); |
566 | // dst[1] = (dst[1] & ~(mask >> shift_right)) | (color >> shift_right); | 567 | dst[8] = (dst[8] & ~(mask >> shift_right)) | (color >> shift_right); |
567 | // } | 568 | } |
568 | 569 | ||
569 | // TODO: different blend modes? | 570 | // TODO: different blend modes? |
570 | } | 571 | } |
@@ -572,41 +573,41 @@ draw_1bpp_row(size_t x, size_t y, u8 a, u8 clr, u8 flip_x) { | |||
572 | IWRAM_CODE | 573 | IWRAM_CODE |
573 | void | 574 | void |
574 | draw_chr(size_t x, size_t y, u8 *sprite, u8 flip_x, u8 flip_y) { | 575 | draw_chr(size_t x, size_t y, u8 *sprite, u8 flip_x, u8 flip_y) { |
575 | // BOUNDCHECK_SCREEN(x, y); | 576 | BOUNDCHECK_SCREEN(x, y); |
576 | // if (!flip_y) { | 577 | if (!flip_y) { |
577 | // for(size_t v = 0; v < 8; v++) { | 578 | for(size_t v = 0; v < 8; v++) { |
578 | // if ((y + v) >= SCREEN_HEIGHT) break; | 579 | if ((y + v) >= SCREEN_HEIGHT) break; |
579 | // u8 ch1 = sprite[v + 0]; | 580 | u8 ch1 = sprite[v + 0]; |
580 | // u8 ch2 = sprite[v + 8]; | 581 | u8 ch2 = sprite[v + 8]; |
581 | // draw_2bpp_row(x, y + v, ch1, ch2, flip_x); | 582 | draw_2bpp_row(x, y + v, ch1, ch2, flip_x); |
582 | // } | 583 | } |
583 | // } else { | 584 | } else { |
584 | // for(size_t v = 0; v < 8; v++) { | 585 | for(size_t v = 0; v < 8; v++) { |
585 | // if ((y + v) >= SCREEN_HEIGHT) break; | 586 | if ((y + v) >= SCREEN_HEIGHT) break; |
586 | // u8 ch1 = sprite[(7 - v) + 0]; | 587 | u8 ch1 = sprite[(7 - v) + 0]; |
587 | // u8 ch2 = sprite[(7 - v) + 8]; | 588 | u8 ch2 = sprite[(7 - v) + 8]; |
588 | // draw_2bpp_row(x, y + v, ch1, ch2, flip_x); | 589 | draw_2bpp_row(x, y + v, ch1, ch2, flip_x); |
589 | // } | 590 | } |
590 | // } | 591 | } |
591 | } | 592 | } |
592 | 593 | ||
593 | IWRAM_CODE | 594 | IWRAM_CODE |
594 | void | 595 | void |
595 | draw_icn(size_t x, size_t y, u8 *sprite, u8 clr, u8 flip_x, u8 flip_y) { | 596 | draw_icn(size_t x, size_t y, u8 *sprite, u8 clr, u8 flip_x, u8 flip_y) { |
596 | // BOUNDCHECK_SCREEN(x, y); | 597 | BOUNDCHECK_SCREEN(x, y); |
597 | // if (!flip_y) { | 598 | if (!flip_y) { |
598 | // for(size_t v = 0; v < 8; v++) { | 599 | for(size_t v = 0; v < 8; v++) { |
599 | // if ((y + v) >= SCREEN_HEIGHT) break; | 600 | if ((y + v) >= SCREEN_HEIGHT) break; |
600 | // u8 ch1 = sprite[v]; | 601 | u8 ch1 = sprite[v]; |
601 | // draw_1bpp_row(x, y + v, ch1, clr, flip_x); | 602 | draw_1bpp_row(x, y + v, ch1, clr, flip_x); |
602 | // } | 603 | } |
603 | // } else { | 604 | } else { |
604 | // for(size_t v = 0; v < 8; v++) { | 605 | for(size_t v = 0; v < 8; v++) { |
605 | // if ((y + v) >= SCREEN_HEIGHT) break; | 606 | if ((y + v) >= SCREEN_HEIGHT) break; |
606 | // u8 ch1 = sprite[(7 - v)]; | 607 | u8 ch1 = sprite[(7 - v)]; |
607 | // draw_1bpp_row(x, y + v, ch1, clr, flip_x); | 608 | draw_1bpp_row(x, y + v, ch1, clr, flip_x); |
608 | // } | 609 | } |
609 | // } | 610 | } |
610 | } | 611 | } |
611 | 612 | ||
612 | #include "font.h" | 613 | #include "font.h" |
@@ -649,7 +650,7 @@ renderer_init(void) { | |||
649 | 650 | ||
650 | // Setup initial background state. | 651 | // Setup initial background state. |
651 | BG_H_SCROLL_0 = 240; | 652 | BG_H_SCROLL_0 = 240; |
652 | BG_H_SCROLL_1 = 0; | 653 | BG_H_SCROLL_1 = 240; |
653 | 654 | ||
654 | // FIXME: clean this up. | 655 | // FIXME: clean this up. |
655 | // u32 *clr_tile =((u32*)(MEM_VRAM) + 0xC000 / 4); | 656 | // u32 *clr_tile =((u32*)(MEM_VRAM) + 0xC000 / 4); |