{$M 4048,0,170000}

{$A+,B-,E+,F-,G+,N+,Q-,R-,S-}

uses mse_tp;

Const VGA=$A000;
      Npages=2;
      MinX=0;
      MaxX=319;
      MinY=0;
      MaxY=199;

Type RgbItem=Record
                   R,G,B:Byte;
             End;
     RgbList=Array[0..255] of RgbItem;

var Virt:Array[1..Npages] Of Pointer;
    VP:Array[1..Npages] Of Word;

Procedure video_mode (mode : Byte); Assembler;
Asm
  mov  AH,00
  mov  AL,mode
  int  10h
end;

Procedure PutPixel(X,Y:word;Col:Byte;Where:Word);
Begin
     if x>-1 then if x<320 then if y>-1 then if y<200 then
     Mem[Where:(y*320)+x]:=Col;
End;

Function GetPixel(X,Y:word;Where:Word):Byte;
Begin
     GetPixel:=Mem[Where:(y*320)+x];
End;

Procedure Cls(Col:Byte;Where:Word);
Begin
     Fillchar(Mem[Where:0000],64000,Col);
End;

Procedure WaitVBL; Assembler;
Label A1,A2;
Asm
   Mov DX,3DAh
   A1:
      In AL,DX
      And AL,08h
      Jnz A1
   A2:
      In AL,DX
      And AL,08h
      Jz A2
End;

Procedure SetColor(Col,R,G,B:Byte);
Begin
     Port[$3C8]:=Col;
     Port[$3C9]:=R;
     Port[$3C9]:=G;
     Port[$3C9]:=B;
End;

Procedure SetPalette(Pal:RgbList);
Var A:Byte;
Begin
     WaitVBL;
     For A:=0 To 255 do SetColor(A,Pal[A].R,Pal[A].G,Pal[A].B);
End;

Procedure InitVirt;
Var A:Byte;
Begin
     For A:=1 To Npages Do
     Begin
          GetMem(Virt[A],64000);
          VP[A]:=Seg(Virt[A]^);
     End;
End;

Procedure CloseVirt;
Var A:Byte;
Begin
     For A:=1 To Npages Do
     Begin
          Freemem(Virt[A],64000);
          VP[A]:=$A000;
     End;
End;

Procedure LoadPCX(Filename:String;Where:Word);
Var Fil:File;
    Dx,Dy:Word;
    J,M:Byte;
    Ph:Word;
    Buff:Array[0..127] of byte;
    PCXPal:RgbList;
Begin
     Assign(Fil,Filename);
     Reset(Fil,1);
     Blockread(Fil,Buff,128);
     Dy:=0;
     Repeat
           Dx:=0;
           Repeat
                 BlockRead(Fil,J,1);
                 If J>192 Then
                 Begin
                      BlockRead(Fil,M,1);
                      Dec(J,192);
                      For Ph:=1 To J Do
                      Begin
                           PutPixel(Dx,Dy,M,Where);
                           Inc(Dx);
                      End;
                 End
                 Else
                 Begin
                      PutPixel(Dx,Dy,J,Where);
                      Inc(Dx);
                 End;
           Until Dx>=320;
           Inc(Dy);
     Until Dy=200;
     BlockRead(Fil,M,1);
     If M=12 Then
     Begin
          BlockRead(Fil,PCXPal,768);
          For M:=0 To 255 Do
          Begin
               PCXPal[M].R:=PCXPal[M].R Div 4;
               PCXPal[M].G:=PCXPal[M].G Div 4;
               PCXPal[M].B:=PCXPal[M].B Div 4;
          End;
          SetPalette(PCXPal);
     End;
     Close(Fil);
End;

Procedure GetImage(x1,y1,x2,y2:Word;Var Img:Pointer;Where:Word);
Var Dx,Dy:Word;
    A,B:Word;
    Segm,Offs:Word;
