/*
* Quick little program to turn your Zork 0 into a Zork 0 demonstration
* Game. For those that don't know, the "Demo" version is contained in
* the game file of Zork 0. If a certain global variable was set, then
* the game would run in "demonstration" mode, where it would start with
* a preview of some graphics in the game, then switch to a limited
* area of the game for the player to explore.
*
* Does anyone know if the demonstration mode was ever used, or was it
* it just legacy code left over?
*
* I wonder if Activision would mind people distributing demo zork 0's...
*
* Sept 28: Added fix for release 383. Added line to modify checksum
*
*
[email protected]
*/
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#define WORD(ad) ((unsigned char) fcontents[ad] * 256 + \
(unsigned char) fcontents[ad+1])
#define FATAL(str) { printf str; return 1; }
int file_size(char *f) {
struct stat *statbuf;
statbuf = (struct stat *) malloc(sizeof(struct stat));
stat(f, statbuf);
return statbuf->st_size;
}
int main(int argc, char *argv[]) {
FILE *game, *dest;
char *fcontents;
int addr, release, sz, var;
if( argc != 3 )
FATAL(("Usage: %s [zork0 file] [newfile]\n", argv[0]));
if( (game = fopen(argv[1], "r")) == NULL )
FATAL(("Unable to open %s for reading\n", argv[1]));
if( (dest = fopen(argv[2], "w")) == NULL )
FATAL(("Unable to open %s\n", argv[2]));
sz = file_size(argv[1]);
fcontents = (char *) malloc(sizeof(char) * sz);
if( fread(fcontents, 1, sz, game) != sz )
FATAL(("Unable to read %d bytes of %s\n", sz, argv[2]));
switch( release = WORD(2) ) { /* Release # */
case 366:
case 383:
case 393: var = 6; break;
case 296: var = 107; break;
default: fprintf(stderr, "Unknown release number: %d\n", release);
return 1;
}
addr = WORD(12) + 2 * var;
if( addr > sz )
FATAL(("Eek! Global variable addr outside of file. Game file corrupt?\n"));
fcontents[addr] = 1; /* Set demo variable */
fcontents[0x1d]++; /* Fix the checksum */
fwrite(fcontents, sz, 1, dest);
return 0;
}