/* mywipe.h by Paul Falstad */

extern long numplanes;
long mx,my,cx,cy,bx,by,topcol,yadd,bpr,D4Store,A5Store;
long rsa[32],gsa[32],bsa[32],rsb[32],gsb[32],bsb[32];
#include "wipecount.h"
#include "jiff.h"
#define CX(X) ((X) << cx)
#define CY(Y) ((Y) << cy)
struct RastPort *MaskRast = 0;
struct BitMap *OldMap,*NewMap;
WORD BMod;
PLANEPTR AllocClearRaster();

struct BitMap *SetupMaps(info,wn)
struct ILBM_info *info;
int wn;
{
static struct BitMap MBitMap,OBitMap,NBitMap;
static struct RastPort MRast;
int t0,neww,newh;

   InitBitMap(&NBitMap,numplanes,mx,my);
   for (t0 = 0; t0 != numplanes; t0++)
      if (!(NBitMap.Planes[t0] = AllocClearRaster(mx,my)))
         {
         while (t0)
            FreeRaster(NBitMap.Planes[--t0],mx,my);
         free_planes(&info->bitmap);
         TheEnd();
         }
   NewMap = &NBitMap;
   neww = info->header.w;
   newh = info->header.h;
   if (neww > mx)
      neww = mx;
   if (newh > my)
      newh = my;
   BltBitMap(&info->bitmap,0L,0L,NewMap,((long) mx-neww) >> 1,
         ((long) my-newh) >> 1,(long) neww,(long) newh,0xc0L,
         (1L << info->header.nPlanes)-1L,0L);
   WaitBlit();
   free_planes(&info->bitmap);
   InitBitMap(&MBitMap,1L,mx,my);
   if ((MBitMap.Planes[0] = (PLANEPTR) AllocRaster(mx,my)) == NULL)
      {
      for (t0 = 0; t0 != numplanes; t0++)
         FreeRaster(NBitMap.Planes[t0],mx,my);
      TheEnd();
      }
   InitRastPort(&MRast);
   MRast.BitMap = &MBitMap;
   SetAPen(&MRast,1L);
   DoTmpStuff(&MRast);
   MaskRast = &MRast;
   InitBitMap(&OBitMap,numplanes,mx,my);
   for (t0 = 0; t0 != numplanes; t0++)
      if ((OBitMap.Planes[t0] = (PLANEPTR) AllocRaster(mx,my)) == NULL)
         {
         while (t0)
            FreeRaster(OBitMap.Planes[--t0],mx,my);
         for (t0 = 0; t0 != numplanes; t0++)
            FreeRaster(NBitMap.Planes[t0],mx,my);
         FreeRaster(MBitMap.Planes[0],mx,my);
         TheEnd();
         }
   OldMap = &OBitMap;
   printf("wipe #%d\n",wn);
}

LoadPict(name,WipeScreen,wipesel,cycsel,fadeflag,exclmap,hires,lace)
struct Screen *WipeScreen;
char *name;
int wipesel,fadeflag,cycsel;
BOOL exclmap[WIPECOUNT],hires,lace;
{
int t0,whichwipe,numleft;
struct ILBM_info *info;
static UWORD oldcmap[32];
static BOOL RandMap[WIPECOUNT];
struct BitMap *ScrnMap;
UWORD startword;
long modes;

if (hires) { mx = 768; cx = 1; topcol = 16; }
      else { mx = 384; cx = 0; topcol = 32; }
if (lace)  { my = 480; cy = 1; } else { my = 240; cy = 0; }
startword = ((lace) ? 0x7800 : 0x3c00) | ((hires) ? 0x0030 : 0x0018);
bpr = mx/8;

bx = mx-1; by = my-1;
modes = WipeScreen->ViewPort.Modes & ~(HAM | EXTRA_HALFBRITE);
StopCringe();
info = read_iff(name,NULL);
if (info == NULL)
   return(NULL);

if (info->camg)
   modes = info->camg;

if (wipesel == -1)
   {
   for (t0 = numleft = 0; t0 != WIPECOUNT; t0++)
      if (!RandMap[t0] && !exclmap[t0])
         numleft++;
   if (!numleft)
      for (t0 = 0; t0 != WIPECOUNT; t0++)
         RandMap[t0] = FALSE;
   do
      whichwipe = rand() % WIPECOUNT;
   while (RandMap[whichwipe] || exclmap[whichwipe]);

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

SetupMaps(info,whichwipe);

GetCols(&WipeScreen->ViewPort,&oldcmap[0]);
for (t0 = 0; t0 != topcol*3; t0++)
   info->cmap[t0] >>= 4;

if (!(rand() % 3) && fadeflag)
   {
   if (WipeScreen->ViewPort.Modes & HAM)
      WipeOut(&WipeScreen->ViewPort,&WipeScreen->RastPort,&oldcmap[0],
         info->cmap,mx,my,(int) topcol);
   else
      FadeOut(&WipeScreen->ViewPort,&oldcmap[0],info->cmap);
   SetRast(&WipeScreen->RastPort,0L);
   WipeScreen->ViewPort.Modes = modes;
   }
else
   WipeScreen->ViewPort.Modes = modes;
MakeScreen(WipeScreen);
RethinkDisplay();
BltBitMap(WipeScreen->RastPort.BitMap,
   0L,0L,OldMap,0L,0L,mx,my,0xC0L,(numplanes == 6) ? 0x3fL : 0x0fL,0L);
yadd = BMod = 0;
ScrnMap = WipeScreen->RastPort.BitMap;
for (t0 = 0; t0 != 64; t0++)
   {
   Wipe(ScrnMap,t0,whichwipe,startword);
   FadeColors(&WipeScreen->ViewPort,oldcmap,&info->cmap[0],t0);
   }
FreeAll();
if (cycsel)
   CycleScreen(WipeScreen,info);
}

FreeAll()
{
int t0;

   for (t0 = 0; t0 != numplanes; t0++)
      FreeRaster(OldMap->Planes[t0],mx,my);
   for (t0 = 0; t0 != numplanes; t0++)
      FreeRaster(NewMap->Planes[t0],mx,my);
   FreeRaster(MaskRast->TmpRas->RasPtr,mx+10L,my+10L);
   FreeRaster(MaskRast->BitMap->Planes[0],mx,my);
}

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

   for (t0 = 0; t0 != topcol; t0++)
      {
      cmap[t0] = GetRGB4(vport->ColorMap,t0);
      rsa[t0] = ((cmap[t0] >> 8) & 0x0f) << 6;
      gsa[t0] = ((cmap[t0] >> 4) & 0x0f) << 6;
      bsa[t0] = ((cmap[t0]) & 0x0f) << 6;
      rsb[t0] = gsb[t0] = bsb[t0] = 0;
      }
}

