This README file was written by Arthur O'Dwyer on 2020-07-02. This distribution contains three zip files obtained from Mike Goetz on 2020-07-01. src.zip and munge.zip have timestamps between 1986 and 1990; adv.zip has timestamps between 1992 and 1993. The code describes itself as version "C01.1 MAR'87". Mike Goetz writes: > There are 3 zip files here. > > adv.zip is the distributed game. It should run, more or less, under DosBox. > > src.zip is the source for the game itself. It's text files, written in a > custom language for game playing. It's also the C source code for adv.exe, > which is the interpreter for the compiled game code. > > munge.zip is the C source code for the munger -- that's the compiler that > turns the source into the pseudo code that is executed by adv.exe > > Build the two C programs, munge.exe and adv.exe. Use munge.exe to compile > the source code to produce the advi.dat, advi.ptr, advt.dat, and advt.ptr > files. Those four files are the input to adv.exe. Arthur elaborates on these instructions, for modern POSIX systems: To compile munge/ on a non-Windows system you'll need to lowercase the filenames first, and remove trailing ^Z bytes (used on MS-DOS to indicate end-of-file), and rename some uses of the name `index` which is a library function these days, and eliminate use of : cd munge for f in *.C *.H; do tr -d '\032' <"$f" >"$f.tmp"; rm "$f"; mv "$f.tmp" "`echo $f | tr "[:upper:]" "[:lower:]"`"; done for f in compress.c; do sed 's/index/index2/g' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in sort.c xref.c; do sed 's/malloc.h/stdlib.h/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in munge.c; do sed 's/void main/int main/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in munge.c; do sed '/process.h/d' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done echo 'int if_break() { return 0; }' >break.c We must also patch `int` to `short` in some places (because `int` is now 32 bits on common systems, whereas Goetz's code assumes 16 bits in many places), and we must add a missing `return` statement: for f in insbuf.h txtbuf.h; do sed 's/int/short/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in keysort.c; do sed 's/int key1/short key1/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in compress.c; do sed 's/int k1/short k1/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in compress.c; do sed 's/inptr = 1;/inptr = 1; } return a; if (0) {/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done The extensionless files COMPRESS, KEYSORT, and MNG are Makefiles showing how to build the corresponding .exe files. Oddly, XREF is not a Makefile, and the "xref.exe" executable doesn't seem to be needed by the munger. gcc -w -std=c89 compress.c -o compress.exe gcc -w -std=c89 keysort.c -o keysort.exe gcc -w -std=c89 munge.c snapit.c sort.c readin.c parse.c eval.c \ find.c define.c inrnge.c buffwr.c initia.c rprime.c setup.c write.c blkdta.c \ fastrd.c puttxt.c endtxt.c encryp.c encry2.c insput.c endins.c inskey.c mash.c \ break.c -o munge.exe gcc -w -std=c89 xref.c -o xref.exe Still in the "munge" directory, run the munger on one of the top-level A-code files. Again, you'll need to remove trailing ^Z bytes first. Using XEROX5 or XEROX8 will produce slightly bowdlerized message texts (e.g. dropping the LSD reference from the Fourier passage). You must use one of XEROX5, XEROX8, NORMAL, or KAYPRO; otherwise some messages will not exist and munging will fail (again, the Fourier passage is an example). So in particular the top-level file ADV is not suitable for munging. for f in NORMAL NULLS BITS PLACE OBJECTS OBJSYN VERBS TEXT VARS LABELS MOVES DEFINE INIT REPEAT ACTION; do tr -d '\032' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done ./munge.exe < NORMAL Now go build the A-code interpreter from source, starting with the same MS-DOS and 32-bit cleanups. Again, extensionless file ADV is a Makefile. cd ../src for f in *.C *.H; do tr -d '\032' <"$f" >"$f.tmp"; rm "$f"; mv "$f.tmp" "`echo $f | tr "[:upper:]" "[:lower:]"`"; done for f in getmem.c; do sed 's/malloc.h/stdlib.h/' < "$f" > "$f.tmp"; mv "$f.tmp" "$f"; done for f in *.c; do sed '/process.h/d' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in opendb.c; do sed 's@sys.types.h@sys/types.h@' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in opendb.c; do sed 's@sys.timeb.h@sys/timeb.h@' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in check.c gkey.c keyins.c keytxt.c; do sed 's/int[^a-z]*k1/short k1/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in check.c gkey.c keyins.c keytxt.c; do sed 's/int[^a-z]*k2/short k2/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in check.h gkey.h; do sed 's/int .18./short [18]/g' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in gkey.c keyins.c keytxt.c; do sed 's/int rptr/short rptr/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in getkey.c; do sed 's/int key/short key/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in insget.c; do sed 's/int buff/short buff/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in insget.c; do sed 's/inst = decry2/inst = (short)decry2/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done for f in webstr.c; do sed 's/int symbol/short symbol/' <"$f" >"$f.tmp"; mv "$f.tmp" "$f"; done gcc -w -std=c89 -Dstricmp=strcasecmp '-Ditoa(x,buf,base)=sprintf(buf,"%d",x)' \ '-Dstrupr(s)=for (char *p=s; *p; ++p) *p = toupper(*p)' adv.c \ add.c bitval.c blkdta.c check.c clear.c commnd.c decry2.c decryp.c eval.c execute.c find.c get.c getkey.c \ getmem.c gkey.c halt.c hours.c hufget.c init.c insget.c isnear.c keyins.c keytxt.c movobj.c null.c object.c \ opendb.c parse.c place.c proces.c rdbuff.c rdtext.c readin.c ref.c rnd.c say.c setbit.c setval.c start.c \ svar.c text.c txtget.c var.c verb.c webstr.c where.c -o adv.exe Then copy the munged files into the "src" directory and run "adv.exe" to play the game. cp ../munge/advi.dat . cp ../munge/advi.ptr . cp ../munge/advt.dat . cp ../munge/advt.ptr . cp ../munge/compress.dat . ./adv.exe Here's the overall flow of data through the whole process: munge.exe reads the A-code source writes advi.key advt.tmp advtkey.tmp xref.dat execs compress.exe compress.exe reads advt.tmp advtkey.tmp writes advt.dat advt.key compress.dat ana.dat execs keysort.exe keysort.exe reads advi.key advt.key writes advi.ptr advt.ptr adv.exe reads advi.dat advi.ptr advt.dat advt.ptr compress.dat