/* by Paul Falstad */
/* vulgarities edited out */

#define WIPECOUNT 35
struct RastPort *MaskRast;

LoadPict(name,WipeScreen,wipesel,fadeflag)
struct Screen *WipeScreen;
char *name;
int wipesel,fadeflag;
{
int t0,whichwipe;
struct BitMap *WipeMap,*SetupMask(),*OldMap,*SetupOld();
struct ILBM_info *info;
static UWORD oldcmap[32];
static BOOL RandMap[WIPECOUNT];
static int randcount = 1;

info = read_iff(name,NULL);
if (info == NULL)
   return(NULL);

if (wipesel == -1)
   {
   if (--randcount == 0)
      {
      for (t0 = 0; t0 != WIPECOUNT; t0++)
         RandMap[t0] = FALSE;
      randcount = WIPECOUNT;
      }

   while(RandMap[whichwipe = rand() % WIPECOUNT])
      ;

   RandMap[whichwipe] = TRUE;
   }
else
   whichwipe = wipesel;

WipeMap = SetupMask();
OldMap = SetupOld();

GetCols(&WipeScreen->ViewPort,&oldcmap[0]);
if (!(rand() % 3) && fadeflag)
   {
   FadeOut(&WipeScreen->ViewPort,&oldcmap[0]);
   SetRast(&WipeScreen->RastPort,0L);
   }
BltBitMap(WipeScreen->RastPort.BitMap,0L,0L,OldMap,0L,0L,320L,200L,0xC0L,
	0x1fL,0L);

for (t0 = 0; t0 != 64; t0++)
   {
   Wipe(WipeScreen->RastPort.BitMap,&info->bitmap,WipeMap,OldMap,t0,whichwipe);
   FadeColors(&WipeScreen->ViewPort,oldcmap,&info->cmap[0],t0);
   }

free_planes(&info->bitmap);
FreeOld(OldMap);
}

struct BitMap *SetupMask()
{
static struct BitMap MyBitMap;
static BOOL Inited = FALSE;

if (!Inited)
   {
   InitBitMap(&MyBitMap,1L,320L,200L);
   Inited = TRUE;
   if ((MyBitMap.Planes[0] = (PLANEPTR) AllocRaster(320L,200L)) == NULL)
      exit(0L);
   }

return(&MyBitMap);
}

struct BitMap *SetupOld()
{
static struct BitMap MyBitMap;
static BOOL Inited = FALSE;
int t0;

   if (!Inited)
      {
      InitBitMap(&MyBitMap,5L,320L,200L);
      Inited = TRUE;
      }
   for (t0 = 0; t0 != 5; t0++)
      if ((MyBitMap.Planes[t0] = (PLANEPTR) AllocRaster(320L,200L)) == NULL)
         exit(0L);

return(&MyBitMap);
}

FreeOld(map)
struct BitMap *map;
{
int t0;

   for (t0 = 0; t0 != 5; t0++)
      FreeRaster(map->Planes[t0],320L,200L);
}

GetCols(vport,cmap)
UWORD *cmap;
struct ViewPort *vport;
{
long t0;

   for (t0 = 0; t0 != 32; t0++)
      cmap[t0] = GetRGB4(vport->ColorMap,t0);
}

FadeOut(vport,cmap)
UWORD *cmap;
struct ViewPort *vport;
{
long r,g,b,col;
int or,og,ob;
int nfix;
int step;

   for (step = 0; step != 32; step++)
      {
      Delay(1L);
      nfix = 31-step;
      for (col = 0; col != 32; col++)
         {
         r = (nfix * ((cmap[col] >> 8) & 0x0f));
         g = (nfix * ((cmap[col] >> 4) & 0x0f));
         b = (nfix * ((cmap[col]) & 0x0f));
         SetRGB4(vport,col,r >> 5,g >> 5,b >> 5);
         }
      }

   for (col = 0; col != 32; col++)
      cmap[col] = 0;
}


FadeColors(vport,ocmap,ncmap,step)
int step;
BYTE *ncmap;
UWORD *ocmap;
struct ViewPort *vport;
{
long r,g,b,col;
int or,og,ob;
int ofix,nfix;

