home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1998 / MacHack 1998.toast / The Hacks! / 3D No 'doz II / Source / Sources / Drawing.cp < prev    next >
Encoding:
Text File  |  1998-06-20  |  7.9 KB  |  372 lines  |  [TEXT/CWIE]

  1. #include <Timer.h>
  2. #include <QDOffscreen.h>
  3. #include <A4Stuff.h>
  4. #include "Drawing.h"
  5.  
  6. #define kAnimTime    95                // Ironic, isn't it?
  7.  
  8. typedef void (*BlitProcPtr)(void);
  9.  
  10. static void BlitImage1(void);
  11. static void BlitImage2(void);
  12. static void BlitImage4(void);
  13. static void BlitImage8(void);
  14. static void BlitImage16(void);
  15. static void BlitImage32(void);
  16.  
  17. static void DrawFrame(void);
  18.  
  19. static TMTask        drawTask;
  20. static Handle        pict8 = nil, pict4 = nil, pict1 = nil;
  21. static Rect            srcRect, destRect;
  22. static GWorldPtr    srcWorld = nil;
  23. static PixMapHandle    destPMH = nil;
  24. static Ptr            srcPMBaseAddr;
  25. static short        curBitDepth, srcRight;
  26. static long            pictBytesToCopy, pictBytesPerRow;
  27. static BlitProcPtr    blitter = nil;
  28.  
  29. OSErr InitDraw(short pictID)            // resource id of system pict file
  30. {
  31.     drawTask.tmAddr = (TimerUPP) DrawFrame;
  32.     drawTask.tmWakeUp = 0;
  33.     
  34.     if ((pict8 == nil) && (pict4 == nil) && (pict1 == nil))
  35.     {
  36.         if (pict8 == nil)
  37.         {
  38.             pict8 = Get1Resource('PICT', 128);
  39.             if (pict8 != nil)
  40.             {
  41.                 HNoPurge(pict8);
  42.                 DetachResource(pict8);
  43.             }
  44.         }
  45.         
  46.         if (pict4 == nil)
  47.         {
  48.             pict4 = Get1Resource('PICT', 129);
  49.             if (pict4 != nil)
  50.             {
  51.                 HNoPurge(pict4);
  52.                 DetachResource(pict4);
  53.             }
  54.         }
  55.         
  56.         if (pict1 == nil)
  57.         {
  58.             pict1 = Get1Resource('PICT', 130);
  59.             if (pict1 != nil)
  60.             {
  61.                 HNoPurge(pict1);
  62.                 DetachResource(pict1);
  63.             }
  64.         }
  65.         
  66.         if ((pict8 == nil) || (pict4 == nil) || (pict1 == nil))
  67.             return resNotFound;
  68.     }
  69.     
  70.     return noErr;
  71. }
  72.  
  73. void DoneDraw(void)                        // done once at last init windows (performs cleanup)
  74. {
  75.     RmvTime((QElemPtr) &drawTask);                    // make sure that this is stopped!
  76.     
  77.     if (pict1 != nil)
  78.         DisposeHandle(pict1);
  79.     pict1 = nil;
  80.     
  81.     if (pict4 != nil)
  82.         DisposeHandle(pict4);
  83.     pict4 = nil;
  84.     
  85.     if (pict8 != nil)
  86.         DisposeHandle(pict8);
  87.     pict8 = nil;
  88. }
  89.  
  90. void StartDraw(Rect *dest, PixMapHandle pixMap) // dest rect and pixmap handle
  91. {
  92.     GWorldPtr        saveGWorld;
  93.     GDHandle        saveGDHand;
  94.     PicHandle        thePict;
  95.     Rect            pictRect;
  96.     THz                cZone;
  97.     short            vShift = 0;
  98.     
  99.     StopDraw();
  100.     
  101.     destPMH = pixMap;
  102.     curBitDepth = (**pixMap).pixelSize;
  103.     
  104.     switch (curBitDepth)
  105.     {
  106.         case 1:
  107.         case 2:
  108.             thePict = (PicHandle) pict1;
  109.             vShift = 45;
  110.             break;
  111.         case 4:
  112.             thePict = (PicHandle) pict4;
  113.             vShift = 45;
  114.             break;
  115.         case 8:
  116.         case 16:
  117.         case 32:
  118.             thePict = (PicHandle) pict8;
  119.             vShift = 45;
  120.             break;
  121.         default:
  122.             return;
  123.     }
  124.  
  125.     destRect = *dest;
  126.     destRect.bottom = destRect.top
  127.             + ((**thePict).picFrame.bottom - (**thePict).picFrame.top);
  128.     destRect.right = destRect.left + 117;
  129.     OffsetRect(&destRect,
  130.             ((dest->right - dest->left) - (destRect.right - destRect.left)) >> 1,
  131.             vShift);
  132.  
  133.     pictRect = (**thePict).picFrame;
  134.     
  135.     if ((pictRect.top != 0) || (pictRect.left != 0))
  136.         OffsetRect(&pictRect, -pictRect.left, -pictRect.top);
  137.     
  138.     switch (curBitDepth)
  139.     {
  140.         case 1:
  141.             blitter = BlitImage1;
  142.             pictBytesToCopy = (destRect.right - destRect.left) >> 3;
  143.             break;
  144.         case 2:
  145.             blitter = BlitImage2;
  146.             pictBytesToCopy = (destRect.right - destRect.left) >> 2;
  147.             break;
  148.         case 4:
  149.             blitter = BlitImage4;
  150.             pictBytesToCopy = (destRect.right - destRect.left) >> 1;
  151.             break;
  152.         case 8:
  153.             blitter = BlitImage8;
  154.             pictBytesToCopy = (destRect.right - destRect.left);
  155.             break;
  156.         case 16:
  157.             blitter = BlitImage16;
  158.             pictBytesToCopy = (destRect.right - destRect.left) << 1;
  159.             break;
  160.         case 32:
  161.             blitter = BlitImage32;
  162.             pictBytesToCopy = (destRect.right - destRect.left) << 2;
  163.             break;
  164.     }
  165.     
  166.     srcRect = pictRect;
  167.     srcRight = pictRect.right;
  168.     srcRect.right = pictRect.left + 117;
  169.     OffsetRect(&srcRect, srcRect.right, 0);        // start with frame 2
  170.     
  171.     cZone = GetZone();
  172.     SetZone(SystemZone());
  173.     
  174.     GetGWorld(&saveGWorld, &saveGDHand);
  175.     
  176.     if (NewGWorld(&srcWorld, curBitDepth, &pictRect, nil, nil, keepLocal) == noErr)
  177.     {
  178.         PixMapHandle    pmh = GetGWorldPixMap(srcWorld);
  179.         
  180.         LockPixels(pmh);
  181.         
  182.         srcPMBaseAddr = GetPixBaseAddr(pmh);
  183.         pictBytesPerRow = 0x00003FFF & (**pmh).rowBytes;
  184.         
  185.         SetGWorld(srcWorld, nil);
  186.         
  187.         EraseRect(&pictRect);
  188.         
  189.         DrawPicture(thePict, &pictRect);
  190.         
  191.         InsXTime((QElemPtr) &drawTask);                // insert the time manager task
  192.         PrimeTime((QElemPtr) &drawTask, kAnimTime);
  193.     }
  194.     
  195.     SetGWorld(saveGWorld, saveGDHand);
  196.     
  197.     SetZone(cZone);
  198.     
  199.     return;
  200. }
  201.  
  202. void StopDraw(void)                        // called to stop animation
  203. {
  204.     THz        cZone;
  205.     
  206.     RmvTime((QElemPtr) &drawTask);        // stop the time manager task
  207.     
  208.     if (srcWorld != nil)
  209.     {
  210.         cZone = GetZone();
  211.         SetZone(SystemZone());
  212.         
  213.         UnlockPixels(GetGWorldPixMap(srcWorld));
  214.         
  215.         DisposeGWorld(srcWorld);
  216.         
  217.         srcWorld = nil;
  218.         blitter = nil;
  219.         curBitDepth = 0;
  220.         
  221.         SetZone(cZone);
  222.     }
  223. }
  224.  
  225. static void DrawFrame(void)
  226. {
  227.     long    oldA4 = SetCurrentA4();
  228.     
  229.     if (*blitter != nil)
  230.         (*blitter)();
  231.     
  232.     PrimeTime((QElemPtr) &drawTask, kAnimTime);
  233.     
  234.     SetA4(oldA4);
  235. }
  236.  
  237. static void BlitImage(Ptr srcAddress, Ptr destAddress, long bytesPerRow)
  238. {
  239.     register short    rowsLeft = destRect.bottom - destRect.top;
  240.     Ptr                srcAddr = srcAddress;
  241.     Ptr                destAddr = destAddress;
  242.     register Ptr    s;
  243.     register Ptr    d;
  244.     
  245.     if (((0x00000003 & (long) srcAddr) == 0)
  246.             && ((0x00000003 & (long) destAddr) == 0))    // both are long-aligned
  247.     {
  248.         while (rowsLeft--)
  249.         {
  250.             register long    toCopy = pictBytesToCopy >> 2;    // copy long-word at a time
  251.             
  252.             d = destAddr;
  253.             s = srcAddr;
  254.             
  255.             while (toCopy--)
  256.                 *((long*) d)++ = *((long*) s)++;
  257.             
  258.             destAddr += bytesPerRow;
  259.             srcAddr += pictBytesPerRow;
  260.         }
  261.     }
  262.     else if (((0x00000001 & (long) srcAddr) == 0)
  263.             && ((0x00000001 & (long) destAddr) == 0))    // both are word-aligned
  264.     {
  265.         while (rowsLeft--)
  266.         {
  267.             register long    toCopy = pictBytesToCopy >> 1;    // copy word at a time
  268.             
  269.             d = destAddr;
  270.             s = srcAddr;
  271.             
  272.             while (toCopy--)
  273.                 *((short*) d)++ = *((short*) s)++;
  274.             
  275.             destAddr += bytesPerRow;
  276.             srcAddr += pictBytesPerRow;
  277.         }
  278.     }
  279.     else                // at least one is byte-aligned
  280.     {
  281.         while (rowsLeft--)
  282.         {
  283.             register long    toCopy = pictBytesToCopy;    // copy byte at a time
  284.             
  285.             d = destAddr;
  286.             s = srcAddr;
  287.             
  288.             while (toCopy--)
  289.                 *((Byte*) d)++ = *((Byte*) s)++;
  290.             
  291.             destAddr += bytesPerRow;
  292.             srcAddr += pictBytesPerRow;
  293.         }
  294.     }
  295.     
  296.     rowsLeft = srcRect.right - srcRect.left;
  297.     srcRect.right += rowsLeft;
  298.     srcRect.left += rowsLeft;
  299.     
  300.     if (srcRect.left >= srcRight)
  301.     {
  302.         srcRect.left = 0;
  303.         srcRect.right = rowsLeft;
  304.     }
  305. }
  306.  
  307. static void BlitImage1(void)
  308. {
  309.     Ptr                baseAddr = (**destPMH).baseAddr;
  310.     Ptr                srcAddr = srcPMBaseAddr + ((long) srcRect.left >> 3);
  311.     long            rowBytes = 0x00003FFF & (**destPMH).rowBytes;
  312.     
  313.     baseAddr += ((long) destRect.top * rowBytes) + ((long) destRect.left >> 3);
  314.     
  315.     BlitImage(srcAddr, baseAddr, rowBytes);
  316. }
  317.  
  318. static void BlitImage2(void)
  319. {
  320.     Ptr                baseAddr = (**destPMH).baseAddr;
  321.     Ptr                srcAddr = srcPMBaseAddr + ((long) srcRect.left >> 2);
  322.     long            rowBytes = 0x00003FFF & (**destPMH).rowBytes;
  323.     
  324.     baseAddr += ((long) destRect.top * rowBytes) + ((long) destRect.left >> 2);
  325.     
  326.     BlitImage(srcAddr, baseAddr, rowBytes);
  327. }
  328.  
  329. static void BlitImage4(void)
  330. {
  331.     Ptr                baseAddr = (**destPMH).baseAddr;
  332.     Ptr                srcAddr = srcPMBaseAddr + ((long) srcRect.left >> 1);
  333.     long            rowBytes = 0x00003FFF & (**destPMH).rowBytes;
  334.     
  335.     baseAddr += (destRect.top * rowBytes) + (destRect.left >> 1);
  336.     
  337.     BlitImage(srcAddr, baseAddr, rowBytes);
  338. }
  339.  
  340. static void BlitImage8(void)
  341. {
  342.     Ptr                baseAddr = (**destPMH).baseAddr;
  343.     Ptr                srcAddr = srcPMBaseAddr + (long) srcRect.left;
  344.     long            rowBytes = 0x00003FFF & (**destPMH).rowBytes;
  345.     
  346.     baseAddr += ((long) destRect.top * rowBytes) + (long) destRect.left;
  347.     
  348.     BlitImage(srcAddr, baseAddr, rowBytes);
  349. }
  350.  
  351. static void BlitImage16(void)
  352. {
  353.     Ptr                baseAddr = (**destPMH).baseAddr;
  354.     Ptr                srcAddr = srcPMBaseAddr + ((long) srcRect.left << 1);
  355.     long            rowBytes = 0x00003FFF & (**destPMH).rowBytes;
  356.     
  357.     baseAddr += ((long) destRect.top * rowBytes) + ((long) destRect.left << 1);
  358.     
  359.     BlitImage(srcAddr, baseAddr, rowBytes);
  360. }
  361.  
  362. static void BlitImage32(void)
  363. {
  364.     Ptr                baseAddr = (**destPMH).baseAddr;
  365.     Ptr                srcAddr = srcPMBaseAddr + ((long) srcRect.left << 2);
  366.     long            rowBytes = 0x00003FFF & (**destPMH).rowBytes;
  367.     
  368.     baseAddr += ((long) destRect.top * rowBytes) + ((long) destRect.left << 2);
  369.     
  370.     BlitImage(srcAddr, baseAddr, rowBytes);
  371. }
  372.