summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2007-02-16 01:10:41 +0000
committerIan C <ianc@noddybox.co.uk>2007-02-16 01:10:41 +0000
commitb369f37c6244b5d56742b56f745219fb2544efe2 (patch)
treea838093b033d302e6c7f64e7e255594d490d093a
parent284d8dec91155107f04ad4e2c02338bcb6263abc (diff)
Some hi-res support. Added new config page and averaging touchscreen reads.
In process of writing file selector.
-rw-r--r--fat_patch.sh1
-rw-r--r--include/config.h48
-rw-r--r--include/ds81_debug.h36
-rw-r--r--include/framebuffer.h1
-rw-r--r--include/gui.h2
-rw-r--r--include/touchwrap.h38
-rw-r--r--instructions.txt66
-rw-r--r--mkrelease.sh2
-rw-r--r--source/config.c130
-rw-r--r--source/framebuffer.c15
-rw-r--r--source/gui.c428
-rw-r--r--source/keyboard.c48
-rw-r--r--source/main.c21
-rw-r--r--source/touchwrap.c55
-rw-r--r--source/zx81.c71
15 files changed, 881 insertions, 81 deletions
diff --git a/fat_patch.sh b/fat_patch.sh
index 65af06f..2265d15 100644
--- a/fat_patch.sh
+++ b/fat_patch.sh
@@ -1,3 +1,4 @@
#!/bin/sh
+make
dlditool.exe ../DLDI/mmcf.dldi ds81.nds
dlditool.exe ../DLDI/mmcf.dldi ds81.ds.gba
diff --git a/include/config.h b/include/config.h
new file mode 100644
index 0000000..82c0c4f
--- /dev/null
+++ b/include/config.h
@@ -0,0 +1,48 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2006 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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$
+*/
+#ifndef DS81_CONFIG_H
+#define DS81_CONFIG_H
+
+typedef enum
+{
+ DS81_STICKY_SHIFT,
+ DS81_AVERAGE_TOUCHSCREEN,
+ DS81_NUM_CONFIG_ITEMS
+} DS81_ConfigItem;
+
+/* Returns TRUE if config loaded from FAT device
+*/
+int LoadConfig(void);
+
+/* Returns TRUE if config saved to FAT device
+*/
+int SaveConfig(void);
+
+/* Gets a description for a config item.
+*/
+const char *ConfigDesc(DS81_ConfigItem item);
+
+/* Table of configs. Done like this for simple performance reasons.
+*/
+extern int DS81_Config[/*DS81_ConfigItem item*/];
+
+#endif /* DS81_CONFIG_H */
diff --git a/include/ds81_debug.h b/include/ds81_debug.h
new file mode 100644
index 0000000..82e8c45
--- /dev/null
+++ b/include/ds81_debug.h
@@ -0,0 +1,36 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2006 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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$
+*/
+#ifndef DS81_DEBUG_H
+#define DS81_DEBUG_H
+
+#include "framebuffer.h"
+
+#define DS81_DEBUG(fmt, args...) \
+ do \
+ { \
+ FB_FillBox(0,184,256,8,FB_RGB(10,0,0)); \
+ FB_printf(0,184,FB_RGB(31,31,31),FB_RGB(10,0,0), fmt , ## args);\
+ while (keysDownRepeat()!=KEY_A); \
+ } while(0)
+
+
+#endif /* DS81_DEBUG_H */
diff --git a/include/framebuffer.h b/include/framebuffer.h
index 2fd7bc3..7b04685 100644
--- a/include/framebuffer.h
+++ b/include/framebuffer.h
@@ -27,6 +27,7 @@
void FB_Init(uint16 *vram);
void FB_Print(const char *text, int x, int y, int colour, int paper);
void FB_Centre(const char *text, int y, int colour, int paper);
+void FB_printf(int x, int y, int colour, int paper, const char *format, ...);
void FB_HLine(int x1, int x2, int y, int colour);
void FB_VLine(int x, int y1, int y2, int colour);
void FB_Box(int x, int y, int w, int h, int colour);
diff --git a/include/gui.h b/include/gui.h
index 4a07915..388c200 100644
--- a/include/gui.h
+++ b/include/gui.h
@@ -24,5 +24,7 @@
int GUI_Menu(const char *opts[]);
void GUI_Alert(int fatal, const char *text);
+void GUI_Config(void);
+bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter);
#endif /* DS81_GUI_H */
diff --git a/include/touchwrap.h b/include/touchwrap.h
new file mode 100644
index 0000000..1ba9f90
--- /dev/null
+++ b/include/touchwrap.h
@@ -0,0 +1,38 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2006 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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$
+*/
+#ifndef DS81_TOUCHWRAP_H
+#define DS81_TOUCHWRAP_H
+
+/* Don't know whether I have a problem with my DS or the library, but sometimes
+ the touchscreen value is off (one co-ord generally completely out).
+
+ To alleviate this, and as this is a simple touch screen keyboard, allow
+ touchs to be averaged if the config says so. And averaged touch just means
+ that two touchs have to happen within 5 pixels on X and Y before being
+ allowed.
+
+ If not configured to average, this simply reads the touchscreen position
+ and returns true.
+*/
+int AllowTouch(touchPosition *tp);
+
+#endif /* DS81_TOUCHWRAP_H */
diff --git a/instructions.txt b/instructions.txt
index b7f6089..a929069 100644
--- a/instructions.txt
+++ b/instructions.txt
@@ -56,6 +56,9 @@
I'm probably being overly paranoid there, but better safe than sorry.
+ In any of the following sections where files are mentioned it obviously
+ doesn't apply to the 'nofat' versions.
+
3. Using DS81
-------------
@@ -96,11 +99,12 @@
built into it). The next section has extra information on the
loading of games.
- STICK SHIFT ON
- Sets the shift key so it stays down until pressed again.
-
- STICK SHIFT OFF
- Sets the shift key so it behaves likes all the other keys.
+ CONFIGURE
+ Lets you configure settings (see last section for settings).
+
+ If you press SELECT to exit the configuration screen then the
+ configuration is saved into the file /DS81.CFG which is read on
+ start-up.
MAP JOYPAD TO KEYS
Allows you to redefine the DS's joypad and buttons to ZX81 keys.
@@ -111,7 +115,7 @@
-3. Using the internal tapes on DS81
+4. Using the internal tapes on DS81
-----------------------------------
Games on the ZX81 were supplied on cassette. DS81 includes a few tape
@@ -133,7 +137,7 @@
7. The tape will load and run.
-3. Using external tapes on DS81
+5. Using external tapes on DS81
-------------------------------
If you are using the version of DS81 that allows the use of FAT devices,
@@ -144,9 +148,51 @@
and either put it in the root directory of the FAT device or in a directory
called ZX81SNAP.
- Note that currently hi-resolution games will not work. For that matter,
- it can't be at all guaranteed that all original ZX81 games will work as
- expected. After all, DS81 isn't really a ZX81.
+ Alternatively if you can't remember the names of files, loading "*" will
+ give you with a file selector to select the tape file with.
+
+ Note it can't be at all guaranteed that all original ZX81 games will work
+ as expected. After all, DS81 isn't really a ZX81.
+
+
+6. High Resolution Support
+--------------------------
+
+ There is now some support for high-resolution ZX81 games. Currently
+ it doesn't run quite full speed, and it won't work if the routines are
+ too clever - unfortunately, like Manic Miner where it switches between
+ high and low-resolution in the same frame.
+
+ I know the Software Farms games seem to work (though "Forty Niner"
+ sometimes goes mad on the 2nd level). Steven McDonald's games seem to
+ cause no-problem.
+
+ If you know of a game that seems to cause it real trouble, please let me
+ know -- the high-resolution support is still a bit of a hack whereby the
+ emulator searches memory for the display file on detecting that the I
+ register has changed.
+
+
+7. Configuration Options
+------------------------
+
+ STICKY SHIFT
+
+ This option allows you to decide whether the shift key on the soft
+ keyboard is sticky (toggles when you press it) or acts like the other
+ keys. You should never need to make it non-sticky unless a game needs
+ it.
+
+ AVERAGE TOUCHSCREEN
+
+ This option can be enabled if your touch-screen seems to suffer from
+ jumps (mine seems to once in a while) and causes the soft keyboard to
+ only register touchscreen presses if they are withing 5 pixels of each
+ other over two frames. Your milage my vary, but for me it stops the
+ menu randomly appearing.
+
+ This means that response can be reduced by a frame, but it shouldn't
+ cause problems.
-------------------------------------------------------------------------------
diff --git a/mkrelease.sh b/mkrelease.sh
index 2210ca2..4002f4b 100644
--- a/mkrelease.sh
+++ b/mkrelease.sh
@@ -8,7 +8,7 @@ make ADDITIONAL_CFLAGS="-DDS81_DISABLE_FAT"
mv ds81.nds ds81-nofat.nds
mv ds81.ds.gba ds81-nofat.ds.gba
-rm -f build/main.*
+make clean
make
./fat_patch.sh
diff --git a/source/config.c b/source/config.c
new file mode 100644
index 0000000..b2abec8
--- /dev/null
+++ b/source/config.c
@@ -0,0 +1,130 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2006 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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 <stdio.h>
+#include <string.h>
+
+#include "config.h"
+
+/* ---------------------------------------- PRIVATE DATA
+*/
+const char *conf_filename = "DS81.CFG";
+
+const char *conf_entry[DS81_NUM_CONFIG_ITEMS]=
+{
+ "sticky_shift",
+ "average_touchscreen"
+};
+
+
+/* ---------------------------------------- GLOBAL DATA
+*/
+int DS81_Config[DS81_NUM_CONFIG_ITEMS]=
+{
+ TRUE,
+ FALSE
+};
+
+
+/* ---------------------------------------- PUBLIC INTERFACES
+*/
+int LoadConfig(void)
+{
+ FILE *fp = NULL;
+
+#ifndef DS81_DISABLE_FAT
+ fp=fopen(conf_filename,"r");
+#endif
+
+ if (fp)
+ {
+ char line[80];
+
+ while(fgets(line, sizeof line, fp))
+ {
+ char *p;
+
+ if ((p = strchr(line, '=')))
+ {
+ int f;
+
+ for(f=0;f<DS81_NUM_CONFIG_ITEMS;f++)
+ {
+ if (strncmp(line, conf_entry[f],
+ strlen(conf_entry[f])) == 0)
+ {
+ DS81_Config[f] = (*(p+1) == '1');
+ }
+ }
+
+ }
+ }
+
+ fclose(fp);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+int SaveConfig(void)
+{
+ FILE *fp = NULL;
+
+#ifndef DS81_DISABLE_FAT
+ fp=fopen(conf_filename,"w");
+#endif
+
+ if (fp)
+ {
+ int f;
+
+ for(f=0;f<DS81_NUM_CONFIG_ITEMS;f++)
+ {
+ fprintf(fp,"%s=%d\n",conf_entry[f],DS81_Config[f]);
+ }
+
+ fclose(fp);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+const char *ConfigDesc(DS81_ConfigItem item)
+{
+ switch(item)
+ {
+ case DS81_STICKY_SHIFT:
+ return "STICKY SHIFT";
+
+ case DS81_AVERAGE_TOUCHSCREEN:
+ return "AVERAGE TOUCHSCREEN";
+
+ default:
+ return "UNKNOWN";
+ }
+}
+
diff --git a/source/framebuffer.c b/source/framebuffer.c
index ef66235..691862e 100644
--- a/source/framebuffer.c
+++ b/source/framebuffer.c
@@ -21,6 +21,8 @@
*/
#include <nds.h>
+#include <stdio.h>
+#include <stdarg.h>
#include <string.h>
/* ---------------------------------------- STATIC DATA
@@ -183,6 +185,19 @@ void FB_Centre(const char *text, int y, int colour, int paper)
}
+void FB_printf(int x, int y, int colour, int paper, const char *format, ...)
+{
+ char buff[80];
+ va_list va;
+
+ va_start(va,format);
+ vsnprintf(buff,sizeof buff,format,va);
+ va_end(va);
+
+ FB_Print(buff,x,y,colour,paper);
+}
+
+
void FB_HLine(int x1, int x2, int y, int colour)
{
uint16 *line;
diff --git a/source/gui.c b/source/gui.c
index 713ad02..7e55b97 100644
--- a/source/gui.c
+++ b/source/gui.c
@@ -20,10 +20,160 @@
$Id$
*/
-#include <nds.h>
+#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
+#include <nds.h>
+
+#include <sys/dir.h>
#include "framebuffer.h"
+#include "config.h"
+
+
+/* ---------------------------------------- PRIVATE INTERFACES - PATH HANDLING
+*/
+#define FSEL_FILENAME_LEN 20
+#define FSEL_LINES 15
+#define FSEL_MAX_FILES 512
+
+#define FSEL_LIST_Y 12
+#define FSEL_LIST_H FSEL_LINES*8
+
+typedef struct
+{
+ char name[FSEL_FILENAME_LEN+1];
+ int is_dir;
+ int size;
+} FSEL_File;
+
+static FSEL_File fsel[FSEL_MAX_FILES];
+
+
+static void CheckPath(char *path)
+{
+ size_t l;
+
+ l = strlen(path);
+
+ if (l == 1)
+ {
+ path[0] = '/';
+ }
+ else
+ {
+ if (path[l-1] != '/')
+ {
+ path[l] = '/';
+ path[l+1] = 0;
+ }
+ }
+}
+
+
+static void AddPath(char *path, const char *dir)
+{
+ if (strcmp(dir,"..") == 0)
+ {
+ char *p;
+
+ p = strrchr(path,'/');
+
+ if (p && p!=path)
+ {
+ *p = 0;
+ }
+ }
+ else
+ {
+ strcat(path,dir);
+ strcat(path,"/");
+ }
+}
+
+
+
+
+static int SortFiles(const void *a, const void *b)
+{
+ const FSEL_File *f1;
+ const FSEL_File *f2;
+
+ f1 = (const FSEL_File *)a;
+ f2 = (const FSEL_File *)b;
+
+ if (f1->is_dir == f1->is_dir)
+ {
+ return strcmp(f1->name, f2->name);
+ }
+ else if (f1->is_dir)
+ {
+ return -1;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+
+static int ValidFilename(const char *name, int is_dir, const char *filter)
+{
+ size_t l;
+ size_t f;
+
+ l = strlen(name);
+
+ if (l > FSEL_FILENAME_LEN)
+ return 0;
+
+ if (strcmp(name,".") == 0)
+ return 0;
+
+ if (is_dir || !filter)
+ return 1;
+
+ f = strlen(filter);
+
+ if (l > f)
+ {
+ if (strcmp(name+l-f,filter) == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int LoadDir(const char *path, const char *filter)
+{
+ DIR_ITER *dir;
+ struct stat st;
+ char name[FILENAME_MAX];
+ int no = 0;
+
+ if ((dir = diropen(path)))
+ {
+ while(no < FSEL_MAX_FILES && dirnext(dir,name,&st) == 0)
+ {
+ if (ValidFilename(name, (st.st_mode & S_IFDIR), filter))
+ {
+ strcpy(fsel[no].name,name);
+ fsel[no].is_dir = (st.st_mode & S_IFDIR);
+ fsel[no].size = (int)st.st_size;
+ no++;
+ }
+ }
+
+ dirclose(dir);
+
+ qsort(fsel,no,sizeof fsel[0],SortFiles);
+ }
+
+ return no;
+}
/* ---------------------------------------- PUBLIC INTERFACES
@@ -189,3 +339,279 @@ void GUI_Alert(int fatal, const char *text)
}
}
}
+
+
+void GUI_Config(void)
+{
+ int sel;
+ DS81_ConfigItem f;
+ bool done;
+ bool save;
+
+ sel = 0;
+ done = false;
+ save = false;
+
+ FB_Clear();
+
+ FB_Centre("Up/Down to select",140,FB_RGB(31,31,0),-1);
+ FB_Centre("A to toggle",150,FB_RGB(31,31,0),-1);
+ FB_Centre("Or use touchscreen",160,FB_RGB(31,31,0),-1);
+ FB_Centre("START to finish",170,FB_RGB(31,31,0),-1);
+
+#ifndef DS81_DISABLE_FAT
+ FB_Centre("SELECT to save to \\DS81.CFG",180,FB_RGB(31,31,0),-1);
+#endif
+
+ for(f=0;f<DS81_NUM_CONFIG_ITEMS;f++)
+ {
+ FB_Print(ConfigDesc(f),14,20+f*14,FB_RGB(31,31,31),-1);
+ }
+
+ while(!done)
+ {
+ uint32 key=0;
+
+ for(f=0;f<DS81_NUM_CONFIG_ITEMS;f++)
+ {
+ FB_FillBox(2,20+f*14-1,10,10,
+ DS81_Config[f] ? FB_RGB(31,31,31):FB_RGB(0,0,0));
+
+ FB_Box(2,20+f*14-1,10,10,FB_RGB(18,18,18));
+ }
+
+ FB_Box(0,20+sel*14-3,SCREEN_WIDTH-1,14,FB_RGB(18,18,31));
+
+ do
+ {
+ swiWaitForVBlank();
+ } while(!(key=keysDownRepeat()));
+
+ FB_Box(0,20+sel*14-3,SCREEN_WIDTH-1,14,FB_RGB(0,0,0));
+
+ if (key & KEY_START)
+ {
+ done=true;
+ }
+#ifndef DS81_DISABLE_FAT
+ else if (key & KEY_SELECT)
+ {
+ done=true;
+ save=true;
+ }
+#endif
+ else if (key & KEY_A)
+ {
+ DS81_Config[sel] = !DS81_Config[sel];
+ }
+ else if ((key & KEY_UP) && sel)
+ {
+ sel--;
+ }
+ else if ((key & KEY_DOWN) && sel<DS81_NUM_CONFIG_ITEMS-1)
+ {
+ sel++;
+ }
+ else if (key & KEY_TOUCH)
+ {
+ touchPosition tp = touchReadXY();
+ int nsel;
+
+ nsel = (tp.py-18)/14;
+
+ if (nsel>=0 && nsel<DS81_NUM_CONFIG_ITEMS)
+ {
+ sel = nsel;
+ DS81_Config[sel] = !DS81_Config[sel];
+ }
+ }
+ }
+
+ if (save)
+ {
+ SaveConfig();
+ }
+}
+
+
+bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter)
+{
+ int no;
+ int sel;
+ int top;
+ int bar_size;
+ double bar_step;
+ bool done;
+ bool ret;
+ int pen;
+ int paper;
+ int off;
+ int f;
+
+ CheckPath(pwd);
+
+ FB_Clear();
+
+ FB_printf(0,0,FB_RGB(0,0,0),FB_RGB(22,22,22),"%-31.31s",pwd);
+
+ no = LoadDir(pwd,filter);
+
+ sel = 0;
+ top = 0;
+ done = false;
+ ret = false;
+
+ if (no<=FSEL_LINES)
+ {
+ bar_step = 0;
+ bar_size = FSEL_LIST_H;
+ }
+ else
+ {
+ bar_step = FSEL_LIST_H/(double)no;
+ bar_size = bar_step*FSEL_LINES;
+ }
+
+ while(!done)
+ {
+ uint32 key=0;
+
+ for (f=0;f<FSEL_LINES;f++)
+ {
+ off = f + top;
+
+ if (off<no)
+ {
+ if (off == sel)
+ {
+ pen = FB_RGB(0,0,0);
+ paper = FB_RGB(31,31,31);
+ }
+ else
+ {
+ pen = FB_RGB(31,31,31);
+ paper = FB_RGB(0,0,0);
+ }
+
+ FB_printf(8,FSEL_LIST_Y+f*8,pen,paper,
+ "%-*s %s",
+ FSEL_FILENAME_LEN,
+ fsel[off].name,
+ fsel[off].is_dir ? "DIR" : " ");
+ }
+ else
+ {
+ FB_printf(8,FSEL_LIST_Y+f*8,FB_RGB(31,31,31),FB_RGB(0,0,0),
+ "%-*s %s",
+ FSEL_FILENAME_LEN,
+ off==0 ? "No Files!" : "",
+ "");
+ }
+ }
+
+ FB_FillBox(240,FSEL_LIST_Y,16,FSEL_LIST_H,FB_RGB(10,10,10));
+ FB_FillBox(240,FSEL_LIST_Y+top*bar_step,16,bar_size,FB_RGB(31,31,31));
+
+ do
+ {
+ swiWaitForVBlank();
+ } while(!(key=keysDownRepeat()));
+
+ if (key & KEY_UP)
+ {
+ if (sel)
+ {
+ sel--;
+
+ if (sel<top)
+ {
+ top--;
+ }
+ }
+ }
+ else if (key & KEY_DOWN)
+ {
+ if (sel < (no-1))
+ {
+ sel++;
+
+ if (sel >= (top+FSEL_LINES))
+ {
+ top++;
+ }
+ }
+ }
+ else if (key & KEY_L)
+ {
+ if (sel)
+ {
+ sel-=FSEL_LINES;
+
+ if (sel < 0)
+ {
+ sel = 0;
+ }
+
+ top = sel;
+ }
+ }
+ else if (key & KEY_R)
+ {
+ if (sel < (no-1))
+ {
+ sel+=FSEL_LINES;
+
+ if (sel > (no-1))
+ {
+ sel = no-1;
+ }
+
+ top = sel - FSEL_LINES + 1;
+
+ if (top < 0)
+ {
+ top = 0;
+ }
+ }
+ }
+ else if (key & KEY_A)
+ {
+ if (fsel[sel].is_dir)
+ {
+ AddPath(pwd,fsel[sel].name);
+
+ no = LoadDir(pwd,filter);
+
+ sel = 0;
+ top = 0;
+
+ if (no<=FSEL_LINES)
+ {
+ bar_step = 0;
+ bar_size = FSEL_LIST_H;
+ }
+ else
+ {
+ bar_step = FSEL_LIST_H/(double)no;
+ bar_size = bar_step*FSEL_LINES;
+ }
+ }
+ else
+ {
+ done = true;
+ ret = true;
+
+ strcpy(selected_file,pwd);
+ strcat(selected_file,fsel[sel].name);
+ }
+ }
+ else if (key & KEY_START)
+ {
+ done=true;
+ }
+ }
+
+ while (keysHeld());
+
+ return ret;
+}
diff --git a/source/keyboard.c b/source/keyboard.c
index cb6a932..37ae4ef 100644
--- a/source/keyboard.c
+++ b/source/keyboard.c
@@ -24,6 +24,7 @@
#include "keyboard.h"
#include "framebuffer.h"
+#include "touchwrap.h"
#include "keyb_bin.h"
/* ---------------------------------------- STATIC DATA
@@ -166,36 +167,39 @@ static int GetEvent(SoftKeyEvent *ev, int map)
*/
if (keys & KEY_TOUCH)
{
- touchPosition tp=touchReadXY();
+ touchPosition tp;
- if (tp.py<21 || tp.py>165)
+ if (AllowTouch(&tp))
{
- key_state[SK_CONFIG].new_state = TRUE;
- }
- else
- {
- SoftKey press;
-
- press = LocatePress(&tp);
-
- if (press != NUM_SOFT_KEYS)
+ if (tp.py<21 || tp.py>165)
+ {
+ key_state[SK_CONFIG].new_state = TRUE;
+ }
+ else
{
- key_state[press].handled = TRUE;
+ SoftKey press;
+
+ press = LocatePress(&tp);
- if (key_state[press].is_sticky)
+ if (press != NUM_SOFT_KEYS)
{
- if (last != press)
+ key_state[press].handled = TRUE;
+
+ if (key_state[press].is_sticky)
{
- key_state[press].new_state =
- !key_state[press].state;
+ if (last != press)
+ {
+ key_state[press].new_state =
+ !key_state[press].state;
+ }
+ }
+ else
+ {
+ key_state[press].new_state = TRUE;
}
- }
- else
- {
- key_state[press].new_state = TRUE;
- }
- last = press;
+ last = press;
+ }
}
}
}
diff --git a/source/main.c b/source/main.c
index aed05f5..f2b0e70 100644
--- a/source/main.c
+++ b/source/main.c
@@ -32,6 +32,7 @@
#include "z80.h"
#include "zx81.h"
#include "tapes.h"
+#include "config.h"
#include "splashimg_bin.h"
#include "rom_font_bin.h"
@@ -42,8 +43,7 @@ static const char *main_menu[]=
{
"Reset ZX81",
"Select Tape",
- "Sticky Shift On",
- "Sticky Shift Off",
+ "Configure",
"Map Joypad to Keys",
"Cancel",
NULL
@@ -53,8 +53,7 @@ typedef enum
{
MenuReset,
MenuSelectTape,
- MenuStickyOn,
- MenuStickyOff,
+ MenuConfigure,
MenuMapJoypad,
} MenuOpt;
@@ -301,9 +300,11 @@ int main(int argc, char *argv[])
Splash();
+ LoadConfig();
+
SK_DisplayKeyboard(BG_GFX_SUB);
- SK_SetSticky(SK_SHIFT,1);
+ SK_SetSticky(SK_SHIFT,DS81_Config[DS81_STICKY_SHIFT]);
while(1)
{
@@ -329,12 +330,10 @@ int main(int argc, char *argv[])
SelectTape();
break;
- case MenuStickyOn:
- SK_SetSticky(SK_SHIFT,1);
- break;
-
- case MenuStickyOff:
- SK_SetSticky(SK_SHIFT,0);
+ case MenuConfigure:
+ GUI_Config();
+ SK_SetSticky(SK_SHIFT,
+ DS81_Config[DS81_STICKY_SHIFT]);
break;
case MenuMapJoypad:
diff --git a/source/touchwrap.c b/source/touchwrap.c
new file mode 100644
index 0000000..4fa373b
--- /dev/null
+++ b/source/touchwrap.c
@@ -0,0 +1,55 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2006 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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 <stdlib.h>
+
+#include "touchwrap.h"
+#include "config.h"
+
+/* ---------------------------------------- PUBLIC INTERFACES
+*/
+int AllowTouch(touchPosition *tp)
+{
+ static touchPosition last;
+ int16 dx;
+ int16 dy;
+ int res;
+
+ *tp = touchReadXY();
+
+ if (DS81_Config[DS81_AVERAGE_TOUCHSCREEN])
+ {
+ dx = last.px - tp->px;
+ dy = last.py - tp->py;
+
+ res = (abs(dx) < 5 && abs(dy) < 5);
+ }
+ else
+ {
+ res = TRUE;
+ }
+
+ last = *tp;
+
+ return res;
+}
diff --git a/source/zx81.c b/source/zx81.c
index 9a053b5..7964ed1 100644
--- a/source/zx81.c
+++ b/source/zx81.c
@@ -41,9 +41,6 @@
#define FALSE 0
#endif
-#define MAX_FNAME_LEN 30
-
-
/* ---------------------------------------- STATICS
*/
#define ROMLEN 0x2000
@@ -99,6 +96,8 @@ static int enable_filesystem;
static const Z80Byte *tape_image;
static int tape_len;
+static char last_dir[FILENAME_MAX] = "/";
+
/* GFX vars
*/
static uint16 *txt_screen;
@@ -259,58 +258,58 @@ static Z80Byte FromASCII(char c)
*/
static FILE *OpenTapeFile(Z80Word addr)
{
+ static const char zx_chars[] = "\"#$:?()><=+-*/;,."
+ "0123456789"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
FILE *fp;
- char fn[MAX_FNAME_LEN];
+ char fn[FILENAME_MAX];
int f;
int done;
- f=0;
- done=FALSE;
+ fp = NULL;
+ f = 0;
+ done = FALSE;
- while(f<(MAX_FNAME_LEN-3) && !done)
+ while(f<(FILENAME_MAX-3) && !done)
{
int ch;
- ch=mem[addr++];
+ ch = mem[addr++];
if (ch&0x80)
{
- done=TRUE;
- ch&=0x7f;
+ done = TRUE;
+ ch &= 0x7f;
}
- switch(ch)
+ if (ch>=11 && ch<=63)
{
- case 22:
- fn[f++]='-';
- break;
-
- case 27:
- fn[f++]='.';
-
- default:
- if (ch>=28 && ch<=37)
- {
- fn[f++]='0'+(ch-28);
- }
- else if (ch>=38 && ch<=63)
- {
- fn[f++]='A'+(ch-38);
- }
- break;
+ fn[f++] = zx_chars[ch-11];
}
}
- fn[f++]='.';
- fn[f++]='P';
- fn[f]=0;
+ if (fn[0] == '*')
+ {
+ if (GUI_FileSelect(last_dir,fn,".P"))
+ {
+ fp = fopen(fn,"rb");
+ }
- if (!(fp=fopen(fn,"rb")))
+ SK_DisplayKeyboard(BG_GFX_SUB);
+ }
+ else
{
- char full_fn[MAX_FNAME_LEN+11]="\\ZX81SNAP\\";
+ fn[f++] = '.';
+ fn[f++] = 'P';
+ fn[f] = 0;
- strcat(full_fn,fn);
- fp=fopen(full_fn,"rb");
+ if (!(fp = fopen(fn,"rb")))
+ {
+ char full_fn[FILENAME_MAX+11] = "/ZX81SNAP/";
+
+ strcat(full_fn,fn);
+ fp = fopen(full_fn,"rb");
+ }
}
return fp;
@@ -378,7 +377,7 @@ static void DrawScreen_HIRES(Z80 *z80)
bmp = bmp_screen;
table = z80->I << 8;
- /* scr is increment in both loops so that it can skip of the end-of-line
+ /* scr is increment in both loops so that it can skip the end-of-line
character
*/
for(y=0; y<192; y++)