   ofix = 63-step;
   nfix = step+1;
   for (col = 0; col != 32; col++)
      {
      or = (ocmap[col] >> 8) & 0x0f;
      og = (ocmap[col] >> 4) & 0x0f;
      ob = (ocmap[col]) & 0x0f;
      r = (nfix * ((ncmap[col*3] >> 4) & 0x0f)) + or*ofix;
      g = (nfix * ((ncmap[col*3+1] >> 4) & 0x0f)) + og*ofix;
      b = (nfix * ((ncmap[col*3+2] >> 4) & 0x0f)) + ob*ofix;
      SetRGB4(vport,col,r >> 6,g >> 6,b >> 6);
      }
}

void DoTheBlitSh_t();

Wipe(dispbits,newbits,mask,oldbits,step,wipeid)
struct BitMap *oldbits,*newbits,*dispbits,*mask;
int step,wipeid; /* step 0 to 63 */
{
int plane;
static BOOL rastinited = FALSE;
static struct RastPort MyRast;

if (!rastinited)
   {
   InitRastPort(&MyRast);
   MyRast.BitMap = mask;
   SetAPen(&MyRast,1L);
   DoTmpStuff(&MyRast);
   MaskRast = &MyRast;
   rastinited = TRUE;
   }

if (step == 0)
   SetRast(&MyRast,0L);

switch(wipeid) {
 case 0:
   UpAndDownPanel(&MyRast,step);
   break;
 case 1:
   Random(&MyRast,step);
   break;
 case 2:
   LeftLinePanel(&MyRast,step);
   break;
 case 3:
   Dice(&MyRast,step);
   break;
 case 4:
   GrowBoxes(&MyRast,step);
   break;
 case 5:
   SideToSide(&MyRast,step);
   break;
 case 6:
   TwoClock(&MyRast,step);
   break;
 case 7:
   OneClock(&MyRast,step);
   break;
 case 8:
   RandomOut(&MyRast,step);
   break;
 case 9:
   Spiral(&MyRast,step);
   break;
 case 10:
   ExpandBox(&MyRast,step);
   break;
 case 11:
   Doors(&MyRast,step);
   break;
 case 12:
   WipeUp(&MyRast,step);
   break;
 case 13:
   WipeDown(&MyRast,step);
   break;
 case 14:
   WipeLeft(&MyRast,step);
   break;
 case 15:
   WipeRight(&MyRast,step);
   break;
 case 16:
   WipeDiag(&MyRast,step);
   break;
 case 17:
   TwoBox(&MyRast,step);
   break;
 case 18:
   Shades(&MyRast,step);
   break;
 case 19:
   RandomShade(&MyRast,step);
   break;
 case 20:
   SymArr(&MyRast,step);
   break;
 case 21:
   FourSweep(&MyRast,step);
   break;
 case 22:
   FourLines(&MyRast,step);
   break;
 case 23:
   HexSweep(&MyRast,step);
   break;
 case 24:
   DiagSplit(&MyRast,step);
   break;
 case 25:
   Xes(&MyRast,step);
   break;
 case 26:
   SlideBoxes(&MyRast,step);
   break;
 case 27:
   Cannon(&MyRast,step);
   break;
 case 28:
   Drip(&MyRast,step);
   break;
 case 29:
   MovingWindow(&MyRast,step);
   break;
 case 30:
   Sun(&MyRast,step);
   break;
 case 31:
   Monolith(&MyRast,step);
   break;
 case 32:
   Rain(&MyRast,step);
   break;
 case 33:
   MergeWindows(&MyRast,step);
   break;
 case 34:
   Slides(&MyRast,step);
   break;
   };

if (step == 63)
   SetRast(&MyRast,1L);

OwnBlitter();
WaitBlit();

for (plane = 4; plane >= 0; plane--)
   DoTheBlitSh_t(dispbits->Planes[plane],newbits->Planes[plane],
      mask->Planes[0],oldbits->Planes[plane]);

DisownBlitter();
}

Dice(rp,step)
struct RastPort *rp;
int step;
{
   RectFill(rp,0L,0L,step*3L,step*2L);
   RectFill(rp,0L,199L-step*2L,step*3L,199L);
   RectFill(rp,319L-step*3L,0L,319L,step*2L);
   RectFill(rp,319L-step*3L,199L-step*2L,319L,199L);
   RectFill(rp,159L-step,99L-step,159L+step,99L+step);
}

#asm
      cseg