FadeOut(vport,cmap,ncmap)
UWORD *cmap;
UBYTE *ncmap;
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 != topcol; 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 != topcol; col++)
      {
      or = ncmap[col*3]; og = ncmap[col*3+1]; ob = ncmap[col*3+2];
      cmap[col] = (or << 8) | (og << 4) | ob;
      rsa[col] = or << 6;
      gsa[col] = og << 6;
      bsa[col] = ob << 6;
      }
}

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

   for (col = cz = 0; col != topcol; col++,cz += 3)
      {
      rsa[col] -= (ocmap[col] >> 8) & 0x0f;
      gsa[col] -= (ocmap[col] >> 4) & 0x0f;
      bsa[col] -= (ocmap[col]) & 0x0f;
      rsb[col] += ncmap[cz];
      gsb[col] += ncmap[cz+1];
      bsb[col] += ncmap[cz+2];
      SetRGB4(vport,col,(rsa[col]+rsb[col]) >> 6,
                        (gsa[col]+gsb[col]) >> 6,(bsa[col]+bsb[col]) >> 6);
      }
}

void DoTheBlitSh_t(),Sh_tLoop();

Wipe(dispbits,step,wipeid,startword)
struct BitMap *dispbits;
int step,wipeid; /* step 0 to 63 */
UWORD startword;
{
int plane;
static BOOL rastinited = FALSE;
PLANEPTR *p1,*p2,p3,*p4;

if (step == 0)
   SetRast(MaskRast,0L);

switch(wipeid) {
 case 0:
   UpAndDownPanel(MaskRast,step);
   break;
 case 1:
   Random(MaskRast,step);
   break;
 case 2:
   LeftLinePanel(MaskRast,step);
   break;
 case 3:
   Dice(MaskRast,step);
   break;
 case 4:
   GrowBoxes(MaskRast,step);
   break;
 case 5:
   SideToSide(MaskRast,step);
   break;
 case 6:
   TwoClock(MaskRast,step);
   break;
 case 7:
   OneClock(MaskRast,step);
   break;
 case 8:
   RandomOut(MaskRast,step);
   break;
 case 9:
   Spiral(MaskRast,step);
   break;
 case 10:
   ExpandBox(MaskRast,step);
   break;
 case 11:
   Doors(MaskRast,step);
   break;
 case 12:
   WipeUp(MaskRast,step);
   break;
 case 13:
   WipeDown(MaskRast,step);
   break;
 case 14:
   WipeLeft(MaskRast,step);
   break;
 case 15:
   WipeRight(MaskRast,step);
   break;
 case 16:
   WipeDiag(MaskRast,step);
   break;
 case 17:
   TwoBox(MaskRast,step);
   break;
 case 18:
   Shades(MaskRast,step);
   break;
 case 19:
   RandomShade(MaskRast,step);
   break;
 case 20:
   SymArr(MaskRast,step);
   break;
 case 21:
   FourSweep(MaskRast,step);
   break;
 case 22:
   FourLines(MaskRast,step);
   break;
 case 23:
   HexSweep(MaskRast,step);
   break;
 case 24:
   DiagSplit(MaskRast,step);
   break;
 case 25:
   Xes(MaskRast,step);
   break;
 case 26:
   SlideBoxes(MaskRast,step);
   break;
 case 27:
   Cannon(MaskRast,step);
   break;
 case 28:
   Drip(MaskRast,step);
   break;
 case 29:
   MovingWindow(MaskRast,step);
   break;
 case 30:
   Sun(MaskRast,step);
   break;
 case 31:
   Monolith(MaskRast,step);
   break;
 case 32:
   Rain(MaskRast,step);
   break;
 case 33:
   MergeWindows(MaskRast,step);
   break;
 case 34:
   Slides(MaskRast,step);
   break;
 case 35:
   RandomDown(MaskRast,step);
   break;
 case 36:
   Stretch(MaskRast,step);
   break;
 case 37:
   ExpandSlide(MaskRast,step);
   break;
 case 38:
   SlideSlabs(MaskRast,step);
   break;
 case 39:
   Checkerboard(MaskRast,step);
   break;
 case 40:
   MiniRandom(MaskRast,step);
   break;
 case 41:
   ConcentricRectangles(MaskRast,step);
   break;
 case 42:
   Cloverleaf(MaskRast,step);
   break;
 case 43:
   Cloverleaf2(MaskRast,step);
   break;
 case 44:
   ConcentricRectangles2(MaskRast,step);
   break;
   };

if (step == 63)
   {
   SetRast(MaskRast,1L);
   yadd = 0;
   }
p1 = &dispbits->Planes[numplanes];
p2 = &NewMap->Planes[numplanes];
p3 = MaskRast->BitMap->Planes[0];
p4 = &OldMap->Planes[numplanes];

   OwnBlitter();
   WaitBlit();
   Forbid();
   DoTheBlitSh_t(p1,p2,p3,p4,startword,(int) (numplanes-1));
   Permit();
   DisownBlitter();
}

