home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / da / zoomidle.sit / ZoomIdle.1.1.c < prev    next >
Text File  |  1986-07-29  |  6KB  |  254 lines

  1. /*
  2.     ZoomIdle
  3.     Version 1.1     25 July 1986
  4.  
  5.     Screen saver desk accessory.  Generates successive randomly chosen
  6.     rectangles, and zooms each into the next by interpolating a series
  7.     of rectangles intermediate in shape and location.  Click and hold in
  8.  
  9.     menu bar to pause the display.  Click below menu bar to terminate.
  10.  
  11.     The project should include MacTraps and ZoomIdle1.1.c.  The project
  12.     type should be Desk Accessory.
  13.  
  14.     Changes since 1.0:
  15.  
  16.     Works with Macintosh XL (wider screen).
  17.     Doesn't clear the menu bar until the window receives an activate
  18.     event.  1.0 cleared the bar immediately, which was too early -
  19.     some programs would crash when ZoomIdle exited.
  20.  
  21.  
  22.     Paul DuBois
  23.     Wisconsin Regional Primate Research Center
  24.     1220 Capitol Court
  25.     University of Wisconsin-Madison
  26.     Madison, WI  53706
  27.  
  28.     UUCP: {allegra, ihnp4, seismo}!uwvax!uwmacc!dubois
  29.     ARPA: dubois@easter
  30.           dubois@unix.macc.wisc.edu
  31. */
  32.  
  33.  
  34. # include    <DeviceMgr.h>
  35. # include    <WindowMgr.h>    /* includes QuickDraw.h, MacTypes.h */
  36.  
  37. # include    <EventMgr.h>
  38. # include    <MenuMgr.h>
  39.  
  40. # define    nil            0L
  41.  
  42.  
  43. /*
  44.     zoomSteps controls the number of rectangles that are drawn in each
  45.     interpolative series.  zoomShow controls how many rectangles are
  46.     visible at once.  These two values may be varied independently, but
  47.     they must both be greater than zero.
  48. */
  49.  
  50. # define    zoomSteps    15
  51. # define    zoomShow    15
  52.  
  53.  
  54. /*  global variables  */
  55.  
  56. Rect        zRect[zoomShow];
  57. int            zIndex;
  58.  
  59.  
  60. /*
  61.     Return integer between zero and max (inclusive).  Assumes max is
  62.  
  63.     non-negative.
  64. */
  65.  
  66.  
  67. Rand (max)
  68. int    max;
  69. {
  70. register int    t;
  71.  
  72.     if ((t = Random ()) < 0) t = -t;
  73.     return (t % (max + 1));
  74. }
  75.  
  76.  
  77. /*
  78.     Interpolate one rectangle smoothly into another.  This algorithm
  79.     assumes that it is erasing the previous series while it's
  80.     drawing the new one.  The first time this is called, that is not
  81.     true, which is why the init code sets all the zRect rectangles
  82.     empty - it's harmless to erase empty rectangles (doesn't show on
  83.     screen).
  84.     
  85.     Pen mode should be set to patXor, so that the first drawing shows
  86.     the rectangle, the second time erases it.  Gray seems to work
  87.     best for the pen pattern:  white is too stark a contrast, except
  88.     perhaps for the very dialectic.
  89. */
  90.  
  91. ZoomRect (r1, r2)
  92. Rect    r1, r2;
  93.  
  94. {
  95. register int    r1left, r1top;
  96. register int    l, t;
  97. register int    j;
  98. int                hDiff, vDiff, widDiff, htDiff;
  99. int                r, b;
  100. int                rWid, rHt;
  101. register Rect    *rp;
  102.  
  103.     r1left = r1.left;
  104.     r1top = r1.top;
  105.     hDiff = r2.left - r1left;    /* positive if moving to right */
  106.  
  107.     vDiff = r2.top - r1top;        /* positive if moving down */
  108.     rWid = r1.right - r1left;
  109.     rHt = r1.bottom - r1top;
  110.     widDiff = (r2.right - r2.left) - rWid;
  111.     htDiff = (r2.bottom - r2.top) - rHt;
  112.  
  113. /*
  114.     order of evaluation is important in the rect coordinate calculations.
  115.     since all arithmetic is integer, you can't save time by calculating
  116.     j/zoomSteps and using that - it'll usually be zero.
  117. */
  118.  
  119.     for (j = 1; j <= zoomSteps; j++)
  120.     {
  121.         if (++zIndex >= zoomShow)
  122.             zIndex = 0;
  123.         rp = &zRect[zIndex];
  124.         FrameRect (rp);                /* erase a rectangle */
  125.         l = r1left + (hDiff * j) / zoomSteps;
  126.         t = r1top + (vDiff * j) / zoomSteps;
  127.         r = l + rWid + (widDiff * j) / zoomSteps;
  128.         b = t + rHt + (htDiff * j) / zoomSteps;
  129.         SetRect (rp, l, t, r, b);
  130.         FrameRect (rp);
  131.  
  132.     }
  133.         
  134. }
  135.  
  136.  
  137. main(p, d, n)
  138. cntrlParam *p;    /*  ==> parameter block  */
  139. DCtlPtr d;        /*  ==> device control entry  */
  140. int n;            /*  entry point selector  */
  141.  
  142. {
  143. register DCtlPtr    dce = d;
  144. Rect                dstRect;
  145. Point                pt1, pt2;
  146. long                pat[2];
  147. static int            scrnSizeX;
  148. static int            scrnSizeY;
  149. static Rect            srcRect;
  150. static Handle        theMenuBar;
  151. static WindowPtr    theWind;
  152. static Boolean        zoomAway = false;
  153.  
  154.  
  155.     /*  check to make sure our data area was allocated  */
  156.         
  157.     if (dce->dCtlStorage == 0)
  158.     {
  159.  
  160.         if (n == 0)                        /*  open  */
  161.             CloseDriver(dce->dCtlRefNum);
  162.     }
  163.     else switch (n)    /*  dispatch  */
  164.     {
  165.         case 0:        /*  open  */
  166.  
  167.             dce->dCtlFlags |= dNeedLock | dNeedTime;
  168.             dce->dCtlDelay = 0;
  169.             dce->dCtlEMask = everyEvent;
  170.         
  171.             GetWMgrPort (&theWind);
  172.             srcRect = theWind->portRect;
  173.             scrnSizeX = srcRect.right;    /* get size of screen */
  174.             scrnSizeY = srcRect.bottom;
  175.             theWind = NewWindow (nil, &srcRect, "\p", true,
  176.                                     noGrowDocProc, -1L, true, 0L);
  177.             RectRgn (theWind->visRgn, &srcRect);
  178.             ((WindowPeek) theWind)->windowKind = dce->dCtlRefNum;
  179.         
  180. /*
  181.             Initialize the rect array.  This also sets zIndex
  182.             to a value that causes it to reset to zero on the
  183.             first call to ZoomRect.
  184. */
  185.             for (zIndex = 0; zIndex < zoomShow; ++zIndex)
  186.                 SetRect (&zRect[zIndex], 0, 0, 0, 0);
  187.  
  188.             break;
  189.  
  190.         case 2:        /*  control  */
  191.  
  192.             SetPort (theWind);
  193.             switch (p->csCode)
  194.             {
  195.                 case accEvent:    /* put glasses on to read next switch */
  196.  
  197.                     switch (((EventRecord *) * (long *) &p->csParam)->what)
  198.                     {
  199.                         case activateEvt:
  200.  
  201.                             theMenuBar = GetMenuBar ();
  202.                             ClearMenuBar ();
  203.                             PaintRect (&srcRect /* = &theWind->portRect */);
  204.                             PenMode (patXor);    /* do all drawing in xor */
  205.                             pat[0] = pat[1] = 0xaa55aa55L;
  206.                             PenPat (&pat);    /* can't use QD global pats! */
  207.                             zoomAway = true;
  208.                             break;
  209.  
  210.                         case mouseDown:    /* quit on mousedown event */
  211.  
  212.                             CloseDriver(dce->dCtlRefNum);
  213.                             break;
  214.                     }
  215.                     break;
  216.  
  217.                 case accRun:
  218.  
  219.  
  220.  
  221.                     if (zoomAway)    /* activated */
  222.                     {
  223.                         ObscureCursor ();    /* keep cursor hidden */
  224.                         pt1.h = Rand (scrnSizeX);    /* generate rect and zoom to it */
  225.                         pt1.v = Rand (scrnSizeY);
  226.                         pt2.h = Rand (scrnSizeX);
  227.                         pt2.v = Rand (scrnSizeY);
  228.                         Pt2Rect (pt1, pt2, &dstRect);
  229.                         ZoomRect (srcRect, dstRect);
  230.                         srcRect = dstRect;
  231.                     }
  232.                     break;
  233.             }
  234.             break;
  235.  
  236.         case 4:        /*  close  */
  237.  
  238.             DisposeWindow (theWind);
  239.             SetMenuBar (theMenuBar);    /* restore menu bar */
  240.  
  241.             DisposHandle (theMenuBar);
  242.             DrawMenuBar ();
  243.             break;
  244.     }
  245.     
  246.     /*  done  */
  247.     
  248.     return(0);
  249. }
  250. --- end ---
  251.  
  252.  
  253.  
  254.