_DoTheBlitSh_t:
      move.l 12(sp),$dff050 ; A get mask argument */
      move.l #0,$dff060  ; modulos */
      move.l #0,$dff064
      move.l #%00001111110010100000000000000000,$dff040  ; bltcon01 */
      move.l #$ffffffff,$dff044 ; first & last word masks */
      move.l 16(sp),$dff048   ; C */
      move.l 8(sp),$dff04c   ; B */
      move.l 4(sp),$dff054   ; D */
      move.w #%0011001000010100,$dff058  ;go! */
      jsr _WaitBlit
      rts

#endasm

UpAndDownPanel(rp,step)
struct RastPort *rp;
int step;
{
long t0;

   for (t0 = 0; t0 != 320; t0+=40)
      {
      RectFill(rp,t0,0L,t0+19L,step*3L+10L);
      RectFill(rp,t0+20L,189L-step*3L,t0+39L,199L);
      }
}

Random(rp,step)
struct RastPort *rp;
int step;
{
static unsigned char matx[64];
int t0,bx;
long x,y;

   if (step == 0)
      for (t0 = 0; t0 != 64; t0++)
         matx[t0] = t0;

   t0 = (rand() % (64-step))+step;
   bx = matx[t0];
   matx[t0] = matx[step];
   matx[step] = bx;
   x = (bx & 7)*40;
   y = (bx >> 3)*25;
   RectFill(rp,x,y,x+39,y+24);
}

LeftLinePanel(rp,step)
struct RastPort *rp;
int step;
{
long x,y;

   x = step*5+4;
   for (y = 0; y != 200L; y += 2)
      {
      Move(rp,0L,y);
      Draw(rp,x,y);
      Move(rp,319L-x,y+1L);
      Draw(rp,319L,y+1L);
      }
}

GrowBoxes(rp,step)
struct RastPort *rp;
int step;
{
long x,y;
int stepx,stepy;

   if ((step & 3) != 0)
      return;
   stepx = 15-(step >> 2);
   stepy = 3-(step >> 4);
   for (x = 0L; x != 320L; x += 32L)
      for (y = 0L; y != 200L; y += 8L)
         RectFill(rp,stepx+x,stepy+y,(31-stepx)+x,(7-stepy)+y);
}


SideToSide(rp,step)
struct RastPort *rp;
int step;
{
long xstep;

   if ((step & 1) != 0)
      return;
   xstep = 155-(step >> 1)*5;
   RectFill(rp,0L,0L,159L-xstep,199L);
   RectFill(rp,159L+xstep,0L,319L,199L);
}

DoTmpStuff(rp)
struct RastPort *rp;
{
static UWORD areabuffer[2000];
PLANEPTR TmpRasPlane;
static struct TmpRas MyTmpRas;
static struct AreaInfo MyAreaInfo;

InitArea(&MyAreaInfo,&areabuffer[0],800L);
rp->AreaInfo = &MyAreaInfo;
if (!(TmpRasPlane = AllocRaster(330L,210L)))
   exit(0L);
InitTmpRas(&MyTmpRas,TmpRasPlane,RASSIZE(330L,210L));
rp->TmpRas = &MyTmpRas;
}

DetachAll()
{
FreeRaster(MaskRast->TmpRas->RasPtr,330L,210L);
FreeRaster(MaskRast->BitMap->Planes[0],320L,200L);
}

int XYClock[130] = {
 0,99,-16,99,-31,97,-46,95,-61,91,-75,87,-88,82,
-101,77,-112,70,-123,63,-132,55,-140,47,-147,38,-152,29,
-156,19,-158,10,-159,0,-158, -10,-156, -19,-152, -29,-147, -38,
-140, -47,-132, -55,-123, -63,-112, -70,-101, -77,-88, -82,-75, -87,
-61, -91,-46, -95,-31, -97,-16, -99, 0, -99, 16, -99, 31, -97,
 46, -95, 61, -91, 75, -87, 88, -82, 101, -77, 112, -70, 123, -63,
 132, -55, 140, -47, 147, -38, 152, -29, 156, -19, 158, -10, 159,0,
 158,10, 156,19, 152,29, 147,38, 140,47, 132,55, 123,63,
 112,70, 101,77, 88,82, 75,87, 61,91, 46,95, 31,97,
 16,99, 0,99
   };

