forked from Logicalshift/zoom
-
Notifications
You must be signed in to change notification settings - Fork 0
License
465499642/zoom
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Zoom - A Z-Machine
----// 8888 \\----
by Andrew Hunter
Zoom was originally designed as an experiment into writing fast
bytecode interpreters, just over 3 years ago (first checkin into
the CVS repository was on 19/11/2000). Last time I timed it, it
could run up to around 2x faster than frotz, depending on what
code was being executed. It's changed a lot since then, as the
emphasis is now on designing a good user interface for the
interpreter. As I changed my main machine from a Linux PC to a
PowerMac about a year ago, and for another reason that will be
revealed later in the year, the recent development focus has been
on producing a Cocoa interface.
Send any bug reports to [email protected], and anything
else to [email protected]. Zoom's homepage can be
located at http://www.logicalshift.co.uk/unix/zoom/
You can get the latest version of the source code at any time
using git:
git clone http://code.logicalshift.co.uk/zoom/zoom.git
git submodule init
git submodule update
aclocal -Im4 && autoconf && autoheader && automake --add-missing
Versions
========
This is version 1.1.6 of Zoom. As the components have gained an
increasing tendency to change at different rates, I've given them
separate versions:
Zoom interpreter core: 1.1.6
X11 interface: 1.1.6
Windows interface: 0.9.99beta5
Carbon interface: 1.0.1
Cocoa interface: 2.1.6
ZoomPlugins: 1.1.6
Spotlight importer: 1.5
QuickLook plugin: 1.1.6
CocoaGlk version: 1.0.8
Glulxe version: 0.4.7
Note that Zoom's display system underwent a fairly major change
between 1.0.0 and 1.0.1 due to the addition of version 6 support. This
means that the Windows version of Zoom will not compile any longer.
The 2.0 version of the Cocoa interface refers to the version number
displayed in the About box for the Macintosh version of Zoom.
Compiling Zoom
==============
(See later for Cocoa)
To get a full-featured interpreter under X windows or Carbon,
you'll want to have at least libpng installed. For X, having an
X server with Xrender and Xft is a good idea. T1Lib is optional,
but appears to provide improved rendering quality over Xft (which
seems to have great difficulties with hinting).
With all the libraries installed, ./configure && make should be
all that's required to build Zoom for either X or Mac OS X (Carbon).
Please report any build problems to the bugs address listed
above: Zoom should work on a reasonably wide variety of systems.
You can also build the Carbon version of Zoom by opening the
Zoom.pbproj file in Project Builder. The Cocoa version of Zoom has
to be built with XCode, using the ZoomCocoa.xcode file. Building
with project builder may cause problems with yacc generating corrupt
files, producing many spurious errors (XCode does not appear to have
these problems). If this occurs, delete the relevant files from
the build/Zoom.build/DerivedSources directory.
You may want to try the --enable-new-terp option to configure:
this enables an experimental new interpreter design. This gives
gcc's optimiser a much easier time of things (improving compile
times considerably). This style of interpreter produces a slight
(almost insignificant) performance hit.
I've experienced problems with gcc 3's optimiser: specifically,
it reduces the speed of some instructions by a factor of up to
6 (0OPs, usually, for some reason - see the results of NopMark in
zmark). No idea why at all - this effect is most marked with the
new interpreter style. Note that compiling the interpreter can be
a great workout for your system; on my Mac OS X machine, it needs
nearly 1Gb of memory to compile successfully with gcc 3.3.
Earlier versions of gcc require much less memory; I have
successfully compiled under x86 linux on a machine with 32Mb
of memory and gcc 2.95; the PPC version of gcc seems to require
much more memory for optimisation than the standard version, too.
Regardless, at least 256Mb of memory is recommended for those
that wish to compile Zoom.
Compiling Zoom (Cocoa)
======================
Before compiling, you will need to have a version of the expat
library unpacked into the directory containing the Zoom source
directory. Use a symbolic link, or rename this directory 'expat'.
Currently, the Zoom binaries link against expat 1.95.8: later
versions may also work. (Zoom is statically linked against expat
as it was an optional install on versions of OS X prior to 10.3)
You will also need the babel utility and the Sparkle library in the
directory containing the Zoom source code.
Finally, you will need the dependencies in the depend directory: this
means CocoaGlk at the moment. The easiest way to get these is to use git:
in the depends directory type this:
git clone http://code.logicalshift.co.uk/zoom/cocoaglk.git CocoaGlk
If you want to use the versions that correspond to a specific release,
use git checkout with the version number. For example, git checkout
v1.1.5. Note that CocoaGlk requires you to download versions of the
git and glulxe interpreters to compile it.
Rather than use the configure/automake process for this, I have
elected to use Xcode: to compile the new version of Zoom, load the
ZoomCocoa.xcode project into Xcode and hit build. Note that Xcode
seems to have a hard time running Yacc; if the build fails with
many weird errors, you will have to manually delete the relevant
DerivedSources (hidden in build/ZoomCocoa.build/ZoomServer.build).
There also seems to be an occasional problem with precompiled headers
that will produce similar problems (errors in Carbon headers this
time), but simply restarting the build process will fix this - you
are much more likely to see problems with building the Yacc sources.
Using Zoom (X-Windows)
======================
Running Zoom is fairly simple - zoom <filename> should do the
trick, where <filename> is a Z-Code file (modern files created by
Inform tend to have a .z5 or .z8 filename, original Infocom files
tend to have a .dat or .zip filename - note that the .zip stands
for 'Z-Code Interpreter', not PKZip as you might think). Assuming
you haven't tinkered with zmachine.h, Zoom will support Z-Code
versions 3, 4, 5, 6, 7 and 8. As of version 1.0.1beta1, version
6 is fully supported, as is the Standard v1.1draft6. Unicode
support is also much improved from this release.
Zoom needs a configuration file called '.zoomrc' in your home
directory. This file tells Zoom about the colours and fonts it
should use, and also identifies game titles. It consists of many
entries of the form 'game "mygame" 12.345678 { options }', where
'mygame' is the text that appears in the title bar, and { options }
is the options for this game (in curly brackets). You can omit the
options altogether if you want the options to be the same as the
default. There is also exactly one default block, which has the
form 'default "%s (%i.%.6s)" { options }'. The default block must
define the interpreter number and revision, at least 4 fonts, and
the default set of colours:
# Standard settings - applies to all interpreters
# (Note, font 4 must always be fixed-pitch)
default "%s (%i.%.6s)"
{
interpreter 1
revision Z
font 1 "-*-helvetica-medium-r-*-*-14-*-*-*-*-*-*-*" roman
font 2 "-*-helvetica-bold-r-*-*-14-*-*-*-*-*-*-*" bold
font 3 "-*-helvetica-medium-o-*-*-14-*-*-*-*-*-*-*" italic
font 4 "-*-courier-medium-r-*-*-14-*-*-*-*-*-*-*" fixed
font 5 "-*-courier-bold-r-*-*-14-*-*-*-*-*-*-*" fixed-bold
font 6 "-*-courier-medium-o-*-*-14-*-*-*-*-*-*-*" fixed-italic
font 7 "-*-courier-bold-o-*-*-14-*-*-*-*-*-*-*" fixed-bold-italic
font 8 "-*-helvetica-bold-o-*-*-14-*-*-*-*-*-*-*" bold-italic
font 9 "font3" symbolic
colours (0,0,0), (255,0,0), (0,255,0), (255,255,0), (0,0,255),
(255,0,255), (0,255,255), (255,255,204),
# These are the colours provided by DOS interpreters
(187, 187, 187), (136, 136, 136), (68, 68, 68)
size 80, 30
gamedir "/usr/local/share/games/zcode"
savedir "/home/me/zcode/save"
}
This illustrates most of the available options. Unless you have a
particular reason for setting the interpreter number and revision,
the values given should do a reasonable job (version 6 games, and
Beyond Zork benefit from setting the interpreter number).
Fonts are defined using statements of the form:
font <num> "<name>" <style>
Where <num> specifies the font number (note that font 4 *must* be
a fixed-pitch font), and <style> is a list of style attributes
(attributes can be seperated by commas). A style attribute is one
of 'roman', 'bold', 'italic', 'fixed' or 'symbolic', or a combination
made by combining attributes with hyphens, for example 'fixed-bold'. If
you don't specify a font with a given combination of style
attributes, Zoom will use font 1 (for normal text) or font 4 (for
fixed pitch text). You can work out font names with the aid of
xfontsel. The special font name 'font3' refers to the built-in
symbolic font.
Colours are defined using a list of values of the form (R, G,
B). There should be at least 8 colours, coresponding to the
Infocom colour scheme, and there can be up to 11 (corresponding
to the colour scheme allowed by various interpreter versions):
0 = black
1 = red
2 = green
3 = yellow
4 = blue
5 = magenta
6 = cyan
7 = white
(I prefer cream to white, but that's a matter of personal preference)
8 = light grey (amiga) dark grey (DOS)
9 = medium grey (amiga)
10 = dark grey (amiga)
Colour 0 is the first specified in the list, and the rest follow
in sequence.
size <n>, <m> sets the size of the display to (n x m)
characters. These characters are the size of the fixed-pitch font
(font 4). For a version 6 game, the graphics file can be specified
using a command like
resources "/home/me/infocom/zorkzero/ZORK0/ZORK0.blb"
Presently only Blorb graphics files are supported. While I'm aware
of Blorb 1.1, I am somewhat hesitant to include JPEG support until
the current patent unpleasentness is resolved.
Zoom will load sound effects, but won't really do anything with them
at the moment.
If Zoom is run without a game specified, it will try to look in the
directory specified by 'gamedir', and list all of the games it finds
in there (games are assumed to be in files with a .z? extension) as
a menu, giving a choice as to which one to run. 'savedir' gives the
default directory for saving and restoring files.
Each game can be specified with a block like this, or the block
can be omitted. If you do specify a block for a game, the options
there override the defaults. For example:
game "Planetfall (Solid Gold edition)" 10.880531
might have no options, so it runs as the default - but,
game "Beyond Zork" 47.870915, 49.870917, 51.870923, 57.871221
{
interpreter 5
revision Z
savedir "/home/me/zcode/beyond"
}
specifies that Beyond Zork requires a different intepreter number
and should save its games into '/home/me/zcode/beyond' by default
- note that you can also specify different colour schemes and
fonts here (with fonts you can give a partial specification, so
just adding, say, 'font 1 "-weird-font" roman' would cause Zoom to
use that font instead of the default font 1, but keep the defaults
for the rest)
An example .zoomrc file can be found in the source distribution as
'zoomrc'
Xft problems
============
XRender and Xft might well provide nice anti-aliased fonts, but
unfortunately, Xft doesn't provide any 'font not found' mechanism,
instead choosing a default font. When Xft is not setup, in particular
when there is no XftConfig file, this can result in the same font
being used for anything. The troubleshooting section of the manual
describes how to create an XftConfig file. The poor man's solution
is simply to specify 'antialias no' in .zoomrc.
Zoom and Windows
================
*** THE WINDOWS DRIVER IS DEAD ***
Feel free to volunteer to resurrect it...
This version of Zoom now supports windows through the mingw32 library
(and to a lesser extent with Borland's C compiler). The windows display
library is a complete rewrite, and uses the techniques I discussed in
an raif posting to allow the window to be resized while a game is running.
These techniques are not without their penalty, however, and this version
of Zoom cannot be compiled with v6 support, and tends to redraw some
displays much slower than the X version. It also starts v3 games in the
top left of the screen instead of the bottom left, which is strictly
speaking against the standard, but saves me some fiddling.
The zoomrc has the format as described above. A windows font is described
using a string such as:
'Arial' 10 b
Which is Arial, 10pt, bold. The font name MUST be in single quotes ('). The
optional specifiers at the end can be left out entirely, or can be a
combination of:
b - bold
B - extra bold
i - italic
u - underline
f - fixed-pitch
The font specifiers in the example could then be:
font 1 "'Arial' 10" roman
font 2 "'Arial' 10 b" bold
font 3 "'Arial' 10 i" italic
font 4 "'Courier New' 10 f" fixed
font 5 "'Courier New' 10 fb" fixed-bold
font 6 "'Courier New' 10 fi" fixed-italic
font 7 "'Courier New' 10 fbi" fixed-bold-italic
font 8 "'Arial' bi" bold-italic
font 9 "font3" symbolic
(Note that the special font name 'font3' still specifies the built-in
version of font 3)
Zoom and Mac OS X
=================
This has been variously fixed and updated, along with everything else.
The Quartz renderer is to be preferred, for the higher-quality
rendering and best support for Unicode. Version 6 games (and blorb)
are supported in this port: images are *always* rendered using
Quartz.
Why it goes fast
================
Specialisation is a formal name for an optimisation strategy that
removes layers of interpretation from a program. A classic example
is the standard C printf statement:
printf("Foo %i bar %s baz\n", i, s);
The usual technique is for the runtime system to parse the string
and insert the values of i and s appropriately. A specialised
version of this statement would note that the format string is
/constant/, and never changes, so a specialised version of that
printf statement would evaluate the format string at compile time
and output simpler routines that just print 'Foo ', then i, then '
bar ', followed by s and ' baz\n'.
Zoom's particular specialisation is to note that many of the
bytecodes can only appear in limited combinations, so instead of
testing for the opcodes and then working out what the various bits
mean, Zoom simply tests for all possible values in an enormous
switch statement (or three) - this process is applied to the
opcodes themselves and their arguments. In addition, various
opcodes can be 'branch' opcodes or 'store' opcodes, etc. A custom
decoding routine is written for each and every opcode.
This would obviously take rather a long time to do by hand, but the
code is actually generated automatically by a helper program
(general purpose programs like this are known as 'partial
evaluators', but I'm not sure if the name applies to helper
programs such as the one used here). The code has to be generated
individually for different ZCode versions, and a consequence of
this is the rather large size of the Zoom executable (it's strongly
recommended you strip it to get rid of the excessively large
debugging tables :-)
Note that Zoom also makes extensive use of function inlining
(supported in C by gcc) to give an extra speed boost (actually
only an extra few %). If you compile in support for many Z-Code
versions, you may find that turning it off (by uncommenting the
'#define inline' in interp.c) will decrease the executable size
somewhat - as a side note, Zoom also depends on the compiler having
a few sensible optimisation strategies for its speed. Turning
optimisation off is probably never a good idea, as (under gcc under
x86 Linux) that increases the size of the executable and gives
quite a performance hit on those switch statements.
That's actually about it. Zoom is probably actually slower than
frotz in a few areas, I'll get round to writing a few benchmarks to
check them out and see what can be improved.
Z-Machine extensions
====================
Zoom provides a selection of extensions to the Z-Machine:
start_timer (EXT:128) (no arguments, neither branch nor store)
This makes a note of the time this instruction is used. Normally this
will be the CPU clock time returned by clock().
stop_timer (EXT:129)
This makes a note of the time this instruction is used, storing it
seperately from the time marked by start_timer.
read_timer (EXT:130) (store)
This stores the difference between the start time and end time, as
defined by using the instruction above, in the variable. This time is
in centiseconds.
print_timer (EXT:131)
This displays the difference between the start time and end time as a
decimal number of seconds, to centisecond precision.
If you want to add your own extensions for some nefarious purpose, all
opcodes are defined in src/zcode.ops, with definitions like:
OPCODE "print_unicode" EXT:0x0b ARGS:1 VERSION 5,7,8
%{
stream_printc(argblock.arg[0]);
%}
Extended ops are only available in v4+ games and the Z-Machine
specification suggests that you only use extended opcodes that are greater
than 0x80 to add new instructions.
About
No description, website, or topics provided.
Resources
License
Stars
Watchers
Forks
Packages 0
No packages published
Languages
- C 46.0%
- Objective-C 35.9%
- HTML 5.1%
- Shell 5.0%
- C++ 2.5%
- Makefile 1.6%
- Other 3.9%