home *** CD-ROM | disk | FTP | other *** search
/ Carousel Volume 2 #1 / carousel.iso / mactosh / code / c_crabsp.sit < prev    next >
Encoding:
Text File  |  1988-06-20  |  7.0 KB  |  245 lines

  1. 18-Jun-88 14:26:32-MDT,7319;000000000000
  2. Return-Path: <u-lchoqu%sunset@cs.utah.edu>
  3. Received: from cs.utah.edu by SIMTEL20.ARPA with TCP; Sat, 18 Jun 88 14:26:16 MDT
  4. Received: by cs.utah.edu (5.54/utah-2.0-cs)
  5.     id AA22109; Sat, 18 Jun 88 14:26:15 MDT
  6. Received: by sunset.utah.edu (5.54/utah-2.0-leaf)
  7.     id AA24527; Sat, 18 Jun 88 14:26:13 MDT
  8. Date: Sat, 18 Jun 88 14:26:13 MDT
  9. From: u-lchoqu%sunset@cs.utah.edu (Lee Choquette)
  10. Message-Id: <8806182026.AA24527@sunset.utah.edu>
  11. To: rthum@simtel20.arpa
  12. Subject: Crabs+.c
  13.  
  14. /* This is Crabs+, a rewriting of the famous Crabs DA into LightSpeedC.
  15.     It has been written with LsC2.01 by Daniel Ranson from the original
  16.     code in MacC. Contrary to the latter, this code will work on all
  17.     macs, and in all application that supports DAs.
  18.     To compile this, build a DA project with this file and MacTraps.
  19.     It should work with all versions of LsC.
  20.     My contribution, apart from the conversion to LsC, consists of
  21.     two tricks:
  22.     - The screen bitmap is found from the Window Manager port. This
  23.     is more reliable than using QuickDraw because: 1/ QuickDraw
  24.     globals are not DA globals. 2/ The application can choose where
  25.     it places QuickDraw globals. There are at least two favored
  26.     positions: -4(a5) and 0(a5). This is unreliable.
  27.     - When we CopyBits to the screen, the port is changed to a fake
  28.     port to prevent clipping. Without that, in the Finder with nothing
  29.     selected and the mouse outside any window, the crabs will only
  30.     draw OUTSIDE the windows.
  31.     
  32.     There was no copyright notice in the original program I found, so
  33.     I don't add any. Feel free to dump this in your favorite trashcan
  34.     (real or iconic).
  35.             Daniel Ranson.
  36.  */
  37.  
  38. /* Includes */
  39. #include    <QuickDraw.h>
  40. #include    <DeviceMgr.h>
  41.  
  42. /* Global variables */
  43. short    already_open = 0;        /*  1 -> DA is already open  */
  44. DCtlPtr    dce;                /*  device control entry  */
  45. BitMap    grayMap, crabMap;
  46. BitMap    *screenPtr;            /* Pointer to screen bitmap */
  47. GrafPort    fakePort;
  48. Rect    crabRect, topleftRect, drawRect;
  49. Ptr        grayPtr, crabPtr;
  50. unsigned    long    grayBits[] = {
  51.                         0xAAAA5555,
  52.                         0xAAAA5555,
  53.                         0xAAAA5555,
  54.                         0xAAAA5555,
  55.                         0xAAAA5555,
  56.                         0xAAAA5555,
  57.                         0xAAAA5555,
  58.                         0xAAAA5555};
  59. unsigned    long    crabBits[] = {
  60.                         0xBEAA7755,
  61.                         0xAAAA7F55,
  62.                         0xBEAA7F55,
  63.                         0xAAAA5555,
  64.                         0xAAAA5555,
  65.                         0xAAAA5555,
  66.                         0xAAAA5555,
  67.                         0xAAAA5555}; 
  68. short    crabCount, maxCrabs;
  69. Point    crabWhere[40];
  70.  
  71. #define    MBarHeight    *(short*)0xBAA
  72.  
  73. main(p, d, n)
  74. cntrlParam    *p;            /*  ==> parameter block  */
  75. DCtlPtr        d;            /*  ==> device control entry  */
  76. short        n;            /*  entry point selector  */
  77. {
  78.         /*  check to make sure our data area was allocated  */
  79.         
  80.     if (d->dCtlStorage == 0) {
  81.         if (n == 0) {    /*  open  */
  82.             SysBeep(3);
  83.             CloseDriver(d->dCtlRefNum);
  84.         }
  85.         return(0);
  86.     }
  87.     
  88.     /*  dispatch  */
  89.     dce = d;
  90.     switch(n){
  91.     case 0:        /*  open  */
  92.         doOpen();
  93.         break;
  94.     
  95.     case 2:        /*  control  */
  96.         if(p->csCode == accRun){    /*  The real thing  */
  97.             doRun();
  98.         }
  99.         break;
  100.     
  101.     default:    /* Ignore all prayers */
  102.         break;
  103.     }
  104.     
  105.     /*  done  */
  106.     return(0);    /* No Error */
  107. }
  108.  
  109. /* Open routine */
  110. doOpen()
  111. {
  112.      register    short    whichCrab, i;
  113.      GrafPtr        wPort, savedPort;
  114.  
  115.      /*  every time ...  */
  116.     dce->dCtlFlags |= dNeedLock|dNeedTime;
  117.     dce->dCtlDelay = 10;    /* Call every 10 ticks */
  118.     dce->dCtlEMask = 0;        /* No events processed !! */
  119.     if(already_open)
  120.         return;
  121.     
  122.     /*  first time only ...  */
  123.     already_open = 1;
  124.     /* Find screen bitmap through Window Manager port */
  125.     GetWMgrPort(&wPort);
  126.     screenPtr = &(wPort->portBits);
  127.     
  128.     /*set up bitmaps for the screen, the crab, and the gray stuff the crabs
  129.         leave behind.  The latter 2 bitmaps are bigger than they really
  130.         need to be because of the constraint that rowBytes must be even*/
  131.     
  132.     grayPtr = NewPtr(32L);
  133.     crabPtr = NewPtr(32L);
  134.     SetRect(&crabRect,0,0,16,16);
  135.     SetRect(&topleftRect,0,0,8,8);
  136.     BlockMove(grayBits, grayPtr, 32L);
  137.     grayMap.baseAddr = grayPtr;
  138.     grayMap.rowBytes = 2;
  139.     grayMap.bounds = crabRect;
  140.     BlockMove(crabBits, crabPtr, 32L);
  141.     crabMap.baseAddr = crabPtr;
  142.     crabMap.rowBytes = 2;
  143.     crabMap.bounds = crabRect;
  144.     
  145.     /*allocate a random # of crabs to starting positions down the left 
  146.       edge of the screen, starting just below the menu bar */
  147.     
  148.     maxCrabs = (screenPtr->bounds.bottom - screenPtr->bounds.top
  149.                     - MBarHeight) / 8;
  150.     if(maxCrabs > 40) maxCrabs = 40;
  151.     for(i = 0, whichCrab = 0; i < maxCrabs; i++)
  152.         if(Random() & 0x0001){
  153.             crabWhere[whichCrab].h = screenPtr->bounds.left;
  154.             crabWhere[whichCrab].v = MBarHeight + i * 8;
  155.             whichCrab++;
  156.         }
  157.     crabCount = whichCrab;    /* keep track of how many crabs were allocated */
  158.     
  159.     /* Create a fake port to prevent CopyBits clipping */
  160.     GetPort(&savedPort);
  161.     OpenPort(&fakePort);
  162.     /* paste the top left corner of the crab bitmap ( i.e., the crab itself)
  163.         in each crab's starting position on the screen */
  164.     
  165.     for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
  166.         SetRect(&drawRect,
  167.                 crabWhere[whichCrab].h,
  168.                 crabWhere[whichCrab].v,
  169.                 crabWhere[whichCrab].h + 8,
  170.                 crabWhere[whichCrab].v + 8);
  171.         CopyBits(&crabMap, screenPtr,
  172.                     &topleftRect, &drawRect, srcCopy, 0L);
  173.     }
  174.     SetPort(savedPort);
  175. }
  176.  
  177. /* Run routine */
  178. doRun(){
  179.     short offset,voffset,sign;
  180.      register    short    whichCrab;
  181.      GrafPtr        savedPort;
  182.     
  183.     GetPort(&savedPort);
  184.     SetPort(&fakePort);
  185.     /*first, replace all the current crabs with gray*/
  186.     for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
  187.         SetRect(&drawRect,
  188.                 crabWhere[whichCrab].h,
  189.                 crabWhere[whichCrab].v,
  190.                 crabWhere[whichCrab].h + 8,
  191.                 crabWhere[whichCrab].v + 8);
  192.         CopyBits(&grayMap, screenPtr,
  193.                     &topleftRect, &drawRect, srcCopy, 0L);
  194.     }
  195.     
  196.     /* change each crab's position a little bit vertically,
  197.         somewhat more horizontally */
  198.     for(whichCrab = 0; whichCrab < crabCount; whichCrab++){
  199.         offset = (Random() & 0x0003);        /* offset = 0,1,2, or 3*/
  200.         sign = ((Random() & 0x0001)? 1 : -1);    /* + or - */
  201.         /* +/- 2,4,6, or 8 horiz */
  202.         crabWhere[whichCrab].h = 
  203.                 (crabWhere[whichCrab].h + sign * (2+2*offset));
  204.         /* Wraparound */
  205.         if(crabWhere[whichCrab].h + 8 >= screenPtr->bounds.right)
  206.             crabWhere[whichCrab].h = screenPtr->bounds.left;
  207.         else if(crabWhere[whichCrab].h < screenPtr->bounds.left)
  208.             crabWhere[whichCrab].h = screenPtr->bounds.right - 8;
  209.         voffset = (Random() & 0x0003);
  210.         switch(voffset){
  211.         case 0:
  212.             crabWhere[whichCrab].v = (crabWhere[whichCrab].v - 2);
  213.             /* Wraparound */
  214.             if(crabWhere[whichCrab].v + 8 >= screenPtr->bounds.bottom)
  215.                 crabWhere[whichCrab].v = screenPtr->bounds.top;
  216.             else if(crabWhere[whichCrab].v < screenPtr->bounds.top)
  217.                 crabWhere[whichCrab].v = screenPtr->bounds.bottom - 8;
  218.             break;
  219.         
  220.         case 1:
  221.         case 2:
  222.             break;
  223.         
  224.         case 3:
  225.             crabWhere[whichCrab].v = (crabWhere[whichCrab].v + 2)
  226.                     % (screenPtr->bounds.bottom - screenPtr->bounds.top);
  227.             break;
  228.         
  229.         default:
  230.             break;
  231.         }
  232.     }
  233.                 
  234.     /* redraw the little buggers */
  235.     for(whichCrab=0;whichCrab<crabCount;whichCrab++){
  236.         SetRect(&drawRect,
  237.                 crabWhere[whichCrab].h,
  238.                 crabWhere[whichCrab].v,
  239.                 crabWhere[whichCrab].h + 8,
  240.                 crabWhere[whichCrab].v + 8);
  241.         CopyBits(&crabMap, screenPtr, &topleftRect, &drawRect, srcCopy, 0L);
  242.     }
  243.     SetPort(savedPort);
  244. }
  245.