home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld files / Sources / SpriteFrame.c < prev    next >
Encoding:
Text File  |  1999-02-08  |  27.3 KB  |  1,096 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. //    SpriteFrame.c
  3. //
  4. //    Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  5. //
  6. //    Description:    implementation of the frame stuff
  7. ///--------------------------------------------------------------------------------------
  8.  
  9.  
  10. #ifndef __SWCOMMON__
  11. #include "SWCommonHeaders.h"
  12. #endif
  13.  
  14. #ifndef __TOOLUTILS__
  15. #include <ToolUtils.h>
  16. #endif
  17.  
  18. #ifndef __MEMORY__
  19. #include <Memory.h>
  20. #endif
  21.  
  22. #ifndef __RESOURCES__
  23. #include <Resources.h>
  24. #endif
  25.  
  26. #ifndef __ERRORS__
  27. #include <Errors.h>
  28. #endif
  29.  
  30. #ifndef __SPRITEWORLDUTILS__
  31. #include "SpriteWorldUtils.h"
  32. #endif
  33.  
  34. #ifndef __SPRITECOMPILER__
  35. #include "SpriteCompiler.h"
  36. #endif
  37.  
  38. #ifndef __SPRITEFRAME__
  39. #include "SpriteFrame.h"
  40. #endif
  41.  
  42.  
  43. ///--------------------------------------------------------------------------------------
  44. //    SWCreateFrame
  45. ///--------------------------------------------------------------------------------------
  46.  
  47. SW_FUNC OSErr SWCreateFrame(
  48.     GDHandle theGDH,
  49.     FramePtr* newFrameP,
  50.     Rect* frameRect,
  51.     short depth)
  52. {
  53.     OSErr             err = noErr;
  54.     GWorldPtr        frameGWorld;
  55.     FramePtr         tempFrameP;
  56.     long             numScanLines;    
  57.     
  58.     SW_ASSERT(theGDH != NULL);
  59.     SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
  60.             frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
  61.     
  62.     *newFrameP = NULL;
  63.     frameGWorld = NULL;
  64.     
  65.         
  66.     numScanLines = frameRect->bottom - frameRect->top;
  67.  
  68.     tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) + 
  69.         (sizeof(unsigned long) * (numScanLines+1)));
  70.     
  71.     if (tempFrameP != NULL)
  72.     {
  73.         if ( (**((**theGDH).gdPMap)).pixelSize == depth )
  74.             err = NewGWorld( &frameGWorld, depth, frameRect, nil, theGDH, noNewDevice );
  75.         else
  76.             err = NewGWorld( &frameGWorld, depth, frameRect, nil, nil, (GWorldFlags)nil );
  77.         
  78.         if (err == noErr)
  79.         {
  80.             tempFrameP->framePort = frameGWorld;
  81.             tempFrameP->frameRect = *frameRect;
  82.             tempFrameP->hotSpotH = 0;
  83.             tempFrameP->hotSpotV = 0;
  84.             tempFrameP->tileMaskIsSolid = false;
  85.             tempFrameP->numScanLines = numScanLines;
  86.             tempFrameP->sharesGWorld = false;
  87.             tempFrameP->isFrameLocked = false;
  88.             tempFrameP->isWindowFrame = false;
  89.     
  90.             SWInitializeFrame( tempFrameP, depth );
  91.             
  92.             *newFrameP = tempFrameP;
  93.         }
  94.     }
  95.     else
  96.     {
  97.         err = MemError();
  98.     }
  99.  
  100.     if (err != noErr)
  101.     {
  102.         if (tempFrameP != NULL)
  103.         {
  104.             if (tempFrameP->framePort != NULL)
  105.                 DisposeGWorld(tempFrameP->framePort);
  106.             DisposePtr((Ptr)tempFrameP);
  107.         }
  108.     }
  109.     
  110.     SWSetStickyIfError( err );
  111.     return err;
  112. }
  113.  
  114.  
  115. ///--------------------------------------------------------------------------------------
  116. //    SWCreateWindowFrame
  117. ///--------------------------------------------------------------------------------------
  118.  
  119. SW_FUNC OSErr SWCreateWindowFrame(
  120.     FramePtr*     newFrameP,
  121.     Rect*         frameRect,
  122.     short        maxHeight)
  123. {
  124.     OSErr             err = noErr;
  125.     GDHandle        currentGDH;
  126.     GWorldPtr        windowGWorld;
  127.     FramePtr         tempFrameP = NULL;
  128.     short            depth;
  129.     long             numScanLines;
  130.     Point            globalOffset;
  131.     
  132.     SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
  133.               frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
  134.     
  135.     *newFrameP = NULL;
  136.     
  137.     GetGWorld( &windowGWorld, ¤tGDH );
  138.         // more scanlines than we need, but this saves us from 
  139.         // needing to calculate an offset in BlitPixie, and allows 
  140.         // blitting to outside the worldRect. 
  141.     numScanLines = (windowGWorld->portRect.bottom - windowGWorld->portRect.top);
  142.     numScanLines = SW_MAX(numScanLines, maxHeight);
  143.     
  144.         // Clip frameRect with the window's boundaries
  145.     frameRect->top = SW_MAX(frameRect->top, windowGWorld->portRect.top);
  146.     frameRect->left = SW_MAX(frameRect->left, windowGWorld->portRect.left);
  147.     frameRect->bottom = SW_MIN(frameRect->bottom, windowGWorld->portRect.bottom);
  148.     frameRect->right = SW_MIN(frameRect->right, windowGWorld->portRect.right);
  149.     
  150.     globalOffset = topLeft( *frameRect );
  151.     LocalToGlobal( &globalOffset );
  152.     
  153.     tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) + 
  154.             (sizeof(unsigned long) * numScanLines));
  155.  
  156.     if (tempFrameP != NULL)
  157.     {
  158.         depth = (**(**currentGDH).gdPMap).pixelSize;
  159.         tempFrameP->framePort = windowGWorld;
  160.  
  161.         tempFrameP->frameRect = *frameRect;
  162.         
  163.         // cache frameRowBytes for use by our blitter routine
  164.  
  165.         tempFrameP->frameRowBytes = (**tempFrameP->framePort->portPixMap).rowBytes & 0x7FFF;
  166.  
  167.             // this calculation generates a mask value that we use to
  168.             // long word align the rectangle when we draw the frame.
  169.             // note that the expression "sizeof(long) * kBitsPerByte" gives us
  170.             // the number of bits in a long.
  171.     
  172.             // align on long word boundary
  173.         tempFrameP->rightAlignFactor = ((sizeof(long) * kBitsPerByte) / depth) - 1;
  174.         tempFrameP->leftAlignFactor = ~(tempFrameP->rightAlignFactor);
  175.  
  176.             // useCount not used for window/work/back frames
  177.         tempFrameP->useCount = 0;
  178.  
  179.             // here we set up an array of offsets to the scan lines of
  180.             // this frame. this allows us to address a particular scan line
  181.             // without doing a costly multiply.
  182.         tempFrameP->numScanLines = numScanLines;
  183.         tempFrameP->scanLinePtrArray = (unsigned long*)(tempFrameP + 1);
  184.  
  185.         {    
  186.             tempFrameP->worldRectOffset = 0;
  187.                 
  188.             if (depth < 8)
  189.             {
  190.                 short        roundOff;
  191.                 
  192.                 roundOff = 8/depth;
  193.                 tempFrameP->worldRectOffset = 
  194.                     (globalOffset.h - frameRect->left) - 
  195.                     (((globalOffset.h - frameRect->left)/roundOff)*roundOff);
  196.             }
  197.                 
  198.             for (numScanLines = 0; numScanLines < tempFrameP->numScanLines; numScanLines++)
  199.             {
  200.                 tempFrameP->scanLinePtrArray[numScanLines] = 
  201.                     ((numScanLines+(globalOffset.v - frameRect->top) ) * 
  202.                     tempFrameP->frameRowBytes) +
  203.                     (globalOffset.h - frameRect->left)*4/(32/depth);
  204.             }
  205.         }
  206.  
  207.         tempFrameP->sharesGWorld = false;
  208.         tempFrameP->isWindowFrame = true;
  209.  
  210.         *newFrameP = tempFrameP;
  211.     }
  212.     else
  213.     {
  214.         err = MemError();
  215.     }
  216.  
  217.     if (err != noErr)
  218.     {
  219.         if (tempFrameP != NULL)
  220.         {
  221.             DisposePtr((Ptr)tempFrameP);
  222.         }
  223.     }
  224.     
  225.     SWSetStickyIfError( err );
  226.     return err;
  227. }
  228.  
  229.  
  230. ///--------------------------------------------------------------------------------------
  231. //    SWCreateFrameFromCicnResource
  232. ///--------------------------------------------------------------------------------------
  233.  
  234. SW_FUNC OSErr SWCreateFrameFromCicnResource(
  235.     SpriteWorldPtr destSpriteWorld,
  236.     FramePtr* newFrameP,
  237.     short iconResID,
  238.     MaskType maskType)
  239. {
  240.     OSErr             err;  
  241.     GWorldPtr         saveGWorld;
  242.     GDHandle         saveGDH;
  243.     GDHandle        theGDH;
  244.     FramePtr         tempFrameP;
  245.     CIconHandle     cIconH;
  246.     RgnHandle         maskRgn;
  247.     Rect             frameRect;
  248.  
  249.     *newFrameP = NULL;
  250.     tempFrameP = NULL;
  251.     
  252.     SW_ASSERT(destSpriteWorld != NULL);
  253.  
  254.     GetGWorld(&saveGWorld, &saveGDH);
  255.     
  256.     cIconH = GetCIcon( iconResID );
  257.  
  258.     if (cIconH != NULL)
  259.     {
  260.         HNoPurge((Handle)cIconH);
  261.         frameRect = (**cIconH).iconPMap.bounds;
  262.         
  263.         theGDH = destSpriteWorld->mainSWGDH;
  264.         
  265.         err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, destSpriteWorld->pixelDepth);
  266.     }
  267.     else
  268.     {
  269.         err = MemError();
  270.         if ( err == noErr )
  271.             err = resNotFound;
  272.     }
  273.     
  274.     if (err == noErr)
  275.     {
  276.         (void)LockPixels( GetGWorldPixMap(tempFrameP->framePort) );
  277.         SetGWorld(tempFrameP->framePort, nil);
  278.         EraseRect( &frameRect );
  279.         PlotCIcon(&frameRect, cIconH);
  280.         UnlockPixels( GetGWorldPixMap(tempFrameP->framePort) );
  281.  
  282.             // make a region mask
  283.         if ((maskType & kRegionMask) != 0)
  284.         {
  285.             err = SWCreateRegionFromCIconMask(&maskRgn, cIconH);
  286.  
  287.             if (err == noErr)
  288.             {
  289.                 SWSetFrameMaskRgn(tempFrameP, maskRgn);
  290.             }
  291.         }
  292.     }
  293.  
  294.     if (err == noErr)
  295.     {
  296.             // make a pixel mask
  297.         if ((maskType & kPixelMask) != 0)
  298.         {
  299.             err = SWCreateGWorldFromCIconMask(destSpriteWorld, &tempFrameP->maskPort, cIconH);
  300.             
  301.             if (err == noErr && destSpriteWorld->pixelDepth <= 8)
  302.             {
  303.                 (void)LockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
  304.                 SetGWorld(tempFrameP->maskPort, nil);
  305.                 InvertRect(&tempFrameP->maskPort->portRect);
  306.                 UnlockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
  307.             }
  308.         }
  309.     }
  310.  
  311.     if (cIconH != NULL)
  312.     {
  313.         DisposeCIcon(cIconH);
  314.     }
  315.  
  316.     if (err == noErr)
  317.     {
  318.         *newFrameP = tempFrameP;
  319.     }
  320.  
  321.     if (err != noErr)
  322.     {
  323.             // an error occurred so dispose of anything we managed to create
  324.         if (tempFrameP != NULL)
  325.         {
  326.             SWDisposeFrame(&tempFrameP);
  327.         }
  328.     }
  329.  
  330.     SetGWorld(saveGWorld, nil);
  331.  
  332.     SWSetStickyIfError( err );
  333.     return err;
  334. }
  335.  
  336.  
  337. ///--------------------------------------------------------------------------------------
  338. //    SWCreateFrameFromPictResource
  339. ///--------------------------------------------------------------------------------------
  340.  
  341. SW_FUNC OSErr SWCreateFrameFromPictResource(
  342.     SpriteWorldPtr destSpriteWorld,
  343.     FramePtr* newFrameP,
  344.     short pictResID,
  345.     short maskResID,
  346.     MaskType maskType)
  347. {
  348.     OSErr             err;
  349.     GWorldPtr         saveGWorld;
  350.     GDHandle         saveGDH;
  351.     GDHandle        theGDH;
  352.     PicHandle         spritePictH, 
  353.                     maskPictH;
  354.     FramePtr         tempFrameP;
  355.     RgnHandle         maskRgn;
  356.     Rect             frameRect;
  357.  
  358.     SW_ASSERT(destSpriteWorld != NULL);
  359.  
  360.     tempFrameP = NULL;
  361.     *newFrameP = NULL;
  362.     
  363.     GetGWorld(&saveGWorld, &saveGDH);
  364.  
  365.     spritePictH = GetPicture(pictResID);
  366.  
  367.     if (spritePictH != NULL)
  368.     {
  369.         frameRect = (**spritePictH).picFrame;
  370.         OffsetRect( &frameRect, -frameRect.left, -frameRect.top );
  371.  
  372.         theGDH = destSpriteWorld->mainSWGDH;
  373.         
  374.         err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, destSpriteWorld->pixelDepth);
  375.  
  376.         if (err == noErr)
  377.         {
  378.             (void)LockPixels( GetGWorldPixMap(tempFrameP->framePort) );
  379.             SetGWorld(tempFrameP->framePort, nil);
  380.             EraseRect(&frameRect);    // Necessary for some wierd picture formats, like XOr
  381.             DrawPicture(spritePictH, &frameRect);
  382.             UnlockPixels( GetGWorldPixMap(tempFrameP->framePort) );
  383.             ReleaseResource((Handle)spritePictH);
  384.         }
  385.         
  386.             // make a region mask
  387.         if (((maskType & kRegionMask) != 0) && (err == noErr))
  388.         {
  389.             maskPictH = GetPicture(maskResID);
  390.     
  391.             if (maskPictH != NULL)
  392.             {
  393.                 err = SWCreateRegionFromPict(&maskRgn, maskPictH );
  394.         
  395.                 ReleaseResource((Handle)maskPictH);
  396.             }
  397.             else
  398.             {
  399.                 err = MemError();
  400.                 if ( err == noErr )
  401.                     err = resNotFound;
  402.             }
  403.  
  404.             if (err == noErr)
  405.             {
  406.                 SWSetFrameMaskRgn(tempFrameP, maskRgn);
  407.             }
  408.         }
  409.  
  410.             // make a pixel mask
  411.         if (((maskType & kPixelMask) != 0) && (err == noErr))
  412.         {
  413.             err = SWCreateGWorldFromPictResource(destSpriteWorld, &tempFrameP->maskPort, maskResID);
  414.  
  415.             if (err == noErr)
  416.             {
  417.                 if ( pictResID == maskResID )
  418.                 {
  419.                     err = SWBlackenGWorld( tempFrameP->maskPort );
  420.                 
  421.                     if (err == noErr)
  422.                         err = SWWhitenGWorld( tempFrameP->framePort );
  423.                 }
  424.                 if (err == noErr && destSpriteWorld->pixelDepth <= 8)
  425.                 {
  426.                     (void)LockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
  427.                     SetGWorld(tempFrameP->maskPort, nil);
  428.                     InvertRect(&tempFrameP->maskPort->portRect);
  429.                     UnlockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
  430.                 }
  431.             }
  432.         }
  433.  
  434.         if (err == noErr)
  435.         {
  436.             *newFrameP = tempFrameP;
  437.         }
  438.         else
  439.         {
  440.                 // an error occurred so dispose of anything we managed to create
  441.             if (tempFrameP != NULL)
  442.             {
  443.                 SWDisposeFrame(&tempFrameP);
  444.             }
  445.         }
  446.     }
  447.     else
  448.     {
  449.         err = MemError();
  450.         if ( err == noErr )
  451.             err = resNotFound;
  452.     }
  453.  
  454.     SetGWorld(saveGWorld, nil);
  455.  
  456.     SWSetStickyIfError( err );
  457.     return err;
  458. }
  459.  
  460.  
  461. ///--------------------------------------------------------------------------------------
  462. //    SWCreateFrameFromGWorldAndRect
  463. ///--------------------------------------------------------------------------------------
  464.  
  465. SW_FUNC OSErr SWCreateFrameFromGWorldAndRect(
  466.     FramePtr* newFrameP,
  467.     GWorldPtr pictGWorld,
  468.     GWorldPtr maskGWorld,
  469.     Rect* frameRect,
  470.     MaskType maskType)
  471. {
  472.     OSErr err;
  473.     GWorldPtr tempMaskGWorld;
  474.     
  475.     err = SWCreateFrameFromGWorldAndRectStart( &tempMaskGWorld, 
  476.             frameRect->right - frameRect->left, frameRect->bottom - frameRect->top, maskType );
  477.     if ( err == noErr ) {
  478.         err = SWCreateFrameFromGWorldAndRectPartial( newFrameP, pictGWorld, maskGWorld, 
  479.                 tempMaskGWorld, frameRect, maskType );
  480.         SWCreateFrameFromGWorldAndRectFinish( tempMaskGWorld );
  481.     }
  482.     
  483.     SWSetStickyIfError( err );
  484.     return err;
  485. }
  486.  
  487. ///--------------------------------------------------------------------------------------
  488. //    SWCreateFrameFromGWorldAndRectStart
  489. ///--------------------------------------------------------------------------------------
  490.  
  491. SW_FUNC OSErr SWCreateFrameFromGWorldAndRectStart(
  492.     GWorldPtr *tempMaskGWorld,
  493.     short maxWidth,
  494.     short maxHeight,
  495.     MaskType maskType)
  496. {
  497.     OSErr        err = noErr;
  498.     
  499.     *tempMaskGWorld = NULL;
  500.     if ((maskType & kRegionMask) != 0)
  501.     {
  502.         err = SWCreateRegionFromGWorldAndRectStart( tempMaskGWorld, maxWidth, maxHeight );
  503.     }
  504.     return err;
  505. }
  506.  
  507. ///--------------------------------------------------------------------------------------
  508. //    SWCreateFrameFromGWorldAndRectFinish
  509. ///--------------------------------------------------------------------------------------
  510.  
  511. SW_FUNC void SWCreateFrameFromGWorldAndRectFinish(
  512.     GWorldPtr tempMaskGWorld)
  513. {
  514.     SWCreateRegionFromGWorldAndRectFinish( tempMaskGWorld );
  515. }
  516.  
  517. ///--------------------------------------------------------------------------------------
  518. //    SWCreateFrameFromGWorldAndRectPartial
  519. ///--------------------------------------------------------------------------------------
  520.  
  521. SW_FUNC OSErr SWCreateFrameFromGWorldAndRectPartial(
  522.     FramePtr* newFrameP,
  523.     GWorldPtr pictGWorld,
  524.     GWorldPtr maskGWorld,
  525.     GWorldPtr tempMaskGWorld,
  526.     Rect* frameRect,
  527.     MaskType maskType)
  528. {                        
  529.     OSErr             err = noErr;
  530.     short            depth;
  531.     long             numScanLines;
  532.     FramePtr         tempFrameP;
  533.     RgnHandle         maskRgn;
  534.  
  535.     SW_ASSERT(pictGWorld != NULL);
  536.     SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
  537.               frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
  538.  
  539.     tempFrameP = NULL;
  540.     *newFrameP = NULL;
  541.  
  542.     numScanLines = frameRect->bottom - frameRect->top;
  543.     depth = (**(GetGWorldPixMap( pictGWorld ))).pixelSize;
  544.     
  545.     tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) + 
  546.         (sizeof(unsigned long) * (numScanLines+1)));
  547.     
  548.     if (tempFrameP != NULL)
  549.     {
  550.         tempFrameP->framePort = pictGWorld;
  551.         
  552.             // make a pixel mask
  553.         if ((maskType & kPixelMask) != 0) 
  554.         {
  555.             SW_ASSERT(maskGWorld != NULL);
  556.             tempFrameP->maskPort = maskGWorld;
  557.         }
  558.         tempFrameP->frameRect = *frameRect;
  559.         tempFrameP->sharesGWorld = true;
  560.         tempFrameP->numScanLines = numScanLines;
  561.  
  562.         SWInitializeFrame( tempFrameP, depth );
  563.     }
  564.     else
  565.     {
  566.         err = MemError();
  567.     }
  568.  
  569.     if (err == noErr)
  570.     {
  571.             // make a region mask
  572.         if (((maskType & kRegionMask) != 0) && (err == noErr))
  573.         {
  574.             SW_ASSERT(maskGWorld != NULL);
  575.             
  576.             err = SWCreateRegionFromGWorldAndRectPartial(&maskRgn, maskGWorld, 
  577.                     tempMaskGWorld, frameRect);
  578.                 
  579.             if (err == noErr)
  580.             {
  581.                 SWSetFrameMaskRgn(tempFrameP, maskRgn);
  582.             }
  583.         }
  584.     
  585.         if (err == noErr)
  586.         {
  587.             *newFrameP = tempFrameP;
  588.         }
  589.         else
  590.         {
  591.                 // an error occurred so dispose of anything we managed to create
  592.                 
  593.             if (tempFrameP != NULL)
  594.             {
  595.                 SWDisposeFrame(&tempFrameP);
  596.             }
  597.         }
  598.     }
  599.     
  600.     SWSetStickyIfError( err );
  601.     return err;
  602. }
  603.  
  604.  
  605. ///--------------------------------------------------------------------------------------
  606. //    SWDisposeFrame
  607. ///--------------------------------------------------------------------------------------
  608.  
  609. SW_FUNC Boolean SWDisposeFrame(
  610.     FramePtr *oldFramePP)
  611. {
  612.     Boolean        frameDisposed;
  613.     FramePtr    oldFrameP = *oldFramePP;
  614.     
  615.     frameDisposed = false;
  616.     if (oldFrameP != NULL)
  617.     {
  618.             // is this frame still in use by another sprite?
  619.         if (oldFrameP->useCount > 1)
  620.         {
  621.                 // one less sprite is using it now!
  622.             oldFrameP->useCount--;
  623.         }
  624.         else    // no more sprites are using this frame
  625.         {    
  626.             frameDisposed = true;
  627.             if (oldFrameP->framePort != NULL)
  628.             {
  629.                 if ( !oldFrameP->sharesGWorld )
  630.                     DisposeGWorld(oldFrameP->framePort);
  631.                 oldFrameP->framePort = NULL;
  632.             }
  633.             
  634.             if (oldFrameP->maskRgn != NULL)
  635.             {
  636.                 DisposeRgn(oldFrameP->maskRgn);
  637.                 oldFrameP->maskRgn = NULL;
  638.             }
  639.             
  640.             if (oldFrameP->maskPort != NULL)
  641.             {
  642.                 if ( !oldFrameP->sharesGWorld )
  643.                     DisposeGWorld(oldFrameP->maskPort);
  644.                 oldFrameP->maskPort = NULL;
  645.             }
  646.  
  647.             if (oldFrameP->pixCodeH != NULL)
  648.             {
  649.                 DisposeHandle((Handle)oldFrameP->pixCodeH);
  650.                 oldFrameP->pixCodeH = NULL;
  651.                 oldFrameP->frameBlitterP = NULL;
  652.             }
  653.  
  654.             DisposePtr((Ptr)oldFrameP);
  655.             *oldFramePP = NULL;    // Change the original pointer to NULL
  656.         }
  657.     }
  658.     
  659.     return frameDisposed;
  660. }
  661.  
  662.  
  663. ///--------------------------------------------------------------------------------------
  664. //    SWDisposeWindowFrame
  665. ///--------------------------------------------------------------------------------------
  666.  
  667. SW_FUNC void SWDisposeWindowFrame(
  668.     FramePtr *oldFramePP)
  669. {
  670.     FramePtr    oldFrameP = *oldFramePP;
  671.     
  672.     if (oldFrameP != NULL)
  673.     {
  674.         DisposePtr((Ptr)oldFrameP);
  675.         *oldFramePP = NULL;    // Change the original pointer to NULL
  676.     }
  677. }
  678.  
  679.  
  680. ///--------------------------------------------------------------------------------------
  681. //    SWInitializeFrame
  682. ///--------------------------------------------------------------------------------------
  683.  
  684. SW_FUNC void SWInitializeFrame(
  685.     FramePtr tempFrameP,
  686.     short depth )
  687. {
  688.     long     curScanLine;
  689.     
  690.     SW_ASSERT(tempFrameP != NULL);
  691.         
  692.     
  693.         // cache frameRowBytes for use by our blitter routine
  694.  
  695.     tempFrameP->frameRowBytes = (**tempFrameP->framePort->portPixMap).rowBytes & 0x7FFF;
  696.  
  697.         // this calculation generates a mask value that we use to
  698.         // long word align the rectangle when we draw the frame.
  699.         // note that the expression "sizeof(long) * kBitsPerByte" gives us
  700.         // the number of bits in a long.
  701.  
  702.  
  703.         // align on long word boundary
  704.     tempFrameP->rightAlignFactor = ((sizeof(long) * kBitsPerByte) / depth) - 1;
  705.     tempFrameP->leftAlignFactor = ~(tempFrameP->rightAlignFactor);
  706.  
  707.         // the useCount keeps track of the number of sprites that
  708.         // are using this frame. we need to know this so we don't
  709.         // dispose this frame twice when we are disposing the 
  710.         // sprites that use it.
  711.     tempFrameP->useCount = 0;
  712.     
  713.     tempFrameP->worldRectOffset = 0;
  714.     
  715.         // here we set up an array of offsets to the scan lines of
  716.         // this frame. this allows us to address a particular scan line
  717.         // without doing a costly multiply.
  718.     tempFrameP->scanLinePtrArray = (unsigned long*)(tempFrameP + 1);
  719.     
  720.     for (curScanLine = 0; curScanLine < tempFrameP->numScanLines; curScanLine++)
  721.     {
  722.         tempFrameP->scanLinePtrArray[curScanLine] = 
  723.             ((tempFrameP->frameRect.top + curScanLine) * tempFrameP->frameRowBytes);
  724.     }
  725. }
  726.  
  727.  
  728. ///--------------------------------------------------------------------------------------
  729. //    SWSetFrameMaskRgn
  730. ///--------------------------------------------------------------------------------------
  731.  
  732. SW_FUNC void SWSetFrameMaskRgn(
  733.     FramePtr srcFrameP,
  734.     RgnHandle maskRgn)
  735. {
  736.     SW_ASSERT(srcFrameP != NULL);
  737.     SW_ASSERT(maskRgn != NULL);
  738.     
  739.     if (maskRgn != NULL)
  740.     {
  741.         srcFrameP->maskRgn = maskRgn;
  742.     
  743.         srcFrameP->offsetPoint.h = (**maskRgn).rgnBBox.left;
  744.         srcFrameP->offsetPoint.v = (**maskRgn).rgnBBox.top;
  745.     }
  746. }
  747.  
  748.  
  749. ///--------------------------------------------------------------------------------------
  750. //    SWSetFrameHotSpot
  751. ///--------------------------------------------------------------------------------------
  752.  
  753. SW_FUNC void SWSetFrameHotSpot(
  754.     FramePtr srcFrameP,
  755.     short hotSpotH,
  756.     short hotSpotV)
  757. {
  758.     SW_ASSERT(srcFrameP != NULL);
  759.     
  760.     srcFrameP->hotSpotH = hotSpotH;
  761.     srcFrameP->hotSpotV = hotSpotV;
  762. }
  763.  
  764.  
  765. ///--------------------------------------------------------------------------------------
  766. //  SWCopyFrame
  767. ///--------------------------------------------------------------------------------------
  768.  
  769. SW_FUNC OSErr SWCopyFrame(
  770.     SpriteWorldPtr destSpriteWorldP,
  771.     FramePtr oldFrameP, 
  772.     FramePtr *newFrameP,
  773.     Boolean copyMasks)
  774. {
  775.     OSErr             err;  
  776.     GWorldPtr         saveGWorld;
  777.     GDHandle         saveGDH;
  778.     GDHandle        theGDH;
  779.     GWorldFlags        pixelState;
  780.     short            depth;
  781.     FramePtr         tempFrameP;
  782.     Rect             frameRect;
  783.     
  784.     SW_ASSERT(newFrameP != NULL);
  785.     SW_ASSERT(oldFrameP != NULL);
  786.     SW_ASSERT(destSpriteWorldP != NULL);
  787.  
  788.     *newFrameP = NULL;
  789.     tempFrameP = NULL;
  790.     depth = destSpriteWorldP->pixelDepth;
  791.     theGDH = destSpriteWorldP->mainSWGDH;
  792.  
  793.     GetGWorld(&saveGWorld, &saveGDH);
  794.     
  795.         // Get size of new frame
  796.     frameRect = oldFrameP->frameRect;
  797.     OffsetRect(&frameRect, -frameRect.left, -frameRect.top);
  798.     
  799.         // Create the new frame
  800.     err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, depth);
  801.     
  802.         // Copy the image from the old frame into the new frame
  803.     if ( err == noErr )
  804.     {
  805.         pixelState = GetPixelsState( oldFrameP->framePort->portPixMap );
  806.         (void)LockPixels( GetGWorldPixMap(oldFrameP->framePort) );
  807.         (void)LockPixels( GetGWorldPixMap(tempFrameP->framePort) );
  808.         SetGWorld( oldFrameP->framePort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
  809.         SetGWorld( tempFrameP->framePort, nil );
  810.  
  811.         CopyBits ( (BitMap*)*GetGWorldPixMap( oldFrameP->framePort ),
  812.             (BitMap*)*GetGWorldPixMap( tempFrameP->framePort ),
  813.             &oldFrameP->frameRect, 
  814.             &frameRect, 
  815.             srcCopy, 
  816.             nil);
  817.  
  818.         SetPixelsState( oldFrameP->framePort->portPixMap, pixelState );
  819.         UnlockPixels( GetGWorldPixMap(tempFrameP->framePort) );
  820.     }
  821.  
  822.     
  823.         // copy region mask
  824.     if ((oldFrameP->maskRgn != NULL) && (err == noErr))
  825.     {
  826.         tempFrameP->maskRgn = NewRgn();
  827.     
  828.         if (tempFrameP->maskRgn == NULL)
  829.             err = MemError();
  830.         else if (copyMasks)
  831.             CopyRgn(oldFrameP->maskRgn, tempFrameP->maskRgn);
  832.     }
  833.  
  834.         // copy pixel mask
  835.     if ((oldFrameP->maskPort != NULL) && (err == noErr))
  836.     {
  837.         if ( (**((**theGDH).gdPMap)).pixelSize == depth )
  838.             err = NewGWorld( &tempFrameP->maskPort, depth, &frameRect, nil, theGDH, noNewDevice );
  839.         else
  840.             err = NewGWorld( &tempFrameP->maskPort, depth, &frameRect, nil, nil, 0 );
  841.  
  842.             // Copy pixel mask from old frame into new frame
  843.         if ((err == noErr) && (copyMasks))
  844.         {
  845.             pixelState = GetPixelsState( oldFrameP->maskPort->portPixMap );
  846.             (void)LockPixels( GetGWorldPixMap(oldFrameP->maskPort) );
  847.             (void)LockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
  848.             SetGWorld( oldFrameP->maskPort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
  849.             SetGWorld( tempFrameP->maskPort, nil );
  850.     
  851.             CopyBits( (BitMap*)*GetGWorldPixMap( oldFrameP->maskPort ),
  852.                 (BitMap*)*GetGWorldPixMap( tempFrameP->maskPort ),
  853.                 &oldFrameP->frameRect, 
  854.                 &frameRect, 
  855.                 srcCopy, 
  856.                 nil);
  857.     
  858.             SetPixelsState( oldFrameP->maskPort->portPixMap, pixelState );
  859.             UnlockPixels( GetGWorldPixMap(tempFrameP->maskPort) );
  860.         }
  861.     }
  862.  
  863.     if (err == noErr)
  864.     {
  865.         *newFrameP = tempFrameP;
  866.     }
  867.     else
  868.     {
  869.             // an error occurred so dispose of anything we managed to create
  870.         if (tempFrameP != NULL)
  871.         {
  872.             SWDisposeFrame(&tempFrameP);
  873.         }
  874.     }
  875.  
  876.     SetGWorld(saveGWorld, nil);
  877.  
  878.     SWSetStickyIfError( err );
  879.     return err;
  880. }
  881.  
  882.  
  883. ///--------------------------------------------------------------------------------------
  884. //    SWUpdateFrameMasks - updates the pixel and region masks of a frame
  885. ///--------------------------------------------------------------------------------------
  886.  
  887. SW_FUNC OSErr SWUpdateFrameMasks(
  888.     SpriteWorldPtr destSpriteWorldP, 
  889.     FramePtr srcFrameP)
  890. {
  891.     GWorldPtr            saveGWorld, newGWld;
  892.     GDHandle            saveGDH;
  893.     Rect                gwldRect;
  894.     ColorSearchUPP        blackenColSearchUPP;
  895.     Boolean                frameWasUnlocked = false;
  896.     OSErr                err = noErr;
  897.     
  898.     SW_ASSERT(destSpriteWorldP != NULL);
  899.     SW_ASSERT(srcFrameP != NULL);
  900.     
  901.     GetGWorld( &saveGWorld, &saveGDH );
  902.     
  903.     if (!srcFrameP->isFrameLocked)
  904.     {
  905.         SWLockFrame(srcFrameP);
  906.         frameWasUnlocked = true;
  907.     }
  908.     
  909.     gwldRect = srcFrameP->framePort->portRect;
  910.     
  911.         // Create 1-bit GWorld
  912.     err = NewGWorld(&newGWld, 1, &gwldRect, nil, nil, 0 );
  913.     
  914.     if ( err == noErr )
  915.     {
  916.         blackenColSearchUPP = NewColorSearchProc( blackenColorSearch );
  917.         (void)LockPixels( GetGWorldPixMap(newGWld) );
  918.         SetGWorld( srcFrameP->framePort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
  919.         SetGWorld( newGWld, nil );
  920.         AddSearch( blackenColSearchUPP );
  921.         
  922.             // Copy 8-bit image into 1-bit GWorld while turning it into a mask
  923.         CopyBits( (BitMap*)*GetGWorldPixMap( srcFrameP->framePort ),
  924.             (BitMap*)*GetGWorldPixMap( newGWld ),
  925.             &srcFrameP->framePort->portRect, 
  926.             &gwldRect, 
  927.             srcCopy, 
  928.             nil);
  929.         
  930.         DelSearch( blackenColSearchUPP );
  931.         DisposeRoutineDescriptor( blackenColSearchUPP );
  932.  
  933.         
  934.             // update the region mask if there is one
  935.         if (srcFrameP->maskRgn != NULL)
  936.         {
  937.             err = BitMapToRegion(srcFrameP->maskRgn, (BitMap*)*GetGWorldPixMap( newGWld ) );
  938.             
  939.             SWSetFrameMaskRgn(srcFrameP, srcFrameP->maskRgn);
  940.         }
  941.         
  942.             // update the pixel mask if there is one
  943.         if (srcFrameP->maskPort != NULL)
  944.         {
  945.             SetGWorld( srcFrameP->maskPort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
  946.             CopyBits( (BitMap*)*GetGWorldPixMap( newGWld ),
  947.                 (BitMap*)*GetGWorldPixMap( srcFrameP->maskPort ),
  948.                 &gwldRect, 
  949.                 &srcFrameP->maskPort->portRect, 
  950.                 srcCopy,
  951.                 nil);
  952.             
  953.             if (destSpriteWorldP->pixelDepth <= 8)
  954.             {
  955.                 SetGWorld(srcFrameP->maskPort, nil);
  956.                 InvertRect(&srcFrameP->maskPort->portRect);
  957.             }
  958.         }
  959.         
  960.         UnlockPixels( GetGWorldPixMap(newGWld) );
  961.         DisposeGWorld( newGWld );
  962.     }
  963.     
  964.     if (frameWasUnlocked)
  965.         SWUnlockFrame(srcFrameP);
  966.     
  967.     SetGWorld( saveGWorld, saveGDH );
  968.     
  969.     SWSetStickyIfError( err );
  970.     return err;
  971. }
  972.  
  973.  
  974. ///--------------------------------------------------------------------------------------
  975. //    SWLockFrame
  976. ///--------------------------------------------------------------------------------------
  977.  
  978. SW_FUNC void SWLockFrame(
  979.     FramePtr srcFrameP)
  980. {
  981.     PixMapHandle         pixMapH;
  982.     
  983.     SW_ASSERT(srcFrameP != NULL);
  984.  
  985.     if (!srcFrameP->isFrameLocked)
  986.     {
  987.         srcFrameP->isFrameLocked = true;
  988.         pixMapH = GetGWorldPixMap( srcFrameP->framePort );
  989.         (void)LockPixels( pixMapH );
  990.         HLockHi( (Handle)pixMapH );
  991.         srcFrameP->framePixHndl = pixMapH;
  992.         srcFrameP->framePix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
  993.         srcFrameP->frameBaseAddr = GetPixBaseAddr( pixMapH );
  994.         srcFrameP->frameRowBytes = (**pixMapH).rowBytes & 0x7FFF;
  995.         
  996.         if (srcFrameP->pixCodeH != NULL)
  997.         {
  998.             HLockHi((Handle)srcFrameP->pixCodeH);
  999.             srcFrameP->frameBlitterP = (BlitFuncPtr)StripAddress( *srcFrameP->pixCodeH );
  1000.         }
  1001.  
  1002.         if (srcFrameP->maskPort != NULL)
  1003.         {
  1004.             pixMapH = GetGWorldPixMap( srcFrameP->maskPort );
  1005.             (void)LockPixels( pixMapH );
  1006.             HLockHi( (Handle)pixMapH );
  1007.             srcFrameP->maskPixHndl = pixMapH;
  1008.             srcFrameP->maskPix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
  1009.             srcFrameP->maskBaseAddr = GetPixBaseAddr( pixMapH );
  1010.         }
  1011.     }
  1012. }
  1013.  
  1014.  
  1015. ///--------------------------------------------------------------------------------------
  1016. //    SWUnlockFrame
  1017. ///--------------------------------------------------------------------------------------
  1018.  
  1019. SW_FUNC void SWUnlockFrame(
  1020.     FramePtr srcFrameP)
  1021. {
  1022.     SW_ASSERT(srcFrameP != NULL);
  1023.     
  1024.     if (srcFrameP->isFrameLocked)
  1025.     {
  1026.         srcFrameP->isFrameLocked = false;
  1027.         
  1028.         if (srcFrameP->framePort != NULL && srcFrameP->framePixHndl != NULL)
  1029.         {
  1030.             HUnlock( (Handle)srcFrameP->framePixHndl );
  1031.             UnlockPixels(srcFrameP->framePixHndl);
  1032.         }
  1033.  
  1034.         if (srcFrameP->maskPort != NULL && srcFrameP->maskPixHndl != NULL)
  1035.         {
  1036.             HUnlock( (Handle)srcFrameP->maskPixHndl );
  1037.             UnlockPixels(srcFrameP->maskPixHndl);
  1038.         }
  1039.  
  1040.         srcFrameP->framePix = NULL;
  1041.         srcFrameP->frameBaseAddr = NULL;
  1042.         srcFrameP->maskPix = NULL;
  1043.         srcFrameP->maskBaseAddr = NULL;
  1044.         
  1045.         if (srcFrameP->pixCodeH != NULL)
  1046.         {
  1047.             HUnlock((Handle)srcFrameP->pixCodeH);
  1048.             srcFrameP->frameBlitterP = NULL;
  1049.         }
  1050.     }
  1051. }
  1052.  
  1053.  
  1054. ///--------------------------------------------------------------------------------------
  1055. //    SWLockWindowFrame
  1056. ///--------------------------------------------------------------------------------------
  1057.  
  1058. SW_FUNC void SWLockWindowFrame(
  1059.     FramePtr windowFrameP)
  1060. {
  1061.     PixMapHandle         pixMapH;
  1062.     
  1063.     SW_ASSERT(windowFrameP != NULL);
  1064.  
  1065.     if (!windowFrameP->isFrameLocked)
  1066.     {
  1067.         windowFrameP->isFrameLocked = true;
  1068.         pixMapH = windowFrameP->framePort->portPixMap;
  1069.         HLockHi( (Handle)pixMapH );
  1070.         windowFrameP->framePixHndl = pixMapH;
  1071.         windowFrameP->framePix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
  1072.         windowFrameP->frameBaseAddr = GetPixBaseAddr( pixMapH );
  1073.         windowFrameP->frameRowBytes = (**pixMapH).rowBytes & 0x7FFF;
  1074.     }
  1075. }
  1076.  
  1077.  
  1078. ///--------------------------------------------------------------------------------------
  1079. //    SWUnlockWindowFrame
  1080. ///--------------------------------------------------------------------------------------
  1081.  
  1082. SW_FUNC void SWUnlockWindowFrame(
  1083.     FramePtr windowFrameP)
  1084. {
  1085.     SW_ASSERT(windowFrameP != NULL);
  1086.     
  1087.     if (windowFrameP->isFrameLocked)
  1088.     {
  1089.         windowFrameP->isFrameLocked = false;
  1090.         HUnlock( (Handle)windowFrameP->framePixHndl );
  1091.         windowFrameP->framePix = NULL;
  1092.         windowFrameP->frameBaseAddr = NULL;
  1093.     }
  1094. }
  1095.  
  1096.