OneClock(rp,step)
struct RastPort *rp;
int step;
{
long step48;

   AreaMove(rp,(long) 160+XYClock[step*2],(long) 100+XYClock[step*2+1]);
   AreaDraw(rp,160L,100L);
   AreaDraw(rp,(long) 160+XYClock[step*2+2],(long) 100+XYClock[step*2+3]);
   AreaEnd(rp);
   if (step > 47)
      {
      step48 = step-48;
      RectFill(rp,0L,0L,step48*10L,step48*5L);
      RectFill(rp,0L,199L-step48*5L,step48*10L,199L);
      RectFill(rp,319L-step48*10L,0L,319L,step48*5L);
      RectFill(rp,319L-step48*10L,199L-step48*5L,319L,199L);
      }
}

RandomOut(rp,step)
struct RastPort *rp;
int step;
{
long x,y;
int i,numdots;

   if ((numdots = step*20) > 2000)
      numdots = 2000;
   for (i = 0; i != numdots; i++)
      {
      x = 160-(step*5)/2+(rand() % (step*5+1));
      y = 100-(step*25)/16+(rand() % (step*3+4));
      WritePixel(rp,x,y);
      }
   if (step > 47)
      {
      RectFill(rp,300L-10L*(step & 15),0L,319L-10L*(step & 15),199L);
      RectFill(rp,10L*(step & 15),0L,9L+10L*(step & 15),199L);
      }
}

TwoClock(rp,step)
struct RastPort *rp;
int step;
{
long line,nx,ny;
static long ox,oy;

   if (!step)
      ox = oy = 0;

   line = 8*step+4;
   if (line < 320)
      {
      nx = line;
      ny = 0;
      }
   else
      {
      nx = 319;
      ny = line-320;
      }

   AreaMove(rp,ox,oy);
   AreaDraw(rp,nx,ny);
   AreaDraw(rp,160L,100L);
   AreaMove(rp,319-ox,199-oy);
   AreaDraw(rp,319-nx,199-ny);
   AreaDraw(rp,159L,99L);
   AreaEnd(rp);
   ox = nx;
   oy = ny;
}

ExpandBox(rp,step)
struct RastPort *rp;
int step;
{
int x,y;

   x = (5*step)/2;
   y = (25*step)/16;
   RectFill(rp,(long) (160-x),(long) (100-y),(long) (160+x),(long) (100+y));
}

Doors(rp,step)
struct RastPort *rp;
int step;
{
long doorx,doory;

   doorx = 159-(5*(63-step))/2;
   doory = (63-step)/2;
   AreaMove(rp,0L,0L);
   AreaDraw(rp,doorx,doory);
   AreaDraw(rp,doorx,199-doory);
   AreaDraw(rp,0L,199L);
   AreaEnd(rp);
   AreaMove(rp,319L,0L);
   AreaDraw(rp,319-doorx,doory);
   AreaDraw(rp,319-doorx,199-doory);
   AreaDraw(rp,319L,199L);
   AreaEnd(rp);
}

Spiral(rp,step)
struct RastPort *rp;
int step;
{
int bx;
long x,y;
static int spiral[64] = {
   0,1,2,3,4,5,6,7,15,23,31,39,47,55,63,
   62,61,60,59,58,57,56,48,40,32,24,16,8,
   9,10,11,12,13,14,22,30,38,46,54,53,52,
   51,50,49,41,33,25,17,18,19,20,21,29,37,
   45,44,43,42,34,26,27,28,36,35
   };

   bx = spiral[step];
   x = (bx & 7)*40;
   y = (bx >> 3)*25;
   RectFill(rp,x,y,x+39,y+24);
}

WipeUp(rp,step)
struct RastPort *rp;
int step;
{
long y;

   y = (step * 200) / 65;
   RectFill(rp,0L,196L-y,319L,199L-y);
}

WipeDown(rp,step)
struct RastPort *rp;
int step;
{
long y;

   y = (step * 200) / 64;
   RectFill(rp,0L,y,319L,y+3L);
}

WipeRight(rp,step)
struct RastPort *rp;
int step;
{
   RectFill(rp,step*5L,0L,step*5L+4L,199L);
}

WipeLeft(rp,step)
struct RastPort *rp;
int step;
{
   RectFill(rp,315L-step*5L,0L,319L-step*5L,199L);
}

WipeDiag(rp,step)
struct RastPort *rp;
int step;
{
long x,y;

   x = 10*(step+1);
   y = 9*(step+1);
   AreaMove(rp,0L,0L);
   if (x < 320)
      AreaClip(rp,x,0L);
   else
      {
      AreaClip(rp,319L,0L);
      AreaClip(rp,319L,y-287L);
      }
   if (y < 200)
      AreaClip(rp,0L,y);
   else
      {
      AreaClip(rp,x-221L,199L);
      AreaClip(rp,0L,199L);
      }
   AreaEnd(rp);
}

