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

interface

procedure init_boxcube;
procedure scene_boxcube;

implementation
uses smalcube, global, math2, screen, palette, memory, resource, chunky;


type
  xyz = record
  x,y,z : longint;
  end;

type
  xyz_i = record
  x,y,z : integer;
  end;

type
  xyz_s = record
  x,y,z : single;
  end;

var
  Intersect:xyz;
  Reflect:xyz_i;


{const
cubic: array[0..23+3] of single =
(-1,-1,-1, -1,-1,1, -1,1,-1,-1,1,1, 1,-1,-1, 1,-1,1,1,1,-1, 1,1,1,    0,0,0);
pindexc: array[0..23] of byte =
(0,3,1,2, 0,5,4,1, 0,6,2,4, 6,3,2,7, 3,5,1,7, 4,7,6,5);
}

 var
 Aantal, T1: longint;
{ Timer                : Longint ABSOLUTE $0040:$006C;}
 cubeDc:array[0..23+3] of longint;
 q:word;




procedure W_MakePolyEdge(x1,y1,x2,y2,x3,y3,x4,y4:integer; col,numpoly, outp:word);
var
max, min, n:integer;

    procedure w_edge(ax,ay,bx,by:longint; c, numpoly, output:word);
     var
     sy:integer;
     xx,x, delta, temp:longint;
     begin

        if ((ay<0) and (by<0)) or ((ay>199) and (by>199)) then exit;
        if (ay>by) then begin temp:=ay; ay:=by; by:=temp; temp:=ax; ax:=bx; bx:=temp; end;

        if ay=by then exit;

        delta := ((BX - AX) shl 8) div (BY - AY);
        if ay<0 then begin
          ax:=(AX - sar_(delta*AY ,8));
          ay:=0;
        end;

        X:=AX shl 8;
        if BY>200 then BY:=200;
        asm
        mov es, output
        mov cx, word ptr BY

        mov di, word ptr AY
        sub cx, di; jz @exit
        mov si, di
        imul si, si, 320

        shl di, 2
        add di, c
        add di, numpoly
        add di, 1

        db $66; mov ax, word ptr X
        db $66; mov dx, word ptr delta

        @l:{for SY:=AY to BY-1 do begin}
              db $66; add ax, dx {X := X+delta;}
              db $66; mov bx, ax {xx:=sar_(x,8);}
              db $66; sar bx, 8
              jns @skip0; xor bx, bx; @skip0: {if xx<0 then xx:=0;}
              cmp bx, 321; jl @skip319; mov bx,320; @skip319: {if xx>319 then xx:=319;}
              add bx, si
              mov es:[di], bx {memw[outp:1+sy shl 2 +c + numpoly]:=xx+sy*320;}
              add di, 4
              add si, 320
        dec cx
        jnz @l{end;}
        @exit:
        end;
     end;

    procedure w_Edges(num:byte; numpoly:word);
    var
    c:byte;
    dx,x:integer;
    begin
      if num=0 then begin dx:=y1-y2; x:=x1; end;
      if num=1 then begin dx:=y2-y3; x:=x2; end;
      if num=2 then begin dx:=y3-y4; x:=x3; end;
      if num=3 then begin dx:=y4-y1; x:=x4; end;

      if x>x+dx then c:=2 else c:=0;

      if num=0 then w_Edge(x1,y1, x2,y2, c, numpoly, outp);
      if num=1 then w_Edge(x2,y2, x3,y3, c, numpoly, outp);
      if num=2 then w_Edge(x3,y3, x4,y4, c, numpoly, outp);
      if num=3 then w_Edge(x4,y4, x1,y1, c, numpoly, outp);
    end;
begin
      {clear previous data}
      max := y1; min := y1;
      if y2 > max then max := y2; if y3 > max then max := y3;
      if y4 > max then max := y4; if y2 < min then min := y2;
      if y3 < min then min := y3; if y4 < min then min := y4;
      if min<0 then min:=0; if max>199 then max:=199;

      asm
      {for n:=0 to min   do meml[outp:n shl 2 + numpoly]:=0;}
      {for n:=max to 199 do meml[outp:n shl 2 + numpoly]:=0;}
      mov es, outp
      mov di, numpoly
      mov bx, di
      db $66; xor ax, ax
      mov cx, min
      inc cx
      cld
      db $66; rep stosw
      mov di, max
      mov cx, 200
      sub cx, di
      shl di, 2
      add di, bx
      db $66; rep stosw
      end;
      {-------------------}

      mem[outp:numpoly]:=col;
      for n:=0 to 3 do w_Edges(n, numpoly);
end;

procedure Big_DrawCube(p1,p2:word; move,add_color, h_bars:byte; from, where:word);
var
temp, n, y, x1,x2, p,  frame_offset:word;
col,col2:byte;
begin

