Hi all!
As some people have been mentioned, the NanoNote looks interesting for
playing interactive fiction (a. k. a. text adventures). OpenWRT
contains frotz already, but for better text rendering quality, I've
ported sfrotz by Aldo Cumani, which is based on SLD. I've sent patches
to Aldo, but not gotten a response yet. I'm posting them here in case
you are interested.
How to build sfrotz for the NanoNote:
1. Download and untar sfrotz 0.02 from <http://ifarchive.org/>: e. g.
<http://ifarchive.org/if-archive/infocom/interpreters/frotz/sfrotz002.tar.gz>.
2. Apply the attached patches, preferredly in this order:
- sfrotz002-bugfix.diff: as the name says ...
- sfrotz002-dirlist.diff: useful when the file selection dialog is not
usable
- sfrotz002-nanonote.diff: changes necessary for the NanoNote
- sfrotz002-nanonote-jobcontrol.diff: adds a suspend function (Ctrl+Z)
- sfrotz002-sfrotzrc.diff: reads .sfrotz from $HOME
3. Take a look at the makefile and "README.NanoNote".
Compiling is a bit kludgy, feel free to clean up the makefile.
Also, I want to "get rid" of the changes and do not plan any further
development, so I'm not going to maintain it. Instead, I'm working on
a Glk implementation from scratch (see <http://eblong.com/zarf/glk/>).
Sebastian
diff -Nru sfrotz002/sf_util.c sfrotz002-bugfix/sf_util.c
--- sfrotz002/sf_util.c 2011-02-10 11:43:13.000000000 +0100
+++ sfrotz002-bugfix/sf_util.c 2011-06-03 12:22:23.000000000 +0200
@@ -547,7 +547,13 @@
print_string (default_name);
print_string ("\": ");
- read_string (MAX_FILE_NAME - 4, (byte *) file_name);
+ // Read and convert from zword* to char*.
+ zword buf[MAX_FILE_NAME - 4 + 1];
+ read_string (MAX_FILE_NAME - 4, buf);
+ int i;
+ for(i = 0; buf[i]; i++)
+ file_name[i] = buf[i];
+ file_name[i] = 0;
/* Use the default name if nothing was typed */
diff -Nru sfrotz002/sf_util.c sfrotz002-dirlist/sf_util.c
--- sfrotz002/sf_util.c 2011-02-10 11:43:13.000000000 +0100
+++ sfrotz002-dirlist/sf_util.c 2011-06-03 12:54:55.000000000 +0200
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <dirent.h>
#include <zlib.h>
@@ -498,6 +499,39 @@
return buf;
}
+static void print_saved_files (void)
+{
+ print_string("(Saved files:");
+
+ DIR *dir = opendir(".");
+ if(dir == NULL)
+ print_string("<cannot read \".\">");
+ else {
+ int found = 0;
+ struct dirent *de;
+ do {
+ if((de = readdir(dir))) {
+ int l = strlen(de->d_name);
+ if(l > 4 && strcmp(de->d_name + l - 4, ".sav") == 0) {
+ char name[254];
+ name[0] = ' ';
+ memcpy(name + 1, de->d_name, l - 4);
+ name[l - 4 + 1] = 0;
+ print_string(name);
+ found = 1;
+ }
+ }
+ } while(de);
+
+ if(!found)
+ print_string("<none>");
+
+ closedir(dir);
+ }
+
+ print_string(")\n");
+}
+
// fdialog( existing, defname, filter, title, &resultstr)
static int ingame_read_file_name (char *file_name, const char *default_name, int flag);
static int dialog_read_file_name (char *file_name, const char *default_name, int flag);
@@ -543,7 +577,9 @@
print_string ("Enter file name (\"");
print_string (extension);
- print_string ("\" will be added).\nDefault is \"");
+ print_string ("\" will be added).\n");
+ print_saved_files ();
+ print_string ("Default is \"");
print_string (default_name);
print_string ("\": ");
diff -Nru sfrotz002/makefile sfrotz002-nanonote/makefile
--- sfrotz002/makefile 2010-12-16 23:27:50.000000000 +0100
+++ sfrotz002-nanonote/makefile 2011-06-02 14:47:33.000000000 +0200
@@ -40,6 +40,29 @@
LIBS = -ljpeg -lpng -lz -lSDL -lSDL_mixer $(SRLIB)
+ifeq ($(MAKECMDGOALS),sfrotz-nn)
+ NANONOTE=1
+endif
+
+ifeq ($(MAKECMDGOALS),copy-nn)
+ NANONOTE=1
+endif
+
+ifdef NANONOTE
+ # Compiling for the NanoNote is a bit tricky. This should work as described
+ # at <http://en.qi-hardware.com/wiki/Compiling_for_the_NanoNote>.
+ STAGING_DIR = $(HOME)/nanonote/openwrt-xburst/staging_dir
+ ROOT_DIR = $(STAGING_DIR)/target-mipsel_uClibc-0.9.30.1
+ CC = $(STAGING_DIR)/toolchain-mipsel_gcc-4.3.3+cs_uClibc-0.9.30.1/usr/bin/mipsel-openwrt-linux-uclibc-gcc
+ LD = $(CC)
+ CFLAGS = -DNANONOTE -g $(OPTS) $(DEFS) -I$(ROOT_DIR)/usr/include
+ LIBS = -Wl,-rpath-link=$(ROOT_DIR)/usr/lib -ljpeg -lpng -lz -lSDL -lSDL_mixer $(SRLIB) -L$(ROOT_DIR)/usr/lib
+
+ # libsamplerate not avaibalbe on the NanoNote?
+ SRSRC =
+ SRLIB =
+endif
+
SFROTZ = buffer.c err.c fastmem.c files.c getopt.c hotkey.c input.c \
main.c math.c object.c process.c quetzal.c random.c redirect.c \
screen.c sound.c stream.c table.c text.c variable.c blorblib.c
@@ -68,6 +91,9 @@
sfrotz: $(OBJS)
$(LD) $(LDFLAGS) -o sfrotz -Xlinker -Map -Xlinker mymap.map $(OBJS) $(IMGLIB) $(LIBS) $(FTLIBS)
+sfrotz-nn: $(OBJS)
+ $(LD) $(LDFLAGS) -o sfrotz-nn -Xlinker -Map -Xlinker mymap.map $(OBJS) $(IMGLIB) $(LIBS) $(FTLIBS)
+
#################################################################
SOURCES = $(SFROTZ) $(SSDL)
@@ -145,4 +171,11 @@
clean:
rm -f *.o
- rm -f sfrotz
+ rm -f sfrotz sfrotz-nn
+
+# "-o UserKnownHostsFile=/dev/null" and "-o StrictHostKeyChecking=no" turns
+# off RSA key checking, which is useful if you reflash the NanoNote often,
+# or have got more than one NanoNote.
+copy-nn: sfrotz-nn .sfrotzrc-nn
+ scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no sfrotz-nn [email protected]:/usr/bin/sfrotz
+ scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no .sfrotzrc-nn [email protected]:~/.sfrotzrc
diff -Nru sfrotz002/README-NanoNote sfrotz002-nanonote/README-NanoNote
--- sfrotz002/README-NanoNote 1970-01-01 01:00:00.000000000 +0100
+++ sfrotz002-nanonote/README-NanoNote 2011-06-03 15:23:27.000000000 +0200
@@ -0,0 +1,28 @@
+This version adds changes which are necessary for the Ben Nanonote
+(see <https://sharism.cc/> for more informations). All other versions
+still build the same way as in the original sfrotz, the changes have
+been enclosed by "#ifdef NANONOTE" or similar. It has been tested with
+OpenWRT; for other distributions (e. g. Jlime), some more changes may
+be necessary.
+
+To compile the program for the NanoNote, run "make sfrotz-nn", which
+generates sfrotz-nn, a binary for the NanoNote, and "make copy-nn",
+which copies the binary and a specific resource file, .sfrotz-nn, on
+the NanoNote, assuming standard configuration (see makefile for
+details).
+
+Generation is not clean: after building either one of both versions,
+you should run "make clean", so that the object files are rebuild for
+the desired platform.
+
+Compiling for the NanoNote is a bit tricky; refer to
+<http://en.qi-hardware.com/wiki/Compiling_for_the_NanoNote> for
+further informations.
+
+Saving and restoring games will not use the file selection dialog,
+which is too large for the NanoNote screen. Some simple hacks will
+make the file selection dialog possible, but since the NanoNote does
+not have a pointing device (yes, only keyboard), it would be unusable;
+for this reason, this dialog is not used at all.
+
+Sebastian Geerken (s ~dot~ geerken ~at~ ping ~dot~ de)
diff -Nru sfrotz002/.sfrotzrc-nn sfrotz002-nanonote/.sfrotzrc-nn
--- sfrotz002/.sfrotzrc-nn 1970-01-01 01:00:00.000000000 +0100
+++ sfrotz002-nanonote/.sfrotzrc-nn 2011-06-02 14:30:31.000000000 +0200
@@ -0,0 +1,41 @@
+
+[Interpreter]
+SaveNames=date
+
+[Window]
+AcWidth=320
+AcHeight=240
+
+[Display]
+# Uncomment this, if you prefer black on white instead of white on blue.
+#Background=16777215
+#Foreground=0
+
+[Fonts]
+antialias=1
+fontdir=/usr/share/fonts/ttf-dejavu
+
+textroman=DejaVuSans.ttf@12
+textbold=DejaVuSans-Bold.ttf@12
+textitalic=DejaVuSans-Oblique.ttf@12
+textbolditalic=DejaVuSans-BoldOblique.ttf@12
+
+#textroman=DejaVuSerif.ttf@12
+#textbold=DejaVuSerif-Bold.ttf@12
+#textitalic=DejaVuSerif-Italic.ttf@12
+#textbolditalic=DejaVuSerif-BoldItalic.ttf@12
+
+# Rather small, but this way, 80 characters fit into one line, which
+# some games depend on.
+fixedroman=DejaVuSansMono.ttf@9
+fixedbold=DejaVuSansMono-Bold.ttf@9
+fixeditalic=DejaVuSansMono-Oblique.ttf@9
+fixedbolditalic=DejaVuSansMono-BoldOblique.ttf@9
+
+[Resources]
+Dir=./
+Pict=PIC%d
+Snd=SND%d
+
+[Audio]
+#Frequency=22050
diff -Nru sfrotz002/sf_sig.c sfrotz002-nanonote/sf_sig.c
--- sfrotz002/sf_sig.c 2010-12-07 11:09:04.000000000 +0100
+++ sfrotz002-nanonote/sf_sig.c 2011-06-01 21:43:58.000000000 +0200
@@ -3,7 +3,7 @@
#include "sf_frotz.h"
-#ifdef WIN32
+#if defined WIN32 || defined NANONOTE
static void resethandlers()
{
diff -Nru sfrotz002/sf_video.c sfrotz002-nanonote/sf_video.c
--- sfrotz002/sf_video.c 2011-02-09 16:54:36.000000000 +0100
+++ sfrotz002-nanonote/sf_video.c 2011-06-02 00:11:15.000000000 +0200
@@ -420,6 +420,11 @@
os_fatal("Couldn't initialize SDL: %s", SDL_GetError());
}
+#ifdef NANONOTE
+ // The NanoNote does not have a pointing device, so a cursor would be annoying.
+ SDL_ShowCursor(SDL_DISABLE);
+#endif
+
CLEANREG(cleanvideo);
isfullscreen = full;
@@ -594,8 +599,15 @@
// emergency exit
if (((e->key.keysym.mod & 0xfff) == (KMOD_LALT | KMOD_LCTRL)) && (e->key.keysym.sym == 'x'))
os_fatal("Emergency exit!\n\n(Control-Alt-X pressed)");
+
+#ifdef NANONOTE
+ // On the NanoNote, KMOD_RALT defines the red shift key, which is
+ // handled elsewhere.
+ if ((e->key.keysym.mod & KMOD_LALT) == KMOD_LALT)
+#else
if (((e->key.keysym.mod & KMOD_LALT) == KMOD_LALT) ||
((e->key.keysym.mod & KMOD_RALT) == KMOD_RALT))
+#endif
{
if (e->key.keysym.sym == 'q')
{
@@ -654,6 +666,27 @@
case SDLK_F12: return ZC_FKEY_MIN+11;
default: break;
}
+
+#ifdef NANONOTE
+ // NanoNote speficic keys. Unfortunately not handled by SDL.
+ // KMOD_LCTRL defines the "Fn" key. */
+ if ((e->key.keysym.mod & KMOD_LCTRL) == KMOD_LCTRL) {
+ switch (e->key.keysym.sym) {
+ case '/': return '0';
+ case 'n': return '1';
+ case 'm': return '2';
+ case '=': return '3';
+ case 'j': return '4';
+ case 'k': return '5';
+ case 'l': return '6';
+ case 'u': return '7';
+ case 'i': return '8';
+ case 'o': return '9';
+ default: return 0;
+ }
+ }
+#endif
+
c = e->key.keysym.unicode;
if ((c >= 32 && c <= 126) || (c >= 160)) return c;
return 0;
diff -Nru sfrotz002-nanonote/sf_video.c sfrotz002-nanonote-jobcontrol/sf_video.c
--- sfrotz002-nanonote/sf_video.c 2011-06-02 00:11:15.000000000 +0200
+++ sfrotz002-nanonote-jobcontrol/sf_video.c 2011-06-03 15:21:16.000000000 +0200
@@ -570,6 +570,69 @@
dirty = 1;
}
+// ...
+Uint8 *saved_buf = NULL;
+static int saved_w, saved_h, saved_bpp;
+
+// Called, when the suspended process is woken up again (e. g. by "fg" in
+// a shell).
+static void handle_cont()
+{
+ // Do not call handle_cont() again.
+ signal(SIGCONT, SIG_DFL);
+
+ // Reinit SDL again and restore screen contents.
+ if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE | SDL_INIT_TIMER
+ | SDL_INIT_AUDIO) < 0)
+ os_fatal("Couldn't initialize SDL: %s", SDL_GetError());
+
+ SDL_ShowCursor(SDL_DISABLE);
+ CLEANREG(cleanvideo);
+
+ screen = SDL_SetVideoMode(saved_w, saved_h, 8 * saved_bpp, 0);
+ if(screen == NULL)
+ os_fatal("Couldn't set %dx%dx%d video mode: %s",
+ saved_w, saved_h, 8 * saved_bpp, SDL_GetError());
+
+ SDL_EnableUNICODE(1);
+ SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
+ SDL_AddTimer(SFdticks,mytimer,NULL);
+
+ SDL_LockSurface(screen);
+ memcpy(screen->pixels, saved_buf, saved_w * saved_h * saved_bpp);
+ SDL_UnlockSurface(screen);
+ free(saved_buf);
+ SDL_Flip(screen);
+}
+
+// Suspend the process, by sending SIGSTOP to oneself.
+static void suspend()
+{
+ // 1. Save the contents of the screen (before calling SQL_Quit below).
+ // (Hopefully, this is all which must be saved, but I haven't yet
+ // encountered a problem. -- SG)
+ saved_w = screen->w;
+ saved_h = screen->h;
+ saved_bpp = screen->format->BytesPerPixel;
+
+ int size = saved_w * saved_h * saved_bpp;
+ saved_buf = malloc(size);
+ SDL_LockSurface(screen);
+ memcpy(saved_buf, screen->pixels, size);
+ SDL_UnlockSurface(screen);
+
+ // 2. Ensure that the process can be woken up again.
+ signal(SIGCONT, handle_cont);
+
+ // 3. SDL_Quit will have different effects: on X11, the window is closed,
+ // in framebuffer mode, the text mode is restored.
+ SDL_Quit();
+
+ // 4. Finally, stop.
+ kill(getpid(), SIGSTOP);
+}
+
+
static ulong mytimeout;
int mouse_button;
static int numAltQ = 0;
@@ -600,6 +663,19 @@
if (((e->key.keysym.mod & 0xfff) == (KMOD_LALT | KMOD_LCTRL)) && (e->key.keysym.sym == 'x'))
os_fatal("Emergency exit!\n\n(Control-Alt-X pressed)");
+ // suspend
+#ifdef NANONOTE
+ // On Nanonote, KMOD_LCTRL is the "fn" key.
+ if ((e->key.keysym.mod & KMOD_RCTRL) == KMOD_RCTRL
+#else
+ if (((e->key.keysym.mod & KMOD_LCTRL) == KMOD_LCTRL ||
+ (e->key.keysym.mod & KMOD_RCTRL) == KMOD_RCTRL)
+#endif
+ && (e->key.keysym.sym == 'z')) {
+ suspend();
+ return 0;
+ }
+
#ifdef NANONOTE
// On the NanoNote, KMOD_RALT defines the red shift key, which is
// handled elsewhere.
diff -Nru sfrotz002/main.c sfrotz002-sfrotzrc/main.c
--- sfrotz002/main.c 2007-05-01 18:49:18.000000000 +0200
+++ sfrotz002-sfrotzrc/main.c 2011-06-03 11:57:51.000000000 +0200
@@ -40,6 +40,8 @@
extern void init_undo (void);
extern void reset_memory (void);
+extern char m_setupfile[FILENAME_MAX + 1];
+
/* Story file name, id number and size */
char *story_name = 0;
@@ -169,6 +171,13 @@
int cdecl main (int argc, char *argv[])
{
+ // Initialize some default values.
+ char *home;
+
+ if((home = getenv("HOME")) != NULL)
+ sprintf(m_setupfile, "%s/.sfrotzrc", home);
+ else
+ strcpy(m_setupfile, ".sfrotzrc");
os_process_arguments (argc, argv);
//printf("after os_process_arguments\n");
diff -Nru sfrotz002/sf_frotz.h sfrotz002-sfrotzrc/sf_frotz.h
--- sfrotz002/sf_frotz.h 2011-02-10 11:43:46.000000000 +0100
+++ sfrotz002-sfrotzrc/sf_frotz.h 2011-06-03 12:04:53.000000000 +0200
@@ -94,7 +94,7 @@
extern volatile bool SFticked;
extern char * m_fontdir;
extern bool m_aafonts;
-extern char * m_setupfile;
+extern char m_setupfile[FILENAME_MAX + 1];
extern int m_frequency;
extern double m_gamma;
diff -Nru sfrotz002/sf_resource.c sfrotz002-sfrotzrc/sf_resource.c
--- sfrotz002/sf_resource.c 2011-02-10 11:45:16.000000000 +0100
+++ sfrotz002-sfrotzrc/sf_resource.c 2011-06-03 12:07:23.000000000 +0200
@@ -40,7 +40,7 @@
bool m_aafonts = 0;
char m_names_format = 0;
char * m_reslist_file = NULL;
-char * m_setupfile = ".sfrotzrc";
+char m_setupfile[FILENAME_MAX + 1];
extern int m_frequency;
static int countedpics = 0;
diff -Nru sfrotz002/sf_util.c sfrotz002-sfrotzrc/sf_util.c
--- sfrotz002/sf_util.c 2011-02-10 11:43:13.000000000 +0100
+++ sfrotz002-sfrotzrc/sf_util.c 2011-06-03 12:09:28.000000000 +0200
@@ -94,7 +94,7 @@
int m_fullscreen = -1;
int m_reqW = 0, m_reqH = 0;
int m_vga_fonts = 0;
-extern char * m_setupfile;
+extern char m_setupfile[FILENAME_MAX + 1];
extern char m_names_format;
static char user_names_format = 0;
extern char *m_reslist_file;
@@ -234,7 +234,7 @@
if (c == '@')
m_reslist_file = optarg;
if (c == 'I')
- m_setupfile = optarg;
+ strcpy(m_setupfile, optarg);
if (c == 'f')
user_foreground = num;
if (c == 'F')
_______________________________________________
Qi Hardware Discussion List
Mail to list (members only): [email protected]
Subscribe or Unsubscribe:
http://lists.en.qi-hardware.com/mailman/listinfo/discussion