TwoBox(rp,step)
struct RastPort *rp;
int step;
{
long x,y;

   x = (step * 79) / 63;
   y = (step * 99) / 63;
   RectFill(rp,79L-x,99L-y,80L+x,100L+y);
   RectFill(rp,239L-x,99L-y,240L+x,100L+y);
}

Shades(rp,step)
struct RastPort *rp;
int step;
{
long x,y;

   for (x = 0; x != 320; x += 64)
      for (y = 0; y != 200; y += 50)
         {
         Move(rp,x+step,y);
         Draw(rp,x+step,y+24L);
         Move(rp,x+63-step,y+25L);
         Draw(rp,x+63-step,y+49L);
         }
}

RandomShade(rp,step)
struct RastPort *rp;
int step;
{
static unsigned char matx[16];
int t0,bx,num;
static long x,y;

   if (step == 0)
      for (t0 = 0; t0 != 16; t0++)
         matx[t0] = t0;
   if ((step & 3) == 0)
      {
      num = step/4;
      t0 = (rand() % (16-num))+num;
      bx = matx[t0];
      matx[t0] = matx[num];
      matx[num] = bx;
      x = (bx & 3)*80;
      y = (bx >> 2)*50;
      }
   step &= 3;
   RectFill(rp,x+step*20L,y,x+19L+step*20L,y+49L);
}

SymArr(rp,step)
struct RastPort *rp;
int step;
{
long x,y;

   x = 5*step;
   if (x < 160)
      {
      y = (100*x)/160;
      AreaMove(rp,0L,99L-y);
      AreaDraw(rp,x,99L);
      AreaDraw(rp,0L,100L+y);
      AreaMove(rp,319L,99L-y);
      AreaDraw(rp,319L-x,99L);
      AreaDraw(rp,319L,100L+y);
      AreaEnd(rp);
      }
   else
      {
      RectFill(rp,0L,0L,x-160L,199L);
      RectFill(rp,479L-x,0L,319L,199L);
      AreaMove(rp,x-160L,0L);
      AreaDraw(rp,x,99L);
      AreaDraw(rp,x-160L,199L);
      AreaEnd(rp);
      AreaMove(rp,479L-x,0L);
      AreaDraw(rp,319L-x,99L);
      AreaDraw(rp,479L-x,199L);
      AreaEnd(rp);
      }
}

AreaClip(rp,x,y)
long x,y;
struct RastPort *rp;
{
   if (x > 319)
      x = 319;
   if (y > 199)
      y = 199;
   if (x < 0)
      x = 0;
   if (y < 0)
      y = 0;
   AreaDraw(rp,x,y);
}

FourSweep(rp,step)
struct RastPort *rp;
int step;
{
static long x1,y1;
long x2,y2;

   if (step == 0)
      x1 = y1 = 0;
   x2 = (step+1)*5-1;
   y2 = ((step+1)*200)/64-1;
   AreaMove(rp,x1,0L);
   AreaDraw(rp,x2,0L);
   AreaDraw(rp,319L-x2,199L);
   AreaDraw(rp,319L-x1,199L);
   AreaMove(rp,0L,199L-y1);
   AreaDraw(rp,0L,199L-y2);
   AreaDraw(rp,319L,y2);
   AreaDraw(rp,319L,y1);
   AreaEnd(rp);
   x1 = x2;
   y1 = y2;
}

HexSweep(rp,step)
struct RastPort *rp;
int step;
{
long x,y,xa,ya;

   xa = (step * 79) / 64;
   ya = (step * 49) / 64;
   for (x = 0; x != 320; x += 80)
      for (y = 0; y != 200; y += 50)
         {
         RectFill(rp,x,y,x+79L-xa,y+ya);
         RectFill(rp,x+xa,y+49L-ya,x+79L,y+49L);
         }
}

