[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]

    {
    From: SEAN PALMER
    Subj: 3d Landscape src
    ---------------------------------------------------------------------------
    Check it out! Clean-room reverse-engineering of something pretty damn
    similar to Comanche's patented Voxel-space technology... In Turbo!!

    {by Sean Palmer}
    {use I,J,K,L to look around, ESC ends}

    uses crt;

    const
     xSize=256;           {90 degrees}
     ySize=128;           {60 degrees}
     angleMask=xSize*4-1; {xSize must be power of 2 or and's won't work}
     mapSize=128;

    var
     sinTab:array[0..angleMask]of integer;  {sin(xyAngle)*$7FFF}
     tanTab:array[0..ySize-1]of integer; {tan(zAngle)*$7FFF}

     map:array[0..mapSize-1,0..mapSize-1]of byte;

    type
     fixed=record case boolean of
      false:(l:longint);
      true:(f:word;i:integer);
      end;

    procedure drawScene(x,y,z,rot:integer);
    var lastTan,lastAngle,h:integer;
        mapTan:longint;
    var scrn:word;
    var color,height:byte;
    var xs,ys,ds:longint;
    var xp,yp,dp:fixed;
    begin
     fillchar(mem[$A000:0],320*200,0);
     for h:=0 to xSize-1 do begin
      lastAngle:=0;
      scrn:=h+320*(ySize-1);
      lastTan:=tanTab[lastAngle];
      xp.i:=x; xp.f:=0;
      yp.i:=y; yp.f:=0;
      dp.l:=0;
      xs:=longint(sinTab[(h+rot-(xSize shr 1))and angleMask])*2;
      ys:=longint(sinTab[(h+rot-(xSize shr 1)+xSize)and angleMask])*2; {cos}
      ds:=$FFFE;
      inc(xp.l,xs*16);
      inc(yp.l,ys*16);
      inc(dp.l,ds*16);
      while lastAngle<ySize do begin
       inc(xp.l,xs*2);
       inc(yp.l,ys*2);
       inc(dp.l,ds*2);
       inc(xs,xs div 32);
       inc(ys,ys div 32);
       inc(ds,ds shr 5);
       if word(xp.i)>mapSize-1 then
        break;
       if word(yp.i)>mapSize-1 then
        break;
       height:=map[xp.i,yp.i];
       mapTan:=(longint(height-z)*$7FFF)div dp.i;
       color:=32+(z-height);
       while(lastTan<=mapTan)and(lastAngle<ySize)do begin
        mem[$A000:scrn]:=color;
        dec(scrn,320);
        inc(lastAngle);
        lastTan:=tanTab[lastAngle];
        end;
       end;
      end;
     end;

    procedure initTables; var i:integer; r:real; begin
     for i:=0 to angleMask do
      sinTab[i]:=round(sin(i*pi/512)*$7FFF);
     for i:=0 to ySize-1 do begin
      r:=(i-64)*pi/(3*ySize);
      tanTab[i]:=round(sin(r)/cos(r)*$7FFF);
      end;
     end;

    procedure initMap; var x,y:integer; begin
     for x:=0 to 127 do
      for y:=0 to 127 do
       map[x,y]:=((longint(sinTab[(y*21-12)and angleMask])+sinTab[(x*31+296)and angleMask]div 2)shr 12)+120;
     end;

    var c:char;
     x,y,z,r,a:integer;
     i:word;

    begin
     asm mov ax,$13; int $10; end;
     initTables;
     initMap;
     randomize;
     x:=50+random(29);
     y:=50+random(29);
     z:=125+random(10);
     r:=random(angleMask);
     a:=64;
     repeat
      drawScene(x,y,z,r);
      c:=upcase(readkey);
      case c of
       'I':if tanTab[ySize-1]<30000 then for i:=0 to ySize-1 do inc(tanTab[i],500);
       'K':if tanTab[0]>-30000 then for i:=0 to ySize-1 do dec(tanTab[i],500);
       'J':r:=(r-32)and angleMask;
       'L':r:=(r+32)and angleMask;
       end;
      until c=^[;
     textMode(lastMode);
     end.

[Back to GRAPHICS SWAG index] [Back to Main SWAG index] [Original]