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

interface

procedure init_balls0;
procedure scene_balls0;

implementation

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

const
scape:array[0..9*3-1] of integer =(
16,0, 32,
46,0, 20,
80,10, 16,
96,0, 18,
136,0, 32,
180,0, 20,
210,10, 16,
245,10, 25,
290,10, 32);


procedure DrawBox(X1,Y1,X2,Y2:integer; color:Byte;where:word);
var temp, height, b:integer;
BEGIN
if x1>x2 then begin temp:=x2; x2:=x1; x1:=temp; end;
if y1>y2 then begin temp:=y2; y2:=y1; y1:=temp; end;
if x1>319 then exit;
if y1>199 then exit;
if x2<0 then exit;
if y2<0 then exit;

if x1<0 then x1:=0;
if y1<0 then y1:=0;
if x2>319 then x2:=319;
if y2>199 then y2:=199;

b:=320-(x2-x1)-1;
height:=y2-y1+1;

     ASM
        mov  es, where
        mov  ax, y1
        mov  di, ax
        xchg ah, al     {y*256}
        shl  di, 6      {y*64}
        add  di, ax

        mov  cl, color  {set eax to color}
        mov  ch, cl
        mov  ax, cx
        db $66; shl ax, 16
        mov  ax, cx

        mov  bx, x1
        mov  dx, x2
        add  di, bx     {start offset}

        inc  dx
        sub  dx, bx   {length}

        mov  bx, height
        mov  si, b

@loop:
        mov  cx, dx
        and  cx, 65532
        jz @length_less_four
        shr  cx, 2
        db $66; rep stosw

     @length_less_four:
        mov  cx, dx
        and  cx, 3
        jz @end_draw_line
        shr  cx, 1
        rep stosw
        adc cx, cx
        rep stosb

     @end_draw_line:
     add di, si
  dec bx
  jnz @loop
  END;
END;





const
max_ball_count=64;
var
Xc,Yc, R : array[0..max_ball_count-1] of integer;
Xv,Yv : array[0..max_ball_count-1] of single;
w, Y_floor_s,speed_floor:single;
y_floor:integer;
speed_pal, qsub, Aantal,T1,start_time, old_time,elapsed_time:word;
gravy, damping:single;
q, max_count, count,m,n:word;
event, col:byte;

procedure Balls_movement(m:word; elapsed_time:single);
begin
    yv[m]:=yv[m]+gravy*elapsed_time;
    xc[m]:=round(xc[m]+xv[m]*elapsed_time);
    yc[m]:=round(yc[m]+yv[m]*elapsed_time);
end;


procedure Init_balls0;
begin
   {for n:=0 to 64 do PrecalsCircle(n, vaddr3);}

   randseed:=1;
   for m:=0 to max_ball_count-1 do
   begin
        r[m]:=random(16)+8;
        xc[m]:=random(12)*20+20;
        yc[m]:=-r[m]*2 - (m and 1)*50;
        xv[m]:=random(8)-4;
        yv[m]:=0;
   end;

end;



procedure Scene_balls0;
begin
clear(0, 65535, vaddr);
clear(0, 65535, vaddr3);

if useXMS=0 then init_balls0;

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

SetOneColor2MemW(1, 10, 8, 15,  palette1, seg_palitra, ofs_palitra);
SetOneColor2MemW(7, 20, 18, 23, palette1, seg_palitra, ofs_palitra);
SetOneColor2MemW(1, 10+6, 8+6, 15+6,  palette2, seg_palitra, ofs_palitra);
SetOneColor2MemW(7, 20+8, 18+8, 23+8, palette2, seg_palitra, ofs_palitra);

Midas_WaitVR;

SetOneColor(1, 10, 8, 15);
SetOneColor(7, 20, 18, 23);

FlipScreen(vaddr2, vga);
init_pal2pal(seg_palitra,ofs_palitra);


max_count:=63;
gravy:=0.05;
damping:=0.6;
count:=1;
Y_floor_s:=300;
Y_floor:=round(y_floor_s);
speed_floor:=0;
event:=0;
speed_pal:=32;


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); {Clear framebuffer}
FlipScreen(vaddr2, vaddr);


if (mtimer-qsub > 1) and (count<max_count) then
begin
  qsub:=mtimer;
  inc(count);
end;

if y_floor_s>0 then y_floor_s:=y_floor_s-speed_floor*elapsed_time;
if speed_floor<7 then speed_floor:=speed_floor+elapsed_time/60;
y_floor:=round(y_floor_s);{}


if (elapsed_time>0) or (aantal=0) then begin

   MP^.GetInformation(@info);

   if (event=0) and (info^.pos >= 31) and (info^.row >= 0)
               then begin
                  palette_process[0]:=1;
                  inc(event);
               end;
   if (event=1) and (info^.pos >= 31) and (info^.row >= 4)
               then begin
                  SetOneColor2MemW(1, 10, 8, 15,  palette2, seg_palitra, ofs_palitra);
                  SetOneColor2MemW(7, 20, 18, 23, palette2, seg_palitra, ofs_palitra);
                  palette_process[0]:=1;
                  speed_pal:=8;
                  inc(event);
               end;


   if count>0 then
       for n:=0 to count-1 do
       begin

{         if n and 1 = 1 then gravy:=0.1 else gravy:=0.03;}
         Balls_Movement(n, elapsed_time);

         if (yc[n]>y_floor) then
            begin
            if (n and 1 = 1) then begin yv[n]:=-yv[n]*damping;  yc[n]:=y_floor; end
            else begin yv[n]:=yv[n]*0.8; end;
         end;

         if (xc[n]<0) then     begin xv[n]:=-xv[n];  xc[n]:=0;end;
         if (xc[n]>319-r[m]) then begin xv[n]:=-xv[n];  xc[n]:=319-r[m]; end;


       end;

end;


if count>0 then for m:=0 to count-1 do
        FillCircle5(xc[m],yc[m], R[m], 7, vaddr3, vaddr);{}

DrawBox(0, round(y_floor_s), 319, 200, 7,  vaddr);

for m:=0 to 8 do begin
w:=sin_(q/10+m)*10-5;
y_floor:=round(y_floor_s+w);
FillCircle5(scape[m*3],scape[m*3+1]+y_floor, scape[m*3+2], 7, vaddr3, vaddr);
end;{}




if Vsync_mode=1 then Midas_WaitVR;{}

if palette_process[0]=1 then Pal2Pal_asm(palette_process[0], 1, 7, elapsed_time*speed_pal, seg_palitra,ofs_palitra);

FlipScreen(vaddr,VGA);


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

until (esc_test) or (y_floor<=0);

repeat
   MP^.GetInformation(@info);
   Midas_WaitVR;
until (esc_test) or (info^.pos > 31);

end;

end.
