diff options
author | Bad Diode <bd@badd10de.dev> | 2021-05-19 14:26:30 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-05-19 14:26:30 +0200 |
commit | 60684bb15f5c68eb8248673da48cc4469537ffc9 (patch) | |
tree | fd6901719ab8121b9bf8e0c98700a43eff198652 | |
parent | fd5dede600bcaf8d5c16963544512b2e0ba68586 (diff) | |
download | uxngba-60684bb15f5c68eb8248673da48cc4469537ffc9.tar.gz uxngba-60684bb15f5c68eb8248673da48cc4469537ffc9.zip |
Add a new console drawing mode
-rw-r--r-- | src/main.c | 33 | ||||
-rw-r--r-- | src/text.h | 68 | ||||
-rw-r--r-- | src/uxn/devices/ppu.c | 6 | ||||
-rw-r--r-- | src/uxn/uxn.c | 2 |
4 files changed, 95 insertions, 14 deletions
@@ -10,8 +10,11 @@ | |||
10 | #include "uxn/uxn.c" | 10 | #include "uxn/uxn.c" |
11 | #include "uxn/devices/ppu.h" | 11 | #include "uxn/devices/ppu.h" |
12 | #include "uxn/devices/ppu.c" | 12 | #include "uxn/devices/ppu.c" |
13 | // #include "uxn/roms/dvd.c" | 13 | // #include "uxn/roms/console.c" |
14 | #include "uxn/roms/automata.c" | 14 | // #include "uxn/roms/proportional_fonts.c" |
15 | #include "uxn/roms/dvd.c" | ||
16 | // #include "uxn/roms/automata.c" | ||
17 | // #include "uxn/roms/life.c" | ||
15 | 18 | ||
16 | /* | 19 | /* |
17 | Copyright (c) 2021 Bad Diode | 20 | Copyright (c) 2021 Bad Diode |
@@ -24,6 +27,8 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |||
24 | WITH REGARD TO THIS SOFTWARE. | 27 | WITH REGARD TO THIS SOFTWARE. |
25 | */ | 28 | */ |
26 | 29 | ||
30 | static size_t drawing_cycles = 0; | ||
31 | |||
27 | static Ppu ppu; | 32 | static Ppu ppu; |
28 | u8 reqdraw = 0; | 33 | u8 reqdraw = 0; |
29 | static Device *devscreen; | 34 | static Device *devscreen; |
@@ -63,6 +68,7 @@ system_talk(Device *d, Uint8 b0, Uint8 w) | |||
63 | 68 | ||
64 | void | 69 | void |
65 | screen_talk(Device *d, Uint8 b0, Uint8 w) { | 70 | screen_talk(Device *d, Uint8 b0, Uint8 w) { |
71 | profile_start(); | ||
66 | if(w && b0 == 0xe) { | 72 | if(w && b0 == 0xe) { |
67 | Uint16 x = mempeek16(d->dat, 0x8); | 73 | Uint16 x = mempeek16(d->dat, 0x8); |
68 | Uint16 y = mempeek16(d->dat, 0xa); | 74 | Uint16 y = mempeek16(d->dat, 0xa); |
@@ -78,6 +84,8 @@ screen_talk(Device *d, Uint8 b0, Uint8 w) { | |||
78 | } | 84 | } |
79 | reqdraw = 1; | 85 | reqdraw = 1; |
80 | } | 86 | } |
87 | int cycles = profile_stop(); | ||
88 | drawing_cycles += cycles; | ||
81 | } | 89 | } |
82 | 90 | ||
83 | void | 91 | void |
@@ -90,7 +98,7 @@ init_uxn(Uxn *u) { | |||
90 | 98 | ||
91 | // Prepare devices. | 99 | // Prepare devices. |
92 | portuxn(u, 0x0, "system", system_talk); | 100 | portuxn(u, 0x0, "system", system_talk); |
93 | portuxn(u, 0x1, "---", nil_talk); | 101 | portuxn(u, 0x1, "console", console_talk); |
94 | devscreen = portuxn(u, 0x2, "screen", screen_talk); | 102 | devscreen = portuxn(u, 0x2, "screen", screen_talk); |
95 | portuxn(u, 0x3, "---", nil_talk); | 103 | portuxn(u, 0x3, "---", nil_talk); |
96 | portuxn(u, 0x4, "---", nil_talk); | 104 | portuxn(u, 0x4, "---", nil_talk); |
@@ -114,9 +122,20 @@ int main(void) { | |||
114 | irq_init(); | 122 | irq_init(); |
115 | irs_set(IRQ_VBLANK, irs_stub); | 123 | irs_set(IRQ_VBLANK, irs_stub); |
116 | 124 | ||
125 | // Initialize text engine. | ||
126 | txt_init_bitmap( | ||
127 | TXT_MODE_HYBRID, | ||
128 | (Font){ | ||
129 | .data = bd_font, | ||
130 | .char_height = 8, | ||
131 | .char_width = 8, | ||
132 | }); | ||
133 | txt_position(0,0); | ||
134 | |||
117 | // Initialize VM. | 135 | // Initialize VM. |
118 | Uxn u = {0}; | 136 | Uxn u = {0}; |
119 | init_uxn(&u); | 137 | init_uxn(&u); |
138 | txt_clear_screen(); | ||
120 | evaluxn(&u, 0x0100); | 139 | evaluxn(&u, 0x0100); |
121 | 140 | ||
122 | // Main loop. | 141 | // Main loop. |
@@ -125,7 +144,13 @@ int main(void) { | |||
125 | bios_vblank_wait(); | 144 | bios_vblank_wait(); |
126 | poll_keys(); | 145 | poll_keys(); |
127 | evaluxn(&u, mempeek16(devscreen->dat, 0)); | 146 | evaluxn(&u, mempeek16(devscreen->dat, 0)); |
128 | }; | 147 | txt_position(0,0); |
148 | txt_clear_screen(); | ||
149 | txt_printf("FRAME: %d\n", frame_counter); | ||
150 | txt_printf("DRAWING: %d\n", drawing_cycles); | ||
151 | drawing_cycles = 0; | ||
152 | frame_counter++; | ||
153 | } | ||
129 | 154 | ||
130 | return 0; | 155 | return 0; |
131 | } | 156 | } |
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | typedef enum { | 10 | typedef enum { |
11 | TXT_MODE_TILED_BG, | 11 | TXT_MODE_TILED_BG, |
12 | TXT_MODE_HYBRID, | ||
12 | TXT_MODE_MODE3, | 13 | TXT_MODE_MODE3, |
13 | } TextMode; | 14 | } TextMode; |
14 | 15 | ||
@@ -115,6 +116,36 @@ txt_putc_m3(char c) { | |||
115 | } | 116 | } |
116 | 117 | ||
117 | void | 118 | void |
119 | txt_putc_hybrid(char c) { | ||
120 | if (c == '\0') { | ||
121 | return; | ||
122 | } | ||
123 | if (c == '\n') { | ||
124 | text_engine.cursor_x = 0; | ||
125 | text_engine.cursor_y++; | ||
126 | } else { | ||
127 | u8 idx = text_engine.font.char_map[(int)c] * 2; | ||
128 | u32 *packed_char = text_engine.font.data; | ||
129 | packed_char += idx; | ||
130 | Tile tile = {0}; | ||
131 | unpack_tiles(packed_char, &tile, 1); | ||
132 | int x = text_engine.cursor_x; | ||
133 | int y = text_engine.cursor_y; | ||
134 | // DEBUG: should be on the text struct. | ||
135 | Tile *buf = &TILE_MEM[0]; | ||
136 | buf[x + y * 30] = tile; | ||
137 | text_engine.cursor_x += 1; | ||
138 | if (text_engine.cursor_x >= 30) { | ||
139 | text_engine.cursor_x = 0; | ||
140 | text_engine.cursor_y++; | ||
141 | } | ||
142 | } | ||
143 | if (text_engine.cursor_y >= 20) { | ||
144 | text_engine.cursor_y = 0; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | void | ||
118 | txt_putc(char c) { | 149 | txt_putc(char c) { |
119 | switch (text_engine.mode) { | 150 | switch (text_engine.mode) { |
120 | case TXT_MODE_TILED_BG: { | 151 | case TXT_MODE_TILED_BG: { |
@@ -123,6 +154,9 @@ txt_putc(char c) { | |||
123 | case TXT_MODE_MODE3: { | 154 | case TXT_MODE_MODE3: { |
124 | txt_putc_m3(c); | 155 | txt_putc_m3(c); |
125 | } break; | 156 | } break; |
157 | case TXT_MODE_HYBRID: { | ||
158 | txt_putc_hybrid(c); | ||
159 | } break; | ||
126 | } | 160 | } |
127 | } | 161 | } |
128 | 162 | ||
@@ -164,9 +198,6 @@ txt_init_tile(size_t bg, Font font, size_t cb_idx) { | |||
164 | 198 | ||
165 | void | 199 | void |
166 | txt_init_bitmap(TextMode mode, Font font) { | 200 | txt_init_bitmap(TextMode mode, Font font) { |
167 | // NOTE: Only mode 3 is currently supported | ||
168 | assert(mode == TXT_MODE_MODE3); | ||
169 | |||
170 | // If font_map is NULL, initialize the standard 0-255 character map. | 201 | // If font_map is NULL, initialize the standard 0-255 character map. |
171 | if (font.char_map == NULL) { | 202 | if (font.char_map == NULL) { |
172 | for (size_t i = 0; i < 256; ++i) { | 203 | for (size_t i = 0; i < 256; ++i) { |
@@ -201,22 +232,41 @@ txt_printf(char *msg, ...) { | |||
201 | txt_puts(buf); | 232 | txt_puts(buf); |
202 | } | 233 | } |
203 | 234 | ||
204 | // TODO: Update for working on bitmap modes. | ||
205 | void | 235 | void |
206 | txt_clear_line(void) { | 236 | txt_clear_line_tiled(void) { |
207 | for (size_t i = 0; i < 30; ++i) { | 237 | for (size_t i = 0; i < 30; ++i) { |
208 | text_engine.memory[i + 32 * text_engine.cursor_y] = ' '; | 238 | text_engine.memory[i + 32 * text_engine.cursor_y] = ' '; |
209 | } | 239 | } |
210 | text_engine.cursor_x = 0; | 240 | text_engine.cursor_x = 0; |
211 | } | 241 | } |
212 | 242 | ||
213 | // TODO: Update for working on bitmap modes. | 243 | void |
244 | txt_clear_line_bitmap(void) { | ||
245 | // DEBUG: should be on the text struct. | ||
246 | Tile *buf = &TILE_MEM[0]; | ||
247 | for (size_t i = 0; i < 30; ++i) { | ||
248 | buf[i + text_engine.cursor_y * 30] = (Tile){0}; | ||
249 | } | ||
250 | } | ||
251 | |||
252 | void | ||
253 | txt_clear_line(void) { | ||
254 | switch (text_engine.mode) { | ||
255 | case TXT_MODE_TILED_BG: { | ||
256 | txt_clear_line_tiled(); | ||
257 | } break; | ||
258 | case TXT_MODE_MODE3: | ||
259 | case TXT_MODE_HYBRID: { | ||
260 | txt_clear_line_bitmap(); | ||
261 | } break; | ||
262 | } | ||
263 | } | ||
264 | |||
214 | void | 265 | void |
215 | txt_clear_screen(void) { | 266 | txt_clear_screen(void) { |
216 | for (size_t j = 0; j < 20; ++j) { | 267 | for (size_t j = 0; j < 20; ++j) { |
217 | for (size_t i = 0; i < 30; ++i) { | 268 | text_engine.cursor_y = j; |
218 | text_engine.memory[i + 32 * j] = ' '; | 269 | txt_clear_line(); |
219 | } | ||
220 | } | 270 | } |
221 | text_engine.cursor_x = 0; | 271 | text_engine.cursor_x = 0; |
222 | text_engine.cursor_y = 0; | 272 | text_engine.cursor_y = 0; |
diff --git a/src/uxn/devices/ppu.c b/src/uxn/devices/ppu.c index 5894352..836b7f0 100644 --- a/src/uxn/devices/ppu.c +++ b/src/uxn/devices/ppu.c | |||
@@ -114,6 +114,12 @@ initppu(Ppu *p, Uint8 hor, Uint8 ver, Uint8 pad) { | |||
114 | p->bg[i] = 0; | 114 | p->bg[i] = 0; |
115 | } | 115 | } |
116 | 116 | ||
117 | // Initialize default palette. | ||
118 | PAL_BUFFER_BG[0] = COLOR_BLACK; | ||
119 | PAL_BUFFER_BG[1] = COLOR_WHITE; | ||
120 | PAL_BUFFER_BG[2] = COLOR_RED; | ||
121 | PAL_BUFFER_BG[3] = COLOR_BLUE; | ||
122 | |||
117 | // Initialize memory map. | 123 | // Initialize memory map. |
118 | u16 *fg_mem = SCREENBLOCK_MEM[sb_fg]; | 124 | u16 *fg_mem = SCREENBLOCK_MEM[sb_fg]; |
119 | u16 *bg_mem = SCREENBLOCK_MEM[sb_bg]; | 125 | u16 *bg_mem = SCREENBLOCK_MEM[sb_bg]; |
diff --git a/src/uxn/uxn.c b/src/uxn/uxn.c index 08b3b9b..54d56d0 100644 --- a/src/uxn/uxn.c +++ b/src/uxn/uxn.c | |||
@@ -151,6 +151,6 @@ portuxn(Uxn *u, Uint8 id, char *name, void (*talkfn)(Device *d, Uint8 b0, Uint8 | |||
151 | d->u = u; | 151 | d->u = u; |
152 | d->mem = u->ram.dat; | 152 | d->mem = u->ram.dat; |
153 | d->talk = talkfn; | 153 | d->talk = talkfn; |
154 | txt_printf("Device added #%02x: %s, at 0x%04x \n", id, name, d->addr); | 154 | txt_printf("Dev:#%02x:0x%04x:%s \n", id, d->addr, name); |
155 | return d; | 155 | return d; |
156 | } | 156 | } |