#asm
      cseg
_DoTheBlitSh_t:
      move.l d4,_D4Store
      move.l a5,_A5Store
      clr.l d4
      move.w 22(sp),d4     ;# planes
      movea.l 4(sp),a2     ;&Dest
      movea.l 8(sp),a3     ;&New
      movea.l 16(sp),a5    ;&Old
_Sh_tLoop:
      move.l 12(sp),$dff050 ; A get mask argument
      clr.w $dff060  ; modulos
      move.w _BMod,$dff062   ;BMod
      clr.l $dff064
      move.l #$0fca0000,$dff040 ;bltcon01
      move.l -(a3),d0        ; B
      add.l _yadd,d0        ; add yadd
      move.l d0,$dff04c      ; B
      move.l #$ffffffff,$dff044 ; first & last word masks
      move.l -(a5),$dff048    ;C 
      move.l -(a2),$dff054   ; D

      move.w #$8400,$dff096  ; set Blitter Nasty
      move.w 20(sp),$dff058  ; go! (should be $3c18) AB+nAC
      jsr _WaitBlit
      move.w #$0400,$dff096  ; Blitter Nice
      dbf.w d4,_Sh_tLoop
      move.l _D4Store,d4
      movea.l _A5Store,a5
      rts

#endasm

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

InitArea(&MyAreaInfo,&areabuffer[0],50L);
rp->AreaInfo = &MyAreaInfo;
if (!(TmpRasPlane = AllocRaster(mx+10L,my+10L)))
   TheEnd();
InitTmpRas(&MyTmpRas,TmpRasPlane,RASSIZE(mx+10L,my+10L));
rp->TmpRas = &MyTmpRas;
}

PLANEPTR AllocClearRaster(xm,ym)
long xm,ym;
{
PLANEPTR pl;

   pl = AllocMem(xm/8L*ym,MEMF_CHIP|MEMF_CLEAR);
   if (!pl)
      return(0L);
   return(pl);
}

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

   t3 = (step*by)/63;
   for (t0 = 0, t1 = 24, t2 = 48; t0 != 384; t0 += 48, t1 += 48, t2 += 48)
      {
      RectFill(rp,CX(t0),0L,CX(t1)-1L,t3);
      RectFill(rp,CX(t1),by-t3,CX(t2)-1L,by);
      }
}

Dice(rp,step)
struct RastPort *rp;
int step;
{
long s3,s2;

   s3 = bx*step/126;
   s2 = by*step/126;
   RectFill(rp,0L,0L,s3,s2);
   RectFill(rp,0L,by-s2,s3,by);
   RectFill(rp,bx-s3,0L,bx,s2);
   RectFill(rp,bx-s3,by-s2,bx,by);
   RectFill(rp,bx/2-CX(step),by/2-CY(step),bx/2+CX(step),by/2+CY(step));
}

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

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

   t0 = (rand() % (64-step))+step;
   qx = matx[t0];
   matx[t0] = matx[step];
   matx[step] = qx;
   x = CX((qx & 7)*48);
   y = CY((qx >> 3)*30);
   RectFill(rp,x,y,x+CX(48)-1L,y+CY(30)-1L);
}

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

   x = (step*bx)/63;
   for (y = 0; y != my; y += 2)
      {
      Move(rp,0L,y);
      Draw(rp,x,y);
      Move(rp,bx-x,y+1L);
      Draw(rp,bx,y+1L);
      }
}

