Contents of the ZOX3D.DOC file
Zox3D version 1.5
by Robert Schmidt
(C) Copyright 1993 of Ztiff Zox Softwear
No warranty or guarantee of any kind whatsoever is provided regarding
the software, the fitness of the software for any purpose, or the
software quality or robustness. The software consists of the
executable(s), the data file(s), the source file(s), the documentation
and the graphic file(s).
Under no circumstances is the author, named above, to be held
responsible for consequential or inconsequential damage or any other
incident arising from the use or abuse of any of the components of the
software mentioned above.
Note that the source code is not made available with the standard demo
This software is put into the public domain. This does not include
the freedom to use the graphic images, which I might want to use in
later products of my own.
Zox3D is a demonstration of the idea behind the 3D graphics
engines in games like:
Castle Wolfenstein 3D from Apogee/id
Ken's Labyrinth from Epic
Catacomb Abyss from Apogee
Dracula from Psygnosis
Also, there was a lot of talk about the $25,000 XOX library and its
demo. My goal was to develop a usable 3D game library which had all
the essential features of XOX, and which would be a LOT cheaper...
Well, there are missing features from Zox3D, most notably the lack of
objects. Thus, the sources (see below) should be taken only as an aid
in understanding the principles of ray casting, as Zox3D is not a
complete library of what you would want in a 3D maze game engine.
As will be obvious, this engine will by outclassed _by far_ when
compared to the upcoming Doom from id software. Doom has gotten rid of
the square walls and flat levels. Rooms can have (almost) any shape,
walls can be at any angle around the y axis, floors and ceilings can be
at any height and are movable. This opens up for realistic scenarios
with stairs and elevators. Enough about Doom.
Currently only unchained (planar), 256-color VGA modes are supported in
Zox3D, from 256x240 to 400x300. Mode 13h and the likes are not
supported, because two or more pages are required for satisfactory
performance. On fast computers, using a temporary buffer in
conventional memory and copying this to the video buffer might be an
alternative for die-hard mode 13h'ers, but this is not supported as of
yet. 16-color (EGA) modes are definite no-nos.
I am making the sources available for a modest sum of $100. As a
private hobbyist, this gives you the right to do anything with the
source archive, except making it, or any part within, freely available.
You can use any of the modules or individual functions in your own
projects. If you're going commercial, i.e. if you want to make
money on your product, let me know, and we'll arrange something.
To compile Zox3D from scratch you will need Borland C++ 3.1 or 4.0, and
Turbo Assembler 3.1 or later.
Make a check of $100 payable to "Robert Schmidt", and send it
to the snail-mail address at the bottom. When I receive it, I
will mail you the sources, preferrably via e-mail.
Zox3D requires a VGA and about 400 Kb of free DOS memory to run. (I am
not quite sure how much.) The highest resolution requires a pretty
capable monitor. A mouse and a joystick are optional input devices,
but the keyboard works OK.
When ZOX3D.EXE is executed, a menu of available screen modes will
be offered. Simply press the number in front of the mode you want, and
you're off. 256x240 is the fastest, while 400x300 is the slowest.
400x300 might not work with your VGA monitor, due to the demanding
horizontal sync timing.
After selecting a mode, a logo will appear, and a couple of seconds
will be spent loading the graphics. This will be really slow from
diskette, so you would prefer to copy everything to a directory on
your harddisk. If the screen goes blank forever, simply press ESC to
quit the demo, and try another mode. If this doesn't help, send me
a flaming mail with a few facts about the incident.
The following controls are currently functional in the demo. Note that
several keys pressed at once are detected correctly. For example, you
can walk and turn at the same time.
Mouse & keyboard:
Up - forward
Down - backwards
Left - turn left
Right - turn right
Home - turn slow left
PgUp - turn slow right
End - move left
PgDn - move right
-/+ - move up/down
ESC - quit demo
H - toggle help text on/off
F - toggle floor texturing on/off
S - toggle sky texturing on/off
,/. - resize view window
J - recalibrate joystick
Mouse with right button pressed:
Up - move up (raise)
Down - move down (crouch)
Left - move left
Right - move right
Joystick A should work the way you expect it to. Joystick B doesn't
do anything. I use my own autocalibrating driver, with a fairly large
timeout value, so please let me know if it doesn't work.
Autocalibrating means that you calibrate the joystick in-play by moving
the joystick to all the extremas (any two opposite corners are good
enough). Note that the joystick is polled only once each frame, so you
might need to keep it still for a moment to make sure the extrema is
registered (on a slow machine).
The joystick buttons don't do anything yet. Hitting 'J' will reset the
driver entirly, so you can plug in your joystick even after Zox3D is
started, then recalibrate with 'J'.
ZOX-3D is written in C/C++, except from the fixed point macros, the
division by 0-handler, and the direct screen drawing routines. The
fixed point library was based on the one Michael Abrash introduced
during his development of XSHARP.
A word about the inline assembly routines for wall drawing ---
conditional defines are provided for enabling and disabling at wish:
Inline assembly vs. pure C++, and
Static assembly code vs. self-modifying assembly code.
Thus, it is possibly to compile, link and run a C++-only version of
Zox3D. This is of course much slower than the self-modifying assembly,
but the C++-code might prove valuable in the future, if Zox3D is to be
ported, say, to a 32-bit protected mode environment. It also
helps providing an algorithmic explanation of the inline assembly.
At the moment, speed is not the main issue. Rather, I'm working on
adding as many effects as possible (transparency, moving bitmaps,
etc.). Eventually I might find the code stable enough to optimize the
time critical code in pure assembler. I don't think it will be worth
it though. Because of the new dimension added by mirrors and
transparent walls, ZOX-3D is bound to have a lower frame rate than
Textured floors and ceilings also make things much slower, as it is
impossible to interpolate linearly through the bitmaps when drawing the
floor/ceiling column by column. If it weren't for the mirrors, the
floor/ceiling could have been drawn line by line, which is potentially
The RESOURCE.DAT file is a text file describing the bitmaps used in the
demo. The first number is the number of bitmaps, then the bitmap
descriptions follow, one on each line, in this format:
The bitmap used is cut from the file, as the rectangle with corners
(0,0) and (width-1, height-1). The type field is ignored in this
version, but will tell the resource loader wether the bitmap is
transparent, mirroring, or does some other effect. Currently, only
Deluxe Paint II Enhanced 256-color .LBM files are supported, and the
resulting uncompressed raw data must be smaller than 64 Kb. The .LBM
files supplied with Zox3D are all 320x200 and use the same palette.
The palette used in the demo is loaded from PAL.LBM.
A word about the LBM files. DeLuxe Paint II Enhanced does something
strange to the file if it is saved when a stencil is enabled. DP2E
reads it fine later, but I haven't been able to figure out why my
decoding routines stop working on such files. In short: turn of the
stencils before saving. I've had some spectacular crashes because of
As the Revision History below will tell, I have decided against further
development of Zox3D, so no new features will be added.
Once in a while the tracing process fails by tracing
straight through a corner between two walls. This might be due
to inaccuracies or a too-low resolution in the sin/cos-tables.
It happens when the ray is moving in an exact 45 degree line,
and hits the corner exactly.
When moving along a wall with a slight angle away from it, the
collision detection routine will erronously detect a wall hit,
and turn you further away from the wall while pushing you back
a little. A little annoying, but no real problem.
Gerald Dalley ([email protected]) for interesting and helpful
discussions and sharing of experiences, as we developed
separate Wolf3D-like libraries concurrently.
Nigel Brooke ([email protected]) for discussions on texture mapping of
the more general kind, and for helpful evaluation of early
Dan Vasaru for knowing a lot about lots of things, and being generally
supportive. Also greets to Per Arne, Arne-Dag, Terje, Terje,
Marius, Rolf, Jarle, Yngve, Eirik, Erik, Bjrn, ...
Christophe Meessen ([email protected]),
Torben Mogensen ([email protected]) they both gave lots of help on making
fast sqrt() functions, even though I have no use for it Zox3D.
I thought I needed it though, so thanks, guys!
John Stanley ([email protected]) for help on developing a
Lots of others from the (mostly) helpful lot in comp.lang.c++,
rec.games.programmer, and lots of other newsgroups.
The cool lot on IRC, including, but not limited too: babuu, BioHazard,
Clint, Croc, dux, eveso, Flie, Leinad, marfada9, Megafork, MSR,
NiceBruce, _NOR_, Nrrpf, Pusur, Slaughter, S-man, _TDK_, Thaco,
TheFaker, TheHard1, Tikes, XiaoPi, Zax ...
The Zox3D project was initialized.
Started this log of history.
Added assertions to 'new', so Zox3D should never hang if
available memory is too low.
Reenabled the screen resolution menu.
Resolution can be selected directly by providing ZOX3D.EXE with
the screen resolution number as a parameter.
Walls are now lines seen from above, not Wolf3D-like blocks.
Mirrors can now be covered by bitmaps, and transparent walls
Collision detection to prevent player from walking into walls.
Simple floor/ceiling (sky) texturing implemented (can be
- bitmap limited to 64x64 (floor) and 256x256 (sky)
- one direction only
- reflects correctly in mirrors
Made a moving sky with cool clouds above the maze. This
clearly demonstrates that the sky is correctly mirrored.
Simple help text implemented (can be toggled).
I grabbed, without any permissions, a couple of bitmaps from:
Castle Wolfenstein 3D by id software, Jurassic Park by Ocean,
Windows 3.1 by Microsoft. I will try to replace these with my
own as soon as possible.
Fixed a problem with a bug in the initialization code of
MS MOUSE 9.0.
Added a conditional define for enabling polling of any number
of keys at the same time - more arcade game like. Took the
opportunity to add the Key and Keyboard classes.
Added joystick support with calibration, through classes
Gamecard and Joystick.
Fixed most of the inaccuracies visible on the walls.
Made it impossible (?) to walk through a wall, even at a
corner. Let me know if you are still able to do it!
Added keys , and . to modify the size of the view window. The
window is positioned centered on the screen.
Made the help text gradually change color. I was hoping this
added to readability, but I'm not quite sure.
Added the option to compile C++-only, inline assembler, and
self-modifying assembler versions of Zox3D.
Fixed the inaccuracies in the walls, by calculating the
starting offset into the bitmap in a more accurate way. The
walls now look as close to perfect as can be.
Upon notification from Gerald Dally, some of the self-modifying
code could be made static, while being potentially even faster.
(JMP instead of code modification + CALL/RET.)
Made all-new graphics to replace the ones I had ripped from
I decided against further development of Zox3D, in favour of a
more advanced, Doom-like engine, "Zoom3D"...:) This means
that if objects are ever implemented for Zox3D, it won't be by
Added _CHAIN32.ASM to fix a bug in BC++ 4.0 which makes the RTL
version of _chain_intr() fail.
Did some final cleanups.
Added a Ztiff Zox logo which has been lying around on my HD for
of Ztiff Zox Softwear
[huh? you never heard of US??? :-)]
Snail mail address:
Stud. post 170