Begin
     Dx:=Abs(x2-x1)+1;
     Dy:=Abs(y2-y1)+1;
     GetMem(Img,Dx*Dy+4);
     Segm:=Seg(Img^);
     Offs:=Ofs(Img^);
     Move(Dx,Mem[Segm:Offs],2);
     Move(Dy,Mem[Segm:Offs+2],2);
     Offs:=Offs+4;
     For A:=y1 to y2 Do
     For B:=x1 to x2 Do
     Begin
          Mem[Segm:Offs]:=GetPixel(B,A,Where);
          Inc(Offs);
     End;
End;

Procedure KillImage(Var Img:Pointer);
Var Dx,Dy:Word;
    Segm,Offs:Word;
Begin
     Segm:=Seg(Img^);
     Offs:=Ofs(Img^);
     Move(Mem[Segm:Offs],Dx,2);
     Move(Mem[Segm:Offs+2],Dy,2);
     FreeMem(Img,Dx*Dy+4);
End;

Procedure PutImage(X,Y,C:Integer;Var Img:Pointer;Where:Word);
Var Dx,Dy:Word;
    A,B:Word;
    Segm,Offs:Word;
Begin
     Segm:=Seg(Img^);
     Offs:=Ofs(Img^);
     Move(Mem[Segm:Offs],Dx,2);
     Move(Mem[Segm:Offs+2],Dy,2);
     Offs:=Offs+4;
     A:=Y;
     While (A<=Y+DY-1) And (A<=MaxY) Do
     Begin
          B:=X;
          While (B<=X+DX-1) And (B<=MaxX) Do
          Begin
               If (X>=MinX) And (Y>=MinY) Then
               if Mem[Segm:Offs]<>c then
                 PutPixel(B,A,Mem[Segm:Offs],Where);
               Inc(Offs);
               Inc(B);
          End;
          Inc(A);
     End;
End;

Function GetKey (Var Key : Word) : Boolean; Assembler;
{ determine if key pressed and return it as a Word }
{ if Lo(key) = 0 and Hi(key) <> 0 then we have a FN key ! }
Asm
  MOV     AH, 1
  INT     16H
  MOV     AL, 0
  JE      @@1
  xor     AH, AH
  INT     16H
  LES     DI, Key
  MOV     Word PTR ES : [DI], AX
  MOV     AL, 1
 @@1 :
end;

Function GetChar (Var Key : Char) : Boolean;
{ determine if key pressed and return it as a Char}
Var
  c : Word;
begin
  Key := #0;
  if GetKey (c) then
  begin
    GetChar := True;
    if (LO (c) = 0) and (HI (c) <> 0) then
      Key := CHR ( HI (c) + 128 )  { add 128 For FN keys }
    else
      Key := CHR (LO (c) );
  end
  else
    GetChar := False;
end;

var x,y,a:integer;
    c,n1:char;
    muzak:integer;
    mrow,morder:integer;
    p1:integer;
    cc: array[0..6] of integer;

procedure mupdate(check:integer); {1 means fast, 2 means normal}
begin
     if muzak=1 then mrow:=musicrow;
     if muzak=1 then morder:=musicorder($FF);
     if muzak=0 then if random(check)=0 then mrow:=mrow+1;
     if muzak=0 then if mrow>63 then
        begin
             mrow:=mrow-63;
             morder:=morder+1;
        end;
end;

var left:  array [0..3] of pointer;
    right: array [0..3] of pointer;
    up:    array [0..3] of pointer;
    down:  array [0..3] of pointer;
    sleep: array [0..3] of pointer;
    hit:   array [0..3] of pointer;
    blob:  array [0..3] of pointer;
    sun:   array [0..1] of pointer;
    tree:  array [0..2] of pointer;
    sea:   array [0..1] of pointer;
    land:  array [0..2] of pointer;
    credits: pointer;

Var
  SoundCardName : String;
  DMA, IRQ : Byte;
  BaseIO : Word;
  SampleRate : Word;
  DMABuffer : Word;
  Handle : File;
  Header : GDMHeader;
  EMSFlag : Word;
  MusicChannels : Word;
  ChannelCount : Word;
  ExitProgram : Boolean;

Procedure EndProg(ErrorString : String);
{ Prints the error string and Halts the program }
Begin
  Writeln;
  Writeln(ErrorString);
  If IOResult <> 0 then Close(Handle);
  Halt(0);
