From 8d601a590bd0f920423ca217d6f1473952edd4eb Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Sun, 23 May 2021 20:16:29 +0200 Subject: Add keyboard input method --- roms/controller.keys.rom | Bin 1151 -> 1150 bytes src/bd-font.c | 2 +- src/common.h | 1 + src/main.c | 26 +++++++++++++++-- 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 Binary files a/roms/controller.keys.rom and b/roms/controller.keys.rom 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[] = { 0x081c3e08, 0x083e1c08, 0x00141414, 0x14140014, 0x003c2a2a, 0x2c282828, 0x0038043c, 0x423c201e, 0x00000000, 0x7e000000, 0x081c3e08, 0x3e1c083e, - 0x081c3e08, 0x08080808, 0x08080808, 0x083e1c08, + 0x081c3e08, 0x08080800, 0x00080808, 0x083e1c08, 0x00001030, 0x7e301000, 0x0000080c, 0x7e0c0800, 0x00000000, 0x0002023e, 0x00002466, 0xff662400, 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) { #define MIN(A, B) ((A) <= (B) ? (A) : (B)) #define MAX(A, B) ((A) >= (B) ? (A) : (B)) #define CLAMP(X, MIN, MAX) ((X) <= (MIN) ? (MIN) : (X) > (MAX) ? (MAX): (X)) +#define LEN(ARR) (sizeof(ARR) / sizeof((ARR)[0])) // IWRAM allocation macros for devkitARM. #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. typedef enum { CONTROL_CONTROLLER, CONTROL_MOUSE, + CONTROL_KEYBOARD, } ControlMethod; -static ControlMethod control_method = DEFAULT_CONTROL; +static ControlMethod control_method = CONTROL_KEYBOARD; #define MOUSE_DELTA 1 typedef struct Mouse { @@ -173,12 +174,17 @@ handle_input(Uxn *u) { devctrl->dat[3] = 0; control_method = CONTROL_MOUSE; } break; - default: { + case CONTROL_MOUSE: { devmouse->dat[6] = 0; devmouse->dat[7] = 0; mempoke16(devmouse->dat, 0x2, -10); mempoke16(devmouse->dat, 0x4, -10); evaluxn(u, mempeek16(devmouse->dat, 0)); + toggle_keyboard(); + control_method = CONTROL_KEYBOARD; + } break; + case CONTROL_KEYBOARD: { + toggle_keyboard(); control_method = CONTROL_CONTROLLER; } break; } @@ -270,6 +276,22 @@ handle_input(Uxn *u) { mempoke16(devmouse->dat, 0x2, mouse.x); mempoke16(devmouse->dat, 0x4, mouse.y); evaluxn(u, mempeek16(devmouse->dat, 0)); + } else if (control_method == CONTROL_KEYBOARD) { + if (key_tap(KEY_LEFT)) { + update_cursor(cursor_position - 1); + } else if (key_tap(KEY_RIGHT)) { + update_cursor(cursor_position + 1); + } + if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) { + update_cursor(cursor_position - KEYBOARD_ROW_SIZE); + } else if (key_tap(KEY_DOWN) && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) { + update_cursor(cursor_position + KEYBOARD_ROW_SIZE); + } + if (key_tap(KEY_B)) { + devctrl->dat[3] = keyboard[cursor_position].symbol; + evaluxn(u, mempeek16(devctrl->dat, 0)); + devctrl->dat[3] = 0; + } } } 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. #define TILE_MAP ((u32*)(MEM_VRAM + KB(40))) #define FONT_DATA ((u32*)(MEM_VRAM + KB(84))) +// Keyboard. +#define SPRITE_START_IDX 640 + static u32 unpack_icon_lut[256] = { 0x00000000, 0x00000001, 0x00000010, 0x00000011, 0x00000100, 0x00000101, 0x00000110, 0x00000111, 0x00001000, 0x00001001, @@ -146,6 +149,12 @@ putcolors(u8 *addr) { (r << 1) | (r >> 3), (g << 1) | (g >> 3), (b << 1) | (b >> 3)); + for (size_t j = 0; j < 16; ++j) { + PAL_BUFFER_SPRITES[i * 16 + j] = rgb15( + (r << 1) | (r >> 3), + (g << 1) | (g >> 3), + (b << 1) | (b >> 3)); + } } } @@ -290,6 +299,44 @@ flipbuf(Ppu *p) { } } +typedef struct KeyboardChar { + int x; + int y; + u8 symbol; +} KeyboardChar; + +static u8 cursor_position = 0; + +#define KEYBOARD_ROW_SIZE 12 +#define KEYBOARD_START_TILE_X (30 / 2 - KEYBOARD_ROW_SIZE / 2) +#define KEYBOARD_START_TILE_Y (20 / 2 - 3) + +KeyboardChar keyboard[] = { + {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}, + {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}, + {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}, + {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}, + {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}, + {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}, +}; + +void +toggle_keyboard(void) { + for (size_t i = 0; i < LEN(keyboard); ++i) { + OBJ_ATTR_0(i) ^= OBJ_HIDDEN; + } + OBJ_ATTR_0(127) ^= OBJ_HIDDEN; +} + +void +update_cursor(int pos) { + cursor_position = CLAMP(pos, 0, LEN(keyboard) - 1); + OBJ_ATTR_0(127) = OBJ_ATTR_0(127) & ~0xFF + | OBJ_Y_COORD(keyboard[cursor_position].y); + OBJ_ATTR_1(127) = OBJ_ATTR_0(127) & ~0x1FF + | OBJ_X_COORD(keyboard[cursor_position].x); +} + int initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { p->hor = hor; @@ -299,7 +346,7 @@ initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { p->height = (8 * p->ver + p->pad * 2); // Initialize display mode and bg palette. - DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1; + DISP_CTRL = DISP_MODE_0 | DISP_BG_0 | DISP_BG_1 | DISP_OBJ; // Initialize backgrounds. u8 cb_fg = 0; @@ -329,6 +376,12 @@ initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { PAL_BUFFER_BG[1] = COLOR_WHITE; PAL_BUFFER_BG[2] = COLOR_RED; PAL_BUFFER_BG[3] = COLOR_BLUE; + for (size_t i = 0; i < 16; ++i) { + PAL_BUFFER_SPRITES[i] = COLOR_BLACK; + PAL_BUFFER_SPRITES[1 * 16] = COLOR_WHITE; + PAL_BUFFER_SPRITES[2 * 16] = COLOR_RED; + PAL_BUFFER_SPRITES[3 * 16] = COLOR_BLUE; + } // Initialize background memory map. u16 *mem_map_fg = SCREENBLOCK_MEM[sb_fg]; @@ -342,5 +395,24 @@ initppu(Ppu *p, u8 hor, u8 ver, u8 pad) { // Load font data into VRAM. unpack_tiles(&bd_font, FONT_DATA, 256); + // Initialize keyboard sprites. + int tile_x = KEYBOARD_START_TILE_X; + int tile_y = KEYBOARD_START_TILE_Y; + for (size_t i = 0; i < sizeof(keyboard) / sizeof(keyboard[0]); ++i) { + keyboard[i].x = tile_x * 8; + keyboard[i].y = tile_y * 8; + OBJ_ATTR_0(i) = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(keyboard[i].y); + OBJ_ATTR_1(i) = OBJ_SIZE_SMALL | OBJ_X_COORD(keyboard[i].x); + OBJ_ATTR_2(i) = SPRITE_START_IDX + keyboard[i].symbol | OBJ_PAL_BANK(0); + tile_x++; + if (tile_x - KEYBOARD_START_TILE_X >= KEYBOARD_ROW_SIZE) { + tile_x = KEYBOARD_START_TILE_X; + tile_y++; + } + } + OBJ_ATTR_0(127) = OBJ_SHAPE_SQUARE | OBJ_Y_COORD(keyboard[cursor_position].y); + OBJ_ATTR_1(127) = OBJ_SIZE_SMALL | OBJ_X_COORD(keyboard[cursor_position].x); + OBJ_ATTR_2(127) = SPRITE_START_IDX + 0xdb | OBJ_PAL_BANK(3); + return 1; } -- cgit v1.2.1