FourLines(rp,step)
struct RastPort *rp;
int step;
{
long z1,z2;
int step8;

   if (step & 1)
      return;
   step8 = (step & 0x0f)/2;
   switch (step >> 4)
      {
      case 0:
      case 1:
         step8 = (step & 0x1f)/2;
         z1 = 20*step8;
         for (z2 = 0; z2 != 20; z2 += 2)
            {
            Move(rp,z1+z2,0L);
            Draw(rp,z1+z2,199L);
            }
         break;
      case 2:
         z1 = 25*step8;
         for (z2 = (step8 & 1); z2 <= 25; z2 += 2)
            {
            Move(rp,0L,z1+z2);
            Draw(rp,319L,z1+z2);
            }
         break;
      case 3:
         z1 = 40*step8;
         for (z2 = 0; z2 != 40; z2 += 2)
            {
            Move(rp,319L-(z1+z2),0L);
            Draw(rp,319L-(z1+z2),199L);
            }
         break;
      }
}

DiagSplit(rp,step)
struct RastPort *rp;
int step;
{
int bx;
long x,y;
static int split[64] = {
   56,49,42,35,28,21,14,7,
   6,13,20,27,34,41,48,
   40,33,26,19,12,5,
   4,11,18,25,32,
   24,17,10,3,
   2,9,16,
   8,1,
   0,
   63,
   62,55,
   47,54,61,
   60,53,46,39,
   31,38,45,52,59,
   58,51,44,37,30,23,
   15,22,29,36,43,50,57
   };

   bx = split[step];
   x = (bx & 7)*40;
   y = (bx >> 3)*25;
   RectFill(rp,x,y,x+39,y+24);
}

Xes(rp,step)
struct RastPort *rp;
int step;
{
static unsigned char matx[64];
int t0,bx;
long x,y;

   if (step == 0)
      for (t0 = 0; t0 != 64; t0++)
         matx[t0] = t0;
   t0 = (rand() % (64-step))+step;
   bx = matx[t0];
   matx[t0] = matx[step];
   matx[step] = bx;
   x = (bx & 7)*40;
   y = (bx >> 3)*25;
   AreaMove(rp,x,y);
   AreaClip(rp,x+4L,y);
   AreaClip(rp,x+19L,y+10L);
   AreaClip(rp,x+34L,y);
   AreaClip(rp,x+39L,y);
   AreaClip(rp,x+39L,y+3L);
   AreaClip(rp,x+25L,y+12L);
   AreaClip(rp,x+39L,y+21L);
   AreaClip(rp,x+39L,y+24L);
   AreaClip(rp,x+34L,y+24L);
   AreaClip(rp,x+19L,y+14L);
   AreaClip(rp,x+4L,y+24L);
   AreaClip(rp,x,y+24L);
   AreaClip(rp,x,y+21L);
   AreaClip(rp,x+15L,y+12L);
   AreaClip(rp,x,y+3L);
   AreaEnd(rp);
   if (step >= 32)
      RectFill(rp,(step-32)*10L,0L,(step-32)*10L+9L,199L);
}

SlideBoxes(rp,step)
struct RastPort *rp;
int step;
{
long x,y,xa,ya;

   xa = (step * 79)/63;
   ya = (step * 49)/63;
   for (x = 0; x != 320; x += 80)
      for (y = 0; y != 200; y += 50)
         RectFill(rp,x,y,x+xa,y+ya);
}

Cannon(rp,step)
struct RastPort *rp;
int step;
{
int sstep,tstep;

   sstep = step & 0x0f;
   switch (step >> 4)
      {
      case 0:
         RectFill(rp,206L,96L,216L,103L);
         RectFill(rp,sstep*4L,90L,sstep*4L+3L,109L);
         break;
      case 1:
         RectFill(rp,64L+sstep*4L,95L,sstep*4L+67L,104L);
         break;
      case 2:
         SetAPen(rp,0L);
         RectFill(rp,128L,99L,205L,100L);
         RectFill(rp,124L-sstep*4L,95L,127L-sstep*4L,104L);
         SetAPen(rp,1L);
         RectFill(rp,126L+sstep*5L,99L,130L+sstep*5L,100L);
         break;
      case 3:
         for (tstep = 0; tstep != 40; tstep++)
            {
            Move(rp,206L,99L);
            Draw(rp,rand() % 320L,rand() % 200L);
            }
         if (sstep > 7)
            {
            tstep = sstep-8;
            RectFill(rp,206L-(tstep*206L)/7L,99L-(tstep*99L)/7L,
               206L+(tstep*114L)/7L,100L+(tstep*99L)/7L);
            }
         break;
      }
}

