{$N+,A+,G+,F+,D-,E-,L-,R-,S-,Q-,Y-}
unit bump;

interface

procedure scene_bump;

implementation

uses global, resource, math2, screen, palette, memory;



Procedure Draw(lightx, lighty:integer; texture:word);
var offset_di, offset_si:integer;
begin
offset_di:=0; offset_si:=0;
if lightx<0 then begin offset_di:=abs(lightx); offset_si:=offset_di; end;
if lightx>319-255 then begin
offset_di:=0; offset_si:=-(lightx-(319-255)); lightx:=319-255;end;
asm
push vga
pop es
mov ax, texture
db $8e,$e0 {mov fs, ax}
mov si, lighty
mov di, lightx
add di, offset_di
sub si, offset_si
push ds
push bp
mov ds, vaddr
mov bp, di
shl bp, 1

mov ch, 99
@j:
    mov cl, 0
    @i:
        db $66; mov bx, ds:[bp]
        mov dl, bl
        add bx, cx
        db $64; mov al, [bx+si]
        db $66; shr bx, 16
        mov dh, bl
        add bx, cx
        db $64; mov ah, [bx+si-1]
        and dx, 0101h
        add ax, dx
        mov es:[di], ax

        db $66; mov bx, ds:[bp    +4]
        mov dl, bl
        add bx, cx
        db $64; mov al, [bx+si    -2]
        db $66; shr bx, 16
        mov dh, bl
        add bx, cx
        db $64; mov ah, [bx+si-1  -2]
        and dx, 0101h
        add ax, dx
        mov es:[di+2], ax

        add di, 2                 *2
        add bp, 4                 *2
        sub cl, 2                 *2
    jnz @i
    add di, 64
    add bp, 128
dec ch
jns @j {cmp ch, 0;jge @j}
pop bp
pop ds

push ds
push bp
mov di, lightx
add di, offset_di
mov ds, vaddr2
mov bp, di
shl bp, 1
add di, 320*100
mov ch, 0
@j2:
    mov cl, 0
    @i2:
        db $66; mov bx, ds:[bp]
        mov dl, bl
        add bx, cx
        db $64; mov al, [bx+si]
        db $66; shr bx, 16
        mov dh, bl
        add bx, cx
        db $64; mov ah, [bx+si-1]
        and dx, 0101h
        add ax, dx
        mov es:[di], ax

        db $66; mov bx, ds:[bp    +4]
        mov dl, bl
        add bx, cx
        db $64; mov al, [bx+si    -2]
        db $66; shr bx, 16
        mov dh, bl
        add bx, cx
        db $64; mov ah, [bx+si-1  -2]
        and dx, 0101h
        add ax, dx
        mov es:[di+2], ax

        add di, 2                 *2
        add bp, 4                 *2
        sub cl, 2                 *2
    jnz @i2
    add di, 64
    add bp, 128
dec ch
cmp ch, 157
jae @j2
pop bp
pop ds
end;
end;




var
Aantal, T1: word;
start_time, old_time,elapsed_time:word;
speed_pal, palBuf, qsub, rand_value:word;
nameblock:string[16];
numstr:string[2];
title_data, n,m:integer;
i,j,x,y,q:word;
correct, lightx,lighty:integer;
len_, num_block, needed_block, current_offset, title_fill, title_speed, size, buf1:word;
stage, copy_or_past, red,green,blue:byte;
xc,yc:single;

procedure DrawTitle(block_length, offset, DataSeg:word);
var n,i,x:word;
begin
i:=0;
if block_length>0 then
for n:=1 to block_length div 4 do begin
     x:=memw[DataSeg:i+offset];
     if x<320*100 then memw[vaddr:x shl 1]         :=memw[DataSeg:i+2 +offset]
                  else memw[vaddr2:(x-32000) shl 1]:=memw[DataSeg:i+2 +offset];
     i:=i+4;
end;
end;

procedure ReadBlock(num, len_, write_offset, segm:word);
var n:word;
begin
  { for n:=0 to 1023 do mem[segm: write_offset+n]:=mem[LogoSeg:n + num*1024];}
  LoadBinAdvance(title_data, num*1024,len_, segm, write_offset);
end;




Procedure Scene_Bump;
begin

Clear(0, 65535, vaddr);
Clear(0, 65535, vaddr2);
Clear(0, 65535, vaddr3);


Buf1:=vaddr+4000;
PalBuf:=vaddr2+4000;

red:=10+4; green:=6+3; blue:=14+10;

LoadBinUnpack('test2_t2.bin',  {load->}vaddr,{-unpack->}vaddr3,  0);

LoadBin('bump1.bin',  vaddr,  0);
LoadBin('bump2.bin',  vaddr2,  0);

LoadBin('test2_p2.pal', seg_palitra,  ofs_palitra+palette2);


