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

  1. ///--------------------------------------------------------------------------------------
  2. //    Sprite.c
  3. //
  4. //    Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
  5. //
  6. //    Description:    implementation of the sprites
  7. ///--------------------------------------------------------------------------------------
  8.  
  9.  
  10. #ifndef __SWCOMMON__
  11. #include "SWCommonHeaders.h"
  12. #endif
  13.  
  14. #ifndef __MEMORY__
  15. #include <Memory.h>
  16. #endif
  17.  
  18. #ifndef __SPRITEWORLDUTILS__
  19. #include "SpriteWorldUtils.h"
  20. #endif
  21.  
  22. #ifndef __SPRITEWORLD__
  23. #include "SpriteWorld.h"
  24. #endif
  25.  
  26. #ifndef __SPRITE__
  27. #include "Sprite.h"
  28. #endif
  29.  
  30. #ifndef __SPRITEFRAME__
  31. #include "SpriteFrame.h"
  32. #endif
  33.  
  34. #ifndef __BLITPIXIE__
  35. #include "BlitPixie.h"
  36. #endif
  37.  
  38. extern RgnHandle         gCollisionSectRgn;
  39. extern RgnHandle        gCollisionSpareRgn;
  40. extern Boolean             gSWmmuMode;
  41.  
  42.  
  43. ///--------------------------------------------------------------------------------------
  44. //    SWCreateSprite
  45. ///--------------------------------------------------------------------------------------
  46.  
  47. SW_FUNC OSErr SWCreateSprite(
  48.     SpritePtr* newSpriteP,
  49.     void* spriteStorageP,
  50.     short maxFrames)
  51. {
  52.     OSErr err = noErr;
  53.     SpritePtr tempSpriteP;
  54.     Size frameArraySize;
  55.  
  56.     SWAssert( newSpriteP != NULL && maxFrames > 0 );
  57.     
  58.     *newSpriteP = NULL;
  59.  
  60.     tempSpriteP =  (spriteStorageP == NULL) ? (SpritePtr)NewPtr(sizeof(SpriteRec)) : (SpritePtr)spriteStorageP;
  61.  
  62.     if (tempSpriteP != NULL)
  63.     {
  64.         frameArraySize = (Size)maxFrames * sizeof(FramePtr);
  65.  
  66.         tempSpriteP->frameArray = (FramePtr *)NewPtrClear(frameArraySize);
  67.  
  68.         if (tempSpriteP->frameArray != NULL)
  69.         {
  70.             tempSpriteP->nextSpriteP = NULL;
  71.             tempSpriteP->prevSpriteP = NULL;
  72.  
  73.                 // initialize drawing fields
  74.             tempSpriteP->isVisible = true;
  75.             tempSpriteP->needsToBeDrawn = true;
  76.             tempSpriteP->needsToBeErased = false;
  77.             tempSpriteP->isUnderTiles = false;
  78.             tempSpriteP->destFrameRect.left = 0;
  79.             tempSpriteP->destFrameRect.top = 0;
  80.             tempSpriteP->destFrameRect.right = 0;
  81.             tempSpriteP->destFrameRect.bottom = 0;
  82.             tempSpriteP->oldFrameRect.left = 0;
  83.             tempSpriteP->oldFrameRect.top = 0;
  84.             tempSpriteP->oldFrameRect.right = 0;
  85.             tempSpriteP->oldFrameRect.bottom = 0;
  86.             tempSpriteP->deltaFrameRect.left = 0;
  87.             tempSpriteP->deltaFrameRect.top = 0;
  88.             tempSpriteP->deltaFrameRect.right = 0;
  89.             tempSpriteP->deltaFrameRect.bottom = 0;
  90.             tempSpriteP->frameDrawProc = SWStdSpriteDrawProc;
  91.             
  92.                 // initialize drawing fields for scrolling routines
  93.             tempSpriteP->destOffscreenRect.left = 0;
  94.             tempSpriteP->destOffscreenRect.top = 0;
  95.             tempSpriteP->destOffscreenRect.right = 0;
  96.             tempSpriteP->destOffscreenRect.bottom = 0;
  97.             tempSpriteP->oldOffscreenRect.left = 0;
  98.             tempSpriteP->oldOffscreenRect.top = 0;
  99.             tempSpriteP->oldOffscreenRect.right = 0;
  100.             tempSpriteP->oldOffscreenRect.bottom = 0;
  101.             tempSpriteP->oldRectIsVisible = false;
  102.  
  103.                 // initialize frame fields
  104.             tempSpriteP->curFrameP = NULL;
  105.             tempSpriteP->numFrames = 0;
  106.             tempSpriteP->maxFrames = maxFrames;
  107.             tempSpriteP->frameTimeInterval = -1;
  108.             tempSpriteP->timeOfLastFrameChange = 0;
  109.             tempSpriteP->frameAdvance = 1;
  110.             tempSpriteP->curFrameIndex = 0;
  111.             tempSpriteP->firstFrameIndex = 0;
  112.             tempSpriteP->lastFrameIndex = 0;
  113.             tempSpriteP->frameChangeProc = NULL;
  114.  
  115.                 // initialize movement fields
  116.             tempSpriteP->moveTimeInterval = 0;
  117.             tempSpriteP->timeOfLastMove = 0;
  118.             tempSpriteP->horizMoveDelta = 0;
  119.             tempSpriteP->vertMoveDelta = 0;
  120.             tempSpriteP->moveBoundsRect.left = 0;
  121.             tempSpriteP->moveBoundsRect.top = 0;
  122.             tempSpriteP->moveBoundsRect.right = 0;
  123.             tempSpriteP->moveBoundsRect.bottom = 0;
  124.             tempSpriteP->spriteMoveProc = NULL;
  125.  
  126.             tempSpriteP->spriteCollideProc = NULL;
  127.             
  128.             tempSpriteP->sharedPictGWorld = NULL;
  129.             tempSpriteP->sharedMaskGWorld = NULL;
  130.             tempSpriteP->spriteRemoval = kSWDontRemoveSprite;
  131.             tempSpriteP->userData = 0;
  132.  
  133.                 // the sprite has been successfully created
  134.             *newSpriteP = tempSpriteP;
  135.         }
  136.         else
  137.         {
  138.             err = MemError();
  139.  
  140.             DisposePtr((Ptr)tempSpriteP);
  141.         }
  142.     }
  143.     else
  144.     {
  145.         err = MemError();
  146.     }
  147.  
  148.     SWSetStickyIfError( err );
  149.     return err;
  150. }
  151.  
  152.  
  153. ///--------------------------------------------------------------------------------------
  154. //    SWCreateSpriteFromCicnResource
  155. ///--------------------------------------------------------------------------------------
  156.  
  157. SW_FUNC OSErr SWCreateSpriteFromCicnResource(
  158.     SpriteWorldPtr destSpriteWorld,
  159.     SpritePtr* newSpriteP,
  160.     void* spriteStorageP,
  161.     short cIconID,
  162.     short maxFrames,
  163.     MaskType maskType)
  164. {
  165.     OSErr             err;
  166.     SpritePtr         tempSpriteP;
  167.     FramePtr         newFrameP;
  168.     short             frame;
  169.  
  170.     SWAssert( destSpriteWorld != NULL && newSpriteP != NULL && maxFrames > 0 );
  171.  
  172.     *newSpriteP = NULL;
  173.  
  174.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  175.     
  176.     if (err == noErr)
  177.     {
  178.         for (frame = 0; frame < maxFrames; frame++)
  179.         {
  180.             err = SWCreateFrameFromCicnResource(destSpriteWorld, &newFrameP, 
  181.                     cIconID + frame, maskType);
  182.  
  183.             if (err == noErr)
  184.             {
  185.                 err = SWAddFrame(tempSpriteP, newFrameP);
  186.             }
  187.  
  188.             if (err != noErr)
  189.             {
  190.                 SWDisposeFrame(newFrameP);
  191.                 SWDisposeSprite(tempSpriteP);
  192.                 break;
  193.             }
  194.         }
  195.  
  196.         if (err == noErr)
  197.         {
  198.             SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  199.             *newSpriteP = tempSpriteP;
  200.         }
  201.     }
  202.  
  203.     SWSetStickyIfError( err );
  204.     return err;
  205. }
  206.  
  207.  
  208. ///--------------------------------------------------------------------------------------
  209. //    SWCreateSpriteFromPictResource
  210. ///--------------------------------------------------------------------------------------
  211.  
  212. SW_FUNC OSErr SWCreateSpriteFromPictResource(
  213.     SpriteWorldPtr destSpriteWorld,
  214.     SpritePtr* newSpriteP,
  215.     void* spriteStorageP,
  216.     short pictResID,
  217.     short maskResID,
  218.     short maxFrames,
  219.     MaskType maskType)
  220. {
  221.     OSErr             err;
  222.     SpritePtr         tempSpriteP;
  223.     FramePtr         newFrameP;
  224.     short             frame;
  225.     
  226.     SWAssert( destSpriteWorld != NULL && newSpriteP != NULL && maxFrames > 0 );
  227.     
  228.     *newSpriteP = NULL;
  229.  
  230.  
  231.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  232.  
  233.     if (err == noErr)
  234.     {
  235.         for (frame = 0; frame < maxFrames; frame++)
  236.         {
  237.             err = SWCreateFrameFromPictResource(destSpriteWorld, &newFrameP, 
  238.                     pictResID + frame, maskResID + frame, maskType);
  239.  
  240.             if (err == noErr)
  241.             {
  242.                 err = SWAddFrame(tempSpriteP, newFrameP);
  243.             }
  244.  
  245.             if (err != noErr)
  246.             {
  247.                 SWDisposeFrame(newFrameP);
  248.                 SWDisposeSprite(tempSpriteP);
  249.                 break;
  250.             }
  251.         }
  252.  
  253.         if (err == noErr)
  254.         {
  255.             SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  256.  
  257.             *newSpriteP = tempSpriteP;
  258.         }
  259.     }
  260.     
  261.     SWSetStickyIfError( err );
  262.     return err;
  263. }
  264.  
  265. static void CalcMaxWidthHeight( RectArrayPtr newRectArrayP, short *maxWidthP, short *maxHeightP )
  266. {
  267.     short frame;
  268.     Rect *rectP;
  269.     short maxWidth, maxHeight;
  270.     
  271.     maxWidth = 0;
  272.     maxHeight = 0;
  273.     
  274.     rectP = &newRectArrayP->frameRects[0];
  275.     for( frame = 0; frame < newRectArrayP->numFrames; frame++ ) {
  276.         if ( rectP->right - rectP->left > maxWidth ) {
  277.             maxWidth = rectP->right - rectP->left;
  278.         }
  279.         if ( rectP->bottom - rectP->top > maxHeight ) {
  280.             maxHeight = rectP->bottom - rectP->top;
  281.         }
  282.         rectP++;
  283.     }
  284.  
  285.     *maxWidthP = maxWidth;
  286.     *maxHeightP =maxHeight;
  287. }
  288.  
  289. ///--------------------------------------------------------------------------------------
  290. //    SWCreateSpriteFromSinglePict
  291. ///--------------------------------------------------------------------------------------
  292.  
  293. SW_FUNC OSErr SWCreateSpriteFromSinglePict(
  294.     SpriteWorldPtr destSpriteWorld,
  295.     SpritePtr* newSpriteP,
  296.     void* spriteStorageP,
  297.     short pictResID,
  298.     short maskResID,
  299.     short frameDimension,
  300.     MaskType maskType)
  301. {
  302.     OSErr             err = noErr;
  303.     Handle            rectArrayHndl;
  304.     RectArrayPtr    newRectArrayP;
  305.     PicHandle        tempPic;
  306.     GWorldPtr        tempPictGWorldP;
  307.     GWorldPtr        tempMaskGWorldP;
  308.     GWorldPtr        tempTempMaskGWorldP;
  309.     Rect            frameRect;
  310.     Boolean            verticalStrip;
  311.     SpritePtr         tempSpriteP;
  312.     FramePtr         newFrameP;
  313.     short             maxFrames;
  314.     short             frame;
  315.     short            maxWidth, maxHeight;
  316.     
  317.     SWAssert( destSpriteWorld != NULL && newSpriteP != NULL && frameDimension >= 0 );
  318.  
  319.     tempPictGWorldP = NULL;
  320.     tempMaskGWorldP = NULL;
  321.     *newSpriteP = NULL;
  322.     rectArrayHndl = NULL;
  323.     
  324.     if ( frameDimension == 0 )
  325.     {
  326.         rectArrayHndl = Get1Resource( 'nrct', pictResID );
  327.     
  328.         if ( rectArrayHndl == NULL )
  329.         {
  330.             err = MemError();
  331.             if ( err == noErr )
  332.                 err = resNotFound;
  333.         }
  334.         else
  335.         {
  336.             HLock( rectArrayHndl );
  337.             newRectArrayP = (RectArrayPtr)*rectArrayHndl;
  338.             maxFrames = newRectArrayP->numFrames;
  339.             CalcMaxWidthHeight( newRectArrayP, &maxWidth, &maxHeight );
  340.         }
  341.     }
  342.     else
  343.     {
  344.         tempPic = GetPicture( pictResID );
  345.         if ( tempPic == nil )
  346.         {
  347.             err = MemError();
  348.             if ( err == noErr )
  349.                 err = resNotFound;
  350.         }
  351.         else
  352.         {
  353.             frameRect = (**(tempPic)).picFrame;
  354.             OffsetRect( &frameRect, -frameRect.left, -frameRect.top );
  355.             ReleaseResource( (Handle)tempPic );
  356.             if ( frameRect.right-frameRect.left < frameRect.bottom-frameRect.top )
  357.             {
  358.                 verticalStrip = true;
  359.                 maxFrames = frameRect.bottom/frameDimension;
  360.                 frameRect.bottom = -1;
  361.                 maxWidth = frameRect.right-frameRect.left;
  362.                 maxHeight = frameDimension;
  363.             }
  364.             else
  365.             {
  366.                 verticalStrip = false;
  367.                 maxFrames = frameRect.right/frameDimension;
  368.                 frameRect.right = -1;
  369.                 maxWidth = frameDimension;
  370.                 maxHeight = frameRect.bottom-frameRect.top;
  371.             }
  372.         }
  373.     }
  374.     
  375.     if ( err == noErr )
  376.     {    
  377.         err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  378.     
  379.         if (err == noErr)
  380.         {
  381.             err = SWCreateGWorldFromPictResource( destSpriteWorld, &tempPictGWorldP, pictResID );
  382.             if ( err == noErr && maskType != kNoMask )
  383.                 err = SWCreateGWorldFromPictResource( 
  384.                     destSpriteWorld, &tempMaskGWorldP, maskResID );
  385.             if (err == noErr)
  386.             {
  387.                 if ( pictResID == maskResID && tempMaskGWorldP != NULL )
  388.                 {
  389.                     err = SWBlackenGWorld( tempMaskGWorldP );
  390.                 }
  391.             }
  392.             
  393.             if (err == noErr)
  394.             {
  395.                 err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP, maxWidth, maxHeight );
  396.             }
  397.             
  398.             if (err == noErr)
  399.             {
  400.                 for (frame = 0; frame < maxFrames; frame++)
  401.                 {
  402.                     if ( frameDimension == 0 )
  403.                     {
  404.                         frameRect = newRectArrayP->frameRects[frame];
  405.                     }
  406.                     else
  407.                     {
  408.                         if ( verticalStrip )
  409.                         {
  410.                             frameRect.top = frameRect.bottom + 1;
  411.                             frameRect.bottom = frameRect.top + frameDimension;
  412.                         }
  413.                         else
  414.                         {
  415.                             frameRect.left = frameRect.right + 1;
  416.                             frameRect.right = frameRect.left + frameDimension;
  417.                         }
  418.                     }
  419.                     
  420.                     err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
  421.                             tempMaskGWorldP, tempTempMaskGWorldP, &frameRect, maskType);
  422.         
  423.                     if (err == noErr)
  424.                     {
  425.                         err = SWAddFrame(tempSpriteP, newFrameP);
  426.                     }
  427.         
  428.                     if (err != noErr)
  429.                     {
  430.                         SWDisposeFrame(newFrameP);
  431.                         SWDisposeSprite(tempSpriteP);
  432.                         break;
  433.                     }
  434.                 }
  435.                 SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
  436.             }
  437.                 
  438.             if (err == noErr)
  439.             {
  440.                     // make a pixel mask
  441.                 if ((maskType & kPixelMask) != 0)
  442.                 {
  443.                     if (destSpriteWorld->pixelDepth <= 8)
  444.                     {
  445.                         (void)LockPixels( GetGWorldPixMap(tempMaskGWorldP) );
  446.                         SetGWorld(tempMaskGWorldP, nil);
  447.                         InvertRect(&tempMaskGWorldP->portRect);
  448.                         UnlockPixels( GetGWorldPixMap(tempMaskGWorldP) );
  449.                     }
  450.                 }
  451.                     // If no pixel Mask wanted, dispose
  452.                     // of the GWorld we used to make region
  453.                 else
  454.                 {
  455.                     DisposeGWorld( tempMaskGWorldP );
  456.                     tempMaskGWorldP = NULL;
  457.                 }
  458.                 SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  459.                 tempSpriteP->sharedPictGWorld = tempPictGWorldP;
  460.                 tempSpriteP->sharedMaskGWorld = tempMaskGWorldP;
  461.                 
  462.                 *newSpriteP = tempSpriteP;
  463.             }
  464.         }
  465.     }
  466.     
  467.     if ( rectArrayHndl != NULL )
  468.     {
  469.         HUnlock( rectArrayHndl );
  470.         ReleaseResource( rectArrayHndl );
  471.     }
  472.     
  473.     SWSetStickyIfError( err );
  474.     return err;
  475. }
  476.  
  477.  
  478. ///--------------------------------------------------------------------------------------
  479. //  SWCreateSpriteFromSinglePictXY
  480. //
  481. //  height/width code contributed by Mohsan Khan, 96-06-13
  482. ///--------------------------------------------------------------------------------------
  483.  
  484. SW_FUNC OSErr SWCreateSpriteFromSinglePictXY(
  485.         SpriteWorldPtr destSpriteWorld,
  486.         SpritePtr* newSpriteP,
  487.         void* spriteStorageP,
  488.         short pictResID,
  489.         short maskResID,
  490.         short frameWidth,
  491.         short frameHeight,
  492.         short borderWidth,
  493.         short maxFrames,
  494.         MaskType maskType)
  495. {
  496.     OSErr            err = noErr;
  497.     PicHandle        tempPic;
  498.     GWorldPtr        tempPictGWorldP, tempMaskGWorldP, tempTempMaskGWorldP;
  499.     Rect            frameRect;
  500.     SpritePtr        tempSpriteP;
  501.     FramePtr        newFrameP;
  502.     short            frame;
  503.  
  504.     SWAssert( destSpriteWorld != NULL && newSpriteP != NULL && maxFrames > 0 && 
  505.                         frameWidth > 0 && frameHeight > 0 && borderWidth >= 0 );
  506.  
  507.  
  508.     tempPictGWorldP = NULL;
  509.     tempMaskGWorldP = NULL;
  510.     *newSpriteP = NULL;
  511.  
  512.  
  513.     tempPic = GetPicture( pictResID );
  514.     if ( tempPic == nil )
  515.     {
  516.         err = MemError();
  517.         if ( err == noErr )
  518.             err = resNotFound;
  519.     }
  520.     else
  521.     {
  522.         ReleaseResource( (Handle)tempPic );
  523.     }
  524.  
  525.     if ( err == noErr )
  526.     {    
  527.         {
  528.             err = SWCreateGWorldFromPictResource( destSpriteWorld, &tempPictGWorldP, pictResID );
  529.             if ( err == noErr && maskType != kNoMask )
  530.                 err = SWCreateGWorldFromPictResource(
  531.                     destSpriteWorld, &tempMaskGWorldP, maskResID );
  532.             if (err == noErr)
  533.             {
  534.                 if ( pictResID == maskResID && tempMaskGWorldP != NULL )
  535.                 {
  536.                     err = SWBlackenGWorld( tempMaskGWorldP );
  537.                 }
  538.             }
  539.             if ( maxFrames == 0 )
  540.             {
  541.                 maxFrames = (tempPictGWorldP->portRect.right/frameWidth) *
  542.                             (tempPictGWorldP->portRect.bottom/frameHeight);
  543.             }
  544.             if (err == noErr)
  545.             {
  546.                 err = SWCreateSprite(&tempSpriteP, spriteStorageP, maxFrames);
  547.             }
  548.             if (err == noErr)
  549.             {
  550.                 err = SWCreateFrameFromGWorldAndRectStart( &tempTempMaskGWorldP, frameWidth, frameHeight );
  551.             }
  552.             if (err == noErr)
  553.             {
  554.                 frameRect.left = 0;
  555.                 frameRect.top = 0;
  556.                 frameRect.right = frameWidth;
  557.                 frameRect.bottom = frameHeight;
  558.                 
  559.                 for (frame = 0; frame < maxFrames; frame++)
  560.                 {
  561.                     err = SWCreateFrameFromGWorldAndRectPartial( &newFrameP, tempPictGWorldP,
  562.                             tempMaskGWorldP, tempTempMaskGWorldP, &frameRect, maskType);
  563.  
  564.                     if (err == noErr)
  565.                     {
  566.                         err = SWAddFrame(tempSpriteP, newFrameP);
  567.                         if ( frame < maxFrames-1 )
  568.                         {
  569.                             frameRect.left += frameWidth + borderWidth;
  570.                             frameRect.right = frameRect.left + frameWidth;
  571.                             if ( frameRect.right > tempPictGWorldP->portRect.right )
  572.                             {
  573.                                 frameRect.left = 0;
  574.                                 frameRect.right = frameWidth;
  575.                                 frameRect.top += frameHeight + 1;
  576.                                 frameRect.bottom = frameRect.top + frameHeight;
  577.                                 
  578.                                 if ( frameRect.bottom > tempPictGWorldP->portRect.bottom )
  579.                                 {
  580.                                     err = kOutOfRangeErr;
  581.                                 }
  582.                             }
  583.                         }
  584.                     }
  585.                     if ( err != noErr )
  586.                     {
  587.                         SWDisposeFrame(newFrameP);
  588.                         SWDisposeSprite(tempSpriteP);
  589.                         break;
  590.                     }
  591.                 } // end for
  592.                 SWCreateFrameFromGWorldAndRectFinish( tempTempMaskGWorldP );
  593.             }
  594.  
  595.             if (err == noErr)
  596.             {
  597.                     // make a pixel mask
  598.                 if ((maskType & kPixelMask) != 0)
  599.                 {
  600.                     if (destSpriteWorld->pixelDepth <= 8)
  601.                     {
  602.                         (void)LockPixels( GetGWorldPixMap(tempMaskGWorldP) );
  603.                         SetGWorld(tempMaskGWorldP, nil);
  604.                         InvertRect(&tempMaskGWorldP->portRect);
  605.                         UnlockPixels( GetGWorldPixMap(tempMaskGWorldP) );
  606.                     }
  607.                 }
  608.                     // If no pixel Mask wanted, dispose
  609.                     // of the GWorld we used to make region
  610.                 else
  611.                 {
  612.                     DisposeGWorld( tempMaskGWorldP );
  613.                     tempMaskGWorldP == NULL;
  614.                 }
  615.                 SWSetSpriteFrameRange(tempSpriteP, 0, maxFrames - 1);
  616.                 tempSpriteP->sharedPictGWorld = tempPictGWorldP;
  617.                 tempSpriteP->sharedMaskGWorld = tempMaskGWorldP;
  618.  
  619.                 *newSpriteP = tempSpriteP;
  620.             }
  621.         }
  622.     }
  623.     SWSetStickyIfError( err );
  624.     return err;
  625. }
  626.  
  627.  
  628. ///--------------------------------------------------------------------------------------
  629. //    SWUpdateSpriteFromPictResource
  630. ///--------------------------------------------------------------------------------------
  631.  
  632. SW_FUNC OSErr SWUpdateSpriteFromPictResource(
  633.     SpritePtr theSpriteP,
  634.     short pictResID)
  635. {
  636.     OSErr             err = noErr;
  637.     GDHandle        currentGDH;
  638.     GWorldPtr        currentGWorld;
  639.     GWorldPtr        frameGWorld;
  640.     PicHandle        pictH;
  641.     Rect            frameRect;
  642.     short            frame;
  643.     
  644.     SWAssert( theSpriteP != NULL );
  645.     
  646.     GetGWorld( ¤tGWorld, ¤tGDH );
  647.     
  648.     SWLockSprite( theSpriteP );
  649.     
  650.     if ( theSpriteP->sharedPictGWorld != NULL )
  651.     {
  652.         SetGWorld( theSpriteP->sharedPictGWorld, NULL );
  653.         pictH = GetPicture( pictResID );
  654.         if ( pictH != NULL )
  655.         {
  656.             frameRect = theSpriteP->sharedPictGWorld->portRect;
  657.             EraseRect( &frameRect );
  658.             DrawPicture( pictH, &frameRect );
  659.             ReleaseResource( (Handle)pictH );
  660.         }
  661.         else
  662.         {
  663.             err = MemError();
  664.             if ( err == noErr )
  665.                 err = resNotFound;
  666.         }
  667.     }
  668.     else
  669.     {
  670.         for (frame = 0; frame < theSpriteP->maxFrames; frame++)
  671.         {
  672.             frameGWorld = theSpriteP->frameArray[frame]->framePort;
  673.             if ( frameGWorld != NULL )
  674.             {
  675.                 SetGWorld( frameGWorld, nil );
  676.                 pictH = GetPicture( pictResID + frame );
  677.                 if ( pictH != NULL )
  678.                 {
  679.                     frameRect = frameGWorld->portRect;
  680.                     EraseRect( &frameRect );
  681.                     DrawPicture( pictH, &frameRect );
  682.                     ReleaseResource( (Handle)pictH );
  683.                 }
  684.                 else
  685.                 {
  686.                     err = MemError();
  687.                     if ( err == noErr )
  688.                         err = resNotFound;
  689.                     break;
  690.                 }
  691.             }
  692.         }
  693.     }
  694.     SetGWorld( currentGWorld, currentGDH );
  695.     
  696.     SWSetStickyIfError( err );
  697.     return err;
  698. }
  699.  
  700.  
  701. ///--------------------------------------------------------------------------------------
  702. //    SWCloneSprite
  703. ///--------------------------------------------------------------------------------------
  704. SW_FUNC OSErr SWCloneSprite(
  705.     SpritePtr cloneSpriteP,
  706.     SpritePtr* newSpriteP,
  707.     void* spriteStorageP)
  708. {
  709.     OSErr             err;
  710.     SpritePtr         tempSpriteP;
  711.     short             frame;
  712.     FramePtr*         tempFrameArray;
  713.  
  714.     SWAssert( cloneSpriteP != NULL && newSpriteP != NULL );
  715.     
  716.     err = SWCreateSprite(&tempSpriteP, spriteStorageP, cloneSpriteP->maxFrames);
  717.     
  718.     if (err == noErr)
  719.     {
  720.             // save off the field unique to a particular sprite
  721.         tempFrameArray = tempSpriteP->frameArray;
  722.  
  723.             // copy the clone sprite into the temp sprite
  724.         *tempSpriteP = *cloneSpriteP;
  725.  
  726.             // restore the unique field
  727.         tempSpriteP->frameArray = tempFrameArray;
  728.  
  729.             // clear the next and prev fields, just in case
  730.         tempSpriteP->nextSpriteP = NULL;
  731.         tempSpriteP->prevSpriteP = NULL;
  732.  
  733.             // copy the frame array
  734.         for (frame = 0; frame < tempSpriteP->maxFrames; frame++)
  735.         {
  736.             tempSpriteP->frameArray[frame] = cloneSpriteP->frameArray[frame];
  737.             tempSpriteP->frameArray[frame]->useCount++;
  738.         }
  739.  
  740.         *newSpriteP = tempSpriteP;
  741.     }
  742.  
  743.     SWSetStickyIfError( err );
  744.     return err;
  745. }
  746.  
  747.  
  748. ///--------------------------------------------------------------------------------------
  749. //    SWRemoveSpriteFromAnimation
  750. ///--------------------------------------------------------------------------------------
  751.  
  752. SW_FUNC void  SWRemoveSpriteFromAnimation(
  753.     SpriteWorldPtr    spriteWorldP,
  754.     SpritePtr        spriteP,
  755.     Boolean            disposeOfSprite)
  756. {
  757.     
  758.     SWAssert( spriteWorldP != NULL && spriteP != NULL );
  759.     
  760.     spriteWorldP->anySpritesNeedRemoving = true;
  761.     SWSetSpriteVisible( spriteP, false );
  762.     
  763.     if ( disposeOfSprite )
  764.     {
  765.         spriteP->spriteRemoval = kSWRemoveAndDisposeSprite;
  766.     }
  767.     else
  768.     {
  769.         spriteP->spriteRemoval = kSWRemoveSprite;
  770.     }
  771. }
  772.     
  773.  
  774. ///--------------------------------------------------------------------------------------
  775. //    SWDisposeSprite
  776. ///--------------------------------------------------------------------------------------
  777.  
  778. SW_FUNC void SWDisposeSprite(
  779.     SpritePtr deadSpriteP)
  780. {
  781.     SWAssert( deadSpriteP != NULL );
  782.  
  783.     SWCloseSprite(deadSpriteP);
  784.  
  785.     DisposePtr((Ptr)deadSpriteP);
  786. }
  787.  
  788.  
  789. ///--------------------------------------------------------------------------------------
  790. //    SWCloseSprite
  791. ///--------------------------------------------------------------------------------------
  792.  
  793. SW_FUNC void SWCloseSprite(
  794.     SpritePtr deadSpriteP)
  795. {
  796.     short             frame;
  797.     Boolean            framesDisposed;
  798.     
  799.     SWAssert( deadSpriteP != NULL );
  800.  
  801.     if (deadSpriteP != NULL)
  802.     {
  803.         for (frame = 0; frame < deadSpriteP->numFrames; frame++)
  804.         {
  805.             framesDisposed = SWDisposeFrame(deadSpriteP->frameArray[frame]);
  806.         }
  807.         if ( framesDisposed )
  808.         {
  809.             if ( deadSpriteP->sharedPictGWorld != NULL )
  810.             {
  811.                 DisposeGWorld(deadSpriteP->sharedPictGWorld );
  812.                 deadSpriteP->sharedPictGWorld = NULL;
  813.             }
  814.         
  815.             if ( deadSpriteP->sharedMaskGWorld != NULL )
  816.             {
  817.                 DisposeGWorld(deadSpriteP->sharedMaskGWorld );
  818.                 deadSpriteP->sharedMaskGWorld = NULL;
  819.             }
  820.         }
  821.         SWAssert( deadSpriteP->frameArray != NULL );
  822.         DisposePtr((Ptr)deadSpriteP->frameArray);
  823.     }
  824. }
  825.  
  826.  
  827. ///--------------------------------------------------------------------------------------
  828. //    SWLockSprite
  829. ///--------------------------------------------------------------------------------------
  830.  
  831. SW_FUNC void SWLockSprite(
  832.     SpritePtr srcSpriteP)
  833. {
  834.     register long numFrames;
  835.  
  836.     SWAssert( srcSpriteP != NULL && srcSpriteP->frameArray != NULL );
  837.  
  838.     numFrames = srcSpriteP->numFrames;
  839.     
  840.     while (numFrames--)
  841.     {
  842.         if ( !srcSpriteP->frameArray[numFrames]->isFrameLocked ) {
  843.             SWLockFrame(srcSpriteP->frameArray[numFrames]);
  844.         }
  845.     }
  846. }
  847.  
  848.  
  849. ///--------------------------------------------------------------------------------------
  850. //    SWUnlockSprite
  851. ///--------------------------------------------------------------------------------------
  852.  
  853. SW_FUNC void SWUnlockSprite(
  854.     SpritePtr srcSpriteP)
  855. {
  856.     register long numFrames;
  857.  
  858.     SWAssert( srcSpriteP != NULL && srcSpriteP->frameArray != NULL );
  859.     
  860.     if ( srcSpriteP != NULL )
  861.     {
  862.         numFrames = srcSpriteP->numFrames;
  863.     
  864.         while (numFrames--)
  865.         {
  866.             if ( srcSpriteP->frameArray[numFrames]->isFrameLocked ) {
  867.                 SWUnlockFrame(srcSpriteP->frameArray[numFrames]);
  868.             }
  869.         }
  870.     }
  871. }
  872.  
  873.  
  874. ///--------------------------------------------------------------------------------------
  875. //    SWSetSpriteDrawProc
  876. ///--------------------------------------------------------------------------------------
  877.  
  878. SW_FUNC OSErr SWSetSpriteDrawProc(
  879.     SpritePtr srcSpriteP,
  880.     DrawProcPtr drawProc)
  881. {
  882.     OSErr        err = noErr;
  883.     FramePtr    headFrameP = NULL;
  884.     short        framePixelDepth = 0;
  885.     
  886.     SWAssert( srcSpriteP != NULL && drawProc != NULL && srcSpriteP->frameArray != NULL  );
  887.  
  888. #if SW_PPC
  889.     if ( drawProc == CompiledSprite8BitDrawProc )
  890.         drawProc = BlitPixie8BitMaskDrawProc;
  891. #endif
  892.     
  893.     headFrameP = srcSpriteP->frameArray[0];
  894.     if ( headFrameP != NULL )
  895.     {
  896.         if ( headFrameP->framePort != NULL )
  897.         {
  898.             framePixelDepth = (*headFrameP->framePort->portPixMap)->pixelSize;
  899.         }
  900.     }
  901.     
  902.     if (framePixelDepth != 8)
  903.     {
  904.         if ( (drawProc == BlitPixie8BitRectDrawProc) ||
  905.              (drawProc == BlitPixie8BitMaskDrawProc) ||
  906.              (drawProc == BP8BitInterlacedRectDrawProc) ||
  907.              (drawProc == BP8BitInterlacedMaskDrawProc) ||
  908.              (drawProc == BlitPixie8BitPartialMaskDrawProc) ||
  909.              (drawProc == BP8BitInterlacedPartialMaskDrawProc) ||
  910.              (drawProc == CompiledSprite8BitDrawProc) )
  911.         {
  912.             err = kWrongDepthErr;
  913.         }
  914.     }
  915.  
  916.     if (headFrameP->maskPort == NULL)
  917.     {
  918.         if ( (drawProc == BlitPixie8BitMaskDrawProc) ||
  919.              (drawProc == BP8BitInterlacedMaskDrawProc) ||
  920.              (drawProc == BlitPixie8BitPartialMaskDrawProc) ||
  921.              (drawProc == BP8BitInterlacedPartialMaskDrawProc) ||
  922.              (drawProc == CompiledSprite8BitDrawProc) )
  923.         {
  924.             err = kWrongMaskErr;
  925.         }
  926.     }
  927.     else if (drawProc == CompiledSprite8BitDrawProc && headFrameP->pixCodeH == NULL)
  928.     {
  929.         err = kWrongMaskErr;
  930.     }
  931.         
  932.     if ( err == noErr )
  933.         srcSpriteP->frameDrawProc = drawProc;
  934.         
  935.     SWSetStickyIfError( err );
  936.     return err;
  937. }
  938.  
  939.  
  940. ///--------------------------------------------------------------------------------------
  941. //    SWStdSpriteDrawProc - for drawing sprites
  942. ///--------------------------------------------------------------------------------------
  943.  
  944. SW_FUNC void SWStdSpriteDrawProc(
  945.     FramePtr srcFrameP,
  946.     FramePtr dstFrameP,
  947.     Rect* srcRect,
  948.     Rect* dstRect)
  949. {
  950.  
  951.     SWAssert( srcFrameP != NULL && dstFrameP != NULL && srcRect != NULL && dstRect != NULL &&
  952.                         srcFrameP->framePix != NULL && dstFrameP->framePix != NULL );
  953.  
  954.     if (srcFrameP->maskRgn != NULL)
  955.     {
  956.         Rect rgnRect = (**srcFrameP->maskRgn).rgnBBox;
  957.  
  958.             // move the mask region to the new sprite location
  959.         OffsetRgn(srcFrameP->maskRgn,
  960.             (dstRect->left - (srcRect->left - srcFrameP->frameRect.left) - rgnRect.left) 
  961.             + srcFrameP->offsetPoint.h,
  962.             (dstRect->top - (srcRect->top - srcFrameP->frameRect.top) - rgnRect.top)
  963.             + srcFrameP->offsetPoint.v);
  964.     }
  965.     
  966.         // CopyBits with a mask region is generally faster than CopyMask
  967.     CopyBits((BitMapPtr)srcFrameP->framePix, (BitMapPtr)dstFrameP->framePix,
  968.                 srcRect, dstRect, srcCopy, srcFrameP->maskRgn);
  969. }
  970.  
  971.  
  972. ///--------------------------------------------------------------------------------------
  973. //    SWAddFrame 
  974. ///--------------------------------------------------------------------------------------
  975.  
  976. SW_FUNC OSErr SWAddFrame(
  977.     SpritePtr srcSpriteP,
  978.     FramePtr newFrameP)
  979. {
  980.     OSErr err = noErr;
  981.     
  982.     SWAssert( srcSpriteP != NULL && newFrameP != NULL && srcSpriteP->numFrames < srcSpriteP->maxFrames );
  983.  
  984.         // don’t exceed maximum number of frames
  985.     if (srcSpriteP->numFrames < srcSpriteP->maxFrames)
  986.     {
  987.         srcSpriteP->frameArray[srcSpriteP->numFrames] = newFrameP;
  988.  
  989.             // increment the number of frames
  990.         srcSpriteP->numFrames++;
  991.         newFrameP->useCount++;
  992.  
  993. //        SWSetCurrentFrame(srcSpriteP, srcSpriteP->frameArray[0]); PNL use SWSetCurrentFrameIndex?
  994.         SWSetCurrentFrameIndex(srcSpriteP, 0);
  995.     }
  996.     else
  997.     {
  998.         err = kMaxFramesErr;
  999.     }
  1000.  
  1001.     SWSetStickyIfError( err );
  1002.     return err;
  1003. }
  1004.  
  1005.  
  1006. ///--------------------------------------------------------------------------------------
  1007. //    SWRemoveFrame
  1008. ///--------------------------------------------------------------------------------------
  1009.  
  1010. SW_FUNC void SWRemoveFrame(
  1011.     SpritePtr srcSpriteP,
  1012.     FramePtr oldFrameP)
  1013. {
  1014.     register long numFrames;
  1015.     register FramePtr *frameArray;
  1016.  
  1017.     SWAssert( srcSpriteP != NULL && oldFrameP != NULL );
  1018.  
  1019.     numFrames = srcSpriteP->numFrames;
  1020.     frameArray = srcSpriteP->frameArray;
  1021.  
  1022.     oldFrameP->useCount--;
  1023.  
  1024.         // find the frame to be removed
  1025.     while (numFrames--)
  1026.     {
  1027.         if (frameArray[numFrames] == oldFrameP)
  1028.         {
  1029.                 // move the rest of the frames down
  1030.             while (numFrames < (srcSpriteP->numFrames - 1L))
  1031.             {
  1032.                 frameArray[numFrames] = frameArray[numFrames + 1L];
  1033.  
  1034.                 numFrames++;
  1035.             }
  1036.  
  1037.             break;
  1038.         }
  1039.     }
  1040. }
  1041.  
  1042.  
  1043. ///--------------------------------------------------------------------------------------
  1044. //    SWSetCurrentFrame
  1045. ///--------------------------------------------------------------------------------------
  1046.  
  1047. SW_FUNC void SWSetCurrentFrame(
  1048.     SpritePtr srcSpriteP,
  1049.     FramePtr newFrameP)
  1050. {
  1051.     Rect lastRect;
  1052.     short horizOffset, vertOffset;
  1053.     short frameIndex = 0;
  1054.  
  1055.     SWAssert( srcSpriteP != NULL && newFrameP != NULL );
  1056.  
  1057.     if (srcSpriteP->curFrameP != newFrameP)
  1058.     {
  1059.         srcSpriteP->curFrameP = newFrameP;
  1060.  
  1061.         lastRect = srcSpriteP->destFrameRect;
  1062.  
  1063.         srcSpriteP->destFrameRect = newFrameP->frameRect;
  1064.  
  1065.         horizOffset = (lastRect.left - srcSpriteP->destFrameRect.left);
  1066.         vertOffset = (lastRect.top - srcSpriteP->destFrameRect.top);
  1067.  
  1068.         srcSpriteP->destFrameRect.left += horizOffset;
  1069.         srcSpriteP->destFrameRect.right += horizOffset;
  1070.         srcSpriteP->destFrameRect.top += vertOffset;
  1071.         srcSpriteP->destFrameRect.bottom += vertOffset;
  1072.  
  1073.             // this really lame search is performed so we set the
  1074.             // frame index of the sprite properly, which could
  1075.             // prevent strange behavior later on. The lesson to be learned
  1076.             // here is to call SWSetCurrentFrameIndex instead.
  1077.         for (frameIndex = 0; frameIndex < srcSpriteP->numFrames; frameIndex++)
  1078.         {
  1079.             if (srcSpriteP->frameArray[frameIndex] == newFrameP)
  1080.             {
  1081.                 srcSpriteP->curFrameIndex = frameIndex;
  1082.                 break;
  1083.             }
  1084.         }
  1085.  
  1086.         srcSpriteP->needsToBeDrawn = true;
  1087.     }
  1088. }
  1089.  
  1090.  
  1091. ///--------------------------------------------------------------------------------------
  1092. //    SWSetCurrentFrameIndex
  1093. ///--------------------------------------------------------------------------------------
  1094.  
  1095. SW_FUNC void SWSetCurrentFrameIndex(
  1096.     SpritePtr srcSpriteP,
  1097.     short frameIndex)
  1098. {
  1099.     register FramePtr newFrameP;
  1100.     Rect lastRect;
  1101.     short horizOffset, vertOffset;
  1102.  
  1103.     SWAssert( srcSpriteP != NULL && frameIndex >= 0 && 0 <= frameIndex && frameIndex < srcSpriteP->numFrames );
  1104.  
  1105.     if (frameIndex < srcSpriteP->numFrames)
  1106.     {
  1107.         newFrameP = srcSpriteP->frameArray[frameIndex];
  1108.  
  1109.         srcSpriteP->curFrameP = newFrameP;
  1110.  
  1111.         lastRect = srcSpriteP->destFrameRect;
  1112.  
  1113.         srcSpriteP->destFrameRect = newFrameP->frameRect;
  1114.  
  1115.         horizOffset = (lastRect.left - srcSpriteP->destFrameRect.left);
  1116.         vertOffset = (lastRect.top - srcSpriteP->destFrameRect.top);
  1117.  
  1118.         srcSpriteP->destFrameRect.left += horizOffset;
  1119.         srcSpriteP->destFrameRect.right += horizOffset;
  1120.         srcSpriteP->destFrameRect.top += vertOffset;
  1121.         srcSpriteP->destFrameRect.bottom += vertOffset;
  1122.  
  1123.         srcSpriteP->curFrameIndex = frameIndex;
  1124.  
  1125.         srcSpriteP->needsToBeDrawn = true;
  1126.     }
  1127. }
  1128.  
  1129.  
  1130. ///--------------------------------------------------------------------------------------
  1131. //    SWSetSpriteFrameAdvance
  1132. ///--------------------------------------------------------------------------------------
  1133.  
  1134. SW_FUNC void SWSetSpriteFrameAdvance(
  1135.     SpritePtr srcSpriteP,
  1136.     short frameAdvance)
  1137. {
  1138.     SWAssert( srcSpriteP != NULL );
  1139.  
  1140.     srcSpriteP->frameAdvance = frameAdvance;
  1141. }
  1142.  
  1143.  
  1144. ///--------------------------------------------------------------------------------------
  1145. //    SWSetSpriteFrameRange
  1146. ///--------------------------------------------------------------------------------------
  1147.  
  1148. SW_FUNC void SWSetSpriteFrameRange(
  1149.     SpritePtr srcSpriteP,
  1150.     short firstFrameIndex,
  1151.     short lastFrameIndex)
  1152. {
  1153.     SWAssert( srcSpriteP != NULL && 0 <= firstFrameIndex && firstFrameIndex <= lastFrameIndex && lastFrameIndex < srcSpriteP->maxFrames );
  1154.  
  1155.     if ( firstFrameIndex < 0 )
  1156.     {
  1157.         firstFrameIndex = 0;
  1158.     }
  1159.     if ( lastFrameIndex > srcSpriteP->maxFrames - 1 )
  1160.     {
  1161.         lastFrameIndex = srcSpriteP->maxFrames - 1;
  1162.     }
  1163.     srcSpriteP->firstFrameIndex = firstFrameIndex;
  1164.     srcSpriteP->lastFrameIndex = lastFrameIndex;
  1165. }
  1166.  
  1167.  
  1168. ///--------------------------------------------------------------------------------------
  1169. //    SWSetSpriteFrameTime
  1170. ///--------------------------------------------------------------------------------------
  1171.  
  1172. SW_FUNC void SWSetSpriteFrameTime(
  1173.     SpritePtr srcSpriteP,
  1174.     long timeInterval)
  1175. {
  1176.     SWAssert( srcSpriteP != NULL && timeInterval >= -1 );
  1177.  
  1178.     srcSpriteP->frameTimeInterval = timeInterval;
  1179. }
  1180.  
  1181.  
  1182. ///--------------------------------------------------------------------------------------
  1183. //    SWSetSpriteFrameProc
  1184. ///--------------------------------------------------------------------------------------
  1185.  
  1186. SW_FUNC void SWSetSpriteFrameProc(
  1187.     SpritePtr srcSpriteP,
  1188.     FrameProcPtr frameProc)
  1189. {
  1190.     SWAssert( srcSpriteP != NULL && frameProc != NULL );
  1191.     
  1192.     srcSpriteP->frameChangeProc = frameProc;
  1193. }
  1194.  
  1195.  
  1196. ///--------------------------------------------------------------------------------------
  1197. //    SWMoveSprite
  1198. ///--------------------------------------------------------------------------------------
  1199.  
  1200. SW_FUNC void SWMoveSprite(
  1201.     SpritePtr srcSpriteP,
  1202.     short horizLoc,
  1203.     short vertLoc)
  1204. {
  1205.     SWAssert( srcSpriteP != NULL );
  1206.  
  1207.     srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom -
  1208.                                                 srcSpriteP->destFrameRect.top);
  1209.     srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right -
  1210.                                                 srcSpriteP->destFrameRect.left);
  1211.     srcSpriteP->destFrameRect.top = vertLoc;
  1212.     srcSpriteP->destFrameRect.left = horizLoc;
  1213.  
  1214.     srcSpriteP->needsToBeDrawn = true;
  1215. }
  1216.  
  1217.  
  1218. ///--------------------------------------------------------------------------------------
  1219. //    SWOffsetSprite
  1220. ///--------------------------------------------------------------------------------------
  1221.  
  1222. SW_FUNC void SWOffsetSprite(
  1223.     SpritePtr srcSpriteP,
  1224.     short horizOffset,
  1225.     short vertOffset)
  1226. {
  1227.     SWAssert( srcSpriteP != NULL );
  1228.  
  1229.     if ((horizOffset != 0) || (vertOffset != 0))
  1230.     {
  1231.         srcSpriteP->destFrameRect.right += horizOffset;
  1232.         srcSpriteP->destFrameRect.bottom += vertOffset;
  1233.         srcSpriteP->destFrameRect.left += horizOffset;
  1234.         srcSpriteP->destFrameRect.top += vertOffset;
  1235.         
  1236.         srcSpriteP->needsToBeDrawn = true;
  1237.     }
  1238. }
  1239.  
  1240.  
  1241. ///--------------------------------------------------------------------------------------
  1242. //    SWSetSpriteLocation
  1243. ///--------------------------------------------------------------------------------------
  1244.  
  1245. SW_FUNC void SWSetSpriteLocation(
  1246.     SpritePtr srcSpriteP,
  1247.     short horizLoc,
  1248.     short vertLoc)
  1249. {
  1250.     SWAssert( srcSpriteP != NULL );
  1251.  
  1252.     srcSpriteP->destFrameRect.bottom = vertLoc + (srcSpriteP->destFrameRect.bottom -
  1253.                                                 srcSpriteP->destFrameRect.top);
  1254.     srcSpriteP->destFrameRect.right = horizLoc + (srcSpriteP->destFrameRect.right -
  1255.                                                 srcSpriteP->destFrameRect.left);
  1256.     srcSpriteP->destFrameRect.top = vertLoc;
  1257.     srcSpriteP->destFrameRect.left = horizLoc;
  1258.  
  1259.     srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
  1260.     srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
  1261.     srcSpriteP->needsToBeDrawn = true;
  1262. }
  1263.  
  1264.  
  1265. ///--------------------------------------------------------------------------------------
  1266. //    SWSetSpriteMoveBounds
  1267. ///--------------------------------------------------------------------------------------
  1268.  
  1269. SW_FUNC void SWSetSpriteMoveBounds(
  1270.     SpritePtr srcSpriteP,
  1271.     Rect* moveBoundsRect)
  1272. {
  1273.     SWAssert( srcSpriteP != NULL && moveBoundsRect != NULL );
  1274.     
  1275.     srcSpriteP->moveBoundsRect = *moveBoundsRect;
  1276. }
  1277.  
  1278.  
  1279. ///--------------------------------------------------------------------------------------
  1280. //    SWSetSpriteMoveDelta
  1281. ///--------------------------------------------------------------------------------------
  1282.  
  1283. SW_FUNC void SWSetSpriteMoveDelta(
  1284.     SpritePtr srcSpriteP,
  1285.     short horizDelta,
  1286.     short vertDelta)
  1287. {
  1288.     SWAssert( srcSpriteP != NULL );
  1289.  
  1290.         // set sprite’s velocity
  1291.     srcSpriteP->horizMoveDelta = horizDelta;
  1292.     srcSpriteP->vertMoveDelta = vertDelta;
  1293. }
  1294.  
  1295.  
  1296. ///--------------------------------------------------------------------------------------
  1297. //    SWSetSpriteMoveTime
  1298. ///--------------------------------------------------------------------------------------
  1299.  
  1300. SW_FUNC void SWSetSpriteMoveTime(
  1301.     SpritePtr srcSpriteP,
  1302.     long timeInterval)
  1303. {
  1304.     SWAssert( srcSpriteP != NULL && timeInterval >= -1 );
  1305.     
  1306.     srcSpriteP->moveTimeInterval = timeInterval;
  1307. }
  1308.  
  1309.  
  1310. ///--------------------------------------------------------------------------------------
  1311. //    SWSetSpriteMoveProc
  1312. ///--------------------------------------------------------------------------------------
  1313.  
  1314. SW_FUNC void SWSetSpriteMoveProc(
  1315.     SpritePtr srcSpriteP,
  1316.     MoveProcPtr moveProc)
  1317. {
  1318.     SWAssert( srcSpriteP != NULL && moveProc != NULL );
  1319.  
  1320.     srcSpriteP->spriteMoveProc = moveProc;
  1321. }
  1322.  
  1323.  
  1324. ///--------------------------------------------------------------------------------------
  1325. //    SWBounceSprite
  1326. ///--------------------------------------------------------------------------------------
  1327.  
  1328. SW_FUNC void SWBounceSprite(
  1329.     SpritePtr srcSpriteP)
  1330. {
  1331.     short    horizOffset, vertOffset;
  1332.  
  1333.     SWAssert( srcSpriteP != NULL );
  1334.  
  1335.         // Hit left side or right side
  1336.     if (srcSpriteP->destFrameRect.left < srcSpriteP->moveBoundsRect.left)
  1337.     {
  1338.         srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
  1339.         horizOffset = (srcSpriteP->moveBoundsRect.left - srcSpriteP->destFrameRect.left) * 2;
  1340.     }
  1341.     else if (srcSpriteP->destFrameRect.right > srcSpriteP->moveBoundsRect.right)
  1342.     {
  1343.         srcSpriteP->horizMoveDelta = -srcSpriteP->horizMoveDelta;
  1344.         horizOffset = (srcSpriteP->moveBoundsRect.right - srcSpriteP->destFrameRect.right) * 2;
  1345.     }
  1346.     else
  1347.         horizOffset = 0;
  1348.  
  1349.  
  1350.         // Hit top or bottom
  1351.     if (srcSpriteP->destFrameRect.top < srcSpriteP->moveBoundsRect.top)
  1352.     {
  1353.         srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
  1354.         vertOffset = (srcSpriteP->moveBoundsRect.top - srcSpriteP->destFrameRect.top) * 2;
  1355.     }
  1356.     else if (srcSpriteP->destFrameRect.bottom > srcSpriteP->moveBoundsRect.bottom)
  1357.     {
  1358.         srcSpriteP->vertMoveDelta = -srcSpriteP->vertMoveDelta;
  1359.         vertOffset = (srcSpriteP->moveBoundsRect.bottom - srcSpriteP->destFrameRect.bottom) * 2;
  1360.     }
  1361.     else
  1362.         vertOffset = 0;
  1363.     
  1364.     
  1365.         // Bounce the sprite if it had a collision with the wall
  1366.     SWOffsetSprite(srcSpriteP, horizOffset, vertOffset);
  1367. }
  1368.  
  1369.  
  1370. ///--------------------------------------------------------------------------------------
  1371. //    SWWrapSprite
  1372. ///--------------------------------------------------------------------------------------
  1373.  
  1374. SW_FUNC void SWWrapSprite(
  1375.     SpritePtr srcSpriteP)
  1376. {
  1377.     short    horizOffset, vertOffset;
  1378.     
  1379.     SWAssert( srcSpriteP != NULL );
  1380.  
  1381.         // Wrap to left or right
  1382.     if (srcSpriteP->oldFrameRect.left > srcSpriteP->moveBoundsRect.right)
  1383.     {
  1384.         horizOffset = - ((srcSpriteP->moveBoundsRect.right -
  1385.                         srcSpriteP->moveBoundsRect.left) +
  1386.                         (srcSpriteP->destFrameRect.right - 
  1387.                         srcSpriteP->destFrameRect.left) + srcSpriteP->horizMoveDelta);
  1388.     }
  1389.     else if (srcSpriteP->oldFrameRect.right < srcSpriteP->moveBoundsRect.left)
  1390.     {
  1391.         horizOffset = (srcSpriteP->moveBoundsRect.right -
  1392.                         srcSpriteP->moveBoundsRect.left) +
  1393.                         (srcSpriteP->destFrameRect.right - 
  1394.                         srcSpriteP->destFrameRect.left) - srcSpriteP->horizMoveDelta;
  1395.     }
  1396.     else
  1397.         horizOffset = 0;
  1398.     
  1399.     
  1400.         // Wrap to top or bottom
  1401.     if (srcSpriteP->oldFrameRect.top > srcSpriteP->moveBoundsRect.bottom)
  1402.     {
  1403.         vertOffset = -((srcSpriteP->moveBoundsRect.bottom -
  1404.                             srcSpriteP->moveBoundsRect.top) +
  1405.                             (srcSpriteP->destFrameRect.bottom - 
  1406.                             srcSpriteP->destFrameRect.top) + srcSpriteP->vertMoveDelta);
  1407.     }
  1408.     else if (srcSpriteP->oldFrameRect.bottom < srcSpriteP->moveBoundsRect.top)
  1409.     {
  1410.         vertOffset = (srcSpriteP->moveBoundsRect.bottom -
  1411.                             srcSpriteP->moveBoundsRect.top) +
  1412.                             (srcSpriteP->destFrameRect.bottom - 
  1413.                             srcSpriteP->destFrameRect.top) - srcSpriteP->vertMoveDelta;
  1414.     }
  1415.     else
  1416.         vertOffset = 0;
  1417.     
  1418.     
  1419.         // Wrap sprite, and set delta and old rects to current rect
  1420.     if (horizOffset || vertOffset)
  1421.     {
  1422.         SWOffsetSprite(srcSpriteP, horizOffset, vertOffset);
  1423.         srcSpriteP->deltaFrameRect = srcSpriteP->destFrameRect;
  1424.         srcSpriteP->oldFrameRect = srcSpriteP->destFrameRect;
  1425.     }
  1426. }
  1427.  
  1428.  
  1429. ///--------------------------------------------------------------------------------------
  1430. //    SWSetSpriteCollideProc
  1431. ///--------------------------------------------------------------------------------------
  1432.  
  1433. SW_FUNC void SWSetSpriteCollideProc(
  1434.     SpritePtr srcSpriteP,
  1435.     CollideProcPtr collideProc)
  1436. {
  1437.     SWAssert( srcSpriteP != NULL && collideProc != NULL );
  1438.  
  1439.     srcSpriteP->spriteCollideProc = collideProc;
  1440. }
  1441.  
  1442.  
  1443. ///--------------------------------------------------------------------------------------
  1444. // SWRegionCollision
  1445. ///--------------------------------------------------------------------------------------
  1446.  
  1447. SW_FUNC Boolean SWRegionCollision(
  1448.     SpritePtr srcSpriteP,
  1449.     SpritePtr dstSpriteP)
  1450. {
  1451.     Rect                 rgnRect;
  1452.  
  1453.     SWAssert( dstSpriteP != NULL && dstSpriteP->curFrameP != NULL && dstSpriteP->curFrameP->maskRgn != NULL );
  1454.     SWAssert( srcSpriteP != NULL && srcSpriteP->curFrameP != NULL && srcSpriteP->curFrameP->maskRgn != NULL );
  1455.  
  1456.         // copy one of the regions in case they're the same 
  1457.         // (would happen if the sprites are clones using the same frame)
  1458.     CopyRgn( dstSpriteP->curFrameP->maskRgn, gCollisionSpareRgn );
  1459.     
  1460.     rgnRect = (**srcSpriteP->curFrameP->maskRgn).rgnBBox;
  1461.  
  1462.         // move the mask region to the new sprite location
  1463.     OffsetRgn(srcSpriteP->curFrameP->maskRgn,
  1464.                 (srcSpriteP->destFrameRect.left - rgnRect.left) +
  1465.                 srcSpriteP->curFrameP->offsetPoint.h,
  1466.                 (srcSpriteP->destFrameRect.top - rgnRect.top) +
  1467.                 srcSpriteP->curFrameP->offsetPoint.v);
  1468.  
  1469.     rgnRect = (**gCollisionSpareRgn).rgnBBox;
  1470.  
  1471.         // move the mask region to the new sprite location
  1472.     OffsetRgn(gCollisionSpareRgn,
  1473.                 (dstSpriteP->destFrameRect.left - rgnRect.left) +
  1474.                 dstSpriteP->curFrameP->offsetPoint.h,
  1475.                 (dstSpriteP->destFrameRect.top - rgnRect.top) +
  1476.                 dstSpriteP->curFrameP->offsetPoint.v);
  1477.  
  1478.     SectRgn(srcSpriteP->curFrameP->maskRgn, gCollisionSpareRgn, gCollisionSectRgn);
  1479.  
  1480.     return (!EmptyRgn(gCollisionSectRgn));
  1481. }
  1482.  
  1483.  
  1484. ///--------------------------------------------------------------------------------------
  1485. // SWRadiusCollision
  1486. ///--------------------------------------------------------------------------------------
  1487.  
  1488. SW_FUNC Boolean SWRadiusCollision(
  1489.     SpritePtr srcSpriteP,
  1490.     SpritePtr dstSpriteP)
  1491. {
  1492.     Point                 centerOne, centerTwo;
  1493.     register short        radiusOne, radiusTwo;
  1494.     register short        horizDistance, vertDistance;
  1495.  
  1496.     SWAssert( srcSpriteP != NULL && dstSpriteP != NULL );
  1497.  
  1498.         // get radii - - assumes circular sprites!
  1499.     radiusOne = (srcSpriteP->destFrameRect.right-srcSpriteP->destFrameRect.left)/2;
  1500.     radiusTwo = (dstSpriteP->destFrameRect.right-dstSpriteP->destFrameRect.left)/2;
  1501.     
  1502.         // find centers
  1503.     centerOne.h = srcSpriteP->destFrameRect.left + radiusOne;
  1504.     centerOne.v = srcSpriteP->destFrameRect.top + radiusOne;
  1505.     centerTwo.h = dstSpriteP->destFrameRect.left + radiusTwo;
  1506.     centerTwo.v = dstSpriteP->destFrameRect.top + radiusTwo;
  1507.                     
  1508.     horizDistance = centerOne.h - centerTwo.h;
  1509.     vertDistance = centerOne.v - centerTwo.v;
  1510.  
  1511.     return ( (horizDistance*horizDistance) + (vertDistance*vertDistance) <
  1512.         ((radiusOne+radiusTwo)*(radiusOne+radiusTwo)) );
  1513. }
  1514.  
  1515.  
  1516. ///--------------------------------------------------------------------------------------
  1517. // SWPixelCollision
  1518. ///--------------------------------------------------------------------------------------
  1519.  
  1520. SW_FUNC Boolean SWPixelCollision(
  1521.     SpritePtr srcSpriteP,
  1522.     SpritePtr dstSpriteP)
  1523. {
  1524.     Boolean            collision;
  1525.     SInt8             mmuMode;
  1526.     Rect            sectRect;
  1527.     FramePtr        srcFrameP,
  1528.                     dstFrameP;
  1529.     short            numBytesPerRow;
  1530.     short            srcPieceTop,
  1531.                     srcPieceLeft,
  1532.                     dstPieceTop,
  1533.                     dstPieceLeft;
  1534.     unsigned long     srcBaseOffset,
  1535.                     dstBaseOffset;
  1536.     unsigned char*    srcPixelPtr;
  1537.     unsigned char*    dstPixelPtr;
  1538.     short            i, 
  1539.                     j;
  1540.     
  1541.         
  1542.     SWAssert( srcSpriteP != NULL && srcSpriteP->curFrameP != NULL && 
  1543.             srcSpriteP->curFrameP->scanLinePtrArray != NULL && srcSpriteP->curFrameP->maskBaseAddr != NULL );
  1544.     SWAssert( dstSpriteP != NULL && dstSpriteP->curFrameP != NULL && 
  1545.             dstSpriteP->curFrameP->scanLinePtrArray != NULL && dstSpriteP->curFrameP->maskBaseAddr != NULL );
  1546.  
  1547.     collision = false;
  1548.         
  1549.     sectRect.left =
  1550.         SW_MAX(srcSpriteP->destFrameRect.left, dstSpriteP->destFrameRect.left);
  1551.     sectRect.top =
  1552.         SW_MAX(srcSpriteP->destFrameRect.top, dstSpriteP->destFrameRect.top);
  1553.     sectRect.right =
  1554.         SW_MIN(srcSpriteP->destFrameRect.right, dstSpriteP->destFrameRect.right);
  1555.     sectRect.bottom =
  1556.         SW_MIN(srcSpriteP->destFrameRect.bottom, dstSpriteP->destFrameRect.bottom);
  1557.     
  1558.     if ( sectRect.right > sectRect.left && sectRect.bottom > sectRect.top )
  1559.     {
  1560.         if (gSWmmuMode != true32b)
  1561.         {
  1562.             mmuMode = true32b;
  1563.             SwapMMUMode(&mmuMode);
  1564.         }
  1565.         
  1566.         srcFrameP = srcSpriteP->curFrameP;
  1567.         dstFrameP = dstSpriteP->curFrameP;
  1568.     
  1569.             // calculate the top left of the intersecting portions of the frameRects
  1570.         srcPieceTop = srcFrameP->frameRect.top + (sectRect.top-srcSpriteP->destFrameRect.top);
  1571.         srcPieceLeft = srcFrameP->frameRect.left + (sectRect.left-srcSpriteP->destFrameRect.left);
  1572.         dstPieceTop = dstFrameP->frameRect.top + (sectRect.top-dstSpriteP->destFrameRect.top);
  1573.         dstPieceLeft = dstFrameP->frameRect.left + (sectRect.left-dstSpriteP->destFrameRect.left);
  1574.         
  1575.             // calculate the offset to the first byte of the sectRect of srcSprite
  1576.         srcBaseOffset = srcFrameP->scanLinePtrArray[srcPieceTop - srcFrameP->frameRect.top] + 
  1577.             srcPieceLeft;
  1578.             
  1579.             // ... and for the dstSprite
  1580.         dstBaseOffset = dstFrameP->scanLinePtrArray[dstPieceTop - dstFrameP->frameRect.top] + 
  1581.             dstPieceLeft;
  1582.         
  1583.             // calculate pointers to the mask pixels within the overlapping sections
  1584.         srcPixelPtr = (unsigned char*)(srcFrameP->maskBaseAddr + srcBaseOffset);
  1585.         dstPixelPtr = (unsigned char*)(dstFrameP->maskBaseAddr + dstBaseOffset);
  1586.         
  1587.             // calculate the number of bytes in a row
  1588.         numBytesPerRow = (sectRect.right - sectRect.left);
  1589.         
  1590.         i = 0;
  1591.         while ( i < sectRect.bottom-sectRect.top && !collision )
  1592.         {
  1593.             j = 0;
  1594.             while ( j < numBytesPerRow && !collision )
  1595.             {
  1596.                 j++;
  1597.                 collision = ( (*srcPixelPtr | *dstPixelPtr) == 0 );
  1598.                 srcPixelPtr++;
  1599.                 dstPixelPtr++;
  1600.             }
  1601.             i++;
  1602.             srcPixelPtr += (unsigned long)(srcFrameP->frameRowBytes - numBytesPerRow);
  1603.             dstPixelPtr += (unsigned long)(dstFrameP->frameRowBytes - numBytesPerRow);
  1604.         }
  1605.         
  1606.         if (gSWmmuMode != true32b)
  1607.         {
  1608.             SwapMMUMode(&mmuMode);
  1609.         }
  1610.     }
  1611.     return collision;
  1612. }
  1613.  
  1614.  
  1615. ///--------------------------------------------------------------------------------------
  1616. //    SWSetSpriteVisible
  1617. ///--------------------------------------------------------------------------------------
  1618.  
  1619. SW_FUNC void SWSetSpriteVisible(
  1620.     SpritePtr srcSpriteP,
  1621.     Boolean isVisible)
  1622. {
  1623.     SWAssert( srcSpriteP != NULL );
  1624.     
  1625.     if ( srcSpriteP->isVisible != isVisible ) {
  1626.         srcSpriteP->isVisible = isVisible;
  1627.         srcSpriteP->needsToBeDrawn = true;
  1628.         srcSpriteP->needsToBeErased = !isVisible;
  1629.     }
  1630. }
  1631.  
  1632.  
  1633. ///--------------------------------------------------------------------------------------
  1634. //    SWIsSpriteInRect
  1635. ///--------------------------------------------------------------------------------------
  1636.  
  1637. SW_FUNC Boolean SWIsSpriteInRect(
  1638.     SpritePtr srcSpriteP,
  1639.     Rect* testRect)
  1640. {
  1641.     SWAssert( srcSpriteP != NULL && testRect != NULL );
  1642.  
  1643.     return ((srcSpriteP->destFrameRect.top < testRect->bottom) &&
  1644.             (srcSpriteP->destFrameRect.bottom > testRect->top) &&
  1645.              (srcSpriteP->destFrameRect.left < testRect->right) &&
  1646.              (srcSpriteP->destFrameRect.right > testRect->left));
  1647. }
  1648.  
  1649. ///--------------------------------------------------------------------------------------
  1650. //    SWIsSpriteFullyInRect
  1651. ///--------------------------------------------------------------------------------------
  1652.  
  1653. SW_FUNC Boolean SWIsSpriteFullyInRect(
  1654.     SpritePtr srcSpriteP,
  1655.     Rect* testRect)
  1656. {
  1657.     SWAssert( srcSpriteP != NULL && testRect != NULL );
  1658.  
  1659.     return ((srcSpriteP->destFrameRect.top >= testRect->top) &&
  1660.             (srcSpriteP->destFrameRect.bottom <= testRect->bottom) &&
  1661.              (srcSpriteP->destFrameRect.left >= testRect->left) &&
  1662.              (srcSpriteP->destFrameRect.right <= testRect->right));
  1663. }
  1664.  
  1665. ///--------------------------------------------------------------------------------------
  1666. //    SWIsPointInSprite
  1667. ///--------------------------------------------------------------------------------------
  1668.  
  1669. SW_FUNC Boolean SWIsPointInSprite(
  1670.     SpritePtr srcSpriteP,
  1671.     Point testPoint)
  1672. {
  1673.     SWAssert( srcSpriteP != NULL );
  1674.  
  1675.     return    (testPoint.h >= srcSpriteP->destFrameRect.left) &&
  1676.             (testPoint.h <= srcSpriteP->destFrameRect.right) &&
  1677.             (testPoint.v >= srcSpriteP->destFrameRect.top) &&
  1678.             (testPoint.v <= srcSpriteP->destFrameRect.bottom);
  1679. }
  1680.  
  1681.  
  1682.  
  1683.