From 215465df74a6065f4b0fdf199b8b04454520a398 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 2 Jun 2021 20:20:23 +0200 Subject: Update the renderer to support a text layer --- src/renderer.c | 71 +++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 23 deletions(-) (limited to 'src/renderer.c') diff --git a/src/renderer.c b/src/renderer.c index 9fe55b2..ec54411 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -1,14 +1,28 @@ -// TODO: For now we pack front/backbuffers together but this make it so that we -// can only use 2 backgrounds. Instead we can move the backbuffer to the end of -// the VRAM. This will give us 3 backgrounds but eats into the available memory -// for sprites but should be fine for non sprite intensive applications. -#define FRONTBUFFER ((u32*)(MEM_VRAM)) -#define BACKBUFFER ((u32*)(MEM_VRAM + KB(96) - KB(20))) +#include "bd-font.c" + +// The frontbuffer is located at the beginning of the VRAM, and requires 20KB of +// video memory for 32 * 20 tiles at 4bpp. +#define FRONTBUF ((u32*)(MEM_VRAM)) // Adjust both of these if the location of the map changes. Each screnblock -// requires 2K. -#define FRONTBUFFER_TILEMAP ((u16*)(MEM_VRAM + KB(20))) -#define FRONTBUFFER_SCREENBLOCK 10 +// requires less than 2KB. +#define FRONTBUF_TILEMAP ((u16*)(MEM_VRAM + KB(20))) +#define FRONTBUF_SB 10 + +// The backbuffer is located at the end of the VRAM. This can allow us to use +// more backgrounds but eats into the available memory for sprites. This should +// be fine for non sprite intensive applications. If more sprite memory is +// needed, the backbuffer can be located at the end of the background memory +// instead (64KB - 20KB). +#define BACKBUF ((u32*)(MEM_VRAM + KB(96) - KB(20))) + +// The font data is located at the end of the frontbuffer memory, after the tile +// map and requires 8KB for 256 8x8 characters at 4bpp. This, along with the +// tilemap information allow us to store the frontbuffer and font for a text +// background in the first 2 charblocks (32KB). +#define FONT_DATA ((u32*)(MEM_VRAM + KB(22))) +#define FONT_TILEMAP ((u16*)(MEM_VRAM + KB(30))) +#define FONT_SB 15 static u32 dirty_tiles[21] = {0}; @@ -29,7 +43,7 @@ draw_pixel(u16 x, u16 y, u8 color) { // Update backbuffer. size_t shift = start_col * sizeof(u32); - BACKBUFFER[pos] = (BACKBUFFER[pos] & ~(0xF << shift)) | color << shift; + BACKBUF[pos] = (BACKBUF[pos] & ~(0xF << shift)) | color << shift; // Mark tile as dirty. dirty_tiles[tile_y] |= 1 << tile_x; @@ -39,8 +53,8 @@ IWRAM_CODE void flip_buffer(void) { // Copy dirty tiles from the backbuffer to the frontbuffer. - Tile *dst = FRONTBUFFER; - Tile *src = BACKBUFFER; + Tile *dst = FRONTBUF; + Tile *src = BACKBUF; for (size_t j = 0; j < 20; ++j) { if (dirty_tiles[j] == 0) { continue; @@ -54,19 +68,23 @@ flip_buffer(void) { } } +static u16 font_map[256] = {0}; + void renderer_init(void) { // Initialize display mode and bg palette. - DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_OBJ; + DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1 | DISP_OBJ; // Initialize backgrounds. - BG_CTRL(0) = BG_CHARBLOCK(0) | BG_SCREENBLOCK(FRONTBUFFER_SCREENBLOCK); + BG_CTRL(0) = BG_CHARBLOCK(0) | BG_SCREENBLOCK(FRONTBUF_SB) | BG_PRIORITY(1); + BG_CTRL(1) = BG_CHARBLOCK(1) | BG_SCREENBLOCK(FONT_SB) | BG_PRIORITY(0); - // TODO: Initialize other backgrounds if needed. - - // Use DMA to clear front and back buffers. - dma_fill(FRONTBUFFER, 0, KB(20), 3); - dma_fill(BACKBUFFER, 0, KB(20), 3); + // Use DMA to clear front and back buffers as well as the font memory map. + dma_fill(FRONTBUF, 0, KB(20), 3); + dma_fill(FRONTBUF_TILEMAP, 0, KB(2), 3); + dma_fill(FONT_DATA, 0, KB(8), 3); + dma_fill(FONT_TILEMAP, 0, KB(2), 3); + dma_fill(BACKBUF, 0, KB(20), 3); // Initialize default palette. PAL_BUFFER_BG[0] = COLOR_BLACK; @@ -76,11 +94,18 @@ renderer_init(void) { PAL_BUFFER_BG[4] = COLOR_CYAN; PAL_BUFFER_BG[5] = COLOR_GREY; - // Initialize background memory map. + // Initialize background memory map for frontbuffer and font backgorund. for (size_t i = 0; i < 32 * 20; ++i) { - FRONTBUFFER_TILEMAP[i] = i; + FRONTBUF_TILEMAP[i] = i; } -// // Load font data into VRAM. -// unpack_tiles(&bd_font, FONT_DATA, 256); + // Load font data into VRAM. + unpack_tiles(&bd_font, FONT_DATA, 256); + + // Initialize the font map translation table. That way we can write + // a character on the text background layer with: + // FONT_TILEMAP[tile_x + 32 * tile_y] = font_map['A']; + for (size_t i = 0; i < 256; ++i) { + font_map[i] = 192 + i; + } } -- cgit v1.2.1