unit ufloor;

interface

procedure FLOOR_INIT;
procedure FLOOR_ACTION;
procedure FLOOR_CLOSE;

implementation

uses
  video,usm,crt,grafix;

type
  Ttex=array[0..65535] of dword;
  Ptex=^Ttex;
  vector=record
           x,y,z:longint;
         end;
  fvector=record
           x,y,z:longint;
         end;
  tfloorrec=record
            u,v:longint;
          end;
  tfloor=array[0..1055] of tfloorrec;
  Pfloor=^tfloor;
  Tsin=array[0..81919] of longint;
  Psin=^Tsin;

var
  tex:Ptex;
  floor:Pfloor;
  sint:psin;

  cax,cay,caz:longint;
  xr,yr,zr:real;

  term:boolean;
  korder,vorder,aorder,row:byte;
  amp:longint;

procedure loadpic;
var
  pal:array[0..767] of byte;
  f:file;
  x:word;
  counter:dword;
  value : byte;
begin
  assign(f,'flor_tex.dat');
  reset(f,1);
  blockread(f,tex^,196608);
  close(f);
end;

procedure convertimage(image:pointer;size:dword);
begin
  asm
    mov esi,[image]
    mov edi,[image]
    mov eax,4
    mov ebx,size
    dec ebx
    mul ebx
    add edi,eax
    mov eax,3
    mul ebx
    add esi,eax
    mov ecx,size
   @loop0:
    mov eax,[esi]
    mov bh,ah
    ror eax,16
    mov ah,bh
    mov [edi],eax
    sub esi,3
    sub edi,4
    loop @loop0
  end;
end;

procedure alloc;
begin
  new(tex);
  new(floor);
  new(sint);
end;

procedure dealloc;
begin
{  dispose(tex);
  dispose(floor);
  dispose(sint);}
end;

procedure maketables;
var
  a:longint;
begin
  for a:=0 to 81919 do begin
    sint^[a]:=round(sin(a/65536*360*pi/180)*65536);
  end;
end;

procedure rotatecoords(var s:vector;xrot,yrot,zrot:real);
var
  x1,y1,z1:real;
begin
  with s do begin
    x1:=x*cos(yrot*pi/180)+z*sin(yrot*pi/180);
    z1:=z*cos(yrot*pi/180)-x*sin(yrot*pi/180);
    x:=round(x1);
    z:=round(z1);
    z1:=z*cos(xrot*pi/180)+y*sin(xrot*pi/180);
    y1:=y*cos(xrot*pi/180)-z*sin(xrot*pi/180);
    z:=round(z1);
    y:=round(y1);
    x1:=x*cos(zrot*pi/180)+y*sin(zrot*pi/180);
    y1:=y*cos(zrot*pi/180)-x*sin(zrot*pi/180);
    x:=round(x1);
    y:=round(y1);
  end;
end;

procedure render;
var
  camera,v0,v1,v2,v3,v4,v5:vector;
  HFOV,VFOV:longint;
  dist:longint;
  a,b,e,f,uu,vv:longint;
  color:byte;
  uu1,uu2,uu3,uu4:longint;
  vv1,vv2,vv3,vv4:longint;
  uu5,uu6,uu7,uu8,uu9:longint;
  vv5,vv6,vv7,vv8,vv9:longint;
  currentaddress:dword;
  shade:byte;

