Second Reality Code Review: Part 5 (Parts)
Each Second Reality visual effects is a full DOS executable. They are called PART and there are 23 of them in total. This design decision allowed fast prototyping, simultaneous development (since FC probably did not have source control tools) and free languages choice (ASM, C and even Pascal can be found in the source).
Part 1: Introduction
Part 2: Engine
Part 3: Demo Interrupt Server
Part 4: Dev Vs Prod
Part 5: Parts
Parts
A list of each PART/EXE can be found in the source code of the Engine:
U2.ASM.
Here is a more pleasant summary of the 23 parts (with source code location since the names can be very confusing) :
Name | Executable | Coder | Screenshot | Source |
STARTMUS.EXE | MAIN/STARTMUS.C | |||
START.EXE | WILDFIRE | START/MAIN.c | ||
Hidden part | DDSTARS.EXE | WILDFIRE | DDSTARS/STARS.ASM | |
Alkutekstit I | ALKU.EXE | WILDFIRE | ALKU/MAIN.C | |
Alkutekstit II | U2A.EXE | PSI | VISU/C/CPLAY.C | |
Alkutekstit III | PAM.EXE | TRUG/WILDFIRE | PAM/ | |
BEGLOGO.EXE | BEG/BEG.C | |||
Glenz | GLENZ.EXE | PSI | GLENZ/ | |
Dottitunneli | TUNNELI.EXE | TRUG | TUNNELI/TUN10.PAS | |
Techno | TECHNO.EXE | PSI | TECHNO/KOEA.ASM | |
Panicfake | PANICEND.EXE | PSI | PANIC | |
Vuori-Scrolli | MNTSCRL.EXE | FOREST/READ2.PAS | ||
Desert Dream Stars | DDSTARS.EXE | TRUG | ||
Lens | PSI | |||
Rotazoomer | LNS&ZOOM.EXE | PSI | LENS/ | |
Plasma | WILDFIRE | |||
Plasmacube | PLZPART.EXE | WILDFIRE | PLZPART/ | |
MiniVectorBalls | MINVBALL.EXE | PSI | DOTS/ | |
Peilipalloscroll | RAYSCRL.EXE | TRUG | WATER/DEMO.PAS | |
3D-Sinusfield | 3DSINFLD.EXE | PSI | COMAN/DOLOOP.C | |
Jellypic | JPLOGO.EXE | PSI | JPLOGO/JP.C | |
Vector Part II' | U2E.EXE | PSI | VISU/C/CPLAY.C | |
Credits/Greetings | ||||
ENDLOGO.EXE | END/END.C | |||
CRED.EXE | WILDFIRE | CREDITS/MAIN.C | ||
ENDSCRL.EXE | ENDSCRL/MAIN.C |
It seems each developer had his specialty and they could be mixed during a same sequence. It is especially visible during the first scrolling/ships/explosion sequence
(Alkutekstit). Even though it looks like a continuous effect, it is actually three executables coded
by three different persons:
Alkutekstit (Credits) sequence | ||
ALKU by WILDFIRE | U2A by PSI | PAM by TRUG/WILDFIRE |
Assets
The images assets (.LBM
) were generated using Deluxe Paint, an extremely popular bitmap editor in the 90s. The interesting thing is that they were converted to an array of byte and compiled within a PART.
As a result, loading the exe also loaded all the assets. It also made reverse-engineering harder.
An other cool set of assets are the famous CITY and the SHIP from the final 3D sequence :
Part internals
Since they are compiled to a DOS executable, PARTs can use any language:
- ASM.
- C.
- PASCAL: Brass knuckles monster (MNTSCRL.EXE), Dotted Tunnel (TUNNELI.EXE) and Raytracing sword (RAYSCRL.EXE).
- Some parts go even further and use C in order to generate ASM code: GLENZ/DOLOOP.C (The bouncing polyhderon) and the Water effect (3DSINFLD.EXE).
In terms of memory usage, I read a lot of things involving MMU on Wikipedia and other websites...but
actually each part was free to use whatever it wanted since it was unloaded entirely after usage.
In terms of VGA, each part uses its own set of tricks and run at different resolutions. It is neither
Mode 13h nor ModeX but rather tweaked mode 13h with custom resolution everywhere. The SCRIPT file
mentions a lot of 320x200 and 320x400.
Unfortunately, reading the source code become quite difficult at the PART level: The code
quality and comments drops sharply at this point.
Maybe it is due to urgency or the
fact that only one dev was working on a PART (so no "real" need to comment or be clear) but
the result is something completely opaque :
Not only the algorithms are difficult, the variable names are also a challenge (a
, b
, co[]
, ... )
It could have been so much more readable if the devs had given us a few pointers in the release notes. As a result I did not spend too much time reading each of them individually,
except for the 3D engine responsible for U2A.EXE and U2E.EXE.
Second Reality 3D engine
I still took a close look at the 3D engine, which was used in two places:
U2A.EXE
and U2E.EXE
.The source code is C with Assembly optimized routines (especially filling and Gouraud shading):
- CITY.C (Main).
- VISU.C (Library
visu.lib
). - AVID.ASM (Optimized video assembly (clear, copy screen, etc)).
- ADRAW.ASM (Object drawing and clipping).
- ACALC.ASM (Matrices and sin/cos fast calculations).
The architecture of those components is pretty cool: A VISU
library does all the heavy lifting like loading assests: 3DS objects, materials and streams (camera movement and ships movements).
The engine sorts objects to draw and renders with a painter algorithm. That induces a lot
of overdraw but since VGA latches allows to write 4 pixels simultaneously it is not bad at all.
Trivia : The engine carries transformations in an "old school" way: Instead of
using the common 4x4 homogeneous matrices, it uses a 3*3 rotations matrix and a translation vector.
Here is a pseudo code summary :
main(){ scenem=readfile(tmpname); // Load materials scene0=readfile(tmpname); // Load animation for(f=-1,c=1;c<d;c++){ //Load objects sprintf(tmpname,"%s.%03i",scene,e); co[c].o=vis_loadobject(tmpname); } vid_init(1); vid_setpal(cp); for(;;){ vid_switch(); _asm mov bx,1 _asm int 0fch // waitb for retrace via copper simulator interrupt call vid_clear(); // parse animation stream, update objects for(;;){} vid_cameraangle(fov); // Field of vision // Calc matrices and add to order list (only enabled objects) for(a=1;ac<conum;a++) if(co[a].on) /* start at 1 to skip camera */ calc_applyrmatrix(o->r,&cam); // Zsort via Bubble Sort for(a=0;ac<ordernum;a++) for(b=a-1;b>=0 && dis>co[order[b]].dist;b--) // Draw for(a=0;ac<ordernum;a++) vis_drawobject(o); } } return(0); }
Ports to modern systems.
EDIT: Thu, January 30, 2014:
Since the parution of this article, many developers have started to port Second Reality to modern systems. Claudio Matsuoka started sr-port a C, Linux and OpenGL ES 2.0 port
which looks rather impressive so far. Nick Kovac's did a lot of work on the plz part and ported it to C (now part of sr-port source code) and also ported it to javascript :
Next
Back to "Second Reality Introduction"