GrowBoxes(rp,step)
struct RastPort *rp;
int step;
{
long x1,y1,x2,y2;
int stepx,stepy;

   if ((step & 3) != 0)
      return;
   stepx = 15-(step >> 2);
   stepy = 3-(step >> 4);
   for (x1 = CX(stepx), x2 = CX(32-stepx)-1; x1 < mx;
         x1 += CX(32L), x2 += CX(32L))
      for (y1 = CY(stepy), y2 = CY(8-stepy)-1; y1 < my;
            y1 += CY(8L), y2 += CY(8L))
         RectFill(rp,x1,y1,x2,y2);
}

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

   if ((step & 1) != 0)
      return;
   bx2 = bx/2;
   xstep = CX(188-(step >> 1)*6);
   RectFill(rp,0L,0L,bx2-xstep,by);
   RectFill(rp,bx2+xstep,0L,bx,by);
}

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,ccx,ccy;

   ccx = cx+1; ccy = cy+1;
   AreaMove(rp,ccx*(192L+XYClock[step*2]*191L/159),
      ccy*(120L+XYClock[step*2+1]*119L/99));
   AreaDraw(rp,mx/2,my/2);
   AreaDraw(rp,ccx*(192L+XYClock[step*2+2]*191L/159),
      ccy*(120L+XYClock[step*2+3]*119L/99));
   AreaEnd(rp);
   if (step > 47)
      {
      step48 = step-48;
      RectFill(rp,0L,0L,CX(step48*12L),CY(step48*8L));
      RectFill(rp,0L,by-CY(step48*8L),CX(step48*12L),by);
      RectFill(rp,bx-CX(step48*12L),0L,bx,CY(step48*8L));
      RectFill(rp,bx-CX(step48*12L),by-CY(step48*8L),bx,by);
      }
}

RandomOut(rp,step)
struct RastPort *rp;
int step;
{
long x,y,x1,x2,y1,y2;
int i,num;

   x1 = mx/2-CX(step*5)/2;
   x2 = CX(step*5+1);
   y1 = my/2-CY(step*25)/16;
   y2 = CY(step*3+4);
   num = 7*step;
   for (i = 0; i != num; i++)
      {
      x = x1+(rand() % x2);
      y = y1+(rand() % y2);
      WritePixel(rp,x,y);
      }
   if (step > 47)
      {
      RectFill(rp,CX(371L-12L*(step & 15)),0L,bx-CX(12L*(step & 15)),by);
      RectFill(rp,CX(12L*(step & 15)),0L,CX(12L*(1+(step & 15)))-1L,by);
      }
}

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

   if (!step)
      ox = oy = 0;

   line = (622L*step)/63L;
   if (line < 384)
      {
      nx = line;
      ny = 0;
      }
   else
      {
      nx = 383;
      ny = line-384;
      }
   AreaMove(rp,CX(ox),CY(oy));
   AreaDraw(rp,CX(nx),CY(ny));
   AreaDraw(rp,mx/2,my/2);
   AreaMove(rp,bx-CX(ox),by-CY(oy));
   AreaDraw(rp,bx-CX(nx),by-CY(ny));
   AreaDraw(rp,bx/2,by/2);
   AreaEnd(rp);
   ox = nx;
   oy = ny;
}

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

   x = step*mx/126;
   y = step*my/126;
   RectFill(rp,(long) (mx/2-x),(long) (my/2-y),
               (long) (mx/2+x),(long) (my/2+y));
}

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

   doorx = CX(step*191/63);
   doory = CY(63-step);
   AreaMove(rp,0L,0L);
   AreaDraw(rp,doorx,doory);
   AreaDraw(rp,doorx,by-doory);
   AreaDraw(rp,0L,by);
   AreaEnd(rp);
   AreaMove(rp,bx,0L);
   AreaDraw(rp,bx-doorx,doory);
   AreaDraw(rp,bx-doorx,by-doory);
   AreaDraw(rp,bx,by);
   AreaEnd(rp);
}

Spiral(rp,step)
struct RastPort *rp;
int step;
{
int qx;
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
   };

   qx = spiral[step];
   x = CX((qx & 7)*48);
   y = CY((qx >> 3)*30);
   RectFill(rp,x,y,x+CX(48)-1L,y+CY(30)-1L);
}

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

   y = (step * by) / 63;
   yadd = -(by-y)*bpr;
   RectFill(rp,0L,by-y,bx,by);
}

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

   y = (step * my) / 63;
   yadd = (by-y)*bpr;
   RectFill(rp,0L,0L,bx,y);
}

WipeRight(rp,step)
struct RastPort *rp;
int step;
{
   RectFill(rp,CX(step*6L),0L,CX((step+1)*6L)-1,by);
}

