summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2023-04-15 23:18:32 +0200
committerBad Diode <bd@badd10de.dev>2023-04-15 23:18:32 +0200
commit11f0ac686707000900f6ef4f7ce4e8047d623c7e (patch)
tree587b995dcc3628448c89a6fc17ec442e6a49eeaf
parent85bff5e057c62b82f9cfc39f0ded555ed2533bd4 (diff)
downloadgba-renderers-11f0ac686707000900f6ef4f7ce4e8047d623c7e.tar.gz
gba-renderers-11f0ac686707000900f6ef4f7ce4e8047d623c7e.zip
Add icn and chr drawing functions
-rw-r--r--src/main.c25
-rw-r--r--src/renderer_m0.c205
2 files changed, 114 insertions, 116 deletions
diff --git a/src/main.c b/src/main.c
index c6f3c49..129493b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
76IWRAM_CODE 76IWRAM_CODE
77void screen_fill(u8 clr) { 77void 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
478static u32 dec_nibble[] = { 479static 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
485static u32 dec_nibble_flip_x[] = { 486static 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
492IWRAM_CODE 493IWRAM_CODE
493static inline 494static inline
494u64 495u32
495decode_1bpp(u8 row, u8 flip_x) { 496decode_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
504IWRAM_CODE 505IWRAM_CODE
505static inline 506static inline
506void 507void
507draw_2bpp_row(size_t x, size_t y, u8 a, u8 b, u8 flip_x) { 508draw_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
542static inline 543static inline
543void 544void
544draw_1bpp_row(size_t x, size_t y, u8 a, u8 clr, u8 flip_x) { 545draw_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) {
572IWRAM_CODE 573IWRAM_CODE
573void 574void
574draw_chr(size_t x, size_t y, u8 *sprite, u8 flip_x, u8 flip_y) { 575draw_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
593IWRAM_CODE 594IWRAM_CODE
594void 595void
595draw_icn(size_t x, size_t y, u8 *sprite, u8 clr, u8 flip_x, u8 flip_y) { 596draw_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);