End;

Function GetSoundCardName : String;
Begin
  Writeln;
  Writeln(' Select Sound Card: ');
  Writeln('   0. No Sound');
  Writeln('   1. Gravis Ultrasound');
  Writeln('   2. Sound Blaster 1.0');
  Writeln('   3. Sound Blaster 2.0');
  Writeln('   4. Sound Blaster Pro');
  Writeln('   5. Sound Blaster 16');
  Writeln('   6. Pro Audio Spectrum');
  repeat until getchar(n1)=true;
    if n1='0' then GetSoundCardName := 'none';
    if n1='1' then GetSoundCardName := 'GUS.MSE';
    if n1='2' then GetSoundCardName := 'SB1X.MSE';
    if n1='3' then GetSoundCardName := 'SB2X.MSE';
    if n1='4' then GetSoundCardName := 'SBPRO.MSE';
    if n1='5' then GetSoundCardName := 'SB16.MSE';
    if n1='6' then GetSoundCardName := 'PAS.MSE';
End;

Function GetIRQNumber : Byte;
Begin
  Writeln;
  Writeln(' Select IRQ: ');
  Writeln('   1. IRQ 2');
  Writeln('   2. IRQ 3');
  Writeln('   3. IRQ 5');
  Writeln('   4. IRQ 7');
  Writeln('   5. IRQ 11');
  Writeln('   6. IRQ 12');
  Writeln('   7. auto-detect');
  repeat until getchar(n1)=true;
  if n1='1' then GetIRQNumber := 2;
  if n1='2' then GetIRQNumber := 3;
  if n1='3' then GetIRQNumber := 5;
  if n1='4' then GetIRQNumber := 7;
  if n1='5' then GetIRQNumber := 11;
  if n1='6' then GetIRQNumber := 12;
  if n1='7' then GetIRQNumber := $FF;
End;

Function GetDMAChannel : Byte;
Begin
  Writeln;
  Writeln(' Select DMA Channel: ');
  Writeln('   1. DMA Channel 1');
  Writeln('   2. DMA Channel 2');
  Writeln('   3. DMA Channel 3');
  Writeln('   4. DMA Channel 5');
  Writeln('   5. auto-detect');
  repeat until getchar(n1)=true;
  if n1='1' then GetDMAChannel := 1;
  if n1='2' then GetDMAChannel := 2;
  if n1='3' then GetDMAChannel := 3;
  if n1='4' then GetDMAChannel := 5;
  if n1='5' then GetDMAChannel := $FF;
End;

Function GetBaseIO : Word;
Begin
  Writeln;
  Writeln(' Select Base I/O Address: ');
  Writeln('   1. 210h');
  Writeln('   2. 220h');
  Writeln('   3. 230h');
  Writeln('   4. 240h');
  Writeln('   5. 250h');
  Writeln('   6. 260h');
  Writeln('   7. auto-detect');
  repeat until getchar(n1)=true;
  if n1='1' then GetBaseIO := $210;
  if n1='2' then GetBaseIO := $220;
  if n1='3' then GetBaseIO := $230;
  if n1='4' then GetBaseIO := $240;
  if n1='5' then GetBaseIO := $250;
  if n1='6' then GetBaseIO := $260;
  if n1='7' then GetBaseIO := $FFFF;
End;

Function ToHex(Num : Word) : String;
{ Converts a decimal number to Hexidecimal }
Const HexChars : String = '0123456789ABCDEF';
Var   Temp : String;
Begin
  Temp := '';
  Temp := Temp + HexChars[((Num Shr 8) And 15) + 1];
  Temp := Temp + HexChars[((Num Shr 4) And 15) + 1];
  Temp := Temp + HexChars[((Num Shr 0) And 15) + 1];
  ToHex := Temp + 'h';
End;

{start}

Begin
  SoundCardName := GetSoundCardName; { Get the Sound card to be used      }

