$(CURSES_DIR)/ux_screen.o \
$(CURSES_DIR)/ux_text.o \
$(CURSES_DIR)/ux_blorb.o \
- $(CURSES_DIR)/ux_audio_none.o \
- $(CURSES_DIR)/ux_audio_oss.o
+ $(CURSES_DIR)/ux_audio.o
+# $(CURSES_DIR)/ux_audio_none.o \
+# $(CURSES_DIR)/ux_audio_oss.o
DUMB_DIR = $(SRCDIR)/dumb
DUMB_TARGET = $(SRCDIR)/frotz_dumb.a
FLAGS = $(OPTS) $(CURSES_DEFS) $(INCL)
-
$(NAME): $(NAME)-curses
curses: $(NAME)-curses
$(NAME)-curses: $(COMMON_TARGET) $(CURSES_TARGET) $(BLORB_TARGET)
#define bb_err_NotAMap (4)
#define bb_err_Format (5)
#define bb_err_NotFound (6)
+#define bb_err_NoBlorb (7)
/* Methods for loading a chunk */
#define bb_method_DontLoad (0)
extern void script_open (void);
extern void script_close (void);
-extern FILE *os_path_open (const char *, const char *);
extern FILE *os_load_story (void);
extern zword save_quetzal (FILE *, FILE *);
/* Open story file */
-/*
- if ((story_fp = os_path_open(f_setup.story_file, "rb")) == NULL)
- os_fatal ("Cannot open story file");
-*/
if ((story_fp = os_load_story()) == NULL)
os_fatal ("Cannot open story file");
#define EXT_SAVE ".qzl"
#define EXT_SCRIPT ".scr"
#define EXT_BLORB ".blb"
-#define EXT_BLORB2 ".zblb"
-#define EXT_BLORB3 ".blorb"
-#define EXT_BLORB4 ".zblorb"
+#define EXT_BLORBLONG ".blorb"
#define EXT_COMMAND ".rec"
#define EXT_AUX ".aux"
+/*
+ * ux_blorb.c - Blorb routines
+ * David Griffith <dave@661.org>
+ *
+ * This file is part of Frotz.
+ *
+ * Frotz 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.
+ *
+ * Frotz 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
+ */
+
+#define __UNIX_PORT_FILE
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <getopt.h>
+
+#include <unistd.h>
+#include <libgen.h>
#include <math.h>
-#include <errno.h>
-#include "../common/frotz.h"
-#include "../blorb/blorb.h"
-#include "../blorb/blorblow.h"
+#ifdef USE_NCURSES_H
+#include <ncurses.h>
+#else
+#include <curses.h>
+#endif
+
+#include "ux_frotz.h"
#include "ux_blorb.h"
+f_setup_t f_setup;
+u_setup_t u_setup;
-char *findchunk(char *data, char *string, int length)
+
+/*
+ * isblorb
+ *
+ * Returns 1 if this file is a Blorb file, 0 if not.
+ *
+ * FIXME Is there a potential endian problem here?
+ */
+static int isblorb(FILE *fp)
{
- char *mydata = data+12;
- while (TRUE) {
- if (strncmp((char*)mydata, string, 4) == 0)
- return mydata+8;
+ char mybuf[4];
+
+ if (fp == NULL)
+ return 0;
+
+ fread(mybuf, 1, 4, fp);
+ if (strncmp(mybuf, "FORM", 4))
+ return 0;
+
+ fseek(fp, 4, SEEK_CUR);
+ fread(mybuf, 1, 4, fp);
+
+ if (strncmp(mybuf, "IFRS", 4))
+ return 0;
+
+ return 1;
+}
+
+
+/*
+ * ux_init_blorb
+ *
+ * Check if we're opening a Blorb file directly. If not, check
+ * to see if there's a seperate Blorb file that looks like it goes
+ * along with this Zcode file. If we have a Blorb file one way or the
+ * other, make a Blorb map. If we opened a Blorb file directly, that
+ * means that our executable is in that file and therefore we will look
+ * for a ZCOD chunk and record its location so os_load_story() can find it.
+ *
+ */
+bb_err_t ux_init_blorb(char *filename)
+{
+ FILE *fp;
+ char *p;
+ char *mystring;
+ int len1;
+ int len2;
+
+ bb_err_t blorb_err;
+
+ if ((fp = fopen(filename, "rb")) == NULL)
+ return bb_err_Read;
- mydata += ReadLong(mydata+4)+8;
+ printf("filename: %s\n", filename);
- if ((mydata - data) >= length)
- break;
+ /* Is this really a Blorb file? If not, maybe we're loading a naked
+ * zcode file and our resources are in a seperate blorb file.
+ */
+ if (isblorb(fp)) { /* Now we know to look */
+ u_setup.exec_in_blorb = 1; /* for zcode in the blorb */
+ } else {
+ len1 = strlen(filename) + strlen(EXT_BLORB);
+ len2 = strlen(filename) + strlen(EXT_BLORBLONG);
+
+ mystring = malloc(len2 * sizeof(char) + 1);
+ strncat(mystring, filename, len1 * sizeof(char));
+ p = rindex(mystring, '.');
+ *p = '\0';
+
+ strncat(mystring, EXT_BLORB, len1 * sizeof(char));
+
+ /* Check if foo.blb is there. */
+ if ((fp = fopen(mystring, "rb")) == NULL) {
+ p = rindex(mystring, '.');
+ *p = '\0';
+ strncat(mystring, EXT_BLORBLONG, len2 * sizeof(char));
+ fp = fopen(mystring, "rb");
}
- return NULL;
+ if (fp == NULL || !isblorb(fp)) /* No matching blorbs found. */
+ return bb_err_NoBlorb;
+
+ u_setup.exec_in_blorb = 0; /* Using naked zcode with */
+ } /* resources in seperate blorb. */
+
+ /* Create a Blorb map from this file.
+ * This will fail if the file is not a valid Blorb file.
+ * From this map, we can now pick out any resource we need.
+ */
+ blorb_err = bb_create_map(fp, &blorb_map);
+ if (blorb_err != bb_err_None)
+ return bb_err_Format;
+
+ /* Locate the EXEC chunk within the blorb file and record its
+ * location so os_load_story() can find it.
+ */
+ if (u_setup.exec_in_blorb) {
+ blorb_err = bb_load_chunk_by_type(blorb_map, bb_method_FilePos,
+ &blorb_res, bb_make_id('Z','C','O','D'), 0);
+ }
+
+ if (blorb_err == bb_err_None) {
+ u_setup.exec_in_blorb = 1;
+ u_setup.use_blorb = 1;
+ }
+
+ fclose(fp);
+ return blorb_err;
+}
+
+
+char *findchunk(char *data, char *string, int length)
+{
+ char *mydata = data+12;
+ while (TRUE) {
+ if (strncmp((char*)mydata, string, 4) == 0)
+ return mydata+8;
+ mydata += ReadLong(mydata+4)+8;
+ if ((mydata - data) >= length)
+ break;
+ }
+ return NULL;
}
unsigned short ReadShort(const unsigned char *bytes)
{
- return (unsigned short)(
- ((unsigned short)(bytes[0] & 0xFF) << 8) |
- ((unsigned short)(bytes[1] & 0xFF)));
+ return (unsigned short)(
+ ((unsigned short)(bytes[0] & 0xFF) << 8) |
+ ((unsigned short)(bytes[1] & 0xFF)));
}
+
unsigned long ReadLong(const unsigned char *bytes)
{
- return (unsigned long)(
- ((unsigned long)(bytes[0] & 0xFF) << 24) |
- ((unsigned long)(bytes[1] & 0xFF) << 16) |
- ((unsigned long)(bytes[2] & 0xFF) << 8) |
- ((unsigned long)(bytes[3] & 0xFF)));
+ return (unsigned long)(
+ ((unsigned long)(bytes[0] & 0xFF) << 24) |
+ ((unsigned long)(bytes[1] & 0xFF) << 16) |
+ ((unsigned long)(bytes[2] & 0xFF) << 8) |
+ ((unsigned long)(bytes[3] & 0xFF)));
}
+
double ReadExtended(const unsigned char *bytes)
{
- double f;
- int expon;
- unsigned long hiMant, loMant;
+ double f;
+ int expon;
+ unsigned long hiMant, loMant;
- expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
- hiMant = ReadLong(bytes+2);
- loMant = ReadLong(bytes+6);
+ expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
+ hiMant = ReadLong(bytes+2);
+ loMant = ReadLong(bytes+6);
- if (expon == 0 && hiMant == 0 && loMant == 0)
- f = 0;
+ if (expon == 0 && hiMant == 0 && loMant == 0)
+ f = 0;
+ else {
+ if (expon == 0x7FFF) /* Infinity or NaN */
+ f = -1;
else {
- if (expon == 0x7FFF) /* Infinity or NaN */
- f = -1;
- else {
- expon -= 16383;
- /* must #include <math.h> or these won't work */
- f = ldexp(UnsignedToFloat(hiMant),expon -= 31);
- f += ldexp(UnsignedToFloat(loMant),expon -= 32);
- }
+ expon -= 16383;
+ /* must #include <math.h> or these won't work */
+ f = ldexp(UnsignedToFloat(hiMant),expon -= 31);
+ f += ldexp(UnsignedToFloat(loMant),expon -= 32);
}
+ }
- if (bytes[0] & 0x80)
- return -f;
- return f;
+ if (bytes[0] & 0x80)
+ return -f;
+ return f;
}
-
-
-/* /home/dave/zcode/mystory.z5 */
-/* /home/dave/zcode/mystory.blb */
} blorb_data_t;
*/
-bb_err_t blorb_err;
+typedef struct {
+ bb_result_t bbres;
+ ulong type;
+ FILE *file;
+} myresource;
+
+//bb_err_t blorb_err;
bb_map_t *blorb_map;
bb_result_t blorb_res;
#include <ctype.h>
-/*
- * os_path_open
- *
- * Open a file in the current directory. If this fails, then search the
- * directories in the ZCODE_PATH environmental variable. If that's not
- * defined, search INFOCOM_PATH.
- *
- */
-
-FILE *os_path_open(const char *name, const char *mode)
-{
- FILE *fp;
- char buf[FILENAME_MAX + 1];
- char *p;
-
- /* Let's see if the file is in the currect directory */
- /* or if the user gave us a full path. */
- if ((fp = fopen(name, mode))) {
- return fp;
- }
-
- /* If zcodepath is defined in a config file, check that path. */
- /* If we find the file a match in that path, great. */
- /* Otherwise, check some environmental variables. */
- if (f_setup.zcode_path != NULL) {
- if ((fp = pathopen(name, f_setup.zcode_path, mode, buf)) != NULL) {
- strncpy(f_setup.story_name, buf, FILENAME_MAX);
- return fp;
- }
- }
-
- if ( (p = getenv(PATH1) ) == NULL)
- p = getenv(PATH2);
-
- if (p != NULL) {
- fp = pathopen(name, p, mode, buf);
- strncpy(f_setup.story_name, buf, FILENAME_MAX);
- return fp;
- }
- return NULL; /* give up */
-} /* os_path_open() */
-
/*
* pathopen
*
void os_process_arguments (int argc, char *argv[])
{
int c, i;
-
char *p = NULL;
- char *blorb_ext = NULL;
-
char *home;
char configfile[FILENAME_MAX + 1];
/* Now strip off the extension. */
p = rindex(f_setup.story_name, '.');
- if ((p != NULL) &&
- ((strcmp(p,EXT_BLORB2) == 0) ||
- (strcmp(p,EXT_BLORB3) == 0) ||
- (strcmp(p,EXT_BLORB4) == 0) ) )
- {
- blorb_ext = strdup(p);
- }
- else
- {
- blorb_ext = strdup(EXT_BLORB);
- }
-
- /* Get rid of extensions with 1 to 6 character extensions. */
- /* This will take care of an extension like ".zblorb". */
- /* More than that, there might be something weird going on */
- /* which is not our concern. */
- if (p != NULL) {
- if (strlen(p) >= 2 && strlen(p) <= 7) {
- *p = '\0'; /* extension removed */
- }
- }
+ *p = 0;
f_setup.story_path = strdup(dirname(argv[optind]));
- /* Create nice default file names */
-
- u_setup.blorb_name = malloc(FILENAME_MAX * sizeof(char));
- strncpy(u_setup.blorb_name, f_setup.story_name,
- strlen(f_setup.story_name) +1);
- strncat(u_setup.blorb_name, blorb_ext, strlen(blorb_ext));
-
- u_setup.blorb_file = malloc(strlen(f_setup.story_path) *
- sizeof(char) + strlen(u_setup.blorb_name) * sizeof(char) + 4);
- strncpy(u_setup.blorb_file, f_setup.story_path,
- strlen(f_setup.story_path));
- strncat(u_setup.blorb_file, "/", 1);
- strncat(u_setup.blorb_file, u_setup.blorb_name,
- strlen(u_setup.blorb_name) + 1);
-
- f_setup.script_name = malloc(strlen(f_setup.story_name) * sizeof(char) + 5);
- strncpy(f_setup.script_name, f_setup.story_name, strlen(f_setup.story_name));
+ f_setup.script_name = malloc((strlen(f_setup.story_name) + strlen(EXT_SCRIPT)) * sizeof(char) + 1);
+ strncpy(f_setup.script_name, f_setup.story_name, strlen(f_setup.story_name) + 1);
strncat(f_setup.script_name, EXT_SCRIPT, strlen(EXT_SCRIPT));
- f_setup.command_name = malloc(strlen(f_setup.story_name) * sizeof(char) + 5);
- strncpy(f_setup.command_name, f_setup.story_name, strlen(f_setup.story_name));
+ f_setup.command_name = malloc((strlen(f_setup.story_name) + strlen(EXT_COMMAND)) * sizeof(char) + 1);
+ strncpy(f_setup.command_name, f_setup.story_name, strlen(f_setup.story_name) + 1);
strncat(f_setup.command_name, EXT_COMMAND, strlen(EXT_COMMAND));
- f_setup.save_name = malloc(strlen(f_setup.story_name) * sizeof(char) + 5);
- strncpy(f_setup.save_name, f_setup.story_name, strlen(f_setup.story_name));
+ f_setup.save_name = malloc((strlen(f_setup.story_name) + strlen(EXT_SAVE)) * sizeof(char) + 1);
+ strncpy(f_setup.save_name, f_setup.story_name, strlen(f_setup.story_name) + 1);
strncat(f_setup.save_name, EXT_SAVE, strlen(EXT_SAVE));
- f_setup.aux_name = malloc(strlen(f_setup.story_name) * sizeof(char) + 5);
- strncpy(f_setup.aux_name, f_setup.story_name, strlen(f_setup.story_name));
+ f_setup.aux_name = malloc((strlen(f_setup.story_name) + strlen(EXT_AUX)) * sizeof(char) + 1);
+ strncpy(f_setup.aux_name, f_setup.story_name, strlen(f_setup.story_name) + 1);
strncat(f_setup.aux_name, EXT_AUX, strlen(EXT_AUX));
- switch (ux_init_blorb()) {
+/*
+ printf("f_setup.story_file %s\n", f_setup.story_file);
+ printf("f_setup.story_name %s\n", f_setup.story_name);
+ printf("f_setup.story_path %s\n", f_setup.story_path);
+*/
+
+ switch (c = ux_init_blorb(f_setup.story_file)) {
case bb_err_Format:
printf("Blorb file loaded, but unable to build map.\n\n");
break;
break;
}
- printf("u_setup.blorb_file %s\n", u_setup.blorb_file);
- printf("u_setup.blorb_name %s\n", u_setup.blorb_name);
}/* os_process_arguments */
}/* os_random_seed */
-/*
- * os_path_open
- *
- * Open a file in the current directory. If this fails, then search the
- * directories in the ZCODE_PATH environmental variable. If that's not
- * defined, search INFOCOM_PATH.
- *
- */
-
-FILE *os_path_open(const char *name, const char *mode)
-{
- FILE *fp;
- char buf[FILENAME_MAX + 1];
- char *p;
-
- /* Let's see if the file is in the currect directory */
- /* or if the user gave us a full path. */
- if ((fp = fopen(name, mode))) {
- return fp;
- }
-
- /* If zcodepath is defined in a config file, check that path. */
- /* If we find the file a match in that path, great. */
- /* Otherwise, check some environmental variables. */
- if (f_setup.zcode_path != NULL) {
- if ((fp = pathopen(name, f_setup.zcode_path, mode, buf)) != NULL) {
- strncpy(f_setup.story_name, buf, FILENAME_MAX);
- return fp;
- }
- }
-
- if ( (p = getenv(PATH1) ) == NULL)
- p = getenv(PATH2);
-
- if (p != NULL) {
- fp = pathopen(name, p, mode, buf);
- strncpy(f_setup.story_name, buf, FILENAME_MAX);
- return fp;
- }
- return NULL; /* give up */
-} /* os_path_open() */
-
/*
* os_load_story
*
{
FILE *fp;
+printf("Loading %s\n", f_setup.story_file);
+
+ fp = fopen(f_setup.story_file, "rb");
+
+
/* Did we build a valid blorb map? */
- if (u_setup.exec_in_blorb) {
- fp = fopen(u_setup.blorb_file, "rb");
+ if (u_setup.exec_in_blorb)
fseek(fp, blorb_res.data.startpos, SEEK_SET);
- } else {
- fp = fopen(f_setup.story_file, "rb");
- }
+
return fp;
}
}
-int ux_init_blorb(void)
-{
- FILE *blorbfile;
-
- /* If the filename given on the command line is the same as our
- * computed blorb filename, then we will assume the executable
- * is contained in the blorb file.
- */
-
- if (strncmp(basename(f_setup.story_file),
- basename(u_setup.blorb_file), 55) == 0) {
- if ((blorbfile = fopen(u_setup.blorb_file, "rb")) == NULL)
- return bb_err_Read;
- blorb_err = bb_create_map(blorbfile, &blorb_map);
- if (blorb_err != bb_err_None)
- return bb_err_Format;
-
- /* Now we need to locate the EXEC chunk within the blorb file
- * and present it to the rest of the program as a file stream.
- */
-
- blorb_err = bb_load_chunk_by_type(blorb_map, bb_method_FilePos,
- &blorb_res, bb_make_id('Z','C','O','D'), 0);
-
- if (blorb_err == bb_err_None) {
- u_setup.exec_in_blorb = 1;
- u_setup.use_blorb = 1;
- }
- return blorb_err;
- }
-}
int current_color; /* ux_text.c ux_screen.c */
bool color_enabled; /* ux_init.c ux_pic.c ux_text.c */
- char *blorb_name;
- char *blorb_file;
+ char *blorb_name; /* probably should be removed */
+ char *blorb_file; /* probably should be removed */
+
bool use_blorb;
bool exec_in_blorb;