diff options
author | Bad Diode <bd@badd10de.dev> | 2023-04-22 21:12:14 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2023-04-22 21:12:14 +0200 |
commit | deb9c48fbd3dc5854de4ae3a04dc999029c10ae0 (patch) | |
tree | 53d34672d676c5f9b9b56b2b185c511470c068a0 /src/text/text.h | |
parent | d4fe4d95f105d8b9b47d26264c4876cbf4095a5d (diff) | |
download | stepper-deb9c48fbd3dc5854de4ae3a04dc999029c10ae0.tar.gz stepper-deb9c48fbd3dc5854de4ae3a04dc999029c10ae0.zip |
Add new renderer and prepare for render overhaul
Diffstat (limited to 'src/text/text.h')
-rw-r--r-- | src/text/text.h | 115 |
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 | ||
6 | typedef void (*TxtDrawc)(char c, size_t x, size_t y, u8 clr); | ||
9 | typedef struct TextEngine { | 7 | typedef 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 | ||
26 | static TextEngine text_engine = {0}; | 20 | static TextEngine text_engine = {0}; |
@@ -28,20 +22,11 @@ static TextEngine text_engine = {0}; | |||
28 | // Initializes the text engine. | 22 | // Initializes the text engine. |
29 | static inline | 23 | static inline |
30 | void | 24 | void |
31 | txt_init(u32 *font_data, u16 *font_tilemap, u16 font_offset) { | 25 | txt_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) { | |||
76 | static inline | 61 | static inline |
77 | void | 62 | void |
78 | txt_clear_line(void) { | 63 | txt_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. |
88 | static inline | 70 | static inline |
89 | void | 71 | void |
90 | txt_clear_screen(void) { | 72 | txt_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 | ||
89 | static inline | ||
90 | void | ||
91 | txt_color(u8 clr) { | ||
92 | text_engine.color = clr; | ||
93 | } | ||
94 | |||
95 | static inline | ||
96 | void | ||
97 | txt_spacing(u8 spacing) { | ||
98 | text_engine.spacing = spacing; | ||
99 | } | ||
100 | |||
101 | // Renders the contents of the scrollback buffer to the screen. | ||
102 | void | ||
103 | txt_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. |
110 | static inline | 122 | static inline |
111 | void | 123 | void |
112 | txt_draws(char *msg, size_t x, size_t y, size_t spacing, u8 clr) { | 124 | txt_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 | ||
122 | static inline | ||
123 | void | ||
124 | txt_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 |