summaryrefslogtreecommitdiff
path: root/source/keyboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/keyboard.c')
-rw-r--r--source/keyboard.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/source/keyboard.c b/source/keyboard.c
new file mode 100644
index 0000000..d33346d
--- /dev/null
+++ b/source/keyboard.c
@@ -0,0 +1,262 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2006 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+ $Id$
+*/
+
+#include <nds.h>
+#include "keyboard.h"
+#include "framebuffer.h"
+#include "keyb_bin.h"
+
+/* ---------------------------------------- STATIC DATA
+*/
+static uint16 white = FB_RGB(31, 31, 31);
+static uint16 black = FB_RGB(0, 0, 0);
+
+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 CHECK_STATE(KEYS,BIT,CODE,SHORTCUT) \
+ do \
+ { \
+ key_state[CODE].new_state = (KEYS & BIT); \
+ if (SHORTCUT != NUM_SOFT_KEYS && \
+ !key_state[SHORTCUT].handled) \
+ { \
+ key_state[SHORTCUT].new_state = (KEYS & BIT); \
+ } \
+ } while(0)
+
+
+/* ---------------------------------------- PRIVATE INTERFACES
+*/
+static SoftKey LocatePress(const touchPosition *p)
+{
+ int kx=0,ky=0;
+ int py=0;
+ SoftKey key = NUM_SOFT_KEYS;
+
+ if (p->py > 36 && p->px > 2)
+ {
+ kx = (p->px - 3) / 25;
+ ky = p->py - 37;
+
+ py = ky % 30;
+ ky /= 30;
+
+ if (py<17 && kx >= 0 && kx<10 && ky>=0 && ky<=4)
+ {
+ key = kx + ky * 10;
+ }
+ }
+
+ return key;
+}
+
+
+/* ---------------------------------------- PUBLIC INTERFACES
+*/
+void SK_DisplayKeyboard(uint16 *vram)
+{
+ sImage img;
+
+ loadPCX(keyb_bin,&img);
+ image8to16(&img);
+ dmaCopy(img.data8,vram,SCREEN_WIDTH*SCREEN_HEIGHT*2);
+}
+
+
+int SK_GetEvent(SoftKeyEvent *ev)
+{
+ static SoftKey last = NUM_SOFT_KEYS;
+ static int poll_index = -1;
+
+ /* Read the keys if this is a new loop
+ */
+ if (poll_index == -1)
+ {
+ int f;
+ uint32 keys;
+
+ scanKeys();
+
+ 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=touchReadXY();
+
+ if (tp.py<21 || tp.py>165)
+ {
+ 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);
+ CHECK_STATE(keys, KEY_B, SK_PAD_B, pad_B_key);
+ CHECK_STATE(keys, KEY_X, SK_PAD_X, pad_X_key);
+ CHECK_STATE(keys, KEY_Y, SK_PAD_Y, pad_Y_key);
+ CHECK_STATE(keys, KEY_R, SK_PAD_R, pad_R_key);
+ CHECK_STATE(keys, KEY_L, SK_PAD_L, pad_L_key);
+ CHECK_STATE(keys, KEY_START, SK_PAD_START, pad_start_key);
+ CHECK_STATE(keys, KEY_SELECT, SK_PAD_SELECT, pad_select_key);
+ CHECK_STATE(keys, KEY_UP, SK_PAD_UP, pad_up_key);
+ CHECK_STATE(keys, KEY_DOWN, SK_PAD_DOWN, pad_down_key);
+ CHECK_STATE(keys, KEY_LEFT, SK_PAD_LEFT, pad_left_key);
+ CHECK_STATE(keys, KEY_RIGHT, SK_PAD_RIGHT, pad_right_key);
+
+ /* Reset key event poll index
+ */
+ poll_index = 0;
+
+ /* Update any on-screen indicators
+ */
+ for(f=SK_1; f<SK_CONFIG; f++)
+ {
+ if (key_state[f].state != key_state[f].new_state)
+ {
+ int x,y;
+
+ x = 2 + (f % 10) * 25;
+ y = 36 + (f / 10) * 30;
+
+ FB_Box(x, y, 26, 19, key_state[f].new_state ? white:black);
+ }
+ }
+ }
+
+ while(poll_index < NUM_SOFT_KEYS &&
+ key_state[poll_index].state == key_state[poll_index].new_state)
+ {
+ poll_index++;
+ }
+
+ if (poll_index < NUM_SOFT_KEYS)
+ {
+ key_state[poll_index].state = key_state[poll_index].new_state;
+
+ ev->key = poll_index;
+ ev->pressed = key_state[poll_index].state;
+
+ return TRUE;
+ }
+ else
+ {
+ poll_index = -1;
+ return FALSE;
+ }
+}
+
+
+void SK_SetSticky(SoftKey key, int is_sticky)
+{
+ key_state[key].is_sticky = is_sticky;
+
+ if (!is_sticky)
+ {
+ key_state[key].new_state = FALSE;
+ }
+}
+
+
+void SK_ClearKeys(void)
+{
+ int f;
+
+ for(f=0; f < NUM_SOFT_KEYS; f++)
+ {
+ key_state[f].state = FALSE;
+ }
+}
+
+
+void SK_DefineJoypad(void)
+{
+}
+
+