home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld files / Sources / BlitPixie8Bit.c next >
Encoding:
Text File  |  1999-01-14  |  37.8 KB  |  1,403 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    BlitPixie8Bit.c
  3. //
  4. //    Ideas and code snippets contributed by:
  5. //        Ben Sharpe, Brigham Stevens, Sean Callahan, Joe Britt and Tim Collins
  6. //
  7. //    Portions are copyright: © 1991-94 Tony Myles
  8. //
  9. //    Description: Implementation of BlitPixie8Bit - a fast 8-bit blitter
  10. ///--------------------------------------------------------------------------------------
  11.  
  12.  
  13. #ifndef __SWCOMMON__
  14. #include "SWCommonHeaders.h"
  15. #endif
  16.  
  17. #ifndef __SPRITEWORLDUTILS__
  18. #include "SpriteWorldUtils.h"
  19. #endif
  20.  
  21. #ifndef __TOOLUTILS__
  22. #include <ToolUtils.h>
  23. #endif
  24.  
  25. #ifndef __OSUTILS__
  26. #include <OSUtils.h>
  27. #endif
  28.  
  29. #ifndef __QUICKDRAW__
  30. #include <Quickdraw.h>
  31. #endif
  32.  
  33. #ifndef __QDOFFSCREEN__
  34. #include <QDOffscreen.h>
  35. #endif
  36.  
  37. #ifndef __SPRITEWORLD__
  38. #include "SpriteWorld.h"
  39. #endif
  40.  
  41. #ifndef __SPRITEFRAME__
  42. #include "SpriteFrame.h"
  43. #endif
  44.  
  45. #ifndef __BLITPIXIE__
  46. #include "BlitPixie.h"
  47. #endif
  48.  
  49. #ifndef __SPRITECOMPILER__
  50. #include "SpriteCompiler.h"
  51. #endif
  52.  
  53.  
  54. extern SInt8         gSWmmuMode;
  55.  
  56.  
  57.  
  58. ///--------------------------------------------------------------------------------------
  59. //        BlitPixie8BitRectDrawProc
  60. ///--------------------------------------------------------------------------------------
  61.  
  62. SW_FUNC void BlitPixie8BitRectDrawProc(
  63.     FramePtr srcFrameP,
  64.     FramePtr dstFrameP,
  65.     Rect* srcRect,
  66.     Rect* dstRect)
  67. {
  68.     Rect                 srcBlitRect = *srcRect;
  69.     Rect                 dstBlitRect = *dstRect;
  70.     unsigned long         numBytesPerRow;
  71.     
  72.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  73.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  74.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  75.     
  76.     BP_CLIP_RECT(dstFrameP->frameRect, srcBlitRect, dstBlitRect);
  77.     START_32_BIT_MODE
  78.     
  79.         // calculate the number of bytes in each row to be copied
  80.     numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  81.  
  82.     BlitPixie8Bit(
  83.             // calculate the address of the first byte of the source
  84.         (PixelChunkPtr)(srcFrameP->frameBaseAddr + 
  85.             (srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top]) + 
  86.             srcBlitRect.left),
  87.  
  88.             // calculate the address of the first byte of the destination
  89.         (PixelChunkPtr)(dstFrameP->frameBaseAddr + 
  90.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  91.  
  92.             // calculate the number of rows to blit
  93.         dstBlitRect.bottom - dstBlitRect.top,
  94.  
  95.             // number of bytes in a row (also the number of pixels to be copied)
  96.         numBytesPerRow,
  97.  
  98.         srcFrameP->frameRowBytes,
  99.         dstFrameP->frameRowBytes);
  100.  
  101.     END_32_BIT_MODE
  102. }
  103.  
  104.  
  105. ///--------------------------------------------------------------------------------------
  106. //        BP8BitInterlacedRectDrawProc
  107. ///--------------------------------------------------------------------------------------
  108.  
  109. SW_FUNC void BP8BitInterlacedRectDrawProc(
  110.     FramePtr srcFrameP,
  111.     FramePtr dstFrameP,
  112.     Rect* srcRect,
  113.     Rect* dstRect)
  114. {
  115.     Rect             srcBlitRect = *srcRect;
  116.     Rect             dstBlitRect = *dstRect;
  117.     unsigned long     numBytesPerRow, numRowsToCopy;
  118.  
  119.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  120.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  121.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  122.     
  123.     BP_CLIP_RECT_INTERLACED(dstFrameP->frameRect, srcBlitRect, dstBlitRect);
  124.     
  125.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;        
  126.     numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  127.     if (numRowsToCopy < 1)
  128.         return;
  129.         
  130.         
  131.     START_32_BIT_MODE
  132.     
  133.         // calculate the number of bytes in a row
  134.     numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  135.     
  136.     
  137.     BlitPixie8Bit(
  138.             // calculate the address of the first byte of the source
  139.         (PixelChunkPtr)(srcFrameP->frameBaseAddr + 
  140.             (srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top]) + 
  141.             srcBlitRect.left),
  142.                 
  143.             // calculate the address of the first byte of the destination
  144.         (PixelChunkPtr)(dstFrameP->frameBaseAddr + 
  145.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  146.             
  147.             // number of rows to copy, already calculated for Interlaced mode
  148.         numRowsToCopy,
  149.         
  150.             // number of bytes in a row (duh!)
  151.         numBytesPerRow,
  152.         
  153.         srcFrameP->frameRowBytes<<1,
  154.         dstFrameP->frameRowBytes<<1);
  155.  
  156.     END_32_BIT_MODE
  157. }
  158.  
  159.  
  160. ///--------------------------------------------------------------------------------------
  161. //        BlitPixie8BitMaskDrawProc
  162. ///--------------------------------------------------------------------------------------
  163.  
  164. SW_FUNC void BlitPixie8BitMaskDrawProc(
  165.     FramePtr srcFrameP,
  166.     FramePtr dstFrameP,
  167.     Rect *srcRect,
  168.     Rect *dstRect)
  169. {
  170.     Rect                 dstBlitRect = *dstRect;
  171.     Rect                srcBlitRect = *srcRect;
  172.     unsigned long         numBytesPerRow, srcBaseOffset;
  173.     
  174.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  175.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  176.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  177.     SW_ASSERT(srcFrameP->maskPort != NULL);
  178.     
  179.     BP_CLIP_RECT(dstFrameP->frameRect, srcBlitRect, dstBlitRect);
  180.     START_32_BIT_MODE
  181.  
  182.         // calculate the offset to the first byte of the source
  183.     srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top - 
  184.         srcFrameP->frameRect.top] + srcBlitRect.left;
  185.  
  186.         // calculate the number of bytes in a row
  187.     numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  188.  
  189.     BlitPixieMask8Bit(
  190.             // calculate the address of the first byte of the source
  191.         (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  192.  
  193.             // calculate the address of the first byte of the destination
  194.         (PixelPtr)(dstFrameP->frameBaseAddr + 
  195.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  196.  
  197.             // calculate the address of the first byte of the mask
  198.         (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  199.  
  200.             // calculate the number of rows to blit
  201.         dstBlitRect.bottom - dstBlitRect.top,
  202.  
  203.             // number of bytes in a row (duh!)
  204.         numBytesPerRow,
  205.  
  206.         srcFrameP->frameRowBytes,
  207.         dstFrameP->frameRowBytes);
  208.  
  209.     END_32_BIT_MODE
  210. }
  211.  
  212. ///--------------------------------------------------------------------------------------
  213. //        BlitPixie8BitPartialMaskDrawProc
  214. ///--------------------------------------------------------------------------------------
  215.  
  216. SW_FUNC void BlitPixie8BitPartialMaskDrawProc(
  217.     FramePtr srcFrameP,
  218.     FramePtr dstFrameP,
  219.     Rect *srcRect,
  220.     Rect *dstRect)
  221. {
  222.     Rect             dstBlitRect = *dstRect;
  223.     Rect            srcBlitRect = *srcRect;
  224.     unsigned long     numBytesPerRow, srcBaseOffset;
  225.     
  226.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  227.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  228.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  229.     SW_ASSERT(srcFrameP->maskPort != NULL);
  230.     
  231.     BP_CLIP_RECT(dstFrameP->frameRect, srcBlitRect, dstBlitRect);
  232.     START_32_BIT_MODE
  233.     
  234.         // calculate the offset to the first byte of the source
  235.     srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top] + 
  236.         srcBlitRect.left;
  237.  
  238.         // calculate the number of bytes in a row
  239.     numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  240.  
  241.     BlitPixiePartialMask8Bit(
  242.             // calculate the address of the first byte of the source
  243.         (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  244.  
  245.             // calculate the address of the first byte of the destination
  246.         (PixelPtr)(dstFrameP->frameBaseAddr + 
  247.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  248.  
  249.             // calculate the address of the first byte of the mask
  250.         (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  251.  
  252.             // calculate the number of rows to blit
  253.         dstBlitRect.bottom - dstBlitRect.top,
  254.  
  255.             // number of bytes in a row (duh!)
  256.         numBytesPerRow,
  257.  
  258.         srcFrameP->frameRowBytes,
  259.         dstFrameP->frameRowBytes);
  260.  
  261.     END_32_BIT_MODE
  262. }
  263.  
  264.  
  265. ///--------------------------------------------------------------------------------------
  266. //        BP8BitInterlacedMaskDrawProc
  267. ///--------------------------------------------------------------------------------------
  268.  
  269. SW_FUNC void BP8BitInterlacedMaskDrawProc(
  270.     FramePtr srcFrameP,
  271.     FramePtr dstFrameP,
  272.     Rect* srcRect,
  273.     Rect* dstRect)
  274. {
  275.     Rect                 srcBlitRect = *srcRect;
  276.     Rect                 dstBlitRect = *dstRect;
  277.     unsigned long         numBytesPerRow, numRowsToCopy, srcBaseOffset;
  278.  
  279.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  280.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  281.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  282.     SW_ASSERT(srcFrameP->maskPort != NULL);
  283.     
  284.     BP_CLIP_RECT_INTERLACED(dstFrameP->frameRect, srcBlitRect, dstBlitRect);
  285.     
  286.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;        
  287.     numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  288.     if (numRowsToCopy < 1)
  289.         return;
  290.     
  291.     
  292.     START_32_BIT_MODE
  293.     
  294.         // calculate the offset to the first byte of the source
  295.     srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top] + 
  296.         srcBlitRect.left;
  297.     
  298.         // calculate the number of bytes in a row
  299.     numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  300.     
  301.     
  302.     BlitPixieMask8Bit(
  303.             // calculate the address of the first byte of the source
  304.         (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  305.         
  306.             // calculate the address of the first byte of the destination
  307.         (PixelPtr)(dstFrameP->frameBaseAddr + 
  308.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  309.         
  310.             // calculate the address of the first byte of the mask
  311.         (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  312.             
  313.             // number of rows to copy, already calculated for Interlaced mode
  314.         numRowsToCopy,
  315.         
  316.             // number of bytes in a row (duh!)
  317.         numBytesPerRow,
  318.     
  319.         srcFrameP->frameRowBytes<<1,
  320.         dstFrameP->frameRowBytes<<1);
  321.  
  322.     END_32_BIT_MODE
  323. }
  324.  
  325. ///--------------------------------------------------------------------------------------
  326. //        BP8BitInterlacedPartialMaskDrawProc
  327. ///--------------------------------------------------------------------------------------
  328.  
  329. SW_FUNC void BP8BitInterlacedPartialMaskDrawProc(
  330.     FramePtr srcFrameP,
  331.     FramePtr dstFrameP,
  332.     Rect* srcRect,
  333.     Rect* dstRect)
  334. {
  335.     Rect                 srcBlitRect = *srcRect;
  336.     Rect                 dstBlitRect = *dstRect;
  337.     unsigned long         numBytesPerRow, numRowsToCopy, srcBaseOffset;
  338.  
  339.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  340.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  341.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  342.     SW_ASSERT(srcFrameP->maskPort != NULL);
  343.     
  344.     BP_CLIP_RECT_INTERLACED(dstFrameP->frameRect, srcBlitRect, dstBlitRect);
  345.     
  346.     numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;        
  347.     numRowsToCopy = (numRowsToCopy >> 1) + (numRowsToCopy & 1);
  348.     if (numRowsToCopy < 1)
  349.         return;
  350.     
  351.     
  352.     START_32_BIT_MODE
  353.     
  354.         // calculate the offset to the first byte of the source
  355.     srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top] + 
  356.         srcBlitRect.left;
  357.     
  358.         // calculate the number of bytes in a row
  359.     numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  360.     
  361.     
  362.     BlitPixiePartialMask8Bit(
  363.             // calculate the address of the first byte of the source
  364.         (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  365.         
  366.             // calculate the address of the first byte of the destination
  367.         (PixelPtr)(dstFrameP->frameBaseAddr + 
  368.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  369.         
  370.             // calculate the address of the first byte of the mask
  371.         (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  372.             
  373.             // number of rows to copy, already calculated for Interlaced mode
  374.         numRowsToCopy,
  375.         
  376.             // number of bytes in a row (duh!)
  377.         numBytesPerRow,
  378.         
  379.         srcFrameP->frameRowBytes<<1,
  380.         dstFrameP->frameRowBytes<<1);
  381.  
  382.  
  383.     END_32_BIT_MODE
  384. }
  385.  
  386.  
  387. ///--------------------------------------------------------------------------------------
  388. //        CompiledSprite8BitDrawProc
  389. ///--------------------------------------------------------------------------------------
  390.  
  391. SW_FUNC void CompiledSprite8BitDrawProc(
  392.     FramePtr srcFrameP,
  393.     FramePtr dstFrameP,
  394.     Rect *srcRect,
  395.     Rect *dstRect)
  396. {
  397. #if SW_PPC
  398. #pragma unused(srcFrameP, dstFrameP, srcRect, dstRect)
  399. #else
  400.     Rect         dstBlitRect = *dstRect;
  401.     Rect         srcBlitRect = *srcRect;
  402.     
  403.     SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
  404.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  405.     SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
  406.     SW_ASSERT(srcFrameP->frameBlitterP != NULL);
  407.  
  408.     // we first check to see if any clipping will be necessary, then
  409.     // we determine whether or not we can use the compiled blitter. we must
  410.     // do this since the compiled blitter cannot handle clipping.
  411.  
  412.     BP_CLIP_RECT(dstFrameP->frameRect, srcBlitRect, dstBlitRect);
  413.     START_32_BIT_MODE
  414.         
  415.     // If we didn't have to clip the sprite, we can call the compiled blitter.
  416.     // Hopefully this will be the most common case (i.e. the sprites will be entirely
  417.     // on the screen more often than not)
  418.  
  419.     if (srcBlitRect.top == srcFrameP->frameRect.top &&
  420.         srcBlitRect.bottom == srcFrameP->frameRect.bottom &&
  421.         srcBlitRect.left == srcFrameP->frameRect.left &&
  422.         srcBlitRect.right == srcFrameP->frameRect.right)
  423.     {
  424.         (*srcFrameP->frameBlitterP)(
  425.             srcFrameP->frameRowBytes,
  426.             dstFrameP->frameRowBytes,
  427.             srcFrameP->frameBaseAddr +
  428.                 srcFrameP->scanLinePtrArray[0] + srcRect->left,    // 0 'cause it always starts at top
  429.             dstFrameP->frameBaseAddr +
  430.                 dstFrameP->scanLinePtrArray[dstRect->top] + dstRect->left);
  431.     }
  432.     else
  433.     {
  434.         unsigned long numBytesPerRow;
  435.         unsigned long srcBaseOffset;
  436.         
  437.     
  438.             // calculate the offset to the first byte of the source
  439.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top-srcFrameP->frameRect.top] + 
  440.             srcBlitRect.left;
  441.  
  442.             // calculate the number of bytes in a row
  443.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  444.  
  445.         BlitPixieMask8Bit(
  446.                 // calculate the address of the first byte of the source
  447.             (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  448.  
  449.                 // calculate the address of the first byte of the destination
  450.             (PixelPtr)(dstFrameP->frameBaseAddr + 
  451.                 (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  452.  
  453.                 // calculate the address of the first byte of the mask
  454.             (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  455.  
  456.                 // calculate the number of rows to blit
  457.             dstBlitRect.bottom - dstBlitRect.top,
  458.  
  459.                 // number of bytes in a row (duh!)
  460.             numBytesPerRow,
  461.  
  462.             srcFrameP->frameRowBytes,
  463.             dstFrameP->frameRowBytes);
  464.     }
  465.     
  466.     END_32_BIT_MODE
  467.     
  468. #endif
  469. }
  470.  
  471. #pragma mark -
  472. #pragma mark *** Misc Routines:
  473. ///--------------------------------------------------------------------------------------
  474. //        BlitPixie8BitGetPixel
  475. ///--------------------------------------------------------------------------------------
  476.  
  477. SW_FUNC unsigned char BlitPixie8BitGetPixel(
  478.     FramePtr srcFrameP,
  479.     Point thePoint )
  480. {
  481.     unsigned long     srcBaseOffset;
  482.     unsigned char    theColor;
  483.     
  484.     SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
  485.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  486.     
  487.     START_32_BIT_MODE
  488.  
  489.     srcBaseOffset = srcFrameP->scanLinePtrArray[thePoint.v] + 
  490.         thePoint.h+srcFrameP->frameRect.left;
  491.     theColor = *((unsigned char*)(srcFrameP->frameBaseAddr + srcBaseOffset));
  492.         
  493.     END_32_BIT_MODE
  494.     
  495.     return theColor;
  496. }
  497.  
  498. ///--------------------------------------------------------------------------------------
  499. //        BlitPixie8BitSetPixel
  500. ///--------------------------------------------------------------------------------------
  501.  
  502. SW_FUNC void BlitPixie8BitSetPixel(
  503.     FramePtr srcFrameP,
  504.     Point thePoint,
  505.     unsigned char theColor)
  506. {
  507.     unsigned long     srcBaseOffset;
  508.     
  509.     SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
  510.     SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
  511.     
  512.     if ((thePoint.h >= 0) &&
  513.         (thePoint.h < srcFrameP->frameRect.right-srcFrameP->frameRect.left) &&
  514.         (thePoint.v >= 0) &&
  515.         (thePoint.v < srcFrameP->frameRect.bottom-srcFrameP->frameRect.top) )
  516.     {
  517.         START_32_BIT_MODE
  518.         
  519.         srcBaseOffset = srcFrameP->scanLinePtrArray[thePoint.v] + 
  520.             thePoint.h + srcFrameP->frameRect.left;
  521.         *((unsigned char*)(srcFrameP->frameBaseAddr + srcBaseOffset)) = theColor;
  522.             
  523.         END_32_BIT_MODE
  524.     }
  525. }
  526.  
  527.  
  528. ///--------------------------------------------------------------------------------------
  529. //    SWAnimate8BitStarField
  530. ///--------------------------------------------------------------------------------------
  531.  
  532. SW_FUNC void SWAnimate8BitStarField(
  533.     SpriteWorldPtr    spriteWorldP,
  534.     StarArray        *starArray,
  535.     short            numStars,
  536.     unsigned short    backColor)
  537. {
  538.     short            curStar;
  539.     short            horizOffset, vertOffset;    // Offset from window to work area
  540.     FramePtr        windFrameP = spriteWorldP->windowFrameP;
  541.     FramePtr        workFrameP = spriteWorldP->workFrameP;
  542.     unsigned long     srcBaseOffset;
  543.     
  544.     SW_ASSERT(windFrameP->isFrameLocked && workFrameP->isFrameLocked);
  545.     SW_ASSERT(spriteWorldP->pixelDepth == 8);
  546.  
  547.     START_32_BIT_MODE
  548.     
  549.         // Stores offset if spriteWorld is smaller than window
  550.     horizOffset = windFrameP->frameRect.left;
  551.     vertOffset = windFrameP->frameRect.top;
  552.     
  553.     
  554.     for (curStar = 0; curStar < numStars; curStar++)
  555.     {
  556.             // Make sure we aren't erasing part of a sprite
  557.         if (starArray[curStar].needsToBeErased)
  558.         {
  559.             srcBaseOffset = windFrameP->scanLinePtrArray[starArray[curStar].oldVertLoc] + 
  560.                 starArray[curStar].oldHorizLoc;
  561.             *((unsigned char*)(windFrameP->frameBaseAddr + srcBaseOffset)) = backColor;
  562.         }
  563.         
  564.             // Make sure we aren't going to draw over a sprite
  565.         srcBaseOffset = workFrameP->scanLinePtrArray[starArray[curStar].vertLoc - vertOffset] + 
  566.             starArray[curStar].horizLoc - horizOffset;
  567.         if ( *((unsigned char*)(workFrameP->frameBaseAddr + srcBaseOffset)) == backColor)
  568.         {
  569.                 // Draw the new star position
  570.             srcBaseOffset = windFrameP->scanLinePtrArray[starArray[curStar].vertLoc] + 
  571.                 starArray[curStar].horizLoc;
  572.             *((unsigned char*)(windFrameP->frameBaseAddr + srcBaseOffset)) = 
  573.                 starArray[curStar].color;
  574.             
  575.             starArray[curStar].needsToBeErased = true;
  576.         }
  577.         else
  578.         {
  579.             starArray[curStar].needsToBeErased = false;
  580.         }
  581.     }
  582.     
  583.     END_32_BIT_MODE
  584. }
  585.  
  586.  
  587. ///--------------------------------------------------------------------------------------
  588. //        BlitPixie8BitFlipSprite
  589. ///--------------------------------------------------------------------------------------
  590.  
  591. SW_FUNC void BlitPixie8BitFlipSprite(
  592.     SpritePtr srcSpriteP )
  593. {
  594.     FramePtr        curFrameP;
  595.     unsigned char    holdPixel;
  596.     short            frameCounter, 
  597.                     scanLineCounter,
  598.                     halfWidth, 
  599.                     leftPixel,
  600.                     rightPixel,
  601.                     frameLeft;
  602.     GDHandle        currentGDH;
  603.     GWorldPtr        currentGWorld;
  604.         
  605.     frameCounter = srcSpriteP->numFrames;
  606.     while (frameCounter--)
  607.     {
  608.         START_32_BIT_MODE
  609.  
  610.         curFrameP = srcSpriteP->frameArray[frameCounter];
  611.         SW_ASSERT(curFrameP->isFrameLocked);
  612.         SW_ASSERT((*curFrameP->framePort->portPixMap)->pixelSize == 8);
  613.         
  614.         frameLeft = curFrameP->frameRect.left;
  615.         halfWidth = (curFrameP->frameRect.right - curFrameP->frameRect.left)/2;
  616.         scanLineCounter = curFrameP->numScanLines;
  617.         while (scanLineCounter--)
  618.         {
  619.             rightPixel = leftPixel = halfWidth;
  620.             while (leftPixel--)
  621.             {
  622.                 holdPixel = *((unsigned char*)(curFrameP->frameBaseAddr + 
  623.                     curFrameP->scanLinePtrArray[scanLineCounter] + leftPixel+frameLeft));
  624.                 if ( holdPixel != *((unsigned char*)(curFrameP->frameBaseAddr + 
  625.                         curFrameP->scanLinePtrArray[scanLineCounter] + rightPixel+frameLeft)) )
  626.                 {
  627.                     *((unsigned char*)(curFrameP->frameBaseAddr + 
  628.                         curFrameP->scanLinePtrArray[scanLineCounter] + leftPixel+frameLeft)) = 
  629.                         *((unsigned char*)(curFrameP->frameBaseAddr + 
  630.                         curFrameP->scanLinePtrArray[scanLineCounter] + rightPixel+frameLeft));
  631.                     *((unsigned char*)(curFrameP->frameBaseAddr + 
  632.                         curFrameP->scanLinePtrArray[scanLineCounter] + rightPixel+frameLeft)) = 
  633.                         holdPixel;                    
  634.                 }
  635.                 rightPixel++;
  636.             }            
  637.         }
  638.         
  639.         if ( curFrameP->maskPort != NULL )
  640.         {
  641.             scanLineCounter = curFrameP->numScanLines;
  642.             while (scanLineCounter--)
  643.             {
  644.                 rightPixel = leftPixel = halfWidth;
  645.                 while (leftPixel--)
  646.                 {
  647.                     holdPixel = *((unsigned char*)(curFrameP->maskBaseAddr + 
  648.                         curFrameP->scanLinePtrArray[scanLineCounter] + leftPixel+frameLeft));
  649.                     if ( holdPixel != *((unsigned char*)(curFrameP->maskBaseAddr + 
  650.                         curFrameP->scanLinePtrArray[scanLineCounter] + rightPixel+frameLeft)) )
  651.                     {
  652.                         *((unsigned char*)(curFrameP->maskBaseAddr + 
  653.                             curFrameP->scanLinePtrArray[scanLineCounter] + 
  654.                             leftPixel+frameLeft)) = 
  655.                             *((unsigned char*)(curFrameP->maskBaseAddr + 
  656.                             curFrameP->scanLinePtrArray[scanLineCounter] + 
  657.                             rightPixel+frameLeft));
  658.                         *((unsigned char*)(curFrameP->maskBaseAddr + 
  659.                             curFrameP->scanLinePtrArray[scanLineCounter] + 
  660.                             rightPixel+frameLeft)) = holdPixel;
  661.                     }
  662.                     rightPixel++;
  663.                 }
  664.             }
  665.         }
  666.         
  667.         END_32_BIT_MODE
  668.  
  669.         if ( curFrameP->maskRgn != NULL && curFrameP->maskPort != NULL )
  670.         {
  671.             GetGWorld( ¤tGWorld, ¤tGDH );
  672.             SetGWorld( curFrameP->maskPort, NULL );
  673.             InvertRect( &(curFrameP->frameRect) );
  674.             (void)SWCreateRegionFromGWorldAndRect( &(curFrameP->maskRgn), 
  675.                 curFrameP->maskPort, &(curFrameP->frameRect) );
  676.             SWSetFrameMaskRgn(curFrameP, curFrameP->maskRgn);
  677.             InvertRect( &(curFrameP->frameRect) );
  678.             SetGWorld( currentGWorld, currentGDH );
  679.         }
  680.     }
  681. }
  682.  
  683. #pragma mark -
  684. #pragma mark *** PowerPC:
  685. #if SW_PPC
  686. ///--------------------------------------------------------------------------------------
  687. //        BlitPixie8Bit
  688. ///--------------------------------------------------------------------------------------
  689. // Since this blit routine just does straight copying and requires no boolean operations,
  690. // we can make use of the floating point registers on the Power PC.  This means we
  691. // can blit a double, 8 bytes at a time, rather than a long.  This makes the blitter 
  692. // almost twice as fast when this is done.  We could speed this up even more by unrolling 
  693. // the loop for big blits, but it would make the code much less readable.
  694. // Note that we only use doubles to copy only when we are 4-byte aligned for both
  695. // source and destination.  Otherwise PPC 603, 604 and laters will run slower.
  696. // (Yes, you can use doubles as long as you're aligned to a 4-byte boundary, even if it's
  697. // not an 8-byte boundary!)
  698.  
  699. void BlitPixie8Bit(
  700.     PixelChunkPtr srcPixelPTemp,
  701.     PixelChunkPtr dstPixelPTemp,
  702.     register unsigned long rowsToCopy,
  703.     register unsigned long numBytesPerRow,
  704.     register unsigned long srcOffset,
  705.     register unsigned long dstOffset)
  706. {
  707.     if (((unsigned long)srcPixelPTemp & 3) || ((unsigned long)dstPixelPTemp & 3))
  708.     {
  709.         register long index;
  710.         register PixelChunkPtr srcPixelP = srcPixelPTemp;
  711.         register PixelChunkPtr dstPixelP = dstPixelPTemp;
  712.         register PixelChunkPtr startSrcPixelP;
  713.         register PixelChunkPtr startDstPixelP;
  714.         
  715.             
  716.         startSrcPixelP = srcPixelP;
  717.         startDstPixelP = dstPixelP;
  718.  
  719.         while (rowsToCopy--)
  720.         {
  721.             register fourblits = (numBytesPerRow >> 2);
  722.             
  723.             srcPixelP = startSrcPixelP;
  724.             dstPixelP = startDstPixelP;
  725.             
  726.             for (index = 0; index < fourblits; index++)
  727.             {
  728.                 register unsigned long temp1;
  729.                 
  730.                 temp1 = srcPixelP[index];
  731.                 dstPixelP[index] = temp1;
  732.             }
  733.             srcPixelP += fourblits;
  734.             dstPixelP += fourblits;
  735.             if (numBytesPerRow & 0x2)
  736.                 *((unsigned short *) dstPixelP)++ = *((unsigned short *) srcPixelP)++;
  737.             if (numBytesPerRow & 0x1)
  738.                 *((unsigned char *)dstPixelP)++ = *((unsigned char *)srcPixelP)++;
  739.  
  740.                 // bump to next row    
  741.             (char *)startSrcPixelP += srcOffset;
  742.             (char *)startDstPixelP += dstOffset;
  743.         }
  744.     }
  745.     else
  746.     {
  747.         register long index;
  748.         register double *startSrcPixelP;
  749.         register double *startDstPixelP;
  750.         register double *srcPixelP = (double *)srcPixelPTemp;
  751.         register double *dstPixelP = (double *)dstPixelPTemp;
  752.  
  753.         startSrcPixelP = srcPixelP;
  754.         startDstPixelP = dstPixelP;
  755.  
  756.         while (rowsToCopy--)
  757.         {
  758.             register eightblits = (numBytesPerRow >> 3);
  759.             
  760.             srcPixelP = startSrcPixelP;
  761.             dstPixelP = startDstPixelP;
  762.             
  763.             for (index = 0; index < eightblits; index++)
  764.             {
  765.                 dstPixelP[index] = srcPixelP[index];
  766.             }
  767.             srcPixelP += eightblits;
  768.             dstPixelP += eightblits;
  769.             
  770.             if (numBytesPerRow & 0x4)
  771.                 *((unsigned long *) dstPixelP)++ = *((unsigned long *) srcPixelP)++;
  772.             if (numBytesPerRow & 0x2)
  773.                 *((unsigned short *) dstPixelP)++ = *((unsigned short *) srcPixelP)++;
  774.             if (numBytesPerRow & 0x1)
  775.                 *((unsigned char *)dstPixelP)++ = *((unsigned char *)srcPixelP)++;
  776.  
  777.                 // bump to next row    
  778.             (char *)startSrcPixelP += srcOffset;
  779.             (char *)startDstPixelP += dstOffset;
  780.         }
  781.     }
  782. }
  783.  
  784. ///--------------------------------------------------------------------------------------
  785. //        BlitPixieMask8Bit
  786. ///--------------------------------------------------------------------------------------
  787.  
  788. void BlitPixieMask8Bit(
  789.     register PixelPtr srcPixelP,
  790.     register PixelPtr dstPixelP,
  791.     register PixelPtr maskPixelP,
  792.     register unsigned long rowsToCopy,
  793.     register unsigned long numBytesPerRow,
  794.     register unsigned long srcOffset,
  795.     register unsigned long dstOffset)
  796. {
  797.     register long index;
  798.     register PixelPtr startSrcPixelP;
  799.     register PixelPtr startDstPixelP;
  800.     register PixelPtr startMaskPixelP;
  801.     
  802.     startSrcPixelP = srcPixelP;
  803.     startDstPixelP = dstPixelP;
  804.     startMaskPixelP = maskPixelP;
  805.     
  806.     while (rowsToCopy--)    
  807.     {
  808.         register fourblits = (numBytesPerRow >> 2);
  809.         
  810.         srcPixelP = startSrcPixelP;
  811.         dstPixelP = startDstPixelP;
  812.         maskPixelP = startMaskPixelP;
  813.         
  814.         for (index = 0; index < fourblits; index++)
  815.         {
  816.             register unsigned long temp1;
  817.             
  818.             temp1 = dstPixelP[index] & maskPixelP[index] | srcPixelP[index];
  819.             dstPixelP[index] = temp1;
  820.         }
  821.         srcPixelP += fourblits;
  822.         dstPixelP += fourblits;
  823.         maskPixelP += fourblits;
  824.         if (numBytesPerRow & 0x2)
  825.         {
  826.             register unsigned short temp1;
  827.             
  828.             temp1 = (*((unsigned short *) dstPixelP)) & (*((unsigned short *) maskPixelP)++) |
  829.             *((unsigned short *) srcPixelP)++;
  830.             
  831.             (*((unsigned short *) dstPixelP)++) = temp1;
  832.         }
  833.         if (numBytesPerRow & 0x1)
  834.         {
  835.             register unsigned char temp1;
  836.             
  837.             temp1 = (*((unsigned char *) dstPixelP)) & (*((unsigned char *) maskPixelP)++) |
  838.             *((unsigned char *) srcPixelP)++;
  839.             
  840.             (*((unsigned char *) dstPixelP)++) = temp1;
  841.         }
  842.  
  843.             // bump to next row
  844.         startSrcPixelP = (PixelPtr)(((char*)startSrcPixelP) + srcOffset);
  845.         startDstPixelP = (PixelPtr)(((char*)startDstPixelP) + dstOffset);
  846.         startMaskPixelP = (PixelPtr)(((char*)startMaskPixelP) + srcOffset);
  847.     }
  848. }
  849.  
  850.  
  851. ///--------------------------------------------------------------------------------------
  852. //        BlitPixiePartialMask8Bit
  853. ///--------------------------------------------------------------------------------------
  854.  
  855. void BlitPixiePartialMask8Bit(
  856.     register PixelPtr srcPixelP,
  857.     register PixelPtr dstPixelP,
  858.     register PixelPtr maskPixelP,
  859.     register unsigned long rowsToCopy,
  860.     register unsigned long numBytesPerRow,
  861.     register unsigned long srcOffset,
  862.     register unsigned long dstOffset)
  863. {
  864.     register long index;
  865.     register PixelPtr startSrcPixelP;
  866.     register PixelPtr startDstPixelP;
  867.     register PixelPtr startMaskPixelP;
  868.     
  869.     startSrcPixelP = srcPixelP;
  870.     startDstPixelP = dstPixelP;
  871.     startMaskPixelP = maskPixelP;
  872.     
  873.     while (rowsToCopy--)    
  874.     {
  875.         register fourblits = (numBytesPerRow >> 2);
  876.         
  877.         srcPixelP = startSrcPixelP;
  878.         dstPixelP = startDstPixelP;
  879.         maskPixelP = startMaskPixelP;
  880.         
  881.         for (index = 0; index < fourblits; index++)
  882.         {
  883.             register unsigned long temp1;
  884.             
  885.             temp1 = dstPixelP[index] & maskPixelP[index] | 
  886.                 ( (~maskPixelP[index])&srcPixelP[index]);
  887.             dstPixelP[index] = temp1;
  888.         }
  889.         srcPixelP += fourblits;
  890.         dstPixelP += fourblits;
  891.         maskPixelP += fourblits;
  892.         if (numBytesPerRow & 0x2)
  893.         {
  894.             register unsigned short temp1;
  895.             
  896.             temp1 = (*((unsigned short *) dstPixelP)) & (*((unsigned short *) maskPixelP)) |
  897.             (~(*((unsigned short *) maskPixelP)++) &
  898.             *((unsigned short *) srcPixelP)++);
  899.                 
  900.             (*((unsigned short *) dstPixelP)++) = temp1;
  901.         }
  902.         if (numBytesPerRow & 0x1)
  903.         {
  904.             register unsigned char temp1;
  905.             
  906.             temp1 = (*((unsigned char *) dstPixelP)) & (*((unsigned char *) maskPixelP)) |
  907.             (~(*((unsigned char *) maskPixelP)++) &
  908.             *((unsigned char *) srcPixelP)++);
  909.                 
  910.             (*((unsigned char *) dstPixelP)++) = temp1;
  911.         }
  912.         
  913.             // bump to next row
  914.         startSrcPixelP = (PixelPtr)(((char*)startSrcPixelP) + srcOffset);
  915.         startDstPixelP = (PixelPtr)(((char*)startDstPixelP) + dstOffset);
  916.         startMaskPixelP = (PixelPtr)(((char*)startMaskPixelP) + srcOffset);
  917.     }
  918. }
  919.  
  920.  
  921. #pragma mark *** 68k:
  922. #else /* SW_PPC */
  923.  
  924. ///--------------------------------------------------------------------------------------
  925. //        BlitPixie8Bit
  926. ///--------------------------------------------------------------------------------------
  927.  
  928. SW_ASM_FUNC void BlitPixie8Bit(
  929.     register PixelPtr srcPixelP,            // address of source pixel
  930.     register PixelPtr dstPixelP,            // address of destination pixel
  931.     register unsigned long rowsToCopy,        // number of rows to copy
  932.     register unsigned long numBytesPerRow,    // number of pixels to copy in each row
  933.     register unsigned long srcRowStride,    // frameRowBytes when passed to this function
  934.     register unsigned long dstRowStride)    // frameRowBytes when passed to this function
  935. {
  936.     register unsigned long loopsPerRow;
  937.  
  938.         SW_ASM_BEGIN
  939.  
  940. #if __MWERKS__
  941.         fralloc +
  942. #endif
  943.  
  944.             // srcRowStride = distance from end of a row to beginning of next
  945.         sub.l    numBytesPerRow, srcRowStride
  946.         sub.l    numBytesPerRow, dstRowStride
  947.         
  948.             // longWordsPerRow = numBytesPerRow >> 2;
  949.         move.l    numBytesPerRow, d0
  950.         lsr.l    #2, d0
  951.  
  952.             // numBytesPerRow -= longWordsPerRow << 2;
  953.         move.l    d0, d1
  954.         lsl.l    #2, d1
  955.         sub.l    d1, numBytesPerRow
  956.  
  957.             // loopsPerRow = longWordsPerRow >> 4;
  958.         move.l    d0, loopsPerRow
  959.         lsr.l    #4, loopsPerRow
  960.  
  961.         moveq    #0xF, d1
  962.         and.l    d1, d0
  963.         add.l    d0, d0            // multiply longWordsPerRow by 2 (size of move.l (srcPixelP)+,(dstPixelP)+)
  964.         lea     @loopEnd, a0    // get address of the end of the loop
  965.         suba.l    d0, a0            // calculate where to jmp in the loop
  966.  
  967.     @forEachRow:
  968.         move.l    loopsPerRow, d0
  969.         jmp        (a0)
  970.     @loopBase:
  971.         move.l    (srcPixelP)+, (dstPixelP)+    // 16
  972.         move.l    (srcPixelP)+, (dstPixelP)+    // 15
  973.         move.l    (srcPixelP)+, (dstPixelP)+    // 14
  974.         move.l    (srcPixelP)+, (dstPixelP)+    // 13
  975.         move.l    (srcPixelP)+, (dstPixelP)+    // 12
  976.         move.l    (srcPixelP)+, (dstPixelP)+    // 11 
  977.         move.l    (srcPixelP)+, (dstPixelP)+    // 10
  978.         move.l    (srcPixelP)+, (dstPixelP)+    //  9
  979.         move.l    (srcPixelP)+, (dstPixelP)+    //  8
  980.         move.l    (srcPixelP)+, (dstPixelP)+    //  7
  981.         move.l    (srcPixelP)+, (dstPixelP)+    //  6
  982.         move.l    (srcPixelP)+, (dstPixelP)+    //  5
  983.         move.l    (srcPixelP)+, (dstPixelP)+    //  4
  984.         move.l    (srcPixelP)+, (dstPixelP)+    //  3
  985.         move.l    (srcPixelP)+, (dstPixelP)+    //  2
  986.         move.l    (srcPixelP)+, (dstPixelP)+    //  1
  987.     @loopEnd:
  988.         subq.l    #1,d0
  989.         bpl        @loopBase
  990.  
  991.         // now do any leftover bits
  992.         move.l    numBytesPerRow, d0
  993.         beq        @nextRow
  994.         subq.l    #2, d0
  995.         bmi        @moveByte
  996.         move.w    (srcPixelP)+, (dstPixelP)+
  997.         tst        d0
  998.         beq        @nextRow
  999.     @moveByte:    
  1000.         move.b    (srcPixelP)+, (dstPixelP)+
  1001.  
  1002.     @nextRow:
  1003.         adda.l    srcRowStride, srcPixelP
  1004.         adda.l    dstRowStride, dstPixelP
  1005.         subq.l    #1, rowsToCopy
  1006.         bne        @forEachRow
  1007.  
  1008. #if __MWERKS__
  1009.         frfree
  1010. #endif
  1011.  
  1012.         SW_ASM_END
  1013. }
  1014.  
  1015.  
  1016. ///--------------------------------------------------------------------------------------
  1017. //        BlitPixieMask8Bit
  1018. ///--------------------------------------------------------------------------------------
  1019.  
  1020. SW_ASM_FUNC void BlitPixieMask8Bit(
  1021.     register PixelPtr srcPixelP,
  1022.     register PixelPtr dstPixelP,
  1023.     register PixelPtr maskPixelP,
  1024.     register unsigned long rowsToCopy,
  1025.     register unsigned long numBytesPerRow,
  1026.     register unsigned long srcRowStride,
  1027.     register unsigned long dstRowStride)
  1028. {
  1029.     register unsigned long loopsPerRow;
  1030.  
  1031.         SW_ASM_BEGIN
  1032.  
  1033. #if __MWERKS__
  1034.         fralloc +
  1035. #endif
  1036.  
  1037.         sub.l    numBytesPerRow, srcRowStride
  1038.         sub.l    numBytesPerRow, dstRowStride
  1039.         
  1040.             // longWordsPerRow = numBytesPerRow >> 2;
  1041.         move.l    numBytesPerRow, d0
  1042.         lsr.l    #2, d0
  1043.  
  1044.             // numBytesPerRow -= longWordsPerRow << 2;
  1045.         move.l    d0, d1
  1046.         lsl.l    #2, d1
  1047.         sub.l    d1, numBytesPerRow
  1048.  
  1049.             // loopsPerRow = longWordsPerRow >> 4;
  1050.         move.l    d0, loopsPerRow
  1051.         lsr.l    #4, loopsPerRow
  1052.  
  1053.             
  1054.         moveq    #0xF, d1
  1055.         and.l    d1, d0
  1056.         lsl.l    #3, d0                    // longWordsPerRow *= 8;
  1057.         lea     @loopEnd, a0            // get address of the end of the loop
  1058.         sub.l    d0, a0                    // calculate where to jmp in the loop
  1059.  
  1060.     @forEachRow:
  1061.         move.l    loopsPerRow, d2
  1062.         jmp        (a0)
  1063.     @loopBase:
  1064.             // 16
  1065.         move.l    (dstPixelP), d0
  1066.         and.l    (maskPixelP)+, d0
  1067.         or.l    (srcPixelP)+, d0
  1068.         move.l    d0, (dstPixelP)+
  1069.             // 15
  1070.         move.l    (dstPixelP), d0
  1071.         and.l    (maskPixelP)+, d0
  1072.         or.l    (srcPixelP)+, d0
  1073.         move.l    d0, (dstPixelP)+
  1074.             // 14
  1075.         move.l    (dstPixelP), d0
  1076.         and.l    (maskPixelP)+, d0
  1077.         or.l    (srcPixelP)+, d0
  1078.         move.l    d0, (dstPixelP)+
  1079.           // 13
  1080.         move.l    (dstPixelP), d0
  1081.         and.l    (maskPixelP)+, d0
  1082.         or.l    (srcPixelP)+, d0
  1083.         move.l    d0, (dstPixelP)+
  1084.           // 12
  1085.         move.l    (dstPixelP), d0
  1086.         and.l    (maskPixelP)+, d0
  1087.         or.l    (srcPixelP)+, d0
  1088.         move.l    d0, (dstPixelP)+
  1089.           // 11
  1090.         move.l    (dstPixelP), d0
  1091.         and.l    (maskPixelP)+, d0
  1092.         or.l    (srcPixelP)+, d0
  1093.         move.l    d0, (dstPixelP)+
  1094.           // 10
  1095.         move.l    (dstPixelP), d0
  1096.         and.l    (maskPixelP)+, d0
  1097.         or.l    (srcPixelP)+, d0
  1098.         move.l    d0, (dstPixelP)+
  1099.           //  9
  1100.         move.l    (dstPixelP), d0
  1101.         and.l    (maskPixelP)+, d0
  1102.         or.l    (srcPixelP)+, d0
  1103.         move.l    d0, (dstPixelP)+
  1104.           //  8
  1105.         move.l    (dstPixelP), d0
  1106.         and.l    (maskPixelP)+, d0
  1107.         or.l    (srcPixelP)+, d0
  1108.         move.l    d0, (dstPixelP)+
  1109.           //  7
  1110.         move.l    (dstPixelP), d0
  1111.         and.l    (maskPixelP)+, d0
  1112.         or.l    (srcPixelP)+, d0
  1113.         move.l    d0, (dstPixelP)+
  1114.             //  6
  1115.         move.l    (dstPixelP), d0
  1116.         and.l    (maskPixelP)+, d0
  1117.         or.l    (srcPixelP)+, d0
  1118.         move.l    d0, (dstPixelP)+
  1119.           //  5
  1120.         move.l    (dstPixelP), d0
  1121.         and.l    (maskPixelP)+, d0
  1122.         or.l    (srcPixelP)+, d0
  1123.         move.l    d0, (dstPixelP)+
  1124.           //  4
  1125.         move.l    (dstPixelP), d0
  1126.         and.l    (maskPixelP)+, d0
  1127.         or.l    (srcPixelP)+, d0
  1128.         move.l    d0, (dstPixelP)+
  1129.           //  3
  1130.         move.l    (dstPixelP), d0
  1131.         and.l    (maskPixelP)+, d0
  1132.         or.l    (srcPixelP)+, d0
  1133.         move.l    d0, (dstPixelP)+
  1134.         //  2
  1135.         move.l    (dstPixelP), d0
  1136.         and.l    (maskPixelP)+, d0
  1137.         or.l    (srcPixelP)+, d0
  1138.         move.l    d0, (dstPixelP)+
  1139.           //  1
  1140.         move.l    (dstPixelP), d0
  1141.         and.l    (maskPixelP)+, d0
  1142.         or.l    (srcPixelP)+, d0
  1143.         move.l    d0, (dstPixelP)+
  1144.     @loopEnd:
  1145.         subq.l    #1, d2
  1146.         bpl        @loopBase
  1147.  
  1148.         // now do any leftover bits
  1149.         move.l    numBytesPerRow, d2
  1150.         beq        @nextRow
  1151.         subq.l    #2, d2
  1152.         bmi        @moveByte
  1153.         move.w    (dstPixelP), d0
  1154.         and.w    (maskPixelP)+, d0
  1155.         or.w    (srcPixelP)+, d0
  1156.         move.w    d0, (dstPixelP)+
  1157.         tst        d2
  1158.         beq        @nextRow
  1159.     @moveByte:    
  1160.         move.b    (dstPixelP), d0
  1161.         and.b    (maskPixelP)+, d0
  1162.         or.b    (srcPixelP)+, d0
  1163.         move.b    d0, (dstPixelP)+
  1164.  
  1165.     @nextRow:
  1166.         adda.l    srcRowStride, srcPixelP
  1167.         adda.l    srcRowStride, maskPixelP
  1168.         adda.l    dstRowStride, dstPixelP
  1169.         subq.l    #1, rowsToCopy
  1170.         bne        @forEachRow
  1171.  
  1172. #if __MWERKS__
  1173.         frfree
  1174. #endif
  1175.  
  1176.         SW_ASM_END
  1177. }
  1178.  
  1179.  
  1180.  
  1181.  
  1182. ///--------------------------------------------------------------------------------------
  1183. //        BlitPixiePartialMask8Bit
  1184. ///--------------------------------------------------------------------------------------
  1185.  
  1186. SW_ASM_FUNC void BlitPixiePartialMask8Bit(
  1187.     register PixelPtr srcPixelP,
  1188.     register PixelPtr dstPixelP,
  1189.     register PixelPtr maskPixelP,
  1190.     register unsigned long rowsToCopy,
  1191.     register unsigned long numBytesPerRow,
  1192.     register unsigned long srcRowStride,
  1193.     register unsigned long dstRowStride)
  1194. {
  1195.     register unsigned long loopsPerRow;
  1196.  
  1197.         SW_ASM_BEGIN
  1198.  
  1199. #if __MWERKS__
  1200.         fralloc +
  1201. #endif
  1202.     
  1203.         sub.l    numBytesPerRow, srcRowStride
  1204.         sub.l    numBytesPerRow, dstRowStride
  1205.  
  1206.             // longWordsPerRow = numBytesPerRow >> 2;
  1207.         move.l    numBytesPerRow, d0
  1208.         lsr.l    #2, d0
  1209.  
  1210.             // numBytesPerRow -= longWordsPerRow << 2;
  1211.         move.l    d0, d1
  1212.         lsl.l    #2, d1
  1213.         sub.l    d1, numBytesPerRow
  1214.  
  1215.             // loopsPerRow = longWordsPerRow >> 4;
  1216.         move.l    d0, loopsPerRow
  1217.         lsr.l    #4, loopsPerRow
  1218.  
  1219.             
  1220.         moveq    #0xF, d1
  1221.         and.l    d1, d0
  1222.         mulu    #14, d0                    // longWordsPerRow *= 14 (bytes in segment of loop)
  1223.         lea     @loopEnd, a0            // get address of the end of the loop
  1224.         sub.l    d0, a0                    // calculate where to jmp in the loop
  1225.  
  1226.     @forEachRow:
  1227.         move.l    loopsPerRow, d2
  1228.         jmp        (a0)
  1229.     @loopBase:
  1230.             // 16
  1231.         move.l    (dstPixelP), d0
  1232.         and.l    (maskPixelP), d0
  1233.         move.l    (maskPixelP)+, d1
  1234.         not.l    d1
  1235.         and.l    (srcPixelP)+, d1
  1236.         or.l    d1, d0
  1237.         move.l    d0, (dstPixelP)+
  1238.             // 15
  1239.         move.l    (dstPixelP), d0
  1240.         and.l    (maskPixelP), d0
  1241.         move.l    (maskPixelP)+, d1
  1242.         not.l    d1
  1243.         and.l    (srcPixelP)+, d1
  1244.         or.l    d1, d0
  1245.         move.l    d0, (dstPixelP)+
  1246.             // 14
  1247.         move.l    (dstPixelP), d0
  1248.         and.l    (maskPixelP), d0
  1249.         move.l    (maskPixelP)+, d1
  1250.         not.l    d1
  1251.         and.l    (srcPixelP)+, d1
  1252.         or.l    d1, d0
  1253.         move.l    d0, (dstPixelP)+
  1254.           // 13
  1255.         move.l    (dstPixelP), d0
  1256.         and.l    (maskPixelP), d0
  1257.         move.l    (maskPixelP)+, d1
  1258.         not.l    d1
  1259.         and.l    (srcPixelP)+, d1
  1260.         or.l    d1, d0
  1261.         move.l    d0, (dstPixelP)+
  1262.           // 12
  1263.         move.l    (dstPixelP), d0
  1264.         and.l    (maskPixelP), d0
  1265.         move.l    (maskPixelP)+, d1
  1266.         not.l    d1
  1267.         and.l    (srcPixelP)+, d1
  1268.         or.l    d1, d0
  1269.         move.l    d0, (dstPixelP)+
  1270.           // 11
  1271.         move.l    (dstPixelP), d0
  1272.         and.l    (maskPixelP), d0
  1273.         move.l    (maskPixelP)+, d1
  1274.         not.l    d1
  1275.         and.l    (srcPixelP)+, d1
  1276.         or.l    d1, d0
  1277.         move.l    d0, (dstPixelP)+
  1278.           // 10
  1279.         move.l    (dstPixelP), d0
  1280.         and.l    (maskPixelP), d0
  1281.         move.l    (maskPixelP)+, d1
  1282.         not.l    d1
  1283.         and.l    (srcPixelP)+, d1
  1284.         or.l    d1, d0
  1285.         move.l    d0, (dstPixelP)+
  1286.           //  9
  1287.         move.l    (dstPixelP), d0
  1288.         and.l    (maskPixelP), d0
  1289.         move.l    (maskPixelP)+, d1
  1290.         not.l    d1
  1291.         and.l    (srcPixelP)+, d1
  1292.         or.l    d1, d0
  1293.         move.l    d0, (dstPixelP)+
  1294.           //  8
  1295.         move.l    (dstPixelP), d0
  1296.         and.l    (maskPixelP), d0
  1297.         move.l    (maskPixelP)+, d1
  1298.         not.l    d1
  1299.         and.l    (srcPixelP)+, d1
  1300.         or.l    d1, d0
  1301.         move.l    d0, (dstPixelP)+
  1302.           //  7
  1303.         move.l    (dstPixelP), d0
  1304.         and.l    (maskPixelP), d0
  1305.         move.l    (maskPixelP)+, d1
  1306.         not.l    d1
  1307.         and.l    (srcPixelP)+, d1
  1308.         or.l    d1, d0
  1309.         move.l    d0, (dstPixelP)+
  1310.             //  6
  1311.         move.l    (dstPixelP), d0
  1312.         and.l    (maskPixelP), d0
  1313.         move.l    (maskPixelP)+, d1
  1314.         not.l    d1
  1315.         and.l    (srcPixelP)+, d1
  1316.         or.l    d1, d0
  1317.         move.l    d0, (dstPixelP)+
  1318.           //  5
  1319.         move.l    (dstPixelP), d0
  1320.         and.l    (maskPixelP), d0
  1321.         move.l    (maskPixelP)+, d1
  1322.         not.l    d1
  1323.         and.l    (srcPixelP)+, d1
  1324.         or.l    d1, d0
  1325.         move.l    d0, (dstPixelP)+
  1326.           //  4
  1327.         move.l    (dstPixelP), d0
  1328.         and.l    (maskPixelP), d0
  1329.         move.l    (maskPixelP)+, d1
  1330.         not.l    d1
  1331.         and.l    (srcPixelP)+, d1
  1332.         or.l    d1, d0
  1333.         move.l    d0, (dstPixelP)+
  1334.           //  3
  1335.         move.l    (dstPixelP), d0
  1336.         and.l    (maskPixelP), d0
  1337.         move.l    (maskPixelP)+, d1
  1338.         not.l    d1
  1339.         and.l    (srcPixelP)+, d1
  1340.         or.l    d1, d0
  1341.         move.l    d0, (dstPixelP)+
  1342.         //  2
  1343.         move.l    (dstPixelP), d0
  1344.         and.l    (maskPixelP), d0
  1345.         move.l    (maskPixelP)+, d1
  1346.         not.l    d1
  1347.         and.l    (srcPixelP)+, d1
  1348.         or.l    d1, d0
  1349.         move.l    d0, (dstPixelP)+
  1350.           //  1
  1351.         move.l    (dstPixelP), d0
  1352.         and.l    (maskPixelP), d0
  1353.         move.l    (maskPixelP)+, d1
  1354.         not.l    d1
  1355.         and.l    (srcPixelP)+, d1
  1356.         or.l    d1, d0
  1357.         move.l    d0, (dstPixelP)+
  1358.     @loopEnd:
  1359.         subq.l    #1, d2
  1360.         bpl        @loopBase
  1361.  
  1362.         // now do any leftover bits
  1363.         move.l    numBytesPerRow, d2
  1364.         beq        @nextRow
  1365.         subq.l    #2, d2
  1366.         bmi        @moveByte
  1367.         move.w    (dstPixelP), d0
  1368.         and.w    (maskPixelP), d0
  1369.         move.w    (maskPixelP)+, d1
  1370.         not.w    d1
  1371.         and.w    (srcPixelP)+, d1
  1372.         or.w    d1, d0
  1373.         move.w    d0, (dstPixelP)+
  1374.         tst        d2
  1375.         beq        @nextRow
  1376.     @moveByte:
  1377.         move.b    (dstPixelP), d0
  1378.         and.b    (maskPixelP), d0
  1379.         move.b    (maskPixelP)+, d1
  1380.         not.b    d1
  1381.         and.b    (srcPixelP)+, d1
  1382.         or.b    d1, d0
  1383.         move.b    d0, (dstPixelP)+
  1384.  
  1385.     @nextRow:
  1386.         adda.l    srcRowStride, srcPixelP
  1387.         adda.l    srcRowStride, maskPixelP
  1388.         adda.l    dstRowStride, dstPixelP
  1389.         subq.l    #1, rowsToCopy
  1390.         bne        @forEachRow
  1391.  
  1392. #if __MWERKS__
  1393.         frfree
  1394. #endif
  1395.  
  1396.         SW_ASM_END
  1397. }
  1398.  
  1399.  
  1400. #endif /* SW_PPC */
  1401.  
  1402.  
  1403.