home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / PNL Libraries / Libraries / SpriteWorld / SpriteWorld files / Sources / BlitPixie8Bit.c next >
Encoding:
Text File  |  1996-11-26  |  43.6 KB  |  1,715 lines  |  [TEXT/KAHL]

  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 char                 gSWmmuMode;
  55.  
  56.  
  57. ///--------------------------------------------------------------------------------------
  58. //        BlitPixie8BitRectDrawProc
  59. ///--------------------------------------------------------------------------------------
  60.  
  61. SW_FUNC void BlitPixie8BitRectDrawProc(
  62.     FramePtr srcFrameP,
  63.     FramePtr dstFrameP,
  64.     Rect* srcRect,
  65.     Rect* dstRect)
  66. {
  67.     Rect                     srcBlitRect = *srcRect;
  68.     Rect                     dstBlitRect = *dstRect;
  69.     
  70.     SWAssert( srcFrameP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL );
  71.     
  72.         // clip off the top so we don't write into random memory
  73.     if (dstBlitRect.top < dstFrameP->frameRect.top)
  74.     {
  75.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  76.         dstBlitRect.top =  dstFrameP->frameRect.top;
  77.     }
  78.     
  79.         // clip off the bottom
  80.     if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)    // can't use "else if"s here because the
  81.     {                                                        // deltaRects sent to SWScreenDrawProc
  82.         dstBlitRect.bottom = dstFrameP->frameRect.bottom;    // can have a "wrap around" effect
  83.     }
  84.     
  85.         // clip off the left
  86.     if (dstBlitRect.left < dstFrameP->frameRect.left)
  87.     {
  88.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  89.         dstBlitRect.left = dstFrameP->frameRect.left;
  90.     }
  91.     
  92.         // clip off the right
  93.     if (dstBlitRect.right > dstFrameP->frameRect.right)
  94.     {
  95.         dstBlitRect.right = dstFrameP->frameRect.right;
  96.     }
  97.     
  98.     
  99.     if (dstBlitRect.bottom <= dstBlitRect.top)    // Make sure height is valid
  100.         return;
  101.         
  102.     if (dstBlitRect.right <= dstBlitRect.left)    // Make sure width is valid
  103.         return;
  104.  
  105.     {
  106.         unsigned long         numBytesPerRow;
  107.         SInt8                 mmuMode;
  108.     
  109.         if (gSWmmuMode != true32b)
  110.         {
  111.             mmuMode = true32b;
  112.             SwapMMUMode(&mmuMode);
  113.         }
  114.             // calculate the number of bytes in a row
  115.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  116.  
  117.         BlitPixie8Bit(
  118.                 // calculate the address of the first byte of the source
  119.             (PixelChunkPtr)(srcFrameP->frameBaseAddr + 
  120.                 (srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top]) + 
  121.                 srcBlitRect.left),
  122.  
  123.                 // calculate the address of the first byte of the destination
  124.             (PixelChunkPtr)(dstFrameP->frameBaseAddr + 
  125.                 (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  126.  
  127.                 // calculate the number of rows to blit
  128.             dstBlitRect.bottom - dstBlitRect.top,
  129.  
  130.                 // number of bytes in a row (duh!)
  131.             numBytesPerRow,
  132.  
  133.             srcFrameP->frameRowBytes,
  134.             dstFrameP->frameRowBytes);
  135.  
  136.         if (gSWmmuMode != true32b)
  137.         {
  138.             SwapMMUMode(&mmuMode);
  139.         }
  140.     }
  141. }
  142.  
  143.  
  144. ///--------------------------------------------------------------------------------------
  145. //        BP8BitInterlacedRectDrawProc
  146. ///--------------------------------------------------------------------------------------
  147.  
  148. SW_FUNC void BP8BitInterlacedRectDrawProc(
  149.     FramePtr srcFrameP,
  150.     FramePtr dstFrameP,
  151.     Rect* srcRect,
  152.     Rect* dstRect)
  153. {
  154.     Rect         srcBlitRect = *srcRect;
  155.     Rect         dstBlitRect = *dstRect;
  156.  
  157.     SWAssert( srcFrameP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL );
  158.         
  159.         // clip off the top so we don't write into random memory
  160.     if (dstBlitRect.top < dstFrameP->frameRect.top)
  161.     {
  162.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  163.         dstBlitRect.top =  dstFrameP->frameRect.top;
  164.     }
  165.         
  166.         // clip off the bottom
  167.     if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)    // can't use "else if"s here because the
  168.     {                                                        // deltaRects sent to SWScreenDrawProc
  169.         dstBlitRect.bottom = dstFrameP->frameRect.bottom;    // can have a "wrap around" effect
  170.     }
  171.     
  172.         // clip off the left
  173.     if (dstBlitRect.left < dstFrameP->frameRect.left)
  174.     {
  175.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  176.         dstBlitRect.left = dstFrameP->frameRect.left;
  177.     }
  178.     
  179.         // clip off the right
  180.     if (dstBlitRect.right > dstFrameP->frameRect.right)
  181.     {
  182.         dstBlitRect.right = dstFrameP->frameRect.right;
  183.     }
  184.     
  185.         // If first line is not on an even number, then skip it.
  186.     if ( (dstBlitRect.top - dstFrameP->frameRect.top)>>1<<1 != 
  187.         dstBlitRect.top - dstFrameP->frameRect.top )
  188.     {
  189.         srcBlitRect.top++;
  190.         dstBlitRect.top++;
  191.     }
  192.  
  193.     
  194.     if (dstBlitRect.bottom <= dstBlitRect.top)    // Make sure height is valid
  195.         return;
  196.         
  197.     if (dstBlitRect.right <= dstBlitRect.left)    // Make sure width is valid
  198.         return;
  199.  
  200.     {
  201.         unsigned long         numBytesPerRow;
  202.         unsigned long        numRowsToCopy;
  203.         SInt8                 mmuMode;
  204.         
  205.         
  206.             // Is destBlitRect height an even number?
  207.         numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;        
  208.         
  209.         if ( numRowsToCopy>>1<<1 == numRowsToCopy )
  210.             numRowsToCopy>>=1;
  211.         else
  212.             numRowsToCopy = (numRowsToCopy>>1) + 1;
  213.         
  214.         if (numRowsToCopy < 1)
  215.             return;
  216.         
  217.         
  218.         if (gSWmmuMode != true32b)
  219.         {
  220.             mmuMode = true32b;
  221.             SwapMMUMode(&mmuMode);
  222.         }
  223.             // calculate the number of bytes in a row
  224.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  225.         
  226.         
  227.         BlitPixie8Bit(
  228.             // calculate the address of the first byte of the source
  229.         (PixelChunkPtr)(srcFrameP->frameBaseAddr + 
  230.             (srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top]) + 
  231.             srcBlitRect.left),
  232.                 
  233.             // calculate the address of the first byte of the destination
  234.         (PixelChunkPtr)(dstFrameP->frameBaseAddr + 
  235.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  236.             
  237.             // number of rows to copy, already calculated for Interlaced mode
  238.         numRowsToCopy,
  239.         
  240.             // number of bytes in a row (duh!)
  241.         numBytesPerRow,
  242.         
  243.             srcFrameP->frameRowBytes<<1,
  244.             dstFrameP->frameRowBytes<<1);
  245.  
  246.         if (gSWmmuMode != true32b)
  247.         {
  248.             SwapMMUMode(&mmuMode);
  249.         }
  250.     }
  251. }
  252.  
  253.  
  254. ///--------------------------------------------------------------------------------------
  255. //        BlitPixie8BitMaskDrawProc
  256. ///--------------------------------------------------------------------------------------
  257.  
  258. SW_FUNC void BlitPixie8BitMaskDrawProc(
  259.     FramePtr srcFrameP,
  260.     FramePtr dstFrameP,
  261.     Rect *srcRect,
  262.     Rect *dstRect)
  263. {
  264.     Rect dstBlitRect = *dstRect;
  265.     Rect srcBlitRect = *srcRect;
  266.  
  267.     SWAssert( srcFrameP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL );
  268.     SWAssert( dstFrameP->frameRect.top == 0 );
  269.     
  270.         // clip off the top so we don't write into random memory
  271.     if (dstBlitRect.top < dstFrameP->frameRect.top)
  272.     {
  273.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  274.         dstBlitRect.top =  dstFrameP->frameRect.top;
  275.     }
  276.     
  277.         // clip off the bottom
  278.     if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)    // can't use "else if"s here because the
  279.     {                                                        // deltaRects sent to SWScreenDrawProc
  280.         dstBlitRect.bottom = dstFrameP->frameRect.bottom;    // can have a "wrap around" effect
  281.     }
  282.     
  283.         // clip off the left
  284.     if (dstBlitRect.left < dstFrameP->frameRect.left)
  285.     {
  286.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  287.         dstBlitRect.left = dstFrameP->frameRect.left;
  288.     }
  289.     
  290.         // clip off the right
  291.     if (dstBlitRect.right > dstFrameP->frameRect.right)
  292.     {
  293.         dstBlitRect.right = dstFrameP->frameRect.right;
  294.     }
  295.     
  296.     
  297.     if (dstBlitRect.bottom <= dstBlitRect.top)    // Make sure height is valid
  298.         return;
  299.         
  300.     if (dstBlitRect.right <= dstBlitRect.left)    // Make sure width is valid
  301.         return;
  302.     
  303.     
  304.     {
  305.         unsigned long         numBytesPerRow;
  306.         unsigned long         srcBaseOffset;
  307.         SInt8                 mmuMode;
  308.                 
  309.     
  310.         if (gSWmmuMode != true32b)
  311.         {
  312.             mmuMode = true32b;
  313.             SwapMMUMode(&mmuMode);
  314.         }
  315.             // calculate the offset to the first byte of the source
  316.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top - 
  317.             srcFrameP->frameRect.top] + srcBlitRect.left;
  318.  
  319.             // calculate the number of bytes in a row
  320.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  321.  
  322.         BlitPixieMask8Bit(
  323.                 // calculate the address of the first byte of the source
  324.             (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  325.  
  326.                 // calculate the address of the first byte of the destination
  327.             (PixelPtr)(dstFrameP->frameBaseAddr + 
  328.                 (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  329.  
  330.                 // calculate the address of the first byte of the mask
  331.             (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  332.  
  333.                 // calculate the number of rows to blit
  334.             dstBlitRect.bottom - dstBlitRect.top,
  335.  
  336.                 // number of bytes in a row (duh!)
  337.             numBytesPerRow,
  338.  
  339.             srcFrameP->frameRowBytes,
  340.             dstFrameP->frameRowBytes);
  341.  
  342.         if (gSWmmuMode != true32b)
  343.         {
  344.             SwapMMUMode(&mmuMode);
  345.         }
  346.     }
  347. }
  348.  
  349. ///--------------------------------------------------------------------------------------
  350. //        BlitPixie8BitPartialMaskDrawProc
  351. ///--------------------------------------------------------------------------------------
  352.  
  353. SW_FUNC void BlitPixie8BitPartialMaskDrawProc(
  354.     FramePtr srcFrameP,
  355.     FramePtr dstFrameP,
  356.     Rect *srcRect,
  357.     Rect *dstRect)
  358. {
  359.     Rect dstBlitRect = *dstRect;
  360.     Rect srcBlitRect = *srcRect;
  361.     
  362.     SWAssert( srcFrameP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL );
  363.     
  364.         // clip off the top so we don't write into random memory
  365.     if (dstBlitRect.top < dstFrameP->frameRect.top)
  366.     {
  367.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  368.         dstBlitRect.top =  dstFrameP->frameRect.top;
  369.     }
  370.     
  371.         // clip off the bottom
  372.     if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)    // can't use "else if"s here because the
  373.     {                                                        // deltaRects sent to SWScreenDrawProc
  374.         dstBlitRect.bottom = dstFrameP->frameRect.bottom;    // can have a "wrap around" effect
  375.     }
  376.     
  377.         // clip off the left
  378.     if (dstBlitRect.left < dstFrameP->frameRect.left)
  379.     {
  380.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  381.         dstBlitRect.left = dstFrameP->frameRect.left;
  382.     }
  383.     
  384.         // clip off the right
  385.     if (dstBlitRect.right > dstFrameP->frameRect.right)
  386.     {
  387.         dstBlitRect.right = dstFrameP->frameRect.right;
  388.     }
  389.     
  390.     
  391.     if (dstBlitRect.bottom <= dstBlitRect.top)    // Make sure height is valid
  392.         return;
  393.         
  394.     if (dstBlitRect.right <= dstBlitRect.left)    // Make sure width is valid
  395.         return;
  396.     
  397.     
  398.     {
  399.         unsigned long         numBytesPerRow;
  400.         unsigned long         srcBaseOffset;
  401.         SInt8                 mmuMode;
  402.                 
  403.     
  404.         if (gSWmmuMode != true32b)
  405.         {
  406.             mmuMode = true32b;
  407.             SwapMMUMode(&mmuMode);
  408.         }
  409.             // calculate the offset to the first byte of the source
  410.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top] + 
  411.             srcBlitRect.left;
  412.  
  413.             // calculate the number of bytes in a row
  414.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  415.  
  416.         BlitPixiePartialMask8Bit(
  417.                 // calculate the address of the first byte of the source
  418.             (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  419.  
  420.                 // calculate the address of the first byte of the destination
  421.             (PixelPtr)(dstFrameP->frameBaseAddr + 
  422.                 (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  423.  
  424.                 // calculate the address of the first byte of the mask
  425.             (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  426.  
  427.                 // calculate the number of rows to blit
  428.             dstBlitRect.bottom - dstBlitRect.top,
  429.  
  430.                 // number of bytes in a row (duh!)
  431.             numBytesPerRow,
  432.  
  433.             srcFrameP->frameRowBytes,
  434.             dstFrameP->frameRowBytes);
  435.  
  436.         if (gSWmmuMode != true32b)
  437.         {
  438.             SwapMMUMode(&mmuMode);
  439.         }
  440.     }
  441. }
  442.  
  443.  
  444. ///--------------------------------------------------------------------------------------
  445. //        BP8BitInterlacedMaskDrawProc
  446. ///--------------------------------------------------------------------------------------
  447.  
  448. SW_FUNC void BP8BitInterlacedMaskDrawProc(
  449.     FramePtr srcFrameP,
  450.     FramePtr dstFrameP,
  451.     Rect* srcRect,
  452.     Rect* dstRect)
  453. {
  454.     Rect     srcBlitRect = *srcRect;
  455.     Rect     dstBlitRect = *dstRect;
  456.  
  457.     SWAssert( srcFrameP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL );
  458.     
  459.         // clip off the top so we don't write into random memory
  460.     if (dstBlitRect.top < dstFrameP->frameRect.top)
  461.     {
  462.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  463.         dstBlitRect.top =  dstFrameP->frameRect.top;
  464.     }
  465.     
  466.         // clip off the bottom
  467.     if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)    // can't use "else if"s here because the
  468.     {                                                        // deltaRects sent to SWScreenDrawProc
  469.         dstBlitRect.bottom = dstFrameP->frameRect.bottom;    // can have a "wrap around" effect
  470.     }
  471.     
  472.         // clip off the left
  473.     if (dstBlitRect.left < dstFrameP->frameRect.left)
  474.     {
  475.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  476.         dstBlitRect.left = dstFrameP->frameRect.left;
  477.     }
  478.     
  479.         // clip off the right
  480.     if (dstBlitRect.right > dstFrameP->frameRect.right)
  481.     {
  482.         dstBlitRect.right = dstFrameP->frameRect.right;
  483.     }
  484.     
  485.     
  486.         // If first line is not on an even number, then skip it.
  487.     if ( (dstBlitRect.top - dstFrameP->frameRect.top)>>1<<1 != 
  488.         dstBlitRect.top - dstFrameP->frameRect.top )
  489.     {
  490.         srcBlitRect.top++;
  491.         dstBlitRect.top++;
  492.     }
  493.     
  494.     
  495.     if (dstBlitRect.bottom <= dstBlitRect.top)    // Make sure height is valid
  496.         return;
  497.         
  498.     if (dstBlitRect.right <= dstBlitRect.left)    // Make sure width is valid
  499.         return;
  500.  
  501.     {
  502.         unsigned long         numBytesPerRow;
  503.         unsigned long        numRowsToCopy;
  504.         unsigned long         srcBaseOffset;
  505.         SInt8                 mmuMode;
  506.         
  507.         
  508.             // Is destBlitRect height an even number?
  509.         numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;        
  510.     
  511.         if ( numRowsToCopy>>1<<1 == numRowsToCopy )
  512.             numRowsToCopy>>=1;
  513.         else
  514.             numRowsToCopy = (numRowsToCopy>>1) + 1;
  515.             
  516.         if (numRowsToCopy < 1)
  517.             return;
  518.         
  519.         
  520.         if (gSWmmuMode != true32b)
  521.         {
  522.             mmuMode = true32b;
  523.             SwapMMUMode(&mmuMode);
  524.         }
  525.         
  526.             // calculate the offset to the first byte of the source
  527.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top] + 
  528.             srcBlitRect.left;
  529.         
  530.             // calculate the number of bytes in a row
  531.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  532.         
  533.         
  534.         BlitPixieMask8Bit(
  535.             // calculate the address of the first byte of the source
  536.         (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  537.         
  538.             // calculate the address of the first byte of the destination
  539.         (PixelPtr)(dstFrameP->frameBaseAddr + 
  540.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  541.         
  542.             // calculate the address of the first byte of the mask
  543.         (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  544.             
  545.             // number of rows to copy, already calculated for Interlaced mode
  546.         numRowsToCopy,
  547.         
  548.             // number of bytes in a row (duh!)
  549.         numBytesPerRow,
  550.         
  551.             srcFrameP->frameRowBytes<<1,
  552.             dstFrameP->frameRowBytes<<1);
  553.  
  554.         if (gSWmmuMode != true32b)
  555.         {
  556.             SwapMMUMode(&mmuMode);
  557.         }
  558.     }
  559. }
  560.  
  561. ///--------------------------------------------------------------------------------------
  562. //        BP8BitInterlacedPartialMaskDrawProc
  563. ///--------------------------------------------------------------------------------------
  564.  
  565. SW_FUNC void BP8BitInterlacedPartialMaskDrawProc(
  566.     FramePtr srcFrameP,
  567.     FramePtr dstFrameP,
  568.     Rect* srcRect,
  569.     Rect* dstRect)
  570. {
  571.     Rect     srcBlitRect = *srcRect;
  572.     Rect     dstBlitRect = *dstRect;
  573.  
  574.     SWAssert( srcFrameP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL );
  575.     
  576.         // clip off the top so we don't write into random memory
  577.     if (dstBlitRect.top < dstFrameP->frameRect.top)
  578.     {
  579.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  580.         dstBlitRect.top =  dstFrameP->frameRect.top;
  581.     }
  582.     
  583.         // clip off the bottom
  584.     if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)    // can't use "else if"s here because the
  585.     {                                                        // deltaRects sent to SWScreenDrawProc
  586.         dstBlitRect.bottom = dstFrameP->frameRect.bottom;    // can have a "wrap around" effect
  587.     }
  588.     
  589.         // clip off the left
  590.     if (dstBlitRect.left < dstFrameP->frameRect.left)
  591.     {
  592.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  593.         dstBlitRect.left = dstFrameP->frameRect.left;
  594.     }
  595.     
  596.         // clip off the right
  597.     if (dstBlitRect.right > dstFrameP->frameRect.right)
  598.     {
  599.         dstBlitRect.right = dstFrameP->frameRect.right;
  600.     }
  601.     
  602.     
  603.         // If first line is not on an even number, then skip it.
  604.     if ( (dstBlitRect.top - dstFrameP->frameRect.top)>>1<<1 != 
  605.         dstBlitRect.top - dstFrameP->frameRect.top )
  606.     {
  607.         srcBlitRect.top++;
  608.         dstBlitRect.top++;
  609.     }
  610.     
  611.     
  612.     if (dstBlitRect.bottom <= dstBlitRect.top)    // Make sure height is valid
  613.         return;
  614.         
  615.     if (dstBlitRect.right <= dstBlitRect.left)    // Make sure width is valid
  616.         return;
  617.  
  618.     {
  619.         unsigned long         numBytesPerRow;
  620.         unsigned long        numRowsToCopy;
  621.         unsigned long         srcBaseOffset;
  622.         SInt8                 mmuMode;
  623.         
  624.         
  625.             // Is destBlitRect height an even number?
  626.         numRowsToCopy = dstBlitRect.bottom - dstBlitRect.top;        
  627.     
  628.         if ( numRowsToCopy>>1<<1 == numRowsToCopy )
  629.             numRowsToCopy>>=1;
  630.         else
  631.             numRowsToCopy = (numRowsToCopy>>1) + 1;
  632.             
  633.         if (numRowsToCopy < 1)
  634.             return;
  635.         
  636.         
  637.         if (gSWmmuMode != true32b)
  638.         {
  639.             mmuMode = true32b;
  640.             SwapMMUMode(&mmuMode);
  641.         }
  642.         
  643.             // calculate the offset to the first byte of the source
  644.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top] + 
  645.             srcBlitRect.left;
  646.         
  647.             // calculate the number of bytes in a row
  648.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  649.         
  650.         
  651.         BlitPixiePartialMask8Bit(
  652.             // calculate the address of the first byte of the source
  653.         (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  654.         
  655.             // calculate the address of the first byte of the destination
  656.         (PixelPtr)(dstFrameP->frameBaseAddr + 
  657.             (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  658.         
  659.             // calculate the address of the first byte of the mask
  660.         (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  661.             
  662.             // number of rows to copy, already calculated for Interlaced mode
  663.         numRowsToCopy,
  664.         
  665.             // number of bytes in a row (duh!)
  666.         numBytesPerRow,
  667.         
  668.             srcFrameP->frameRowBytes<<1,
  669.             dstFrameP->frameRowBytes<<1);
  670.  
  671.  
  672.         if (gSWmmuMode != true32b)
  673.         {
  674.             SwapMMUMode(&mmuMode);
  675.         }
  676.     }
  677. }
  678.  
  679.  
  680. ///--------------------------------------------------------------------------------------
  681. //        CompiledSprite8BitDrawProc
  682. ///--------------------------------------------------------------------------------------
  683.  
  684. SW_FUNC void CompiledSprite8BitDrawProc(
  685.     FramePtr srcFrameP,
  686.     FramePtr dstFrameP,
  687.     Rect *srcRect,
  688.     Rect *dstRect)
  689. {
  690. #if !SW_PPC
  691.     Rect         dstBlitRect = *dstRect;
  692.     Rect         srcBlitRect = *srcRect;
  693.     SInt8        mmuMode;
  694.     
  695.     SWAssert( srcFrameP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL );
  696.  
  697.     // we first check to see if any clipping will be necessary, then
  698.     // we determine whether or not we can use the compiled blitter. we must
  699.     // do this since the compiled blitter cannot handle clipping.
  700.  
  701.         // clip off the top so we don't write into random memory
  702.     if (dstBlitRect.top < dstFrameP->frameRect.top)
  703.     {
  704.         srcBlitRect.top += dstFrameP->frameRect.top - dstBlitRect.top;
  705.         dstBlitRect.top =  dstFrameP->frameRect.top;
  706.     }
  707.     
  708.         // clip off the bottom
  709.     if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)
  710.     {
  711.         srcBlitRect.bottom -= dstBlitRect.bottom - dstFrameP->frameRect.bottom;
  712.         dstBlitRect.bottom = dstFrameP->frameRect.bottom;
  713.     }
  714.     
  715.         // clip off the left
  716.     if (dstBlitRect.left < dstFrameP->frameRect.left)
  717.     {
  718.         srcBlitRect.left += dstFrameP->frameRect.left - dstBlitRect.left;
  719.         dstBlitRect.left = dstFrameP->frameRect.left;
  720.     }
  721.     
  722.         // clip off the right
  723.     if (dstBlitRect.right > dstFrameP->frameRect.right)
  724.     {
  725.         srcBlitRect.right -= dstBlitRect.right - dstFrameP->frameRect.right;
  726.         dstBlitRect.right = dstFrameP->frameRect.right;
  727.     }
  728.     
  729.     
  730.     if (dstBlitRect.bottom <= dstBlitRect.top)    // Make sure height is valid
  731.         return;
  732.         
  733.     if (dstBlitRect.right <= dstBlitRect.left)    // Make sure width is valid
  734.         return;
  735.  
  736.     
  737.     if (gSWmmuMode != true32b)
  738.     {
  739.         mmuMode = true32b;
  740.         SwapMMUMode(&mmuMode);
  741.     }
  742.         
  743.     // If we didn't have to clip the sprite, we can call the compiled blitter.
  744.     // Hopefully this will be the most common case (i.e. the sprites will be entirely
  745.     // on the screen more often than not)
  746.  
  747.     if (srcBlitRect.top == srcFrameP->frameRect.top &&
  748.         srcBlitRect.bottom == srcFrameP->frameRect.bottom &&
  749.         srcBlitRect.left == srcFrameP->frameRect.left &&
  750.         srcBlitRect.right == srcFrameP->frameRect.right)
  751.     {
  752.         (*srcFrameP->frameBlitterP)(
  753.             srcFrameP->frameRowBytes,
  754.             dstFrameP->frameRowBytes,
  755.             srcFrameP->frameBaseAddr +
  756.                 srcFrameP->scanLinePtrArray[0] + srcRect->left,    // 0 'cause it always starts at top
  757.             dstFrameP->frameBaseAddr +
  758.                 dstFrameP->scanLinePtrArray[dstRect->top] + dstRect->left);
  759.     }
  760.     else
  761.     {
  762.         unsigned long numBytesPerRow;
  763.         unsigned long srcBaseOffset;
  764.         
  765.     
  766.             // calculate the offset to the first byte of the source
  767.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top-srcFrameP->frameRect.top] + 
  768.             srcBlitRect.left;
  769.  
  770.             // calculate the number of bytes in a row
  771.         numBytesPerRow = (dstBlitRect.right - dstBlitRect.left);
  772.  
  773.         BlitPixieMask8Bit(
  774.                 // calculate the address of the first byte of the source
  775.             (PixelPtr)(srcFrameP->frameBaseAddr + srcBaseOffset),
  776.  
  777.                 // calculate the address of the first byte of the destination
  778.             (PixelPtr)(dstFrameP->frameBaseAddr + 
  779.                 (dstFrameP->scanLinePtrArray[dstBlitRect.top]) + dstBlitRect.left),
  780.  
  781.                 // calculate the address of the first byte of the mask
  782.             (PixelPtr)(srcFrameP->maskBaseAddr + srcBaseOffset),
  783.  
  784.                 // calculate the number of rows to blit
  785.             dstBlitRect.bottom - dstBlitRect.top,
  786.  
  787.                 // number of bytes in a row (duh!)
  788.             numBytesPerRow,
  789.  
  790.             srcFrameP->frameRowBytes,
  791.             dstFrameP->frameRowBytes);
  792.     }
  793.     if (gSWmmuMode != true32b)
  794.     {
  795.         SwapMMUMode(&mmuMode);
  796.     }
  797. #endif
  798. }
  799.  
  800. ///--------------------------------------------------------------------------------------
  801. //        BlitPixie8BitGetPixel
  802. ///--------------------------------------------------------------------------------------
  803.  
  804. SW_FUNC unsigned char BlitPixie8BitGetPixel(
  805.     FramePtr srcFrameP,
  806.     Point thePoint )
  807. {
  808.     SInt8             mmuMode;
  809.     unsigned long     srcBaseOffset;
  810.     unsigned char    theColor;
  811.     
  812.     SWAssert( srcFrameP != NULL && srcFrameP->frameBaseAddr != NULL );
  813.  
  814.     if (gSWmmuMode != true32b)
  815.     {
  816.         mmuMode = true32b;
  817.         SwapMMUMode(&mmuMode);
  818.     }
  819.  
  820.     srcBaseOffset = srcFrameP->scanLinePtrArray[thePoint.v] + 
  821.         thePoint.h+srcFrameP->frameRect.left;
  822.     theColor = *((unsigned char*)(srcFrameP->frameBaseAddr + srcBaseOffset));
  823.         
  824.     if (gSWmmuMode != true32b)
  825.     {
  826.         SwapMMUMode(&mmuMode);
  827.     }
  828.     return theColor;
  829. }
  830.  
  831. ///--------------------------------------------------------------------------------------
  832. //        BlitPixie8BitSetPixel
  833. ///--------------------------------------------------------------------------------------
  834.  
  835. SW_FUNC void BlitPixie8BitSetPixel(
  836.     FramePtr srcFrameP,
  837.     Point thePoint,
  838.     unsigned char theColor)
  839. {
  840.     SInt8             mmuMode;
  841.     unsigned long     srcBaseOffset;
  842.     
  843.     SWAssert( srcFrameP != NULL && srcFrameP->frameBaseAddr != NULL );
  844.  
  845.     if ((thePoint.h >= 0) &&
  846.         (thePoint.h < srcFrameP->frameRect.right-srcFrameP->frameRect.left) &&
  847.         (thePoint.v >= 0) &&
  848.         (thePoint.v < srcFrameP->frameRect.bottom-srcFrameP->frameRect.top) )
  849.     {
  850.     
  851.         if (gSWmmuMode != true32b)
  852.         {
  853.             mmuMode = true32b;
  854.             SwapMMUMode(&mmuMode);
  855.         }
  856.         srcBaseOffset = srcFrameP->scanLinePtrArray[thePoint.v] + 
  857.             thePoint.h + srcFrameP->frameRect.left;
  858.         *((unsigned char*)(srcFrameP->frameBaseAddr + srcBaseOffset)) = theColor;
  859.             
  860.         if (gSWmmuMode != true32b)
  861.         {
  862.             SwapMMUMode(&mmuMode);
  863.         }
  864.     }
  865. }
  866.  
  867.  
  868. ///--------------------------------------------------------------------------------------
  869. //    SWAnimate8BitStarField
  870. ///--------------------------------------------------------------------------------------
  871.  
  872. SW_FUNC void SWAnimate8BitStarField(
  873.     SpriteWorldPtr    spriteWorldP,
  874.     StarArray        *starArray,
  875.     short            numStars,
  876.     short            backColor)
  877. {
  878.     short            curStar;
  879.     short            horizOffset, vertOffset;    // Offset from window to work area
  880.     SInt8             mmuMode;
  881.     FramePtr        windFrameP = spriteWorldP->windowFrameP;
  882.     FramePtr        workFrameP = spriteWorldP->workFrameP;
  883.     unsigned long     srcBaseOffset;
  884.  
  885.     SWAssert( spriteWorldP != NULL && starArray != NULL && windFrameP != NULL && workFrameP != NULL &&
  886.                     windFrameP->frameBaseAddr != NULL && workFrameP->frameBaseAddr != NULL
  887.             );
  888.  
  889.     if (gSWmmuMode != true32b)
  890.     {
  891.         mmuMode = true32b;
  892.         SwapMMUMode(&mmuMode);
  893.     }
  894.     
  895.         // Stores offset if spriteWorld is smaller than window
  896.     horizOffset = windFrameP->frameRect.left;
  897.     vertOffset = windFrameP->frameRect.top;
  898.     
  899.     
  900.     for (curStar = 0; curStar < numStars; curStar++)
  901.     {
  902.             // Make sure we aren't erasing part of a sprite
  903.         if (starArray[curStar].needsToBeErased)
  904.         {
  905.             srcBaseOffset = windFrameP->scanLinePtrArray[starArray[curStar].oldVertLoc] + 
  906.                 starArray[curStar].oldHorizLoc;
  907.             *((unsigned char*)(windFrameP->frameBaseAddr + srcBaseOffset)) = backColor;
  908.         }
  909.         
  910.             // Make sure we aren't going to draw over a sprite
  911.         srcBaseOffset = workFrameP->scanLinePtrArray[starArray[curStar].vertLoc - vertOffset] + 
  912.             starArray[curStar].horizLoc - horizOffset;
  913.         if ( *((unsigned char*)(workFrameP->frameBaseAddr + srcBaseOffset)) == backColor)
  914.         {
  915.                 // Draw the new star position
  916.             srcBaseOffset = windFrameP->scanLinePtrArray[starArray[curStar].vertLoc] + 
  917.                 starArray[curStar].horizLoc;
  918.             *((unsigned char*)(windFrameP->frameBaseAddr + srcBaseOffset)) = 
  919.                 starArray[curStar].color;
  920.             
  921.             starArray[curStar].needsToBeErased = true;
  922.         }
  923.         else
  924.         {
  925.             starArray[curStar].needsToBeErased = false;
  926.         }
  927.     }
  928.     
  929.     
  930.     if (gSWmmuMode != true32b)
  931.     {
  932.         SwapMMUMode(&mmuMode);
  933.     }
  934. }
  935.  
  936.  
  937. ///--------------------------------------------------------------------------------------
  938. //        BlitPixie8BitFlipSprite
  939. ///--------------------------------------------------------------------------------------
  940.  
  941. SW_FUNC void SWBlitPixie8BitFlipSprite(
  942.     SpritePtr srcSpriteP )
  943. {
  944.     SInt8             mmuMode;
  945.     FramePtr        curFrameP;
  946.     unsigned char    holdPixel;
  947.     short            frameCounter, 
  948.                     scanLineCounter,
  949.                     halfWidth, 
  950.                     leftPixel,
  951.                     rightPixel,
  952.                     frameLeft;
  953.     GDHandle        currentGDH;
  954.     GWorldPtr        currentGWorld;
  955.  
  956.     SWAssert( srcSpriteP != NULL && srcSpriteP->frameArray[0]->isFrameLocked );
  957.     
  958.     if ( !srcSpriteP->frameArray[0]->isFrameLocked )
  959.     {
  960.         return;
  961.     }
  962.         
  963.     frameCounter = srcSpriteP->numFrames;
  964.     while (frameCounter--)
  965.     {
  966.         if (gSWmmuMode != true32b)
  967.         {
  968.             mmuMode = true32b;
  969.             SwapMMUMode(&mmuMode);
  970.         }
  971.  
  972.  
  973.         curFrameP = srcSpriteP->frameArray[frameCounter];
  974.         
  975.         SWAssert( curFrameP != NULL && curFrameP->frameBaseAddr != NULL );
  976.         
  977.         frameLeft = curFrameP->frameRect.left;
  978.         halfWidth = (curFrameP->frameRect.right - curFrameP->frameRect.left)/2;
  979.         scanLineCounter = curFrameP->numScanLines;
  980.         while (scanLineCounter--)
  981.         {
  982.             rightPixel = leftPixel = halfWidth;
  983.             while (leftPixel--)
  984.             {
  985.                 holdPixel = *((unsigned char*)(curFrameP->frameBaseAddr + 
  986.                     curFrameP->scanLinePtrArray[scanLineCounter] + leftPixel+frameLeft));
  987.                 if ( holdPixel != *((unsigned char*)(curFrameP->frameBaseAddr + 
  988.                         curFrameP->scanLinePtrArray[scanLineCounter] + rightPixel+frameLeft)) )
  989.                 {
  990.                     *((unsigned char*)(curFrameP->frameBaseAddr + 
  991.                         curFrameP->scanLinePtrArray[scanLineCounter] + leftPixel+frameLeft)) = 
  992.                         *((unsigned char*)(curFrameP->frameBaseAddr + 
  993.                         curFrameP->scanLinePtrArray[scanLineCounter] + rightPixel+frameLeft));
  994.                     *((unsigned char*)(curFrameP->frameBaseAddr + 
  995.                         curFrameP->scanLinePtrArray[scanLineCounter] + rightPixel+frameLeft)) = 
  996.                         holdPixel;                    
  997.                 }
  998.                 rightPixel++;
  999.             }            
  1000.         }
  1001.         if ( curFrameP->maskPort != NULL )
  1002.         {
  1003.             scanLineCounter = curFrameP->numScanLines;
  1004.             while (scanLineCounter--)
  1005.             {
  1006.                 rightPixel = leftPixel = halfWidth;
  1007.                 while (leftPixel--)
  1008.                 {
  1009.                     holdPixel = *((unsigned char*)(curFrameP->maskBaseAddr + 
  1010.                         curFrameP->scanLinePtrArray[scanLineCounter] + leftPixel+frameLeft));
  1011.                     if ( holdPixel != *((unsigned char*)(curFrameP->maskBaseAddr + 
  1012.                         curFrameP->scanLinePtrArray[scanLineCounter] + rightPixel+frameLeft)) )
  1013.                     {
  1014.                         *((unsigned char*)(curFrameP->maskBaseAddr + 
  1015.                             curFrameP->scanLinePtrArray[scanLineCounter] + 
  1016.                             leftPixel+frameLeft)) = 
  1017.                             *((unsigned char*)(curFrameP->maskBaseAddr + 
  1018.                             curFrameP->scanLinePtrArray[scanLineCounter] + 
  1019.                             rightPixel+frameLeft));
  1020.                         *((unsigned char*)(curFrameP->maskBaseAddr + 
  1021.                             curFrameP->scanLinePtrArray[scanLineCounter] + 
  1022.                             rightPixel+frameLeft)) = holdPixel;
  1023.                     }
  1024.                     rightPixel++;
  1025.                 }
  1026.             }
  1027.         }
  1028.         
  1029.         if (gSWmmuMode != true32b)
  1030.         {
  1031.             SwapMMUMode(&mmuMode);
  1032.         }
  1033.  
  1034.         if ( curFrameP->maskRgn != NULL && curFrameP->maskPort != NULL )
  1035.         {
  1036.             GetGWorld( ¤tGWorld, ¤tGDH );
  1037.             SetGWorld( curFrameP->maskPort, NULL );
  1038.             InvertRect( &(curFrameP->frameRect) );
  1039.             (void)SWCreateRegionFromGWorldAndRect( &(curFrameP->maskRgn), 
  1040.                 curFrameP->maskPort, &(curFrameP->frameRect) );
  1041.             SWSetFrameMaskRgn(curFrameP, curFrameP->maskRgn);
  1042.             InvertRect( &(curFrameP->frameRect) );
  1043.             SetGWorld( currentGWorld, currentGDH );
  1044.         }
  1045.     }
  1046. }
  1047.  
  1048.  
  1049. #if SW_USE_C
  1050. ///--------------------------------------------------------------------------------------
  1051. //        BlitPixie8Bit
  1052. ///--------------------------------------------------------------------------------------
  1053. void BlitPixie8Bit(
  1054.     PixelChunkPtr srcPixelP,
  1055.     PixelChunkPtr dstPixelP,
  1056.     register unsigned long rowsToCopy,
  1057.     register unsigned long numBytesPerRow,
  1058.     register unsigned long srcOffset,
  1059.     register unsigned long dstOffset)
  1060. {
  1061.     register long index;
  1062.     register PixelChunkPtr startSrcPixelP;
  1063.     register PixelChunkPtr startDstPixelP;
  1064.     
  1065.         
  1066.     startSrcPixelP = srcPixelP;
  1067.     startDstPixelP = dstPixelP;
  1068.  
  1069.     while (rowsToCopy--)
  1070.     {
  1071.         register fourblits = (numBytesPerRow >> 2);
  1072.         
  1073.         srcPixelP = startSrcPixelP;
  1074.         dstPixelP = startDstPixelP;
  1075.         
  1076.         for (index = 0; index < fourblits; index++)
  1077.         {
  1078.             register unsigned long temp1;
  1079.             
  1080.             temp1 = srcPixelP[index];
  1081.             dstPixelP[index] = temp1;
  1082.         }
  1083.         srcPixelP += fourblits;
  1084.         dstPixelP += fourblits;
  1085.         if (numBytesPerRow & 0x2)
  1086.             *((unsigned short *) dstPixelP)++ = *((unsigned short *) srcPixelP)++;
  1087.         if (numBytesPerRow & 0x1)
  1088.             *((unsigned char *)dstPixelP)++ = *((unsigned char *)srcPixelP)++;
  1089.  
  1090.             // bump to next row    
  1091.         (char *)startSrcPixelP += srcOffset;
  1092.         (char *)startDstPixelP += dstOffset;
  1093.     }
  1094. }
  1095.  
  1096.  
  1097. ///--------------------------------------------------------------------------------------
  1098. //        BlitPixieMask8Bit
  1099. ///--------------------------------------------------------------------------------------
  1100.  
  1101. void BlitPixieMask8Bit(
  1102.     register PixelPtr srcPixelP,
  1103.     register PixelPtr dstPixelP,
  1104.     register PixelPtr maskPixelP,
  1105.     register unsigned long rowsToCopy,
  1106.     register unsigned long numBytesPerRow,
  1107.     register unsigned long srcOffset,
  1108.     register unsigned long dstOffset)
  1109. {
  1110.     register long index;
  1111.     register PixelPtr startSrcPixelP;
  1112.     register PixelPtr startDstPixelP;
  1113.     register PixelPtr startMaskPixelP;
  1114.     
  1115.     startSrcPixelP = srcPixelP;
  1116.     startDstPixelP = dstPixelP;
  1117.     startMaskPixelP = maskPixelP;
  1118.     
  1119.     while (rowsToCopy--)    
  1120.     {
  1121.         register fourblits = (numBytesPerRow >> 2);
  1122.         
  1123.         srcPixelP = startSrcPixelP;
  1124.         dstPixelP = startDstPixelP;
  1125.         maskPixelP = startMaskPixelP;
  1126.         
  1127.         for (index = 0; index < fourblits; index++)
  1128.         {
  1129.             register unsigned long temp1;
  1130.             
  1131.             temp1 = dstPixelP[index] & maskPixelP[index] | srcPixelP[index];
  1132.             dstPixelP[index] = temp1;
  1133.         }
  1134.         srcPixelP += fourblits;
  1135.         dstPixelP += fourblits;
  1136.         maskPixelP += fourblits;
  1137.         if (numBytesPerRow & 0x2)
  1138.         {
  1139.             register unsigned short temp1;
  1140.             
  1141.             temp1 = (*((unsigned short *) dstPixelP)) & (*((unsigned short *) maskPixelP)++) |
  1142.             *((unsigned short *) srcPixelP)++;
  1143.             
  1144.             (*((unsigned short *) dstPixelP)++) = temp1;
  1145.         }
  1146.         if (numBytesPerRow & 0x1)
  1147.         {
  1148.             register unsigned char temp1;
  1149.             
  1150.             temp1 = (*((unsigned char *) dstPixelP)) & (*((unsigned char *) maskPixelP)++) |
  1151.             *((unsigned char *) srcPixelP)++;
  1152.             
  1153.             (*((unsigned char *) dstPixelP)++) = temp1;
  1154.         }
  1155.  
  1156.             // bump to next row
  1157.         startSrcPixelP = (PixelPtr)(((char*)startSrcPixelP) + srcOffset);
  1158.         startDstPixelP = (PixelPtr)(((char*)startDstPixelP) + dstOffset);
  1159.         startMaskPixelP = (PixelPtr)(((char*)startMaskPixelP) + srcOffset);
  1160.     }
  1161. }
  1162.  
  1163.  
  1164. ///--------------------------------------------------------------------------------------
  1165. //        BlitPixiePartialMask8Bit
  1166. ///--------------------------------------------------------------------------------------
  1167.  
  1168. void BlitPixiePartialMask8Bit(
  1169.     register PixelPtr srcPixelP,
  1170.     register PixelPtr dstPixelP,
  1171.     register PixelPtr maskPixelP,
  1172.     register unsigned long rowsToCopy,
  1173.     register unsigned long numBytesPerRow,
  1174.     register unsigned long srcOffset,
  1175.     register unsigned long dstOffset)
  1176. {
  1177.     register long index;
  1178.     register PixelPtr startSrcPixelP;
  1179.     register PixelPtr startDstPixelP;
  1180.     register PixelPtr startMaskPixelP;
  1181.     
  1182.     startSrcPixelP = srcPixelP;
  1183.     startDstPixelP = dstPixelP;
  1184.     startMaskPixelP = maskPixelP;
  1185.     
  1186.     while (rowsToCopy--)    
  1187.     {
  1188.         register fourblits = (numBytesPerRow >> 2);
  1189.         
  1190.         srcPixelP = startSrcPixelP;
  1191.         dstPixelP = startDstPixelP;
  1192.         maskPixelP = startMaskPixelP;
  1193.         
  1194.         for (index = 0; index < fourblits; index++)
  1195.         {
  1196.             register unsigned long temp1;
  1197.             
  1198.             temp1 = dstPixelP[index] & maskPixelP[index] | 
  1199.                 ( (~maskPixelP[index])&srcPixelP[index]);
  1200.             dstPixelP[index] = temp1;
  1201.         }
  1202.         srcPixelP += fourblits;
  1203.         dstPixelP += fourblits;
  1204.         maskPixelP += fourblits;
  1205.         if (numBytesPerRow & 0x2)
  1206.         {
  1207.             register unsigned short temp1;
  1208.             
  1209.             temp1 = (*((unsigned short *) dstPixelP)) & (*((unsigned short *) maskPixelP)) |
  1210.             (~(*((unsigned short *) maskPixelP)++) &
  1211.             *((unsigned short *) srcPixelP)++);
  1212.                 
  1213.             (*((unsigned short *) dstPixelP)++) = temp1;
  1214.         }
  1215.         if (numBytesPerRow & 0x1)
  1216.         {
  1217.             register unsigned char temp1;
  1218.             
  1219.             temp1 = (*((unsigned char *) dstPixelP)) & (*((unsigned char *) maskPixelP)) |
  1220.             (~(*((unsigned char *) maskPixelP)++) &
  1221.             *((unsigned char *) srcPixelP)++);
  1222.                 
  1223.             (*((unsigned char *) dstPixelP)++) = temp1;
  1224.         }
  1225.         
  1226.             // bump to next row
  1227.         startSrcPixelP = (PixelPtr)(((char*)startSrcPixelP) + srcOffset);
  1228.         startDstPixelP = (PixelPtr)(((char*)startDstPixelP) + dstOffset);
  1229.         startMaskPixelP = (PixelPtr)(((char*)startMaskPixelP) + srcOffset);
  1230.     }
  1231. }
  1232.  
  1233.  
  1234. #else /* SW_USE_C */
  1235.  
  1236. ///--------------------------------------------------------------------------------------
  1237. //        BlitPixie8Bit
  1238. ///--------------------------------------------------------------------------------------
  1239.  
  1240. SW_ASM_FUNC void BlitPixie8Bit(
  1241.     register PixelPtr srcPixelP,
  1242.     register PixelPtr dstPixelP,
  1243.     register unsigned long rowsToCopy,
  1244.     register unsigned long numBytesPerRow,
  1245.     register unsigned long srcRowStride,
  1246.     register unsigned long dstRowStride)
  1247. {
  1248.     register unsigned long loopsPerRow;
  1249.  
  1250.         SW_ASM_BEGIN
  1251.  
  1252. #if __MWERKS__
  1253.         fralloc +
  1254. #endif
  1255.  
  1256.         sub.l    numBytesPerRow, srcRowStride
  1257.         sub.l    numBytesPerRow, dstRowStride
  1258.         
  1259.             // longWordsPerRow = numBytesPerRow >> 2;
  1260.         move.l    numBytesPerRow, d0
  1261.         lsr.l    #2, d0
  1262.  
  1263.             // numBytesPerRow -= longWordsPerRow << 2;
  1264.         move.l    d0, d1
  1265.         lsl.l    #2, d1
  1266.         sub.l    d1, numBytesPerRow
  1267.  
  1268.             // loopsPerRow = longWordsPerRow >> 4;
  1269.         move.l    d0, loopsPerRow
  1270.         lsr.l    #4, loopsPerRow
  1271.  
  1272.         moveq    #0xF, d1
  1273.         and.l    d1, d0
  1274.         add.l    d0, d0            // multiply longWordsPerRow by 2 (size of move.l (srcPixelP)+,(dstPixelP)+)
  1275.         lea     @loopEnd, a0    // get address of the end of the loop
  1276.         suba.l    d0, a0            // calculate where to jmp in the loop
  1277.  
  1278.     @forEachRow:
  1279.         move.l    loopsPerRow, d0
  1280.         jmp        (a0)
  1281.     @loopBase:
  1282.         move.l    (srcPixelP)+, (dstPixelP)+    // 16
  1283.         move.l    (srcPixelP)+, (dstPixelP)+    // 15
  1284.         move.l    (srcPixelP)+, (dstPixelP)+    // 14
  1285.         move.l    (srcPixelP)+, (dstPixelP)+    // 13
  1286.         move.l    (srcPixelP)+, (dstPixelP)+    // 12
  1287.         move.l    (srcPixelP)+, (dstPixelP)+    // 11 
  1288.         move.l    (srcPixelP)+, (dstPixelP)+    // 10
  1289.         move.l    (srcPixelP)+, (dstPixelP)+    //  9
  1290.         move.l    (srcPixelP)+, (dstPixelP)+    //  8
  1291.         move.l    (srcPixelP)+, (dstPixelP)+    //  7
  1292.         move.l    (srcPixelP)+, (dstPixelP)+    //  6
  1293.         move.l    (srcPixelP)+, (dstPixelP)+    //  5
  1294.         move.l    (srcPixelP)+, (dstPixelP)+    //  4
  1295.         move.l    (srcPixelP)+, (dstPixelP)+    //  3
  1296.         move.l    (srcPixelP)+, (dstPixelP)+    //  2
  1297.         move.l    (srcPixelP)+, (dstPixelP)+    //  1
  1298.     @loopEnd:
  1299.         subq.l    #1,d0
  1300.         bpl        @loopBase
  1301.  
  1302.         // now do any leftover bits
  1303.         move.l    numBytesPerRow, d0
  1304.         beq        @nextRow
  1305.         subq.l    #2, d0
  1306.         bmi        @moveByte
  1307.         move.w    (srcPixelP)+, (dstPixelP)+
  1308.         tst        d0
  1309.         beq        @nextRow
  1310.     @moveByte:    
  1311.         move.b    (srcPixelP)+, (dstPixelP)+
  1312.  
  1313.     @nextRow:
  1314.         adda.l    srcRowStride, srcPixelP
  1315.         adda.l    dstRowStride, dstPixelP
  1316.         subq.l    #1, rowsToCopy
  1317.         bne        @forEachRow
  1318.  
  1319. #if __MWERKS__
  1320.         frfree
  1321. #endif
  1322.  
  1323.         SW_ASM_END
  1324. }
  1325.  
  1326.  
  1327.  
  1328. ///--------------------------------------------------------------------------------------
  1329. //        BlitPixieMask8Bit
  1330. ///--------------------------------------------------------------------------------------
  1331.  
  1332. SW_ASM_FUNC void BlitPixieMask8Bit(
  1333.     register PixelPtr srcPixelP,
  1334.     register PixelPtr dstPixelP,
  1335.     register PixelPtr maskPixelP,
  1336.     register unsigned long rowsToCopy,
  1337.     register unsigned long numBytesPerRow,
  1338.     register unsigned long srcRowStride,
  1339.     register unsigned long dstRowStride)
  1340. {
  1341.     register unsigned long loopsPerRow;
  1342.  
  1343.         SW_ASM_BEGIN
  1344.  
  1345. #if __MWERKS__
  1346.         fralloc +
  1347. #endif
  1348.  
  1349.         sub.l    numBytesPerRow, srcRowStride
  1350.         sub.l    numBytesPerRow, dstRowStride
  1351.         
  1352.             // longWordsPerRow = numBytesPerRow >> 2;
  1353.         move.l    numBytesPerRow, d0
  1354.         lsr.l    #2, d0
  1355.  
  1356.             // numBytesPerRow -= longWordsPerRow << 2;
  1357.         move.l    d0, d1
  1358.         lsl.l    #2, d1
  1359.         sub.l    d1, numBytesPerRow
  1360.  
  1361.             // loopsPerRow = longWordsPerRow >> 4;
  1362.         move.l    d0, loopsPerRow
  1363.         lsr.l    #4, loopsPerRow
  1364.  
  1365.             
  1366.         moveq    #0xF, d1
  1367.         and.l    d1, d0
  1368.         lsl.l    #3, d0                    // longWordsPerRow *= 8;
  1369.         lea     @loopEnd, a0            // get address of the end of the loop
  1370.         sub.l    d0, a0                    // calculate where to jmp in the loop
  1371.  
  1372.     @forEachRow:
  1373.         move.l    loopsPerRow, d2
  1374.         jmp        (a0)
  1375.     @loopBase:
  1376.             // 16
  1377.         move.l    (dstPixelP), d0
  1378.         and.l    (maskPixelP)+, d0
  1379.         or.l    (srcPixelP)+, d0
  1380.         move.l    d0, (dstPixelP)+
  1381.             // 15
  1382.         move.l    (dstPixelP), d0
  1383.         and.l    (maskPixelP)+, d0
  1384.         or.l    (srcPixelP)+, d0
  1385.         move.l    d0, (dstPixelP)+
  1386.             // 14
  1387.         move.l    (dstPixelP), d0
  1388.         and.l    (maskPixelP)+, d0
  1389.         or.l    (srcPixelP)+, d0
  1390.         move.l    d0, (dstPixelP)+
  1391.           // 13
  1392.         move.l    (dstPixelP), d0
  1393.         and.l    (maskPixelP)+, d0
  1394.         or.l    (srcPixelP)+, d0
  1395.         move.l    d0, (dstPixelP)+
  1396.           // 12
  1397.         move.l    (dstPixelP), d0
  1398.         and.l    (maskPixelP)+, d0
  1399.         or.l    (srcPixelP)+, d0
  1400.         move.l    d0, (dstPixelP)+
  1401.           // 11
  1402.         move.l    (dstPixelP), d0
  1403.         and.l    (maskPixelP)+, d0
  1404.         or.l    (srcPixelP)+, d0
  1405.         move.l    d0, (dstPixelP)+
  1406.           // 10
  1407.         move.l    (dstPixelP), d0
  1408.         and.l    (maskPixelP)+, d0
  1409.         or.l    (srcPixelP)+, d0
  1410.         move.l    d0, (dstPixelP)+
  1411.           //  9
  1412.         move.l    (dstPixelP), d0
  1413.         and.l    (maskPixelP)+, d0
  1414.         or.l    (srcPixelP)+, d0
  1415.         move.l    d0, (dstPixelP)+
  1416.           //  8
  1417.         move.l    (dstPixelP), d0
  1418.         and.l    (maskPixelP)+, d0
  1419.         or.l    (srcPixelP)+, d0
  1420.         move.l    d0, (dstPixelP)+
  1421.           //  7
  1422.         move.l    (dstPixelP), d0
  1423.         and.l    (maskPixelP)+, d0
  1424.         or.l    (srcPixelP)+, d0
  1425.         move.l    d0, (dstPixelP)+
  1426.             //  6
  1427.         move.l    (dstPixelP), d0
  1428.         and.l    (maskPixelP)+, d0
  1429.         or.l    (srcPixelP)+, d0
  1430.         move.l    d0, (dstPixelP)+
  1431.           //  5
  1432.         move.l    (dstPixelP), d0
  1433.         and.l    (maskPixelP)+, d0
  1434.         or.l    (srcPixelP)+, d0
  1435.         move.l    d0, (dstPixelP)+
  1436.           //  4
  1437.         move.l    (dstPixelP), d0
  1438.         and.l    (maskPixelP)+, d0
  1439.         or.l    (srcPixelP)+, d0
  1440.         move.l    d0, (dstPixelP)+
  1441.           //  3
  1442.         move.l    (dstPixelP), d0
  1443.         and.l    (maskPixelP)+, d0
  1444.         or.l    (srcPixelP)+, d0
  1445.         move.l    d0, (dstPixelP)+
  1446.         //  2
  1447.         move.l    (dstPixelP), d0
  1448.         and.l    (maskPixelP)+, d0
  1449.         or.l    (srcPixelP)+, d0
  1450.         move.l    d0, (dstPixelP)+
  1451.           //  1
  1452.         move.l    (dstPixelP), d0
  1453.         and.l    (maskPixelP)+, d0
  1454.         or.l    (srcPixelP)+, d0
  1455.         move.l    d0, (dstPixelP)+
  1456.     @loopEnd:
  1457.         subq.l    #1, d2
  1458.         bpl        @loopBase
  1459.  
  1460.         // now do any leftover bits
  1461.         move.l    numBytesPerRow, d2
  1462.         beq        @nextRow
  1463.         subq.l    #2, d2
  1464.         bmi        @moveByte
  1465.         move.w    (dstPixelP), d0
  1466.         and.w    (maskPixelP)+, d0
  1467.         or.w    (srcPixelP)+, d0
  1468.         move.w    d0, (dstPixelP)+
  1469.         tst        d2
  1470.         beq        @nextRow
  1471.     @moveByte:    
  1472.         move.b    (dstPixelP), d0
  1473.         and.b    (maskPixelP)+, d0
  1474.         or.b    (srcPixelP)+, d0
  1475.         move.b    d0, (dstPixelP)+
  1476.  
  1477.     @nextRow:
  1478.         adda.l    srcRowStride, srcPixelP
  1479.         adda.l    srcRowStride, maskPixelP
  1480.         adda.l    dstRowStride, dstPixelP
  1481.         subq.l    #1, rowsToCopy
  1482.         bne        @forEachRow
  1483.  
  1484. #if __MWERKS__
  1485.         frfree
  1486. #endif
  1487.  
  1488.         SW_ASM_END
  1489. }
  1490.  
  1491.  
  1492.  
  1493.  
  1494. ///--------------------------------------------------------------------------------------
  1495. //        BlitPixiePartialMask8Bit
  1496. ///--------------------------------------------------------------------------------------
  1497.  
  1498. SW_ASM_FUNC void BlitPixiePartialMask8Bit(
  1499.     register PixelPtr srcPixelP,
  1500.     register PixelPtr dstPixelP,
  1501.     register PixelPtr maskPixelP,
  1502.     register unsigned long rowsToCopy,
  1503.     register unsigned long numBytesPerRow,
  1504.     register unsigned long srcRowStride,
  1505.     register unsigned long dstRowStride)
  1506. {
  1507.     register unsigned long loopsPerRow;
  1508.  
  1509.         SW_ASM_BEGIN
  1510.  
  1511. #if __MWERKS__
  1512.         fralloc +
  1513. #endif
  1514.  
  1515.         sub.l    numBytesPerRow, srcRowStride
  1516.         sub.l    numBytesPerRow, dstRowStride
  1517.  
  1518.             // longWordsPerRow = numBytesPerRow >> 2;
  1519.         move.l    numBytesPerRow, d0
  1520.         lsr.l    #2, d0
  1521.  
  1522.             // numBytesPerRow -= longWordsPerRow << 2;
  1523.         move.l    d0, d1
  1524.         lsl.l    #2, d1
  1525.         sub.l    d1, numBytesPerRow
  1526.  
  1527.             // loopsPerRow = longWordsPerRow >> 4;
  1528.         move.l    d0, loopsPerRow
  1529.         lsr.l    #4, loopsPerRow
  1530.  
  1531.             
  1532.         moveq    #0xF, d1
  1533.         and.l    d1, d0
  1534.         mulu    #14, d0                    // longWordsPerRow *= 14 (bytes in segment of loop)
  1535.         lea     @loopEnd, a0            // get address of the end of the loop
  1536.         sub.l    d0, a0                    // calculate where to jmp in the loop
  1537.  
  1538.     @forEachRow:
  1539.         move.l    loopsPerRow, d2
  1540.         jmp        (a0)
  1541.     @loopBase:
  1542.             // 16
  1543.         move.l    (dstPixelP), d0
  1544.         and.l    (maskPixelP), d0
  1545.         move.l    (maskPixelP)+, d1
  1546.         not.l    d1
  1547.         and.l    (srcPixelP)+, d1
  1548.         or.l    d1, d0
  1549.         move.l    d0, (dstPixelP)+
  1550.             // 15
  1551.         move.l    (dstPixelP), d0
  1552.         and.l    (maskPixelP), d0
  1553.         move.l    (maskPixelP)+, d1
  1554.         not.l    d1
  1555.         and.l    (srcPixelP)+, d1
  1556.         or.l    d1, d0
  1557.         move.l    d0, (dstPixelP)+
  1558.             // 14
  1559.         move.l    (dstPixelP), d0
  1560.         and.l    (maskPixelP), d0
  1561.         move.l    (maskPixelP)+, d1
  1562.         not.l    d1
  1563.         and.l    (srcPixelP)+, d1
  1564.         or.l    d1, d0
  1565.         move.l    d0, (dstPixelP)+
  1566.           // 13
  1567.         move.l    (dstPixelP), d0
  1568.         and.l    (maskPixelP), d0
  1569.         move.l    (maskPixelP)+, d1
  1570.         not.l    d1
  1571.         and.l    (srcPixelP)+, d1
  1572.         or.l    d1, d0
  1573.         move.l    d0, (dstPixelP)+
  1574.           // 12
  1575.         move.l    (dstPixelP), d0
  1576.         and.l    (maskPixelP), d0
  1577.         move.l    (maskPixelP)+, d1
  1578.         not.l    d1
  1579.         and.l    (srcPixelP)+, d1
  1580.         or.l    d1, d0
  1581.         move.l    d0, (dstPixelP)+
  1582.           // 11
  1583.         move.l    (dstPixelP), d0
  1584.         and.l    (maskPixelP), d0
  1585.         move.l    (maskPixelP)+, d1
  1586.         not.l    d1
  1587.         and.l    (srcPixelP)+, d1
  1588.         or.l    d1, d0
  1589.         move.l    d0, (dstPixelP)+
  1590.           // 10
  1591.         move.l    (dstPixelP), d0
  1592.         and.l    (maskPixelP), d0
  1593.         move.l    (maskPixelP)+, d1
  1594.         not.l    d1
  1595.         and.l    (srcPixelP)+, d1
  1596.         or.l    d1, d0
  1597.         move.l    d0, (dstPixelP)+
  1598.           //  9
  1599.         move.l    (dstPixelP), d0
  1600.         and.l    (maskPixelP), d0
  1601.         move.l    (maskPixelP)+, d1
  1602.         not.l    d1
  1603.         and.l    (srcPixelP)+, d1
  1604.         or.l    d1, d0
  1605.         move.l    d0, (dstPixelP)+
  1606.           //  8
  1607.         move.l    (dstPixelP), d0
  1608.         and.l    (maskPixelP), d0
  1609.         move.l    (maskPixelP)+, d1
  1610.         not.l    d1
  1611.         and.l    (srcPixelP)+, d1
  1612.         or.l    d1, d0
  1613.         move.l    d0, (dstPixelP)+
  1614.           //  7
  1615.         move.l    (dstPixelP), d0
  1616.         and.l    (maskPixelP), d0
  1617.         move.l    (maskPixelP)+, d1
  1618.         not.l    d1
  1619.         and.l    (srcPixelP)+, d1
  1620.         or.l    d1, d0
  1621.         move.l    d0, (dstPixelP)+
  1622.             //  6
  1623.         move.l    (dstPixelP), d0
  1624.         and.l    (maskPixelP), d0
  1625.         move.l    (maskPixelP)+, d1
  1626.         not.l    d1
  1627.         and.l    (srcPixelP)+, d1
  1628.         or.l    d1, d0
  1629.         move.l    d0, (dstPixelP)+
  1630.           //  5
  1631.         move.l    (dstPixelP), d0
  1632.         and.l    (maskPixelP), d0
  1633.         move.l    (maskPixelP)+, d1
  1634.         not.l    d1
  1635.         and.l    (srcPixelP)+, d1
  1636.         or.l    d1, d0
  1637.         move.l    d0, (dstPixelP)+
  1638.           //  4
  1639.         move.l    (dstPixelP), d0
  1640.         and.l    (maskPixelP), d0
  1641.         move.l    (maskPixelP)+, d1
  1642.         not.l    d1
  1643.         and.l    (srcPixelP)+, d1
  1644.         or.l    d1, d0
  1645.         move.l    d0, (dstPixelP)+
  1646.           //  3
  1647.         move.l    (dstPixelP), d0
  1648.         and.l    (maskPixelP), d0
  1649.         move.l    (maskPixelP)+, d1
  1650.         not.l    d1
  1651.         and.l    (srcPixelP)+, d1
  1652.         or.l    d1, d0
  1653.         move.l    d0, (dstPixelP)+
  1654.         //  2
  1655.         move.l    (dstPixelP), d0
  1656.         and.l    (maskPixelP), d0
  1657.         move.l    (maskPixelP)+, d1
  1658.         not.l    d1
  1659.         and.l    (srcPixelP)+, d1
  1660.         or.l    d1, d0
  1661.         move.l    d0, (dstPixelP)+
  1662.           //  1
  1663.         move.l    (dstPixelP), d0
  1664.         and.l    (maskPixelP), d0
  1665.         move.l    (maskPixelP)+, d1
  1666.         not.l    d1
  1667.         and.l    (srcPixelP)+, d1
  1668.         or.l    d1, d0
  1669.         move.l    d0, (dstPixelP)+
  1670.     @loopEnd:
  1671.         subq.l    #1, d2
  1672.         bpl        @loopBase
  1673.  
  1674.         // now do any leftover bits
  1675.         move.l    numBytesPerRow, d2
  1676.         beq        @nextRow
  1677.         subq.l    #2, d2
  1678.         bmi        @moveByte
  1679.         move.w    (dstPixelP), d0
  1680.         and.w    (maskPixelP), d0
  1681.         move.w    (maskPixelP)+, d1
  1682.         not.w    d1
  1683.         and.w    (srcPixelP)+, d1
  1684.         or.w    d1, d0
  1685.         move.w    d0, (dstPixelP)+
  1686.         tst        d2
  1687.         beq        @nextRow
  1688.     @moveByte:
  1689.         move.b    (dstPixelP), d0
  1690.         and.b    (maskPixelP), d0
  1691.         move.b    (maskPixelP)+, d1
  1692.         not.b    d1
  1693.         and.b    (srcPixelP)+, d1
  1694.         or.b    d1, d0
  1695.         move.b    d0, (dstPixelP)+
  1696.  
  1697.     @nextRow:
  1698.         adda.l    srcRowStride, srcPixelP
  1699.         adda.l    srcRowStride, maskPixelP
  1700.         adda.l    dstRowStride, dstPixelP
  1701.         subq.l    #1, rowsToCopy
  1702.         bne        @forEachRow
  1703.  
  1704. #if __MWERKS__
  1705.         frfree
  1706. #endif
  1707.  
  1708.         SW_ASM_END
  1709. }
  1710.  
  1711.  
  1712. #endif /* SW_USE_C */
  1713.  
  1714.  
  1715.