From deb9c48fbd3dc5854de4ae3a04dc999029c10ae0 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sat, 22 Apr 2023 21:12:14 +0200 Subject: Add new renderer and prepare for render overhaul --- src/text/text.h | 115 +++++++++++++++++++++++--------------------------------- 1 file changed, 48 insertions(+), 67 deletions(-) (limited to 'src/text/text.h') diff --git a/src/text/text.h b/src/text/text.h index 0bcf090..ab525d4 100644 --- a/src/text/text.h +++ b/src/text/text.h @@ -2,10 +2,8 @@ #define TEXT_H #include "posprintf.h" -#include "renderer.h" - -#include "font.h" +typedef void (*TxtDrawc)(char c, size_t x, size_t y, u8 clr); typedef struct TextEngine { // Cursor for tiled text mode The X and Y positions correspond to the tile // X and Y starting from the top left of the screen. For a 240x160 screen, @@ -13,14 +11,10 @@ typedef struct TextEngine { size_t cursor_x; size_t cursor_y; - // Memory location of font tile data and tilemap. Likely located on the - // VRAM. - u32 *font_data; - u16 *font_tilemap; - - // The font map for tiled text. Writing the character stored in this - // position on the tilemap will show a character on the screen. - u16 font_map[256]; + u8 buffer[30 * 20]; + u8 spacing; + u8 color; + TxtDrawc drawc; } TextEngine; static TextEngine text_engine = {0}; @@ -28,20 +22,11 @@ static TextEngine text_engine = {0}; // Initializes the text engine. static inline void -txt_init(u32 *font_data, u16 *font_tilemap, u16 font_offset) { - // Load font data into VRAM. - unpack_tiles(&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) { - text_engine.font_map[i] = font_offset + i; - } - +txt_init(TxtDrawc drawc) { // Initialize remaining variables. - text_engine.font_data = font_data; - text_engine.font_tilemap = font_tilemap; + text_engine.spacing = 8; + text_engine.color = 1; + text_engine.drawc = drawc; } // Writes a message to the tile text background. @@ -59,7 +44,7 @@ txt_puts(char *msg) { } else { int x = text_engine.cursor_x; int y = text_engine.cursor_y; - text_engine.font_tilemap[x + 32 * y] = text_engine.font_map[(u16)c]; + text_engine.buffer[x + 30 * y] = c; text_engine.cursor_x += 1; if (text_engine.cursor_x >= 30) { text_engine.cursor_x = 0; @@ -76,18 +61,15 @@ txt_puts(char *msg) { static inline void txt_clear_line(void) { - for (size_t i = 0; i < 30; ++i) { - int x = text_engine.cursor_x; - int y = text_engine.cursor_y; - text_engine.font_tilemap[x + 32 * y] = text_engine.font_map[0]; - } + dma_fill(text_engine.buffer, 0, sizeof(text_engine.buffer), 3); text_engine.cursor_x = 0; + text_engine.cursor_y = 0; } // Clears the screen on the tile text mode. static inline void -txt_clear_screen(void) { +txt_clear(void) { for (size_t j = 0; j < 20; ++j) { text_engine.cursor_y = j; txt_clear_line(); @@ -104,30 +86,49 @@ txt_position(size_t tile_x, size_t tile_y) { text_engine.cursor_y = tile_y; } +static inline +void +txt_color(u8 clr) { + text_engine.color = clr; +} + +static inline +void +txt_spacing(u8 spacing) { + text_engine.spacing = spacing; +} + +// Renders the contents of the scrollback buffer to the screen. +void +txt_render(void) { + for (size_t y = 0; y < 20; y++) { + for (size_t x = 0; x < 30; x++) { + size_t pos = x + y * 30; + if (text_engine.buffer[pos] == 0) { + continue; + } + text_engine.drawc( + text_engine.buffer[pos], + x * text_engine.spacing, + y * text_engine.spacing, + text_engine.color); + } + } +} + // Draws a message where the first character's top-left corner begins at the // given x and y position. The character spacing can be adjusted, but beware of // color merging issues. static inline void -txt_draws(char *msg, size_t x, size_t y, size_t spacing, u8 clr) { +txt_draws(char *msg, size_t x, size_t y, u8 clr) { + size_t i = 0; while (*msg) { char c = *msg++; - Tile *tile = FONT_DATA; - tile += c; - draw_tile(x, y, tile, clr, true); - x += spacing; + text_engine.drawc(c, x + i++ * text_engine.spacing, y, clr); } } -static inline -void -txt_drawc(char c, size_t x, size_t y, size_t spacing, u8 clr) { - Tile *tile = FONT_DATA; - tile += c; - draw_tile(x, y, tile, clr, true); - x += spacing; -} - // Print text to the screen with formatting. #define txt_printf(msg, ...) \ { \ @@ -138,31 +139,11 @@ txt_drawc(char c, size_t x, size_t y, size_t spacing, u8 clr) { // Draws text to the screen with formatting starting on the x and y position and // with custom character spacing. -#define txt_drawf(msg, x, y, s, c, ...) \ - { \ - char buf[256] = {0}; \ - posprintf(buf, msg, ##__VA_ARGS__); \ - txt_draws(buf, x, y, s, c); \ - } - -// Small font is located after the initial ASCII characters, and only supports -// lowercase characters. -// NOTE: Slow, we should do this with a LUT. -#define txt_drawf_small(msg, x, y, s, c, ...) \ +#define txt_drawf(msg, x, y, c, ...) \ { \ char buf[256] = {0}; \ posprintf(buf, msg, ##__VA_ARGS__); \ - for (size_t i = 0; i < 256; i++) { \ - if (buf[i] == 0) { \ - break; \ - } \ - if (buf[i] < 'a') { \ - buf[i] += 16 * 6; \ - } else { \ - buf[i] += 16 * 4; \ - }\ - } \ - txt_draws(buf, x, y, s, c); \ + txt_draws(buf, x, y, c); \ } #endif // TEXT_H -- cgit v1.2.1