From 25a57883291bc89210edbd3670e5548a0b838913 Mon Sep 17 00:00:00 2001 From: Ian C Date: Wed, 30 Jun 2021 18:41:43 +0000 Subject: Copied over 3ds81 code and changed some names. Not yet a speccy. --- source/keyboard.c | 428 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 428 insertions(+) create mode 100644 source/keyboard.c (limited to 'source/keyboard.c') diff --git a/source/keyboard.c b/source/keyboard.c new file mode 100644 index 0000000..9562bfa --- /dev/null +++ b/source/keyboard.c @@ -0,0 +1,428 @@ +/* + 3dsspec - Nintendo 3DS Spectrum emulator. + + Copyright (C) 2021 Ian Cowburn + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see + + $Id: keyboard.c 64 2008-12-05 00:37:26Z ianc $ +*/ + +#include <3ds.h> + +#include "keyboard.h" +#include "framebuffer.h" +#include "stream.h" + +/* ---------------------------------------- STATIC DATA +*/ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +static int selection_on = COL_WHITE; +static int selection_off = COL_BLACK; + +static struct +{ + int state; + int new_state; + int handled; + int is_sticky; +} key_state[NUM_SOFT_KEYS]; + +static SoftKey pad_left_key = SK_5; +static SoftKey pad_right_key = SK_8; +static SoftKey pad_up_key = SK_7; +static SoftKey pad_down_key = SK_6; +static SoftKey pad_A_key = SK_0; +static SoftKey pad_B_key = SK_NEWLINE; +static SoftKey pad_X_key = NUM_SOFT_KEYS; +static SoftKey pad_Y_key = NUM_SOFT_KEYS; +static SoftKey pad_R_key = NUM_SOFT_KEYS; +static SoftKey pad_L_key = NUM_SOFT_KEYS; +static SoftKey pad_start_key = NUM_SOFT_KEYS; +static SoftKey pad_select_key = NUM_SOFT_KEYS; + +#define CLEAR_STATE(SHORTCUT) \ + do \ + { \ + if (SHORTCUT != NUM_SOFT_KEYS && \ + !key_state[SHORTCUT].handled) \ + { \ + key_state[SHORTCUT].new_state = FALSE; \ + } \ + } while(0) + +#define CHECK_STATE(KEYS,BIT,CODE,SHORTCUT,USE_SHORTCUT) \ + do \ + { \ + key_state[CODE].new_state = (KEYS & BIT); \ + if (USE_SHORTCUT && SHORTCUT != NUM_SOFT_KEYS && \ + !key_state[SHORTCUT].handled && (KEYS & BIT)) \ + { \ + key_state[SHORTCUT].new_state = TRUE; \ + } \ + } while(0) + +#define CELL_WIDTH 32 +#define CELL_HEIGHT 48 + +static const char *keynames[]= +{ + "1", "2", "3", "4", "5", + "6", "7", "8", "9", "0", + "Q", "W", "E", "R", "T", + "Y", "U", "I", "O", "P", + "A", "S", "D", "F", "G", + "H", "J", "K", "L", "NEWLINE", + "SHIFT", "Z", "X", "C", "V", + "B", "N", "M", "PERIOD", "SPACE", + + "ABOUT", + "CONFIG", + "JOYPAD UP", + "JOYPAD DOWN", + "JOYPAD LEFT", + "JOYPAD RIGHT", + "A BUTTON", + "B BUTTON", + "X BUTTON", + "Y BUTTON", + "RIGHT SHOULDER BUTTON", + "LEFT SHOULDER BUTTON", + "START BUTTON", + "SELECT BUTTON" +}; + +/* ---------------------------------------- PRIVATE INTERFACES +*/ +static SoftKey LocatePress(const touchPosition *p) +{ + int kx=0,ky=0; + int key = NUM_SOFT_KEYS; + + kx = p->px / CELL_WIDTH; + ky = p->py / CELL_HEIGHT; + + key = kx + ky * 10; + + if (key>SK_SPACE) + { + key = NUM_SOFT_KEYS; + } + + return key; +} + + +static void DrawSelect(Framebuffer *fb, int key, int selected) +{ + int x,y; + + x = (key % 10) * CELL_WIDTH; + y = (key / 10) * CELL_HEIGHT; + + FB_Box(fb, x, fb->height - 1 - y, CELL_WIDTH, CELL_HEIGHT, + selected ? selection_on : selection_off); +} + + +static int GetEvent(SoftKeyEvent *ev, int map) +{ + static SoftKey last = NUM_SOFT_KEYS; + static int poll_index = -1; + Framebuffer lower; + + FB_StartFrame(NULL, &lower); + + /* Read the keys if this is a new loop + */ + if (poll_index == -1) + { + int f; + u32 keys; + + keys = keysHeld(); + + /* Clear the non-sticky keys + */ + for(f=SK_1; f<=SK_CONFIG; f++) + { + key_state[f].handled = FALSE; + + if (key_state[f].is_sticky) + { + key_state[f].new_state = key_state[f].state; + } + else + { + key_state[f].new_state = FALSE; + } + } + + /* Check the soft keyboard + */ + if (keys & KEY_TOUCH) + { + touchPosition tp; + + hidTouchRead(&tp); + + if (tp.py>192) + { + key_state[SK_CONFIG].new_state = TRUE; + } + else + { + SoftKey press; + + press = LocatePress(&tp); + + if (press != NUM_SOFT_KEYS) + { + key_state[press].handled = TRUE; + + if (key_state[press].is_sticky) + { + if (last != press) + { + key_state[press].new_state = + !key_state[press].state; + } + } + else + { + key_state[press].new_state = TRUE; + } + + last = press; + } + } + } + else + { + last = NUM_SOFT_KEYS; + } + + /* Check non soft-keyboard controls + */ + CHECK_STATE(keys, KEY_A, SK_PAD_A, pad_A_key, map); + CHECK_STATE(keys, KEY_B, SK_PAD_B, pad_B_key, map); + CHECK_STATE(keys, KEY_X, SK_PAD_X, pad_X_key, map); + CHECK_STATE(keys, KEY_Y, SK_PAD_Y, pad_Y_key, map); + CHECK_STATE(keys, KEY_R, SK_PAD_R, pad_R_key, map); + CHECK_STATE(keys, KEY_L, SK_PAD_L, pad_L_key, map); + CHECK_STATE(keys, KEY_START, SK_PAD_START, pad_start_key, map); + CHECK_STATE(keys, KEY_SELECT, SK_PAD_SELECT, pad_select_key, map); + CHECK_STATE(keys, KEY_UP, SK_PAD_UP, pad_up_key, map); + CHECK_STATE(keys, KEY_DOWN, SK_PAD_DOWN, pad_down_key, map); + CHECK_STATE(keys, KEY_LEFT, SK_PAD_LEFT, pad_left_key, map); + CHECK_STATE(keys, KEY_RIGHT, SK_PAD_RIGHT, pad_right_key, map); + + /* Reset key event poll index + */ + poll_index = 0; + + /* Update any on-screen indicators + */ + for(f=SK_1; fkey = poll_index; + ev->pressed = key_state[poll_index].state; + + return TRUE; + } + else + { + poll_index = -1; + return FALSE; + } +} + + +/* ---------------------------------------- PUBLIC INTERFACES +*/ +void SK_DisplayKeyboard(void) +{ + int f; + Framebuffer lower; + + FB_StartFrame(NULL, &lower); + + FB_Blit(&lower,IMG_KEYBOARD,0,0); + + /* Update any on-screen indicators + */ + for(f=SK_1; f