From a3b16f394aae46dfd18f5952f16803867bc1f400 Mon Sep 17 00:00:00 2001 From: Ian C Date: Fri, 15 Sep 2006 00:30:18 +0000 Subject: Works enough to run Manic Miner. Slowly. --- .cvsignore | 8 +- include/keyboard.h | 10 ++- source/keyboard.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++---- source/main.c | 151 ++++++++++++++++++++++++++++---------- source/snap.c | 8 ++ source/spec.c | 90 ++++++++++++++++++----- 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 #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,37 +103,159 @@ 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; fkey = 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