                        zzzzz    eeee    aaaa   l
                             z  e    e  a    a  l
                           zz   eeeee   a    a  l
                         zz     e       a    a  l
                        z       e    e  a   aa  l
                         zzzzz   eeee    aaa a   lll

                               zeal 1.1 readme

                  jeremy condit <jcondit@eecs.harvard.edu>

--------------------------------------------------------------------------

welcome to zeal!

contents:

i.    what is zeal?
ii.   compiling zeal
iii.  using zeal
iv.   known bugs and shortcomings
v.    notes for nerds
vi.   copying zeal
vii.  acknowledgments
viii. contact info

--------------------------------------------------------------------------

i.    what is zeal?

zeal is a z-code interpreter capable of running version 1-5 and 7-8 story
files.  if you don't know what this means, have a look at graham nelson's
inform page for more info about interactive fiction, the z-machine, and
inform.  also, the if-archive at gmd.de has tons of software and
information related to interactive fiction.

http://www.gnelson.demon.co.uk/inform/
ftp://ftp.gmd.de/if-archive/

zeal is written from scratch in c++ and uses the glk interactive fiction
i/o api and a pseudo-random number generator called mersenne twister (see
acknowledgments below).  it relies on very few machine or system
dependent features, and those that it does rely on it attempts to abstract
away.  some parts of the z-machine specification are as yet unimplemented,
but those parts are infrequently used by games; in fact, every game i've
tried to play with zeal works just fine or doesn't work for a "good" (i.e.
known) reason.

if i was selling zeal, i'd put these bullets on the box:
  o  runs version 1-5 and 7-8 story files
  o  supports quetzal saved-game format
  o  supports standard strictz levels
  o  uses the glk api
  o  uses a slick random number generator
  o  portable

to be perfectly honest, though, zeal's feature set is basically a subset
of the features offered by some of the other interpreters available (most
notably nitfol).  why bother, then?  zeal actually started as a random
coding challenge and ultimately became a usable program, so i figured i'd
give it away to anybody who happens to be interested.

enjoy!

--------------------------------------------------------------------------

ii.   compiling zeal

if you downloaded a compiled application for a specific platform, skip to
the next section.

* unix:

zeal should work with either the xglk or glkterm libraries, which you can
obtain from the following url:

http://eblong.com/zarf/glk/

compile whichever glk library you chose.  if you're using glkterm or xglk,
put their directory and the zeal directory in the same parent directory,
and then set the GLKLIB variable in zeal's makefile to the glk library
you're using.  (if you're using something other than glkterm or xglk,
you'll need to add a few extra lines to the makefile.)

cross your fingers, and try compiling with the following:

    make depend
    make

if all goes well, you should have a zeal binary available.  if not, try
changing the compiler or the compiler flags to suit your particular
machine.  note that you may need to change the definitions of glui32 and
glsi32 in glk.h.  (you're on your own from this point forward, but if you
fix the makefile for a particular unix os, please let me know what you
did!)

i've successfully compiled zeal under digital unix, linux, and freebsd.
for freebsd, i had to use c++ instead of g++ to compile, but otherwise
things worked fine.  note that zeal does not use glk's 32-bit integers to
store pointers, so you can safely compile zeal on a 64-bit machine (e.g.
an alpha) without modifications, though you may need to remove some
warnings from glkterm and adjust the types in glk.h.

* mac & windows:

you're more or less on your own here.  code and resources for interfacing
with macglk and windowsglk are provided in mac.* and win.*; follow
directions accompanying these glk libraries to figure out how to build
zeal for your favorite os.  you'll probably need to tweak include paths
and that kind of thing, but you shouldn't need to write any new code.

* and finally:

please see the notes about copying/distribution of zeal source and
executables (below) if you intend to do so!

--------------------------------------------------------------------------

iii.  using zeal

* unix:

under unix systems running glkterm or xglk, zeal can be run from the
command line using the following syntax:

    zeal [-d] [-strictz n] [filename]
    xzeal [-d] [-strictz n] [filename]

the options are as follows:

    -d
        turns on debug mode.  a trace will be written to the file
        debug.log during execution.

    -strictz n
        set the strictz value for the game being played.  strictz
        determines the level of warnings issued by the interpreter for
        story files that use the z-machine improperly but in a non-fatal
        way.  the value of n determines the behavior on such an error as
        follows:
            0: do nothing
            1: issue a warning once for each type of error (default)
            2: issue a warning on every occurrence of every error
            3: halt on the first occurrence of an error

    filename
        the name of story file with a game to be run.

the glk library may provide additional options; run zeal with an invalid
flag (say, -h) or look at the library documentation to learn about those
options.

of course, the options above apply only to the glkterm/xglk version of
zeal.

* mac & pc:

run zeal by double-clicking the application and then select the game you'd
like to play using the dialog that pops up.

* and finally:

as with zip, you are expressly forbidden to use this program on an infocom
game data file if, in so doing, you violate the copyright notice supplied
with the original infocom game.  (thanks to the xzip man page for the
wording of this notice.)

