summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cvsignore8
-rw-r--r--include/keyboard.h10
-rw-r--r--source/keyboard.c210
-rw-r--r--source/main.c151
-rw-r--r--source/snap.c8
-rw-r--r--source/spec.c90
6 files changed, 401 insertions, 76 deletions
diff --git a/.cvsignore b/.cvsignore
index 6b59bb1..2965e34 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -1,5 +1,5 @@
build
-ds81.arm9
-ds81.ds.gba
-ds81.elf
-ds81.nds \ No newline at end of file
+dsspec.arm9
+dsspec.ds.gba
+dsspec.elf
+dsspec.nds
diff --git a/include/keyboard.h b/include/keyboard.h
index c4d989c..69990ad 100644
--- a/include/keyboard.h
+++ b/include/keyboard.h
@@ -22,7 +22,8 @@
#ifndef DSSPEC_KEYBOARD_H
#define DSSPEC_KEYBOARD_H
-/* Note that the first 40 values purposefully are the keyboard matrix keys
+/* Note that the first 40 values purposefully are the keyboard matrix keys.
+ Note also that they are in display order, not matrix order.
*/
typedef enum
{
@@ -89,7 +90,7 @@ typedef enum
SK_PAD_START,
SK_PAD_SELECT,
- NUM_OF_SOFT_KEYS
+ NUM_SOFT_KEYS
} SoftKey;
typedef struct
@@ -116,4 +117,9 @@ void SK_SetSticky(SoftKey key, int is_sticky);
*/
void SK_ClearKeys(void);
+/* Map the joypad to keys. Note that when mapped that both the key and the
+ joypad code will be generated.
+*/
+void SK_DefineJoypad(void);
+
#endif /* DSSPEC_KEYBOARD_H */
diff --git a/source/keyboard.c b/source/keyboard.c
index 978d3d5..2c4d63f 100644
--- a/source/keyboard.c
+++ b/source/keyboard.c
@@ -22,10 +22,72 @@
#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_O;
+static SoftKey pad_right_key = SK_P;
+static SoftKey pad_up_key = SK_Q;
+static SoftKey pad_down_key = SK_A;
+static SoftKey pad_A_key = SK_SPACE;
+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
*/
@@ -41,38 +103,160 @@ void SK_DisplayKeyboard(uint16 *vram)
int SK_GetEvent(SoftKeyEvent *ev)
{
- uint32 key=0;
-
- key=keysDownRepeat();
+ static SoftKey last = NUM_SOFT_KEYS;
+ static int poll_index = -1;
- if (key & KEY_TOUCH)
+ /* Read the keys if this is a new loop
+ */
+ if (poll_index == -1)
{
- touchPosition tp=touchReadXY();
+ 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;
- /*
- if (tp.px>=x && tp.px<(w+w) && tp.py>=y && tp.py<(y+h))
+ 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
{
- defer=true;
- sel=(tp.py-y)/16;
+ 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;
- ev->key=SK_CONFIG;
- ev->pressed=TRUE;
- return 1;
+ /* 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);
+ }
+ }
}
- return 0;
+ 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)
+{
}
diff --git a/source/main.c b/source/main.c
index 0cab2ab..e8b4c6b 100644
--- a/source/main.c
+++ b/source/main.c
@@ -28,11 +28,18 @@
#include "gui.h"
#include "z80.h"
#include "spec.h"
+#include "snap.h"
#include "keyboard.h"
#include "error.h"
#include "splashimg_bin.h"
+/* Put tape image includes here
+*/
+#include "manic_miner_bin.h"
+#include "ant3d_bin.h"
+#include "thrust_bin.h"
+
/* ---------------------------------------- STATIC DATA
*/
static const char *main_menu[]=
@@ -55,6 +62,40 @@ typedef enum
MenuDefineJoystick
} MenuOpt;
+static struct
+{
+ const u8 *tape;
+ const u32 *len;
+ const char *name;
+ const char *author;
+} tape_image_list[] =
+ {
+ {
+ manic_miner_bin,
+ &manic_miner_bin_size,
+ "Manic Miner",
+ "Matt Smith"
+ },
+
+ {
+ ant3d_bin,
+ &ant3d_bin_size,
+ "3D Ant Attack",
+ "Sandy White & Angela Sutherland"
+ },
+
+ {
+ thrust_bin,
+ &thrust_bin_size,
+ "Thrust",
+ "Jeremy Smith & D.Lowe"
+ },
+
+ /* List terminated with 0s
+ */
+ {0}
+ };
+
/* ---------------------------------------- DISPLAY FUNCS
*/
@@ -65,7 +106,7 @@ static void VBlankFunc(void)
static void Splash(void)
{
- static const char *text[]=
+ static const char *start_text[]=
{
"DS-SPEC",
"\177 2006 Ian C",
@@ -73,19 +114,13 @@ static void Splash(void)
"SPECTRUM ROM",
"\177 Amstrad PLC",
" ",
- "Manic Miner",
- "by Matthew Smith",
- " ",
- "Ant Attack by",
- "Sandy White/Angela Sutherland",
- " ",
- "Thrust by",
- "Jeremy Smith and D.Lowe",
- " ",
- "Only play these images if",
- "you legallly own a copy.",
+ NULL
+ };
+
+ static const char *end_text[]=
+ {
" ",
- "PRESS A TO CONTINUE",
+ "PRESS START",
" ",
"http://www.noddybox.co.uk/",
NULL
@@ -93,6 +128,7 @@ static void Splash(void)
sImage img;
int f;
+ int y;
loadPCX(splashimg_bin,&img);
image8to16(&img);
@@ -107,12 +143,37 @@ static void Splash(void)
FB_Box(0,0,SCREEN_WIDTH,SCREEN_HEIGHT,FB_RGB(31,31,31));
- for(f=0;text[f];f++)
+ y=10;
+
+ for(f=0;start_text[f];f++)
+ {
+ FB_Centre(start_text[f],y,FB_RGB(31,31,31),-1);
+ y+=8;
+ }
+
+ for(f=0;f<3 && tape_image_list[f].tape;f++)
+ {
+ FB_Centre(tape_image_list[f].name,y,FB_RGB(31,31,0),-1);
+ y+=8;
+ FB_Centre(tape_image_list[f].author,y,FB_RGB(0,31,31),-1);
+ y+=8;
+ FB_Centre(" ",y,FB_RGB(31,31,31),-1);
+ y+=8;
+ }
+
+ if (tape_image_list[f].tape)
{
- FB_Centre(text[f],10+f*8,FB_RGB(31,31,31),-1);
+ FB_Centre("...more...",y,FB_RGB(31,31,31),-1);
+ y+=8;
}
- while(!(keysDown() & KEY_A))
+ for(f=0;end_text[f];f++)
+ {
+ FB_Centre(end_text[f],y,FB_RGB(31,31,31),-1);
+ y+=8;
+ }
+
+ while(!(keysDown() & KEY_START))
{
swiWaitForVBlank();
}
@@ -170,6 +231,15 @@ int main(int argc, char *argv[])
SPECInit(BG_GFX,z80);
SK_DisplayKeyboard(BG_GFX_SUB);
+ SK_SetSticky(SK_CAPS,1);
+ SK_SetSticky(SK_SYMBOL,1);
+
+ if (tape_image_list[0].tape)
+ {
+ TAPSetTape(tape_image_list[0].tape,
+ *tape_image_list[0].len);
+ }
+
while(1)
{
SoftKeyEvent ev;
@@ -182,26 +252,33 @@ int main(int argc, char *argv[])
{
case SK_ABOUT:
case SK_CONFIG:
- switch(GUI_Menu(main_menu))
+ if (ev.pressed)
{
- case MenuReset:
- SPECReset(z80);
- break;
-
- case MenuSelectTape:
- break;
-
- case MenuStickyOn:
- break;
-
- case MenuStickyOff:
- break;
-
- case MenuDefineJoystick:
- break;
+ switch(GUI_Menu(main_menu))
+ {
+ case MenuReset:
+ SPECReset(z80);
+ break;
+
+ case MenuSelectTape:
+ break;
+
+ case MenuStickyOn:
+ SK_SetSticky(SK_CAPS,1);
+ SK_SetSticky(SK_SYMBOL,1);
+ break;
+
+ case MenuStickyOff:
+ SK_SetSticky(SK_CAPS,0);
+ SK_SetSticky(SK_SYMBOL,0);
+ break;
+
+ case MenuDefineJoystick:
+ break;
+ }
+
+ SK_DisplayKeyboard(BG_GFX_SUB);
}
-
- SK_DisplayKeyboard(BG_GFX_SUB);
break;
default:
@@ -209,11 +286,5 @@ int main(int argc, char *argv[])
break;
}
}
-
- {
- static int pressed=0;
- SPECHandleKey(SK_P,pressed);
- pressed=!pressed;
- }
}
}
diff --git a/source/snap.c b/source/snap.c
index 2e3fb92..7ab783f 100644
--- a/source/snap.c
+++ b/source/snap.c
@@ -72,6 +72,14 @@ static Z80Word GetLSBWord(void)
/* ---------------------------------------- INTERFACES
*/
+void TAPSetTape(Z80Byte *tape, int len)
+{
+ tap_file = tape;
+ tap_len = len;
+ tap_ptr = 0;
+}
+
+
int TAPLoad(Z80Byte id, Z80Word *addr, Z80Word *len, SNAP_Poke poke)
{
Z80Word blen;
diff --git a/source/spec.c b/source/spec.c
index 7137834..10a5d0a 100644
--- a/source/spec.c
+++ b/source/spec.c
@@ -114,9 +114,49 @@ static struct
*/
static Z80Byte matrix[8];
+static struct
+{
+ int row;
+ int bit;
+} key_matrix[]=
+ {
+ {3,0x01}, {3,0x02}, {3,0x04}, {3,0x08}, {3,0x10}, /* 1 - 5 */
+ {4,0x10}, {4,0x08}, {4,0x04}, {4,0x02}, {4,0x01}, /* 6 - 0 */
+ {2,0x01}, {2,0x02}, {2,0x04}, {2,0x08}, {2,0x10}, /* Q - T */
+ {5,0x10}, {5,0x08}, {5,0x04}, {5,0x02}, {5,0x01}, /* Y - P */
+ {1,0x01}, {1,0x02}, {1,0x04}, {1,0x08}, {1,0x10}, /* A - G */
+ {6,0x10}, {6,0x08}, {6,0x04}, {6,0x02}, {6,0x01}, /* H - NL */
+ {0,0x01}, {0,0x02}, {0,0x04}, {0,0x08}, {0,0x10}, /* CAPS - V */
+ {7,0x10}, {7,0x08}, {7,0x04}, {7,0x02}, {7,0x01} /* B - SPACE */
+ };
+
+static int debug_matrix = FALSE;
+
/* ---------------------------------------- PRIVATE FUNCTIONS
*/
+static void FillBox(int x, int y, int w, int h, int colour)
+{
+ int f;
+ uint16 *base;
+
+ colour|=0x8000;
+
+ base=vram+x+y*256;
+
+ while(h--)
+ {
+ for(f=0;f<w;f++)
+ {
+ *(base+f)=colour;
+ }
+
+ base+=256;
+ }
+}
+
+
+
static void DrawScreen(void)
{
int f,r;
@@ -170,6 +210,31 @@ static void DrawScreen(void)
}
}
}
+
+ if (debug_matrix)
+ {
+ int m;
+ int b;
+
+ for(m=0;m<8;m++)
+ {
+ for(b=0;b<8;b++)
+ {
+ uint16 col;
+
+ if (matrix[m]&(1<<b))
+ {
+ col=RGB15(0,31,0);
+ }
+ else
+ {
+ col=RGB15(31,0,0);
+ }
+
+ FillBox((7-b)*5,150+m*5,4,4,col);
+ }
+ }
+ }
}
static void RomPatch(void)
@@ -314,34 +379,25 @@ void SPECInit(uint16 *v, Z80 *z80)
void SPECHandleKey(SoftKey key, int is_pressed)
{
- if (key<=SK_SPACE)
+ if (key<SK_CONFIG)
{
- int row;
- int bit;
-
- row=key/5;
-
- if (row&1)
- {
- bit=5-(key%5);
- }
- else
- {
- bit=(key%5);
- }
-
if (is_pressed)
{
- matrix[row]&=~bit;
+ matrix[key_matrix[key].row]&=~key_matrix[key].bit;
}
else
{
- matrix[row]|=bit;
+ matrix[key_matrix[key].row]|=key_matrix[key].bit;
}
}
else
{
/* TODO: Joysticks! */
+
+ if (is_pressed && key==SK_PAD_SELECT)
+ {
+ debug_matrix = !debug_matrix;
+ }
}
}