aboutsummaryrefslogtreecommitdiffstats
path: root/src/text/text.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/text/text.h')
-rw-r--r--src/text/text.h115
1 files changed, 48 insertions, 67 deletions
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 @@
2#define TEXT_H 2#define TEXT_H
3 3
4#include "posprintf.h" 4#include "posprintf.h"
5#include "renderer.h"
6
7#include "font.h"
8 5
6typedef void (*TxtDrawc)(char c, size_t x, size_t y, u8 clr);
9typedef struct TextEngine { 7typedef struct TextEngine {
10 // Cursor for tiled text mode The X and Y positions correspond to the tile 8 // Cursor for tiled text mode The X and Y positions correspond to the tile
11 // X and Y starting from the top left of the screen. For a 240x160 screen, 9 // X and Y starting from the top left of the screen. For a 240x160 screen,
@@ -13,14 +11,10 @@ typedef struct TextEngine {
13 size_t cursor_x; 11 size_t cursor_x;
14 size_t cursor_y; 12 size_t cursor_y;
15 13
16 // Memory location of font tile data and tilemap. Likely located on the 14 u8 buffer[30 * 20];
17 // VRAM. 15 u8 spacing;
18 u32 *font_data; 16 u8 color;
19 u16 *font_tilemap; 17 TxtDrawc drawc;
20
21 // The font map for tiled text. Writing the character stored in this
22 // position on the tilemap will show a character on the screen.
23 u16 font_map[256];
24} TextEngine; 18} TextEngine;
25 19
26static TextEngine text_engine = {0}; 20static TextEngine text_engine = {0};
@@ -28,20 +22,11 @@ static TextEngine text_engine = {0};
28// Initializes the text engine. 22// Initializes the text engine.
29static inline 23static inline
30void 24void
31txt_init(u32 *font_data, u16 *font_tilemap, u16 font_offset) { 25txt_init(TxtDrawc drawc) {
32 // Load font data into VRAM.
33 unpack_tiles(&font, font_data, 256);
34
35 // Initialize the font map translation table. That way we can write
36 // a character on the text background layer with:
37 // FONT_TILEMAP[tile_x + 32 * tile_y] = font_map['A'];
38 for (size_t i = 0; i < 256; ++i) {
39 text_engine.font_map[i] = font_offset + i;
40 }
41
42 // Initialize remaining variables. 26 // Initialize remaining variables.
43 text_engine.font_data = font_data; 27 text_engine.spacing = 8;
44 text_engine.font_tilemap = font_tilemap; 28 text_engine.color = 1;
29 text_engine.drawc = drawc;
45} 30}
46 31
47// Writes a message to the tile text background. 32// Writes a message to the tile text background.
@@ -59,7 +44,7 @@ txt_puts(char *msg) {
59 } else { 44 } else {
60 int x = text_engine.cursor_x; 45 int x = text_engine.cursor_x;
61 int y = text_engine.cursor_y; 46 int y = text_engine.cursor_y;
62 text_engine.font_tilemap[x + 32 * y] = text_engine.font_map[(u16)c]; 47 text_engine.buffer[x + 30 * y] = c;
63 text_engine.cursor_x += 1; 48 text_engine.cursor_x += 1;
64 if (text_engine.cursor_x >= 30) { 49 if (text_engine.cursor_x >= 30) {
65 text_engine.cursor_x = 0; 50 text_engine.cursor_x = 0;
@@ -76,18 +61,15 @@ txt_puts(char *msg) {
76static inline 61static inline
77void 62void
78txt_clear_line(void) { 63txt_clear_line(void) {
79 for (size_t i = 0; i < 30; ++i) { 64 dma_fill(text_engine.buffer, 0, sizeof(text_engine.buffer), 3);
80 int x = text_engine.cursor_x;
81 int y = text_engine.cursor_y;
82 text_engine.font_tilemap[x + 32 * y] = text_engine.font_map[0];
83 }
84 text_engine.cursor_x = 0; 65 text_engine.cursor_x = 0;
66 text_engine.cursor_y = 0;
85} 67}
86 68
87// Clears the screen on the tile text mode. 69// Clears the screen on the tile text mode.
88static inline 70static inline
89void 71void
90txt_clear_screen(void) { 72txt_clear(void) {
91 for (size_t j = 0; j < 20; ++j) { 73 for (size_t j = 0; j < 20; ++j) {
92 text_engine.cursor_y = j; 74 text_engine.cursor_y = j;
93 txt_clear_line(); 75 txt_clear_line();
@@ -104,30 +86,49 @@ txt_position(size_t tile_x, size_t tile_y) {
104 text_engine.cursor_y = tile_y; 86 text_engine.cursor_y = tile_y;
105} 87}
106 88
89static inline
90void
91txt_color(u8 clr) {
92 text_engine.color = clr;
93}
94
95static inline
96void
97txt_spacing(u8 spacing) {
98 text_engine.spacing = spacing;
99}
100
101// Renders the contents of the scrollback buffer to the screen.
102void
103txt_render(void) {
104 for (size_t y = 0; y < 20; y++) {
105 for (size_t x = 0; x < 30; x++) {
106 size_t pos = x + y * 30;
107 if (text_engine.buffer[pos] == 0) {
108 continue;
109 }
110 text_engine.drawc(
111 text_engine.buffer[pos],
112 x * text_engine.spacing,
113 y * text_engine.spacing,
114 text_engine.color);
115 }
116 }
117}
118
107// Draws a message where the first character's top-left corner begins at the 119// Draws a message where the first character's top-left corner begins at the
108// given x and y position. The character spacing can be adjusted, but beware of 120// given x and y position. The character spacing can be adjusted, but beware of
109// color merging issues. 121// color merging issues.
110static inline 122static inline
111void 123void
112txt_draws(char *msg, size_t x, size_t y, size_t spacing, u8 clr) { 124txt_draws(char *msg, size_t x, size_t y, u8 clr) {
125 size_t i = 0;
113 while (*msg) { 126 while (*msg) {
114 char c = *msg++; 127 char c = *msg++;
115 Tile *tile = FONT_DATA; 128 text_engine.drawc(c, x + i++ * text_engine.spacing, y, clr);
116 tile += c;
117 draw_tile(x, y, tile, clr, true);
118 x += spacing;
119 } 129 }
120} 130}
121 131
122static inline
123void
124txt_drawc(char c, size_t x, size_t y, size_t spacing, u8 clr) {
125 Tile *tile = FONT_DATA;
126 tile += c;
127 draw_tile(x, y, tile, clr, true);
128 x += spacing;
129}
130
131// Print text to the screen with formatting. 132// Print text to the screen with formatting.
132#define txt_printf(msg, ...) \ 133#define txt_printf(msg, ...) \
133 { \ 134 { \
@@ -138,31 +139,11 @@ txt_drawc(char c, size_t x, size_t y, size_t spacing, u8 clr) {
138 139
139// Draws text to the screen with formatting starting on the x and y position and 140// Draws text to the screen with formatting starting on the x and y position and
140// with custom character spacing. 141// with custom character spacing.
141#define txt_drawf(msg, x, y, s, c, ...) \ 142#define txt_drawf(msg, x, y, c, ...) \
142 { \
143 char buf[256] = {0}; \
144 posprintf(buf, msg, ##__VA_ARGS__); \
145 txt_draws(buf, x, y, s, c); \
146 }
147
148// Small font is located after the initial ASCII characters, and only supports
149// lowercase characters.
150// NOTE: Slow, we should do this with a LUT.
151#define txt_drawf_small(msg, x, y, s, c, ...) \
152 { \ 143 { \
153 char buf[256] = {0}; \ 144 char buf[256] = {0}; \
154 posprintf(buf, msg, ##__VA_ARGS__); \ 145 posprintf(buf, msg, ##__VA_ARGS__); \
155 for (size_t i = 0; i < 256; i++) { \ 146 txt_draws(buf, x, y, c); \
156 if (buf[i] == 0) { \
157 break; \
158 } \
159 if (buf[i] < 'a') { \
160 buf[i] += 16 * 6; \
161 } else { \
162 buf[i] += 16 * 4; \
163 }\
164 } \
165 txt_draws(buf, x, y, s, c); \
166 } 147 }
167 148
168#endif // TEXT_H 149#endif // TEXT_H