unit uhullam;

interface

procedure HULLAM_INIT;
procedure HULLAM_ACTION;
procedure HULLAM_CLOSE;

implementation

uses
  video,grafix,crt,usm;

const
  pii:real=3.141592654/180;

type
  TBbuffer=array[0..63999] of byte;
  PBbuffer=^TBbuffer;
  TWbuffer=array[0..63999] of word;
  PWbuffer=^TWbuffer;
  Tlight=array[0..65535] of byte;
  Plight=^Tlight;
  TSinTab=array[0..359] of real;
  PSinTab=^TSinTab;
  TISinTab=array[0..35] of byte;
  PISinTab=^TISinTab;

var
  bszoveg:PBbuffer;
  btav:PWbuffer;
  light:Plight;
  SinTab,CosTab:PSinTab;
  ISin:PISinTab;
  allas,lallas:integer;
  lpx,lpy:word;
  mfade,sfade:byte;

  korder,vorder,aorder,row:byte;
  TERM:boolean;

procedure newint;
begin
  inc(counter);
end;

procedure Alloc;
begin
  new(bszoveg);
  new(btav);
  new(SinTab);
  new(CosTab);
  new(ISin);
  new(light);
end;

procedure DeAlloc;
begin
  dispose(bszoveg);
  dispose(btav);
  dispose(SinTab);
  dispose(CosTab);
  dispose(ISin);
  dispose(light);
end;

procedure MakeTav;
var
  x,y:longint;
begin
  for x:=0 to 319 do
    for y:=0 to 199 do begin
      btav^[320*y+x]:=round(sqrt(sqr(x)+sqr(y)));
    end;
end;

procedure MakeSinTab;
var
  i:word;
begin
  for i:=0 to 359 do begin
    SinTab^[i]:=sin(i*pii);
    CosTab^[i]:=cos(i*pii);
  end;
  for i:=0 to 35 do begin
    ISin^[i]:=round(sin(i*10*pii)*32+160);
  end;
end;

procedure LoadFiles;
var
  f:file;
begin
  assign(f,'hull_map.dat');
  reset(f,1);
  blockread(f,bszoveg^,64000);
  close(f);
  assign(f,'hull_lig.dat');
  reset(f,1);
  blockread(f,light^,65536);
  close(f);
end;

procedure Render;
var
  addr:word;
  x,y:word;
  r,g,b:byte;
begin
  addr:=0;
  for y:=0 to 199 do
    for x:=0 to 319 do begin
      if (x+128>lpx) and (x<lpx+127) and (y+128>lpy) and (y<lpy+127) then begin
        asm
          xor eax,eax
          mov esi,[btav]
          mov ax,addr
          shl eax,1
          add esi,eax
          xor eax,eax
          lodsw
          add ax,allas
          add ax,36
          xor edx,edx
          mov bx,36
          div bx
          xor eax,eax
          mov al,dl
          mov esi,[isin]
          add esi,eax
          lodsb
          sub al,mfade
          jnc @ook0
          mov al,0
         @ook0:
          mov bl,al

          xor eax,eax
          mov esi,[bszoveg]
          mov ax,addr
          add esi,eax
          lodsb
          sub al,sfade
          jnc @ook2
          mov al,0
         @ook2:
          mov bh,al

          mov esi,[light]
          mov ax,128
          sub ax,lpy
          add ax,y
          shl ax,8
          add ax,128
          sub ax,lpx
          add ax,x
          add esi,eax
          lodsb

          cmp bl,bh
          jb @j0
          mul bl
          shr eax,8
          mov r,0
          mov b,al
          shr eax,1
          mov g,al
          jmp @j1
         @j0:
          mul bh
          shr eax,8
          mov r,al
          shr eax,1
          mov g,al
          shr eax,1
          mov b,al
         @j1:
      end;
      end else
      asm
        mov r,0
        mov g,0
        mov b,0
      end;
      putpixel(x,y,r,g,b);
      inc(addr);
    end;
end;

procedure HULLAM_INIT;
begin
  Alloc;
  MakeTav;
  MakeSinTab;
  LoadFiles;
end;

procedure HULLAM_ACTION;
begin
  asm
   mov al,[_order]
   mov korder,al
  end;
  vorder:=korder+4;
  mfade:=0;
  sfade:=0;
  TERM:=false;
  counter:=0;
  USS_SetTimer(@newint,timerspeed div 60);
  repeat
    allas:=359-(counter mod 360);
    lallas:=359-(counter mod 360);
    lpx:=160+round(CosTab^[lallas]*60);
    lpy:=100+round(SinTab^[lallas]*40);
    Render;
    if counter<512 then mfade:=255-counter div 2;
    if counter<256 then fadedown(255-counter);
    if (counter>=690) and (counter<722) then fadeup(16-(counter-690) div 2);
    if (counter>=860) and (counter<892) then fadeup(16-(counter-860) div 2);
    if (counter>=1030) and (counter<1062) then fadeup(32-(counter-1030));
    if (counter>=1208) and (counter<1240) then fadeup(64-(counter-1208)*2);
    if (counter>=1252) and (counter<1380) then fadeup((counter-1252)*2+40-(counter mod 10)*4);
    if (counter>=700) and (counter<764) then sfade:=round(sin((counter-700)/64*pi)*30);
    if (counter>=870) and (counter<934) then sfade:=round(sin((counter-870)/64*pi)*30);
    if (counter>=1040) and (counter<1104) then sfade:=round(sin((counter-1040)/64*pi)*60);
    if (counter>=1215) and (counter<1252) then sfade:=round(sin((counter-1215)/64*pi)*90);
    if (counter>=1252) and (counter<1380) then sfade:=round((counter-1252)/128*168);
    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;

procedure HULLAM_CLOSE;
begin
  DeAlloc;
end;

begin
end.