for p:=p1 to p2 do begin

   frame_offset:=p*801;
   col:=mem[from:frame_offset];
   col2:=col+add_color;
   inc(frame_offset);
   asm
    mov es, where

    mov bl, col
    mov bh, bl
    mov ax, bx
    db $66; shl ax, 16
    mov ax, bx

    mov dl, col2
    mov dh, dl
    mov bx, dx
    db $66; shl bx, 16
    mov bx, dx

    mov ch, move
    mov dl, h_bars
{----------------------self_modify------------------------}
    db $66; mov cs:[offset @col2+2], bx
    mov cs:[offset @h_bars+2], dl

    jmp @clear_prefetch; @clear_prefetch:
{---------------------------------------------------------}

    xor di, di
    mov si, frame_offset
    push ds
    mov ds, from
    push bp
    db $66; mov bp, ax {save color in BP}
    mov cl, 200
    @y:{for y:=0 to 199 do begin}
      db $66; mov di, ds:[si]
      db $66,$0f,$a4,$fa,$10 {shld edx, edi, 16 {mov dx, ds:[si+2]}
      sub dx, di
      jz @exit
      js @exit

             {poloski}
             db $66;  mov ax, bp
             @h_bars: test ch, 16
             jz @skip_bar
             @col2: db $66; mov ax, 0101h; dw $0101
             @skip_bar:

             test dx, 65520
                 jz @length_less_sixteen
                 mov  bx, dx
                 shr  bx, 4
                 @l16:
                    db $66; mov es:[di], ax
                    db $66; mov es:[di+4], ax
                    db $66; mov es:[di+8], ax
                    db $66; mov es:[di+12], ax
                    add di, 16
                    dec bx
                 jnz @l16
             @length_less_sixteen:
                 mov bx, dx
                 and bx, 15
                 shr bx, 2
                 jz @length_less_four
                 @l4:
                    db $66; mov es:[di], ax
                    add di, 4
                    dec bx
                 jnz @l4
             @length_less_four:
                 test dx, 2
                 jz @length_less_two
                    mov es:[di], ax
                    add di, 2
             @length_less_two:
                 test dx, 1
                 jz @exit
                    mov es:[di], al
             @exit:
   add si, 4
   inc ch {poloski}
   dec cl
   jnz @y
   pop bp
   pop ds
   end;
end;
end;


procedure Big_DrawCube_add(p1,p2, from, where:word);
var
temp, n, y, x1,x2, p,  frame_offset:word;
col:byte;
begin

for p:=p1 to p2 do begin

   frame_offset:=p*801;
   col:=mem[from:frame_offset];
   inc(frame_offset);
   asm
    mov es, where

    mov bl, col
    mov bh, bl
    mov ax, bx
    db $66; shl ax, 16
    mov ax, bx

    xor di, di
    mov si, frame_offset
    push ds
    mov ds, from
    mov cx, 200
    @y:{for y:=0 to 199 do begin}
      db $66; mov di, ds:[si]
      db $66,$0f,$a4,$fa,$10 {shld edx, edi, 16 {mov dx, ds:[si+2]}
      sub dx, di
      jz @exit
      js @exit
             test dx, 65520
                 jz @length_less_sixteen
                 mov  bx, dx
                 shr  bx, 4
                 @l16:
                    db $66; add es:[di], ax
                    db $66; add es:[di+4], ax
                    db $66; add es:[di+8], ax
                    db $66; add es:[di+12], ax
                    add di, 16
                    dec bx
                 jnz @l16
             @length_less_sixteen:
                 mov bx, dx
                 and bx, 15
                 shr bx, 2
                 jz @length_less_four
                 @l4:
                    db $66; add es:[di], ax
                    add di, 4
                    dec bx
                 jnz @l4
             @length_less_four:
                 test dx, 2
                 jz @length_less_two
                    add es:[di], ax
                    add di, 2
             @length_less_two:
                 test dx, 1
                 jz @exit
                    add es:[di], al
             @exit:
   add si, 4
   dec cx
   jnz @y
   pop ds
   end;
end;
end;






Var
N_plan:xyz;
N_plan_normal:xyz_s;
Distance:longint;
count_dots, ofs_step, seg_coord, seg_vect, ofs_coord, ofs_vect:word;
seg_logo1, seg_logo2, seg_random, seg_dpal1, seg_dpal2:word;



procedure DrawCube(yy:word; x_cube, y_cube:integer; color:byte; from,where:word);
var
face_size_, cube_size_fix, y_fix, frame_offset, p:word;
col:byte;
begin
x_cube:=x_cube-cube_size shr 1;
y_cube:=y_cube-cube_size shr 1;

if (y_cube>199) or (y_cube+cube_size<1) then exit;

face_size_:=face_size;

y_fix:=0;
cube_size_fix:=cube_size;
if y_cube+cube_size>199 then begin
    y_fix := (y_cube+cube_size-200);
    cube_size_fix:=cube_size-y_fix;
    y_fix := y_fix shl 1;
end;

if y_cube<0 then begin
    cube_size_fix:=cube_size+y_cube;
    y_cube:=0;
end;

if (f<yy) then yy:=history_size+(f-yy) else  yy:=f-yy;
yy:=yy*frame_size;

asm
mov es, where
mov ax, y_cube
imul ax, ax, 320
add ax, x_cube
mov cs:[offset @y_cube+1], ax {db $8e,$e8 {mov gs, ax}

mov di, yy {frame_offset:=yy;}

mov cx, 2
@p: {for p:=0 to 2 do begin}
push cx
push di

    mov al, color

    mov si, cube_size_fix
    dec si
    shl si, 1

    push ds
    push bp
    mov ds, from

    mov bl, ds:[di] {col:=mem[vaddr3:frame_offset];}
    add bl, al   {individual color-group}
    mov bh, bl
    mov ax, bx
    db $66; shl ax, 16
    mov ax, bx

    inc di {inc(frame_offset);}

    add di, y_fix
    mov cs:[offset @frame_offset+2], di {db $8E,$E7 {mov fs, di} {frame_offset}
    jmp @clear_prefetch; @clear_prefetch:

    xor bx, bx
    xor bp, bp
    {for y:=0 to cube_size-1 do begin}
    @y:
       @frame_offset: mov dx, ds:[si+1234h]
       mov bl, dl
       sub dh, dl
       jz @exit
       js @exit

           @y_cube: mov di, 1234h {db $8c,$ef {mov di, gs}{y_cube}
           add di, bp

             {DrawLineH(x1, x2, y, c, where);}
             {-------------------------------------}
             add  di, bx
             mov  cl, dh

             and  cx, 252; jz @length_less_four
                 shr  cx, 2
                 db $66; rep stosw

             @length_less_four:
             test dh, 2; jz @length_less_two
                 mov es:[di], ax
                 add di, 2
             @length_less_two:
             test dh, 1; jz @exit
                 mov es:[di], al
             @exit:
            {---------------------}
    add bp, 320
    sub si, 2
    jns @y {end;}
    pop bp
    pop ds

pop di
add di, face_size_ {frame_offset:=frame_offset + face_size;}
pop cx
dec cx
jns @p
   end;
end;



{Вычисляем нормаль плоскости по трем точкам A,B,C}
Procedure PlanNormal(A,B,C:xyz);
var
VectorAB, VectorAC: xyz;
N:xyz_s;
len:single;
begin
{N :=  VectorProduct(CreateVector(A,B),CreateVector(A,C));}
VectorAB.x := B.x-A.x;
VectorAB.y := B.y-A.y;
VectorAB.z := B.z-A.z;

VectorAC.x := C.x-A.x;
VectorAC.y := C.y-A.y;
VectorAC.z := C.z-A.z;

{//Векторное произведение}
N.x := (VectorAB.y*VectorAC.z - VectorAC.y*VectorAB.z);
N.y := (VectorAB.z*VectorAC.x - VectorAC.z*VectorAB.x);
N.z := (VectorAB.x*VectorAC.y - VectorAC.x*VectorAB.y);

{нормализуем нормаль}
len:=rsqrt_(n.x*n.x + n.y*n.y + n.z*n.z); {1/sqrt(n.x*n.x + n.y*n.y + n.z*n.z);}
n_plan_normal.x:=(n.x*len);
n_plan_normal.y:=(n.y*len);
n_plan_normal.z:=(n.z*len);

n_plan.x:=round(n_plan_normal.x*256);
n_plan.y:=round(n_plan_normal.y*256);
n_plan.z:=round(n_plan_normal.z*256);
end;


procedure CalsDistance(A:xyz);
var v:xyz;
begin
{// расстояние до плоскости по нормали}
{d :=  DotProduct(N,V);}
Distance :=shl_(N_plan.x*A.x + N_plan.y*A.y + N_plan.z*A.z, 8);
end;


const
g_scale=1024*8;
scale=50;
per=5*g_scale;

var numpoly1,numpoly2:byte;
light:array[0..5] of integer;
procedure Big_cube_edge_render(mode:byte; light_big,scaler:single; xx,yy:integer; where:word);
var p,n,v, gg_scale:word;
c:byte;
x,y,z : array[0..3] of integer;
ax,ay, bx,by, cx,cy, dx, dy:integer;
dot_norm,c_scale, pom, axv,ayv,azv,bxv,byv,bzv,nx,ny,nz:single;
begin
for n:=0 to 5 do light[n]:=255;
numpoly1:=0;
numpoly2:=0;
gg_scale:=13;
c_scale:=scale*scaler;
for n:=0 to 5 do begin
  p:=n*4;
  for v:=0 to 3 do
  begin
    x[v]:=sar_(round(  (cubeDc[pindexc[p+v]*3]    * per / (per-cubeDc[pindexc[p+v]*3+2]) )*c_scale), gg_scale );
    y[v]:=sar_(round(  (cubeDc[pindexc[p+v]*3+1]  * per / (per-cubeDc[pindexc[p+v]*3+2]) )*c_scale), gg_scale );
    z[v]:=sar_(round(  (cubeDc[pindexc[p+v]*3+2]) * c_scale), gg_scale );
  end;
  axv:=x[2]-x[0];{cx-ax;}
  ayv:=y[2]-y[0];{cy-ay;}
  azv:=z[2]-z[0];{cz-az;}
  bxv:=x[1]-x[0];{bx-ax;}
  byv:=y[1]-y[0];{by-ay;}
  bzv:=z[1]-z[0];{bz-az;}
  nx:=ayv*bzv-azv*byv;
  ny:=azv*bxv-axv*bzv;
  nz:=axv*byv-ayv*bxv;
  pom:=nz*-4+nx*axv+ny*ayv+nz*azv;
  dot_norm:=sqrt_(nx*nx+ny*ny+nz*nz)*4;

     ax:=x[0]+xx;
     ay:=y[0]+yy;
     bx:=x[1]+xx;
     by:=y[1]+yy;
     cx:=x[2]+xx;
     cy:=y[2]+yy;
     dx:=x[3]+xx;
     dy:=y[3]+yy;

     if pom>0 then
        begin
          if mode=0 then c:=round((nz*-4)/dot_norm *22);{}
          if mode=1 then c:=n+1;
          w_MakePolyEdge(dx,dy,bx,by,cx,cy,ax,ay, c,numpoly1*801, where);{}
          inc(numpoly1);
     end else
        begin
          if mode=0 then c:=32-round((nz*4)/dot_norm *32);{}
          if mode=1 then begin c:=n*6; light[n]:=25-abs(round((nz*-4)/dot_norm *light_big)); end;
          w_MakePolyEdge(ax,ay,cx,cy,bx,by,dx,dy, c,numpoly2*801, where+256);
          inc(numpoly2);
        end;
  end;
end;



procedure big_cube_rotate(xxx,yyy,zzz, xx,yy,zz, xr,yr,zr, scalec:single);
var x,y,z,X1,Y1,Z1:single;
CosX, CosY, CosZ, SinX,SinY,SinZ:single;
p:integer;
begin
CosX:=cos_(Xr);SinX:=sin_(Xr);
CosY:=cos_(Yr);SinY:=sin_(Yr);
CosZ:=cos_(Zr);SinZ:=sin_(Zr);
 for p:=0 to 7+1 do begin
  x:=cubic[p*3]   +xx;
  y:=cubic[p*3+1] +yy;
  z:=cubic[p*3+2] +zz;
  x1:=cosy*x-siny*z;
  z1:=siny*x+cosy*z;
  x:=cosz*x1+sinz*y;
  y1:=cosz*y-sinz*x1;
  z:=cosx*z1-sinx*y1;
  y:=sinx*z1+cosx*y1;
  CubeDc[p*3]:=round(x*scalec+xxx);{trunc(x*per/(z-per)*scalec);}
  CubeDc[p*3+1]:=round(y*scalec+yyy);{trunc(y*per/(z-per)*scalec);}
  CubeDc[p*3+2]:=round(z*scalec+zzz);
end;
end;


procedure dots_process(count, gravy, speed_scale:word);
begin
asm
push ds
  mov es, seg_coord
  mov di, ofs_coord
  mov bx, speed_scale
  mov dx, gravy
  mov cx, count
  mov si, ofs_vect
  mov ds, seg_vect
  @l:{for n:=0 to count-1 do}
       {dots_vect[n].y:=dots_vect[n].y + gravy;}
       add ds:[si+2], dx

       {dots_coord[n].x:=dots_coord[n].x + dots_vect[n].x * speed_scale;}
       mov ax, ds:[si]
       db $0f,$af,$c3 {imul ax, bx}
       db $66,$0f,$bf,$c0 {movsx eax, ax}
       db $66; add es:[di], ax
       {dots_coord[n].y:=dots_coord[n].y + dots_vect[n].y * speed_scale;}
       mov ax, ds:[si+2]
       db $0f,$af,$c3 {imul ax, bx}
       db $66,$0f,$bf,$c0 {movsx eax, ax}
       db $66; add es:[di+4], ax
       {dots_coord[n].z:=dots_coord[n].z + dots_vect[n].z * speed_scale;}
       mov ax, ds:[si+4]
       db $0f,$af,$c3 {imul ax, bx}
       db $66,$0f,$bf,$c0 {movsx eax, ax}
       db $66; add es:[di+8], ax

       add di, 12
       add si, 6
  loop @l
pop ds
end;
end;

procedure dots_collision(from_dots,to_dots:word; damping:single; CubeC:xyz);
var
count_dots, ofs_coord,ofs_vect:word;
begin
ofs_coord:=0; ofs_vect:=0;

count_dots:=to_dots-from_dots;

ofs_coord:=ofs_coord + from_dots*12;
ofs_vect:= ofs_vect  + from_dots*6;

asm
mov es, seg_coord
mov ax, seg_vect
db $8E,$E0 {mov fs, ax}
mov cx, count_dots

mov di, ofs_vect
db $66; shl di, 16
mov di, ofs_coord


{------------self-moding---------------}
db $66; mov ax, word ptr n_plan.x
db $66; mov cs:[offset @n_plan_x1+3], ax
db $66; mov cs:[offset @n_plan_x2+3], ax
db $66; mov cs:[offset @n_plan_x3+3], ax
db $66; mov ax, word ptr n_plan.y
db $66; mov cs:[offset @n_plan_y1+3], ax
db $66; mov cs:[offset @n_plan_y2+3], ax
db $66; mov cs:[offset @n_plan_y3+3], ax
db $66; mov ax, word ptr n_plan.z
db $66; mov cs:[offset @n_plan_z1+3], ax
db $66; mov cs:[offset @n_plan_z2+3], ax
db $66; mov cs:[offset @n_plan_z3+3], ax

db $66; mov ax, word ptr CubeC.x
db $66; mov cs:[offset @CubeC_x1+3], ax
db $66; mov cs:[offset @CubeC_x2+3], ax
db $66; mov ax, word ptr CubeC.y
db $66; mov cs:[offset @CubeC_y1+3], ax
db $66; mov cs:[offset @CubeC_y2+3], ax
db $66; mov ax, word ptr CubeC.z
db $66; mov cs:[offset @CubeC_z1+3], ax
db $66; mov cs:[offset @CubeC_z2+3], ax

db $66; mov ax, word ptr distance
db $66; cwd
db $66; mov cs:[offset @distance_ax+2], ax
db $66; mov cs:[offset @distance_dx+2], dx

jmp @clear_prefetch; @clear_prefetch:
{--------------------------------------}


finit
fld dword ptr damping
push bp

@l:
push cx

db $66; mov si, es:[di]   {P.x}
db $66; mov bx, es:[di+4] {P.y}
db $66; mov cx, es:[di+8] {P.z}

{корректируем координаты частицы с учем сдвига к нулевом центру координат}
@CubeC_x1: db $66; sub si, 1234h; db $56,$78; {word ptr CubeC.x}
@CubeC_y1: db $66; sub bx, 1234h; db $56,$78; {word ptr CubeC.y}
@CubeC_z1: db $66; sub cx, 1234h; db $56,$78; {word ptr CubeC.z}

{e := N_plan.x*P.x + N_plan.y*P.y + N_plan.z*P.z;}
@n_plan_x1: db $66,$69,$c6,  $00,$00,$00,$00 {imul eax, esi, (N_plan.x)}
@n_plan_y1: db $66,$69,$d3,  $00,$00,$00,$00 {imul edx, ebx, (N_plan.y)}
db $66; add ax, dx
@n_plan_z1: db $66,$69,$e9,  $00,$00,$00,$00 {imul ebp, ecx, (N_plan.z)}
db $66; add bp, ax

jns @section_test_fail {if e<0 then begin}
{d := distance div e;}
@distance_ax: db $66; mov ax, 1234h; db $56,$78; {distance}
@distance_dx: db $66; mov dx, 1234h; db $56,$78;
db $66; idiv bp

{Intersect.x := sar_( (P.x * d) , 8);}
db $66; mov dx, si {save P.x}
db $66,$0f,$af,$f0 {imul esi, eax}
db $66; sar si, 8
{if (((intersect.x < 0) and (intersect.x < P.x)) or
    ((intersect.x > 0) and (intersect.x > P.x)) ) then exit;}
jns @X_skip1 {db $66; cmp si, 0;  jnl @X_skip1;}
db $66; cmp si, dx; jl @section_test_fail
@X_skip1:
db $66; cmp si, 0;  jng @X_skip2;
db $66; cmp si, dx; jg @section_test_fail
@X_skip2:

{Intersect.y := sar_( (P.y * d) , 8);}
db $66; mov dx, bx
db $66,$0f,$af,$d8 {imul ebx, eax}
db $66; sar bx, 8
{if (((intersect.y < 0) and (intersect.y < P.y)) or
     ((intersect.y > 0) and (intersect.y > P.y))) then exit;}
jns @Y_skip1 {db $66; cmp bx, 0;  jnl @Y_skip1;}
db $66; cmp bx, dx; jl @section_test_fail;
@Y_skip1:
db $66; cmp bx, 0;  jng @Y_skip2;
db $66; cmp bx, dx; jg @section_test_fail;
@Y_skip2:

{Intersect.z := sar_( (P.z * d) , 8);}
db $66; mov dx, cx
db $66,$0f,$af,$c8 {imul ecx, eax}
db $66; sar cx, 8
{if (((intersect.z < 0) and (intersect.z < P.z)) or
      ((intersect.z > 0) and (intersect.z > P.z)) ) then exit;}
jns @Z_skip1 {db $66; cmp cx, 0;  jnl @Z_skip1;}
db $66; cmp cx, dx; jl @section_test_fail;
@Z_skip1:
db $66; cmp cx, 0;  jng @Z_skip2;
db $66; cmp cx, dx; jg @section_test_fail;
@Z_skip2:


@CubeC_x2: db $66; add si, 1234h; db $56,$78; {word ptr CubeC.x}
@CubeC_y2: db $66; add bx, 1234h; db $56,$78; {word ptr CubeC.y}
@CubeC_z2: db $66; add cx, 1234h; db $56,$78; {word ptr CubeC.z}

db $66; mov es:[di],   si
db $66; mov es:[di+4], bx
db $66; mov es:[di+8], cx

{-------------------REFLECTION--------------------------------}
    db $66; rol di, 16

    {dot:=v.x*n_plan.x + v.y*n_plan.y + v.z*n_plan.z;}
    db $64,$66,$0f,$bf,$15 {movsx edx, fs:[di]} {v.x}
    @n_plan_x2: db $66,$69,$d2,  $00,$00,$00,$00 {imul edx, n_plan.x}

    db $64,$66,$0f,$bf,$75,$02 {movsx esi, fs:[di+2]} {v.y}
    @n_plan_y2: db $66,$69,$f6,  $00,$00,$00,$00  {imul esi, n_plan_y}
    db $66; add dx, si

    db $64,$66,$0f,$bf,$75,$04 {movsx esi, fs:[di+4]} {v.z}
    @n_plan_z2: db $66,$69,$f6,  $00,$00,$00,$00  {imul esi, n_plan.z}
    db $66; add dx, si

    db $66; add dx, dx {dot:=dot+dot;}

    {Reflect.x:= v.x - sar_(dot * n_plan.x, 16);
    Reflect.y:= v.y - sar_(dot * n_plan.y, 16);
    Reflect.z:= v.z - sar_(dot * n_plan.z, 16);}

    @n_plan_x3: db $66,$69,$c2,  $00,$00,$00,$00 {imul eax, edx, n_plan.x}
    db $66; sar ax, 16
    @n_plan_y3: db $66,$69,$da,  $00,$00,$00,$00 {imul ebx, edx, n_plan.y}
    db $66; sar bx, 16
    @n_plan_z3: db $66,$69,$ca,  $00,$00,$00,$00 {imul ecx, edx, n_plan.z}
    db $66; sar cx, 16

    db $64; sub [di],   ax
    db $64; sub [di+2], bx
    db $64; sub [di+4], cx

    {dots_vect[n].x:=round(Reflect.x * damping);
    dots_vect[n].y:=round(Reflect.y * damping);
    dots_vect[n].z:=round(Reflect.z * damping);}
    db $64,$df,$05      {fild  word ptr fs:[di]}
    db $d8,$c9          {fmul  st(0), st(1)}
    db $64,$df,$45,$02  {fild  word ptr fs:[di+2]}
    db $d8,$ca          {fmul  st(0), st(2)}
    db $64,$df,$45,$04  {fild  word ptr fs:[di+4]}
    db $d8,$cb          {fmul  st(0), st(3)}
    db $64,$df,$5d,$04  {fistp word ptr fs:[di+4]}
    db $64,$df,$5d,$02  {fistp word ptr fs:[di+2]}
    db $64,$df,$1d      {fistp word ptr fs:[di]}

    db $66; rol di, 16
    db $66,$81,$c7,$0C,$00,$06,$00 {add edi, 06 00 0Ch (ofs_coord+12, ofs_vect+6)}
    pop cx
    dec cx
    jnz @l
jmp @exit

@section_test_fail:
db $66,$81,$c7,$0C,$00,$06,$00 {add edi, 06 00 0Ch (ofs_coord+12, ofs_vect+6)}

pop cx
dec cx
jnz @l

@exit:
pop bp
end;
end;


procedure dots_draw(mode:byte; count, xx,yy:integer; from, where:word);
var n:word;
col, c:byte;
p, scale_long, per_long, per_256 : longint;
step, nn, x,y,speed:integer;
begin
col:=0;
per_long:=per;
per_256:=per shl 8;
scale_long:=scale;
nn:=(count-1)*12;
for n:=count-1 downto 0 do
  begin
   asm
    mov es, seg_coord
    mov di, nn

    db $66; mov si, word ptr per_long
    db $66; sub si, es:[di+8]
    db $66; mov ax, word ptr per_256
    db $66; cwd
    db $66; idiv si
    db $66; mov bx, ax

    {x:=(dots_coord[n].x * p }
    db $66,$26,$0f,$af,$1d     {imul ebx, fs:[di]}
    {y:=(dots_coord[n].y * p }
    db $66,$26,$0f,$af,$45,$04 {imul eax, fs:[di+4]}

    db $66; mov dx, word ptr scale_long
    db $66,$0f,$af,$c2 {imul eax, edx}
    db $66,$0f,$af,$da {imul ebx, edx}
    db $66; sar ax, 13+8 {y}
    db $66; sar bx, 13+8 {x}
    mov x, bx
    mov y, ax
   end;

    if mode=1 then col:=36*(n and 3+1);

    if mem[seg_coord:ofs_step+n] = 0 then
       DrawCube(n, x+xx, y+yy, col, from, where) else
       DrawCube(n shl 2, x+xx, y+yy, col, from, where);


    nn:=nn-12;
  end;
end;

var color_morph_process:array[0..5] of byte;
procedure color_morph(face, morph, pal1, pal2:word);
var m,j,o:word;
otsechka:word;
begin
  otsechka:=0;
  m:=face*6 *3  +3;
  for j:=0 to 25 do begin
  o:=j*(180*3) + m;
  asm
  mov es, pal1
  mov dl, byte ptr morph
  mov di, otsechka
  mov si, o
  push ds
  mov ds, pal2
  mov ch, 5
  @p:  {for p:=0 to 4 do begin}
          {col:=p*(36*3) + o;}

          mov cl, 18/2
          @n: {for n:=3 to 6*3+2 do begin}{index:=n+col;}
            mov bx, ds:[si] {r2 :=mem[pal2: index];}
            mov ax, es:[si] {r1 :=mem[pal1: index];}

            {if r1 < r2 then begin r1:=r1+morph; if r1>r2 then r1:=r2; mem[pal1:index]:=r1;   end;}
            {if r1 > r2 then begin r1:=r1-morph; if r1<r2 then r1:=r2; mem[pal1:index]:=r1;   end;}
            cmp al, bl; jae @sk1; add al, dl; jc @align_1_1; cmp al, bl;jbe @sk1_1;
            @align_1_1: mov al, bl; @sk1_1:;  inc di; mov es:[si], al;
            @sk1:
            cmp al, bl; jbe @sk2; sub al, dl; jc @align_1_2; cmp al, bl;jae @sk2_1;
            @align_1_2: mov al, bl; @sk2_1:;  inc di; mov es:[si], al; @sk2:

            cmp ah, bh; jae @ssk1; add ah, dl; jc @align_2_1; cmp ah, bh;jbe @ssk1_1;
            @align_2_1: mov ah, bh; @ssk1_1:; inc di; mov es:[si+1], ah;
            @ssk1:
            cmp ah, bh; jbe @ssk2; sub ah, dl; jc @align_2_2 ;cmp ah, bh;jae @ssk2_1;
            @align_2_2: mov ah, bh; @ssk2_1:; inc di; mov es:[si+1], ah; @ssk2:

           add si, 2
           dec cl
           jnz @n {end;}

        add si, (36*3)-18
        dec ch
        jnz @p
        pop ds

        mov otsechka, di
        end;
    end;
    if otsechka=0 then color_morph_process[face]:=0;
end;



procedure set_dpal(pal1:word);
var o,mp, p36,mp3o, r,g,b, p,m,opacity,n,index,col:word;
begin
    for p:=0 to 4 do begin
        p36:=p*36;

        for m:=0 to 5 do begin
          o:=light[m];
          if o <> 255 then begin  {set palette only for visible faces}
             opacity:=o*(180*3);
             mp:=m*6+p36;
             mp3o:=mp*3 + opacity;
             asm
             mov si, mp3o
             add si, 3
             mov bl, byte ptr mp
             add bl, 1
             push ds
             mov ds, pal1
             mov cl, 6
             @n:{for n:=1 to 6 do begin}
                mov dx, 3c8h
                mov al, bl
                out dx, al
                inc dx
                {index:=n*3+mp3o;}
                db $66; mov ax, ds:[si]
                db $66; shr ax, 2
                db $66; and ax, 3f3fh; dw $3f3f;
                out dx, al {r:=mem[pal1: index];}
                mov al, ah
                out dx, al {g:=mem[pal1: index+1];}
                db $66; shr ax, 16
                out dx, al {b:=mem[pal1: index+2];}
                {setonecolor(n+mp,    r shr 2,g shr 2,b shr 2);}
             add si, 3
             inc bl
             dec cl
             jnz @n{end;}
             pop ds
             end;
          end;
        end;
    end;
end;




var
jump_on:array[0..31] of word;
col_m:array[0..31] of byte;

event:word;
glitch_jump, scale_jump, current_q:single;
colors_morph_speed:word;
cubiki_visible, h_bars, logo1_on, logo2_on, cubiki_on, final_events_start:byte;

procedure randomize_vectors;
var n:word;
begin
for n:=0 to 99 do begin
memw[seg_vect:n*6]:=random(100)-50;
memw[seg_vect:n*6+2]:=random(100)-50;
memw[seg_vect:n*6+4]:=random(100)-50;
end;
end;



procedure colors_morph_on(p0,p1,p2,p3,p4,p5:byte);
begin
color_morph_process[0]:=p0;
color_morph_process[1]:=p1;
color_morph_process[2]:=p2;
color_morph_process[3]:=p3;
color_morph_process[4]:=p4;
color_morph_process[5]:=p5;
end;


function jump1(var jump_this:word; 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 go_event(e:word;name:string; param1:integer);
begin
  if (e=event) then begin

     if      name='jump1' then begin
                         jump_on[1]:=q;
             end
     else if name='jump2' then begin
                         jump_on[2]:=q;
             end
     else if name='jump4' then begin
                         jump_on[4]:=q;
             end
     else if name='jump5' then begin
                         jump_on[5]:=q;
             end
     else if name='jump7' then begin
                         jump_on[7]:=q;
             end
     else if name='jump8' then begin
                         jump_on[8]:=q;
             end
     else if name='jump9' then begin
                         h_bars:=param1;
                         jump_on[9]:=q;
             end
     else if name='jump10' then begin
                         h_bars:=param1;
                         jump_on[10]:=q;
             end
     else if name='jump11' then begin
                         h_bars:=param1;
                         jump_on[11]:=q;
             end
     else if name='jump12' then begin
                         jump_on[12]:=q;
             end

     else if name='randomize_vectors' then begin
                         randomize_vectors;
             end
     else if name='set_glitch_table' then begin
                         if useXMS=1 then
                         LoadBufferFromXMS('glitch_table2', seg_random, 0)
                         else table_for_FlipScreen2(1, 1, seg_random);
                         cubiki_visible:=0;
             end
     else if name='logo1_on' then begin
                         logo1_on:=logo1_on xor 1;
             end
     else if name='logo2_on' then begin
                         logo1_on:=0;
                         logo_mode:=0;
                         Logo_clear[0]:=0; Logo_Fill[0]:=0;
                         Logo_clear[1]:=0; Logo_Fill[1]:=0;
                         logo2_on:=logo2_on xor 1;
             end
     else if name='logo_mode_switch' then begin
                         logo_mode:=logo_mode xor 1;
             end

     else if name='colors2' then begin
                   LoadBin('colors2.bin',  seg_dpal2, 0);
                   colors_morph_on(1,1,1,1,1,1);
                   colors_morph_speed:=5;
             end
     else if name='colors3' then begin
                   LoadBin('colors3.bin',  seg_dpal2, 0);
                   colors_morph_on(0,0,0,0,0,0);
                   colors_morph_speed:=16;
             end
     else if name='colors4' then begin
                   LoadBin('colors4.bin',  seg_dpal2, 0);
                   colors_morph_on(1,1,1,1,1,1);
                   colors_morph_speed:=8;
             end
     else if name='colors5' then begin
                   LoadBin('colors5.bin',  seg_dpal2, 0);
                   colors_morph_on(1,1,0,0,0,0);
                   colors_morph_speed:=8;
             end
     else if name='cube_fall' then begin
                   final_events_start:=1;
             end;

  inc(event);
  end;
end;



var
col_morph_event, blink_num, cheredovanie_graney, step4:byte;
active_dots, plan, p,n,m,j,h,w,q300, vect_big_cube:word;
damping, cube_scale, u:single;
vect_scale, gravy:longint;
x,y, a,b,c:xyz;
cube_amp, add_cube_position, add_cube_rotate, cube_rotate, cube_position, cube_center:xyz_s;
CubeC:xyz;
start_time, old_time:longint;
elapsed_time:word;
temp, opacity, more_red, m_comp, comp1,comp2:integer;
poloski1,poloski2,poloski1_col, add_color, col,red,green,blue, r2,g2,b2:byte;



procedure init_boxcube;
begin
 Clear(0, 65535, vaddr);
 Clear(0, 65535, vaddr2);
 Clear(0, 65535, vaddr3);

{------small_cube parameters------}
cube_size:=26;
face_size:=cube_size*2+1; {2 byte for x1,x2, +1 byte color}
frame_size:=face_size*3;  {maximum 3 faces visible}

history_size:=400;{(65536-frame_size) div frame_size;}

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

gravy:=round(0.001*g_scale/8);
damping:=0.98;

cube_scale:=1.8;
cube_center.x:=0;
cube_center.y:=0;
cube_center.z:=0;
cube_position.x:=0;
cube_position.y:=0;
cube_position.z:=0;
cube_rotate.x:=0; cube_rotate.y:=0; cube_rotate.z:=0;
add_cube_rotate.x:=0; add_cube_rotate.y:=0;add_cube_rotate.z:=0;
vect_big_cube:=0;

seg_coord:=vaddr2;
seg_vect:=vaddr2+ ((128*12+128) div 16); {+count_dots*12 + (ofs_step data)}
ofs_coord:=0;
ofs_vect:=0;

active_dots:=0;
cubiki_on:=1;
cubiki_visible:=1;
cube_amp.y:=2000;
cube_amp.x:=0;
final_events_start:=0;
count_dots:=0;

RandSeed:=0;
for m:=0 to 9 do for n:=0 to 9 do begin
meml[seg_coord:count_dots*12]:=  round(  (n/4-1.15) * g_scale);
meml[seg_coord:count_dots*12+4]:=round(  (m/4-1.10) * g_scale);
meml[seg_coord:count_dots*12+8]:=round(  (1) * g_scale);
memw[seg_vect:count_dots*6]:=random(60)-30;
memw[seg_vect:count_dots*6+2]:=random(60)-30;
memw[seg_vect:count_dots*6+4]:=random(60)-30;
inc(count_dots);
end;

{fill step-value for every dots-cube}
ofs_step:=(count_dots+1)*12;
for n:=0 to count_dots do mem[seg_coord:ofs_step +n]:=0;

{-------start init all history cubes-------}
for n:=199 to 399 do begin
  Clear_Frame(n, frame_size, vaddr3);
  Small_rotateCubic(0,0,0, -5,  cube_size div 4);
  Small_drawcubic(1, cube_size div 2, face_size, n*frame_size,vaddr3);
  end;

for n:=199 downto 0 do begin
  Clear_Frame(n, frame_size, vaddr3);
  Small_rotateCubic(n/40,n/50,n/60, -5,  cube_size div 4);
  Small_drawcubic(1, cube_size div 2, face_size, n*frame_size,vaddr3);
  end;
{------------------------------------------}

{clear masive with lighting faces of cube}
for n:=0 to 5 do light[n]:=0;


{dynamic palette precalc data seg}
seg_dpal1:=vaddr2+160+512;
seg_dpal2:=seg_dpal1+1000;


if (useXMS=1) then begin {prepare glitch-table and store to XMS}
   table_for_flipscreen2(1, 1, vaddr);
   LoadBufferToXMS('glitch_table2', 16*256, vaddr);
end;

{mode 0 color scheme}
LoadBin('colors0.bin',  seg_dpal1, 0);
{mode 1 color scheme}
LoadBin('colors1.bin',  seg_dpal2, 0);

{random table for glitch-effect}
seg_random:=seg_dpal2+1000;
Table_for_FlipScreen2(0, 1, seg_random);

{Load logo-data}
seg_logo1:=seg_random+256;
LoadBin('7dump.bin',  seg_logo1,     0);
LoadBin('7dump2.bin', seg_logo1+16,  0);

seg_logo2:=seg_logo1+81;
LoadBin('sands.bin', seg_logo2,     0);
LoadBin('sands2.bin', seg_logo2+17, 0);


for n:=0 to 31 do jump_on[n]:=0; {обнуление масива}

colors_morph_on(1,1,1,1,1,1);
colors_morph_speed:=6;

end;


procedure Collision_process(count_dots:word);
var p:word;
begin
    for plan:=0 to 5 do begin;
       p:=plan*4;

       {центр куба после поворота}
       CubeC.x := cubeDc[24];
       CubeC.y := cubeDc[25];
       CubeC.z := cubeDc[26];

       {координаты плоскости со сдвигом в к нулевому центру координат}
       A.x:=cubeDc[pindexc[p]*3]     - CubeC.x;
       A.y:=cubeDc[pindexc[p]*3+1]   - CubeC.y;
       A.z:=cubeDc[pindexc[p]*3+2]   - CubeC.z;
       B.x:=cubeDc[pindexc[p+1]*3]   - CubeC.x;
       B.y:=cubeDc[pindexc[p+1]*3+1] - CubeC.y;
       B.z:=cubeDc[pindexc[p+1]*3+2] - CubeC.z;
       C.x:=cubeDc[pindexc[p+2]*3]   - CubeC.x;
       C.y:=cubeDc[pindexc[p+2]*3+1] - CubeC.y;
       C.z:=cubeDc[pindexc[p+2]*3+2] - CubeC.z;

       PlanNormal(A,B,C);
       CalsDistance(A);

       Dots_collision(0, count_dots, damping, CubeC);

    end;
end;

procedure scene_boxcube;
begin
{-------------------------Start scene--------------------------------}

Clear(25,64000,vaddr);
for h:=0 to 9 do for w:=0 to 9 do begin {draw 100 rectangles}
     j:=round(h*15.6+23);
     p:=round(w*15.5+80);
     col:=(h*10)+w+1;
     if col=25 then col:=52;
     for n:=0 to 15 do for m:=0 to 15 do
         mem[vaddr:(n+j)*320+m+p]:=col;
end;

Midas_WaitVR;
{set_dpal(seg_dpal1);
Midas_WaitVR;
readonecolor(87, red,green,blue);}
red:=32; green:=32; blue:=42;

setonecolor(25, 0,0,10);
for col:=1 to 24 do setonecolor(col, red,green,blue);
for col:=26 to 101 do setonecolor(col, red,green,blue);

FlipScreen(vaddr, vga);

for h:=23 to 178 do for w:=80 to 235 do mem[vaddr:h*320+w]:=87;


Wait_music_pos(0, 32); if ESC_PRESSED=1 then exit;


q:=0;
for n:=0 to 31 do col_m[n]:=0;
jump_on[0]:=1;
m:=0;
h:=12;
repeat
q:=q+1;

for p:=0 to m do begin
    if (jump_on[p]>0) then j:= round(jump1(jump_on[p], h, 7));{}

    if col_m[p]>0 then setonecolor(col_m[p], red+j, green+j, blue+j);{}

    if jump_on[p]=0 then begin
                    jump_on[p]:=q; col_m[p]:=random(100)+1;
                    end;
end;

if (m<16)  then inc(m);
if (q>90) and (h>0) then dec(h,2);

MP^.GetInformation(@info);

Midas_WaitVR;
until (info^.row>59) or (info^.pos>0);

{Midas_WaitVR;}
set_dpal(seg_dpal1);
FlipScreen(vaddr, vga);
{-------------------------End start scene----------------------------------}

{colors of logo's}
setonecolor(254, 50,50,50);
setonecolor(255, 0,0,0);

{background poloski colors}
for n:=0 to 31 do setonecolor(192+n, round(n/1.3), round(n/1.2), round(n)); {poloski1}

{readkey;}

f:=0; step4:=0; u:=0; event:=0;

for n:=0 to 31 do jump_on[n]:=0;

scale_jump:=0; glitch_jump:=0; cheredovanie_graney:=0;

blink_num:=0;
col_morph_event:=0;

q300:=0;
logo1_on:=0; logo2_on:=0;
poloski1:=0; poloski2:=0; poloski1_col:=0; add_color:=0; h_bars:=16;

Aantal:=0; T1:=mtimer;
old_time:=mtimer;
start_time:=mtimer;
{------------------------------MAIN SCENE--------------------------------}
repeat
q:=mtimer-start_time;
elapsed_time:=(mtimer-old_time);
old_time:=mtimer;


{background draw}
if poloski1>0 then DrawBarBG(byte(poloski1), poloski1_col+192,poloski1_col+195, h_bars, vaddr)
else Clear(0, 64000, vaddr);


 if (elapsed_time>0) or (Aantal=0) then begin{}

    MP^.GetInformation(@info); {midas get info);


{-------------------------small cube render -------------------------}
    if elapsed_time>0 then
    for n:=1 to elapsed_time do begin
        Clear_Frame(f, frame_size, vaddr3);
        Small_rotateCubic(rad(q*2), rad(q*3), rad(q*4), -5,  cube_size div 4);
        Small_drawcubic(1, cube_size div 2, face_size, f*frame_size, vaddr3);

        if f=history_size then step4:=1;
        if step4=1 then mem[seg_coord:ofs_step+f]:=4;

        {small-cubic frame history var}
        inc(f); if f>history_size then f:=0;{}
    end;
{-------------------------------------------------------------------}


    big_cube_rotate( cube_position.x,cube_position.y,cube_position.z,
                 cube_center.x,cube_center.y,cube_center.z,
                 cube_rotate.x,cube_rotate.y,cube_rotate.z,
                 g_scale*cube_scale  +scale_jump);



    if (active_dots<count_dots) and (q>0) then active_dots:=q;
    if active_dots>count_dots then active_dots:=count_dots;

    vect_scale:=round((elapsed_time*8));
    Dots_process(active_dots, gravy*elapsed_time, vect_scale);{Movement}

    Collision_process(count_dots);{Detect collision and calls reflected vectors}


{------------------------------------------------------------------------}
{-------------------------------Events-----------------------------------}

if q>160 then begin

   if cube_scale>1 then begin
                   cube_scale:=cube_scale-elapsed_time/100;
                   if cube_scale<1 then cube_scale:=1;
                   end;


   if q>260 then cube_rotate.x:=cube_rotate.x+elapsed_time/150;

   cube_rotate.y:=cube_rotate.y+elapsed_time/50+(add_cube_rotate.y*elapsed_time);
   cube_rotate.z:=q/50;{}

   {морфинг таблицы палитры для одной грани за кадр, чтобы меньше тормозило}
   inc(cheredovanie_graney); {for n:=0 to 5 do}
   if cheredovanie_graney>5 then cheredovanie_graney:=0;
        if color_morph_process[cheredovanie_graney]=1 then
           begin
           color_morph(cheredovanie_graney, elapsed_time * colors_morph_speed, seg_dpal1, seg_dpal2);{}
           {sound(300);delay(10);nosound;{}
           end;
end;


if music_pos(0,48) then if q300=0 then q300:=q;
if q300>0 then cube_position.y:=-sin_((q-q300)/7)*cube_amp.y+add_cube_position.y;


case event of

0:  if music_pos(2,32) then go_event(0, 'jump5',0);{small glitch}
1:  if music_pos(2,37) then go_event(1, 'jump4',0);{rotate}
2:  if music_pos(3,0)  then go_event(2, 'colors2',0);{}
3:  if music_pos(3,0)  then go_event(3, 'jump1',0);{scale}
4:  if music_pos(3,0)  then go_event(4, 'jump2',0);{big glitch}
5:  if music_pos(3,0)  then go_event(5, 'randomize_vectors',0);{}
6:  if music_pos(3,0)  then go_event(6, 'jump9', 2);{poloski korotkie}
7:  if music_pos(3,32) then go_event(7, 'colors3',0);{}
8:  if music_pos(4,4)  then go_event(8, 'jump5',0);{small glitch}
9:  if music_pos(4,4)  then go_event(9, 'jump9', 64);{poloski korotkie}
10: if music_pos(4,6)  then go_event(10, 'jump1',0);{scale}
11: if music_pos(4,32) then go_event(11, 'logo1_on',0);{}
12: if music_pos(4,45) then go_event(12, 'jump10', 16);{poloski dolgie}
13: if music_pos(5,0)  then go_event(13, 'jump2',0);{big glitch}
14: if music_pos(5,16) then go_event(14, 'logo_mode_switch',0);{}
15: if music_pos(5,32) then go_event(15, 'colors4',0);{}
16: if music_pos(6,16) then go_event(16, 'logo2_on',0);{}
17: if music_pos(6,32) then go_event(17, 'jump4',0);{rotate}
18: if music_pos(6,34) then go_event(18, 'randomize_vectors',0);{}
19: if music_pos(6,32) then go_event(19, 'jump5',0);{small glitch}
20: if music_pos(6,32) then go_event(20, 'jump9', 32);{poloski korotkie}
21: if music_pos(6,49) then go_event(21, 'jump2',0);{big glitch}
22: if music_pos(7,0)  then go_event(22, 'colors5',0);{}
23: if music_pos(7,16) then go_event(23, 'logo_mode_switch',0);{}
24: if music_pos(7,48) then go_event(24, 'cube_fall',0);
25: if music_pos(7,48) then go_event(25, 'jump7',0);
26: if music_pos(7,48) then go_event(26, 'jump5',0);
27: if music_pos(8,16) then go_event(27, 'set_glitch_table',0);
28: if music_pos(8,18) then go_event(28, 'jump8',0);
29: if music_pos(8,18) then go_event(29, 'jump11', 4);{poloski korotkie}
30: if music_pos(8,58) then go_event(30, 'jump11', 64);{poloski dolgie}

end;


case col_morph_event of
{to color3}
0: if music_pos(3,48) then begin  colors_morph_on(0,0,1,0,1,0); inc(col_morph_event); end;
1: if music_pos(4,0)  then begin  colors_morph_on(0,0,1,0,1,1); inc(col_morph_event); end;
2: if music_pos(4,16) then begin  colors_morph_on(1,1,1,1,1,1); inc(col_morph_event); end;
{to color5}
3: if music_pos(7,16) then begin  colors_morph_on(1,0,1,0,1,1); inc(col_morph_event); end;
4: if music_pos(7,48) then begin  colors_morph_on(1,1,1,1,1,1); inc(col_morph_event); end;
end;

if (Final_events_start=1) then begin
   if (cubiki_on=1) then
   if (color_morph_process[0]+color_morph_process[1]+color_morph_process[2]+
   color_morph_process[3]+color_morph_process[4]+color_morph_process[5]=0)
   then begin cubiki_on:=0; cubiki_visible:=0; jump_on[6]:=q;
              end;

   if cube_scale>=0.9 then {виляние кубом по горизонтали}
          begin
             if (cube_amp.x<5000) then cube_amp.x:=cube_amp.x+elapsed_time*70;
          end
          else begin
             if (cube_amp.x>0) then cube_amp.x:=cube_amp.x-elapsed_time*50;
             if cube_amp.x<0 then cube_amp.x:=0;
          end;
   cube_position.x:=sin(q/10)*cube_amp.x;


   if (cubiki_on=0) then begin {Падение куба}
       if (cube_scale<0.8) and (add_cube_position.y<24000) then
            begin
               vect_big_cube:=vect_big_cube+20*elapsed_time;
               add_cube_position.y:=add_cube_position.y+vect_big_cube*elapsed_time;
            end;
       if (cube_amp.y>0) and (add_cube_position.y>4000) then cube_amp.y:=cube_amp.y-elapsed_time*50;
       if cube_amp.y<0 then cube_amp.y:=0;
   end;

end;


if (jump_on[1]>0)  then scale_jump:= jump1(jump_on[1], 0.2*g_scale, 5);{}
if (jump_on[2]>0)  then glitch_jump:=jump1(jump_on[2], 15, 20);


{мигание яркостью куба в такт музыке}
if (info^.row > 7 + blink_num shl 4) and
   (info^.row < 7 + (blink_num+1) shl 4) then
   begin
      jump_on[3]:=q;
      inc(blink_num);
      blink_num:=blink_num and 3;
   end;
if (jump_on[3]>0)  then u:=jump1(jump_on[3], 15, 5) else u:=0;



if (jump_on[4]>0)  then  add_cube_rotate.y:=jump1(jump_on[4], 0.14, 25);{}
if (jump_on[5]>0)  then glitch_jump:=jump1(jump_on[5], 5, 25);

if (jump_on[6]>0)  then if cube_scale>0.5 then cube_scale:=cube_scale-jump1(jump_on[6], 0.012, 20)*elapsed_time;
if (jump_on[7]>0)  then add_cube_rotate.y:=jump1(jump_on[7], 0.3, 1400);{}
if (jump_on[8]>0)  then glitch_jump:=jump1(jump_on[8], 15, 35);


if (jump_on[9]>0)  then begin {poloski}
                        poloski1:=round(jump1(jump_on[9], 5, 10)) shl 1;
                        poloski2:=poloski1 + h_bars shr 1;
                        poloski1_col:=poloski1;
                        if poloski1_col>1 then add_color:=1 else add_color:=0;
                        end;
if (jump_on[10]>0) then begin {poloski}
                        poloski2:=(q shl 1) and 255;
                        poloski1:=poloski2 + (h_bars shr 1);
                        poloski1_col:=round(jump1(jump_on[10], 8, 20));
                        if poloski1_col>1 then add_color:=byte(-1) else
                                       begin add_color:=0; poloski1:=0; end;
                        end;
if (jump_on[11]>0) then begin {poloski}
                        poloski1_col:=round(jump1(jump_on[11], 6, 15));
                        if poloski1_col>1 then poloski1:=(byte(-q) shl 1) and 255
                                          else poloski1:=0;
                        add_color:=0;
                        end;

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




{Draw part}
big_cube_edge_render(1, 20-u, 1.22,  160,100, vaddr2+160);{}
big_DrawCube(0,numpoly1-1, poloski2, add_color, h_bars,  vaddr2+160, vaddr);{}
if (cubiki_visible=1) then dots_draw(1, count_dots, 160,100, vaddr3, vaddr);{}
big_DrawCube_add(0,numpoly2-1, vaddr2+160+256, vaddr);{}

{logos draw}
if logo1_on=1 then begin
Draw_Logo(Logo_fill[0], Logo_clear[0], {tip:}0,
          logo_mode, {fadesize:}15, {cellsize:}2, {color:}254, {pos:}60+80*320,
          {pos2:}0,  {mask_size/2:}236 shr 2, elapsed_time, {mask:}seg_logo1, {texture_seg:}0, vaddr);{}
Draw_Logo(Logo_fill[1], Logo_clear[1], {tip:}0,
          logo_mode, {fadesize:}15, {cellsize:}1, {color:}255,  {pos:}56+76*320,
          {pos2:}0, {mask_size/2:}1040 shr 2, elapsed_time shl 1, {mask:}seg_logo1+16, {texture_seg:}0, vaddr);{}
end;

if logo2_on=1 then begin
Draw_Logo(Logo_fill[0], Logo_clear[0], 0,
          logo_mode, 15, 2, 254, 60+80*320, 0, 260 shr 2, elapsed_time, seg_logo2, 0, vaddr);{}
Draw_Logo(Logo_fill[1], Logo_clear[1], 0,
          logo_mode, 15, 1, 255,  56+76*320,0, 1200 shr 2, elapsed_time shl 1, seg_logo2+17, 0, vaddr);{}
end;


if Aantal=0 then begin  { fixed start-drop frame on slow PC}
   wait_music_pos(1, 0);

   if (mtimer-start_time)>0 then
            begin
              old_time:=mtimer-1;
              start_time:=mtimer-1;
            end;
end
else begin
   if Vsync_mode=1 then Midas_WaitVR;{}
end;

set_dpal(seg_dpal1); {set dynamic palette}



if glitch_jump>0 then FlipScreen2(mtimer, round(glitch_jump), seg_random, vaddr,vga)
else FlipScreen(vaddr, vga);{}

Inc(Aantal);

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

until (esc_test) or (music_pos(9,12)){};


end;


end.