diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-15 20:54:34 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-15 20:54:34 +0200 |
commit | e56c4d8e3932db4edfa04312e02fa2be071f93c4 (patch) | |
tree | a68cb4f4068bf4037544f47134607d8c9e426efd | |
parent | 87e5c991bf866db9253915f403bdb8e30f9d6449 (diff) | |
download | gba-renderers-e56c4d8e3932db4edfa04312e02fa2be071f93c4.tar.gz gba-renderers-e56c4d8e3932db4edfa04312e02fa2be071f93c4.zip |
Add a 3rd BG to act as a shade while BG register changes
This helps create a double buffering effect but unfortunately due to
delays in setting up BG priority, this creates tearing artifacts.
-rw-r--r-- | src/main.c | 21 | ||||
-rw-r--r-- | src/renderer_m0.c | 136 |
2 files changed, 70 insertions, 87 deletions
@@ -119,24 +119,25 @@ int main(void) { | |||
119 | // Register interrupts. | 119 | // Register interrupts. |
120 | irq_init(); | 120 | irq_init(); |
121 | irs_set(IRQ_VBLANK, irs_stub); | 121 | irs_set(IRQ_VBLANK, irs_stub); |
122 | 122 | flip_buffer(); | |
123 | // Initialize sequencer. | ||
124 | // flip_buffer(); | ||
125 | // screen_fill(1); | ||
126 | // screen_fill(2); | ||
127 | // backbuf[0] = 0x11111111; | ||
128 | // screen_fill(1); | ||
129 | // flip_buffer(); | ||
130 | // screen_fill(2); | ||
131 | // flip_buffer(); | ||
132 | 123 | ||
133 | // Main loop. | 124 | // Main loop. |
134 | PROF_INIT(); | 125 | PROF_INIT(); |
126 | int x = 0; | ||
127 | int inc = 1; | ||
135 | while (true) { | 128 | while (true) { |
136 | bios_vblank_wait(); | 129 | bios_vblank_wait(); |
137 | 130 | ||
138 | PROF(test_clear(), test_clear_cycles); | 131 | PROF(test_clear(), test_clear_cycles); |
139 | // PROF(test_lines(), test_lines_cycles); | 132 | // PROF(test_lines(), test_lines_cycles); |
133 | draw_rect(0 + x, 0, 100 + x, 100, 2); | ||
134 | x += inc; | ||
135 | if (x >= 50) { | ||
136 | inc = -8; | ||
137 | } else if (x <= 0) { | ||
138 | inc = 8; | ||
139 | } | ||
140 | // draw_rect(50, 10, 200, 110, 1); | ||
140 | // PROF(test_rect(), test_rect_cycles); | 141 | // PROF(test_rect(), test_rect_cycles); |
141 | // PROF(test_fill_rect(), test_fill_rect_cycles); | 142 | // PROF(test_fill_rect(), test_fill_rect_cycles); |
142 | // PROF(test_chr(), test_chr_cycles); | 143 | // PROF(test_chr(), test_chr_cycles); |
diff --git a/src/renderer_m0.c b/src/renderer_m0.c index 3034d40..b0d4a6e 100644 --- a/src/renderer_m0.c +++ b/src/renderer_m0.c | |||
@@ -27,8 +27,12 @@ | |||
27 | // Charblock and screenblock for both render buffers. | 27 | // Charblock and screenblock for both render buffers. |
28 | #define CB_0 0 | 28 | #define CB_0 0 |
29 | #define CB_1 1 | 29 | #define CB_1 1 |
30 | // NOTE: CB_2 could be at the end of 2 (0x0600:8000) since we only need a clear | ||
31 | // color tile. Testing at 3 for now. | ||
32 | #define CB_2 3 | ||
30 | #define SB_0 20 | 33 | #define SB_0 20 |
31 | #define SB_1 21 | 34 | #define SB_1 21 |
35 | #define SB_2 23 | ||
32 | 36 | ||
33 | // Available storage for other memory. | 37 | // Available storage for other memory. |
34 | // #define FG_PIXELS ((u32*)(MEM_VRAM + KB(44))) | 38 | // #define FG_PIXELS ((u32*)(MEM_VRAM + KB(44))) |
@@ -71,11 +75,11 @@ static u32 *backbuf = BUF_1; | |||
71 | 75 | ||
72 | IWRAM_CODE | 76 | IWRAM_CODE |
73 | void screen_fill(u8 clr) { | 77 | void screen_fill(u8 clr) { |
74 | #if 0 | 78 | #if 1 |
75 | // u32 *dst = backbuf; | 79 | u32 *dst = backbuf; |
76 | // for(int i = 0; i < KB(75) / 8; i++) { | 80 | for(int i = 0; i < KB(20) / 4; i++) { |
77 | // *dst++ = 0x01010101 * clr; | 81 | *dst++ = 0x11111111 * clr; |
78 | // } | 82 | } |
79 | #else | 83 | #else |
80 | dma_fill(backbuf, 0x11111111 * clr, KB(20), 3); | 84 | dma_fill(backbuf, 0x11111111 * clr, KB(20), 3); |
81 | #endif | 85 | #endif |
@@ -105,7 +109,13 @@ IWRAM_CODE | |||
105 | static inline | 109 | static inline |
106 | void | 110 | void |
107 | draw_hline(size_t x0, size_t x1, size_t y0, u8 clr) { | 111 | draw_hline(size_t x0, size_t x1, size_t y0, u8 clr) { |
108 | // TODO | 112 | BOUNDCHECK_SCREEN(x0, y0); |
113 | BOUNDCHECK_SCREEN(x1, y0); | ||
114 | |||
115 | // TODO: perf | ||
116 | for (size_t x = x0; x <= x1; x++) { | ||
117 | draw_pixel(x, y0, clr); | ||
118 | } | ||
109 | } | 119 | } |
110 | 120 | ||
111 | IWRAM_CODE | 121 | IWRAM_CODE |
@@ -113,14 +123,20 @@ UNROLL_LOOPS | |||
113 | static inline | 123 | static inline |
114 | void | 124 | void |
115 | draw_vline(size_t x0, size_t y0, size_t y1, u8 clr) { | 125 | draw_vline(size_t x0, size_t y0, size_t y1, u8 clr) { |
116 | // TODO | 126 | BOUNDCHECK_SCREEN(x0, y0); |
127 | BOUNDCHECK_SCREEN(x0, y1); | ||
128 | |||
129 | // TODO: perf | ||
130 | for (size_t y = y0; y <= y1; y++) { | ||
131 | draw_pixel(x0, y, clr); | ||
132 | } | ||
117 | } | 133 | } |
118 | 134 | ||
119 | IWRAM_CODE | 135 | IWRAM_CODE |
120 | void | 136 | void |
121 | draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | 137 | draw_line(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { |
122 | // BOUNDCHECK_SCREEN(x0, y0); | 138 | BOUNDCHECK_SCREEN(x0, y0); |
123 | // BOUNDCHECK_SCREEN(x1, y1); | 139 | BOUNDCHECK_SCREEN(x1, y1); |
124 | if (y0 == y1) { | 140 | if (y0 == y1) { |
125 | MAYBE_SWAP(x0, x1); | 141 | MAYBE_SWAP(x0, x1); |
126 | draw_hline(x0, x1, y0, clr); | 142 | draw_hline(x0, x1, y0, clr); |
@@ -271,51 +287,6 @@ draw_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
271 | draw_hline(x0, x1, y1, clr); | 287 | draw_hline(x0, x1, y1, clr); |
272 | draw_vline(x0, y0, y1, clr); | 288 | draw_vline(x0, y0, y1, clr); |
273 | draw_vline(x1, y0, y1, clr); | 289 | draw_vline(x1, y0, y1, clr); |
274 | |||
275 | // TODO: check if this is better. | ||
276 | // BOUNDCHECK_SCREEN(x0, y0); | ||
277 | // BOUNDCHECK_SCREEN(x1, y1); | ||
278 | |||
279 | // // Find row positions for the given x/y coordinates. | ||
280 | // size_t tile_x0 = x0 / 8; | ||
281 | // size_t tile_y0 = y0 / 8; | ||
282 | // size_t tile_x1 = x1 / 8; | ||
283 | // size_t tile_y1 = y1 / 8; | ||
284 | // size_t start_col0 = x0 % 8; | ||
285 | // size_t start_col1 = x1 % 8; | ||
286 | // size_t start_row0 = y0 % 8; | ||
287 | // size_t start_row1 = y1 % 8; | ||
288 | |||
289 | // // Get a pointer to the backbuffer and the tile row. | ||
290 | // u32 *buf_top = &BACKBUF[start_row0 + (tile_x0 + tile_y0 * 32) * 8]; | ||
291 | // u32 *buf_bot = &BACKBUF[start_row1 + (tile_x0 + tile_y1 * 32) * 8]; | ||
292 | |||
293 | // size_t dx = tile_x1 - tile_x0; | ||
294 | // size_t dy = tile_y1 - tile_y0; | ||
295 | |||
296 | // memset(buf_top, 3, x1 - x0); | ||
297 | // memset(buf_bot, 3, x1 - x0); | ||
298 | |||
299 | // if (dx < 1) { | ||
300 | // dirty_tiles[tile_y0] |= 1 << tile_x0; | ||
301 | // dirty_tiles[tile_y1] |= 1 << tile_x0; | ||
302 | // } else { | ||
303 | // dirty_tiles[tile_y0] |= 1 << tile_x0; | ||
304 | // dirty_tiles[tile_y1] |= 1 << tile_x0; | ||
305 | // for (size_t i = 1; i < dx; i++) { | ||
306 | // dirty_tiles[tile_y0] |= 1 << (tile_x0 + i); | ||
307 | // dirty_tiles[tile_y1] |= 1 << (tile_x0 + i); | ||
308 | // } | ||
309 | // dirty_tiles[tile_y0] |= 1 << (tile_x0 + dx); | ||
310 | // dirty_tiles[tile_y1] |= 1 << (tile_x0 + dx); | ||
311 | // } | ||
312 | // if (dy < 1) { | ||
313 | // } else { | ||
314 | // for (size_t j = 1; j < dy; j++) { | ||
315 | // dirty_tiles[tile_y0 + j] |= 1 << tile_x0; | ||
316 | // dirty_tiles[tile_y0 + j] |= 1 << (tile_x0 + dx); | ||
317 | // } | ||
318 | // } | ||
319 | } | 290 | } |
320 | 291 | ||
321 | IWRAM_CODE | 292 | IWRAM_CODE |
@@ -345,21 +316,21 @@ draw_filled_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
345 | 316 | ||
346 | // size_t dx = x1 - x0; | 317 | // size_t dx = x1 - x0; |
347 | // size_t dy = y1 - y0; | 318 | // size_t dy = y1 - y0; |
348 | // u8 *buf = &BACKBUF[0]; | 319 | // u8 *buf = &backbuf[0]; |
349 | // memset(buf, 0x11 * clr, 16); | 320 | // memset(buf, 0x11 * clr, 16); |
350 | //for (size_t j = 0; j < 1; j++) { | 321 | //for (size_t j = 0; j < 1; j++) { |
351 | // // for (size_t i = 0; i < dx; i++) { | 322 | // // for (size_t i = 0; i < dx; i++) { |
352 | // // buf[i + j * 16] = clr; | 323 | // // buf[i + j * 16] = clr; |
353 | // // } | 324 | // // } |
354 | // // | 325 | // // |
355 | // // BACKBUF[j + 0] = 0x11111111 * clr; | 326 | // // backbuf[j + 0] = 0x11111111 * clr; |
356 | // // BACKBUF[j + 1] = 0x11111111 * clr; | 327 | // // backbuf[j + 1] = 0x11111111 * clr; |
357 | // // BACKBUF[j + 2] = 0x11111111 * clr; | 328 | // // backbuf[j + 2] = 0x11111111 * clr; |
358 | // // BACKBUF[j + 3] = 0x11111111 * clr; | 329 | // // backbuf[j + 3] = 0x11111111 * clr; |
359 | // // BACKBUF[j + 4] = 0x11111111 * clr; | 330 | // // backbuf[j + 4] = 0x11111111 * clr; |
360 | // // BACKBUF[j + 5] = 0x11111111 * clr; | 331 | // // backbuf[j + 5] = 0x11111111 * clr; |
361 | // // BACKBUF[j + 6] = 0x11111111 * clr; | 332 | // // backbuf[j + 6] = 0x11111111 * clr; |
362 | // // BACKBUF[j + 7] = 0x11111111 * clr; | 333 | // // backbuf[j + 7] = 0x11111111 * clr; |
363 | 334 | ||
364 | // buf[j + 0] = 0x1 * clr; | 335 | // buf[j + 0] = 0x1 * clr; |
365 | // buf[j + 1] = 0x1 * clr; | 336 | // buf[j + 1] = 0x1 * clr; |
@@ -370,7 +341,7 @@ draw_filled_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
370 | // // buf[j + 6] = 0x1111 * clr; | 341 | // // buf[j + 6] = 0x1111 * clr; |
371 | // // buf[j + 7] = 0x1111 * clr; | 342 | // // buf[j + 7] = 0x1111 * clr; |
372 | //} | 343 | //} |
373 | // u8 *buf = &BACKBUF[0]; | 344 | // u8 *buf = &backbuf[0]; |
374 | // buf[8 * 16 + 0] = clr; | 345 | // buf[8 * 16 + 0] = clr; |
375 | // buf[8 * 16 + 1] = clr; | 346 | // buf[8 * 16 + 1] = clr; |
376 | // buf[8 * 16 + 2] = clr; | 347 | // buf[8 * 16 + 2] = clr; |
@@ -404,7 +375,7 @@ draw_filled_rect(size_t x0, size_t y0, size_t x1, size_t y1, u8 clr) { | |||
404 | 375 | ||
405 | // // Get a pointer to the backbuffer and the tile row. | 376 | // // Get a pointer to the backbuffer and the tile row. |
406 | // size_t pos = start_row + (tile_x + tile_y * 32) * 8; | 377 | // size_t pos = start_row + (tile_x + tile_y * 32) * 8; |
407 | // u32 *backbuffer = &BACKBUF[pos]; | 378 | // u32 *backbuffer = &backbuf[pos]; |
408 | // u32 *row = tile; | 379 | // u32 *row = tile; |
409 | 380 | ||
410 | // // This will blend all colors weirdly if using tiles that contain colors | 381 | // // This will blend all colors weirdly if using tiles that contain colors |
@@ -474,20 +445,18 @@ void | |||
474 | flip_buffer(void) { | 445 | flip_buffer(void) { |
475 | if (backbuf == BUF_0) { | 446 | if (backbuf == BUF_0) { |
476 | backbuf = BUF_1; | 447 | backbuf = BUF_1; |
477 | DISP_CTRL = DISP_MODE_0 | DISP_BG_1 | DISP_OBJ; | 448 | BG_CTRL(0) = BG_CHARBLOCK(CB_0) | BG_SCREENBLOCK(SB_0) | BG_PRIORITY(0); |
478 | BG_CTRL(0) = BG_CHARBLOCK(CB_0) | BG_SCREENBLOCK(SB_0) | BG_PRIORITY(2); | 449 | BG_CTRL(1) = BG_CHARBLOCK(CB_1) | BG_SCREENBLOCK(SB_1) | BG_PRIORITY(2); |
479 | BG_CTRL(1) = BG_CHARBLOCK(CB_1) | BG_SCREENBLOCK(SB_1) | BG_PRIORITY(1); | ||
480 | } else { | 450 | } else { |
481 | backbuf = BUF_0; | 451 | backbuf = BUF_0; |
482 | DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_OBJ; | 452 | BG_CTRL(0) = BG_CHARBLOCK(CB_0) | BG_SCREENBLOCK(SB_0) | BG_PRIORITY(2); |
483 | BG_CTRL(0) = BG_CHARBLOCK(CB_0) | BG_SCREENBLOCK(SB_0) | BG_PRIORITY(1); | 453 | BG_CTRL(1) = BG_CHARBLOCK(CB_1) | BG_SCREENBLOCK(SB_1) | BG_PRIORITY(0); |
484 | BG_CTRL(1) = BG_CHARBLOCK(CB_1) | BG_SCREENBLOCK(SB_1) | BG_PRIORITY(2); | ||
485 | } | 454 | } |
486 | // TODO: Copying all tiles for now. Study if it's better to use dirty_tiles | 455 | // TODO: Copying all tiles for now. Study if it's better to use dirty_tiles |
487 | // or dirty_lines. | 456 | // or dirty_lines. |
488 | // Copy dirty tiles from the backbuffer to the frontbuffer. | 457 | // Copy dirty tiles from the backbuffer to the frontbuffer. |
489 | // Tile *dst = FRONTBUF; | 458 | // Tile *dst = FRONTBUF; |
490 | // Tile *src = BACKBUF; | 459 | // Tile *src = backbuf; |
491 | // for (size_t j = 0; j < 20; ++j) { | 460 | // for (size_t j = 0; j < 20; ++j) { |
492 | // // if (dirty_tiles[j] == 0) { | 461 | // // if (dirty_tiles[j] == 0) { |
493 | // // continue; | 462 | // // continue; |
@@ -647,30 +616,43 @@ txt_drawc(char c, size_t x, size_t y, u8 clr) { | |||
647 | void | 616 | void |
648 | renderer_init(void) { | 617 | renderer_init(void) { |
649 | // Initialize display mode and bg palette. | 618 | // Initialize display mode and bg palette. |
650 | DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1 | DISP_OBJ; | 619 | DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1 | DISP_BG_2 | DISP_OBJ; |
620 | // DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1 | DISP_OBJ; | ||
621 | // TODO: black/grey background to block font/back buffers? | ||
651 | 622 | ||
652 | // Clear VRAM. | 623 | // Clear VRAM. |
653 | dma_fill(MEM_VRAM, 0, KB(96), 3); | 624 | dma_fill(MEM_VRAM, 0, KB(96), 3); |
654 | 625 | ||
655 | |||
656 | // Initialize backgrounds. | 626 | // Initialize backgrounds. |
657 | BG_CTRL(0) = BG_CHARBLOCK(CB_0) | BG_SCREENBLOCK(SB_0) | BG_PRIORITY(1); | 627 | BG_CTRL(0) = BG_CHARBLOCK(CB_0) | BG_SCREENBLOCK(SB_0) | BG_PRIORITY(0); |
628 | BG_CTRL(2) = BG_CHARBLOCK(CB_2) | BG_SCREENBLOCK(SB_2) | BG_PRIORITY(1); | ||
658 | BG_CTRL(1) = BG_CHARBLOCK(CB_1) | BG_SCREENBLOCK(SB_1) | BG_PRIORITY(2); | 629 | BG_CTRL(1) = BG_CHARBLOCK(CB_1) | BG_SCREENBLOCK(SB_1) | BG_PRIORITY(2); |
659 | 630 | ||
660 | DISP_CTRL = DISP_MODE_0 | DISP_OBJ; | ||
661 | |||
662 | // Initialize background memory map for frontbuffer. | 631 | // Initialize background memory map for frontbuffer. |
663 | // for (size_t i = 0; i < 32 * 20; ++i) { | 632 | // for (size_t i = 0; i < 32 * 20; ++i) { |
664 | // TILE_MAP[i] = i; | 633 | // TILE_MAP[i] = i; |
665 | // } | 634 | // } |
666 | u16 *mem_map_fg = SCREENBLOCK_MEM[SB_0]; | 635 | u16 *mem_map_fg = SCREENBLOCK_MEM[SB_0]; |
667 | u16 *mem_map_bg = SCREENBLOCK_MEM[SB_1]; | 636 | u16 *mem_map_bg = SCREENBLOCK_MEM[SB_1]; |
637 | u16 *mem_map_clr = SCREENBLOCK_MEM[SB_2]; | ||
668 | size_t k = 0; | 638 | size_t k = 0; |
669 | for (size_t i = 0; i < 32 * 20; ++i, ++k) { | 639 | for (size_t i = 0; i < 32 * 20; ++i, ++k) { |
670 | mem_map_fg[i] = k; | 640 | mem_map_fg[i] = k; |
671 | mem_map_bg[i] = k + 32 * 4; | 641 | mem_map_bg[i] = k + 32 * 4; |
642 | mem_map_clr[i] = 0; | ||
672 | } | 643 | } |
673 | 644 | ||
645 | // FIXME: clean this up. | ||
646 | u32 *clr_tile =((u32*)(MEM_VRAM) + 0xC000 / 4); | ||
647 | clr_tile[0] = 0x22222222; | ||
648 | clr_tile[1] = 0x22222222; | ||
649 | clr_tile[2] = 0x22222222; | ||
650 | clr_tile[3] = 0x22222222; | ||
651 | clr_tile[4] = 0x22222222; | ||
652 | clr_tile[5] = 0x22222222; | ||
653 | clr_tile[6] = 0x22222222; | ||
654 | clr_tile[7] = 0x22222222; | ||
655 | |||
674 | // Initialize default palette. | 656 | // Initialize default palette. |
675 | PAL_BUFFER_BG[0] = COLOR_BLACK; | 657 | PAL_BUFFER_BG[0] = COLOR_BLACK; |
676 | PAL_BUFFER_BG[1] = COLOR_WHITE; | 658 | PAL_BUFFER_BG[1] = COLOR_WHITE; |