Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!columbia!topaz!ll-xn!cit-vax!elroy!smeagol!usc-oberon!sdcrdcf!trwrb!scgvaxd!felix!macintosh From: dubois@uwmacc.UUCP (Paul DuBois) Newsgroups: mod.mac.sources Subject: ZoomIdle1.1 (LightspeedC source) (part 2 of 3) Message-ID: <1393@felix.UUCP> Date: Sat, 26-Jul-86 10:30:35 EDT Article-I.D.: felix.1393 Posted: Sat Jul 26 10:30:35 1986 Date-Received: Tue, 29-Jul-86 23:28:40 EDT References: <1392@felix.UUCP> Sender: macintosh@felix.UUCP Reply-To: macintosh@felix.UUCP (The Moderator) Organization: FileNet Corp., Costa Mesa, CA Lines: 244 Approved: bytebug@felix.UUCP (Roger L. Long) Here is the LightspeedC source to ZoomIdle1.1. For printing, tab size should be 4. --- cut --- /* ZoomIdle Version 1.1 25 July 1986 Screen saver desk accessory. Generates successive randomly chosen rectangles, and zooms each into the next by interpolating a series of rectangles intermediate in shape and location. Click and hold in menu bar to pause the display. Click below menu bar to terminate. The project should include MacTraps and ZoomIdle1.1.c. The project type should be Desk Accessory. Changes since 1.0: Works with Macintosh XL (wider screen). Doesn't clear the menu bar until the window receives an activate event. 1.0 cleared the bar immediately, which was too early - some programs would crash when ZoomIdle exited. Paul DuBois Wisconsin Regional Primate Research Center 1220 Capitol Court University of Wisconsin-Madison Madison, WI 53706 UUCP: {allegra, ihnp4, seismo}!uwvax!uwmacc!dubois ARPA: dubois@easter dubois@unix.macc.wisc.edu */ # include # include /* includes QuickDraw.h, MacTypes.h */ # include # include # define nil 0L /* zoomSteps controls the number of rectangles that are drawn in each interpolative series. zoomShow controls how many rectangles are visible at once. These two values may be varied independently, but they must both be greater than zero. */ # define zoomSteps 15 # define zoomShow 15 /* global variables */ Rect zRect[zoomShow]; int zIndex; /* Return integer between zero and max (inclusive). Assumes max is non-negative. */ Rand (max) int max; { register int t; if ((t = Random ()) < 0) t = -t; return (t % (max + 1)); } /* Interpolate one rectangle smoothly into another. This algorithm assumes that it is erasing the previous series while it's drawing the new one. The first time this is called, that is not true, which is why the init code sets all the zRect rectangles empty - it's harmless to erase empty rectangles (doesn't show on screen). Pen mode should be set to patXor, so that the first drawing shows the rectangle, the second time erases it. Gray seems to work best for the pen pattern: white is too stark a contrast, except perhaps for the very dialectic. */ ZoomRect (r1, r2) Rect r1, r2; { register int r1left, r1top; register int l, t; register int j; int hDiff, vDiff, widDiff, htDiff; int r, b; int rWid, rHt; register Rect *rp; r1left = r1.left; r1top = r1.top; hDiff = r2.left - r1left; /* positive if moving to right */ vDiff = r2.top - r1top; /* positive if moving down */ rWid = r1.right - r1left; rHt = r1.bottom - r1top; widDiff = (r2.right - r2.left) - rWid; htDiff = (r2.bottom - r2.top) - rHt; /* order of evaluation is important in the rect coordinate calculations. since all arithmetic is integer, you can't save time by calculating j/zoomSteps and using that - it'll usually be zero. */ for (j = 1; j <= zoomSteps; j++) { if (++zIndex >= zoomShow) zIndex = 0; rp = &zRect[zIndex]; FrameRect (rp); /* erase a rectangle */ l = r1left + (hDiff * j) / zoomSteps; t = r1top + (vDiff * j) / zoomSteps; r = l + rWid + (widDiff * j) / zoomSteps; b = t + rHt + (htDiff * j) / zoomSteps; SetRect (rp, l, t, r, b); FrameRect (rp); } } main(p, d, n) cntrlParam *p; /* ==> parameter block */ DCtlPtr d; /* ==> device control entry */ int n; /* entry point selector */ { register DCtlPtr dce = d; Rect dstRect; Point pt1, pt2; long pat[2]; static int scrnSizeX; static int scrnSizeY; static Rect srcRect; static Handle theMenuBar; static WindowPtr theWind; static Boolean zoomAway = false; /* check to make sure our data area was allocated */ if (dce->dCtlStorage == 0) { if (n == 0) /* open */ CloseDriver(dce->dCtlRefNum); } else switch (n) /* dispatch */ { case 0: /* open */ dce->dCtlFlags |= dNeedLock | dNeedTime; dce->dCtlDelay = 0; dce->dCtlEMask = everyEvent; GetWMgrPort (&theWind); srcRect = theWind->portRect; scrnSizeX = srcRect.right; /* get size of screen */ scrnSizeY = srcRect.bottom; theWind = NewWindow (nil, &srcRect, "\p", true, noGrowDocProc, -1L, true, 0L); RectRgn (theWind->visRgn, &srcRect); ((WindowPeek) theWind)->windowKind = dce->dCtlRefNum; /* Initialize the rect array. This also sets zIndex to a value that causes it to reset to zero on the first call to ZoomRect. */ for (zIndex = 0; zIndex < zoomShow; ++zIndex) SetRect (&zRect[zIndex], 0, 0, 0, 0); break; case 2: /* control */ SetPort (theWind); switch (p->csCode) { case accEvent: /* put glasses on to read next switch */ switch (((EventRecord *) * (long *) &p->csParam)->what) { case activateEvt: theMenuBar = GetMenuBar (); ClearMenuBar (); PaintRect (&srcRect /* = &theWind->portRect */); PenMode (patXor); /* do all drawing in xor */ pat[0] = pat[1] = 0xaa55aa55L; PenPat (&pat); /* can't use QD global pats! */ zoomAway = true; break; case mouseDown: /* quit on mousedown event */ CloseDriver(dce->dCtlRefNum); break; } break; case accRun: if (zoomAway) /* activated */ { ObscureCursor (); /* keep cursor hidden */ pt1.h = Rand (scrnSizeX); /* generate rect and zoom to it */ pt1.v = Rand (scrnSizeY); pt2.h = Rand (scrnSizeX); pt2.v = Rand (scrnSizeY); Pt2Rect (pt1, pt2, &dstRect); ZoomRect (srcRect, dstRect); srcRect = dstRect; } break; } break; case 4: /* close */ DisposeWindow (theWind); SetMenuBar (theMenuBar); /* restore menu bar */ DisposHandle (theMenuBar); DrawMenuBar (); break; } /* done */ return(0); } --- end ---