for n:=0 to 253 do setonecolor2memw(n,red,green,blue,  palette1, seg_palitra, ofs_palitra);
setonecolor2memw(255,0,0,0,  palette1, seg_palitra, ofs_palitra);
setonecolor2memw(255,0,0,0,  palette2, seg_palitra, ofs_palitra);

mem2mem(seg_palitra,ofs_palitra+palette1, PalBuf,0, 1536);

init_pal2pal(seg_palitra,ofs_palitra);
palette_process[0]:=1;
palette_process[1]:=1;
speed_pal:=2;

title_data:=index_resource('title.bin');
if (title_data<0) then ErrorLoading('Resource not found!', 0);


Midas_WaitVR;
set_border_color(255);
setpalette_from_memW(palette1,seg_palitra,ofs_palitra);
Clear(0, 64000, vga);

stage:=0;
title_fill:=0;
title_speed:=0;
needed_block:=0;
current_offset:=0;
num_block:=0;
correct:=0;

rand_value:=10;
copy_or_past:=0;
randseed:=1;


old_time:=mtimer;
start_time:=mtimer;
Aantal:=0; T1:=mTimer;
qsub:=mtimer;

repeat
q:=mtimer-start_time;
elapsed_time:=(mtimer-old_time);
old_time:=mtimer;

if elapsed_time>0 then MP^.GetInformation(@info);


{-------------------------- movement lightsource -----------------------}


xc:=-sin(q/25-2.5)*40+30;
yc:= cos(q/50)*50+128;
lightx:=round(xc + cos(q/15)*8);
lighty:=round(yc + sin(q/8)*8);

{lightx:=round(-sin(q/25)*45+35);
lighty:=round(cos(q/50)*50+128);}


{-------------------------- palette operation --------------------------}
 if (stage=0) then
 if (mtimer-qsub > rand_value) then begin {blink effect}
      qsub:=mtimer;
      rand_value:=random(3)*20+5;

      if copy_or_past=0 then {save current morphed palette}
            mem2mem(seg_palitra,ofs_palitra+palette1, PalBuf,0, 1536)
      else  {past previouse safe palette}
            mem2mem(PalBuf,0, seg_palitra,ofs_palitra+palette1, 1536);

      copy_or_past:=copy_or_past xor 1;
 end;

 if (q>320) and (stage=0) then
  begin
    inc(stage);
    for n:=0 to 254 do setonecolor2memw(n,red,green,blue,  palette2, seg_palitra, ofs_palitra);
    init_pal2pal(seg_palitra,ofs_palitra);
    palette_process[0]:=1;
    palette_process[1]:=1;
  end;

 if (q>400) and (stage=1) then
  begin
    inc(stage);
    for n:=0 to 127 do setonecolor2memw(n*2,10,8,15,  palette2, seg_palitra, ofs_palitra);
    for n:=0 to 126 do setonecolor2memw(n*2+1,20,18,23,  palette2, seg_palitra, ofs_palitra);
    init_pal2pal(seg_palitra,ofs_palitra);
    palette_process[0]:=1;
    palette_process[1]:=1;
    speed_pal:=6;
  end;

{-----------------------------------------------------------------------}


{--------------------------title draw operation-------------------------}
if (title_fill = 0) and (elapsed_time>0) then begin

title_speed:=16*elapsed_time;

needed_block:=title_speed*4;

if (needed_block+current_offset) > 1024+correct then
   begin
      correct:=1024-(current_offset-correct);
      if correct>=needed_block then correct:=0;
      if correct>0 then {переносим кусочек с конца буфера в начало}
           for n:=0 to correct-1 do mem[buf1:n]:=mem[buf1:n+current_offset];

      current_offset:=0;

      if correct<1535-1024 then {предотвращаем выход за границы сегмента}
           begin {так как для buf1 юзаются последние 1536 байт сегмента vaddr}
               if (num_block=32) then len_:=512 else len_:=1024;
               if num_block<33 then ReadBlock(num_block, len_, correct, buf1);
               inc(num_block);
               if (num_block>33) then begin title_fill:=1; {sound(300); delay(200); nosound;{} end;
           end;
   end;

DrawTitle(needed_block, current_offset, buf1); {Add title-data to bump-map}

current_offset:=current_offset+needed_block;

end;{----------------------------------------------------------------------}


if Vsync_mode=1 then Midas_WaitVR;{}

if Aantal and 1 = 0 then
   begin
      if palette_process[0]=1 then Pal2Pal_asm(palette_process[0], 0, 127, elapsed_time*speed_pal, seg_palitra,ofs_palitra)
   end
   else begin
      if palette_process[1]=1 then Pal2Pal_asm(palette_process[1], 128, 254, elapsed_time*speed_pal, seg_palitra,ofs_palitra);
   end;

Draw(lightx,lighty*256, vaddr3);{ Frame render }


Inc(Aantal);

if FPS_Mode=1 then WriteFps(100, mtimer, T1, Aantal , vga);

until (esc_test) or ((stage=2) and (info^.pos > 30) and (info^.row >= 0));
end;

end.