home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 / SpriteWorld Examples / SpriteTest / SpriteTest.c < prev    next >
Encoding:
Text File  |  1999-01-12  |  26.1 KB  |  996 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // SpriteTest.c
  3. //
  4. // By: Tony Myles
  5. //
  6. // Extensive modifications by Karl Bunker
  7. //
  8. ///--------------------------------------------------------------------------------------
  9.  
  10. #include <Timer.h>
  11.  
  12. #include <SWIncludes.h>            // Automatically include all SpriteWorld.h files
  13.  
  14. #include <SWGameUtils.h>
  15. #include <SWDitherDown.h>
  16. #include <SWDialogUtils.h>
  17. #include <SWApplication.h>
  18. #include "SpriteTest.h"
  19.  
  20. #if __MWERKS__
  21. #include <profiler.h>
  22. #endif
  23.  
  24. #define kBlitterTest false
  25.  
  26. #define kWorldRectInset 0        // modify to test SpriteWorld rect less than window size
  27.  
  28. Boolean            gGlobesVisible;
  29. Boolean            gTitleVisible;
  30. Boolean            gCollisionDetection;
  31. ProcType        gWhichSpriteProc;
  32. ProcType        gWhichOffscreenProc;
  33. ProcType        gWhichScreenProc;
  34. short             gMoveDelta;
  35. SpritePtr        gMasterGlobeSprite = NULL;
  36.  
  37.  
  38. /******************** SetupSWStuff ********************/
  39. OSErr SetupSWStuff(
  40.     SpriteTestPtr* spriteTestP,
  41.     CWindowPtr srcWindowP)
  42. {
  43.     OSErr                 err = noErr;
  44.     SpriteTestPtr         tempSpriteTestP;
  45.     SpriteWorldPtr         spriteWorldP = NULL;
  46.     SpriteLayerPtr         globeSpriteLayerP;
  47.     SpritePtr             globeSpriteArray[kNumberOfGlobeSprites];
  48.     SpritePtr             titleSpriteP;
  49.     SpritePtr             twoSpriteP;
  50.     PixPatHandle         pixPatH = NULL;
  51.     short                 spriteNum;
  52.     short                 oldResRefNum, curResRefNum;
  53.     Rect                 windowRect, worldRect;
  54.  
  55.     
  56.     *spriteTestP = NULL;
  57.  
  58.     SetPort((GrafPtr)srcWindowP);
  59.     
  60.     
  61.     windowRect = srcWindowP->portRect; 
  62.     worldRect = windowRect;
  63.     InsetRect( &worldRect, kWorldRectInset, kWorldRectInset );
  64.     
  65.     ShowWindow( (WindowPtr)srcWindowP );
  66.     TextFont( systemFont );
  67.     TextSize( 12 );
  68.     MoveTo( 40, 80 );
  69.     DrawString( "\pLoading Sprites... please wait" );
  70.     
  71.     tempSpriteTestP = (SpriteTestPtr)NewPtrClear((Size)sizeof(SpriteTestRec));
  72.     
  73.     {
  74.             // create the sprite world
  75.         (void)SWCreateSpriteWorldFromWindow(&spriteWorldP, srcWindowP, &worldRect, NULL, 0);
  76.     }
  77.  
  78.     if (SWStickyError() == noErr)
  79.     {
  80.         tempSpriteTestP->spriteWorldP = spriteWorldP;
  81.         
  82.             // create the sprite layer
  83.         (void)SWCreateSpriteLayer(&globeSpriteLayerP);
  84.         tempSpriteTestP->globeSpriteLayerP = globeSpriteLayerP;
  85.     }
  86.  
  87.     if (SWStickyError() == noErr)
  88.     {
  89.         oldResRefNum = CurResFile();
  90.         curResRefNum = OpenResFile("\pSpriteTest Frames");
  91.         SWSetStickyIfError( ResError() );
  92.     }
  93.  
  94.     if (SWStickyError() == noErr)
  95.     {
  96.         UseResFile(curResRefNum);
  97.  
  98.         (void)SWCreateSpriteFromSinglePict(
  99.             spriteWorldP,
  100.             &gMasterGlobeSprite,
  101.             NULL,
  102.             kBaseResID,
  103.             kBaseResID+1,
  104.             kGlobeHeight,
  105.             kGlobeBorderWidth,
  106.             kFatMask);
  107.  
  108.         (void)SWCreateSpriteFromSinglePict(
  109.             spriteWorldP,
  110.             &twoSpriteP,
  111.             NULL,
  112.             kBaseResID+2,
  113.             kBaseResID+2,
  114.             kTwoHeight,
  115.             kTwoBorderWidth,
  116.             kFatMask);
  117.         
  118.         if (SWStickyError() == noErr)
  119.         {
  120.             if ( spriteWorldP->pixelDepth < 8 )
  121.             {
  122.                 DitherDownPict( kBaseResID+2, twoSpriteP->sharedPictGWorld );
  123.                 LowerMaskDepth( kBaseResID+2, twoSpriteP->sharedMaskGWorld );
  124.             }
  125.             SWSetSpriteFrameTime( twoSpriteP, kGlobeSpriteFrameTime*4 );
  126.             SWSetSpriteFrameRange( twoSpriteP, 0, kNumberOfTwoFrames - 1 );
  127.             SWSetSpriteFrameAdvanceMode( twoSpriteP, kSWPatrollingMode );
  128.         }
  129.         UseResFile(oldResRefNum);
  130.         CloseResFile(curResRefNum);
  131.     }
  132.  
  133.     if (SWStickyError() == noErr)
  134.     {
  135.         if ( spriteWorldP->pixelDepth == 8 )
  136.             (void)SWCompileSprite( gMasterGlobeSprite );
  137.             // master globe sprite isn't added to any layer, so we have to lock it separately
  138.         SWLockSprite( gMasterGlobeSprite);
  139.     }
  140.  
  141.     if (SWStickyError() == noErr)
  142.     {
  143.             
  144.         for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  145.         {
  146.             (void)SWCloneSprite(gMasterGlobeSprite, globeSpriteArray + spriteNum, NULL);
  147.             tempSpriteTestP->globeSpriteArray[spriteNum] = globeSpriteArray[spriteNum];
  148.         }
  149.     
  150.     }
  151.     
  152.     if (SWStickyError() == noErr)
  153.     {
  154.         (void)SWCreateSpriteFromPictResource( 
  155.             spriteWorldP,
  156.             &titleSpriteP, 
  157.             NULL, 
  158.             kBaseResID, 
  159.             kBaseResID, 
  160.             1, 
  161.             kFatMask);
  162.         
  163.         if ( spriteWorldP->pixelDepth < 8 )
  164.         {
  165.             DitherDownPict( kBaseResID, titleSpriteP->frameArray[0]->framePort );
  166.             LowerMaskDepth( kBaseResID, titleSpriteP->frameArray[0]->maskPort );
  167.         }
  168.         tempSpriteTestP->titleSpriteP = titleSpriteP;
  169.         tempSpriteTestP->twoSpriteP = twoSpriteP;
  170.         
  171.         *spriteTestP = tempSpriteTestP;
  172.         
  173.         for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  174.         {
  175.             if (spriteNum == (kNumberOfGlobeSprites / 2))
  176.             {
  177.                 SWAddSprite(globeSpriteLayerP, titleSpriteP);
  178.                 SWAddSprite(globeSpriteLayerP, twoSpriteP);
  179.             }
  180.             SWAddSprite(globeSpriteLayerP, globeSpriteArray[spriteNum]);
  181.         }
  182.         
  183.  
  184.         SWAddSpriteLayer(spriteWorldP, globeSpriteLayerP);
  185.  
  186.  
  187.         SWLockSpriteWorld(spriteWorldP);
  188.     
  189.         SWSetPortToBackground(spriteWorldP);
  190.         EraseRect( &spriteWorldP->backRect );
  191.         
  192.         if ( spriteWorldP->pixelDepth >= 8 )
  193.         {
  194.             pixPatH = GetPixPat(kBackDropPixPatID);
  195.             if ( pixPatH != NULL )
  196.             {
  197.                 FillCRect(&spriteWorldP->backRect, pixPatH);
  198.                 DisposePixPat(pixPatH);
  199.             }
  200.         }
  201.         else
  202.             FillRect(&spriteWorldP->backRect, &qd.ltGray);
  203.         
  204.         SWSetPortToWindow(spriteWorldP);
  205.         
  206.         SetupSpriteWorldElements(tempSpriteTestP);
  207.     }
  208.     if ( SWStickyError() != noErr)
  209.     {
  210.         DisposeSWStuff(tempSpriteTestP);
  211.     }
  212.  
  213.     return SWStickyError();
  214. }
  215.         
  216.  
  217. /******************** DisposeSWStuff ********************/
  218. void DisposeSWStuff(
  219.     SpriteTestPtr spriteTestP)
  220. {    
  221.     if (spriteTestP != NULL)
  222.     {
  223.         if (spriteTestP->spriteWorldP != NULL)
  224.         {
  225.             SWDisposeSpriteWorld(&spriteTestP->spriteWorldP);
  226.         }
  227.             // gMasterGlobeSprite is not added to any layer, 
  228.             // so SWDisposeSpriteWorld won't dispose of it
  229.         if ( gMasterGlobeSprite != NULL )
  230.         {
  231.             SWDisposeSprite( &gMasterGlobeSprite );
  232.         }
  233.         DisposePtr((Ptr)spriteTestP);
  234.     }
  235. }
  236.  
  237.  
  238. /******************** SetupSpriteWorldElements ********************/
  239. void SetupSpriteWorldElements(
  240.     SpriteTestPtr spriteTestP)
  241. {
  242.     register         long spriteNum;
  243.     Rect             moveBoundsRect;
  244.     Rect            titleDestRect;
  245.     
  246.  
  247.     moveBoundsRect = spriteTestP->spriteWorldP->backRect;
  248.     
  249.         // set up the globe sprites
  250.     gMoveDelta = 0;
  251.     for (spriteNum = 0; spriteNum < kNumberOfGlobeSprites; spriteNum++)
  252.     {
  253.         SetupGlobeSprite(spriteTestP->globeSpriteArray[spriteNum], &moveBoundsRect,
  254.                 GetRandom(moveBoundsRect.left, moveBoundsRect.right),
  255.                 GetRandom(moveBoundsRect.top, moveBoundsRect.bottom));
  256.     }
  257.  
  258.         // set up the title sprites
  259.     titleDestRect = spriteTestP->titleSpriteP->destFrameRect;
  260.  
  261.     CenterRect( &titleDestRect, &moveBoundsRect );
  262.     OffsetRect( &titleDestRect, -(kTwoHeight + 2 ), 0 );
  263.     SWSetSpriteLocation(spriteTestP->titleSpriteP, titleDestRect.left, titleDestRect.top );
  264.     
  265.     SWSetSpriteLocation(spriteTestP->twoSpriteP, titleDestRect.right, titleDestRect.top-7 );
  266.     
  267.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 30 );
  268. //    SWSyncSpriteWorldToVBL( spriteTestP->spriteWorldP, true );
  269.     SWSetCleanUpSpriteWorld(spriteTestP->spriteWorldP);
  270.  
  271.     gGlobesVisible = true;
  272.     gTitleVisible = true;
  273.     gCollisionDetection = false;
  274.     gWhichSpriteProc = kCopyBitsProc;
  275.     gWhichOffscreenProc = kCopyBitsProc;
  276.     gWhichScreenProc = kCopyBitsProc;
  277. }
  278.  
  279.  
  280. /******************** SetupGlobeSprite ********************/
  281.  
  282. void SetupGlobeSprite(
  283.     SpritePtr globeSpriteP,
  284.     Rect *moveBoundsRect,
  285.     short horizLocation,
  286.     short vertLocation)
  287. {
  288.     Rect tempBoundsRect;
  289.     short horizMoveDelta;
  290.     short vertMoveDelta;
  291.  
  292.     gMoveDelta++;
  293.     if ( gMoveDelta > 17 )
  294.         gMoveDelta = 1;
  295.  
  296.     tempBoundsRect = *moveBoundsRect;
  297.  
  298.     horizMoveDelta = GetRandom(2, 6);    // gMoveDelta
  299.     vertMoveDelta =    GetRandom(2, 6);    // gMoveDelta
  300.  
  301.     if (GetRandom(0, 1) == 0)
  302.     {
  303.         horizMoveDelta = -horizMoveDelta;
  304.     }
  305.  
  306.     if (GetRandom(0, 1) == 0)
  307.     {
  308.         vertMoveDelta = -vertMoveDelta;
  309.     }
  310.  
  311.         // set the sprite’s movement characteristics
  312.     SWSetSpriteMoveBounds(globeSpriteP, &tempBoundsRect);
  313.     SWSetSpriteMoveDelta(globeSpriteP, horizMoveDelta, vertMoveDelta);
  314.     SWSetSpriteMoveProc(globeSpriteP, GlobeSpriteMoveProc);
  315.     SWSetSpriteMoveTime(globeSpriteP, kGlobeSpriteMoveTime);
  316.  
  317.     SWSetSpriteFrameTime(globeSpriteP, kGlobeSpriteFrameTime);
  318.     SWSetSpriteFrameRange(globeSpriteP, 0, kNumberOfGlobeFrames - 1);
  319.     SWSetSpriteFrameAdvance(globeSpriteP, GetRandom(0, 1) ? -1 : 1);
  320.  
  321.         // three to try:
  322.         // PixelBounceCollideProc,
  323.         // RegionBounceCollideProc,
  324.         // RadiusBounceCollideProc
  325.     SWSetSpriteCollideProc(globeSpriteP, RegionBounceCollideProc);
  326.  
  327.         // set the sprite’s initial location
  328.     SWSetSpriteLocation(globeSpriteP, horizLocation, vertLocation);
  329. }
  330.  
  331.  
  332. /******************** SpriteTestIdle ********************/
  333. void SpriteTestIdle(
  334.     SpriteTestPtr spriteTestP )
  335. {
  336.     if (gCollisionDetection)
  337.     {
  338.         SWCollideSpriteLayer(spriteTestP->spriteWorldP, 
  339.             spriteTestP->globeSpriteLayerP, spriteTestP->globeSpriteLayerP);
  340.     }
  341.     SWProcessSpriteWorld( spriteTestP->spriteWorldP );
  342.     SWAnimateSpriteWorld( spriteTestP->spriteWorldP );
  343. }
  344.  
  345.  
  346. /******************** UpdateSpriteTest ********************/
  347. void UpdateSpriteTest(
  348.     SpriteTestPtr spriteTestP,
  349.     WindowPtr updateWindowP)
  350. {
  351.     SetPort( updateWindowP );
  352.     if ( updateWindowP->portRect.right - updateWindowP->portRect.left > 
  353.         spriteTestP->spriteWorldP->backRect.right - 
  354.         spriteTestP->spriteWorldP->backRect.left )
  355.     {
  356.         ForeColor( blueColor );
  357.         PaintRect( &updateWindowP->portRect );
  358.     }
  359.     ForeColor( blackColor );
  360.     SWUpdateSpriteWorld(spriteTestP->spriteWorldP, true);
  361. }
  362.  
  363.  
  364. /******************** HandleCreateSpriteCommand ********************/
  365. void HandleCreateSpriteCommand(
  366.     SpriteTestPtr spriteTestP)
  367. {
  368.     OSErr err;
  369.     SpritePtr globeSpriteP;
  370.     Rect moveBoundsRect;
  371.     Point mouseLocation;
  372.  
  373.  
  374.     err = SWCloneSprite(gMasterGlobeSprite, &globeSpriteP, NULL);
  375.  
  376.     if (err == noErr)
  377.     {
  378.         moveBoundsRect = spriteTestP->spriteWorldP->backRect;
  379.         GetMouse(&mouseLocation);
  380.         mouseLocation.h -= spriteTestP->spriteWorldP->windRect.left;
  381.         mouseLocation.v -= spriteTestP->spriteWorldP->windRect.top;
  382.         
  383.         SetupGlobeSprite(globeSpriteP, &moveBoundsRect, mouseLocation.h, mouseLocation.v);
  384.  
  385.             // Add sprite in front of or behind the title sprite
  386.         if ( GetRandom(0,1) )
  387.             SWAddSprite(spriteTestP->globeSpriteLayerP, globeSpriteP);
  388.         else
  389.             SWInsertSpriteBeforeSprite(globeSpriteP, spriteTestP->titleSpriteP);
  390.     }
  391. }
  392.  
  393.  
  394. /******************** HandleSpriteTestTitleCommand ********************/
  395. void HandleSpriteTestTitleCommand(
  396.     SpriteTestPtr spriteTestP)
  397. {
  398.     gTitleVisible = !gTitleVisible;
  399.  
  400.     SWSetSpriteVisible(spriteTestP->titleSpriteP, gTitleVisible);
  401.     SWSetSpriteVisible(spriteTestP->twoSpriteP, gTitleVisible);
  402. }
  403.  
  404.  
  405. /******************** HandleBouncingBallsCommand ********************/
  406. void HandleBouncingBallsCommand(
  407.     SpriteTestPtr spriteTestP)
  408. {
  409.     SpritePtr globeSpriteP;
  410.     
  411.     
  412.     gGlobesVisible = !gGlobesVisible;
  413.  
  414.     globeSpriteP = NULL;
  415.     while ((globeSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, globeSpriteP)) != NULL)
  416.     {
  417.         if (globeSpriteP != spriteTestP->titleSpriteP && globeSpriteP != spriteTestP->twoSpriteP)
  418.         {
  419.             SWSetSpriteVisible(globeSpriteP, gGlobesVisible);
  420.         }
  421.     }
  422. }
  423.  
  424.  
  425. /******************** RemoveClickedSprite ********************/
  426. void RemoveClickedSprite(
  427.     SpriteTestPtr spriteTestP)
  428. {
  429.     Point         mouseLocation;
  430.     SpritePtr    spriteToRemove;
  431.     
  432.     
  433.     if ( spriteTestP != NULL )
  434.     {
  435.         GetMouse(&mouseLocation);
  436.         
  437.         mouseLocation.h -= spriteTestP->spriteWorldP->windRect.left;
  438.         mouseLocation.v -= spriteTestP->spriteWorldP->windRect.top;
  439.             // if a sprite has been clicked on, and it isn't the title sprite,
  440.             // then remove it and dispose of it
  441.         spriteToRemove = SWFindSpriteByPoint(spriteTestP->globeSpriteLayerP, NULL, mouseLocation);
  442.         if ( spriteToRemove != NULL &&
  443.             spriteToRemove != spriteTestP->titleSpriteP &&
  444.             spriteToRemove != spriteTestP->twoSpriteP)
  445.         {
  446.             SWRemoveSpriteFromAnimation( spriteTestP->spriteWorldP, spriteToRemove, true );
  447.         }
  448.     }
  449. }
  450.  
  451.  
  452. /******************** SetUpTestDialog ********************/
  453. void SetUpTestDialog(
  454.     SpriteTestPtr spriteTestP)
  455. {
  456.     GrafPtr            savePort;
  457.     DialogPtr        theDialog;
  458.     short            itemHit;
  459.     ProcType        originalSpriteProc, 
  460.                     originalOffscreenProc,
  461.                     originalScreenProc;
  462.     Boolean            runNow;
  463.     Boolean            done = false;
  464.     OSErr            err = noErr;
  465.     
  466.  
  467.     GetPort( &savePort );
  468.         
  469.     theDialog = GetNewDialog(kSetUpTestResID, nil, (WindowPtr)-1L);
  470.         
  471.     SetDialogDefaultItem( theDialog, ok );
  472.     SetDialogCancelItem( theDialog, cancel );
  473.     
  474.     originalSpriteProc = gWhichSpriteProc;
  475.     originalOffscreenProc = gWhichOffscreenProc;
  476.     originalScreenProc = gWhichScreenProc;
  477.                 
  478.         // Check if we can do 8-bit-specific tests 
  479.     SetDItemHilite( theDialog, kCompiledSpriteButton, 
  480.             (spriteTestP->spriteWorldP->pixelDepth==8) );
  481. #if SW_PPC    
  482.     SetDItemHilite( theDialog, kBlitPixieSpriteButton, 
  483.             (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  484.     SetDItemHilite( theDialog, kBlitPixieOffscreenButton, 
  485.             (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  486.     SetDItemHilite( theDialog, kBlitPixieScreenButton, 
  487.             (spriteTestP->spriteWorldP->pixelDepth >= 8) );
  488.  
  489.     SetDItemHilite( theDialog, kCompiledSpriteButton, false );
  490. #endif
  491.  
  492.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kRunTestNowCheckBox), true );
  493.     
  494.     SetSetUpTestButtons( theDialog );
  495.     
  496.     ShowWindow( theDialog );
  497.     
  498.     while ( !done )
  499.     {    
  500.         ModalDialog( nil, &itemHit );
  501.         switch( itemHit )
  502.         {
  503.             case kCopyBitsSpriteButton:
  504.                 gWhichSpriteProc = kCopyBitsProc;
  505.                 SetSetUpTestButtons( theDialog );
  506.             break;
  507.             case kBlitPixieSpriteButton:
  508.                 gWhichSpriteProc = kBlitPixieProc;
  509.                 SetSetUpTestButtons( theDialog );
  510.             break;
  511.             case kCompiledSpriteButton:
  512.                 gWhichSpriteProc = kCompiledProc;
  513.                 SetSetUpTestButtons( theDialog );
  514.             break;
  515.             case kCopyBitsOffscreenButton:
  516.                 gWhichOffscreenProc = kCopyBitsProc;
  517.                 SetSetUpTestButtons( theDialog );
  518.             break;
  519.             case kBlitPixieOffscreenButton:
  520.                 gWhichOffscreenProc = kBlitPixieProc;
  521.                 SetSetUpTestButtons( theDialog );
  522.             break;
  523.             case kCopyBitsScreenButton:
  524.                 gWhichScreenProc = kCopyBitsProc;
  525.                 SetSetUpTestButtons( theDialog );
  526.             break;
  527.             case kBlitPixieScreenButton:
  528.                 gWhichScreenProc = kBlitPixieProc;
  529.                 SetSetUpTestButtons( theDialog );
  530.             break;
  531.             case kRunTestNowCheckBox:
  532.                 ToggleDItemValue(theDialog, kRunTestNowCheckBox);
  533.             break;
  534.             case ok:
  535.                 runNow = GetControlValue( (ControlHandle)GetDItemHandle(theDialog, kRunTestNowCheckBox));
  536.             case cancel:
  537.                 done = true;
  538.             break;
  539.         }
  540.     }
  541.     DisposeDialog( theDialog );
  542.     SetPort( savePort );
  543.     
  544.     if ( itemHit == ok )
  545.     {
  546.         if ( runNow )
  547.             RunTheTest( spriteTestP );
  548.     }
  549.     if ( itemHit == cancel )
  550.     {
  551.         gWhichSpriteProc = originalSpriteProc;
  552.         gWhichOffscreenProc = originalOffscreenProc;
  553.         gWhichScreenProc = originalScreenProc;
  554.     }
  555. }
  556.  
  557.  
  558.  
  559. /******************** SetSetUpTestButtons ********************/
  560. void SetSetUpTestButtons(
  561.     DialogPtr theDialog)
  562. {
  563.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kCopyBitsSpriteButton), 
  564.         (gWhichSpriteProc == kCopyBitsProc) );
  565.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kBlitPixieSpriteButton), 
  566.         (gWhichSpriteProc == kBlitPixieProc) );
  567.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kCompiledSpriteButton), 
  568.         (gWhichSpriteProc == kCompiledProc) );
  569.     
  570.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kCopyBitsOffscreenButton), 
  571.         (gWhichOffscreenProc == kCopyBitsProc) );
  572.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kBlitPixieOffscreenButton), 
  573.         (gWhichOffscreenProc == kBlitPixieProc) );
  574.     
  575.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kCopyBitsScreenButton), 
  576.         (gWhichScreenProc == kCopyBitsProc) );
  577.     SetControlValue( (ControlHandle)GetDItemHandle(theDialog, kBlitPixieScreenButton), 
  578.         (gWhichScreenProc == kBlitPixieProc) );
  579. }
  580.  
  581.  
  582. /******************** RunTheTest ********************/
  583. void RunTheTest(
  584.     SpriteTestPtr spriteTestP)
  585. {
  586.     WindowPtr         testWindowP = FrontWindow();
  587.     SpritePtr         curSpriteP;
  588.     unsigned long     frames, seconds;
  589.     long             ticks;
  590.     Rect            shieldRect;
  591.     Point            shieldRectOffset;
  592.     Rect            srcRect,
  593.                     destRect;
  594.     UnsignedWide    startMicroseconds,
  595.                     endMicroseconds;
  596.  
  597.  
  598.         // set up for the test
  599.     
  600.     shieldRect = spriteTestP->spriteWorldP->windowFrameP->frameRect;
  601.     LocalToGlobal( &topLeft(shieldRect) );
  602.     LocalToGlobal( &botRight(shieldRect) );
  603.     shieldRectOffset.h = shieldRectOffset.v = 0;
  604.     ShieldCursor( &shieldRect, shieldRectOffset );
  605.     
  606.     SWHideMenuBar(testWindowP);
  607.     
  608.     UpdateSpriteTest( spriteTestP, testWindowP );
  609.     
  610.     curSpriteP = NULL;
  611.     while ((curSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, curSpriteP)) != NULL)
  612.     {
  613.         if (curSpriteP != spriteTestP->titleSpriteP && curSpriteP != spriteTestP->twoSpriteP)
  614.         {
  615.             SWSetSpriteFrameTime(curSpriteP, 0);
  616.             SWSetSpriteMoveTime(curSpriteP, 0);
  617.             switch ( gWhichSpriteProc )
  618.             {
  619.                 case kBlitPixieProc:
  620.                     if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  621.                         (void)SWSetSpriteDrawProc(curSpriteP, BlitPixie8BitMaskDrawProc);
  622.                     else
  623.                     {
  624.                         (void)SWSetSpriteDrawProc(curSpriteP, BlitPixieAllBitMaskDrawProc);
  625.                     }
  626.                 break;
  627.                 case kCompiledProc:
  628.                     (void)SWSetSpriteDrawProc(curSpriteP, CompiledSprite8BitDrawProc);
  629.                 break;
  630.             }
  631.         }
  632.     }
  633.     
  634.     if ( gWhichSpriteProc == kBlitPixieProc || gWhichSpriteProc == kCompiledProc )
  635.     {
  636.         if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  637.         {
  638.             (void)SWSetSpriteDrawProc(spriteTestP->titleSpriteP, BlitPixie8BitMaskDrawProc);
  639.             (void)SWSetSpriteDrawProc(spriteTestP->twoSpriteP, BlitPixie8BitMaskDrawProc);
  640.         }
  641.         else
  642.         {
  643.             (void)SWSetSpriteDrawProc(spriteTestP->titleSpriteP, BlitPixieAllBitMaskDrawProc);
  644.             (void)SWSetSpriteDrawProc(spriteTestP->twoSpriteP, BlitPixieAllBitMaskDrawProc);    
  645.         }
  646.     }
  647.     if ( gWhichOffscreenProc == kBlitPixieProc )
  648.     {
  649.         if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  650.         {
  651.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  652.                 BlitPixie8BitRectDrawProc);
  653.         }
  654.         else
  655.         {
  656.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  657.                 BlitPixieAllBitRectDrawProc);    
  658.         }
  659.     }
  660.     if ( gWhichScreenProc == kBlitPixieProc )
  661.     {
  662.         if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  663.         {
  664.             (void)SWSetSpriteWorldScreenDrawProc(spriteTestP->spriteWorldP, 
  665.                 BlitPixie8BitRectDrawProc);
  666.         }
  667.         else
  668.         {
  669.             (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, 
  670.                 BlitPixieAllBitRectDrawProc);
  671.         }
  672.     }
  673.  
  674.         // Floor it!!!
  675.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 0 );
  676.     
  677.     ticks = TickCount();
  678.  
  679.  
  680.         // the actual tests...
  681.         
  682.         // a straight blitter test -- no animation to screen
  683.  
  684.     if ( kBlitterTest )
  685.     {
  686.         srcRect = gMasterGlobeSprite->frameArray[0]->frameRect;
  687.         destRect = srcRect;
  688.         OffsetRect( &destRect, 3, 0 );
  689.         Microseconds( &startMicroseconds );
  690.         
  691.         if ( spriteTestP->spriteWorldP->pixelDepth == 8 )
  692.         {
  693.             for (frames = 0; frames < 10000; frames++ )
  694.             {
  695.                 BlitPixie8BitMaskDrawProc(
  696.                     gMasterGlobeSprite->frameArray[0],
  697.                     spriteTestP->spriteWorldP->workFrameP,
  698.                     &srcRect,
  699.                     &destRect);
  700.             }
  701.         }
  702.         else
  703.         {
  704.             for (frames = 0; frames < 10000; frames++ )
  705.             {
  706.                 BlitPixieAllBitMaskDrawProc(
  707.                     gMasterGlobeSprite->frameArray[0],
  708.                     spriteTestP->spriteWorldP->workFrameP,
  709.                     &srcRect,
  710.                     &destRect);
  711.             }
  712.         }
  713.         
  714.         Microseconds( &endMicroseconds );
  715.         seconds = endMicroseconds.lo - startMicroseconds.lo;
  716.         if ( endMicroseconds.hi != startMicroseconds.hi )
  717.             seconds = 0;        // do test over
  718.     }
  719.     else    // a test of animation to screen
  720.     {
  721. /*
  722.         ProfilerSetStatus( true );
  723. */
  724.         for (frames = 0; ((TickCount() - ticks) < kTestTime) && (!Button()); frames++)
  725.         {
  726.             if (gCollisionDetection)
  727.             {
  728.                 SWCollideSpriteLayer(spriteTestP->spriteWorldP, 
  729.                     spriteTestP->globeSpriteLayerP, spriteTestP->globeSpriteLayerP);
  730.             }
  731.  
  732.             SWProcessSpriteWorld( spriteTestP->spriteWorldP );
  733.             SWAnimateSpriteWorld( spriteTestP->spriteWorldP );
  734.         }
  735.         seconds = ((TickCount() - ticks) / 60);
  736.     }
  737. /*
  738.     ProfilerSetStatus( false );
  739.     ProfilerDump( "\pSWPPC Profile" );
  740.     ProfilerTerm();
  741. */
  742.  
  743.         // restore things to default state
  744.     RestoreFromTest( testWindowP, spriteTestP );
  745.     
  746.     DisplayPerformance(frames, seconds);
  747. }
  748.  
  749.  
  750.  
  751. /******************** RestoreFromTest ********************/
  752. void RestoreFromTest(
  753.     WindowPtr testWindowP,
  754.     SpriteTestPtr spriteTestP)
  755. {
  756.     SpritePtr             curSpriteP;
  757.     
  758.     
  759.         // restore things to default state
  760.         
  761.     curSpriteP = NULL;
  762.  
  763.     while ((curSpriteP = SWGetNextSprite(spriteTestP->globeSpriteLayerP, curSpriteP)) != NULL)
  764.     {
  765.         (void)SWSetSpriteDrawProc(curSpriteP, SWStdSpriteDrawProc);
  766.         if (curSpriteP != spriteTestP->titleSpriteP && curSpriteP != spriteTestP->twoSpriteP)
  767.         {
  768.             SWSetSpriteFrameTime(curSpriteP, kGlobeSpriteFrameTime);
  769.         }
  770.     }
  771.     
  772.     (void)SWSetSpriteWorldOffscreenDrawProc(spriteTestP->spriteWorldP, SWStdWorldDrawProc);
  773.     (void)SWSetSpriteWorldScreenDrawProc(spriteTestP->spriteWorldP, SWStdWorldDrawProc);
  774.     
  775.     SWSetSpriteWorldMaxFPS( spriteTestP->spriteWorldP, 30 );
  776.     
  777.     ShowCursor();
  778.     SWShowMenuBar(testWindowP);
  779. }
  780.  
  781.  
  782. /******************** DisplayPerformance ********************/
  783. void DisplayPerformance(
  784.     long frames,
  785.     long seconds)
  786. {
  787.     Str255 framesString, secondsString, fpsString;
  788.     long fps;
  789.     
  790.     NumToString(frames, framesString);
  791.     NumToString(seconds, secondsString);
  792.  
  793.     fps = (seconds > 0) ? frames / seconds : frames;
  794.     
  795.     NumToString(fps, fpsString);
  796.     
  797.     ParamText(framesString, secondsString, fpsString, "\p");
  798.     NoteAlert(kPerformanceAlertID, NULL);
  799. }
  800.  
  801.  
  802. /******************** GlobeSpriteMoveProc ********************/
  803. SW_FUNC void GlobeSpriteMoveProc(SpritePtr globeSpriteP)
  804. {    
  805.     SWOffsetSprite(globeSpriteP, globeSpriteP->horizMoveDelta, globeSpriteP->vertMoveDelta);
  806.     (void)SWBounceSprite(globeSpriteP);
  807. }
  808.  
  809.  
  810. /******************** PixelBounceCollideProc ********************/
  811. SW_FUNC void PixelBounceCollideProc(
  812.     SpritePtr srcSpriteP,
  813.     SpritePtr dstSpriteP,
  814.     Rect* sectRect)
  815. {    
  816.  
  817.         // If both sprites use the same collision routine (this one),ignore the second collision.
  818.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  819.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  820.         (srcSpriteP > dstSpriteP)))
  821.     {
  822.         return;
  823.     }
  824.  
  825.     if ( SWPixelCollision(srcSpriteP, dstSpriteP) )
  826.     {
  827.             // if a stationary sprite (the title), just bounce off it
  828.         if ((dstSpriteP->horizMoveDelta == 0) && (dstSpriteP->vertMoveDelta == 0))
  829.         {
  830.             BounceGlobeOffTitle( dstSpriteP, srcSpriteP, sectRect );
  831.         }
  832.         else    
  833.             // globe to globe collision; swap movement delta's
  834.         {
  835.             BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  836.         }
  837.     }
  838. }
  839.  
  840.  
  841. /******************** RegionBounceCollideProc ********************/
  842. SW_FUNC void RegionBounceCollideProc(
  843.     SpritePtr srcSpriteP,
  844.     SpritePtr dstSpriteP,
  845.     Rect* sectRect)
  846. {    
  847.  
  848.         // If both sprites use the same collision routine (this one),ignore the second collision.
  849.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  850.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  851.         (srcSpriteP > dstSpriteP)))
  852.     {
  853.         return;
  854.     }
  855.  
  856.  
  857.     if ( SWRegionCollision(srcSpriteP, dstSpriteP) )
  858.     {
  859.             // if a stationary sprite (the title), just bounce off it
  860.         if ((dstSpriteP->horizMoveDelta == 0) && (dstSpriteP->vertMoveDelta == 0))
  861.         {
  862.             BounceGlobeOffTitle( dstSpriteP, srcSpriteP, sectRect );
  863.         }
  864.         else    
  865.             // globe to globe collision; swap movement delta's
  866.         {
  867.             BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  868.         }
  869.     }
  870. }
  871.  
  872.  
  873. /******************** RadiusBounceCollideProc ********************/
  874. SW_FUNC void RadiusBounceCollideProc(
  875.     SpritePtr srcSpriteP,
  876.     SpritePtr dstSpriteP,
  877.     Rect* sectRect)
  878. {
  879.      #pragma unused(sectRect)
  880.  
  881.         // If both sprites use the same collision routine (this one),ignore the second collision.
  882.     if ((!srcSpriteP->isVisible || !dstSpriteP->isVisible) ||
  883.         ((srcSpriteP->spriteCollideProc == dstSpriteP->spriteCollideProc) &&
  884.         (srcSpriteP > dstSpriteP)))
  885.         return;
  886.  
  887.         // ignore collision with title sprite
  888.     if ( (srcSpriteP->destFrameRect.right-srcSpriteP->destFrameRect.left !=
  889.          srcSpriteP->destFrameRect.bottom-srcSpriteP->destFrameRect.top) ||
  890.          (dstSpriteP->destFrameRect.right-dstSpriteP->destFrameRect.left !=
  891.          dstSpriteP->destFrameRect.bottom-dstSpriteP->destFrameRect.top))
  892.         return;
  893.  
  894.     if ( SWRadiusCollision( srcSpriteP, dstSpriteP ) )
  895.     {
  896.         BounceGlobeOffGlobe( srcSpriteP, dstSpriteP );
  897.     }
  898. }
  899.  
  900.  
  901. /******************** BounceGlobeOffGlobe ********************/
  902. void BounceGlobeOffGlobe(
  903.     SpritePtr srcSpriteP,
  904.     SpritePtr dstSpriteP )
  905. {
  906.     short            tempDelta;
  907.     short            nextHorizDistA, nextVertDistA,
  908.                     nextHorizDistB, nextVertDistB;
  909.  
  910.     
  911.         // reverse spins.
  912.     srcSpriteP->frameAdvance = -srcSpriteP->frameAdvance;
  913.     dstSpriteP->frameAdvance = -dstSpriteP->frameAdvance;
  914.  
  915.         // Calculate what the distance between sprites will be if we don't switch deltas
  916.     nextHorizDistA = srcSpriteP->destFrameRect.left + srcSpriteP->horizMoveDelta - 
  917.                 (dstSpriteP->destFrameRect.left + dstSpriteP->horizMoveDelta);
  918.     if (nextHorizDistA < 0)
  919.         nextHorizDistA = -nextHorizDistA;
  920.     
  921.     nextVertDistA = srcSpriteP->destFrameRect.top + srcSpriteP->vertMoveDelta - 
  922.                 (dstSpriteP->destFrameRect.top + dstSpriteP->vertMoveDelta);
  923.     if (nextVertDistA < 0)
  924.         nextVertDistA = -nextVertDistA;
  925.     
  926.         // Calculate what the distance between sprites will be if we do switch deltas
  927.     nextHorizDistB = srcSpriteP->destFrameRect.left + dstSpriteP->horizMoveDelta - 
  928.                 (dstSpriteP->destFrameRect.left + srcSpriteP->horizMoveDelta);
  929.     if (nextHorizDistB < 0)
  930.         nextHorizDistB = -nextHorizDistB;
  931.     
  932.     nextVertDistB = srcSpriteP->destFrameRect.top + dstSpriteP->vertMoveDelta - 
  933.                 (dstSpriteP->destFrameRect.top + srcSpriteP->vertMoveDelta);
  934.     if (nextVertDistB < 0)
  935.         nextVertDistB = -nextVertDistB;
  936.     
  937.     
  938.         // Will swapping the horizontal deltas move the sprites farther apart?
  939.     if (nextHorizDistB > nextHorizDistA)
  940.     {
  941.             // swap horizontal deltas
  942.         tempDelta = srcSpriteP->horizMoveDelta;
  943.         srcSpriteP->horizMoveDelta = dstSpriteP->horizMoveDelta;
  944.         dstSpriteP->horizMoveDelta = tempDelta;
  945.     }
  946.     
  947.         // Will swapping the vertical deltas move the sprites farther apart?
  948.     if (nextVertDistB > nextVertDistA)
  949.     {
  950.             // swap vertical deltas
  951.         tempDelta = srcSpriteP->vertMoveDelta;
  952.         srcSpriteP->vertMoveDelta = dstSpriteP->vertMoveDelta;
  953.         dstSpriteP->vertMoveDelta = tempDelta;
  954.     }
  955. }
  956.  
  957.  
  958.  /******************** BounceGlobeOffTitle ********************/
  959. void BounceGlobeOffTitle(
  960.     SpritePtr titleSpriteP,
  961.     SpritePtr globeSpriteP,
  962.     Rect* sectRect )
  963. {
  964.     short        absHorizDelta,
  965.                 absVertDelta;
  966.                 
  967.     absHorizDelta = globeSpriteP->horizMoveDelta;
  968.     if ( absHorizDelta < 0 )
  969.         absHorizDelta = -absHorizDelta;
  970.     absVertDelta = globeSpriteP->vertMoveDelta;
  971.     if ( absVertDelta < 0 )
  972.         absVertDelta = -absVertDelta;
  973.         
  974.     // draw a picture and this test algorithm will become clear
  975.     if ((sectRect->right - sectRect->left) < (sectRect->bottom - sectRect->top) )
  976.     {
  977.             // Hit left or right side
  978.         if ( sectRect->left <= titleSpriteP->destFrameRect.left )
  979.             // hit on left side
  980.             globeSpriteP->horizMoveDelta = -absHorizDelta;
  981.         else
  982.             // hit on right side
  983.             globeSpriteP->horizMoveDelta = absHorizDelta;
  984.     }
  985.     else
  986.     {
  987.             // Hit top or bottom
  988.         if ( sectRect->top <= titleSpriteP->destFrameRect.top )
  989.             // hit on top
  990.             globeSpriteP->vertMoveDelta = -absVertDelta;
  991.         else
  992.             // hit on bottom
  993.             globeSpriteP->vertMoveDelta = absVertDelta;
  994.     }
  995. }
  996.