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

interface

procedure scene_hexfall;

implementation

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

const
hexoid :array[0..4*6-1] of shortint =(
-3, -5,   -3, 5,   -6, 0,
-3, -5,    3, 5,   -3, 5,
-3, -5,    3,-5,    3, 5,
 3, -5,    6, 0,    3, 5);

hexik  :array[0..3*18-1] of integer = (
-24, 0, 5,
120, 0, 4,
48,40,  8,
-24, 80,3,
264, 0, 3,
192,40, 7,
120,80, 2,
48,120, 6,
-24,160,1,
336,40, 6,
264,80, 1,
192,120,5,
120,160,8,
48,200, 4,
336,120,4,
264,160,7,
192,200,3,
336,200,2);

hexorder: array[0..17] of byte = (
1, 16, 7, 12, 17, 11, 0, 15, 4, 13, 5, 8, 3, 6, 9, 14, 10, 2
);


procedure draw_mesh(ymesh, xx,yy:integer; xr, per:single; num, mesh, where:word);
var n,t:word;
col:byte;
x,y:array[0..2] of integer;
xt,yt:integer;
ys,zs,per_,Cosxan,Sinxan:single;

begin
CosXan:=cos(Xr);
SinXan:=sin(Xr);

   for n:=0 to num-1 do begin
      for t:=0 to 2 do begin
        xt:=integer(memw[mesh:n*12  +t*4  ]);
        yt:=integer(memw[mesh:n*12  +t*4+2])+ymesh;
        zs:=-sinxan*yt;
        ys:=cosxan*yt;
        per_:=per/(zs-per);
        x[t]:=round( xt*per_ )+xx;
        y[t]:=round( ys*per_ )+yy;
        {z[t]:=round( zs*per_ );}
      end;
    col:=((n div 4) and 7) * 32+31;
    triangle_asm(x[0],y[0], x[1],y[1], x[2],y[2], col, where);
    end;
end;


procedure hexagon(xx,yy:integer; size:single; col:byte;  where:word);
var
x,y:array[0..2] of integer;
n,m:word;
begin
  for m:=0 to 3 do begin
     for n:=0 to 2 do begin
         x[n]:=round(hexoid[n*2   +m*6]   * size) +xx;
         y[n]:=round(hexoid[n*2+1 +m*6]   * size) +yy;
     end;
     Triangle_asm(x[0],y[0], x[1],y[1], x[2],y[2], col, vaddr);
  end;
end;


var
 Aantal, T1,start_time, old_time,elapsed_time:word;

 q,qsub, num_triangles, num_hexagons, n,m:word;
 complete, active_p, col:byte;
 fall, speed_fall, gravy, j, b, size:single;
 h,v, xx,yy,x,y:integer;
 complete_col:array[0..17] of byte;
 jump_on:array[0..17] of integer;
 complete_jump:array[0..17] of single;
 red,green,blue:byte;

function jump1(var jump_this:integer; d, speed:single):single;
var jump:single;
begin
  jump:= sin((q-jump_this)/speed)*d;
  if jump<0 then begin jump_this:=0; jump:=0;end;
  jump1:=jump;
end;

procedure Scene_Hexfall;
begin

readonecolor_from_memW(76, red,green,blue, palette1 ,seg_palitra,ofs_palitra);
setonecolor2memW(1, red, green, blue, palette1, seg_palitra, ofs_palitra);
setonecolor2memW(0, 0, 0, 0, palette1, seg_palitra, ofs_palitra);


LoadBin('hexmesh.bin',  vaddr2,  0);
LoadBin('hexfall.pal', seg_palitra,  ofs_palitra+palette2);
init_pal2pal(seg_palitra,ofs_palitra);

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


speed_fall:=0;
fall:=0;
active_p:=0;
complete:=0;
for n:=0 to 17 do begin
   jump_on[n]:=0;
   complete_col[n]:=1;
   complete_jump[n]:=0;
end;

gravy:=0.05;
size:=8;
y:=0;
b:=1;


palette_process[0]:=1;
repeat
     MP^.GetInformation(@info);
     if palette_process[0]=1 then Pal2Pal_asm(palette_process[0], 1, 1, 8, seg_palitra,ofs_palitra);
     Midas_WaitVR;
until (esc_test) or (music_pos(45,42));

setpalette_from_memW(palette2,seg_palitra,ofs_palitra);
mem2mem(seg_palitra,ofs_palitra+palette2,  seg_palitra,ofs_palitra+palette1, 1536);


for n:=0 to 255 do setonecolor2memW(n, 63, 63, 63, palette2, seg_palitra,ofs_palitra); {1}
init_pal2pal(seg_palitra,ofs_palitra);
palette_process[0]:=0;


qsub:=mtimer;

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

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

Clear(1, 64000, vaddr);


if complete<18 then
begin

       if (elapsed_time>0) or (aantal=0) then
       begin
          MP^.GetInformation(@info);
       {-----------------------------------------------}
          if (mtimer-qsub > 4) and (active_p<18) then begin
              qsub:=mtimer;
              jump_on[hexorder[active_p]]:=q;
              inc(active_p);
          end;
       end;
       {-----------------------------------------------}

          for n:=0 to 17 do
          begin
                if (jump_on[n]>0) then
                begin
                     complete_jump[n]:= jump1(jump_on[n], 2, 5);
                     if jump_on[n]=0 then begin complete_col[n]:=30; inc(complete); end;
                     if complete_col[n]<30 then complete_col[n]:=complete_col[n]+elapsed_time;
                end;

                col:=(hexik[n*3+2]-1)*32  +complete_col[n];
                hexagon(hexik[n*3], hexik[n*3+1], 7+complete_jump[n], col, vaddr);{}

                if complete=18 then palette_process[0]:=1;
           end;

end else
     begin
          speed_fall:=speed_fall+gravy*elapsed_time;
          if fall<150 then fall:=fall+speed_fall*elapsed_time;
          draw_mesh(round(-fall), 160,200,   rad(fall), 200, 50*4, vaddr2, vaddr);{}
     end;


if Vsync_mode=1 then Midas_WaitVR;

if palette_process[0]=1 then Pal2Pal_asm(palette_process[0], 0, 255, elapsed_time*4, seg_palitra,ofs_palitra);{}

FlipScreen(vaddr,VGA);{}

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

until music_pos(45,62) or (esc_test) or ((complete=18) and (palette_process[0]=0));
end;

end.