forked from Logicalshift/zoom
-
Notifications
You must be signed in to change notification settings - Fork 0
License
brokaw/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 andrew@logicalshift.co.uk, and anything else to andrew@logicalshift.co.uk. 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 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
Releases
No releases published
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%