home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / Utils / SWStats.c < prev    next >
Encoding:
Text File  |  2000-10-06  |  7.6 KB  |  288 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // SWStats.c - by Vern Jensen, June 1999
  3. ///--------------------------------------------------------------------------------------
  4. #ifndef __RESOURCES__
  5. #include <Resources.h>
  6. #endif
  7. #include <SWStats.h>
  8. #include <SWCommonHeaders.h>
  9. #include <SpriteWorldUtils.h>
  10. #include <SWGameUtils.h>    // Needed for CenterRect and ResourceExists.
  11.  
  12. ///--------------------------------------------------------------------------------------
  13. // CreateStatsSpriteClone
  14. ///--------------------------------------------------------------------------------------
  15.  
  16. SpritePtr CreateStatsSpriteClone(
  17.     SpritePtr masterSpriteP,
  18.     short numDigits,
  19.     JustifyType justification,
  20.     Boolean fillWithZeros)
  21. {
  22.     StatsStructPtr    spriteStructP;
  23.     SpritePtr        newSpriteP;
  24.     OSErr            err;
  25.     
  26.     SW_ASSERT(masterSpriteP != NULL);
  27.     SW_ASSERT(masterSpriteP->maxFrames >= 10);
  28.     
  29.         // Allocate memory for the StatsStruct
  30.     spriteStructP = (StatsStructPtr)NewPtr(sizeof(StatsStruct));
  31.     err = MemError();
  32.     
  33.     if (err == noErr)
  34.     {
  35.         err = SWCloneSprite(masterSpriteP, &newSpriteP, spriteStructP);
  36.     }
  37.     
  38.     if (err == noErr)
  39.     {
  40.             // Set the Sprite's DrawProc to our special digit-drawing DrawProc.
  41.         newSpriteP->frameDrawProc = StatsItemDrawProc;
  42.         
  43.             // Adjust the Sprite's width to match the width of all the digits put together.
  44.         newSpriteP->scaledWidth = SW_RECT_WIDTH(newSpriteP->destFrameRect) * numDigits;
  45.         newSpriteP->scaledHeight = SW_RECT_HEIGHT(newSpriteP->destFrameRect);
  46.         SWSetCurrentFrameIndex(newSpriteP, newSpriteP->curFrameIndex);
  47.         
  48.         spriteStructP->numDigits = numDigits;
  49.         spriteStructP->theNum = -1;
  50.         spriteStructP->justification = justification;
  51.         spriteStructP->fillWithZeros = fillWithZeros;
  52.         spriteStructP->drawProc = SWStdWorldDrawProc;
  53.     }
  54.     else
  55.     {
  56.         newSpriteP = NULL;
  57.     }
  58.     
  59.     return newSpriteP;
  60. }
  61.  
  62.  
  63. ///--------------------------------------------------------------------------------------
  64. // SetUpStatsSprite
  65. ///--------------------------------------------------------------------------------------
  66.  
  67. OSErr SetUpStatsSprite(
  68.     SpritePtr statsSpriteP,
  69.     SpriteLayerPtr dstSpriteLayer,
  70.     DrawProcPtr drawProcP,
  71.     short horizLoc,
  72.     short vertLoc,
  73.     long theNum)
  74. {
  75.     OSErr    err = noErr;
  76.     
  77.     if (statsSpriteP == NULL)
  78.         err = -1;
  79.     
  80.     if (err == noErr)
  81.     {
  82.         SWSetSpriteLocation(statsSpriteP, horizLoc, vertLoc);
  83.         SWAddSprite(dstSpriteLayer, statsSpriteP);
  84.         SetStatsSpriteDrawProc(statsSpriteP, drawProcP);
  85.         SetStatsSpriteNumber(statsSpriteP, theNum);
  86.     }
  87.     
  88.     return err;
  89. }
  90.  
  91.  
  92. ///--------------------------------------------------------------------------------------
  93. //  DrawPictInFrame - useful for stats areas that have a background pict
  94. ///--------------------------------------------------------------------------------------
  95.  
  96. OSErr DrawPictInFrame(
  97.     FramePtr dstFrameP, 
  98.     short pictID)
  99. {
  100.     PicHandle     myPictH;
  101.     Rect        pictRect;
  102.     OSErr        err = noErr;
  103.     
  104.     SW_ASSERT(dstFrameP->isFrameLocked);
  105.  
  106.     myPictH = GetPicture(pictID);
  107.     if (myPictH == NULL)
  108.         err = ResourceExists('PICT', pictID) ? memFullErr : resNotFound;
  109.     
  110.     if (err == noErr)
  111.     {
  112.         pictRect = (**myPictH).picFrame;
  113.         SetGWorld(dstFrameP->framePort, nil);
  114.         CenterRect(&pictRect, &dstFrameP->frameRect);
  115.         
  116.         DrawPicture(myPictH, &pictRect);
  117.         ReleaseResource((Handle)myPictH);
  118.     }
  119.  
  120.     return err;
  121. }
  122.  
  123.  
  124. ///--------------------------------------------------------------------------------------
  125. //    SetStatsSpriteDrawProc
  126. ///--------------------------------------------------------------------------------------
  127.  
  128. void SetStatsSpriteDrawProc(
  129.     SpritePtr srcSpriteP,
  130.     DrawProcPtr drawProc)
  131. {
  132.     StatsStructPtr    statsStructP = (StatsStructPtr)srcSpriteP;
  133.     
  134.     statsStructP->drawProc = drawProc;
  135. }
  136.  
  137.  
  138. ///--------------------------------------------------------------------------------------
  139. //    SetStatsSpriteNumber
  140. ///--------------------------------------------------------------------------------------
  141.  
  142. void SetStatsSpriteNumber(
  143.     SpritePtr srcSpriteP,
  144.     long newNumber)
  145. {
  146.     StatsStructPtr    statsStructP = (StatsStructPtr)srcSpriteP;
  147.     
  148.     if (statsStructP->theNum != newNumber)
  149.     {
  150.         statsStructP->theNum = newNumber;
  151.         srcSpriteP->needsToBeDrawn = true;
  152.     }
  153. }
  154.  
  155.  
  156. ///--------------------------------------------------------------------------------------
  157. //    GetStatsSpriteNumber
  158. ///--------------------------------------------------------------------------------------
  159.  
  160. long GetStatsSpriteNumber(SpritePtr srcSpriteP)
  161. {
  162.     return ((StatsStructPtr)srcSpriteP)->theNum;
  163. }
  164.  
  165.  
  166. ///--------------------------------------------------------------------------------------
  167. //    StatsItemDrawProc
  168. ///--------------------------------------------------------------------------------------
  169.  
  170. SW_FUNC void StatsItemDrawProc(
  171.     FramePtr srcFrameP,
  172.     FramePtr dstFrameP,
  173.     Rect* srcRectP,
  174.     Rect* dstRectP)
  175. {
  176.     short            n, theDigit, width, index, fillValue;
  177.     long            theNum;
  178.     char            digitArray[10];            // Enough digits for a long
  179.     StatsStructPtr    statsStructP;
  180.     FramePtr        *srcFrameArray;
  181.     Rect            destRect, srcRect, frameRect, clippedDstRect;
  182.     
  183.     SW_ASSERT(gSWCurrentSpriteBeingDrawn != NULL);
  184.     
  185.     statsStructP = (StatsStructPtr)gSWCurrentSpriteBeingDrawn;
  186.     srcFrameArray = gSWCurrentSpriteBeingDrawn->frameArray;
  187.     theNum = statsStructP->theNum;
  188.  
  189.     if (statsStructP->fillWithZeros)
  190.         fillValue = 0;
  191.     else
  192.         fillValue = -1;
  193.  
  194.         // Fill the unused part of the display with either nothing or 0s.
  195.     for (n=0; n < statsStructP->numDigits; n++)
  196.         digitArray[n] = fillValue;
  197.     
  198.         // Put the number into the digitArray
  199.     if (theNum >= 0)
  200.     {
  201.         if (statsStructP->justification == kLeftJustify)
  202.             index = GetNumberLength(theNum)-1;
  203.         else
  204.             index = statsStructP->numDigits-1;
  205.  
  206.         do
  207.         {        // Fill digitArray with the digits from the new number
  208.             digitArray[index] = theNum%10;        // Get the right-most digit
  209.             index--;
  210.             theNum /= 10;                        // Remove the right-most digit
  211.         } while (theNum > 0 && index >= 0);
  212.     }
  213.     
  214.     destRect = *dstRectP;
  215.     frameRect = srcFrameArray[0]->frameRect;
  216.     width = SW_RECT_WIDTH(frameRect);
  217.     
  218.         // Expand destRect's left and top to its original size before it was clipped
  219.     if (srcRectP->top > frameRect.top)
  220.         destRect.top += frameRect.top - srcRectP->top;
  221.     if (srcRectP->left > frameRect.left)
  222.         destRect.left += frameRect.left - srcRectP->left;
  223.     
  224.         // The destRect's width and height should be the size of one digit.
  225.     destRect.bottom = destRect.top + SW_RECT_HEIGHT(frameRect);
  226.     destRect.right = destRect.left + width;
  227.  
  228.     
  229.         // Draw the number
  230.     for (index = 0; index < statsStructP->numDigits; index++)
  231.     {
  232.         theDigit = digitArray[index];
  233.         
  234.         if (theDigit >= 0)
  235.         {
  236.             srcFrameP = srcFrameArray[theDigit];
  237.             srcRect = srcFrameP->frameRect;
  238.             
  239.                 // Clip each digit with the dstRect passed to this drawProc.
  240.             clippedDstRect = destRect;
  241.             SW_CLIP_DST_AND_SRC_RECT(clippedDstRect, srcRect, (*dstRectP));
  242.             
  243.                 // Draw the digit
  244.             (*statsStructP->drawProc)(srcFrameP, dstFrameP, &srcRect, &clippedDstRect);
  245.         }
  246.         
  247.         destRect.left += width;
  248.         destRect.right += width;
  249.     }
  250. }
  251.  
  252.  
  253. ///--------------------------------------------------------------------------------------
  254. //    GetNumberLength - a pretty fast routine for getting the number of digits in a long.
  255. //    Note: if the number is negative, this doesn't count the minus symbol as a digit.
  256. ///--------------------------------------------------------------------------------------
  257.  
  258. short GetNumberLength(long theNum)
  259. {
  260.     short    length;
  261.     
  262.     if (theNum < 0)
  263.         theNum = -theNum;
  264.     
  265.     if (theNum < 10)
  266.         length = 1;
  267.     else if (theNum < 100)
  268.         length = 2;
  269.     else if (theNum < 1000)
  270.         length = 3;
  271.     else if (theNum < 10000)
  272.         length = 4;
  273.     else if (theNum < 100000)
  274.         length = 5;
  275.     else if (theNum < 1000000)
  276.         length = 6;
  277.     else if (theNum < 10000000)
  278.         length = 7;
  279.     else if (theNum < 100000000)
  280.         length = 8;
  281.     else if (theNum < 1000000000)
  282.         length = 9;
  283.     else
  284.         length = 10;
  285.     
  286.     return length;
  287. }
  288.