home *** CD-ROM | disk | FTP | other *** search
- 18-Jun-88 14:26:32-MDT,7319;000000000000
- Return-Path: <u-lchoqu%sunset@cs.utah.edu>
- Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:26:16 MDT
- Received: by cs.utah.edu (5.54/utah-2.0-cs)
- id AA22109; Sat, 18 Jun 88 14:26:15 MDT
- Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
- id AA24527; Sat, 18 Jun 88 14:26:13 MDT
- Date: Sat, 18 Jun 88 14:26:13 MDT
- From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
- Message-Id: <8806182026.AA24527@sunset.utah.edu>
- To: rthum@simtel20.arpa
- Subject: Crabs+.c
-
- /* This is Crabs+, a rewriting of the famous Crabs DA into LightSpeedC.
- It has been written with LsC2.01 by Daniel Ranson from the original
- code in MacC. Contrary to the latter, this code will work on all
- macs, and in all application that supports DAs.
- To compile this, build a DA project with this file and MacTraps.
- It should work with all versions of LsC.
- My contribution, apart from the conversion to LsC, consists of
- two tricks:
- - The screen bitmap is found from the Window Manager port. This
- is more reliable than using QuickDraw because: 1/ QuickDraw
- globals are not DA globals. 2/ The application can choose where
- it places QuickDraw globals. There are at least two favored
- positions: -4(a5) and 0(a5). This is unreliable.
- - When we CopyBits to the screen, the port is changed to a fake
- port to prevent clipping. Without that, in the Finder with nothing
- selected and the mouse outside any window, the crabs will only
- draw OUTSIDE the windows.
-
- There was no copyright notice in the original program I found, so
- I don't add any. Feel free to dump this in your favorite trashcan
- (real or iconic).
- Daniel Ranson.
- */
-
- /* Includes */
- #include <QuickDraw.h>
- #include <DeviceMgr.h>
-
- /* Global variables */
- short already_open = 0; /* 1 -> DA is already open */
- DCtlPtr dce; /* device control entry */
- BitMap grayMap, crabMap;
- BitMap *screenPtr; /* Pointer to screen bitmap */
- GrafPort fakePort;
- Rect crabRect, topleftRect, drawRect;
- Ptr grayPtr, crabPtr;
- unsigned long grayBits[] = {
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555};
- unsigned long crabBits[] = {
- 0xBEAA7755,
- 0xAAAA7F55,
- 0xBEAA7F55,
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555,
- 0xAAAA5555};
- short crabCount, maxCrabs;
- Point crabWhere[40];
-
- #define MBarHeight *(short*)0xBAA
-
- main(p, d, n)
- cntrlParam *p; /* ==> parameter block */
- DCtlPtr d; /* ==> device control entry */
- short n; /* entry point selector */
- {
- /* check to make sure our data area was allocated */
-
- if (d->dCtlStorage == 0) {
- if (n == 0) { /* open */
- SysBeep(3);
- CloseDriver(d->dCtlRefNum);
- }
- return(0);
- }
-
- /* dispatch */
- dce = d;
- switch(n){
- case 0: /* open */
- doOpen();
- break;
-
- case 2: /* control */
- if(p->csCode == accRun){ /* The real thing */
- doRun();
- }
- break;
-
- default: /* Ignore all prayers */
- break;
- }
-
- /* done */
- return(0); /* No Error */
- }
-
- /* Open routine */
- doOpen()
- {
- register short whichCrab, i;
- GrafPtr wPort, savedPort;
-
- /* every time ... */
- dce->dCtlFlags |= dNeedLock|dNeedTime;
- dce->dCtlDelay = 10; /* Call every 10 ticks */
- dce->dCtlEMask = 0; /* No events processed !! */
- if(already_open)
- return;
-
- /* first time only ... */
- already_open = 1;
- /* Find screen bitmap through Window Manager port */
- GetWMgrPort(&wPort);
- screenPtr = &(wPort->portBits);
-
- /*set up bitmaps for the screen, the crab, and the gray stuff the crabs
- leave behind. The latter 2 bitmaps are bigger than they really
- need to be because of the constraint that rowBytes must be even*/
-
- grayPtr = NewPtr(32L);
- crabPtr = NewPtr(32L);
- SetRect(&crabRect,0,0,16,16);
- SetRect(&topleftRect,0,0,8,8);
- BlockMove(grayBits, grayPtr, 32L);
- grayMap.baseAddr = grayPtr;
- grayMap.rowBytes = 2;
- grayMap.bounds = crabRect;
- BlockMove(crabBits, crabPtr, 32L);
- crabMap.baseAddr = crabPtr;
- crabMap.rowBytes = 2;
- crabMap.bounds = crabRect;
-
- /*allocate a random # of crabs to starting positions down the left
- edge of the screen, starting just below the menu bar */
-
- maxCrabs = (screenPtr->bounds.bottom - screenPtr->bounds.top
- - MBarHeight) / 8;
- if(maxCrabs > 40) maxCrabs = 40;
- for(i = 0, whichCrab = 0; i < maxCrabs; i++)
- if(Random() & 0x0001){
- crabWhere[whichCrab].h = screenPtr->bounds.left;
- crabWhere[whichCrab].v = MBarHeight + i * 8;
- whichCrab++;
- }
- crabCount = whichCrab; /* keep track of how many crabs were allocated */
-
- /* Create a fake port to prevent CopyBits clipping */
- GetPort(&savedPort);
- OpenPort(&fakePort);
- /* paste the top left corner of the crab bitmap ( i.e., the crab itself)
- in each crab's starting position on the screen */
-
- for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
- SetRect(&drawRect,
- crabWhere[whichCrab].h,
- crabWhere[whichCrab].v,
- crabWhere[whichCrab].h + 8,
- crabWhere[whichCrab].v + 8);
- CopyBits(&crabMap, screenPtr,
- &topleftRect, &drawRect, srcCopy, 0L);
- }
- SetPort(savedPort);
- }
-
- /* Run routine */
- doRun(){
- short offset,voffset,sign;
- register short whichCrab;
- GrafPtr savedPort;
-
- GetPort(&savedPort);
- SetPort(&fakePort);
- /*first, replace all the current crabs with gray*/
- for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
- SetRect(&drawRect,
- crabWhere[whichCrab].h,
- crabWhere[whichCrab].v,
- crabWhere[whichCrab].h + 8,
- crabWhere[whichCrab].v + 8);
- CopyBits(&grayMap, screenPtr,
- &topleftRect, &drawRect, srcCopy, 0L);
- }
-
- /* change each crab's position a little bit vertically,
- somewhat more horizontally */
- for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
- offset = (Random() & 0x0003); /* offset = 0,1,2, or 3*/
- sign = ((Random() & 0x0001)? 1 : -1); /* + or - */
- /* +/- 2,4,6, or 8 horiz */
- crabWhere[whichCrab].h =
- (crabWhere[whichCrab].h + sign * (2+2*offset));
- /* Wraparound */
- if(crabWhere[whichCrab].h + 8 >= screenPtr->bounds.right)
- crabWhere[whichCrab].h = screenPtr->bounds.left;
- else if(crabWhere[whichCrab].h < screenPtr->bounds.left)
- crabWhere[whichCrab].h = screenPtr->bounds.right - 8;
- voffset = (Random() & 0x0003);
- switch(voffset){
- case 0:
- crabWhere[whichCrab].v = (crabWhere[whichCrab].v - 2);
- /* Wraparound */
- if(crabWhere[whichCrab].v + 8 >= screenPtr->bounds.bottom)
- crabWhere[whichCrab].v = screenPtr->bounds.top;
- else if(crabWhere[whichCrab].v < screenPtr->bounds.top)
- crabWhere[whichCrab].v = screenPtr->bounds.bottom - 8;
- break;
-
- case 1:
- case 2:
- break;
-
- case 3:
- crabWhere[whichCrab].v = (crabWhere[whichCrab].v + 2)
- % (screenPtr->bounds.bottom - screenPtr->bounds.top);
- break;
-
- default:
- break;
- }
- }
-
- /* redraw the little buggers */
- for(whichCrab=0;whichCrab<crabCount;whichCrab++){
- SetRect(&drawRect,
- crabWhere[whichCrab].h,
- crabWhere[whichCrab].v,
- crabWhere[whichCrab].h + 8,
- crabWhere[whichCrab].v + 8);
- CopyBits(&crabMap, screenPtr, &topleftRect, &drawRect, srcCopy, 0L);
- }
- SetPort(savedPort);
- }
-