diff options
author | Bad Diode <bd@badd10de.dev> | 2021-05-23 20:16:29 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-05-23 20:16:29 +0200 |
commit | 8d601a590bd0f920423ca217d6f1473952edd4eb (patch) | |
tree | 1538b0b66566787657b3a9042d3cb0e4674fb10e | |
parent | a928aab86ec33f385b749771747d1097b1fba277 (diff) | |
download | uxngba-8d601a590bd0f920423ca217d6f1473952edd4eb.tar.gz uxngba-8d601a590bd0f920423ca217d6f1473952edd4eb.zip |
Add keyboard input method
-rw-r--r-- | roms/controller.keys.rom | bin | 1151 -> 1150 bytes | |||
-rw-r--r-- | src/bd-font.c | 2 | ||||
-rw-r--r-- | src/common.h | 1 | ||||
-rw-r--r-- | src/main.c | 26 | ||||
-rw-r--r-- | src/uxn/devices/ppu.c | 74 |
5 files changed, 99 insertions, 4 deletions
diff --git a/roms/controller.keys.rom b/roms/controller.keys.rom index d31f071..7ef8f14 100644 --- a/roms/controller.keys.rom +++ b/roms/controller.keys.rom | |||
Binary files differ | |||
diff --git a/src/bd-font.c b/src/bd-font.c index 0374496..5276735 100644 --- a/src/bd-font.c +++ b/src/bd-font.c | |||
@@ -22,7 +22,7 @@ static const u32 bd_font[] = { | |||
22 | 0x081c3e08, 0x083e1c08, 0x00141414, 0x14140014, | 22 | 0x081c3e08, 0x083e1c08, 0x00141414, 0x14140014, |
23 | 0x003c2a2a, 0x2c282828, 0x0038043c, 0x423c201e, | 23 | 0x003c2a2a, 0x2c282828, 0x0038043c, 0x423c201e, |
24 | 0x00000000, 0x7e000000, 0x081c3e08, 0x3e1c083e, | 24 | 0x00000000, 0x7e000000, 0x081c3e08, 0x3e1c083e, |
25 | 0x081c3e08, 0x08080808, 0x08080808, 0x083e1c08, | 25 | 0x081c3e08, 0x08080800, 0x00080808, 0x083e1c08, |
26 | 0x00001030, 0x7e301000, 0x0000080c, 0x7e0c0800, | 26 | 0x00001030, 0x7e301000, 0x0000080c, 0x7e0c0800, |
27 | 0x00000000, 0x0002023e, 0x00002466, 0xff662400, | 27 | 0x00000000, 0x0002023e, 0x00002466, 0xff662400, |
28 | 0x0008081c, 0x1c3e3e00, 0x003e3e1c, 0x1c080800, | 28 | 0x0008081c, 0x1c3e3e00, 0x003e3e1c, 0x1c080800, |
diff --git a/src/common.h b/src/common.h index 049533e..39f3ada 100644 --- a/src/common.h +++ b/src/common.h | |||
@@ -714,6 +714,7 @@ wait_vsync(void) { | |||
714 | #define MIN(A, B) ((A) <= (B) ? (A) : (B)) | 714 | #define MIN(A, B) ((A) <= (B) ? (A) : (B)) |
715 | #define MAX(A, B) ((A) >= (B) ? (A) : (B)) | 715 | #define MAX(A, B) ((A) >= (B) ? (A) : (B)) |
716 | #define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X)) | 716 | #define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X)) |
717 | #define LEN(ARR) (sizeof(ARR) / sizeof((ARR)[0])) | ||
717 | 718 | ||
718 | // IWRAM allocation macros for devkitARM. | 719 | // IWRAM allocation macros for devkitARM. |
719 | #define IWRAM_CODE __attribute__((section(".iwram"), long_call, target("arm"))) | 720 | #define IWRAM_CODE __attribute__((section(".iwram"), long_call, target("arm"))) |
@@ -37,9 +37,10 @@ WITH REGARD TO THIS SOFTWARE. | |||
37 | typedef enum { | 37 | typedef enum { |
38 | CONTROL_CONTROLLER, | 38 | CONTROL_CONTROLLER, |
39 | CONTROL_MOUSE, | 39 | CONTROL_MOUSE, |
40 | CONTROL_KEYBOARD, | ||
40 | } ControlMethod; | 41 | } ControlMethod; |
41 | 42 | ||
42 | static ControlMethod control_method = DEFAULT_CONTROL; | 43 | static ControlMethod control_method = CONTROL_KEYBOARD; |
43 | 44 | ||
44 | #define MOUSE_DELTA 1 | 45 | #define MOUSE_DELTA 1 |
45 | typedef struct Mouse { | 46 | typedef struct Mouse { |
@@ -173,12 +174,17 @@ handle_input(Uxn *u) { | |||
173 | devctrl->dat[3] = 0; | 174 | devctrl->dat[3] = 0; |
174 | control_method = CONTROL_MOUSE; | 175 | control_method = CONTROL_MOUSE; |
175 | } break; | 176 | } break; |
176 | default: { | 177 | case CONTROL_MOUSE: { |
177 | devmouse->dat[6] = 0; | 178 | devmouse->dat[6] = 0; |
178 | devmouse->dat[7] = 0; | 179 | devmouse->dat[7] = 0; |
179 | mempoke16(devmouse->dat, 0x2, -10); | 180 | mempoke16(devmouse->dat, 0x2, -10); |
180 | mempoke16(devmouse->dat, 0x4, -10); | 181 | mempoke16(devmouse->dat, 0x4, -10); |
181 | evaluxn(u, mempeek16(devmouse->dat, 0)); | 182 | evaluxn(u, mempeek16(devmouse->dat, 0)); |
183 | toggle_keyboard(); | ||
184 | control_method = CONTROL_KEYBOARD; | ||
185 | } break; | ||
186 | case CONTROL_KEYBOARD: { | ||
187 | toggle_keyboard(); | ||
182 | control_method = CONTROL_CONTROLLER; | 188 | control_method = CONTROL_CONTROLLER; |
183 | } break; | 189 | } break; |
184 | } | 190 | } |
@@ -270,6 +276,22 @@ handle_input(Uxn *u) { | |||
270 | mempoke16(devmouse->dat, 0x2, mouse.x); | 276 | mempoke16(devmouse->dat, 0x2, mouse.x); |
271 | mempoke16(devmouse->dat, 0x4, mouse.y); | 277 | mempoke16(devmouse->dat, 0x4, mouse.y); |
272 | evaluxn(u, mempeek16(devmouse->dat, 0)); | 278 | evaluxn(u, mempeek16(devmouse->dat, 0)); |
279 | } else if (control_method == CONTROL_KEYBOARD) { | ||
280 | if (key_tap(KEY_LEFT)) { | ||
281 | update_cursor(cursor_position - 1); | ||
282 | } else if (key_tap(KEY_RIGHT)) { | ||
283 | update_cursor(cursor_position + 1); | ||
284 | } | ||
285 | if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) { | ||
286 | update_cursor(cursor_position - KEYBOARD_ROW_SIZE); | ||
287 | } else if (key_tap(KEY_DOWN) && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) { | ||
288 | update_cursor(cursor_position + KEYBOARD_ROW_SIZE); | ||
289 | } | ||
290 | if (key_tap(KEY_B)) { | ||
291 | devctrl->dat[3] = keyboard[cursor_position].symbol; | ||
292 | evaluxn(u, mempeek16(devctrl->dat, 0)); | ||
293 | devctrl->dat[3] = 0; | ||
294 | } | ||
273 | } | 295 | } |
274 | } | 296 | } |
275 | 297 | ||
diff --git a/src/uxn/devices/ppu.c b/src/uxn/devices/ppu.c index 64f3fb4..4a5a13d 100644 --- a/src/uxn/devices/ppu.c +++ b/src/uxn/devices/ppu.c | |||
@@ -22,6 +22,9 @@ WITH REGARD TO THIS SOFTWARE. | |||
22 | #define TILE_MAP ((u32*)(MEM_VRAM + KB(40))) | 22 | #define TILE_MAP ((u32*)(MEM_VRAM + KB(40))) |
23 | #define FONT_DATA ((u32*)(MEM_VRAM + KB(84))) | 23 | #define FONT_DATA ((u32*)(MEM_VRAM + KB(84))) |
24 | 24 | ||
25 | // Keyboard. | ||
26 | #define SPRITE_START_IDX 640 | ||
27 | |||
25 | static u32 unpack_icon_lut[256] = { | 28 | static u32 unpack_icon_lut[256] = { |
26 | 0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, | 29 | 0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, |
27 | 0x00000101, 0x00000110, 0x00000111, 0x00001000, 0x00001001, | 30 | 0x00000101, 0x00000110, 0x00000111, 0x00001000, 0x00001001, |
@@ -146,6 +149,12 @@ putcolors(u8 *addr) { | |||
146 | (r << 1) | (r >> 3), | 149 | (r << 1) | (r >> 3), |
147 | (g << 1) | (g >> 3), | 150 | (g << 1) | (g >> 3), |
148 | (b << 1) | (b >> 3)); | 151 | (b << 1) | (b >> 3)); |
152 | for (size_t j = 0; j < 16; ++j) { | ||
153 | PAL_BUFFER_SPRITES[i * 16 + j] = rgb15( | ||
154 | (r << 1) | (r >> 3), | ||
155 | (g << 1) | (g >> 3), | ||
156 | (b << 1) | (b >> 3)); | ||
157 | } | ||
149 | } | 158 | } |
150 | } | 159 | } |
151 | 160 | ||
@@ -290,6 +299,44 @@ flipbuf(Ppu *p) { | |||
290 | } | 299 | } |
291 | } | 300 | } |
292 | 301 | ||
302 | typedef struct KeyboardChar { | ||
303 | int x; | ||
304 | int y; | ||
305 | u8 symbol; | ||
306 | } KeyboardChar; | ||
307 | |||
308 | static u8 cursor_position = 0; | ||
309 | |||
310 | #define KEYBOARD_ROW_SIZE 12 | ||
311 | #define KEYBOARD_START_TILE_X (30 / 2 - KEYBOARD_ROW_SIZE / 2) | ||
312 | #define KEYBOARD_START_TILE_Y (20 / 2 - 3) | ||
313 | |||
314 | KeyboardChar keyboard[] = { | ||
315 | {0, 0, '!'}, {0, 0, '?'}, {0, 0, '@'}, {0, 0, '#'}, {0, 0, '$'}, {0, 0, '%'}, {0, 0, '^'}, {0, 0, '&'}, {0, 0, '*'}, {0, 0, '"'}, {0, 0, '\''}, {0, 0, 0x7f}, | ||
316 | {0, 0, '('}, {0, 0, ')'}, {0, 0, '['}, {0, 0, ']'}, {0, 0, '{'}, {0, 0, '}'}, {0, 0, '<'}, {0, 0, '>'}, {0, 0, '+'}, {0, 0, '-'}, {0, 0, '='}, {0, 0, 0x14}, | ||
317 | {0, 0, '0'}, {0, 0, '1'}, {0, 0, '2'}, {0, 0, '3'}, {0, 0, '4'}, {0, 0, '5'}, {0, 0, '6'}, {0, 0, '7'}, {0, 0, '8'}, {0, 0, '9'}, {0, 0, '~'}, {0, 0, 0x18}, | ||
318 | {0, 0, 'a'}, {0, 0, 'b'}, {0, 0, 'c'}, {0, 0, 'd'}, {0, 0, 'e'}, {0, 0, 'f'}, {0, 0, 'g'}, {0, 0, 'h'}, {0, 0, 'i'}, {0, 0, 'j'}, {0, 0, '/'}, {0, 0, 0x19}, | ||
319 | {0, 0, 'k'}, {0, 0, 'l'}, {0, 0, 'm'}, {0, 0, 'n'}, {0, 0, 'o'}, {0, 0, 'p'}, {0, 0, 'q'}, {0, 0, 'r'}, {0, 0, 's'}, {0, 0, 't'}, {0, 0, '\\'}, {0, 0, 0x1a}, | ||
320 | {0, 0, 'u'}, {0, 0, 'v'}, {0, 0, 'w'}, {0, 0, 'x'}, {0, 0, 'y'}, {0, 0, 'z'}, {0, 0, ','}, {0, 0, '.'}, {0, 0, ';'}, {0, 0, ':'}, {0, 0, '_'}, {0, 0, 0x1b}, | ||
321 | }; | ||
322 | |||
323 | void | ||
324 | toggle_keyboard(void) { | ||
325 | for (size_t i = 0; i < LEN(keyboard); ++i) { | ||
326 | OBJ_ATTR_0(i) ^= OBJ_HIDDEN; | ||
327 | } | ||
328 | OBJ_ATTR_0(127) ^= OBJ_HIDDEN; | ||
329 | } | ||
330 | |||
331 | void | ||
332 | update_cursor(int pos) { | ||
333 | cursor_position = CLAMP(pos, 0, LEN(keyboard) - 1); | ||
334 | OBJ_ATTR_0(127) = OBJ_ATTR_0(127) & ~0xFF | ||
335 | | OBJ_Y_COORD(keyboard[cursor_position].y); | ||
336 | OBJ_ATTR_1(127) = OBJ_ATTR_0(127) & ~0x1FF | ||
337 | | OBJ_X_COORD(keyboard[cursor_position].x); | ||
338 | } | ||
339 | |||
293 | int | 340 | int |
294 | initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { | 341 | initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { |
295 | p->hor = hor; | 342 | p->hor = hor; |
@@ -299,7 +346,7 @@ initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { | |||
299 | p->height = (8 * p->ver + p->pad * 2); | 346 | p->height = (8 * p->ver + p->pad * 2); |
300 | 347 | ||
301 | // Initialize display mode and bg palette. | 348 | // Initialize display mode and bg palette. |
302 | DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1; | 349 | DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1 | DISP_OBJ; |
303 | 350 | ||
304 | // Initialize backgrounds. | 351 | // Initialize backgrounds. |
305 | u8 cb_fg = 0; | 352 | u8 cb_fg = 0; |
@@ -329,6 +376,12 @@ initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { | |||
329 | PAL_BUFFER_BG[1] = COLOR_WHITE; | 376 | PAL_BUFFER_BG[1] = COLOR_WHITE; |
330 | PAL_BUFFER_BG[2] = COLOR_RED; | 377 | PAL_BUFFER_BG[2] = COLOR_RED; |
331 | PAL_BUFFER_BG[3] = COLOR_BLUE; | 378 | PAL_BUFFER_BG[3] = COLOR_BLUE; |
379 | for (size_t i = 0; i < 16; ++i) { | ||
380 | PAL_BUFFER_SPRITES[i] = COLOR_BLACK; | ||
381 | PAL_BUFFER_SPRITES[1 * 16] = COLOR_WHITE; | ||
382 | PAL_BUFFER_SPRITES[2 * 16] = COLOR_RED; | ||
383 | PAL_BUFFER_SPRITES[3 * 16] = COLOR_BLUE; | ||
384 | } | ||
332 | 385 | ||
333 | // Initialize background memory map. | 386 | // Initialize background memory map. |
334 | u16 *mem_map_fg = SCREENBLOCK_MEM[sb_fg]; | 387 | u16 *mem_map_fg = SCREENBLOCK_MEM[sb_fg]; |
@@ -342,5 +395,24 @@ initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { | |||
342 | // Load font data into VRAM. | 395 | // Load font data into VRAM. |
343 | unpack_tiles(&bd_font, FONT_DATA, 256); | 396 | unpack_tiles(&bd_font, FONT_DATA, 256); |
344 | 397 | ||
398 | // Initialize keyboard sprites. | ||
399 | int tile_x = KEYBOARD_START_TILE_X; | ||
400 | int tile_y = KEYBOARD_START_TILE_Y; | ||
401 | for (size_t i = 0; i < sizeof(keyboard) / sizeof(keyboard[0]); ++i) { | ||
402 | keyboard[i].x = tile_x * 8; | ||
403 | keyboard[i].y = tile_y * 8; | ||
404 | OBJ_ATTR_0(i) = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(keyboard[i].y); | ||
405 | OBJ_ATTR_1(i) = OBJ_SIZE_SMALL | OBJ_X_COORD(keyboard[i].x); | ||
406 | OBJ_ATTR_2(i) = SPRITE_START_IDX + keyboard[i].symbol | OBJ_PAL_BANK(0); | ||
407 | tile_x++; | ||
408 | if (tile_x - KEYBOARD_START_TILE_X >= KEYBOARD_ROW_SIZE) { | ||
409 | tile_x = KEYBOARD_START_TILE_X; | ||
410 | tile_y++; | ||
411 | } | ||
412 | } | ||
413 | OBJ_ATTR_0(127) = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(keyboard[cursor_position].y); | ||
414 | OBJ_ATTR_1(127) = OBJ_SIZE_SMALL | OBJ_X_COORD(keyboard[cursor_position].x); | ||
415 | OBJ_ATTR_2(127) = SPRITE_START_IDX + 0xdb | OBJ_PAL_BANK(3); | ||
416 | |||
345 | return 1; | 417 | return 1; |
346 | } | 418 | } |