Drip(rp,step)
struct BitMap *rp;
int step;
{
static long y1[8] = {450,300,700,500,199,400,340,210};
long y;
int t0;

   for (t0 = 0; t0 != 8; t0++)
      {
      y = (y1[t0]*step)/63;
      if (y > 199)
         y = 199;
      RectFill(rp,t0*40L,0L,t0*40L+39L,y);
      }
}

MovingWindow(rp,step)
struct BitMap *rp;
int step;
{
long x,y;

   if (step < 48)
      {
      SetRast(rp,0L);
      x = (140L*step)/47;
      y = (80L*step)/47;
      RectFill(rp,x,y,x+39L,y+39L);
      }
   else
      {
      x = ((step-48)*140L)/7L+20L;
      y = ((step-48)*80L)/7L+20L;
      RectFill(rp,160L-x,100L-y,159L+x,99L+y);
      }
}

int RoughSin(ang)
int ang;
{
static int sintab[8] = {
   1,7,8,5,-1,-7,-8,-5
   };

   return(sintab[ang & 0x07]);
}

Monolith(rp,step)
struct RastPort *rp;
int step;
{
long maxy,x1,x2,y;

   SetRast(rp,0L);
   maxy = (105L*step)/63L;
   x1 = (150L*step)/63L;
   x2 = (165L*step)/63L;
   y = (maxy*RoughSin(step+4))/8;
   AreaMove(rp,159L,99L);
   AreaClip(rp,159L-x1,99L-y);
   AreaClip(rp,159L+x1,99L-y);
   AreaClip(rp,159L+x2,100L+y);
   AreaClip(rp,159L-x2,100L+y);
   AreaClip(rp,159L-x1,99L-y);
   AreaEnd(rp);
}

Sun(rp,step)
struct RastPort *rp;
int step;
{
int t0;
long x,y;

   x = (159L*step)/63;
   y = (99L*step)/63;
   SetRast(rp,0L);
   for (t0 = 0; t0 != 50; t0++)
      {
      Move(rp,159L,99L);
      Draw(rp,rand() % 320L,rand() % 200L);
      }
   RectFill(rp,159L-x,99L-y,160L+x,100L+y);
}

MergeWindows(rp,step)
struct RastPort *rp;
int step;
{
long x,ss;

   SetRast(rp,0L);
   SetDrMd(rp,COMPLEMENT);
   x = (130L*step)/47L;
   if (step < 48)
      {
      RectFill(rp,x,65L,x+59L,114L);
      RectFill(rp,260L-x,85L,319L-x,134L);
      }
   if (step > 47 && step < 58)
      {
      ss = step-48;
      RectFill(rp,130L,65L+ss,189L,114L+ss);
      RectFill(rp,130L,85L-ss,189L,134L-ss);
      }
   if (step > 47)
      {
      ss = (99L*(step-48))/15L;
      RectFill(rp,0L,0L,319L,ss);
      RectFill(rp,0L,199L-ss,319L,199L);
      }
   SetDrMd(rp,JAM1);
}

Slides(rp,step)
struct RastPort *rp;
int step;
{
static int right,brick;

   if (step == 0)
      {
      right = 11;
      brick = 0;
      }
   else
      {
      brick++;
      if (brick != right)
         {
         SetAPen(rp,0L);
         RectFill(rp,29L*brick-29L,0L,29L*brick-1L,199L);
         }
      else
         {
         right--; 
         brick = 0;
         }
      }
   SetAPen(rp,1L);
   RectFill(rp,29L*brick,0L,29L*brick+28L,199L);
}

Rain(rp,step)
struct RastPort *rp;
int step;
{
static unsigned char matx[64];
int t0,t1,bx;
long x,y;

   if (step == 0)
      for (t0 = 0; t0 != 64; t0++)
         matx[t0] = 0;

   for (t0 = 0; t0 != 8; t0++)
      for (t1 = 6; t1 >= 0; t1--)
         {
         bx = t0+t1*8;
         if (matx[bx] == 1 && matx[bx+8] == 0)
            {
            x = t0*40;
            y = t1*25;
            SetAPen(rp,0L);
            RectFill(rp,x,y,x+39L,y+24L);
            matx[bx] = 0;
            matx[bx+8] = 1;
            SetAPen(rp,1L);
            RectFill(rp,x,y+25L,x+39L,y+49L);
            }
         }
   while (matx[t0 = (rand() % 8)]);
   matx[t0] = 1;
   RectFill(rp,t0*40L,0L,t0*40L+39L,24L);
}
