aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-23 20:16:29 +0200
committerBad Diode <bd@badd10de.dev>2021-05-23 20:16:29 +0200
commit8d601a590bd0f920423ca217d6f1473952edd4eb (patch)
tree1538b0b66566787657b3a9042d3cb0e4674fb10e
parenta928aab86ec33f385b749771747d1097b1fba277 (diff)
downloaduxngba-8d601a590bd0f920423ca217d6f1473952edd4eb.tar.gz
uxngba-8d601a590bd0f920423ca217d6f1473952edd4eb.zip
Add keyboard input method
-rw-r--r--roms/controller.keys.rombin1151 -> 1150 bytes
-rw-r--r--src/bd-font.c2
-rw-r--r--src/common.h1
-rw-r--r--src/main.c26
-rw-r--r--src/uxn/devices/ppu.c74
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")))
diff --git a/src/main.c b/src/main.c
index dd4145a..17e0127 100644
--- a/src/main.c
+++ b/src/main.c
@@ -37,9 +37,10 @@ WITH REGARD TO THIS SOFTWARE.
37typedef enum { 37typedef enum {
38 CONTROL_CONTROLLER, 38 CONTROL_CONTROLLER,
39 CONTROL_MOUSE, 39 CONTROL_MOUSE,
40 CONTROL_KEYBOARD,
40} ControlMethod; 41} ControlMethod;
41 42
42static ControlMethod control_method = DEFAULT_CONTROL; 43static ControlMethod control_method = CONTROL_KEYBOARD;
43 44
44#define MOUSE_DELTA 1 45#define MOUSE_DELTA 1
45typedef struct Mouse { 46typedef 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
25static u32 unpack_icon_lut[256] = { 28static 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
302typedef struct KeyboardChar {
303 int x;
304 int y;
305 u8 symbol;
306} KeyboardChar;
307
308static 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
314KeyboardChar 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
323void
324toggle_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
331void
332update_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
293int 340int
294initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { 341initppu(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}