Program Wh0_KNoWs;
{$M 4000,0,65535}
Uses CRT,GFX,GFX2,GP15;

{ This thingy is dedicated to everyone here in da place! }
{ Written By INSane. / WH0 KNoWs? }
{ During Gardening '96 Stage ][ }
{ Read FILE_ID.DIZ for more info }

TYPE VBmap= ARRAY [1..64000] OF BYTE;

CONST RI: INTEGER=0;
      GI: INTEGER=0;
      BI: INTEGER=0; {Indexes... i don't know... find out yourself}
      PI=3.1415;
      FrameCounter: INTEGER = 3600; {60 fps * 60 Secs}

VAR I,J,K,L,M,N: INTEGER; { Counters }
    F: WORD;
    { Pasma shit stuff }
    _SIN_: ARRAY [0..511] OF BYTE;
    _COS_: ARRAY [0..511] OF BYTE;
    _PALSIN_: ARRAY [0..511] OF BYTE;
    _PALCOS_: ARRAY [0..511] OF BYTE;
    _INDSIN_: ARRAY [0..511] OF INTEGER;
    _XSIN_: ARRAY [0..511] OF WORD;
    _Pal_: ARRAY [0..255,1..3] OF BYTE;
    Yees: ARRAY [0..199] OF INTEGER;
    X1,X2: INTEGER;
    Y1,Y2: INTEGER;

    {distortion shit}
    _DistSIN_: ARRAY [0..511] OF INTEGER;
    _DistCOS_: ARRAY [0..511] OF INTEGER;
    Dx1,Dx2: INTEGER;
    Dy1,Dy2: INTEGER;

    {general Shit}
    DSTbmap: ^VBmap;  { as above}


{ Shittie and useless routines ;-)}
Procedure CopyToScn(What,Where:WORD);Assembler;
ASM
  mov es,[Where]
  mov si,0
  mov di,0
  push ds
  mov ds,[What]
  mov cx,125
@loop:
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  db $66; movsw;  db $66; movsw;  db $66; movsw;  db $66; movsw
  dec cx
  jg @loop
  pop ds
END;

{$I 320200c.256} {Procedure SetFreq}
Procedure SetVGA;Assembler;
Asm mov ax,13h
    int 10h
    Call SetFreq { set refresh rate at 60Hz... the same as the projector}
    end;

Procedure SetTxT;Assembler;
ASM
  mov ax,03h
  int 10h
END;

Procedure InitVirtual;
Begin
  GetMem( DSTbmap, 64000);
END;

Procedure KillVirtual;
Begin
  FreeMem( DSTbmap, 64000);
End;

procedure Pal(c,r,g,b:byte);Assembler;
{I'm using this just to check the speed of my routines}
ASM
  mov dx,$3C8
  mov al,[C]
  out dx,al
  inc dx
  mov al,[R]
  out dx,al
  mov al,[G]
  out dx,al
  mov al,[B]
  out dx,al
END;

Procedure waitretrace;Assembler;
ASM
  mov dx,$3DA
  mov cl,08h
@Lp1:
  in  al,dx
  test al,cl
  jnz @Lp1
@Lp2:
  in  al,dx
  test al,cl
  jz  @Lp2
END;

Procedure SetPal; Assembler;
ASM
   mov cx,0
   mov si,OFFSet [_PAL_]
   mov dx,$3C8
@loop:
   mov al,cl
   out dx,al
   inc dx
   lodsb
   out dx,al
   lodsb
   out dx,al
   lodsb
   out dx,al
   dec dx
   inc cx
   cmp cx,255
   jle @loop
END;

Procedure PalRot( From, _to_: INTEGER);
VAR I: INTEGER; { FUCKING Array INDEX }
BEGIN
 FOR I:= From TO _to_ DO
   BEGIN
   _PAL_[I,1]:=_PALSIN_[_INDSIN_[(RI+I) AND 511]];
   _PAL_[I,2]:=_PALCOS_[_INDSIN_[(GI+I SHL 1) AND 511]];
   _PAL_[I,3]:=_PALCOS_[_INDSIN_[(BI+I) AND 511]];
   END;
 ASM
     ADD [RI],1
     AND [RI],511
     ADD [GI],2
     AND [GI],511
     ADD [BI],-3
     AND [BI],511
 END;
END;

Procedure Plasma( a,b,c,d: INTEGER;  Where: WORD );FAR; {;-)}
VAR X,Y: INTEGER;
    tX1,tX2: INTEGER;
    tY1,tY2: INTEGER;
    ttX1,ttX2: INTEGER;
    Color: WORD;
    lop: WORD;
BEGIN
  tX1:=X1; tX2:=X2;  tY1:=Y1; tY2:=Y2;
ASM
     mov [Lop],99
     mov es,[Where]
     mov ax,[A]
     mov WORD PTR CS:@X1+3,ax
     mov WORD PTR CS:@X1b+3,ax
     mov ax,[B]
     mov WORD PTR CS:@X2+3,ax
     mov WORD PTR CS:@X2b+3,ax
     mov ax,[C]
     mov WORD PTR CS:@Y1+3,ax
     mov ax,[D]
     mov WORD PTR CS:@Y2+3,ax
     xor di,di
@loooop:

     mov bx,[tX1]
     add bx,[lop]
     add bx,bx
     and bx,1023
     mov SI,OFFSet [_XSIN_]  {agi killer}
     mov ax,[si+bx]
     mov bx,[tX2]
     add bx,[lop]
     add bx,bx
     and bx,1023
     mov [ttX1],ax {agi killer}
     mov ax,[si+bx]
     mov [ttX2],ax


     mov bx,[tY1]
     mov SI,OFFset [_COS_]   {agi killer}
     mov ax,[si+bx]
     mov bx,[tY2]
     mov cx,159 {agi killer}
     add ax,[si+bx]
     mov dx,ax

     mov SI,OFFset [_SIN_]

      @loop:
          mov ax,dx
          mov bx,[ttX1]
          and bx,511
      @x1:add [ttX1],0ffh {agi killer}
          add ax,[si+bx]
          mov bx,[ttX2]
          and bx,511
      @x2:add [ttX2],0ffh {agi killer}
          add ax,[si+bx]
          mov ah,al

          DB $66,$0F,$C8 {bswap eax}

          mov ax,dx
          mov bx,[ttX1]
          and bx,511
     @x1b:add [ttX1],0ffh {agi killer}
          add ax,[si+bx]
          mov bx,[ttX2]
          and bx,511
     @x2b:add [ttX2],0ffh {agi killer}
          add ax,[si+bx]
          mov ah,al

          db $66,$0f,$C8 {bswap eax}
          DB $66; stosw
          DB $66; mov es:[di+316],ax

          sub cx,2
          jge @loop

     add di,320
 @y1:add [tY1],0ffh
     and [tY1],511
 @y2:add [tY2],0ffh
     and [tY2],511

     dec Lop
     jge @loooop

   @END:
    ADD [X1],1
    AND [X1],511
    ADD [X2],2
    AND [X2],511
    ADD [Y1],3
    AND [Y1],511
    ADD [Y2],4
    AND [Y2],511
END;
END;

Procedure Distort(Where:WORD);
VAR tDx1,tDx2: INTEGER;
    tDy1,tDy2: INTEGER;
    X,Y:INTEGER;
BEGIN
    tDx1:=Dx1; tDx2:=Dx2;
    tDy1:=Dy1; tDy2:=Dy2;
    Asm mov [Y],0
        mov di,12200
        mov es,[Where]
    @for:
           mov ax,[tDy2]
           add ax,5
           and ax,511
           mov si,OFFset [_DistSIN_] {agi killer}
           mov [tDy2],ax
           mov WORD PTR cs:@tDy2+1,ax

           mov bx,[tDy1]
           add bx,6
           and bx,511
           mov [tDy1],bx
           add bx,bx
           xor cx,cx  {X... agi killer}
           mov dx,[si+bx] {_DistSIN_[tDy1]}
           add dx,13800   {source offset}
           mov bx,[Y]
           mov si,OFFSet [_DistCOS_] {agi killer}
           add dx,OFFSet [Yees]+[bx]

       @loop:
     @tDy2:mov bx,0ffh
           add bx,cx
           and bx,511
           add bx,bx
           push ds              {agi killer}
           mov bx,[bx+si]
           mov ax,SEG [Logara]  {agi killer}
           mov bx,[bx]+OFFset [Yees]
           add bx,cx {+x} {bx= source pixel}

           add bx,dx
           mov ds,ax            {agi killer}
           inc cx               {here's one more agi...}
           mov al,[bx]+OFFSET[logara]
           pop ds
           or  al,al
           je  @noviz
              stosb
              cmp cx,230
              jle @loop
              add di,89
              jmp @ENDFOR
       @noviz:
           inc di
           cmp cx,230
           jle @loop
           add di,89
      @ENDFOR:
      add [Y],2
      cmp [Y],210
      jle @for
      add [Dy1],4
      add [Dy2],-3
    END;
END;

BEGIN
  GP_ResetGUS;
  GP_LoadModule('amu-chip.mod');
  GP_StartPlaying;
  WaitRetrace;
  IF NOT(GP_PlayOK AND GP_Playing) THEN
     BEGIN
     GP_KillModule ;
     GP_ResetGUS ;
     END;

FOR I:=0 To 50 DO
  BEGIN WaitReTrace; WriteLN END;

InitVirtual;
setVGA;
_PAL_[00,1]:=00;_PAL_[00,2]:=00;_PAL_[00,3]:=00;
_PAL_[01,1]:=15;_PAL_[01,2]:=05;_PAL_[01,3]:=02;
_PAL_[02,1]:=15;_PAL_[02,2]:=10;_PAL_[02,3]:=06;
_PAL_[03,1]:=20;_PAL_[03,2]:=15;_PAL_[03,3]:=10;
_PAL_[04,1]:=25;_PAL_[04,2]:=20;_PAL_[04,3]:=15;
_PAL_[05,1]:=30;_PAL_[05,2]:=25;_PAL_[05,3]:=20;
_PAL_[06,1]:=35;_PAL_[06,2]:=30;_PAL_[06,3]:=25;
_PAL_[07,1]:=40;_PAL_[07,2]:=35;_PAL_[07,3]:=30;
_PAL_[08,1]:=22;_PAL_[08,2]:=15;_PAL_[08,3]:=15;
_PAL_[09,1]:=63;_PAL_[09,2]:=63;_PAL_[09,3]:=63;
_PAL_[10,1]:=00;_PAL_[10,2]:=00;_PAL_[10,3]:=00;
_PAL_[11,1]:=20;_PAL_[11,2]:=30;_PAL_[11,3]:=40;
_PAL_[12,1]:=63;_PAL_[12,2]:=20;_PAL_[12,3]:=20;
_PAL_[13,1]:=30;_PAL_[13,2]:=15;_PAL_[13,3]:=10;
_PAL_[14,1]:=23;_PAL_[14,2]:=10;_PAL_[14,3]:=00;
_PAL_[15,1]:=63;_PAL_[15,2]:=63;_PAL_[15,3]:=63;

{Plasma shit-look-at-your-pussy-up tables}
 FOR I:=0 TO 511 DO
    BEGIN
       _SIN_[I]:=4+Round(SIN(I*PI/256)*9+9+COS(I*2*PI/256)*9+9);
       _COS_[I]:=4+Round(COS(I*PI/256)*14+14+SIN(I*6*PI/256)*4+4);
       _PALSIN_[I]:=Round(SIN(I*PI/256)*10+11);
       _PALCOS_[I]:=Round(COS(I*PI/256)*6+7+COS(I*PI/256)*4+4);
       _INDSIN_[I]:=Round(COS(I*PI/256)*200+200+COS(I*4*PI/256)*55+55);
       _XSIN_[I]:=Round(COS(I*2*PI/256)*90+90+COS(I*4*PI/256)*85+85);
       _DistSIN_[I]:=Round(SIN(I*4*PI/256)*2+2+SIN(I*PI/256)*3+3);
       _DistCOS_[I]:=Round(COS(I*PI/256)*1+1+SIN(I*3*PI/256)*3+3) SHL 1;
    END;
 X1:=0;X2:=0;Y1:=0;Y2:=0;
 Dx1:=0; Dx2:=0; Dy1:=0; Dy2:=0;
 FOR I:=0 to 199 DO Yees[I]:=I*320;

SetPal;
Repeat
   Plasma(-7,-3,2,1,SEG(DSTbmap^));
   Distort(SEG(DSTbmap^));
   PalRot(16,224);
{   Pal(0,10,20,30); {uncomment to see the free time / frame}
   WaitRetrace;
   CopyToScn(SEG(DSTbmap^),SEGA000);
   SetPal;
   ASM dec [FrameCounter] END;
Until Keypressed OR (FrameCounter=0);

CopyToScn(SEG(TheEnd),SEGA000);
For I:=0 to 300 Do WaitRetrace;
{Fake fade... It's a buged-on-purpose routine to fade out the end screen}
FOR J:=0 To 63 DO
 BEGIN
  WAITrETRACE;
  setpal;
 FOR I:=0 to 255 do
   BEGIN
    DEC(_PAL_[I,1]);DEC(_PAL_[I,2]);DEC(_PAL_[I,3]);
    IF _PAL_[I,1]<0 THEN _PAL_[I,1]:=0;
    IF _PAL_[I,2]<0 THEN _PAL_[I,2]:=0;
    IF _PAL_[I,3]<0 THEN _PAL_[I,3]:=0;
   END;
 eND;
SetTxT;
KillVirtual;
	GP_KillModule ;
	GP_ResetGUS ;
WriteLN;WriteLN;
WriteLN('"SKATOULA"');
WriteLN('A BiRTHDaY NiGHTrO... FROM a NEW group... maybe... Wh0 KNoWs?');
WriteLN;
WriteLN('VOTE for us NOW!... yeah... RIGHT');
WriteLN;
WriteLN('GREETINGS TO:');
WriteLN('DemaniacS and MOD for letting us their machine');
WriteLN('as well as all the people in the place for help and');
WriteLN('and stuff like shouting, laughing, caughing etc ...');
End.