if soundcardname<>'none' then
 begin

  BaseIO := GetBaseIO;               { Get the Base port address          }
  IRQ := GetIRQNumber;               { Get IRQ number                     }
  DMA := GetDMAChannel;              { Get DMA Channel                    }
  SampleRate := 45;                  { Initially set at 45Khz             }
  DMABuffer := 4096;                 { DMA Buffer of 4096 bytes           }
  Case LoadMSE(SoundCardName, 0, SampleRate, DMABuffer, BaseIO, IRQ, DMA) of
    1 : EndProg('Base I/O address autodetection failure');
    2 : EndProg('IRQ level autodetection failure');
    3 : EndProg('DMA channel autodetection failure');
    4 : EndProg('DMA channel not supported');
    6 : EndProg('Sound device does not respond');
    7 : EndProg('Memory control blocks destroyed');
    8 : EndProg('Insufficient memory for mixing buffers');
    9 : EndProg('Insufficient memory for MSE file');
    10: EndProg('MSE has invalid identification string');
    11: EndProg('MSE disk read failure');
    12: EndProg('MVSOUND.SYS not loaded');
  End;
  ExitProc := @FreeMSE;              { Call FreeMSE on abnormal program end }
  If EMSExist                      { Check for EMS }
    Then EMSFlag := 1              { Yes, EMS exists, so use it }
    Else EMSFlag := 0;             { EMS does not exist }

{$I-}                              { Turn off I/O checking }
  Assign(Handle, 'djamm.gdm');   { Open the file for loading }
  Reset(Handle);
{$I+}                              { Turn I/O checking back on }
  If IOResult <> 0 Then
     EndProg('Module does not exist');    { File not found, exit program }

  Case LoadGDM(Handle, 0, EMSFlag, Header) of
    1 : EndProg('Module is corrupt');
    2 : EndProg('Could not autodetect module type (N/A)');
    3 : EndProg('Bad file format ID string');
    4 : EndProg('Insufficient memory to load module');
    5 : EndProg('Can not unpack samples');
    6 : EndProg('AdLib instruments not supported');
  End;
  Close(Handle);

    MusicChannels := 0;            { Calculate the number of channels in song }
  For ChannelCount := 1 to 32 do
    Begin
      If Header.PanMap[ChannelCount] <> $FF
        Then MusicChannels := MusicChannels + 1;
    End;
  SampleRate := StartOutput(MusicChannels, 0);

  muzak:=1;

 end

else muzak:=0;

