home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #31 / NN_1992_31.iso / spool / comp / sys / mac / programm / 20284 < prev    next >
Encoding:
Text File  |  1992-12-24  |  6.1 KB  |  166 lines

  1. Path: sparky!uunet!psinntp!uu0570!Patrick_J._Toole
  2. Message-ID: <1992Dec23.193203.88542@uu0570.foggybottom.com>
  3. Newsgroups: comp.sys.mac.programmer
  4. Distribution: world
  5. From: Patrick_J._Toole@uu0570.foggybottom.com
  6. Organization: Foggy Bottom / Washington, D.C.
  7. Date: Wed, 23 Dec 1992 19:32:03 EST
  8. Subject: Re: Code for drawing a sprite desired.
  9. Lines: 155
  10.  
  11. Personally, I'm a Pascal programmer-desperately trying to learn C. Since I
  12. don't program in C, I won't be able to refer to code, but I will attach code
  13. from tech note #41. That's all I use. 
  14.  
  15. Every window pointer and grafPtr have a bitmap. This is passed as the first
  16. two parameters; the source, then the destination. (In pascal, you'd pass it by
  17. myWindowPtr^.portBits). Then, of course, the rectangles of the ports you wish
  18. to pass. To use the Mask, you need to use CopyMask (if I'm not mistaken). All
  19. it does is just copy the pixels that are the color black in the rectangle
  20. passed by maskRect.
  21.  
  22. What you want to do is something like this: 
  23. CopyBits(myOffscreen^.portBits, myOffscreen^.portBits, myWindow^.portBits,
  24. OffscreenSourceRect, OffscreenMaskRect, OnScreenRect);
  25.  
  26. Good Luck!
  27.  
  28. Write me personally if you have any other questions.
  29. If you want to do it in color, read TN #120.
  30.  
  31. Excerpt from TN#41:
  32. First, let's look at a general purpose function to create an off-screen
  33. bitmap.  This function creates the GrafPort on the heap.  You could also
  34. create it on the stack and pass the uninitialized structure to a function
  35. similar to this one.
  36.  
  37. Boolean CreateOffscreenBitMap(GrafPtr *newOffscreen, Rect *inBounds)
  38. {
  39.   GrafPtr savePort;
  40.   GrafPtr newPort;
  41.  
  42.   GetPort(&savePort);    /* need this to restore thePort after OpenPort */
  43.  
  44.   newPort = (GrafPtr) NewPtr(sizeof(GrafPort));    /* allocate the grafPort */
  45.   if (MemError() != noErr)
  46.     return false;                 /* failed to allocate the off-screen port */
  47.   /*
  48.   the call to OpenPort does the following . . . 
  49.     allocates space for visRgn (set to screenBits.bounds) and clipRgn (set
  50. wide open)
  51.     sets portBits to screenBits
  52.     sets portRect to screenBits.bounds
  53.     etc. (see IM I-163,164)
  54.     side effect: does a SetPort(&offScreen)
  55.   */
  56.   OpenPort(newPort);
  57.   /* make bitmap the size of the bounds that caller supplied */
  58.   newPort->portRect = *inBounds;
  59.   newPort->portBits.bounds = *inBounds;
  60.   RectRgn(newPort->clipRgn, inBounds);    /* avoid wide-open clipRgn, to be
  61. safe  */
  62.   RectRgn(newPort->visRgn, inBounds);     /* in case newBounds is > screen
  63. bounds */
  64.  
  65.   /* rowBytes is size of row, it must be rounded up to an even number of bytes
  66. */
  67.   newPort->portBits.rowBytes = ((inBounds->right - inBounds->left + 15) >> 4)
  68. << 1;
  69.  
  70.   /* number of bytes in BitMap is rowBytes * number of rows */
  71.   /* see notes at end of Technical Note about using _NewHandle rather than _NewPtr */
  72.   newPort->portBits.baseAddr =
  73.            NewPtr(newPort->portBits.rowBytes * (long) (inBounds->bottom -
  74. inBounds->top));
  75.   if (MemError()!=noErr) {   /* check to see if we had enough room for the
  76. bits */
  77.     SetPort(savePort);
  78.     ClosePort(newPort);      /* dump the visRgn and clipRgn */
  79.     DisposPtr((Ptr)newPort); /* dump the GrafPort */
  80.     return false;            /* tell caller we failed */
  81.     }
  82.   /* since the bits are just memory, let's clear them before we start */
  83.   EraseRect(inBounds);     /* OpenPort did a SetPort(newPort) so we are ok */
  84.   *newOffscreen = newPort;
  85.   SetPort(savePort);
  86.   return true;               /* tell caller we succeeded! */
  87. }
  88.  
  89. Here is the function to get rid of an off-screen bitmap created by the
  90. previous function:
  91.  
  92. void DestroyOffscreenBitMap(GrafPtr oldOffscreen)
  93. {
  94.   ClosePort(oldOffscreen);                       /* dump the visRgn and clipRgn */
  95.   DisposPtr(oldOffscreen->portBits.baseAddr);    /* dump the bits */
  96.   DisposPtr((Ptr)oldOffscreen);                  /* dump the port */
  97. }
  98.  
  99. Now that you know how to create and destroy an off-screen bitmap, let's go through the motions
  100. of using one.  First, let's define a few things to make the _NewWindow call a
  101. little clearer.
  102.  
  103. #define kIsVisible true
  104. #define kNoGoAway false
  105. #define kNoWindowStorage 0L
  106. #define kFrontWindow ((WindowPtr) -1L)
  107.  
  108. Here's the body of the test code:
  109.  
  110. main()
  111. {
  112.   char* myString = "\pThe EYE";  /* string to display */
  113.  
  114.   GrafPtr   offscreen;           /* our off-screen bitmap */
  115.   Rect      ovalRect;            /* used for example drawing */
  116.   Rect      myWBounds;           /* for creating window */
  117.   Rect      OSRect;              /* portRect and bounds for off-screen
  118. bitmap*/
  119.   WindowPtr myWindow;
  120.  
  121.   InitToolbox();                 /* exercise for the reader */
  122.   myWBounds = qd.screenBits.bounds;  /* size of main screen */
  123.   InsetRect(&myWBounds, 50,50);  /* make it fit better */
  124.   myWindow = NewWindow(kNoWindowStorage, &myWBounds, "\pTest Window",
  125. kIsVisible,
  126.                        noGrowDocProc, kFrontWindow, kNoGoAway, 0);
  127.   if (!CreateOffscreenBitMap(&offscreen, &myWindow->portRect)) {
  128.     SysBeep(1);
  129.     ExitToShell();
  130.     }
  131.   /* Example drawing to our off-screen bitmap*/
  132.   SetPort(offscreen);
  133.   OSRect = offscreen->portRect;  /* offscreen bitmap's local coordinate rect
  134. */
  135.   ovalRect = OSRect;
  136.   FillOval(&ovalRect, qd.black);
  137.   InsetRect(&ovalRect, 1, 20);
  138.   FillOval(&ovalRect, qd.white);
  139.   InsetRect(&ovalRect, 40, 1);
  140.   FillOval(&ovalRect, qd.black);
  141.   MoveTo((ovalRect.left + ovalRect.right - StringWidth(myString)) >> 1,
  142.          (ovalRect.top + ovalRect.bottom - 12) >> 1);
  143.   TextMode(srcXor);
  144.   DrawString(myString);
  145.  
  146.   /* copy from the off-screen bitmap to the on-screen window.  Note that in this
  147.   case the source and destination rects are the same size and both cover the
  148.   entire area.  These rects are allowed to be portions of the source and/or
  149.   destination and do not have to be the same size.  If they are not the same
  150. size
  151.   then _CopyBits scales the image accordingly.
  152.   */
  153.   SetPort(myWindow);
  154.   CopyBits(&offscreen->portBits, &(*myWindow).portBits,
  155.            &offscreen->portRect, &(*myWindow).portRect, srcCopy, 0L);
  156.  
  157.   DestroyOffscreenBitMap(offscreen);    /* dump the off-screen bitmap */
  158.   while (!Button());     /* give user a chance to see our work of art */
  159. }
  160.  
  161. /* This demonstrates offscreening and copyBits */
  162.  
  163. I didn't write this, the BBS did:
  164. Foggy Bottom - your FirstClass Mac connection in Washington, DC
  165.  
  166.