WipeLeft(rp,step)
struct RastPort *rp;
int step;
{
   RectFill(rp,mx-CX((step+1)*6L),0L,bx-CX(step*6L),by);
}

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

   x = 12*(step+1);
   y = 8*(step+1);
   AreaMove(rp,0L,0L);
   if (x < 384)
      AreaClip(rp,CX(x),0L);
   else
      {
      AreaClip(rp,bx,0L);
      AreaClip(rp,bx,CY(y-255L)); /* y = 8/12 x */
      }
   if (y < 240)
      AreaClip(rp,0L,CY(y));
   else
      {
      AreaClip(rp,CX(x-358L),by); /* x = 12/8 y */
      AreaClip(rp,0L,by);
      }
   AreaEnd(rp);
}

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

   x = (step * 95) / 63;
   y = (step * 119) / 63;
   RectFill(rp,CX(95L-x),CY(119L-y),CX(96L+x),CY(120L+y));
   RectFill(rp,CX(287L-x),CY(119L-y),CX(288L+x),CY(120L+y));
}

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

   for (x = 0; x != 384; x += 64)
      for (y = 0; y != 240; y += 60)
         {
         Move(rp,CX(x+step),CY(y));
         Draw(rp,CX(x+step),CY(y+30L)-1L);
         Move(rp,CX(x+64-step)-1L,CY(y+30L));
         Draw(rp,CX(x+64-step)-1L,CY(y+60L)-1L);
         if (cx == 1)
            {
            Move(rp,CX(x+step)+1L,CY(y));
            Draw(rp,CX(x+step)+1L,CY(y+30L)-1L);
            Move(rp,CX(x+64-step)-2L,CY(y+30L));
            Draw(rp,CX(x+64-step)-2L,CY(y+60L)-1L);
            }
         }
}

RandomShade(rp,step)
struct RastPort *rp;
int step;
{
static unsigned char matx[16];
int t0,qx,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;
      qx = matx[t0];
      matx[t0] = matx[num];
      matx[num] = qx;
      x = (qx & 3)*96;
      y = (qx >> 2)*60;
      }
   step &= 3;
   RectFill(rp,CX(x+step*24L),CY(y),CX(x+(step+1)*24L)-1L,CY(y+60L)-1L);
}

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

   x = 6*step;
   if (x < 192)
      {
      y = (120*x)/192;
      AreaMove(rp,0L,CY(119L-y));
      AreaDraw(rp,CX(x),CY(120L)-1L);
      AreaDraw(rp,0L,CY(120L+y));
      AreaMove(rp,bx,CY(119L-y));
      AreaDraw(rp,bx-CX(x),CY(120L)-1L);
      AreaDraw(rp,bx,CY(120L+y));
      AreaEnd(rp);
      }
   else
      {
      RectFill(rp,0L,0L,CX(x-192L),by);
      RectFill(rp,CX(575L-x),0L,bx,by);
      AreaMove(rp,CX(x-192L),0L);
      AreaDraw(rp,CX(x),CY(119L));
      AreaDraw(rp,CX(x-192L),by);
      AreaEnd(rp);
      AreaMove(rp,CX(575L-x),0L);
      AreaDraw(rp,bx-CX(x),CY(119L));
      AreaDraw(rp,CX(575L-x),by);
      AreaEnd(rp);
      }
}

AreaClip(rp,x,y)
long x,y;
struct RastPort *rp;
{
   if (x > bx)
      x = bx;
   if (y > by)
      y = by;
   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,x3,y3;

   if (step == 0)
      x1 = y1 = 0;
   x2 = (step+1)*6-1;
   y2 = ((step+1)*240)/64-1;
   x1 = CX(x1);   y1 = CY(y1);
   x3 = CX(x2);   y3 = CY(y2);
   AreaMove(rp,x1,0L);
   AreaDraw(rp,x3,0L);
   AreaDraw(rp,bx-x3,by);
   AreaDraw(rp,bx-x1,by);
   AreaMove(rp,0L,by-y1);
   AreaDraw(rp,0L,by-y3);
   AreaDraw(rp,bx,y3);
   AreaDraw(rp,bx,y1);
   AreaEnd(rp);
   x1 = x2;
   y1 = y2;
}

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

   xa = (step * 95) / 63;
   ya = (step * 59) / 63;
   for (x = 0; x != 384; x += 96)
      for (y = 0; y != 240; y += 60)
         {
         RectFill(rp,CX(x),CY(y),CX(x+96L-xa)-1L,CY(y+ya+1L));
         RectFill(rp,CX(x+xa),CY(y+59L-ya)-1L,CX(x+96L)-1L,CY(y+60L)-1L);
         }
}

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 = CX(24*step8);
         for (z2 = 0; z2 != CX(24); z2 += 2)
            {
            Move(rp,z1+z2,0L);
            Draw(rp,z1+z2,by);
            }
         break;
      case 2:
         z1 = CY(30*step8);
         for (z2 = 0; z2 != CY(30); z2 += 2)
            {
            Move(rp,0L,z1+z2);
            Draw(rp,bx,z1+z2);
            }
         break;
      case 3:
         z1 = CX(40*step8);
         for (z2 = 0; z2 != CX(48); z2 += 2)
            {
            Move(rp,bx-(z1+z2),0L);
            Draw(rp,bx-(z1+z2),by);
            }
         break;
      }
}