--------------------------------------------------------------------------

iv.   known bugs and shortcomings

zeal works well with the vast majority of z-machine games out there, but
there are still a bunch of issues to be addressed:

  o  a few opcodes aren't implemented (e.g. catch, throw, unicode stuff)
  o  text style support is shaky
  o  no color
  o  no sound

--------------------------------------------------------------------------

v.    notes for nerds

if you're interested in zeal's design, here are a few quick thoughts.

the basic design principle is encapsulation of structured portions of the
z-machine's memory with c++ classes.  that is, certain data structures in
the z-machine's memory (e.g. alphabet tables, dictionaries, objects, and
properties) can be represented in the interpreter as objects of classes.
the objects themselves just store an address within the machine's memory,
but they export a higher-level interface for these objects.

the rest of the interpreter is clumped together at a very high level.
there are classes for the machine itself (memory plus variables plus
stacks) and for the i/o interface.  an abstract class is used to represent
os-dependent features, and a set of classes are used to represent the
string decoder and objects to which the decoder can send data (i.e.
different kinds of streams).

the highest levels of the interpreter are in glk_main (zeal.cc), which has
initialization and main loop code, and in machine::one_inst (machine.cc),
which has instruction fetch and decode algorithms.  each instruction is
handled by looking up a function corresponding to that instruction in a
table.  each instruction handler then passes control to one of the classes
described above, as appropriate.  i've tried to keep most of the
complexity out of the instruction handlers.

global data includes three pointers:  m (the machine itself), io (the i/o
class), and os (the os-dependent parts).  the io object could probably be
nested within the m object, but i didn't feel like doing this just yet.

what i like about zeal:
  o  instruction decoding by table lookup and function pointers
  o  mapping c++ classes onto structured parts of z-machine memory
     (eliminates lots of errors!)
  o  encapsulation of memory operations (machine), i/o operations (iface),
     and os-dependent features (osdep)
  o  cool random number generator (see acknowledgments below)
  o  my own (v)snprintf, so i don't have to rely on the system providing
     one (many systems don't)
  o  useful error-reporting system

what i don't like about zeal:
  o  the machine and iface classes aren't very well split up--there are a
     few monolithic classes that are instantiated once, stuck in a global
     variable, and referenced everywhere
  o  instruction handlers aren't a member of any class--they could probably
     be put in the machine class, but that would make the machine class
     even more bloated, which is why i'm hesitant to do it
  o  i'm still unsure of the decoding mechanism for strings of z-chars (the
     bfish class)--it is designed to produce output by calling another
     component's put_char function for each resulting character, which
     seems to work reasonably well, but i still can't convince myself that
     there's not a better way

--------------------------------------------------------------------------

vi.   copying zeal

zeal has been released under the gnu general public license.  for a copy,
look at the COPYING file that should have accompanied this distribution.

basically, the GPL says that you are free to copy, modify, and
redistribute zeal as long as you make the complete source code available
when you do so.

zeal uses a third-party random number generator library (see the
acknowledgments below) that is released under the LGPL.  see the
COPYING.LIB file for a copy of the license for this library.

if you did not receive the source code for zeal with this distribution, it
can be obtained from one of the urls listed in the contact info section
below.

IMPORTANT NOTE ABOUT ZEAL EXECUTABLES:  i'm no lawyer, but it looks like
section 6 of the LGPL prohibits distribution of binaries compiled using
commercial compilers/libraries.  so, please do not distribute executables
for any platform without first removing the LGPL'ed random number
generator or obtaining appropriate permission (or proving me wrong).

i personally have no problem with people distributing zeal executables
that have been compiled with commercial compilers and linked against their
libraries--if you'd like to do so, go right ahead, as long as you adhere
to the notice above.  however, if you make any modifications to zeal
itself, you are required to distribute the source for your modifications
as well.

--------------------------------------------------------------------------

vii.  acknowledgments

thanks to andrew plotkin for designing glk and implementing glkterm and
xglk.  glk information can be found at the following url:

http://eblong.com/zarf/glk/

more thanks to andrew for supplying the code and resources for interfacing
with the macglk library.

thanks to m. matsumoto and t. nishimura for the mersenne twister
pseudo-random number generator.  i'm using a version that generates
numbers in the range [0,1), which was coded by t. nishimura, using
suggestions by topher cooper and marc rieffel.  this library was released
under the LGPL; see random.cc for code and contact information, and see
the COPYING.LIB file for the LGPL.  the following url provides more
information about mersenne twister:

http://www.math.keio.ac.jp/~matumoto/emt.html

thanks to glkzip (by daniel schepler) for ideas about structuring the
makefile.

thanks to mike for listening to me babble about this program all the time,
and thanks to norman for getting me interested in interactive fiction
again.

--------------------------------------------------------------------------

viii. contact info

if you'd like to contact me for any reason, feel free to write to
jcondit@eecs.harvard.edu.

you can obtain the latest version of zeal from the following urls:

http://www.eecs.harvard.edu/~jcondit/zeal/
ftp://ftp.gmd.de/if-archive/