begin
  camera.x:=0+cax;
  camera.y:=0+cay;
  camera.z:=0+caz;
  v1.x:=-32768;
  v1.y:=39896;
  v1.z:=65536;
  v2.x:=32768;
  v2.y:=39896;
  v2.z:=65536;
  v3.x:=-32768;
  v3.y:=-39896;
  v3.z:=65536;
  rotatecoords(v1,xr,yr,zr);
  rotatecoords(v2,xr,yr,zr);
  rotatecoords(v3,xr,yr,zr);
  v4.x:=(v2.x-v1.x) div 40;
  v4.y:=(v2.y-v1.y) div 40;
  v4.z:=(v2.z-v1.z) div 40;
  v5.x:=(v3.x-v1.x) div 25;
  v5.y:=(v3.y-v1.y) div 25;
  v5.z:=(v3.z-v1.z) div 25;
    asm
          mov edi,floor
          mov b,0
         @loopb:
          mov eax,v5.x
          mul b
          add eax,v1.x
          mov v0.x,eax
          mov eax,v5.y
          mul b
          add eax,v1.y
          mov v0.y,eax
          mov eax,v5.z
          mul b
          add eax,v1.z
          mov v0.z,eax
          mov a,0
         @loopa:
          mov ebx,v0.y
          xor edx,edx
          mov eax,$400000
          sal eax,8
          sar ebx,8
          cmp ebx,0
          je @nodiv
          idiv ebx
         @nodiv:
          mov dist,eax
          fild dist
          fabs
          fistp dist
          mov eax,dist
          sar eax,8
          mov ebx,v0.x
          sar ebx,8
          mul ebx
          add eax,camera.x
          stosd
          mov eax,dist
          sar eax,8
          mov ebx,v0.z
          sar ebx,8
          mul ebx
          add eax,camera.z
          stosd
          mov eax,v0.x
          add eax,v4.x
          mov v0.x,eax
          mov eax,v0.y
          add eax,v4.y
          mov v0.y,eax
          mov eax,v0.z
          add eax,v4.z
          mov v0.z,eax
          inc a
          mov eax,a
          cmp eax,40
          jbe @loopa
          inc b
          mov eax,b
          cmp eax,25
          jbe @loopb

          mov edi,[video_screen]
          mov f,0                                 { loop f start }
         @loop_f:
            mov e,0                               { loop e start }
           @loop_e:
            mov esi,floor
            mov eax,41
            mul f
            add eax,e
            shl eax,3
            add esi,eax
            lodsd
            mov uu1,eax
            lodsd
            mov vv1,eax
            lodsd
            mov uu2,eax
            lodsd
            mov vv2,eax
            add esi,312
            lodsd
            mov uu3,eax
            lodsd
            mov vv3,eax
            lodsd
            mov uu4,eax
            lodsd
            mov vv4,eax
            mov eax,uu2
            sar eax,3
            mov uu5,eax
            mov eax,uu4
            sub eax,uu2
            sar eax,6
            mov uu8,eax
            mov eax,vv2
            sar eax,3
            mov vv5,eax
            mov eax,vv4
            sub eax,vv2
            sar eax,6
            mov vv8,eax
            mov eax,uu1
            sar eax,3
            mov uu6,eax
            mov eax,uu3
            sub eax,uu1
            sar eax,6
            mov uu9,eax
            mov eax,vv1
            sar eax,3
            mov vv6,eax
            mov eax,vv3
            sub eax,vv1
            sar eax,6
            mov vv9,eax

              mov b,0                            { b loop start }
             @loop_b:
              mov eax,uu5
              sub eax,uu6
              mov uu7,eax
              mov eax,vv5
              sub eax,vv6
              mov vv7,eax
              mov eax,uu6
              sal eax,3
              mov uu,eax
              mov eax,vv6
              sal eax,3
              mov vv,eax

                mov a,0                          { a loop start }
               @loop_a:
                mov esi,[tex]
                mov eax,vv
                sub eax,camera.z
                cmp eax,$80000000
                jb @noneg
                neg eax
               @noneg:
                cmp eax,$4000000
                ja @nokirak
                shr eax,18
                cmp ax,128
                jb @nemsok0
                mov al,127
               @nemsok0:
                mov shade,al
                mov eax,uu
                sub eax,camera.x
                cmp eax,$80000000
                jb @noneg1
                neg eax
               @noneg1:
                shr eax,15
                cmp ax,128
                jb @nemsok1
                mov al,127
               @nemsok1:
                add shade,al
                mov eax,vv
                sar eax,8
                mov ebx,eax
                mov eax,uu
                sar eax,16
                and eax,11111111b
                mov ah,bh
                shl eax,2
                add esi,eax
                mov eax,[esi]
                sub al,shade
                jnc @okk0
                mov al,0
               @okk0:
                sub ah,shade
                jnc @okk1
                mov ah,0
                @okk1:
                ror eax,16
                sub al,shade
                jnc @okk2
                mov al,0
               @okk2:
                ror eax,16
                jmp @masik
                @nokirak:
                xor eax,eax
               @masik:
                stosd
                mov eax,uu
                add eax,uu7
                mov uu,eax
                mov eax,vv
                add eax,vv7
                mov vv,eax
                inc a
                mov eax,a
                cmp eax,8
                jb @loop_a                       { a loop end }

              sub edi,32
              add edi,1280
              mov eax,uu5
              add eax,uu8
              mov uu5,eax
              mov eax,vv5
              add eax,vv8
              mov vv5,eax
              mov eax,uu6
              add eax,uu9
              mov uu6,eax
              mov eax,vv6
              add eax,vv9
              mov vv6,eax
              inc b
              mov eax,b
              cmp eax,8
              jb @loop_b                         { b loop end }

            sub edi,8*1280
            add edi,32
            inc e
            mov eax,e
            cmp eax,40
            jb @loop_e                           { e loop end }

          add edi,7*1280
          inc f                                  { f loop end }
          mov eax,f
          cmp eax,25
          jb @loop_f
  end;
end;

procedure floor_init;
begin
  alloc;
  maketables;
  loadpic;
  convertimage(tex,65536);
end;

procedure floor_close;
begin
  dealloc;
end;

procedure newint;
begin
  inc(counter);
  caz:=caz+amp;
  if amp<$60000 then inc(amp,$400);
  if counter>460 then zr:=zr+0.25;
  if counter>690 then begin
    xr:=xr+0.15;
    yr:=yr+1;
  end;
  if counter>1710 then begin
    xr:=xr+0.05;
    yr:=yr+0.5;
    zr:=zr+0.1;
  end;
end;

procedure Floor_action;
begin
  term:=false;
  counter:=0;
  asm
   mov al,[_order]
   mov korder,al
  end;
  vorder:=korder+4;
  cax:=0;
  cay:=0;
  caz:=0;
  xr:=0;
  yr:=0;
  zr:=0;
  amp:=$1000;
  USS_SetTimer(@newint,timerspeed div 80);
  repeat
      render;
      if counter>1580 then fadedown(counter-1580);
      video_copy;
    asm
     mov al,[_order]
     mov aorder,al
    end;
    if (aorder=vorder) then term:=true;
    if TerminateDemo Then Begin USS_StopTimer(@newint); ExitDemo; End;
  until{ (keypressed) or} (term);
  while keypressed do readkey;
  USS_StopTimer(@newint);
end;

begin
end.

