unit ubump;

interface

procedure bump_init;
procedure bump_action;
procedure bump_close;

implementation

uses
  video,crt,usm;

Var Light      : Pointer;
    Normals    : Pointer;
    BackGround : Pointer;
    texture : Pointer;

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

Function Rad(Value : Real) : Real;
Begin
 Rad:=Value * (Pi / 180);
End;

Procedure InitLightSource;
var
  f:file;
Begin
  assign(f,'bump_lig.dat');
  reset(f,1);
  blockread(f,light^,65536);
  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 InitBackGround;
var
  f:file;
Begin
  assign(f,'bump_map.dat');
  reset(f,1);
  blockread(f,background^,64000);
  close(f);
  assign(f,'bump_tex.dat');
  reset(f,1);
  blockread(f,texture^,192000);
  close(f);
End;

Procedure InitNormals; Assembler;
Var LineCounter : Word;
Asm
 XOR EBX,EBX
 MOV ESI,Normals
 MOV EDI,BackGround
 MOV ECX,200
 @CycleHead:
  MOV LineCounter,CX
  MOV CX,320
  @CycleHead2:
   XOR AX,AX
   MOV AL,[EDI+EBX+1]
   MOV AH,AL
   SUB AL,[EDI+EBX]
   SUB AH,[EDI+EBX+320]
   PUSH CX
   SHR CX,1
   MOV DL,CL
   MOV CX,LineCounter
   SHR CX,1
   MOV DH,CL
   POP CX
   ADD AX,DX
   MOV [ESI+(EBX*2)],AX
   INC EBX
   DEC CX
  JNZ @CycleHead2
  MOV CX,LineCounter
  DEC CX
 JNZ @CycleHead
End;

Procedure WaitRetrace; Assembler;
Asm
 MOV DX,3DAH
 @VERT1:
  IN   AL,DX
  TEST AL,8
 JZ @VERT1
 @VERT2:
  IN   AL,DX
  TEST AL,8
 jnz @vert2
End;

Procedure Bump(XPos, YPos : Byte);
Begin
 Asm
  XOR EDX,EDX
  XOR EBX,EBX
  MOV DL,XPos
  MOV DH,YPos
  MOV ESI,Normals
  MOV EDI,[video_Screen]
  MOV ECX,64000
  @CycleHead:
   MOV BX,[ESI]
   add BX,DX
   ADD ESI,2
   PUSH ESI
   mov esi,[texture]
   mov eax,64000
   sub eax,ecx
   shl eax,2
   add esi,eax
   mov eax,[esi]
   MOV ESI,Light
   MOV BL,[ESI+EBX]
   add al,bl
   jnc @ok0
   mov al,255
   @ok0:
   add ah,bl
   jnc @ok1
   mov ah,255
   @ok1:
   ror eax,16
   add al,bl
   jnc @ok2
   mov al,255
   @ok2:
   ror eax,16
   stosd
   POP ESI
  loop @CycleHead
 End;
End;

procedure bump_init;
begin
 GetMem(Light,65535);
 GetMem(Normals,128000);
 GetMem(BackGround,64000);
 GetMem(texture,256000);
 InitLightSource;
 InitBackGround;
 InitNormals;
 convertimage(texture,64000);
end;

procedure newint;
begin
  inc(counter);
end;

procedure bump_action;
begin
  Counter:=0;
  term:=false;
  asm
   mov al,[_order]
   mov korder,al
  end;
  vorder:=korder+3;
  USS_SetTimer(@newint,timerspeed div 40);
  Repeat
    Bump(Round(Sin(Rad((Counter mod 90)*8))*40)+50,
         Round(Cos(Rad((Counter mod 90)*4))*25)+80);
    asm
     mov al,[_order]
     mov aorder,al
    end;
    if (aorder=vorder) then term:=true;
    WaitRetrace;
    video_copy;
    if TerminateDemo Then Begin USS_StopTimer(@newint); ExitDemo; End;
  Until{ (KeyPressed) or} (Term);
  while keypressed do readkey;
  USS_StopTimer(@newint);
end;

procedure bump_close;
begin
 FreeMem(Light,65535);
 FreeMem(Normals,128000);
 FreeMem(BackGround,64000);
 freeMem(texture,256000);
end;

begin
end.