DiagSplit(rp,step)
struct RastPort *rp;
int step;
{
int qx;
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
   };

   qx = split[step];
   x = (qx & 7)*48;
   y = (qx >> 3)*30;
   RectFill(rp,CX(x),CY(y),CX(x+48)-1L,CY(y+30)-1L);
}

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

   if (step == 0)
      for (t0 = 0; t0 != 64; t0++)
         matx[t0] = t0;
   t0 = (rand() % (64-step))+step;
   qx = matx[t0];
   matx[t0] = matx[step];
   matx[step] = qx;
   x = (qx & 7)*48;
   y = (qx >> 3)*30;
   AreaMove(rp,CX(x),CY(y));
   AreaClip(rp,CX(x+5L),CY(y));
   AreaClip(rp,CX(x+23L),CY(y+12L));
   AreaClip(rp,CX(x+41L),CY(y));
   AreaClip(rp,CX(x+48L)-1L,CY(y));
   AreaClip(rp,CX(x+48L)-1L,CY(y+4L));
   AreaClip(rp,CX(x+30L),CY(y+14L));
   AreaClip(rp,CX(x+48L)-1L,CY(y+25L));
   AreaClip(rp,CX(x+48L)-1L,CY(y+30L)-1L);
   AreaClip(rp,CX(x+41L),CY(y+30L)-1L);
   AreaClip(rp,CX(x+23L),CY(y+17L));
   AreaClip(rp,CX(x+5L),CY(y+30L)-1L);
   AreaClip(rp,CX(x),CY(y+30L)-1L);
   AreaClip(rp,CX(x),CY(y+25L));
   AreaClip(rp,CX(x+18L),CY(y+14L));
   AreaClip(rp,CX(x),CY(y+4L));
   AreaEnd(rp);
   if (step >= 32)
      RectFill(rp,CX(step-32)*12L,0L,CX(step-31)*12L-1L,by);
}

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

   xa = (step * 95)/63;
   ya = (step * 59)/63;
   for (x = 0; x != 384; x += 96)
      for (y = 0; y != 240; y += 60)
         RectFill(rp,CX(x),CY(y),CX(x+xa),CY(y+ya));
}

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

   sstep = step & 0x0f;
   switch (step >> 4)
      {
      case 0:
         RectFill(rp,CX(247L),CY(115L),CX(260L)-1L,CY(125L)-1L);
         RectFill(rp,CX(sstep*5L),CY(108L),CX(sstep*5L+5L)-1L,CY(131L));
         break;
      case 1:
         RectFill(rp,CX(80L+sstep*5L),CY(114L),CX(sstep*5L+85L)-1L,CY(126L)-1L);
         break;
      case 2:
         SetAPen(rp,0L);
         RectFill(rp,CX(160L),CY(119L),CX(247L)-1L,CY(120L));
         RectFill(rp,CX(155L-sstep*5L),CY(114L),CX(159L-sstep*5L),CY(126L)-1L);
         SetAPen(rp,1L);
         RectFill(rp,CX(160L+sstep*5L),CY(119L),CX(164L+sstep*5L),CY(120L));
         break;
      case 3:
         for (tstep = 0; tstep != 40; tstep++)
            {
            Move(rp,CX(247L),CY(119L));
            Draw(rp,rand() % mx,rand() % my);
            }
         if (sstep > 7)
            {
            tstep = sstep-8;
            RectFill(rp,CX(247L-(tstep*247L)/7L),CY(119L-(tstep*119L)/7L),
               CX(247L+(tstep*137L)/7L),CY(120L+(tstep*119L)/7L));
            }
         break;
      }
}

