August 16th, 2013

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.EXEWILDFIRE 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.EXEPSI 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 WILDFIREU2A by PSIPAM 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:

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"

 

@
<