Media support added! Probably has bugs.
This commit is contained in:
parent
0d16275af3
commit
e15a7d0df0
18 changed files with 2093 additions and 1904 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
@ -1,2 +1,4 @@
|
||||||
*.sta filter=lfs diff=lfs merge=lfs -text
|
*.sta filter=lfs diff=lfs merge=lfs -text
|
||||||
*.z5 filter=lfs diff=lfs merge=lfs -text
|
*.z5 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.z8 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.vec filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|
95
ansiterm.c
95
ansiterm.c
|
@ -13,38 +13,38 @@ segment "ansiterm";
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int x;
|
byte x;
|
||||||
int y;
|
byte y;
|
||||||
} Vector2T;
|
} PositionT;
|
||||||
|
|
||||||
|
|
||||||
static int _columns = 40;
|
static byte _columns = 40;
|
||||||
static int _rows = 25;
|
static byte _rows = 25;
|
||||||
static int _xoff = 0;
|
static byte _xoff = 0;
|
||||||
static int _yoff = 0;
|
static byte _yoff = 0;
|
||||||
static bool _escFound = false;
|
static bool _escFound = false;
|
||||||
static bool _inEscape = false;
|
static bool _inEscape = false;
|
||||||
static bool _bold = false;
|
static bool _bold = false;
|
||||||
static bool _blink = false;
|
static bool _blink = false;
|
||||||
static bool _reverse = false;
|
static bool _reverse = false;
|
||||||
static bool _destructiveBS = false;
|
static bool _destructiveBS = false;
|
||||||
static int _foreground = 7;
|
static byte _foreground = 7;
|
||||||
static int _background = 0;
|
static byte _background = 0;
|
||||||
static int _fColor = 7;
|
static byte _fColor = 7;
|
||||||
static int _bColor = 0;
|
static byte _bColor = 0;
|
||||||
static int _number = 0;
|
static byte _number = 0;
|
||||||
static int _parameters[5];
|
static byte _parameters[5];
|
||||||
static int _parameterCount = 0;
|
static byte _parameterCount = 0;
|
||||||
static jlStaT *_ansiFont = NULL;
|
static byte _hiddenLines = 0;
|
||||||
static Vector2T _cursorSave;
|
static jlStaT *_ansiFont = NULL;
|
||||||
static Vector2T _cursor;
|
static PositionT _cursorSave;
|
||||||
static Vector2T *_screenBuffer = NULL;
|
static PositionT _cursor;
|
||||||
|
static PositionT *_screenBuffer = NULL;
|
||||||
|
|
||||||
|
|
||||||
void termDebug(const char *what, ...);
|
void termDebug(const char *what, ...);
|
||||||
bool termParseANSI(char c);
|
bool termParseANSI(char c);
|
||||||
void termRenderCharacterAtCursor(byte c);
|
void termRenderCharacterAtCursor(byte c);
|
||||||
void termRepaint(void);
|
|
||||||
void termResetSequence(void);
|
void termResetSequence(void);
|
||||||
void termScrollUp(void);
|
void termScrollUp(void);
|
||||||
void termUpdateColors(void);
|
void termUpdateColors(void);
|
||||||
|
@ -81,13 +81,18 @@ void termDestruciveBackspace(bool dbs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void termGetCursor(int *x, int *y) {
|
void termGetCursor(byte *x, byte *y) {
|
||||||
*x = _cursor.x;
|
*x = _cursor.x;
|
||||||
*y = _cursor.y;
|
*y = _cursor.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void termMoveCursor(int x, int y) {
|
void termHideTopLines(byte count) {
|
||||||
|
_hiddenLines = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void termMoveCursor(byte x, byte y) {
|
||||||
if (x < 1) {
|
if (x < 1) {
|
||||||
_cursor.x = 1;
|
_cursor.x = 1;
|
||||||
termDebug("Attempt to position cursor too far left: %d", x);
|
termDebug("Attempt to position cursor too far left: %d", x);
|
||||||
|
@ -114,13 +119,13 @@ void termMoveCursor(int x, int y) {
|
||||||
|
|
||||||
|
|
||||||
bool termParseANSI(char c) {
|
bool termParseANSI(char c) {
|
||||||
int x;
|
bool x;
|
||||||
int y;
|
bool y;
|
||||||
int oldX;
|
bool oldX;
|
||||||
int cx;
|
bool cx;
|
||||||
int p;
|
int p;
|
||||||
bool updateDisplay = false;
|
bool updateDisplay = false;
|
||||||
Vector2T cursor = _cursor;
|
PositionT cursor = _cursor;
|
||||||
|
|
||||||
// Find leading ESC character.
|
// Find leading ESC character.
|
||||||
if ((c == (char)27) && !_escFound && !_inEscape) {
|
if ((c == (char)27) && !_escFound && !_inEscape) {
|
||||||
|
@ -389,7 +394,7 @@ bool termParseANSI(char c) {
|
||||||
default:
|
default:
|
||||||
// Number?
|
// Number?
|
||||||
if ((c >= '0') && (c <= '9')) {
|
if ((c >= '0') && (c <= '9')) {
|
||||||
_number = _number * 10 + (c - '0');
|
_number = (byte)(_number * 10 + (c - '0'));
|
||||||
} else {
|
} else {
|
||||||
termDebug("Unknown sequence: %d", (int)c);
|
termDebug("Unknown sequence: %d", (int)c);
|
||||||
termResetSequence();
|
termResetSequence();
|
||||||
|
@ -489,23 +494,25 @@ void termPrintChar(char c) {
|
||||||
|
|
||||||
|
|
||||||
void termRenderCharacterAtCursor(byte c) {
|
void termRenderCharacterAtCursor(byte c) {
|
||||||
int r = (_reverse ? 7 : 0);
|
byte r = (_reverse ? 7 : 0);
|
||||||
int cx = c % 40;
|
byte cx = c % 40;
|
||||||
int cy = (c / 40) + r;
|
byte cy = (c / 40) + r;
|
||||||
int i = ((_cursor.y - 1) * _columns) + (_cursor.x - 1);
|
int i = ((_cursor.y - 1) * _columns) + (_cursor.x - 1);
|
||||||
_screenBuffer[i].x = cx;
|
_screenBuffer[i].x = cx;
|
||||||
_screenBuffer[i].y = cy;
|
_screenBuffer[i].y = cy;
|
||||||
jlDrawBlit8x8(_ansiFont, cx, cy, _cursor.x - 1 + _xoff, _cursor.y - 1 + _yoff);
|
if (_cursor.y > _hiddenLines) {
|
||||||
|
jlDrawBlit8x8(_ansiFont, cx, cy, _cursor.x - 1 + _xoff, _cursor.y - 1 + _yoff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void termRepaint(void) {
|
void termRepaint(void) {
|
||||||
int i = 0;
|
int i = _hiddenLines * _columns;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
for (y=0; y<_rows; y++) {
|
for (y=_hiddenLines; y<_rows; y++) {
|
||||||
for (x=0; x<_columns; x++) {
|
for (x=0; x<_columns; x++) {
|
||||||
jlDrawBlit8x8(_ansiFont, _screenBuffer[i].x, _screenBuffer[i].y, x, y);
|
jlDrawBlit8x8(_ansiFont, _screenBuffer[i].x, _screenBuffer[i].y, x + _xoff, y + _yoff);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,7 +553,7 @@ void termScrollUp(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void termStart(jlStaT *font, int xoff, int yoff, int cols, int rows) {
|
void termStart(jlStaT *font, byte xoff, byte yoff, byte cols, byte rows) {
|
||||||
_ansiFont = font;
|
_ansiFont = font;
|
||||||
_xoff = xoff;
|
_xoff = xoff;
|
||||||
_yoff = yoff;
|
_yoff = yoff;
|
||||||
|
@ -556,7 +563,7 @@ void termStart(jlStaT *font, int xoff, int yoff, int cols, int rows) {
|
||||||
_cursorSave.y = 1;
|
_cursorSave.y = 1;
|
||||||
_cursor.x = 1;
|
_cursor.x = 1;
|
||||||
_cursor.y = 1;
|
_cursor.y = 1;
|
||||||
_screenBuffer = (Vector2T *)jlMalloc(sizeof(Vector2T) * (size_t)(_columns * _rows));
|
_screenBuffer = (PositionT *)jlMalloc(sizeof(PositionT) * (size_t)(_columns * _rows));
|
||||||
termClearScreen();
|
termClearScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,13 +5,15 @@
|
||||||
|
|
||||||
void termClearScreen(void);
|
void termClearScreen(void);
|
||||||
void termDestruciveBackspace(bool dbs);
|
void termDestruciveBackspace(bool dbs);
|
||||||
void termGetCursor(int *x, int *y);
|
void termGetCursor(byte *x, byte *y);
|
||||||
void termMoveCursor(int x, int y);
|
void termHideTopLines(byte count);
|
||||||
|
void termMoveCursor(byte x, byte y);
|
||||||
void termPrint(char *string);
|
void termPrint(char *string);
|
||||||
void termPrintChar(char c);
|
void termPrintChar(char c);
|
||||||
|
void termRepaint(void);
|
||||||
void termRestoreCursor(void);
|
void termRestoreCursor(void);
|
||||||
void termSaveCursor(void);
|
void termSaveCursor(void);
|
||||||
void termStart(jlStaT *font, int xoff, int yoff, int cols, int rows);
|
void termStart(jlStaT *font, byte xoff, byte yoff, byte cols, byte rows);
|
||||||
void termStop(void);
|
void termStop(void);
|
||||||
|
|
||||||
#endif // _H_ANSITERM_
|
#endif // _H_ANSITERM_
|
||||||
|
|
21
fileio.c
21
fileio.c
|
@ -52,8 +52,8 @@ static FILE *rfp = NULL; /* Record file pointer */
|
||||||
static char gfpbuffer[BUFSIZ];
|
static char gfpbuffer[BUFSIZ];
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
static char sfpbuffer[BUFSIZ];
|
//static char sfpbuffer[BUFSIZ];
|
||||||
static char rfpbuffer[BUFSIZ];
|
//static char rfpbuffer[BUFSIZ];
|
||||||
|
|
||||||
char save_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1] = "story.sav";
|
char save_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1] = "story.sav";
|
||||||
char script_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1] = "story.scr";
|
char script_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1] = "story.scr";
|
||||||
|
@ -123,7 +123,8 @@ void set_names( const char *storyname )
|
||||||
|
|
||||||
void open_story( const char *storyname )
|
void open_story( const char *storyname )
|
||||||
{
|
{
|
||||||
char *path, *p;
|
char *path = NULL;
|
||||||
|
char *p = NULL;
|
||||||
char tmp[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1];
|
char tmp[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1];
|
||||||
|
|
||||||
// if ( !STANDALONE_FLAG )
|
// if ( !STANDALONE_FLAG )
|
||||||
|
@ -297,7 +298,7 @@ void read_page( int page, void *buffer )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* Read failed. Are we in the last page? */
|
/* Read failed. Are we in the last page? */
|
||||||
file_size = ( unsigned long ) h_file_size *story_scaler;
|
file_size = ( unsigned long )(h_file_size *story_scaler);
|
||||||
|
|
||||||
pages = ( unsigned int ) ( ( unsigned long ) file_size / PAGE_SIZE );
|
pages = ( unsigned int ) ( ( unsigned long ) file_size / PAGE_SIZE );
|
||||||
offset = ( unsigned int ) ( ( unsigned long ) file_size & PAGE_MASK );
|
offset = ( unsigned int ) ( ( unsigned long ) file_size & PAGE_MASK );
|
||||||
|
@ -401,7 +402,7 @@ void z_verify( void )
|
||||||
|
|
||||||
/* Calculate game file dimensions */
|
/* Calculate game file dimensions */
|
||||||
|
|
||||||
file_size = ( unsigned long ) h_file_size *story_scaler;
|
file_size = ( unsigned long )(h_file_size *story_scaler);
|
||||||
|
|
||||||
pages = ( unsigned int ) ( ( unsigned long ) file_size / PAGE_SIZE );
|
pages = ( unsigned int ) ( ( unsigned long ) file_size / PAGE_SIZE );
|
||||||
offset = ( unsigned int ) file_size & PAGE_MASK;
|
offset = ( unsigned int ) file_size & PAGE_MASK;
|
||||||
|
@ -410,7 +411,7 @@ void z_verify( void )
|
||||||
|
|
||||||
for ( i = 0; i <= pages; i++ )
|
for ( i = 0; i <= pages; i++ )
|
||||||
{
|
{
|
||||||
read_page( i, buffer );
|
read_page( (int)i, buffer );
|
||||||
start = ( i == 0 ) ? 64 : 0;
|
start = ( i == 0 ) ? 64 : 0;
|
||||||
end = ( i == pages ) ? offset : PAGE_SIZE;
|
end = ( i == pages ) ? offset : PAGE_SIZE;
|
||||||
for ( j = start; j < end; j++ )
|
for ( j = start; j < end; j++ )
|
||||||
|
@ -448,7 +449,7 @@ static void get_default_name( char *default_name, zword_t addr )
|
||||||
{
|
{
|
||||||
addr++;
|
addr++;
|
||||||
c = get_byte( addr );
|
c = get_byte( addr );
|
||||||
default_name[i] = c;
|
default_name[i] = (char)c;
|
||||||
}
|
}
|
||||||
default_name[i] = 0;
|
default_name[i] = 0;
|
||||||
|
|
||||||
|
@ -503,7 +504,7 @@ int z_save( int argc, zword_t table, zword_t bytes, zword_t name )
|
||||||
setbuf( afp, afpbuffer );
|
setbuf( afp, afpbuffer );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
status = fwrite( datap + table, bytes, 1, afp );
|
status = (int)fwrite( datap + table, bytes, 1, afp );
|
||||||
|
|
||||||
fclose( afp );
|
fclose( afp );
|
||||||
|
|
||||||
|
@ -591,7 +592,7 @@ int z_restore( int argc, zword_t table, zword_t bytes, zword_t name )
|
||||||
setbuf( afp, afpbuffer );
|
setbuf( afp, afpbuffer );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
status = fread( datap + table, bytes, 1, afp );
|
status = (int)fread( datap + table, bytes, 1, afp );
|
||||||
|
|
||||||
fclose( afp );
|
fclose( afp );
|
||||||
|
|
||||||
|
@ -1315,7 +1316,7 @@ int playback_line( int buflen, char *buffer, int *read_size )
|
||||||
{
|
{
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
}
|
}
|
||||||
*read_size = strlen( buffer );
|
*read_size = (int)strlen( buffer );
|
||||||
output_line( buffer );
|
output_line( buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
3
gamedata.dat
Normal file
3
gamedata.dat
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
IF Engine Test Game
|
||||||
|
output.z8
|
||||||
|
8x8thin.sta
|
BIN
gamedata.z5
BIN
gamedata.z5
Binary file not shown.
|
@ -45,7 +45,6 @@ INCLUDEPATH += \
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$JOEY_HEADERS \
|
$$JOEY_HEADERS \
|
||||||
ansiterm.h \
|
ansiterm.h \
|
||||||
jzip.h \
|
|
||||||
ztypes.h
|
ztypes.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
|
653
input.c
653
input.c
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
/* $Id: input.c,v 1.3 2000/07/05 15:20:34 jholder Exp $
|
/* $Id: input.c,v 1.3 2000/07/05 15:20:34 jholder Exp $
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
* see doc/License.txt for License Information
|
* see doc/License.txt for License Information
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* File name: $Id: input.c,v 1.3 2000/07/05 15:20:34 jholder Exp $
|
* File name: $Id: input.c,v 1.3 2000/07/05 15:20:34 jholder Exp $
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
* Modification history:
|
* Modification history:
|
||||||
* $Log: input.c,v $
|
* $Log: input.c,v $
|
||||||
* Revision 1.3 2000/07/05 15:20:34 jholder
|
* Revision 1.3 2000/07/05 15:20:34 jholder
|
||||||
* Updated code to remove warnings.
|
* Updated code to remove warnings.
|
||||||
|
@ -57,63 +57,63 @@ static zword_t find_word( int, const char *, long );
|
||||||
|
|
||||||
void z_read_char( int argc, zword_t * argv )
|
void z_read_char( int argc, zword_t * argv )
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
zword_t arg_list[2];
|
zword_t arg_list[2];
|
||||||
|
|
||||||
/* Supply default parameters */
|
/* Supply default parameters */
|
||||||
|
|
||||||
if ( argc < 3 )
|
if ( argc < 3 )
|
||||||
argv[2] = 0;
|
argv[2] = 0;
|
||||||
if ( argc < 2 )
|
if ( argc < 2 )
|
||||||
argv[1] = 0;
|
argv[1] = 0;
|
||||||
|
|
||||||
/* Flush any buffered output before read */
|
/* Flush any buffered output before read */
|
||||||
|
|
||||||
flush_buffer( FALSE );
|
flush_buffer( FALSE );
|
||||||
|
|
||||||
/* Reset line count */
|
/* Reset line count */
|
||||||
|
|
||||||
lines_written = 0;
|
lines_written = 0;
|
||||||
|
|
||||||
/* If more than one characters was asked for then fail the call */
|
/* If more than one characters was asked for then fail the call */
|
||||||
|
|
||||||
if ( argv[0] != 1 )
|
if ( argv[0] != 1 )
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( ( c = playback_key( ) ) == -1 )
|
if ( ( c = playback_key( ) ) == -1 )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Setup the timeout routine argument list */
|
/* Setup the timeout routine argument list */
|
||||||
|
|
||||||
arg_list[0] = argv[2];
|
arg_list[0] = argv[2];
|
||||||
arg_list[1] = 0; /* as per spec 1.0 */
|
arg_list[1] = 0; /* as per spec 1.0 */
|
||||||
/* was: arg_list[1] = argv[1]/10; */
|
/* was: arg_list[1] = argv[1]/10; */
|
||||||
|
|
||||||
/* Read a character with a timeout. If the input timed out then
|
/* Read a character with a timeout. If the input timed out then
|
||||||
* call the timeout action routine. If the return status from the
|
* call the timeout action routine. If the return status from the
|
||||||
* timeout routine was 0 then try to read a character again */
|
* timeout routine was 0 then try to read a character again */
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
flush_buffer( FALSE );
|
flush_buffer( FALSE );
|
||||||
c = input_character( ( int ) argv[1] );
|
c = input_character( ( int ) argv[1] );
|
||||||
}
|
}
|
||||||
while ( c == -1 && z_call( 1, arg_list, ASYNC ) == 0 );
|
while ( c == -1 && z_call( 1, arg_list, ASYNC ) == 0 );
|
||||||
|
|
||||||
/* Fail call if input timed out */
|
/* Fail call if input timed out */
|
||||||
|
|
||||||
if ( c == -1 )
|
if ( c == -1 )
|
||||||
c = 0;
|
c = 0;
|
||||||
else
|
else
|
||||||
record_key( c );
|
record_key( c );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
store_operand( (zword_t)c );
|
store_operand( (zword_t)c );
|
||||||
|
|
||||||
} /* z_read_char */
|
} /* z_read_char */
|
||||||
|
|
||||||
|
@ -131,68 +131,68 @@ void z_read_char( int argc, zword_t * argv )
|
||||||
|
|
||||||
void z_sread_aread( int argc, zword_t * argv )
|
void z_sread_aread( int argc, zword_t * argv )
|
||||||
{
|
{
|
||||||
int i, in_size, out_size, terminator;
|
int i, in_size, out_size, terminator;
|
||||||
char *cbuf, *buffer;
|
char *cbuf, *buffer;
|
||||||
|
|
||||||
/* Supply default parameters */
|
/* Supply default parameters */
|
||||||
|
|
||||||
if ( argc < 4 )
|
if ( argc < 4 )
|
||||||
argv[3] = 0;
|
argv[3] = 0;
|
||||||
if ( argc < 3 )
|
if ( argc < 3 )
|
||||||
argv[2] = 0;
|
argv[2] = 0;
|
||||||
if ( argc < 2 )
|
if ( argc < 2 )
|
||||||
argv[1] = 0;
|
argv[1] = 0;
|
||||||
|
|
||||||
/* Refresh status line */
|
/* Refresh status line */
|
||||||
|
|
||||||
if ( h_type < V4 )
|
if ( h_type < V4 )
|
||||||
z_show_status( );
|
z_show_status( );
|
||||||
|
|
||||||
/* Flush any buffered output before read */
|
/* Flush any buffered output before read */
|
||||||
|
|
||||||
flush_buffer( TRUE );
|
flush_buffer( TRUE );
|
||||||
|
|
||||||
/* Reset line count */
|
/* Reset line count */
|
||||||
|
|
||||||
lines_written = 0;
|
lines_written = 0;
|
||||||
|
|
||||||
/* Initialise character pointer and initial read size */
|
/* Initialise character pointer and initial read size */
|
||||||
|
|
||||||
cbuf = ( char * ) &datap[argv[0]];
|
cbuf = ( char * ) &datap[argv[0]];
|
||||||
in_size = ( h_type > V4 ) ? cbuf[1] : 0;
|
in_size = ( h_type > V4 ) ? cbuf[1] : 0;
|
||||||
|
|
||||||
/* Read the line then script and record it */
|
/* Read the line then script and record it */
|
||||||
|
|
||||||
terminator = get_line( cbuf, argv[2], argv[3] );
|
terminator = get_line( cbuf, argv[2], argv[3] );
|
||||||
script_line( ( h_type > V4 ) ? &cbuf[2] : &cbuf[1] );
|
script_line( ( h_type > V4 ) ? &cbuf[2] : &cbuf[1] );
|
||||||
record_line( ( h_type > V4 ) ? &cbuf[2] : &cbuf[1] );
|
record_line( ( h_type > V4 ) ? &cbuf[2] : &cbuf[1] );
|
||||||
|
|
||||||
/* Convert new text in line to lowercase */
|
/* Convert new text in line to lowercase */
|
||||||
|
|
||||||
if ( h_type > V4 )
|
if ( h_type > V4 )
|
||||||
{
|
{
|
||||||
buffer = &cbuf[2];
|
buffer = &cbuf[2];
|
||||||
out_size = cbuf[1];
|
out_size = cbuf[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
buffer = &cbuf[1];
|
buffer = &cbuf[1];
|
||||||
out_size = strlen( buffer );
|
out_size = (int)strlen( buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( out_size > in_size )
|
if ( out_size > in_size )
|
||||||
for ( i = in_size; i < out_size; i++ )
|
for ( i = in_size; i < out_size; i++ )
|
||||||
buffer[i] = ( char ) tolower( buffer[i] );
|
buffer[i] = ( char ) tolower( buffer[i] );
|
||||||
|
|
||||||
/* Tokenise the line, if a token buffer is present */
|
/* Tokenise the line, if a token buffer is present */
|
||||||
|
|
||||||
if ( argv[1] )
|
if ( argv[1] )
|
||||||
tokenise_line( argv[0], argv[1], h_words_offset, 0 );
|
tokenise_line( argv[0], argv[1], h_words_offset, 0 );
|
||||||
|
|
||||||
/* Return the line terminator */
|
/* Return the line terminator */
|
||||||
|
|
||||||
if ( h_type > V4 )
|
if ( h_type > V4 )
|
||||||
store_operand( ( zword_t ) terminator );
|
store_operand( ( zword_t ) terminator );
|
||||||
|
|
||||||
} /* z_sread_aread */
|
} /* z_sread_aread */
|
||||||
|
|
||||||
|
@ -205,78 +205,78 @@ void z_sread_aread( int argc, zword_t * argv )
|
||||||
|
|
||||||
int get_line( char *cbuf, zword_t timeout, zword_t action_routine )
|
int get_line( char *cbuf, zword_t timeout, zword_t action_routine )
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
int buflen, read_size, status, c;
|
int buflen, read_size, status, c;
|
||||||
zword_t arg_list[2];
|
zword_t arg_list[2];
|
||||||
|
|
||||||
/* Set maximum buffer size to width of screen minus any
|
/* Set maximum buffer size to width of screen minus any
|
||||||
* right margin and 1 character for a terminating NULL */
|
* right margin and 1 character for a terminating NULL */
|
||||||
|
|
||||||
buflen = ( screen_cols > 127 ) ? 127 : screen_cols;
|
buflen = ( screen_cols > 127 ) ? 127 : screen_cols;
|
||||||
buflen -= right_margin + 1;
|
buflen -= right_margin + 1;
|
||||||
if ( ( int ) cbuf[0] <= buflen )
|
if ( ( int ) cbuf[0] <= buflen )
|
||||||
buflen = cbuf[0];
|
buflen = cbuf[0];
|
||||||
|
|
||||||
/* Set read size and start of read buffer. The buffer may already be
|
/* Set read size and start of read buffer. The buffer may already be
|
||||||
* primed with some text in V5 games. The Z-code will have already
|
* primed with some text in V5 games. The Z-code will have already
|
||||||
* displayed the text so we don't have to do that */
|
* displayed the text so we don't have to do that */
|
||||||
|
|
||||||
if ( h_type > V4 )
|
if ( h_type > V4 )
|
||||||
{
|
{
|
||||||
read_size = cbuf[1];
|
read_size = cbuf[1];
|
||||||
buffer = &cbuf[2];
|
buffer = &cbuf[2];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
read_size = 0;
|
read_size = 0;
|
||||||
buffer = &cbuf[1];
|
buffer = &cbuf[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to read input from command file */
|
/* Try to read input from command file */
|
||||||
|
|
||||||
c = playback_line( buflen, buffer, &read_size );
|
c = playback_line( buflen, buffer, &read_size );
|
||||||
|
|
||||||
if ( c == -1 )
|
if ( c == -1 )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Setup the timeout routine argument list */
|
/* Setup the timeout routine argument list */
|
||||||
|
|
||||||
arg_list[0] = action_routine;
|
arg_list[0] = action_routine;
|
||||||
arg_list[1] = 0; /* as per spec.1.0 */
|
arg_list[1] = 0; /* as per spec.1.0 */
|
||||||
/* arg_list[1] = timeout/10; */
|
/* arg_list[1] = timeout/10; */
|
||||||
|
|
||||||
/* Read a line with a timeout. If the input timed out then
|
/* Read a line with a timeout. If the input timed out then
|
||||||
* call the timeout action routine. If the return status from the
|
* call the timeout action routine. If the return status from the
|
||||||
* timeout routine was 0 then try to read the line again */
|
* timeout routine was 0 then try to read the line again */
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
c = input_line( buflen, buffer, timeout, &read_size );
|
c = input_line( buflen, buffer, timeout, &read_size );
|
||||||
status = 0;
|
status = 0;
|
||||||
}
|
}
|
||||||
while ( c == -1 && ( status = z_call( 1, arg_list, ASYNC ) ) == 0 );
|
while ( c == -1 && ( status = z_call( 1, arg_list, ASYNC ) ) == 0 );
|
||||||
|
|
||||||
/* Throw away any input if timeout returns success */
|
/* Throw away any input if timeout returns success */
|
||||||
|
|
||||||
if ( status )
|
if ( status )
|
||||||
read_size = 0;
|
read_size = 0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Zero terminate line */
|
/* Zero terminate line */
|
||||||
|
|
||||||
if ( h_type > V4 )
|
if ( h_type > V4 )
|
||||||
{
|
{
|
||||||
cbuf[1] = ( char ) read_size;
|
cbuf[1] = ( char ) read_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Zero terminate line (V1-4 only) */
|
/* Zero terminate line (V1-4 only) */
|
||||||
buffer[read_size] = '\0';
|
buffer[read_size] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( c );
|
return ( c );
|
||||||
|
|
||||||
} /* get_line */
|
} /* get_line */
|
||||||
|
|
||||||
|
@ -295,108 +295,109 @@ int get_line( char *cbuf, zword_t timeout, zword_t action_routine )
|
||||||
|
|
||||||
static void tokenise_line( zword_t char_buf, zword_t token_buf, zword_t dictionary, zword_t flag )
|
static void tokenise_line( zword_t char_buf, zword_t token_buf, zword_t dictionary, zword_t flag )
|
||||||
{
|
{
|
||||||
int i, count, words, token_length;
|
int i, count, words, token_length;
|
||||||
long word_index, chop = 0;
|
long word_index, chop = 0;
|
||||||
int slen;
|
int slen;
|
||||||
char *str_end;
|
char *str_end;
|
||||||
char *cbuf, *tbuf, *tp;
|
char *cbuf, *tbuf, *tp;
|
||||||
const char *cp, *token;
|
const char *cp, *token;
|
||||||
char punctuation[16];
|
char punctuation[16];
|
||||||
zword_t word;
|
zword_t word;
|
||||||
|
|
||||||
/* Initialise character and token buffer pointers */
|
/* Initialise character and token buffer pointers */
|
||||||
|
|
||||||
cbuf = ( char * ) &datap[char_buf];
|
cbuf = ( char * ) &datap[char_buf];
|
||||||
tbuf = ( char * ) &datap[token_buf];
|
tbuf = ( char * ) &datap[token_buf];
|
||||||
|
|
||||||
/* Find the string length */
|
/* Find the string length */
|
||||||
|
|
||||||
if ( h_type > V4 )
|
if ( h_type > V4 )
|
||||||
{
|
{
|
||||||
slen = ( unsigned char ) ( cbuf[1] );
|
slen = ( unsigned char ) ( cbuf[1] );
|
||||||
str_end = cbuf + 2 + slen;
|
str_end = cbuf + 2 + slen;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
slen = strlen( cbuf + 1 );
|
slen = (int)strlen( cbuf + 1 );
|
||||||
str_end = cbuf + 1 + slen;
|
str_end = cbuf + 1 + slen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise word count and pointers */
|
/* Initialise word count and pointers */
|
||||||
|
|
||||||
words = 0;
|
words = 0;
|
||||||
cp = ( h_type > V4 ) ? cbuf + 2 : cbuf + 1;
|
cp = ( h_type > V4 ) ? cbuf + 2 : cbuf + 1;
|
||||||
tp = tbuf + 2;
|
tp = tbuf + 2;
|
||||||
|
|
||||||
/* Initialise dictionary */
|
/* Initialise dictionary */
|
||||||
|
|
||||||
count = get_byte( dictionary++ );
|
count = get_byte( dictionary++ );
|
||||||
for ( i = 0; i < count; i++ )
|
for ( i = 0; i < count; i++ )
|
||||||
punctuation[i] = get_byte( dictionary++ );
|
punctuation[i] = (char)get_byte( dictionary++ );
|
||||||
punctuation[i] = '\0';
|
punctuation[i] = '\0';
|
||||||
entry_size = get_byte( dictionary++ );
|
entry_size = get_byte( dictionary++ );
|
||||||
dictionary_size = ( ZINT16 ) get_word( dictionary );
|
dictionary_size = ( ZINT16 ) get_word( dictionary );
|
||||||
dictionary_offset = dictionary + 2;
|
dictionary_offset = dictionary + 2;
|
||||||
|
|
||||||
/* Calculate the binary chop start position */
|
/* Calculate the binary chop start position */
|
||||||
|
|
||||||
if ( dictionary_size > 0 )
|
if ( dictionary_size > 0 )
|
||||||
{
|
{
|
||||||
word_index = dictionary_size / 2;
|
word_index = dictionary_size / 2;
|
||||||
chop = 1;
|
chop = 1;
|
||||||
do
|
do
|
||||||
chop *= 2;
|
chop *= 2;
|
||||||
while ( word_index /= 2 );
|
while ( word_index /= 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tokenise the line */
|
/* Tokenise the line */
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Skip to next token */
|
/* Skip to next token */
|
||||||
|
|
||||||
cp = next_token( cp, str_end, &token, &token_length, punctuation );
|
cp = next_token( cp, str_end, &token, &token_length, punctuation );
|
||||||
if ( token_length )
|
if ( token_length ) {
|
||||||
|
|
||||||
/* If still space in token buffer then store word */
|
/* If still space in token buffer then store word */
|
||||||
|
|
||||||
if ( words <= tbuf[0] )
|
if ( words <= tbuf[0] )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Get the word offset from the dictionary */
|
/* Get the word offset from the dictionary */
|
||||||
|
|
||||||
word = find_word( token_length, token, chop );
|
word = find_word( token_length, token, chop );
|
||||||
|
|
||||||
/* Store the dictionary offset, token length and offset */
|
/* Store the dictionary offset, token length and offset */
|
||||||
|
|
||||||
if ( word || flag == 0 )
|
if ( word || flag == 0 )
|
||||||
{
|
{
|
||||||
tp[0] = ( char ) ( word >> 8 );
|
tp[0] = ( char ) ( word >> 8 );
|
||||||
tp[1] = ( char ) ( word & 0xff );
|
tp[1] = ( char ) ( word & 0xff );
|
||||||
}
|
}
|
||||||
tp[2] = ( char ) token_length;
|
tp[2] = ( char ) token_length;
|
||||||
tp[3] = ( char ) ( token - cbuf );
|
tp[3] = ( char ) ( token - cbuf );
|
||||||
|
|
||||||
/* Step to next token position and count the word */
|
/* Step to next token position and count the word */
|
||||||
|
|
||||||
tp += 4;
|
tp += 4;
|
||||||
words++;
|
words++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Moan if token buffer space exhausted */
|
/* Moan if token buffer space exhausted */
|
||||||
|
|
||||||
output_string( "Too many words typed, discarding: " );
|
output_string( "Too many words typed, discarding: " );
|
||||||
output_line( token );
|
output_line( token );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while ( token_length );
|
}
|
||||||
|
while ( token_length );
|
||||||
|
|
||||||
/* Store word count */
|
/* Store word count */
|
||||||
|
|
||||||
tbuf[1] = ( char ) words;
|
tbuf[1] = ( char ) words;
|
||||||
|
|
||||||
} /* tokenise_line */
|
} /* tokenise_line */
|
||||||
|
|
||||||
|
@ -415,71 +416,71 @@ static void tokenise_line( zword_t char_buf, zword_t token_buf, zword_t dictiona
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static const char *next_token( const char *s, const char *str_end, const char **token, int *length,
|
static const char *next_token( const char *s, const char *str_end, const char **token, int *length,
|
||||||
const char *punctuation )
|
const char *punctuation )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Set the token length to zero */
|
/* Set the token length to zero */
|
||||||
|
|
||||||
*length = 0;
|
*length = 0;
|
||||||
|
|
||||||
/* Step through the string looking for separators */
|
/* Step through the string looking for separators */
|
||||||
|
|
||||||
for ( ; s < str_end; s++ )
|
for ( ; s < str_end; s++ )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Look for game specific word separators first */
|
/* Look for game specific word separators first */
|
||||||
|
|
||||||
for ( i = 0; punctuation[i] && *s != punctuation[i]; i++ )
|
for ( i = 0; punctuation[i] && *s != punctuation[i]; i++ )
|
||||||
;
|
;
|
||||||
|
|
||||||
/* If a separator is found then return the information */
|
/* If a separator is found then return the information */
|
||||||
|
|
||||||
if ( punctuation[i] )
|
if ( punctuation[i] )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* If length has been set then just return the word position */
|
/* If length has been set then just return the word position */
|
||||||
|
|
||||||
if ( *length )
|
if ( *length )
|
||||||
return ( s );
|
return ( s );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
/* End of word, so set length, token pointer and return string */
|
/* End of word, so set length, token pointer and return string */
|
||||||
|
|
||||||
( *length )++;
|
( *length )++;
|
||||||
*token = s;
|
*token = s;
|
||||||
return ( ++s );
|
return ( ++s );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look for statically defined separators last */
|
/* Look for statically defined separators last */
|
||||||
|
|
||||||
for ( i = 0; separators[i] && *s != separators[i]; i++ )
|
for ( i = 0; separators[i] && *s != separators[i]; i++ )
|
||||||
;
|
;
|
||||||
|
|
||||||
/* If a separator is found then return the information */
|
/* If a separator is found then return the information */
|
||||||
|
|
||||||
if ( separators[i] )
|
if ( separators[i] )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* If length has been set then just return the word position */
|
/* If length has been set then just return the word position */
|
||||||
|
|
||||||
if ( *length )
|
if ( *length )
|
||||||
return ( ++s );
|
return ( ++s );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
/* If first token character then remember its position */
|
/* If first token character then remember its position */
|
||||||
|
|
||||||
if ( *length == 0 )
|
if ( *length == 0 )
|
||||||
*token = s;
|
*token = s;
|
||||||
( *length )++;
|
( *length )++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( s );
|
return ( s );
|
||||||
|
|
||||||
} /* next_token */
|
} /* next_token */
|
||||||
|
|
||||||
|
@ -493,89 +494,89 @@ static const char *next_token( const char *s, const char *str_end, const char **
|
||||||
|
|
||||||
static zword_t find_word( int len, const char *cp, long chop )
|
static zword_t find_word( int len, const char *cp, long chop )
|
||||||
{
|
{
|
||||||
ZINT16 word[3];
|
ZINT16 word[3];
|
||||||
long word_index, offset, status;
|
long word_index, offset, status;
|
||||||
|
|
||||||
/* Don't look up the word if there are no dictionary entries */
|
/* Don't look up the word if there are no dictionary entries */
|
||||||
|
|
||||||
if ( dictionary_size == 0 )
|
if ( dictionary_size == 0 )
|
||||||
return ( 0 );
|
return ( 0 );
|
||||||
|
|
||||||
/* Encode target word */
|
/* Encode target word */
|
||||||
|
|
||||||
encode_text( len, cp, word );
|
encode_text( len, cp, word );
|
||||||
|
|
||||||
/* Do a binary chop search on the main dictionary, otherwise do
|
/* Do a binary chop search on the main dictionary, otherwise do
|
||||||
* a linear search */
|
* a linear search */
|
||||||
|
|
||||||
word_index = chop - 1;
|
word_index = chop - 1;
|
||||||
|
|
||||||
if ( dictionary_size > 0 )
|
if ( dictionary_size > 0 )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Binary chop until the word is found */
|
/* Binary chop until the word is found */
|
||||||
|
|
||||||
while ( chop )
|
while ( chop )
|
||||||
{
|
{
|
||||||
|
|
||||||
chop /= 2;
|
chop /= 2;
|
||||||
|
|
||||||
/* Calculate dictionary offset */
|
/* Calculate dictionary offset */
|
||||||
|
|
||||||
if ( word_index > ( dictionary_size - 1 ) )
|
if ( word_index > ( dictionary_size - 1 ) )
|
||||||
word_index = dictionary_size - 1;
|
word_index = dictionary_size - 1;
|
||||||
|
|
||||||
offset = dictionary_offset + ( word_index * entry_size );
|
offset = dictionary_offset + ( word_index * entry_size );
|
||||||
|
|
||||||
/* If word matches then return dictionary offset */
|
/* If word matches then return dictionary offset */
|
||||||
|
|
||||||
if ( ( status = word[0] - ( ZINT16 ) get_word( offset + 0 ) ) == 0 &&
|
if ( ( status = word[0] - ( ZINT16 ) get_word( offset + 0 ) ) == 0 &&
|
||||||
( status = word[1] - ( ZINT16 ) get_word( offset + 2 ) ) == 0 &&
|
( status = word[1] - ( ZINT16 ) get_word( offset + 2 ) ) == 0 &&
|
||||||
( h_type < V4 || ( status = word[2] - ( ZINT16 ) get_word( offset + 4 ) ) == 0 ) )
|
( h_type < V4 || ( status = word[2] - ( ZINT16 ) get_word( offset + 4 ) ) == 0 ) )
|
||||||
return ( ( zword_t ) offset );
|
return ( ( zword_t ) offset );
|
||||||
|
|
||||||
/* Set next position depending on direction of overshoot */
|
/* Set next position depending on direction of overshoot */
|
||||||
|
|
||||||
if ( status > 0 )
|
if ( status > 0 )
|
||||||
{
|
{
|
||||||
word_index += chop;
|
word_index += chop;
|
||||||
|
|
||||||
/* Deal with end of dictionary case */
|
/* Deal with end of dictionary case */
|
||||||
|
|
||||||
if ( word_index >= ( int ) dictionary_size )
|
if ( word_index >= ( int ) dictionary_size )
|
||||||
word_index = dictionary_size - 1;
|
word_index = dictionary_size - 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
word_index -= chop;
|
word_index -= chop;
|
||||||
|
|
||||||
/* Deal with start of dictionary case */
|
/* Deal with start of dictionary case */
|
||||||
|
|
||||||
if ( word_index < 0 )
|
if ( word_index < 0 )
|
||||||
word_index = 0;
|
word_index = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
for ( word_index = 0; word_index < -dictionary_size; word_index++ )
|
for ( word_index = 0; word_index < -dictionary_size; word_index++ )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Calculate dictionary offset */
|
/* Calculate dictionary offset */
|
||||||
|
|
||||||
offset = dictionary_offset + ( word_index * entry_size );
|
offset = dictionary_offset + ( word_index * entry_size );
|
||||||
|
|
||||||
/* If word matches then return dictionary offset */
|
/* If word matches then return dictionary offset */
|
||||||
|
|
||||||
if ( ( status = word[0] - ( ZINT16 ) get_word( offset + 0 ) ) == 0 &&
|
if ( ( status = word[0] - ( ZINT16 ) get_word( offset + 0 ) ) == 0 &&
|
||||||
( status = word[1] - ( ZINT16 ) get_word( offset + 2 ) ) == 0 &&
|
( status = word[1] - ( ZINT16 ) get_word( offset + 2 ) ) == 0 &&
|
||||||
( h_type < V4 || ( status = word[2] - ( ZINT16 ) get_word( offset + 4 ) ) == 0 ) )
|
( h_type < V4 || ( status = word[2] - ( ZINT16 ) get_word( offset + 4 ) ) == 0 ) )
|
||||||
return ( ( zword_t ) offset );
|
return ( ( zword_t ) offset );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( 0 );
|
return ( 0 );
|
||||||
|
|
||||||
} /* find_word */
|
} /* find_word */
|
||||||
|
|
||||||
|
@ -592,15 +593,15 @@ static zword_t find_word( int len, const char *cp, long chop )
|
||||||
void z_tokenise( int argc, zword_t * argv )
|
void z_tokenise( int argc, zword_t * argv )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Supply default parameters */
|
/* Supply default parameters */
|
||||||
|
|
||||||
if ( argc < 4 )
|
if ( argc < 4 )
|
||||||
argv[3] = 0;
|
argv[3] = 0;
|
||||||
if ( argc < 3 )
|
if ( argc < 3 )
|
||||||
argv[2] = h_words_offset;
|
argv[2] = h_words_offset;
|
||||||
|
|
||||||
/* Convert the line to tokens */
|
/* Convert the line to tokens */
|
||||||
|
|
||||||
tokenise_line( argv[0], argv[1], argv[2], argv[3] );
|
tokenise_line( argv[0], argv[1], argv[2], argv[3] );
|
||||||
|
|
||||||
} /* z_tokenise */
|
} /* z_tokenise */
|
||||||
|
|
175
joeyio.c
175
joeyio.c
|
@ -3,10 +3,31 @@
|
||||||
#include "ztypes.h"
|
#include "ztypes.h"
|
||||||
|
|
||||||
|
|
||||||
static int _cursorIndex = 0;
|
#define DISPLAY_MIXED_SIZE 5
|
||||||
static int _cursorSize = 9;
|
#define COMMAND_BUFFER_SIZE 32
|
||||||
static unsigned int _cursorTime = 0;
|
|
||||||
static byte _cursor[] = { 32, 176, 177, 178, 219, 178, 177, 176, 32 };
|
typedef enum {
|
||||||
|
DISPLAY_MODE_TEXT = 0,
|
||||||
|
DISPLAY_MODE_GRAPHICS,
|
||||||
|
DISPLAY_MODE_MIXED,
|
||||||
|
DISPLAY_MODE_LAST
|
||||||
|
} DModeT;
|
||||||
|
|
||||||
|
|
||||||
|
static jlVecT *_vectorImage = NULL;
|
||||||
|
static jlStaT *_graphicsPage = NULL;
|
||||||
|
static jlSoundT *_soundEffect = NULL;
|
||||||
|
static DModeT _displayMode = DISPLAY_MODE_TEXT;
|
||||||
|
static byte _bufferCount = 0;
|
||||||
|
static char _buffer[COMMAND_BUFFER_SIZE];
|
||||||
|
static bool _inCommand = false;
|
||||||
|
static byte _cursorIndex = 0;
|
||||||
|
static byte _cursorSize = 9;
|
||||||
|
static unsigned int _cursorTime = 0;
|
||||||
|
static byte _cursor[] = { 32, 176, 177, 178, 219, 178, 177, 176, 32 };
|
||||||
|
|
||||||
|
|
||||||
|
void set_next_display_mode(void);
|
||||||
|
|
||||||
|
|
||||||
void clear_line(void) {
|
void clear_line(void) {
|
||||||
|
@ -16,7 +37,7 @@ void clear_line(void) {
|
||||||
|
|
||||||
void clear_screen(void) {
|
void clear_screen(void) {
|
||||||
termClearScreen();
|
termClearScreen();
|
||||||
termMoveCursor(1, screen_rows);
|
termMoveCursor(1, (byte)screen_rows);
|
||||||
jlDisplayPresent();
|
jlDisplayPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,17 +79,106 @@ void delete_status_window(void) {
|
||||||
|
|
||||||
|
|
||||||
void display_char(int c) {
|
void display_char(int c) {
|
||||||
termPrintChar((char)c);
|
char command;
|
||||||
|
char *token;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
// This also handles processing of embedded media commands:
|
||||||
|
// {I name x y} - Display Image "name" @ x, y
|
||||||
|
// {M name} - Play Music "name"
|
||||||
|
// {S name} - Play Sound "name"
|
||||||
|
// {Q} - Quiet!
|
||||||
|
if (_inCommand) {
|
||||||
|
if ((char) c == '}') {
|
||||||
|
// Exit command mode.
|
||||||
|
if (_bufferCount > 0) {
|
||||||
|
// Did we get a command we understand?
|
||||||
|
command = (char)toupper(_buffer[0]);
|
||||||
|
_buffer[_bufferCount] = 0;
|
||||||
|
(void)strtok(_buffer, " ");
|
||||||
|
switch (command) {
|
||||||
|
case 'I':
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
if (jlVecLoad(_vectorImage, token)) {
|
||||||
|
x = y = 0;
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
if (token != NULL) {
|
||||||
|
x = atoi(token);
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
if (token != NULL) {
|
||||||
|
y = atoi(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Put user into GRAPHICS mode if they aren't.
|
||||||
|
_displayMode = DISPLAY_MODE_GRAPHICS - 1;
|
||||||
|
set_next_display_mode();
|
||||||
|
// Render the image.
|
||||||
|
jlVecDisplay(_vectorImage, x, y);
|
||||||
|
// Save it to the graphics page.
|
||||||
|
jlStaCreate(_graphicsPage);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
jlSoundMusicPlay(token);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'S':
|
||||||
|
token = strtok(NULL, " ");
|
||||||
|
if (jlSoundLoad(_soundEffect, token)) {
|
||||||
|
jlSoundPlay(_soundEffect);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Q':
|
||||||
|
jlSoundMusicStop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Exit command mode
|
||||||
|
_bufferCount = 0;
|
||||||
|
_inCommand = false;
|
||||||
|
} else {
|
||||||
|
if (_bufferCount < COMMAND_BUFFER_SIZE - 1) {
|
||||||
|
// Add character to command buffer.
|
||||||
|
_buffer[_bufferCount++] = (char)c;
|
||||||
|
} else {
|
||||||
|
// Overflowed buffer - exit command mode
|
||||||
|
_bufferCount = 0;
|
||||||
|
_inCommand = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((char)c == '{') {
|
||||||
|
// Switch to embedded command mode.
|
||||||
|
_inCommand = true;
|
||||||
|
} else {
|
||||||
|
// Display game text.
|
||||||
|
termPrintChar((char)c);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void get_cursor_position(int *row, int *col) {
|
void get_cursor_position(int *row, int *col) {
|
||||||
termGetCursor(col, row);
|
byte x;
|
||||||
|
byte y;
|
||||||
|
termGetCursor(&x, &y);
|
||||||
|
*col = (int)x;
|
||||||
|
*row = (int)y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void initialize_screen(void) {
|
void initialize_screen(void) {
|
||||||
// Handled in main
|
// Also handled in main
|
||||||
|
|
||||||
|
// Create initial empty graphics image.
|
||||||
|
jlDrawColor(0);
|
||||||
|
jlDrawClear();
|
||||||
|
jlDrawColor(15);
|
||||||
|
jlDisplayPresent();
|
||||||
|
jlStaCreate(_graphicsPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -129,8 +239,12 @@ int input_line(int buflen, char *buffer, int timeout, int *read_size) {
|
||||||
//***TODO*** Flash border or ding or something
|
//***TODO*** Flash border or ding or something
|
||||||
} else {
|
} else {
|
||||||
if (c == 13) {
|
if (c == 13) {
|
||||||
scroll_line();
|
if (curr_char_pos == 0) {
|
||||||
return c;
|
set_next_display_mode();
|
||||||
|
} else {
|
||||||
|
scroll_line();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
buffer[curr_char_pos++] = (char)c;
|
buffer[curr_char_pos++] = (char)c;
|
||||||
if (*read_size < curr_char_pos) {
|
if (*read_size < curr_char_pos) {
|
||||||
|
@ -148,12 +262,15 @@ int input_line(int buflen, char *buffer, int timeout, int *read_size) {
|
||||||
|
|
||||||
|
|
||||||
void move_cursor(int row, int col) {
|
void move_cursor(int row, int col) {
|
||||||
termMoveCursor(col, row);
|
termMoveCursor((byte)col, (byte)row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void reset_screen(void) {
|
void reset_screen(void) {
|
||||||
// Handled in main
|
// Also handled in main
|
||||||
|
jlStaFree(_graphicsPage);
|
||||||
|
jlVecFree(_vectorImage);
|
||||||
|
jlSoundFree(_soundEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,3 +314,37 @@ void set_attribute(int attribute) {
|
||||||
termPrint("\33[7m");
|
termPrint("\33[7m");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void set_next_display_mode(void) {
|
||||||
|
|
||||||
|
_displayMode++;
|
||||||
|
if (_displayMode >= DISPLAY_MODE_LAST) {
|
||||||
|
_displayMode = DISPLAY_MODE_TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (_displayMode) {
|
||||||
|
case DISPLAY_MODE_TEXT:
|
||||||
|
printf("Terminal now TEXT\n");
|
||||||
|
termHideTopLines(0);
|
||||||
|
termRepaint();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISPLAY_MODE_GRAPHICS:
|
||||||
|
printf("Terminal now GRAPHICS\n");
|
||||||
|
termHideTopLines((byte)screen_rows);
|
||||||
|
jlStaDisplay(_graphicsPage);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISPLAY_MODE_MIXED:
|
||||||
|
printf("Terminal now MIXED\n");
|
||||||
|
termHideTopLines((byte)screen_rows - DISPLAY_MIXED_SIZE);
|
||||||
|
jlStaDisplay(_graphicsPage);
|
||||||
|
termRepaint();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISPLAY_MODE_LAST:
|
||||||
|
// Won't happen. Silences a warning.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
37
jzip.h
37
jzip.h
|
@ -1,37 +0,0 @@
|
||||||
|
|
||||||
/* $Id: jzip.h,v 1.5 2000/10/10 14:46:22 jholder Exp $
|
|
||||||
* --------------------------------------------------------------------
|
|
||||||
* see doc/License.txt for License Information
|
|
||||||
* --------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* File name: $Id: jzip.h,v 1.5 2000/10/10 14:46:22 jholder Exp $
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
*
|
|
||||||
* Modification history:
|
|
||||||
* $Log: jzip.h,v $
|
|
||||||
* Revision 1.5 2000/10/10 14:46:22 jholder
|
|
||||||
* Fixed text wrap bug when printing array w/ \r chars in it
|
|
||||||
*
|
|
||||||
* Revision 1.4 2000/10/05 17:09:12 jholder
|
|
||||||
* removed old email address
|
|
||||||
*
|
|
||||||
* Revision 1.3 2000/10/04 23:07:57 jholder
|
|
||||||
* fixed redirect problem with isolatin1 range chars
|
|
||||||
*
|
|
||||||
* Revision 1.2 2000/09/18 15:31:44 jholder
|
|
||||||
* Updated release date for package release
|
|
||||||
*
|
|
||||||
* Revision 1.1.1.1 2000/05/10 14:21:34 jholder
|
|
||||||
*
|
|
||||||
* imported
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* --------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define JZIPVER "Jzip V2.1"
|
|
||||||
#define JZIPRELDATE "Tue, Oct 10 2000"
|
|
||||||
#define JZIPAUTHOR "John Holder (j-holder@home.com)"
|
|
||||||
#define JZIPURL "http://jzip.sourceforge.net/"
|
|
||||||
|
|
55
main.c
55
main.c
|
@ -1,5 +1,6 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#include "joey.h"
|
#include "joey.h"
|
||||||
|
@ -94,30 +95,48 @@ void process_arguments(char *game) {
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
||||||
|
FILE *in;
|
||||||
jlStaT *font = NULL;
|
jlStaT *font = NULL;
|
||||||
|
char name[40];
|
||||||
|
char game[40];
|
||||||
|
char text[40];
|
||||||
|
|
||||||
jlUtilStartup("IF Engine");
|
in = fopen("gamedata.dat", "rt");
|
||||||
jlStaLoad(font, "8x8thin.sta");
|
if (in != NULL) {
|
||||||
|
|
||||||
termStart(font, 0, 0, 40, 25);
|
fgets(name, 40, in);
|
||||||
termDestruciveBackspace(false);
|
fgets(game, 40, in);
|
||||||
termMoveCursor(1, 25);
|
fgets(text, 40, in);
|
||||||
termSaveCursor();
|
|
||||||
|
|
||||||
process_arguments("gamedata.z5");
|
fclose(in);
|
||||||
configure(V1, V8);
|
|
||||||
initialize_screen();
|
|
||||||
load_cache();
|
|
||||||
z_restart();
|
|
||||||
(void)interpret();
|
|
||||||
unload_cache();
|
|
||||||
close_story();
|
|
||||||
close_script();
|
|
||||||
reset_screen();
|
|
||||||
|
|
||||||
termStop();
|
name[strlen(name) - 1] = 0;
|
||||||
|
game[strlen(game) - 1] = 0;
|
||||||
|
text[strlen(text) - 1] = 0;
|
||||||
|
|
||||||
jlStaFree(font);
|
jlUtilStartup(name);
|
||||||
|
jlStaLoad(font, text);
|
||||||
|
|
||||||
|
termStart(font, 0, 0, 40, 25);
|
||||||
|
termDestruciveBackspace(false);
|
||||||
|
termMoveCursor(1, 25);
|
||||||
|
termSaveCursor();
|
||||||
|
|
||||||
|
process_arguments(game);
|
||||||
|
configure(V1, V8);
|
||||||
|
initialize_screen();
|
||||||
|
load_cache();
|
||||||
|
z_restart();
|
||||||
|
(void)interpret();
|
||||||
|
unload_cache();
|
||||||
|
close_story();
|
||||||
|
close_script();
|
||||||
|
reset_screen();
|
||||||
|
|
||||||
|
termStop();
|
||||||
|
|
||||||
|
jlStaFree(font);
|
||||||
|
}
|
||||||
|
|
||||||
jlUtilShutdown();
|
jlUtilShutdown();
|
||||||
}
|
}
|
||||||
|
|
0
nowhere.vec
Normal file
0
nowhere.vec
Normal file
29
nowhere.vec.source
Normal file
29
nowhere.vec.source
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Reset Palette, Clear Screen to White, Draw in Black
|
||||||
|
# Hacky Border because we can't hit 319 yet.
|
||||||
|
R
|
||||||
|
C 0
|
||||||
|
E
|
||||||
|
C 15
|
||||||
|
S 0 0 255 199
|
||||||
|
C 0
|
||||||
|
|
||||||
|
# Horizon
|
||||||
|
L 0 87 255 87
|
||||||
|
|
||||||
|
# Sun
|
||||||
|
L 255 64 248 61 240 61 233 62 228 66 223 72 220 78 220 87
|
||||||
|
|
||||||
|
# Beach
|
||||||
|
L 0 101 87 124 126 128 148 133 160 136 168 141 172 146 171 149 169 153 169 158 176 164 188 168 205 171 227 174 255 174
|
||||||
|
|
||||||
|
# Fill Sun
|
||||||
|
C 12
|
||||||
|
F 242 74
|
||||||
|
|
||||||
|
# Fill Beach
|
||||||
|
C 14
|
||||||
|
F 105 161
|
||||||
|
|
||||||
|
# Fill Ocean
|
||||||
|
C 1
|
||||||
|
F 194 106
|
|
@ -468,7 +468,8 @@ void set_font( int font_type )
|
||||||
|
|
||||||
void set_colours( zword_t foreground, zword_t background )
|
void set_colours( zword_t foreground, zword_t background )
|
||||||
{
|
{
|
||||||
|
(void)foreground;
|
||||||
|
(void)background;
|
||||||
} /* set_colours */
|
} /* set_colours */
|
||||||
|
|
||||||
#endif /* !defined MSDOS && !defined OS2 && !defined AMIGA !defined HARD_COLORS && !defined ATARIST */
|
#endif /* !defined MSDOS && !defined OS2 && !defined AMIGA !defined HARD_COLORS && !defined ATARIST */
|
||||||
|
@ -519,6 +520,8 @@ void set_colours( zword_t foreground, zword_t background )
|
||||||
|
|
||||||
int codes_to_text( int c, char *s )
|
int codes_to_text( int c, char *s )
|
||||||
{
|
{
|
||||||
|
(void)c;
|
||||||
|
(void)s;
|
||||||
return 1;
|
return 1;
|
||||||
} /* codes_to_text */
|
} /* codes_to_text */
|
||||||
|
|
||||||
|
|
596
property.c
596
property.c
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
/* $Id: property.c,v 1.2 2000/05/25 22:28:56 jholder Exp $
|
/* $Id: property.c,v 1.2 2000/05/25 22:28:56 jholder Exp $
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
* see doc/License.txt for License Information
|
* see doc/License.txt for License Information
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* File name: $Id: property.c,v 1.2 2000/05/25 22:28:56 jholder Exp $
|
* File name: $Id: property.c,v 1.2 2000/05/25 22:28:56 jholder Exp $
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
* Modification history:
|
* Modification history:
|
||||||
* $Log: property.c,v $
|
* $Log: property.c,v $
|
||||||
* Revision 1.2 2000/05/25 22:28:56 jholder
|
* Revision 1.2 2000/05/25 22:28:56 jholder
|
||||||
* changes routine names to reflect zmachine opcode names per spec 1.0
|
* changes routine names to reflect zmachine opcode names per spec 1.0
|
||||||
|
@ -40,22 +40,22 @@
|
||||||
|
|
||||||
static zword_t get_property_addr( zword_t obj )
|
static zword_t get_property_addr( zword_t obj )
|
||||||
{
|
{
|
||||||
zword_t object_addr;
|
zword_t object_addr;
|
||||||
zword_t prop_addr;
|
zword_t prop_addr;
|
||||||
zbyte_t size;
|
zbyte_t size;
|
||||||
|
|
||||||
/* Calculate the address of the property pointer in the object */
|
/* Calculate the address of the property pointer in the object */
|
||||||
|
|
||||||
object_addr = get_object_address( obj );
|
object_addr = get_object_address( obj );
|
||||||
object_addr += ( h_type <= V3 ) ? O3_PROPERTY_OFFSET : O4_PROPERTY_OFFSET;
|
object_addr += ( h_type <= V3 ) ? O3_PROPERTY_OFFSET : O4_PROPERTY_OFFSET;
|
||||||
|
|
||||||
/* Read the property address */
|
/* Read the property address */
|
||||||
prop_addr = get_word( object_addr );
|
prop_addr = get_word( object_addr );
|
||||||
|
|
||||||
/* Skip past object description which is an ASCIC of encoded words */
|
/* Skip past object description which is an ASCIC of encoded words */
|
||||||
size = get_byte( prop_addr );
|
size = get_byte( prop_addr );
|
||||||
|
|
||||||
return prop_addr + ( size * 2 ) + 1;
|
return prop_addr + ( size * 2 ) + 1;
|
||||||
|
|
||||||
} /* get_property_addr */
|
} /* get_property_addr */
|
||||||
|
|
||||||
|
@ -68,29 +68,29 @@ static zword_t get_property_addr( zword_t obj )
|
||||||
|
|
||||||
static zword_t get_next_property( zword_t prop_addr )
|
static zword_t get_next_property( zword_t prop_addr )
|
||||||
{
|
{
|
||||||
zbyte_t value;
|
zbyte_t value;
|
||||||
|
|
||||||
/* Load the current property id */
|
/* Load the current property id */
|
||||||
value = get_byte( prop_addr );
|
value = get_byte( prop_addr );
|
||||||
prop_addr++;
|
prop_addr++;
|
||||||
|
|
||||||
/* Calculate the length of this property */
|
/* Calculate the length of this property */
|
||||||
|
|
||||||
if ( h_type <= V3 )
|
if ( h_type <= V3 )
|
||||||
value >>= 5;
|
value >>= 5;
|
||||||
else if ( !( value & 0x80 ) )
|
else if ( !( value & 0x80 ) )
|
||||||
value >>= 6;
|
value >>= 6;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value = get_byte( prop_addr );
|
value = get_byte( prop_addr );
|
||||||
value &= property_size_mask;
|
value &= property_size_mask;
|
||||||
|
|
||||||
if ( value == 0 )
|
if ( value == 0 )
|
||||||
value = 64; /* spec 1.0 */
|
value = 64; /* spec 1.0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Address property length to current property pointer */
|
/* Address property length to current property pointer */
|
||||||
return prop_addr + value + 1;
|
return prop_addr + value + 1;
|
||||||
|
|
||||||
} /* get_next_property */
|
} /* get_next_property */
|
||||||
|
|
||||||
|
@ -106,58 +106,58 @@ static zword_t get_next_property( zword_t prop_addr )
|
||||||
|
|
||||||
void z_get_prop( zword_t obj, zword_t prop )
|
void z_get_prop( zword_t obj, zword_t prop )
|
||||||
{
|
{
|
||||||
zword_t prop_addr;
|
zword_t prop_addr;
|
||||||
zword_t wprop_val;
|
zword_t wprop_val;
|
||||||
zbyte_t bprop_val;
|
zbyte_t bprop_val;
|
||||||
zbyte_t value;
|
zbyte_t value;
|
||||||
|
|
||||||
#ifdef STRICTZ
|
#ifdef STRICTZ
|
||||||
if ( obj == 0 )
|
if ( obj == 0 )
|
||||||
{
|
{
|
||||||
report_strictz_error( STRZERR_GET_PROP, "@get_prop called with object 0" );
|
report_strictz_error( STRZERR_GET_PROP, "@get_prop called with object 0" );
|
||||||
store_operand( 0 );
|
store_operand( 0 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load address of first property */
|
/* Load address of first property */
|
||||||
prop_addr = get_property_addr( obj );
|
prop_addr = get_property_addr( obj );
|
||||||
|
|
||||||
/* Scan down the property list */
|
/* Scan down the property list */
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
value = get_byte( prop_addr );
|
value = get_byte( prop_addr );
|
||||||
if ( ( zbyte_t ) ( value & property_mask ) <= ( zbyte_t ) prop )
|
if ( ( zbyte_t ) ( value & property_mask ) <= ( zbyte_t ) prop )
|
||||||
break;
|
break;
|
||||||
prop_addr = get_next_property( prop_addr );
|
prop_addr = get_next_property( prop_addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the property ids match then load the first property */
|
/* If the property ids match then load the first property */
|
||||||
|
|
||||||
if ( ( zbyte_t ) ( value & property_mask ) == ( zbyte_t ) prop ) /* property found */
|
if ( ( zbyte_t ) ( value & property_mask ) == ( zbyte_t ) prop ) /* property found */
|
||||||
{
|
{
|
||||||
prop_addr++;
|
prop_addr++;
|
||||||
/* Only load first property if it is a byte sized property */
|
/* Only load first property if it is a byte sized property */
|
||||||
if ( h_type <= V3 && !( value & 0xe0 ) || h_type >= V4 && !( value & 0xc0 ) )
|
if ( (h_type <= V3 && !( value & 0xe0 )) || (h_type >= V4 && !( value & 0xc0 )) )
|
||||||
{
|
{
|
||||||
bprop_val = get_byte( prop_addr );
|
bprop_val = get_byte( prop_addr );
|
||||||
wprop_val = bprop_val;
|
wprop_val = bprop_val;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
wprop_val = get_word( prop_addr );
|
wprop_val = get_word( prop_addr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* property not found */
|
else /* property not found */
|
||||||
{
|
{
|
||||||
/* Calculate the address of the default property */
|
/* Calculate the address of the default property */
|
||||||
prop_addr = h_objects_offset + ( ( prop - 1 ) * 2 );
|
prop_addr = h_objects_offset + ( ( prop - 1 ) * 2 );
|
||||||
wprop_val = get_word( prop_addr );
|
wprop_val = get_word( prop_addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* store the property value */
|
/* store the property value */
|
||||||
|
|
||||||
store_operand( wprop_val );
|
store_operand( wprop_val );
|
||||||
|
|
||||||
} /* z_get_prop */
|
} /* z_get_prop */
|
||||||
|
|
||||||
|
@ -171,48 +171,48 @@ void z_get_prop( zword_t obj, zword_t prop )
|
||||||
|
|
||||||
void z_put_prop( zword_t obj, zword_t prop, zword_t setvalue )
|
void z_put_prop( zword_t obj, zword_t prop, zword_t setvalue )
|
||||||
{
|
{
|
||||||
zword_t prop_addr;
|
zword_t prop_addr;
|
||||||
zword_t value;
|
zword_t value;
|
||||||
|
|
||||||
#ifdef STRICTZ
|
#ifdef STRICTZ
|
||||||
if ( obj == 0 )
|
if ( obj == 0 )
|
||||||
{
|
{
|
||||||
report_strictz_error( STRZERR_PUT_PROP, "@put_prop called with object 0" );
|
report_strictz_error( STRZERR_PUT_PROP, "@put_prop called with object 0" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load address of first property */
|
/* Load address of first property */
|
||||||
prop_addr = get_property_addr( obj );
|
prop_addr = get_property_addr( obj );
|
||||||
|
|
||||||
/* Scan down the property list */
|
/* Scan down the property list */
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
value = get_byte( prop_addr );
|
value = get_byte( prop_addr );
|
||||||
if ( ( value & property_mask ) <= prop )
|
if ( ( value & property_mask ) <= prop )
|
||||||
break;
|
break;
|
||||||
prop_addr = get_next_property( prop_addr );
|
prop_addr = get_next_property( prop_addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the property id was found, store a new value, otherwise complain */
|
/* If the property id was found, store a new value, otherwise complain */
|
||||||
|
|
||||||
if ( ( value & property_mask ) != prop )
|
if ( ( value & property_mask ) != prop )
|
||||||
{
|
{
|
||||||
fatal( "store_property(): No such property" );
|
fatal( "store_property(): No such property" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine if this is a byte or word sized property */
|
/* Determine if this is a byte or word sized property */
|
||||||
|
|
||||||
prop_addr++;
|
prop_addr++;
|
||||||
|
|
||||||
if ( h_type <= V3 && !( value & 0xe0 ) || h_type >= V4 && !( value & 0xc0 ) )
|
if ( (h_type <= V3 && !( value & 0xe0 )) || (h_type >= V4 && !( value & 0xc0 )) )
|
||||||
{
|
{
|
||||||
set_byte( prop_addr, ( zbyte_t ) setvalue );
|
set_byte( prop_addr, ( zbyte_t ) setvalue );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
set_word( prop_addr, ( zword_t ) setvalue );
|
set_word( prop_addr, ( zword_t ) setvalue );
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* z_put_prop */
|
} /* z_put_prop */
|
||||||
|
|
||||||
|
@ -226,43 +226,43 @@ void z_put_prop( zword_t obj, zword_t prop, zword_t setvalue )
|
||||||
|
|
||||||
void z_get_next_prop( zword_t obj, zword_t prop )
|
void z_get_next_prop( zword_t obj, zword_t prop )
|
||||||
{
|
{
|
||||||
zword_t prop_addr;
|
zword_t prop_addr;
|
||||||
zbyte_t value;
|
zbyte_t value;
|
||||||
|
|
||||||
#ifdef STRICTZ
|
#ifdef STRICTZ
|
||||||
if ( obj == 0 )
|
if ( obj == 0 )
|
||||||
{
|
{
|
||||||
report_strictz_error( STRZERR_GET_NEXT_PROP, "@get_next_prop called with object 0" );
|
report_strictz_error( STRZERR_GET_NEXT_PROP, "@get_next_prop called with object 0" );
|
||||||
store_operand( 0 );
|
store_operand( 0 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load address of first property */
|
/* Load address of first property */
|
||||||
prop_addr = get_property_addr( obj );
|
prop_addr = get_property_addr( obj );
|
||||||
|
|
||||||
/* If the property id is non zero then find the next property */
|
/* If the property id is non zero then find the next property */
|
||||||
if ( prop != 0 )
|
if ( prop != 0 )
|
||||||
{
|
{
|
||||||
/* Scan down the property list while the target property id is less
|
/* Scan down the property list while the target property id is less
|
||||||
* than the property id in the list */
|
* than the property id in the list */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
value = get_byte( prop_addr );
|
value = get_byte( prop_addr );
|
||||||
prop_addr = get_next_property( prop_addr );
|
prop_addr = get_next_property( prop_addr );
|
||||||
}
|
}
|
||||||
while ( ( zbyte_t ) ( value & property_mask ) > ( zbyte_t ) prop );
|
while ( ( zbyte_t ) ( value & property_mask ) > ( zbyte_t ) prop );
|
||||||
|
|
||||||
/* If the property id wasn't found then complain */
|
/* If the property id wasn't found then complain */
|
||||||
if ( ( zbyte_t ) ( value & property_mask ) != ( zbyte_t ) prop )
|
if ( ( zbyte_t ) ( value & property_mask ) != ( zbyte_t ) prop )
|
||||||
{
|
{
|
||||||
fatal( "load_next_property(): No such property" );
|
fatal( "load_next_property(): No such property" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the next property id */
|
/* Return the next property id */
|
||||||
value = get_byte( prop_addr );
|
value = get_byte( prop_addr );
|
||||||
store_operand( ( zword_t ) ( value & property_mask ) );
|
store_operand( ( zword_t ) ( value & property_mask ) );
|
||||||
|
|
||||||
} /* z_get_next_prop */
|
} /* z_get_next_prop */
|
||||||
|
|
||||||
|
@ -275,47 +275,47 @@ void z_get_next_prop( zword_t obj, zword_t prop )
|
||||||
|
|
||||||
void z_get_prop_addr( zword_t obj, zword_t prop )
|
void z_get_prop_addr( zword_t obj, zword_t prop )
|
||||||
{
|
{
|
||||||
zword_t prop_addr;
|
zword_t prop_addr;
|
||||||
zbyte_t value;
|
zbyte_t value;
|
||||||
|
|
||||||
#ifdef STRICTZ
|
#ifdef STRICTZ
|
||||||
if ( obj == 0 )
|
if ( obj == 0 )
|
||||||
{
|
{
|
||||||
report_strictz_error( STRZERR_GET_PROP_ADDR, "@get_prop_addr called with object 0" );
|
report_strictz_error( STRZERR_GET_PROP_ADDR, "@get_prop_addr called with object 0" );
|
||||||
store_operand( 0 );
|
store_operand( 0 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Load address of first property */
|
/* Load address of first property */
|
||||||
prop_addr = get_property_addr( obj );
|
prop_addr = get_property_addr( obj );
|
||||||
|
|
||||||
/* Scan down the property list */
|
/* Scan down the property list */
|
||||||
for ( ;; )
|
for ( ;; )
|
||||||
{
|
{
|
||||||
value = get_byte( prop_addr );
|
value = get_byte( prop_addr );
|
||||||
if ( ( zbyte_t ) ( value & property_mask ) <= ( zbyte_t ) prop )
|
if ( ( zbyte_t ) ( value & property_mask ) <= ( zbyte_t ) prop )
|
||||||
break;
|
break;
|
||||||
prop_addr = get_next_property( prop_addr );
|
prop_addr = get_next_property( prop_addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the property id was found, calc the prop addr, else return zero */
|
/* If the property id was found, calc the prop addr, else return zero */
|
||||||
|
|
||||||
if ( ( zbyte_t ) ( value & property_mask ) == ( zbyte_t ) prop )
|
if ( ( zbyte_t ) ( value & property_mask ) == ( zbyte_t ) prop )
|
||||||
{
|
{
|
||||||
/* Skip past property id, can be a byte or a word */
|
/* Skip past property id, can be a byte or a word */
|
||||||
|
|
||||||
if ( h_type >= V4 && ( value & 0x80 ) )
|
if ( h_type >= V4 && ( value & 0x80 ) )
|
||||||
{
|
{
|
||||||
prop_addr++;
|
prop_addr++;
|
||||||
}
|
}
|
||||||
store_operand( ( zword_t ) ( prop_addr + 1 ) );
|
store_operand( ( zword_t ) ( prop_addr + 1 ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No property found, just return 0 */
|
/* No property found, just return 0 */
|
||||||
store_operand( 0 );
|
store_operand( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* z_get_prop_addr */
|
} /* z_get_prop_addr */
|
||||||
|
|
||||||
|
@ -328,36 +328,36 @@ void z_get_prop_addr( zword_t obj, zword_t prop )
|
||||||
|
|
||||||
void z_get_prop_len( zword_t prop_addr )
|
void z_get_prop_len( zword_t prop_addr )
|
||||||
{
|
{
|
||||||
zbyte_t value;
|
zbyte_t value;
|
||||||
|
|
||||||
/* This is proper according to an email to the Zmachine list by Graham*/
|
/* This is proper according to an email to the Zmachine list by Graham*/
|
||||||
if ( prop_addr == 0 )
|
if ( prop_addr == 0 )
|
||||||
{
|
{
|
||||||
store_operand( ( zword_t ) 0 );
|
store_operand( ( zword_t ) 0 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Back up the property pointer to the property id */
|
/* Back up the property pointer to the property id */
|
||||||
prop_addr--;
|
prop_addr--;
|
||||||
value = get_byte( prop_addr );
|
value = get_byte( prop_addr );
|
||||||
|
|
||||||
if ( h_type <= V3 )
|
if ( h_type <= V3 )
|
||||||
{
|
{
|
||||||
value = ( zbyte_t ) ( ( value >> ( zbyte_t ) 5 ) + ( zbyte_t ) 1 );
|
value = ( zbyte_t ) ( ( value >> ( zbyte_t ) 5 ) + ( zbyte_t ) 1 );
|
||||||
}
|
}
|
||||||
else if ( !( value & 0x80 ) )
|
else if ( !( value & 0x80 ) )
|
||||||
{
|
{
|
||||||
value = ( zbyte_t ) ( ( value >> ( zbyte_t ) 6 ) + ( zbyte_t ) 1 );
|
value = ( zbyte_t ) ( ( value >> ( zbyte_t ) 6 ) + ( zbyte_t ) 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value &= ( zbyte_t ) property_size_mask;
|
value &= ( zbyte_t ) property_size_mask;
|
||||||
|
|
||||||
if ( value == 0 )
|
if ( value == 0 )
|
||||||
value = ( zbyte_t ) 64; /* spec 1.0 */
|
value = ( zbyte_t ) 64; /* spec 1.0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
store_operand( value );
|
store_operand( value );
|
||||||
|
|
||||||
} /* z_get_prop_len */
|
} /* z_get_prop_len */
|
||||||
|
|
||||||
|
@ -372,76 +372,76 @@ void z_get_prop_len( zword_t prop_addr )
|
||||||
|
|
||||||
void z_scan_table( int argc, zword_t * argv )
|
void z_scan_table( int argc, zword_t * argv )
|
||||||
{
|
{
|
||||||
unsigned long address;
|
unsigned long address;
|
||||||
unsigned int i, step;
|
unsigned int i, step;
|
||||||
|
|
||||||
/* Supply default parameters */
|
/* Supply default parameters */
|
||||||
|
|
||||||
if ( argc < 4 )
|
if ( argc < 4 )
|
||||||
argv[3] = 0x82;
|
argv[3] = 0x82;
|
||||||
|
|
||||||
address = argv[1];
|
address = argv[1];
|
||||||
step = argv[3];
|
step = argv[3];
|
||||||
|
|
||||||
/* Check size bit (bit 7 of step, 1 = word, 0 = byte) */
|
/* Check size bit (bit 7 of step, 1 = word, 0 = byte) */
|
||||||
|
|
||||||
if ( step & 0x80 )
|
if ( step & 0x80 )
|
||||||
{
|
{
|
||||||
|
|
||||||
step &= 0x7f;
|
step &= 0x7f;
|
||||||
|
|
||||||
/* Scan down an array for count words looking for a match */
|
/* Scan down an array for count words looking for a match */
|
||||||
|
|
||||||
for ( i = 0; i < argv[2]; i++ )
|
for ( i = 0; i < argv[2]; i++ )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* If the word was found store its address and jump */
|
/* If the word was found store its address and jump */
|
||||||
|
|
||||||
if ( read_data_word( &address ) == argv[0] )
|
if ( read_data_word( &address ) == argv[0] )
|
||||||
{
|
{
|
||||||
store_operand( ( zword_t ) ( address - 2 ) );
|
store_operand( ( zword_t ) ( address - 2 ) );
|
||||||
conditional_jump( TRUE );
|
conditional_jump( TRUE );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Back up address then step by increment */
|
/* Back up address then step by increment */
|
||||||
|
|
||||||
address = ( address - 2 ) + step;
|
address = ( address - 2 ) + step;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
step &= 0x7f;
|
step &= 0x7f;
|
||||||
|
|
||||||
/* Scan down an array for count bytes looking for a match */
|
/* Scan down an array for count bytes looking for a match */
|
||||||
|
|
||||||
for ( i = 0; i < argv[2]; i++ )
|
for ( i = 0; i < argv[2]; i++ )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* If the byte was found store its address and jump */
|
/* If the byte was found store its address and jump */
|
||||||
|
|
||||||
if ( ( zword_t ) read_data_byte( &address ) == ( zword_t ) argv[0] )
|
if ( ( zword_t ) read_data_byte( &address ) == ( zword_t ) argv[0] )
|
||||||
{
|
{
|
||||||
store_operand( ( zword_t ) ( address - 1 ) );
|
store_operand( ( zword_t ) ( address - 1 ) );
|
||||||
conditional_jump( TRUE );
|
conditional_jump( TRUE );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Back up address then step by increment */
|
/* Back up address then step by increment */
|
||||||
|
|
||||||
address = ( address - 1 ) + step;
|
address = ( address - 1 ) + step;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the data was not found store zero and jump */
|
/* If the data was not found store zero and jump */
|
||||||
|
|
||||||
store_operand( 0 );
|
store_operand( 0 );
|
||||||
conditional_jump( FALSE );
|
conditional_jump( FALSE );
|
||||||
|
|
||||||
} /* z_scan_table */
|
} /* z_scan_table */
|
||||||
|
|
||||||
|
@ -452,41 +452,41 @@ void z_scan_table( int argc, zword_t * argv )
|
||||||
|
|
||||||
void z_copy_table( zword_t src, zword_t dst, zword_t count )
|
void z_copy_table( zword_t src, zword_t dst, zword_t count )
|
||||||
{
|
{
|
||||||
unsigned long address;
|
unsigned long address;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
/* Catch no-op move case */
|
/* Catch no-op move case */
|
||||||
|
|
||||||
if ( src == dst || count == 0 )
|
if ( src == dst || count == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* If destination address is zero then fill source with zeros */
|
/* If destination address is zero then fill source with zeros */
|
||||||
|
|
||||||
if ( dst == 0 )
|
if ( dst == 0 )
|
||||||
{
|
{
|
||||||
for ( i = 0; i < count; i++ )
|
for ( i = 0; i < count; i++ )
|
||||||
z_storeb( src++, 0, 0 );
|
z_storeb( src++, 0, 0 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
address = src;
|
address = src;
|
||||||
|
|
||||||
if ( ( ZINT16 ) count < 0 )
|
if ( ( ZINT16 ) count < 0 )
|
||||||
{
|
{
|
||||||
while ( count++ )
|
while ( count++ )
|
||||||
z_storeb( dst++, 0, read_data_byte( &address ) );
|
z_storeb( dst++, 0, read_data_byte( &address ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
address += ( unsigned long ) count;
|
address += ( unsigned long ) count;
|
||||||
dst += count;
|
dst += count;
|
||||||
while ( count-- )
|
while ( count-- )
|
||||||
{
|
{
|
||||||
address--;
|
address--;
|
||||||
z_storeb( --dst, 0, read_data_byte( &address ) );
|
z_storeb( --dst, 0, read_data_byte( &address ) );
|
||||||
address--;
|
address--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* z_copy_table */
|
} /* z_copy_table */
|
||||||
|
|
||||||
|
@ -499,15 +499,15 @@ void z_copy_table( zword_t src, zword_t dst, zword_t count )
|
||||||
|
|
||||||
void z_loadw( zword_t addr, zword_t offset )
|
void z_loadw( zword_t addr, zword_t offset )
|
||||||
{
|
{
|
||||||
unsigned long address;
|
unsigned long address;
|
||||||
|
|
||||||
/* Calculate word array index address */
|
/* Calculate word array index address */
|
||||||
|
|
||||||
address = addr + ( offset * 2 );
|
address = addr + ( offset * 2 );
|
||||||
|
|
||||||
/* Store the byte */
|
/* Store the byte */
|
||||||
|
|
||||||
store_operand( read_data_word( &address ) );
|
store_operand( read_data_word( &address ) );
|
||||||
|
|
||||||
} /* z_loadw */
|
} /* z_loadw */
|
||||||
|
|
||||||
|
@ -520,15 +520,15 @@ void z_loadw( zword_t addr, zword_t offset )
|
||||||
|
|
||||||
void z_loadb( zword_t addr, zword_t offset )
|
void z_loadb( zword_t addr, zword_t offset )
|
||||||
{
|
{
|
||||||
unsigned long address;
|
unsigned long address;
|
||||||
|
|
||||||
/* Calculate byte array index address */
|
/* Calculate byte array index address */
|
||||||
|
|
||||||
address = addr + offset;
|
address = addr + offset;
|
||||||
|
|
||||||
/* Load the byte */
|
/* Load the byte */
|
||||||
|
|
||||||
store_operand( read_data_byte( &address ) );
|
store_operand( read_data_byte( &address ) );
|
||||||
|
|
||||||
} /* z_loadb */
|
} /* z_loadb */
|
||||||
|
|
||||||
|
@ -542,18 +542,18 @@ void z_loadb( zword_t addr, zword_t offset )
|
||||||
void z_storew( zword_t addr, zword_t offset, zword_t value )
|
void z_storew( zword_t addr, zword_t offset, zword_t value )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Calculate word array index address */
|
/* Calculate word array index address */
|
||||||
|
|
||||||
addr += offset * 2;
|
addr += offset * 2;
|
||||||
|
|
||||||
/* Check we are not writing outside of the writeable data area */
|
/* Check we are not writing outside of the writeable data area */
|
||||||
|
|
||||||
if ( addr > data_size )
|
if ( addr > data_size )
|
||||||
fatal( "z_storew(): Attempted write outside of data area" );
|
fatal( "z_storew(): Attempted write outside of data area" );
|
||||||
|
|
||||||
/* Store the word */
|
/* Store the word */
|
||||||
|
|
||||||
set_word( addr, value );
|
set_word( addr, value );
|
||||||
|
|
||||||
} /* z_storew */
|
} /* z_storew */
|
||||||
|
|
||||||
|
@ -567,17 +567,17 @@ void z_storew( zword_t addr, zword_t offset, zword_t value )
|
||||||
void z_storeb( zword_t addr, zword_t offset, zword_t value )
|
void z_storeb( zword_t addr, zword_t offset, zword_t value )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Calculate byte array index address */
|
/* Calculate byte array index address */
|
||||||
|
|
||||||
addr += offset;
|
addr += offset;
|
||||||
|
|
||||||
/* Check we are not writing outside of the writeable data area */
|
/* Check we are not writing outside of the writeable data area */
|
||||||
|
|
||||||
if ( addr > data_size )
|
if ( addr > data_size )
|
||||||
fatal( "z_storeb(): Attempted write outside of data area" );
|
fatal( "z_storeb(): Attempted write outside of data area" );
|
||||||
|
|
||||||
/* Store the byte */
|
/* Store the byte */
|
||||||
|
|
||||||
set_byte( addr, value );
|
set_byte( addr, value );
|
||||||
|
|
||||||
} /* z_storeb */
|
} /* z_storeb */
|
||||||
|
|
880
quetzal.c
880
quetzal.c
|
@ -1,14 +1,14 @@
|
||||||
|
|
||||||
/* $Id: quetzal.c,v 1.3 2000/07/05 15:20:34 jholder Exp $
|
/* $Id: quetzal.c,v 1.3 2000/07/05 15:20:34 jholder Exp $
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
* see doc/License.txt for License Information
|
* see doc/License.txt for License Information
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* File name: $Id: quetzal.c,v 1.3 2000/07/05 15:20:34 jholder Exp $
|
* File name: $Id: quetzal.c,v 1.3 2000/07/05 15:20:34 jholder Exp $
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
*
|
*
|
||||||
* Modification history:
|
* Modification history:
|
||||||
* $Log: quetzal.c,v $
|
* $Log: quetzal.c,v $
|
||||||
* Revision 1.3 2000/07/05 15:20:34 jholder
|
* Revision 1.3 2000/07/05 15:20:34 jholder
|
||||||
* Updated code to remove warnings.
|
* Updated code to remove warnings.
|
||||||
|
@ -59,17 +59,17 @@ typedef unsigned long ul_t;
|
||||||
#define ID_ANNO 0x414e4e4f
|
#define ID_ANNO 0x414e4e4f
|
||||||
|
|
||||||
/* macros to write QUETZAL files */
|
/* macros to write QUETZAL files */
|
||||||
#define write_byte(fp,b) (put_c ((unsigned)(b),fp) != EOF)
|
#define write_byte(fp,b) (put_c ((unsigned)(b),fp) != EOF)
|
||||||
#define write_bytx(fp,b) write_byte(fp,(b) & 0xFF)
|
#define write_bytx(fp,b) write_byte(fp,(b) & 0xFF)
|
||||||
#define write_word(fp,w) \
|
#define write_word(fp,w) \
|
||||||
(write_bytx(fp,(w)>> 8) && write_bytx(fp,(w)))
|
(write_bytx(fp,(w)>> 8) && write_bytx(fp,(w)))
|
||||||
#define write_long(fp,l) \
|
#define write_long(fp,l) \
|
||||||
(write_bytx(fp,(ul_t)(l)>>24) && write_bytx(fp,(ul_t)(l)>>16) && \
|
(write_bytx(fp,(ul_t)(l)>>24) && write_bytx(fp,(ul_t)(l)>>16) && \
|
||||||
write_bytx(fp,(ul_t)(l)>> 8) && write_bytx(fp,(ul_t)(l)))
|
write_bytx(fp,(ul_t)(l)>> 8) && write_bytx(fp,(ul_t)(l)))
|
||||||
#define write_chnk(fp,id,len) \
|
#define write_chnk(fp,id,len) \
|
||||||
(write_long(fp,id) && write_long(fp,len))
|
(write_long(fp,id) && write_long(fp,len))
|
||||||
#define write_run(fp,run) \
|
#define write_run(fp,run) \
|
||||||
(write_byte(fp,0) && write_byte(fp,(run)))
|
(write_byte(fp,0) && write_byte(fp,(run)))
|
||||||
|
|
||||||
/* save_quetzal
|
/* save_quetzal
|
||||||
*
|
*
|
||||||
|
@ -82,160 +82,160 @@ int save_quetzal( FILE * sfp, gzFile * gfp )
|
||||||
int save_quetzal( FILE * sfp, FILE * gfp )
|
int save_quetzal( FILE * sfp, FILE * gfp )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ul_t ifzslen = 0, cmemlen = 0, stkslen = 0, tmp_pc;
|
ul_t ifzslen = 0, cmemlen = 0, stkslen = 0, tmp_pc;
|
||||||
int c;
|
int c;
|
||||||
zword_t i, j, n, init_fp, tmp_fp, nstk, nvars, args;
|
zword_t i, j, n, init_fp, tmp_fp, nstk, nvars, args;
|
||||||
zword_t frames[STACK_SIZE / 4 + 1];
|
zword_t frames[STACK_SIZE / 4 + 1];
|
||||||
zbyte_t var;
|
zbyte_t var;
|
||||||
long cmempos, stkspos;
|
long cmempos, stkspos;
|
||||||
|
|
||||||
/* write IFZS header */
|
/* write IFZS header */
|
||||||
if ( !write_chnk( sfp, ID_FORM, 0 ) )
|
if ( !write_chnk( sfp, ID_FORM, 0 ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_long( sfp, ID_IFZS ) )
|
if ( !write_long( sfp, ID_IFZS ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* write IFhd chunk */
|
/* write IFhd chunk */
|
||||||
if ( !write_chnk( sfp, ID_IFhd, 13 ) )
|
if ( !write_chnk( sfp, ID_IFhd, 13 ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_word( sfp, h_version ) )
|
if ( !write_word( sfp, h_version ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for ( i = 0; i < 6; ++i )
|
for ( i = 0; i < 6; ++i )
|
||||||
if ( !write_byte( sfp, get_byte( H_RELEASE_DATE + i ) ) )
|
if ( !write_byte( sfp, get_byte( H_RELEASE_DATE + i ) ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_word( sfp, h_checksum ) )
|
if ( !write_word( sfp, h_checksum ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_long( sfp, ( ( ul_t ) pc ) << 8 ) ) /* includes pad byte */
|
if ( !write_long( sfp, ( ( ul_t ) pc ) << 8 ) ) /* includes pad byte */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* write CMem chunk */
|
/* write CMem chunk */
|
||||||
/* j is current run length */
|
/* j is current run length */
|
||||||
if ( ( cmempos = ftell( sfp ) ) < 0 )
|
if ( ( cmempos = ftell( sfp ) ) < 0 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_chnk( sfp, ID_CMem, 0 ) )
|
if ( !write_chnk( sfp, ID_CMem, 0 ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
jz_rewind( gfp );
|
jz_rewind( gfp );
|
||||||
for ( i = 0, j = 0, cmemlen = 0; i < h_restart_size; ++i )
|
for ( i = 0, j = 0, cmemlen = 0; i < h_restart_size; ++i )
|
||||||
{
|
{
|
||||||
if ( ( c = jz_getc( gfp ) ) == EOF )
|
if ( ( c = jz_getc( gfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
c ^= get_byte( i );
|
c ^= get_byte( i );
|
||||||
if ( c == 0 )
|
if ( c == 0 )
|
||||||
++j;
|
++j;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* write any run there may be */
|
/* write any run there may be */
|
||||||
if ( j > 0 )
|
if ( j > 0 )
|
||||||
{
|
{
|
||||||
for ( ; j > 0x100; j -= 0x100 )
|
for ( ; j > 0x100; j -= 0x100 )
|
||||||
{
|
{
|
||||||
if ( !write_run( sfp, 0xFF ) )
|
if ( !write_run( sfp, 0xFF ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
cmemlen += 2;
|
cmemlen += 2;
|
||||||
}
|
}
|
||||||
if ( !write_run( sfp, j - 1 ) )
|
if ( !write_run( sfp, j - 1 ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
cmemlen += 2;
|
cmemlen += 2;
|
||||||
j = 0;
|
j = 0;
|
||||||
}
|
}
|
||||||
/* write this byte */
|
/* write this byte */
|
||||||
if ( !write_byte( sfp, c ) )
|
if ( !write_byte( sfp, c ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
++cmemlen;
|
++cmemlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* there may be a run here, which we ignore */
|
/* there may be a run here, which we ignore */
|
||||||
if ( cmemlen & 1 ) /* chunk length must be even */
|
if ( cmemlen & 1 ) /* chunk length must be even */
|
||||||
if ( !write_byte( sfp, 0 ) )
|
if ( !write_byte( sfp, 0 ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* write Stks chunk */
|
/* write Stks chunk */
|
||||||
if ( ( stkspos = ftell( sfp ) ) < 0 )
|
if ( ( stkspos = ftell( sfp ) ) < 0 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_chnk( sfp, ID_Stks, 0 ) )
|
if ( !write_chnk( sfp, ID_Stks, 0 ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/* frames is a list of FPs, most recent first */
|
/* frames is a list of FPs, most recent first */
|
||||||
frames[0] = sp - 5; /* what FP would be if we did a call now */
|
frames[0] = sp - 5; /* what FP would be if we did a call now */
|
||||||
for ( init_fp = fp, n = 0; init_fp <= STACK_SIZE - 5; init_fp = stack[init_fp + 2] )
|
for ( init_fp = fp, n = 0; init_fp <= STACK_SIZE - 5; init_fp = stack[init_fp + 2] )
|
||||||
frames[++n] = init_fp;
|
frames[++n] = init_fp;
|
||||||
init_fp = frames[n] + 4;
|
init_fp = frames[n] + 4;
|
||||||
|
|
||||||
if ( h_type != 6 )
|
if ( h_type != 6 )
|
||||||
{ /* write a dummy frame for stack used before first call */
|
{ /* write a dummy frame for stack used before first call */
|
||||||
for ( i = 0; i < 6; ++i )
|
for ( i = 0; i < 6; ++i )
|
||||||
if ( !write_byte( sfp, 0 ) )
|
if ( !write_byte( sfp, 0 ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
nstk = STACK_SIZE - 1 - init_fp;
|
nstk = STACK_SIZE - 1 - init_fp;
|
||||||
if ( !write_word( sfp, nstk ) )
|
if ( !write_word( sfp, nstk ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for ( i = STACK_SIZE - 1; i > init_fp; --i )
|
for ( i = STACK_SIZE - 1; i > init_fp; --i )
|
||||||
if ( !write_word( sfp, stack[i] ) )
|
if ( !write_word( sfp, stack[i] ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
stkslen = 8 + 2 * nstk;
|
stkslen = 8 + 2 * nstk;
|
||||||
}
|
}
|
||||||
for ( i = n; i > 0; --i )
|
for ( i = n; i > 0; --i )
|
||||||
{
|
{
|
||||||
/* write out one stack frame.
|
/* write out one stack frame.
|
||||||
*
|
*
|
||||||
* tmp_fp : FP when this frame was current
|
* tmp_fp : FP when this frame was current
|
||||||
* tmp_pc : PC on return from this frame, plus 000pvvvv
|
* tmp_pc : PC on return from this frame, plus 000pvvvv
|
||||||
* nvars : number of local vars for this frame
|
* nvars : number of local vars for this frame
|
||||||
* args : argument mask for this frame
|
* args : argument mask for this frame
|
||||||
* nstk : words of evaluation stack used for this frame
|
* nstk : words of evaluation stack used for this frame
|
||||||
* var : variable to store result
|
* var : variable to store result
|
||||||
*/
|
*/
|
||||||
tmp_fp = frames[i];
|
tmp_fp = frames[i];
|
||||||
nvars = ( stack[tmp_fp + 1] & VARS_MASK ) >> VAR_SHIFT;
|
nvars = ( stack[tmp_fp + 1] & VARS_MASK ) >> VAR_SHIFT;
|
||||||
args = stack[tmp_fp + 1] & ARGS_MASK;
|
args = stack[tmp_fp + 1] & ARGS_MASK;
|
||||||
nstk = tmp_fp - frames[i - 1] - nvars - 4;
|
nstk = tmp_fp - frames[i - 1] - nvars - 4;
|
||||||
tmp_pc = stack[tmp_fp + 3] + ( ul_t ) stack[tmp_fp + 4] * PAGE_SIZE;
|
tmp_pc = stack[tmp_fp + 3] + ( ul_t ) stack[tmp_fp + 4] * PAGE_SIZE;
|
||||||
switch ( stack[tmp_fp + 1] & TYPE_MASK )
|
switch ( stack[tmp_fp + 1] & TYPE_MASK )
|
||||||
{
|
{
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
var = read_data_byte( &tmp_pc ); /* also increments tmp_pc */
|
var = read_data_byte( &tmp_pc ); /* also increments tmp_pc */
|
||||||
tmp_pc = ( tmp_pc << 8 ) | nvars;
|
tmp_pc = ( tmp_pc << 8 ) | nvars;
|
||||||
break;
|
break;
|
||||||
case PROCEDURE:
|
case PROCEDURE:
|
||||||
var = 0;
|
var = 0;
|
||||||
tmp_pc = ( tmp_pc << 8 ) | 0x10 | nvars; /* set procedure flag */
|
tmp_pc = ( tmp_pc << 8 ) | 0x10 | nvars; /* set procedure flag */
|
||||||
break;
|
break;
|
||||||
/* case ASYNC: */
|
/* case ASYNC: */
|
||||||
default:
|
default:
|
||||||
output_line( "Illegal Z-machine operation: can't save while in interrupt." );
|
output_line( "Illegal Z-machine operation: can't save while in interrupt." );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ( args != 0 )
|
if ( args != 0 )
|
||||||
args = ( 1 << args ) - 1; /* make args into bitmap */
|
args = ( 1 << args ) - 1; /* make args into bitmap */
|
||||||
if ( !write_long( sfp, tmp_pc ) )
|
if ( !write_long( sfp, tmp_pc ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_byte( sfp, var ) )
|
if ( !write_byte( sfp, var ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_byte( sfp, args ) )
|
if ( !write_byte( sfp, args ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !write_word( sfp, nstk ) )
|
if ( !write_word( sfp, nstk ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for ( j = 0; j < nvars + nstk; ++j, --tmp_fp )
|
for ( j = 0; j < nvars + nstk; ++j, --tmp_fp )
|
||||||
if ( !write_word( sfp, stack[tmp_fp] ) )
|
if ( !write_word( sfp, stack[tmp_fp] ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
stkslen += 8 + 2 * ( nvars + nstk );
|
stkslen += 8 + 2 * ( nvars + nstk );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill in lengths for variable-sized chunks */
|
/* fill in lengths for variable-sized chunks */
|
||||||
ifzslen = 3 * 8 + 4 + 14 + cmemlen + stkslen;
|
ifzslen = 3 * 8 + 4 + 14 + cmemlen + stkslen;
|
||||||
if ( cmemlen & 1 )
|
if ( cmemlen & 1 )
|
||||||
++ifzslen;
|
++ifzslen;
|
||||||
( void ) fseek( sfp, ( long ) 4, SEEK_SET );
|
( void ) fseek( sfp, ( long ) 4, SEEK_SET );
|
||||||
if ( !write_long( sfp, ifzslen ) )
|
if ( !write_long( sfp, ifzslen ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
( void ) fseek( sfp, cmempos + 4, SEEK_SET );
|
( void ) fseek( sfp, cmempos + 4, SEEK_SET );
|
||||||
if ( !write_long( sfp, cmemlen ) )
|
if ( !write_long( sfp, cmemlen ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
( void ) fseek( sfp, stkspos + 4, SEEK_SET );
|
( void ) fseek( sfp, stkspos + 4, SEEK_SET );
|
||||||
if ( !write_long( sfp, stkslen ) )
|
if ( !write_long( sfp, stkslen ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* end save_quetzal */
|
/* end save_quetzal */
|
||||||
|
@ -247,14 +247,14 @@ int save_quetzal( FILE * sfp, FILE * gfp )
|
||||||
|
|
||||||
static int read_word( FILE * fp, zword_t * result )
|
static int read_word( FILE * fp, zword_t * result )
|
||||||
{
|
{
|
||||||
int a, b;
|
int a, b;
|
||||||
|
|
||||||
if ( ( a = get_c( fp ) ) == EOF )
|
if ( ( a = get_c( fp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( ( b = get_c( fp ) ) == EOF )
|
if ( ( b = get_c( fp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
*result = ( ( zword_t ) a << 8 ) | b;
|
*result = ( ( zword_t ) a << 8 ) | b;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read_long
|
/* read_long
|
||||||
|
@ -264,21 +264,21 @@ static int read_word( FILE * fp, zword_t * result )
|
||||||
|
|
||||||
static int read_long( FILE * fp, ul_t * result )
|
static int read_long( FILE * fp, ul_t * result )
|
||||||
{
|
{
|
||||||
int a, b, c, d;
|
int a, b, c, d;
|
||||||
|
|
||||||
if ( ( a = get_c( fp ) ) == EOF )
|
if ( ( a = get_c( fp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( ( b = get_c( fp ) ) == EOF )
|
if ( ( b = get_c( fp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( ( c = get_c( fp ) ) == EOF )
|
if ( ( c = get_c( fp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( ( d = get_c( fp ) ) == EOF )
|
if ( ( d = get_c( fp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
*result = ( ( ul_t ) a << 24 ) | ( ( ul_t ) b << 16 ) | ( ( ul_t ) c << 8 ) | d;
|
*result = ( ( ul_t ) a << 24 ) | ( ( ul_t ) b << 16 ) | ( ( ul_t ) c << 8 ) | d;
|
||||||
#ifdef QDEBUG
|
#ifdef QDEBUG
|
||||||
printf( "%c%c%c%c", a, b, c, d );
|
printf( "%c%c%c%c", a, b, c, d );
|
||||||
#endif
|
#endif
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore_quetzal
|
/* restore_quetzal
|
||||||
|
@ -299,274 +299,274 @@ int restore_quetzal( FILE * sfp, gzFile * gfp )
|
||||||
int restore_quetzal( FILE * sfp, FILE * gfp )
|
int restore_quetzal( FILE * sfp, FILE * gfp )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ul_t ifzslen, currlen, tmpl, skip = 0;
|
ul_t ifzslen, currlen, tmpl, skip = 0;
|
||||||
zword_t i, tmpw;
|
zword_t i, tmpw;
|
||||||
zbyte_t progress = GOT_NONE;
|
zbyte_t progress = GOT_NONE;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
/* check for IFZS file */
|
/* check for IFZS file */
|
||||||
if ( !read_long( sfp, &tmpl ) || !read_long( sfp, &ifzslen ) )
|
if ( !read_long( sfp, &tmpl ) || !read_long( sfp, &ifzslen ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !read_long( sfp, &currlen ) )
|
if ( !read_long( sfp, &currlen ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( tmpl != ID_FORM || currlen != ID_IFZS )
|
if ( tmpl != ID_FORM || currlen != ID_IFZS )
|
||||||
{
|
{
|
||||||
output_line( "This is not a saved game file!" );
|
output_line( "This is not a saved game file!" );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ( ( ifzslen & 1 ) || ifzslen < 4 )
|
if ( ( ifzslen & 1 ) || ifzslen < 4 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
ifzslen -= 4;
|
ifzslen -= 4;
|
||||||
|
|
||||||
/* read a chunk and process it */
|
/* read a chunk and process it */
|
||||||
while ( ifzslen > 0 )
|
while ( ifzslen > 0 )
|
||||||
{
|
{
|
||||||
/* read chunk header */
|
/* read chunk header */
|
||||||
if ( ifzslen < 8 )
|
if ( ifzslen < 8 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !read_long( sfp, &tmpl ) || !read_long( sfp, &currlen ) )
|
if ( !read_long( sfp, &tmpl ) || !read_long( sfp, &currlen ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
ifzslen -= 8;
|
ifzslen -= 8;
|
||||||
|
|
||||||
/* body of chunk */
|
/* body of chunk */
|
||||||
if ( ifzslen < currlen )
|
if ( ifzslen < currlen )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
skip = currlen & 1;
|
skip = currlen & 1;
|
||||||
ifzslen -= currlen + skip;
|
ifzslen -= currlen + skip;
|
||||||
switch ( tmpl )
|
switch ( tmpl )
|
||||||
{
|
{
|
||||||
case ID_IFhd:
|
case ID_IFhd:
|
||||||
if ( progress & GOT_HEADER )
|
if ( progress & GOT_HEADER )
|
||||||
{
|
{
|
||||||
output_line( "Save file has two IFhd chunks!" );
|
output_line( "Save file has two IFhd chunks!" );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
progress |= GOT_HEADER;
|
progress |= GOT_HEADER;
|
||||||
if ( currlen < 13 || !read_word( sfp, &i ) )
|
if ( currlen < 13 || !read_word( sfp, &i ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( i != h_version )
|
if ( i != h_version )
|
||||||
progress = GOT_ERROR;
|
progress = GOT_ERROR;
|
||||||
for ( i = H_RELEASE_DATE; i < H_RELEASE_DATE + 6; ++i )
|
for ( i = H_RELEASE_DATE; i < H_RELEASE_DATE + 6; ++i )
|
||||||
{
|
{
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( x != ( int ) get_byte( i ) )
|
if ( x != ( int ) get_byte( i ) )
|
||||||
progress = GOT_ERROR;
|
progress = GOT_ERROR;
|
||||||
}
|
}
|
||||||
if ( !read_word( sfp, &i ) )
|
if ( !read_word( sfp, &i ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( i != h_checksum )
|
if ( i != h_checksum )
|
||||||
progress = GOT_ERROR;
|
progress = GOT_ERROR;
|
||||||
if ( progress == GOT_ERROR )
|
if ( progress == GOT_ERROR )
|
||||||
{
|
{
|
||||||
output_line( "File was not saved from this story!" );
|
output_line( "File was not saved from this story!" );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
pc = ( ul_t ) x << 16;
|
pc = ( ul_t ) x << 16;
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
pc |= ( ul_t ) x << 8;
|
pc |= ( ul_t ) x << 8;
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
pc |= ( ul_t ) x;
|
pc |= ( ul_t ) x;
|
||||||
for ( i = 13; ( ul_t ) i < currlen; ++i )
|
for ( i = 13; ( ul_t ) i < currlen; ++i )
|
||||||
( void ) get_c( sfp ); /* skip rest of chunk */
|
( void ) get_c( sfp ); /* skip rest of chunk */
|
||||||
break;
|
break;
|
||||||
case ID_Stks:
|
case ID_Stks:
|
||||||
if ( progress & GOT_STACK )
|
if ( progress & GOT_STACK )
|
||||||
{
|
{
|
||||||
output_line( "File contains two stack chunks!" );
|
output_line( "File contains two stack chunks!" );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
progress |= GOT_STACK;
|
progress |= GOT_STACK;
|
||||||
sp = STACK_SIZE;
|
sp = STACK_SIZE;
|
||||||
if ( h_type != 6 )
|
if ( h_type != 6 )
|
||||||
{
|
{
|
||||||
/* dummy stack frame for stack used before call */
|
/* dummy stack frame for stack used before call */
|
||||||
if ( currlen < 8 )
|
if ( currlen < 8 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for ( i = 0; i < 6; ++i )
|
for ( i = 0; i < 6; ++i )
|
||||||
if ( get_c( sfp ) != 0 )
|
if ( get_c( sfp ) != 0 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( !read_word( sfp, &tmpw ) )
|
if ( !read_word( sfp, &tmpw ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
currlen -= 8;
|
currlen -= 8;
|
||||||
if ( currlen < (unsigned long)(tmpw * 2) )
|
if ( currlen < (unsigned long)(tmpw * 2) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for ( i = 0; i < tmpw; ++i )
|
for ( i = 0; i < tmpw; ++i )
|
||||||
if ( !read_word( sfp, stack + ( --sp ) ) )
|
if ( !read_word( sfp, stack + ( --sp ) ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
currlen -= tmpw * 2;
|
currlen -= tmpw * 2;
|
||||||
}
|
}
|
||||||
for ( fp = STACK_SIZE - 1, frame_count = 0; currlen > 0; currlen -= 8 )
|
for ( fp = STACK_SIZE - 1, frame_count = 0; currlen > 0; currlen -= 8 )
|
||||||
{
|
{
|
||||||
if ( currlen < 8 )
|
if ( currlen < 8 )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( sp < 4 )
|
if ( sp < 4 )
|
||||||
{
|
{
|
||||||
output_line( "error: this save-file has too much stack, and I can't cope." );
|
output_line( "error: this save-file has too much stack, and I can't cope." );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/* read PC, procedure flag, and arg count */
|
/* read PC, procedure flag, and arg count */
|
||||||
if ( !read_long( sfp, &tmpl ) )
|
if ( !read_long( sfp, &tmpl ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
y = ( zword_t ) tmpl & 0x0F;
|
y = ( zword_t ) tmpl & 0x0F;
|
||||||
tmpw = y << VAR_SHIFT; /* number of variables */
|
tmpw = (zword_t)(y << VAR_SHIFT); /* number of variables */
|
||||||
/* read result variable */
|
/* read result variable */
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if ( tmpl & 0x10 )
|
if ( tmpl & 0x10 )
|
||||||
{
|
{
|
||||||
tmpw |= PROCEDURE;
|
tmpw |= PROCEDURE;
|
||||||
tmpl >>= 8;
|
tmpl >>= 8;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tmpw |= FUNCTION;
|
tmpw |= FUNCTION;
|
||||||
tmpl >>= 8;
|
tmpl >>= 8;
|
||||||
--tmpl;
|
--tmpl;
|
||||||
/* sanity check on result variable */
|
/* sanity check on result variable */
|
||||||
if ( read_data_byte( &tmpl ) != ( zbyte_t ) x )
|
if ( read_data_byte( &tmpl ) != ( zbyte_t ) x )
|
||||||
{
|
{
|
||||||
output_line( "error: wrong variable number on stack (wrong story file?)." );
|
output_line( "error: wrong variable number on stack (wrong story file?)." );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
--tmpl; /* read_data_byte increments it */
|
--tmpl; /* read_data_byte increments it */
|
||||||
}
|
}
|
||||||
stack[--sp] = ( zword_t ) ( tmpl / PAGE_SIZE );
|
stack[--sp] = ( zword_t ) ( tmpl / PAGE_SIZE );
|
||||||
stack[--sp] = ( zword_t ) ( tmpl % PAGE_SIZE );
|
stack[--sp] = ( zword_t ) ( tmpl % PAGE_SIZE );
|
||||||
stack[--sp] = fp;
|
stack[--sp] = fp;
|
||||||
|
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
++x; /* hopefully x now contains a single set bit */
|
++x; /* hopefully x now contains a single set bit */
|
||||||
|
|
||||||
for ( i = 0; i < 8; ++i )
|
for ( i = 0; i < 8; ++i )
|
||||||
if ( x & ( 1 << i ) )
|
if ( x & ( 1 << i ) )
|
||||||
break;
|
break;
|
||||||
if ( x ^ ( 1 << i ) ) /* if more than 1 bit set */
|
if ( x ^ ( 1 << i ) ) /* if more than 1 bit set */
|
||||||
{
|
{
|
||||||
output_line
|
output_line
|
||||||
( "error: this game uses incomplete argument lists (which I can't handle)." );
|
( "error: this game uses incomplete argument lists (which I can't handle)." );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
tmpw |= i;
|
tmpw |= i;
|
||||||
stack[--sp] = tmpw;
|
stack[--sp] = tmpw;
|
||||||
fp = sp - 1; /* FP for next frame */
|
fp = sp - 1; /* FP for next frame */
|
||||||
if ( !read_word( sfp, &tmpw ) )
|
if ( !read_word( sfp, &tmpw ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
tmpw += y; /* local vars plus eval stack used */
|
tmpw += y; /* local vars plus eval stack used */
|
||||||
if ( tmpw >= sp )
|
if ( tmpw >= sp )
|
||||||
{
|
{
|
||||||
output_line( "error: this save-file uses more stack than I can cope with." );
|
output_line( "error: this save-file uses more stack than I can cope with." );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if ( currlen < (unsigned long)(tmpw * 2) )
|
if ( currlen < (unsigned long)(tmpw * 2) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for ( i = 0; i < tmpw; ++i )
|
for ( i = 0; i < tmpw; ++i )
|
||||||
if ( !read_word( sfp, stack + ( --sp ) ) )
|
if ( !read_word( sfp, stack + ( --sp ) ) )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
currlen -= tmpw * 2;
|
currlen -= tmpw * 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ID_ANNO:
|
case ID_ANNO:
|
||||||
z_buffer_mode( ON );
|
z_buffer_mode( ON );
|
||||||
for ( ; currlen > 0; --currlen )
|
for ( ; currlen > 0; --currlen )
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else
|
else
|
||||||
write_char( x );
|
write_char( x );
|
||||||
write_char( ( char ) 13 );
|
write_char( ( char ) 13 );
|
||||||
break;
|
break;
|
||||||
case ID_CMem:
|
case ID_CMem:
|
||||||
if ( !( progress & GOT_MEMORY ) )
|
if ( !( progress & GOT_MEMORY ) )
|
||||||
{
|
{
|
||||||
jz_rewind( gfp );
|
jz_rewind( gfp );
|
||||||
i = 0; /* bytes written to data area */
|
i = 0; /* bytes written to data area */
|
||||||
for ( ; currlen > 0; --currlen )
|
for ( ; currlen > 0; --currlen )
|
||||||
{
|
{
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if ( x == 0 ) /* start run */
|
if ( x == 0 ) /* start run */
|
||||||
{
|
{
|
||||||
if ( currlen < 2 )
|
if ( currlen < 2 )
|
||||||
{
|
{
|
||||||
output_line( "File contains bogus CMem chunk" );
|
output_line( "File contains bogus CMem chunk" );
|
||||||
for ( ; currlen > 0; --currlen )
|
for ( ; currlen > 0; --currlen )
|
||||||
( void ) get_c( sfp ); /* skip rest */
|
( void ) get_c( sfp ); /* skip rest */
|
||||||
currlen = 1;
|
currlen = 1;
|
||||||
i = 0xFFFF;
|
i = 0xFFFF;
|
||||||
break; /* keep going in case there's a UMem */
|
break; /* keep going in case there's a UMem */
|
||||||
}
|
}
|
||||||
--currlen;
|
--currlen;
|
||||||
if ( ( x = get_c( sfp ) ) == EOF )
|
if ( ( x = get_c( sfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
for ( ; x >= 0 && i < h_restart_size; --x, ++i )
|
for ( ; x >= 0 && i < h_restart_size; --x, ++i )
|
||||||
if ( ( y = jz_getc( gfp ) ) == EOF )
|
if ( ( y = jz_getc( gfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else
|
else
|
||||||
set_byte( i, y );
|
set_byte( i, y );
|
||||||
}
|
}
|
||||||
else /* not a run */
|
else /* not a run */
|
||||||
{
|
{
|
||||||
if ( ( y = jz_getc( gfp ) ) == EOF )
|
if ( ( y = jz_getc( gfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
set_byte( i, x ^ y );
|
set_byte( i, x ^ y );
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
if ( i > h_restart_size )
|
if ( i > h_restart_size )
|
||||||
{
|
{
|
||||||
output_line( "warning: CMem chunk too long!" );
|
output_line( "warning: CMem chunk too long!" );
|
||||||
for ( ; currlen > 1; --currlen )
|
for ( ; currlen > 1; --currlen )
|
||||||
( void ) get_c( sfp ); /* skip rest */
|
( void ) get_c( sfp ); /* skip rest */
|
||||||
break; /* keep going in case there's a UMem */
|
break; /* keep going in case there's a UMem */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* if chunk is short, assume a run */
|
/* if chunk is short, assume a run */
|
||||||
for ( ; i < h_restart_size; ++i )
|
for ( ; i < h_restart_size; ++i )
|
||||||
if ( ( y = jz_getc( gfp ) ) == EOF )
|
if ( ( y = jz_getc( gfp ) ) == EOF )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
else
|
else
|
||||||
set_byte( i, y );
|
set_byte( i, y );
|
||||||
if ( currlen == 0 )
|
if ( currlen == 0 )
|
||||||
progress |= GOT_MEMORY; /* only if succeeded */
|
progress |= GOT_MEMORY; /* only if succeeded */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Fall thru (to default) if already got memory */
|
/* Fall thru (to default) if already got memory */
|
||||||
case ID_UMem:
|
case ID_UMem:
|
||||||
if ( !( progress & GOT_MEMORY ) )
|
if ( !( progress & GOT_MEMORY ) )
|
||||||
{
|
{
|
||||||
if ( currlen == h_restart_size )
|
if ( currlen == h_restart_size )
|
||||||
{
|
{
|
||||||
if ( fread( datap, h_restart_size, 1, sfp ) == 1 )
|
if ( fread( datap, h_restart_size, 1, sfp ) == 1 )
|
||||||
{
|
{
|
||||||
progress |= GOT_MEMORY; /* only if succeeded */
|
progress |= GOT_MEMORY; /* only if succeeded */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
output_line( "warning: UMem chunk wrong size!" );
|
output_line( "warning: UMem chunk wrong size!" );
|
||||||
/* and fall thru into default */
|
/* and fall thru into default */
|
||||||
}
|
}
|
||||||
/* Fall thru (to default) if already got memory */
|
/* Fall thru (to default) if already got memory */
|
||||||
default:
|
default:
|
||||||
( void ) fseek( sfp, currlen, SEEK_CUR ); /* skip chunk */
|
( void ) fseek( sfp, (long)currlen, SEEK_CUR ); /* skip chunk */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( skip )
|
if ( skip )
|
||||||
( void ) get_c( sfp ); /* skip pad byte */
|
( void ) get_c( sfp ); /* skip pad byte */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !( progress & GOT_HEADER ) )
|
if ( !( progress & GOT_HEADER ) )
|
||||||
output_line( "error: no header chunk in file." );
|
output_line( "error: no header chunk in file." );
|
||||||
if ( !( progress & GOT_STACK ) )
|
if ( !( progress & GOT_STACK ) )
|
||||||
output_line( "error: no stack chunk in file." );
|
output_line( "error: no stack chunk in file." );
|
||||||
if ( !( progress & GOT_MEMORY ) )
|
if ( !( progress & GOT_MEMORY ) )
|
||||||
output_line( "error: no memory chunk in file." );
|
output_line( "error: no memory chunk in file." );
|
||||||
return ( progress == GOT_ALL );
|
return ( progress == GOT_ALL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
16
ztypes.h
16
ztypes.h
|
@ -34,8 +34,8 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(__ZTYPES_INCLUDED)
|
#if !defined(ZTYPES_INCLUDED)
|
||||||
#define __ZTYPES_INCLUDED
|
#define ZTYPES_INCLUDED
|
||||||
|
|
||||||
// IIgs stuff - everyone gets it
|
// IIgs stuff - everyone gets it
|
||||||
#include "joey.h"
|
#include "joey.h"
|
||||||
|
@ -74,8 +74,11 @@
|
||||||
#endif /* MSDOS */
|
#endif /* MSDOS */
|
||||||
|
|
||||||
/* Set Version of JZIP */
|
/* Set Version of JZIP */
|
||||||
|
#define JZIPVER "Jzip V2.1"
|
||||||
|
#define JZIPRELDATE "Tue, Oct 10 2000"
|
||||||
|
#define JZIPAUTHOR "John Holder (j-holder@home.com)"
|
||||||
|
#define JZIPURL "http://jzip.sourceforge.net/"
|
||||||
|
|
||||||
#include "jzip.h"
|
|
||||||
extern unsigned char JTERP;
|
extern unsigned char JTERP;
|
||||||
|
|
||||||
/* Configuration options */
|
/* Configuration options */
|
||||||
|
@ -456,6 +459,11 @@ zobjectv4_t;
|
||||||
|
|
||||||
/* External data */
|
/* External data */
|
||||||
|
|
||||||
|
extern char save_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1];
|
||||||
|
extern char script_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1];
|
||||||
|
extern char record_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1];
|
||||||
|
extern char auxilary_name[Z_FILENAME_MAX + Z_PATHNAME_MAX + 1];
|
||||||
|
|
||||||
extern int GLOBALVER;
|
extern int GLOBALVER;
|
||||||
extern zbyte_t h_type;
|
extern zbyte_t h_type;
|
||||||
extern zbyte_t h_config;
|
extern zbyte_t h_config;
|
||||||
|
@ -796,4 +804,4 @@ void z_load( zword_t );
|
||||||
void z_pull( zword_t );
|
void z_pull( zword_t );
|
||||||
void z_push( zword_t );
|
void z_push( zword_t );
|
||||||
|
|
||||||
#endif /* !defined(__ZTYPES_INCLUDED) */
|
#endif /* !defined(ZTYPES_INCLUDED) */
|
||||||
|
|
Loading…
Add table
Reference in a new issue