Drip(rp,step)
struct BitMap *rp;
int step;
{
static long y1[8] = {450,310,750,600,239,400,350,270};
long y;
int t0;

   for (t0 = 0; t0 != 8; t0++)
      {
      y = CY((y1[t0]*step)/63);
      if (y > by)
         y = by;
      RectFill(rp,CX(t0*48L),0L,CY((t0+1)*48L)-1L,y);
      }
}

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

   if (step < 48)
      {
      SetRast(rp,0L);
      x = (172L*step)/47;
      y = (100L*step)/47;
      yadd = bpr*(47-step);
      RectFill(rp,CX(x),CY(y),CX(x+40)-1L,CY(y+40)-1L);
      }
   else
      {
      x = ((step-48)*172L)/15L+20L;
      y = ((step-48)*100L)/15L+20L;
      RectFill(rp,CX(192L-x),CY(120L-y),CX(191L+x),CY(119L+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,bx2,by2;

   bx2 = bx/2; by2 = by/2;
   SetRast(rp,0L);
   maxy = (120L*step)/63L;
   x1 = CX((170L*step)/63L);
   x2 = CX((190L*step)/63L);
   y = CY((maxy*RoughSin(step+4))/8);
   if (y < 0)
      {
      BMod = -2*bpr;
      yadd = bpr*by;
      }
   else
      {
      BMod = 0;
      yadd = 0;
      }
   AreaMove(rp,bx2,by2);
   AreaClip(rp,bx2-x1,by2-y);
   AreaClip(rp,bx2+x1,by2-y);
   AreaClip(rp,bx2+x2,by2+1+y);
   AreaClip(rp,bx2-x2,by2+y);
   AreaClip(rp,bx2-x1,by2+1-y);
   AreaEnd(rp);
}

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

   x = (191L*step)/63;
   y = (119L*step)/63;
   SetRast(rp,0L);
   for (t0 = 0; t0 != 50; t0++)
      {
      Move(rp,bx/2,by/2);
      Draw(rp,rand() % mx,rand() % my);
      }
   RectFill(rp,CX(191L-x),CY(119L-y),CX(192L+x),CY(120L+y));
}

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

   SetRast(rp,0L);
   SetDrMd(rp,COMPLEMENT);
   x = (156L*step)/47L;
   if (step < 48)
      {
      RectFill(rp,CX(x),CY(78L),CX(x+71L),CY(137L));
      RectFill(rp,CX(312L-x),CY(102L),bx-CX(x),CY(161L));
      yadd = 2*bpr*(48-step);
      }
   if (step > 47 && step < 58)
      {
      ss = step-48;
      RectFill(rp,CX(156L),CY(78L+ss),CX(227L),CY(137L+ss));
      RectFill(rp,CX(156L),CY(102L-ss),CX(227L),CY(161L-ss));
      yadd = 0;
      }
   if (step > 47)
      {
      ss = CY((119L*(step-48))/15L);
      RectFill(rp,0L,0L,bx,ss);
      RectFill(rp,0L,by-ss,bx,by);
      }
   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,CX(34L*brick-35L),0L,CX(34L*brick)-1L,by);
         }
      else
         {
         right--; 
         brick = 0;
         }
      }
   SetAPen(rp,1L);
   RectFill(rp,CX(34L*brick),0L,34L*CX(brick+1)-1L,by);
}

Rain(rp,step)
struct RastPort *rp;
int step;
{
static unsigned char matx[64];
int t0,t1,qx;
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--)
         {
         qx = t0+t1*8;
         if (matx[qx] == 1 && matx[qx+8] == 0)
            {
            x = t0*48;
            y = t1*30;
            SetAPen(rp,0L);
            RectFill(rp,CX(x),CY(y),CX(x+48)-1L,CY(y+30)-1L);
            matx[qx] = 0;
            matx[qx+8] = 1;
            SetAPen(rp,1L);
            RectFill(rp,CX(x),CY(y+30L),CX(x+48L)-1L,CY(y+60L)-1L);
            }
         }
   while (matx[t0 = (rand() % 8)]);
   matx[t0] = 1;
   RectFill(rp,CX(t0*48L),0L,CX(t0+1)*48L-1L,CY(30L)-1L);
}

RandomDown(rp,step)
struct RastPort *rp;
int step;
{
static unsigned char matx[16];
int t0,qx,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;
      qx = matx[t0];
      matx[t0] = matx[num];
      matx[num] = qx;
      x = (qx & 3)*96;
      y = (qx >> 2)*60;
      }
   step &= 3;
   RectFill(rp,CX(x),CY(y+step*15),CX(x+96L)-1L,CY(y+step*15+15L)-1L);
}

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

   y = (by*step)/63;
   RectFill(rp,0L,by-y,bx,by);
   zmod = 16*bpr;
   if (y > 15)
      zmod = 8*bpr;
   if (y > 30)
      zmod = 4*bpr;
   if (y > 60)
      zmod = 2*bpr;
   if (y > 120)
      zmod = bpr;
   BMod = zmod-bpr;
   yadd = -(by-y)*zmod;
}

ExpandSlide(rp,step)
struct RastPort *rp;
int step;
{
long x,y,yz;
long x1,y1,x2,y2;

   yz = (my*step)/63;
   yadd = -bpr*(my-yz);
   x = step*mx/126;
   y = step*yz/126;
   x1 = mx/2-x;
   y1 = my-yz/2-y;
   x2 = mx/2+x;
   y2 = my-yz/2+y;
   if (x1 < 0)
      x1 = 0;
   if (y1 < 0)
      y1 = 0;
   if (x2 > bx)
      x2 = bx;
   if (y2 > by)
      y2 = by;
   if (x1 > x2)
      x1 = x2;
   if (y1 > y2)
      y1 = y2;
   RectFill(rp,x1,y1,x2,y2);
}

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

   ya = (step * 59)/63;
   for (y = 0; y != 240; y += 60)
      RectFill(rp,0L,CY(y),bx,CY(y+ya));
   yadd = (59-ya)*bpr;
}

HalfPic(rp,step)
struct RastPort *rp;
int step;
{
int step15;

   step15 = step & 15;
   switch (step / 16)
      {
      case 0:
         BMod = bpr;
         SetAPen(rp,1L);
         RectFill(rp,step15*bx/16,0L,(step15+1)*bx/16-1L,my/2-1L);
         break;
      case 1:
         SetAPen(rp,0L);
         RectFill(rp,step15*bx/16,0L,(step15+1)*bx/16-1L,my/2-1L);
         break;
      case 2:
      case 3:
         BMod = 0;
         SetAPen(rp,1L);
         step15 = step & 31;
         RectFill(rp,bx-(step15+1)*bx/32,0L,bx-step15*bx/32,by);
         break;
      }
}