{-------------begins here------------}

     writeln ('module loaded!');

     c:=' ';

     video_mode ( $13);
     initvirt;

     loadpcx ('gfx.pcx',vp[1]);

     getimage (0,0,19,39,tree[0],vp[1]);
     getimage (20,0,39,39,tree[1],vp[1]);
     getimage (40,0,59,39,tree[2],vp[1]);

     getimage (0,40,19,59,right[0],vp[1]);
     getimage (20,40,39,59,right[1],vp[1]);
     getimage (40,40,59,59,right[2],vp[1]);
     getimage (20,40,39,59,right[3],vp[1]);

     getimage (0,60,19,79,left[0],vp[1]);
     getimage (20,60,39,79,left[1],vp[1]);
     getimage (40,60,59,79,left[2],vp[1]);
     getimage (20,60,39,79,left[3],vp[1]);

     getimage (0,80,19,99,down[0],vp[1]);
     getimage (20,80,39,99,down[1],vp[1]);
     getimage (40,80,59,99,down[2],vp[1]);
     getimage (20,80,39,99,down[3],vp[1]);

     getimage (0,100,19,119,up[0],vp[1]);
     getimage (20,100,39,119,up[1],vp[1]);
     getimage (40,100,59,119,up[2],vp[1]);
     getimage (20,100,39,119,up[3],vp[1]);

     getimage (0,120,19,139,hit[0],vp[1]);
     getimage (20,120,39,139,hit[1],vp[1]);
     getimage (40,120,59,139,hit[2],vp[1]);
     getimage (20,120,39,139,hit[3],vp[1]);

     getimage (0,140,19,159,sleep[0],vp[1]);
     getimage (20,140,39,159,sleep[1],vp[1]);
     getimage (40,140,59,159,sleep[2],vp[1]);
     getimage (60,140,79,159,sleep[3],vp[1]);

     getimage (0,160,19,179,blob[0],vp[1]);
     getimage (20,160,39,179,blob[1],vp[1]);
     getimage (40,160,59,179,blob[2],vp[1]);
     getimage (60,160,79,179,blob[3],vp[1]);

     getimage (60,0,79,19,sea[0],vp[1]);
     getimage (80,0,99,19,sea[1],vp[1]);

     getimage (100,0,119,19,sun[0],vp[1]);
     getimage (120,0,139,19,sun[1],vp[1]);

     getimage (60,20,79,39,land[0],vp[1]);
     getimage (80,20,99,39,land[1],vp[1]);
     getimage (100,20,119,39,land[2],vp[1]);

     a:=0;
     repeat

      cls (255,vp[2]);
      for x:=0 to 1 do for y:=0 to 1 do putimage(x*20,y*20,255,sun[a],vp[2]);

      for x:=0 to 19 do for y:=0 to 39 do
                          begin
                               p1:= getpixel (0+x,y,vp[2]);
                               putpixel (39-x,y,p1,vp[2]);
                          end;
                      for x:=0 to 40 do for y:=0 to 20 do
                          begin
                               p1:= getpixel (x,y,vp[2]);
                               putpixel (x,39-y,p1,vp[2]);
                          end;

      getimage (0,0,39,39,sun[a],vp[2]);
      a:=a+1;

     until a=2;

     randomize;

     if muzak=1 then startmusic;
     if muzak=0 then
        begin
             mrow:=0;
             morder:=0;
        end;

     {letsgo!}

     repeat
       mupdate(1);
       if morder=0 then
             begin
              if (mrow mod 63)>=0 then
                  for x:=0 to 319 do for y:=0 to 199 do mem[vp[2]:x+y*320]:=152;
              if (mrow mod 63)>=1 then
                  for x:=0 to 15 do for y:=3 to 7 do putimage(x*20,y*20,0,land[0],vp[2]);
              if (mrow mod 63)>=2 then
                  for x:=-1 to 15 do for y:=8 to 9 do putimage(x*20,y*20,0,sea[0],vp[2]);
              if (mrow mod 63)>=3 then
                  putimage(10,10,255,sun[0],vp[2]);

              if (mrow mod 63)>=5 then putimage(4*20,4*20,255,tree[0],vp[2]);
              if (mrow mod 63)>=6 then putimage(14*20,2*20,255,tree[2],vp[2]);
              if (mrow mod 63)>=7 then putimage(7*20,4*20,255,tree[2],vp[2]);
              if (mrow mod 63)>=8 then putimage(13*20,5*20,255,tree[1],vp[2]);
              if (mrow mod 63)>=9 then putimage(3*20,6*20,255,land[1],vp[2]);
              if (mrow mod 63)>=10 then putimage(11*20,4*20,255,land[1],vp[2]);
              if (mrow mod 63)>=11 then putimage(9*20,6*20,255,land[2],vp[2]);
              if (mrow mod 63)>=12 then putimage(1*20,4*20,255,land[2],vp[2]);
              if (mrow mod 63)>=13 then putimage(4*20,7*20,255,down[1],vp[2]);
             end
                   else
             begin
                  for x:=0 to 319 do for y:=0 to 199 do mem[vp[2]:x+y*320]:=152;
                  for x:=0 to 15 do for y:=3 to 7 do putimage(x*20,y*20,0,land[0],vp[2]);
                  for x:=-1 to 15 do for y:=8 to 9 do putimage(x*20,y*20,0,sea[(mrow mod 16) div 8],vp[2]);
                  putimage(10,10,255,sun[(mrow mod 8) div 4],vp[2]);
                  putimage(3 *20,6*20,255,land[1],vp[2]);
                  putimage(11*20,4*20,255,land[1],vp[2]);
                  putimage(9 *20,6*20,255,land[2],vp[2]);
                  putimage(1 *20,4*20,255,land[2],vp[2]);

              if morder=1 then
               begin
                if mrow<32 then putimage(4*20+mrow*5,7*20,255,left[mrow mod 4],vp[2]);
                if mrow>=32 then putimage(4*20+32*5-(mrow-32)*5,7*20,255,right[mrow mod 4],vp[2]);
               end;

               if morder=2 then
               begin
                if mrow<32 then putimage(4*20,7*20,255,left[1],vp[2]);
                if mrow<32 then putimage(2*20,10*20-mrow*5 div 2,255,blob[mrow mod 2],vp[2]);
                if mrow>=32 then putimage(4*20,7*20,255,right[1],vp[2]);
                if mrow>=32 then putimage(2*20,6*20,255,blob[mrow mod 2],vp[2]);
                if mrow>=32 then putimage(8*20,10*20-(mrow-32)*5 div 2,255,blob[mrow mod 2],vp[2]);
               end;

               if morder=3 then
               begin
                if mrow<32 then putimage(4*20,7*20,255,up[1],vp[2]);
                if mrow<32 then putimage(8*20-mrow*5 div 2,6*20,255,blob[mrow mod 2],vp[2]);
                if mrow>=32 then putimage(4*20,7*20,255,hit[mrow mod 4],vp[2]);
                putimage(2*20,6*20,255,blob[mrow mod 2],vp[2]);
                if mrow>=32 then putimage(4*20,6*20,255,blob[mrow mod 2],vp[2]);
               end;

               if morder=4 then
               begin
                if mrow<32 then putimage(4*20+mrow*5,7*20,255,right[mrow mod 4],vp[2]);
                if mrow>=32 then putimage(12*20,7*20-(mrow-32)*5 div 2,255,up[mrow mod 4],vp[2]);
                for a:=1 to 2 do putimage(a*2*20,6*20,255,blob[mrow mod 2],vp[2]);
               end;

               if morder=5 then
               begin
                if mrow<32 then putimage(12*20,3*20,255,down[1],vp[2]);
                if mrow<32 then putimage(2*20,6*20-mrow*5 div 8,255,blob[mrow mod 2],vp[2]);
                if mrow<32 then putimage(4*20,6*20+mrow*5 div 8,255,blob[mrow mod 2],vp[2]);
                if mrow>=32 then putimage(12*20,3*20,255,down[1],vp[2]);
                if mrow>=32 then putimage(2*20,5*20-(mrow-32)*5 div 4,255,blob[mrow mod 2],vp[2]);
                if mrow>=32 then putimage(4*20+(mrow-32)*5,7*20,255,blob[mrow mod 2],vp[2]);
               end;

               if morder=6 then
               begin
                if mrow<32 then putimage(12*20,3*20,255,hit[mrow mod 4],vp[2]);
                if mrow<32 then putimage(2*20+mrow*5,3*20,255,blob[mrow mod 4],vp[2]);
                if mrow<32 then putimage(12*20,7*20-mrow*5 div 2,255,blob[mrow mod 4],vp[2]);
               end;

               if morder=7 then
               begin
                if mrow<16 then putimage(12*20,3*20,255,sleep[3],vp[2]);
                if mrow>=16 then if mrow<32 then putimage(12*20,3*20,255,sleep[((mrow mod 8) div 4)+1],vp[2]);
                if mrow>=32 then if mrow<48 then if (mrow mod 16) div 8=0 then putimage(12*20,3*20,255,left[1],vp[2])
                                                                         else putimage(12*20,3*20,255,down[1],vp[2]);
                if mrow>=48 then putimage(12*20,3*20,255,sleep[((mrow mod 8) div 4)],vp[2]);
               end;

               if morder=8 then
               begin
                if mrow<32 then putimage(12*20,3*20+mrow*5 div 4,255,down[mrow mod 4],vp[2]);
                if mrow<32 then putimage(14*20,10*20-mrow*5 div 2,255,blob[mrow mod 2],vp[2]);
                if mrow>=32 then putimage(12*20-(mrow-32)*5 div 4,5*20,255,right[(mrow mod 16) div 4],vp[2]);
                if mrow>=32 then putimage(14*20,6*20,255,blob[mrow mod 2],vp[2]);
                if mrow>=32 then putimage(5*20,10*20-(mrow-32)*5 div 2,255,blob[mrow mod 2],vp[2]);
               end;

               if morder=9 then
               begin
                if mrow<32 then if (mrow mod 16) div 8=0 then putimage(10*20,5*20,255,left[1],vp[2])
                                                         else putimage(10*20,5*20,255,right[1],vp[2]);
                if mrow>=32 then putimage(10*20,5*20,255,hit[mrow mod 4],vp[2]);
                putimage(14*20,6*20,255,blob[mrow mod 4],vp[2]);
                putimage(5*20,6*20,255,blob[mrow mod 4],vp[2]);
               end;

               if morder=10 then
               begin
                if mrow<8 then putimage(10*20-mrow*5,5*20,255,left[mrow mod 4],vp[2]);
                if mrow>=8 then if mrow<16 then putimage(8*20,5*20+(mrow-8)*5,255,down[mrow mod 4],vp[2]);
                if mrow>=16 then if mrow<24 then putimage(8*20+(mrow-16)*5,7*20,255,right[mrow mod 4],vp[2]);
                if mrow>=24 then if mrow<32 then putimage(10*20,7*20-(mrow-24)*5,255,up[mrow mod 4],vp[2]);
                if mrow>=32 then if mrow<40 then putimage(10*20-(mrow-32)*5,5*20,255,left[mrow mod 4],vp[2]);
                if mrow>=40 then if mrow<48 then
                   begin
                     putimage(8*20,5*20,255,left[0],vp[2]);
                     move (mem[vp[2]:0],mem[vp[1]:0],64000);
                     for y:=1 to 198 do move (mem[vp[1]:320*y],mem[vp[2]:320*y+(mrow mod 3) -1],320);
                   end;
                if mrow>=48 then putimage(8*20,5*20,255,hit[0],vp[2]);
                putimage(14*20,6*20,255,blob[mrow mod 4],vp[2]);
                putimage(5*20,6*20,255,blob[mrow mod 4],vp[2]);
               end;

                  putimage(4 *20,4*20,255,tree[0],vp[2]);
                  putimage(14*20,2*20,255,tree[2],vp[2]);
                  putimage(7*20,4*20,255,tree[2],vp[2]);
                  putimage(13*20,5*20,255,tree[1],vp[2]);
             end;
              waitvbl;
              move (mem[vp[2]:0],mem[vga:0],64000);

      if getchar(c)=true then c:=#27;
      if morder=10 then if mrow>62 then c:=#27;

     until c=#27;
     c:=' ';

     for x:=0 to 2 do killimage(tree[x]);
     for x:=0 to 3 do killimage(right[x]);
     for x:=0 to 3 do killimage(left[x]);
     for x:=0 to 3 do killimage(down[x]);
     for x:=0 to 3 do killimage(up[x]);
     for x:=0 to 3 do killimage(hit[x]);
     for x:=0 to 3 do killimage(sleep[x]);
     for x:=0 to 3 do killimage(blob[x]);
     for x:=0 to 1 do killimage(sea[x]);
     for x:=0 to 1 do killimage(sun[x]);
     for x:=0 to 2 do killimage(land[x]);

     loadpcx ('gfx.pcx',vp[1]);
     getimage (100,60,300,180,credits,vp[1]);
     cls (152,vp[2]);
     putimage (60,40,255,credits,vp[2]);
     move (mem[vp[2]:0],mem[vga:0],64000);

     repeat if getchar(c)=true then c:=#27;
     until c=#27;

     killimage(credits);

     closevirt;
     video_mode ( 03);

     if muzak=1 then
     begin
     stopmusic;
     stopoutput;
     unloadmodule;
     freemse;
     end;

     writeln;
     writeln ('Music    Djamm');
     writeln ('Graphics Iceball');
     writeln ('Code     Psychic Symphony');
     writeln;
     writeln ('Arf!Studios');
     writeln ('Dreamhack''98');
end.