Checkerboard(rp,step)
struct RastPort *rp;
int step;
{
long y;
int ww,wh,t0;

   if (step & 1)
      return;
   step >>= 1;
   ww = CX(16); wh = CY(15);
   if (step < 16)
      {
      y = (wh*step);
      wh--;
      for (t0 = (step & 1); t0 < 24; t0 += 2)
         RectFill(rp,(long) (t0*ww),y,(long) ((t0+1)*ww-1),y+wh);
      }
   else
      {
      y = by-(wh*(step & 15));
      wh--;
      for (t0 = (step & 1); t0 < 24; t0 += 2)
         RectFill(rp,(long) (t0*ww),y-wh,(long) ((t0+1)*ww-1),y);
      }
}

MiniRandom(rp,step)
struct RastPort *rp;
int step;
{
static unsigned char matx[256];
int t0,qx,t1,step4;
long x,y;

   if (step == 0)
      for (t0 = 0; t0 != 256; t0++)
         matx[t0] = t0;
   step4 = step << 2;
   for (t1 = 0; t1 != 4; t1++, step4++)
      {
      t0 = (rand() % (256-step4))+step4;
      qx = matx[t0];
      matx[t0] = matx[step4];
      matx[step4] = qx;
      x = CX((qx & 15)*24);
      y = CY((qx >> 4)*15);
      RectFill(rp,x,y,x+CX(24)-1L,y+CY(15)-1L);
      }
}

ConcentricRectangles(rp,step)
struct RastPort *rp;
int step;
{
long divx,divy,x30,y30;

   SetRast(rp,0L);
   divx = CX(15)*step/64;
   divy = CY(15)*step/64;
   x30 = CX(30); y30 = CY(30);
   SetDrMd(rp,COMPLEMENT);
   RectFill(rp,0L,0L,bx,by);
   RectFill(rp,divx,divy,bx-divx,by-divy);
   RectFill(rp,x30-divx,y30-divy,bx-x30+divx,by-y30+divy);
   RectFill(rp,x30+divx,y30+divy,bx-x30-divx,by-y30-divy);
   RectFill(rp,x30*2-divx,y30*2-divy,bx-x30*2+divx,by-y30*2+divy);
   RectFill(rp,x30*2+divx,y30*2+divy,bx-x30*2-divx,by-y30*2-divy);
   RectFill(rp,x30*3-divx,y30*3-divy,bx-x30*3+divx,by-y30*3+divy);
   RectFill(rp,x30*3+divx,y30*3+divy,bx-x30*3-divx,by-y30*3-divy);
   if (divx > 1)
      RectFill(rp,x30*4-divx,y30*4-divy,bx-x30*4+divx,by-y30*4+divy);
   SetDrMd(rp,JAM1);
}

Flash(rp,step)
struct RastPort *rp;
int step;
{
   SetRast(rp,(long) (step & 1));
}

Cloverleaf(rp,step)
struct RastPort *rp;
int step;
{
long tx,ty,hbx,hby,hmx,hmy;

   hmx = mx >> 1;
   hmy = my >> 1;
   hbx = (hmx-1);
   hby = (hmy-1);
   tx = step*hbx/64;
   ty = step*hby/64;
   RectFill(rp,0L,0L,tx,hby);
   RectFill(rp,hmx,0L,bx,ty);
   RectFill(rp,bx-tx,hmy,bx,by);
   RectFill(rp,0L,by-ty,hbx,by);
}

Cloverleaf2(rp,step)
struct RastPort *rp;
int step;
{
long tx,ty,hbx,hby,hmx,hmy;

   hmx = mx >> 1;
   hmy = my >> 1;
   hbx = (hmx-1);
   hby = (hmy-1);
   tx = step*hbx/64;
   ty = step*hby/64;
   RectFill(rp,0L,hby-ty,hbx,hby);
   RectFill(rp,hmx,0L,hmx+tx,hby);
   RectFill(rp,hmx,hmy,bx,ty+hmy);
   RectFill(rp,hbx-tx,hmy,hbx,by);
}

ConcentricRectangles2(rp,step)
struct RastPort *rp;
int step;
{
long divx,divy,x60,y60;

   SetRast(rp,0L);
   divx = CX(30)*step/64;
   divy = CY(30)*step/64;
   x60 = CX(60); y60 = CY(60);
   SetDrMd(rp,COMPLEMENT);
   RectFill(rp,0L,0L,bx,by);
   RectFill(rp,divx,divy,bx-divx,by-divy);
   RectFill(rp,x60-divx,y60-divy,bx-x60+divx,by-y60+divy);
   RectFill(rp,x60+divx,y60+divy,bx-x60-divx,by-y60-divy);
   if (divx > 1)
      RectFill(rp,x60*2-divx,y60*2-divy,bx-x60*2+divx,by-y60*2+divy);
   SetDrMd(rp,JAM1);
}

