home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1999 Spring / macformat-077.iso / Shareware Plus / Development / SpriteWorld 2.2 Extra Demos / Brian's Demos / Lighting Demo / Lighting Demo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-14  |  21.2 KB  |  679 lines  |  [TEXT/CWIE]

  1. /*  -----------------------------------------------------------------------------------
  2.     -----------------------------------------------------------------------------------
  3.     Lighting Demo.c
  4.     
  5.     by Brian Roddy
  6.     
  7.     4/21/97
  8.  
  9.     This demo shows off the tinting and translucency functionality.  Move the cursor
  10.     to move around the light source, the blue ball.  The diamonds will bounce and 
  11.     their light level is affected by the light level of the tile they are over.  Light
  12.     fades slowly away as the light source is moved.
  13.     
  14.     Hitting the space bar will switch the sprites between being opaque and translucent.
  15.     
  16.     Note that translucency will only run properly in 256 or Thousands of colors.
  17.  
  18.     This source code is available for free use.  Crediting me would be nice, but 
  19.     isn't necessary.
  20.     ----------------------------------------------------------------------------------- 
  21.     ----------------------------------------------------------------------------------- */
  22.  
  23.  
  24. #include <SWIncludes.h>
  25. #include <SWGameUtils.h>
  26. #include <SWDitherDown.h>
  27. #include <SWFPSReport.h>
  28.  
  29. #include "SWApplication.h"
  30. #include "Tiling.h"
  31. #include "Lighting Demo.h"
  32. #include "SWTinting.h"
  33. #include "SWTranslucentBlitters.h"
  34.  
  35.  
  36. #define    kFullScreenWindow            true        // Makes the window fill the screen
  37. #define kSyncToVBL                    false        // Syncs animation to VBL
  38. #define kWorldRectInset                0            // Makes SpriteWorld smaller than window
  39. #define kMaxFPS                        0            // Set to 0 for unrestricted speed
  40.  
  41. #define kNumDiamonds                20            // Number of diamonds
  42. #define kMaxDiamondMoveDelta        5            // Max speed for the diamonds
  43.  
  44. #define kTileWidth                    32            // Don't change these unless you
  45. #define kTileHeight                    32            // change the resource as well.
  46.  
  47. //--------------------------------
  48. // For testing Translucency
  49. //--------------------------------
  50. #define kBallTranslucencyLevel        0            // Try 0-8.  0 means solid (not translucent).
  51. #define kDiamondTranslucencyLevel    0            // 1-8 specify translucent.  
  52.                                                 // Higher means more opaque.
  53. //--------------------------------
  54. #define kNumberOfTicksBeforeFade    6
  55. Boolean BigLightOn =                false;          // If this is true, the ball emanate a really big light.
  56.                                                 // Toggle with the L key.
  57.  
  58. /***********/
  59. /* Globals */
  60. /***********/
  61.  
  62. SpriteWorldPtr        gSpriteWorldP;
  63.  
  64. SpriteLayerPtr        gDiamondSpriteLayerP;
  65.     
  66. TileMapStructPtr    gTileMapStructP;
  67. SpritePtr            gBallSpriteP;
  68. WindowPtr            gWindowP;
  69.  
  70. DrawProcPtr            gSpriteDrawProc;
  71. short                gNumTileMapRows, gNumTileMapCols;
  72.  
  73.  
  74. ///--------------------------------------------------------------------------------------
  75. // Main
  76. ///--------------------------------------------------------------------------------------
  77.  
  78. void    main( void )
  79. {
  80.     Initialize(kNumberOfMoreMastersCalls);
  81.     
  82.     if (SWHasSystem7())
  83.     {
  84.         SetCursor(*GetCursor(watchCursor));
  85.         
  86.         CreateSpriteWorld();
  87.         SetUpTiling();
  88.         CreateSprites();
  89.         
  90.         SetCursor(&qd.arrow);
  91.         HideCursor();
  92.  
  93.         
  94.         SetUpAnimation();
  95.         RunAnimation();
  96.         ShutDown();
  97.     }
  98.     else
  99.     {
  100.         CantRunOnThisMachine();
  101.     }
  102. }
  103.  
  104.  
  105. ///--------------------------------------------------------------------------------------
  106. // CreateSpriteWorld
  107. ///--------------------------------------------------------------------------------------
  108.  
  109. void    CreateSpriteWorld( void )
  110. {
  111.     Rect        offscreenRect, worldRect, windRect;
  112.     RgnHandle    mBarUpdateRgn;
  113.     short        depth;
  114.     OSErr        err;
  115.     
  116.     gWindowP = GetNewCWindow(kWindowResID, NULL, (WindowPtr)-1L);
  117.     
  118.     if (gWindowP != NULL)
  119.     {
  120.         depth = GetDepthFromWindow(gWindowP);
  121.         if ( depth < 8 || depth > 16 )
  122.         {
  123.             SetCursor(&qd.arrow);
  124.             StopAlert(130, NULL);
  125.             ExitToShell();
  126.         }
  127.         
  128.         if (kFullScreenWindow == true)
  129.         {
  130.             SizeWindow(gWindowP, qd.screenBits.bounds.right, 
  131.                     qd.screenBits.bounds.bottom, false);
  132.             MoveWindow(gWindowP, 0, 0, false);
  133.         }
  134.         else
  135.         {
  136.                 // Center window in screen
  137.             windRect = gWindowP->portRect;
  138.             CenterRect(&windRect, &qd.screenBits.bounds);
  139.             MoveWindow(gWindowP, windRect.left, windRect.top, false);
  140.         }
  141.         
  142.         ShowWindow(gWindowP);
  143.         SetPort(gWindowP);
  144.         mBarUpdateRgn = SWHideMenuBar(gWindowP); // Must be done *after* showing window!
  145.         EraseRgn(mBarUpdateRgn);
  146.         
  147.     }
  148.     else
  149.         CantFindResource();
  150.     
  151.     
  152.     err = SWEnterSpriteWorld();
  153.     FatalError(err);
  154.  
  155.     
  156.     worldRect = gWindowP->portRect; 
  157.     InsetRect(&worldRect, kWorldRectInset, kWorldRectInset);
  158.     
  159.     
  160.         // Set size of offscreen area
  161.     offscreenRect = worldRect;
  162.     OffsetRect(&offscreenRect, -offscreenRect.left, -offscreenRect.top);
  163.     
  164.  
  165.         // Make offscreen area evenly divisible by tile width & height
  166.     if ( (offscreenRect.right/kTileWidth)*kTileWidth != offscreenRect.right)
  167.         offscreenRect.right = (offscreenRect.right/kTileWidth)*kTileWidth + kTileWidth;
  168.     
  169.     if ( (offscreenRect.bottom/kTileHeight)*kTileHeight != offscreenRect.bottom)
  170.         offscreenRect.bottom = (offscreenRect.bottom/kTileHeight)*kTileHeight + kTileHeight;
  171.     
  172.     
  173.     gNumTileMapRows = offscreenRect.bottom / kTileHeight;
  174.     gNumTileMapCols = offscreenRect.right / kTileWidth;
  175.     
  176.  
  177.     err = SWCreateSpriteWorldFromWindow(&gSpriteWorldP, (CWindowPtr)gWindowP, 
  178.             &worldRect, &offscreenRect, 0);
  179.     FatalError(err);
  180.     
  181.     if (gSpriteWorldP->pixelDepth == 16)
  182.             gSpriteDrawProc = BlitPixieAllBitMaskDrawProc;
  183.     else if (gSpriteWorldP->pixelDepth == 8)
  184.         gSpriteDrawProc = BlitPixie8BitMaskDrawProc;
  185.     else
  186.         gSpriteDrawProc = SWStdSpriteDrawProc;
  187. }
  188.  
  189.  
  190. ///--------------------------------------------------------------------------------------
  191. // SetUpTiling
  192. ///--------------------------------------------------------------------------------------
  193.  
  194. // We have to set aside kNumberOfBrightnessLevels number of tiles 
  195. // for each tile graphic we want to display.
  196. #define    kWallTile (kNumberOfBrightnessLevels * 0)
  197. #define    kBoardTile (kNumberOfBrightnessLevels * 1)
  198. #define    kMaxNumTiles (kNumberOfBrightnessLevels * 2)
  199.  
  200. void    SetUpTiling( void )
  201. {
  202.     short        row, col;
  203.     OSErr        err;
  204.     
  205.         // Must be done before we can load the tiles.
  206.     err = SWInitTiling(gSpriteWorldP, kTileHeight, kTileWidth, kMaxNumTiles);
  207.     FatalError(err);
  208.     
  209.     err = SWCreateTileMap(&gTileMapStructP, gNumTileMapRows, gNumTileMapCols);
  210.     FatalError(err);
  211.     
  212.     SWInstallTileMap(gSpriteWorldP, gTileMapStructP, 0);
  213.  
  214.     
  215.         // Create the wall tiles
  216.     CreateTileBrightnessSetFromCicnResource(
  217.         gSpriteWorldP,
  218.         kWallTile,            // tileID
  219.         200,                 // CICN resource ID
  220.         kNoMask);            // maskType
  221.         
  222.         // Create the board tiles
  223.     CreateTileBrightnessSetFromCicnResource(
  224.         gSpriteWorldP,
  225.         kBoardTile,            // tileID
  226.         300,                 // CICN resource ID
  227.         kNoMask);            // maskType
  228.  
  229.         // Initialize the values in the tileMap
  230.     for (row = 0; row < gNumTileMapRows; row++)
  231.     {
  232.         for (col = 0; col < gNumTileMapCols; col++)
  233.         {
  234.             if (row == 0 || col == 0 || row == gNumTileMapRows-1 || col == gNumTileMapCols-1)
  235.                 gTileMapStructP->tileMap[row][col] = kWallTile;
  236.             else
  237.                 gTileMapStructP->tileMap[row][col] = kBoardTile;
  238.         }
  239.     }
  240. }
  241.  
  242.  
  243. ///--------------------------------------------------------------------------------------
  244. // CreateSprites
  245. ///--------------------------------------------------------------------------------------
  246.  
  247. void    CreateSprites( void )
  248. {
  249.     SpritePtr            otherSpriteP;
  250.     SpritePtr            diamondSpriteP;
  251.     SpritePtr            tempSpriteP;
  252.     short                spriteNum;
  253.     Point                moveDelta, mousePoint;
  254.     Rect                moveBounds;
  255.     OSErr                err;
  256.     
  257.     
  258.         // Create the sprite layer
  259.     err = SWCreateSpriteLayer(&gDiamondSpriteLayerP);
  260.     FatalError(err);
  261.     
  262.     
  263.     moveBounds = gSpriteWorldP->backRect;
  264.     InsetRect(&moveBounds, 40, 40);
  265.     
  266.         // create and set up the diamond sprites
  267.     for (spriteNum = 0; spriteNum < kNumDiamonds; spriteNum++)
  268.     {
  269.         if (spriteNum == 0)
  270.         {
  271.             err = CreateSpriteBrightnessSetFromCicnResource (
  272.                 gSpriteWorldP,
  273.                 &diamondSpriteP, 
  274.                 NULL,        // pointer to memory for sprite
  275.                 130,         // cicn resource id
  276.                 kFatMask);    // mask type
  277.             FatalError(err);
  278.             tempSpriteP = diamondSpriteP;
  279.         }
  280.         else if (spriteNum == 1)
  281.         {
  282.             err = CreateSpriteBrightnessSetFromCicnResource (
  283.                 gSpriteWorldP,
  284.                 &otherSpriteP, 
  285.                 NULL,        // pointer to memory for sprite
  286.                 129,         // cicn resource id
  287.                 kFatMask);    // mask type
  288.             FatalError(err);
  289.             tempSpriteP = otherSpriteP;
  290.         }
  291.         else
  292.         {
  293.             err = SWCloneSprite(((spriteNum & 1) ? diamondSpriteP : otherSpriteP), &tempSpriteP, NULL);
  294.             FatalError(err);
  295.         }
  296.         
  297.  
  298.         SWSetSpriteMoveBounds(tempSpriteP, &moveBounds);
  299.         SWSetSpriteMoveProc(tempSpriteP, DiamondSpriteMoveProc);
  300.         SWSetSpriteFrameTime(tempSpriteP, 2000);
  301.         
  302.         SWSetSpriteLocation(tempSpriteP, 
  303.                 GetRandom(40, gSpriteWorldP->backRect.right-80), 
  304.                 GetRandom(40, gSpriteWorldP->backRect.bottom-80));
  305.         
  306.         do
  307.         {
  308.             moveDelta.h = GetRandom(-kMaxDiamondMoveDelta, kMaxDiamondMoveDelta);
  309.             moveDelta.v = GetRandom(-kMaxDiamondMoveDelta, kMaxDiamondMoveDelta);
  310.         } while (!moveDelta.v || !moveDelta.h);
  311.         
  312.         SWAddSprite(gDiamondSpriteLayerP, tempSpriteP);
  313.         SWSetSpriteMoveDelta(tempSpriteP, moveDelta.h, moveDelta.v);
  314.         SWSetSpriteDrawProc(tempSpriteP, gSpriteDrawProc);
  315.         SWSetSpriteTranslucencyLevel(tempSpriteP, kDiamondTranslucencyLevel);
  316.         err = SWSetSpriteTranslucencyLevel(tempSpriteP, kDiamondTranslucencyLevel);
  317.         FatalError(err);
  318.     }
  319.     
  320.     
  321.         // Create the ball sprite
  322.     //err = CreateSpriteBrightnessSetFromCicnResource(gSpriteWorldP, &gBallSpriteP, NULL, 
  323.     //        128, kFatMask);    
  324.     err = SWCreateSpriteFromCicnResource(gSpriteWorldP, &gBallSpriteP, NULL, 
  325.             500, 10, kFatMask);    
  326.     FatalError(err);
  327.     SWSetSpriteFrameAdvance(gBallSpriteP, 1);
  328.     SWSetSpriteFrameAdvanceMode(gBallSpriteP, kSWWrapAroundMode);
  329.     SWSetSpriteFrameRange(gBallSpriteP, 0, 9);
  330.     SWSetSpriteFrameTime(gBallSpriteP, 100);
  331.     
  332.     
  333.         // Set up the ball sprite
  334.     SWAddSprite(gDiamondSpriteLayerP, gBallSpriteP);
  335.     SWSetSpriteMoveProc(gBallSpriteP, MouseSpriteMoveProc);
  336.     SWSetSpriteDrawProc(gBallSpriteP, gSpriteDrawProc);
  337.     SWSetSpriteTranslucencyLevel(gBallSpriteP, kBallTranslucencyLevel);
  338.     GetMouse(&mousePoint);
  339.     SWSetSpriteLocation(gBallSpriteP, mousePoint.h - 20, mousePoint.v - 20);
  340.     
  341.     SWAddSpriteLayer(gSpriteWorldP, gDiamondSpriteLayerP);
  342.  
  343.     SWLockSpriteWorld(gSpriteWorldP);
  344. }
  345.  
  346.  
  347. ///--------------------------------------------------------------------------------------
  348. // SetUpAnimation
  349. ///--------------------------------------------------------------------------------------
  350.  
  351. void    SetUpAnimation( void )
  352. {
  353.     OSErr    err;
  354.     
  355.     SWSetSpriteWorldMaxFPS(gSpriteWorldP, kMaxFPS);
  356.     SWSyncSpriteWorldToVBL(gSpriteWorldP, kSyncToVBL);
  357.     SWSetCleanUpSpriteWorld(gSpriteWorldP);
  358.     
  359.     if (gSpriteWorldP->pixelDepth == 16)
  360.     {
  361.         err = SWCreate16BitTranslucencyTable();
  362.         FatalError(err);
  363.         SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  364.         SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixieAllBitRectDrawProc);
  365.         SWSetPartialMaskDrawProc(gSpriteWorldP, BlitPixieAllBitPartialMaskDrawProc);
  366.     } 
  367.     else
  368.     {
  369.         err = SWLoadOrCreate8BitTranslucencyTable(2);
  370.         FatalError(err);
  371.         SWSetSpriteWorldOffscreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
  372.         SWSetSpriteWorldScreenDrawProc(gSpriteWorldP, BlitPixie8BitRectDrawProc);
  373.         SWSetPartialMaskDrawProc(gSpriteWorldP, BlitPixie8BitPartialMaskDrawProc);
  374.     }
  375.  
  376.     ForeColor(blackColor);
  377.     BackColor(whiteColor);
  378.  
  379.     SWDrawTilesInBackground(gSpriteWorldP);
  380.     SWLockSpriteWorld(gSpriteWorldP);
  381.     SWUpdateSpriteWorld(gSpriteWorldP, true);
  382. }
  383.  
  384.  
  385. ///--------------------------------------------------------------------------------------
  386. //  RunAnimation
  387. ///--------------------------------------------------------------------------------------
  388.  
  389. void    RunAnimation( void )
  390. {
  391.     unsigned long        frames;
  392.     
  393.     frames = 0;
  394.     StartTimer();
  395.     
  396.     FatalError( SWStickyError() ); // Make sure no errors got past us during setup
  397.     
  398.     while (!Button())
  399.     {
  400.         SWProcessSpriteWorld(gSpriteWorldP);
  401.         FatalError( SWStickyError() );     // Make sure no errors occurred in a MoveProc, etc.
  402.         SWAnimateSpriteWorld(gSpriteWorldP);
  403.         
  404.         if (gSpriteWorldP->frameHasOccurred)
  405.             frames++;
  406.     }
  407.     
  408.     SWShowMenuBar(gWindowP);
  409.     ShowResults(frames);
  410. }
  411.  
  412.  
  413. ///--------------------------------------------------------------------------------------
  414. //  ShutDown (clean up and dispose of the SpriteWorld)
  415. ///--------------------------------------------------------------------------------------
  416.  
  417. void    ShutDown( void )
  418. {
  419.     SWUnlockSpriteWorld(gSpriteWorldP);
  420.     SWDisposeSpriteWorld(&gSpriteWorldP);
  421.     SWExitSpriteWorld();
  422.     SWDispose8BitTranslucencyTable();
  423.     SWDispose16BitTranslucencyTable();
  424.     FlushEvents(everyEvent, 0);
  425.     ShowCursor();
  426. }
  427.  
  428.  
  429. ///--------------------------------------------------------------------------------------
  430. //  RandomNumber
  431. ///--------------------------------------------------------------------------------------
  432.  
  433. // A basic random number generator
  434. short    RandomNumber(short inMax)
  435. {
  436.     short retVal = Random() * (long)inMax / 32767;
  437.     if (retVal < 0) retVal = - retVal;
  438.     return retVal;
  439. }
  440.  
  441. //-----
  442. // some globals for our ball sprite move routine
  443. unsigned long lastTickCount = 0;  // used in our fade routine, see below.
  444. int lastRow = -13;  // start these offscreen so there's no
  445. int lastCol = -13;  // drawing problems
  446.  
  447. //---- The ball sprite routine
  448. // It tracks the mouse and it lights up the area it's over.
  449. // Also checks for hitting the spacebar to change the translucency level.
  450. SW_FUNC void MouseSpriteMoveProc(SpritePtr srcSpriteP)
  451. {
  452.     Point            mousePoint;
  453.     int                row, col;
  454.  
  455.     unsigned long     curTickCount = TickCount();
  456.     EventRecord            event;
  457.     short                theChar;
  458.     
  459.         // Move the ball sprite
  460.     GetMouse(&mousePoint);
  461.     SWMoveSprite(srcSpriteP, mousePoint.h - 20, mousePoint.v - 20);
  462.     
  463.     // Every few ticks, lower the level of the light of all of the tiles.
  464.     // This gives us the slow fade effect as you move around, as well
  465.     // as the flicker of the the light source.
  466.     TickCount();
  467.     if (curTickCount - lastTickCount >= kNumberOfTicksBeforeFade) {
  468.         LowerTileBrightnessLevels(gSpriteWorldP);
  469.         lastTickCount = curTickCount;
  470.     }
  471.  
  472.     // Convert pixel row and col into tile row and col
  473.     col = mousePoint.h / gSpriteWorldP->tileWidth;
  474.     row = mousePoint.v / gSpriteWorldP->tileHeight;
  475.  
  476.     // If we have moved or if some random amount of time has passed
  477.     // we need to redraw the light.  Remember, the light is always
  478.     // fading away after time.
  479.     if ((lastCol != col) ||
  480.         (lastRow != row) ||
  481.         (RandomNumber(3) == 0)) {
  482.         
  483.         // Light up the tiles around the sprite.  Light up the center sprite and
  484.         // adjacent ones really bright, Light up the four diagonally adjacent ones
  485.         // fairly bright. 
  486.         
  487.         // Calculate the light levels
  488.         int lightLevelBorder = (kNumberOfBrightnessLevels / 2) + RandomNumber(3);
  489.         int lightLevelMiddle = lightLevelBorder; // + RandomNumber(2);
  490.         
  491.         // and light them up
  492.         SetTileBrightnessLevel(gSpriteWorldP, 0, row - 1, col - 1, lightLevelBorder, false);
  493.         SetTileBrightnessLevel(gSpriteWorldP, 0, row    , col - 1, lightLevelMiddle, false);
  494.         SetTileBrightnessLevel(gSpriteWorldP, 0, row + 1, col - 1, lightLevelBorder, false);
  495.         SetTileBrightnessLevel(gSpriteWorldP, 0, row - 1, col    , lightLevelMiddle, false);
  496.         SetTileBrightnessLevel(gSpriteWorldP, 0, row    , col    , lightLevelMiddle, false);
  497.         SetTileBrightnessLevel(gSpriteWorldP, 0, row + 1, col    , lightLevelMiddle, false);
  498.         SetTileBrightnessLevel(gSpriteWorldP, 0, row - 1, col + 1, lightLevelBorder, false);
  499.         SetTileBrightnessLevel(gSpriteWorldP, 0, row    , col + 1, lightLevelMiddle, false);
  500.         SetTileBrightnessLevel(gSpriteWorldP, 0, row + 1, col + 1, lightLevelBorder, false);
  501.  
  502.         if (BigLightOn)
  503.         {   /// If BigLightOn is true then we make a really big light that 
  504.             /// lights up a 5x5 area of tiles rather than 3x3
  505.             int lightLevelEdgeCorner = lightLevelBorder - 2;
  506.             int lightLevelEdgeNearCorner = lightLevelBorder - 1;
  507.             int lightLevelEdge = lightLevelBorder - 1;
  508.  
  509.             SetTileBrightnessLevel(gSpriteWorldP, 0, row - 2, col - 2, lightLevelEdgeCorner, false);
  510.             SetTileBrightnessLevel(gSpriteWorldP, 0, row + 2, col - 2, lightLevelEdgeCorner, false);
  511.             SetTileBrightnessLevel(gSpriteWorldP, 0, row - 2, col + 2, lightLevelEdgeCorner, false);
  512.             SetTileBrightnessLevel(gSpriteWorldP, 0, row + 2, col + 2, lightLevelEdgeCorner, false);
  513.             SetTileBrightnessLevel(gSpriteWorldP, 0, row - 1, col - 2, lightLevelEdgeNearCorner, false);
  514.             SetTileBrightnessLevel(gSpriteWorldP, 0, row    , col - 2, lightLevelEdge, false);
  515.             SetTileBrightnessLevel(gSpriteWorldP, 0, row + 1, col - 2, lightLevelEdgeNearCorner, false);
  516.             SetTileBrightnessLevel(gSpriteWorldP, 0, row - 1, col + 2, lightLevelEdgeNearCorner, false);
  517.             SetTileBrightnessLevel(gSpriteWorldP, 0, row    , col + 2, lightLevelEdge, false);
  518.             SetTileBrightnessLevel(gSpriteWorldP, 0, row + 1, col + 2, lightLevelEdgeNearCorner, false);
  519.             SetTileBrightnessLevel(gSpriteWorldP, 0, row - 2, col - 1, lightLevelEdgeNearCorner, false);
  520.             SetTileBrightnessLevel(gSpriteWorldP, 0, row - 2, col    , lightLevelEdge, false);
  521.             SetTileBrightnessLevel(gSpriteWorldP, 0, row - 2, col + 1, lightLevelEdgeNearCorner, false);
  522.             SetTileBrightnessLevel(gSpriteWorldP, 0, row + 2, col - 1, lightLevelEdgeNearCorner, false);
  523.             SetTileBrightnessLevel(gSpriteWorldP, 0, row + 2, col    , lightLevelEdge, false);
  524.             SetTileBrightnessLevel(gSpriteWorldP, 0, row + 2, col + 1, lightLevelEdgeNearCorner, false);
  525.         }
  526.         
  527.         // Light the sprite to the same level as the one it's over.
  528.         //SetSpriteBrightnessLevel(
  529.         //        srcSpriteP, 
  530.         //        GetTileBrightnessLevel(gSpriteWorldP, 0, row, col));
  531.         
  532.         // Save our current row and column so we can detect if we move.
  533.         lastRow = row;
  534.         lastCol = col;
  535.     }
  536.     
  537.         // Toggle between translucent and opaque if the spacebar was hit
  538.     while ( GetOSEvent(keyDownMask, &event) )
  539.     {
  540.         theChar = (event.message & charCodeMask);
  541.         
  542.         if ((theChar == 'l') || (theChar == 'L')) {
  543.             BigLightOn = ! BigLightOn;
  544.         }
  545.         
  546.         if ((theChar == '-') || (theChar == '_')) {
  547.             short tileRow, tileCol;
  548.  
  549.             backgroundTileMinimumLightLevel--;
  550.             if (backgroundTileMinimumLightLevel < 0) 
  551.                 backgroundTileMinimumLightLevel = 0;
  552.  
  553.             // force a redraw
  554.             for (tileRow = 0; tileRow < gSpriteWorldP->tileLayerArray[0]->numRows; tileRow++)
  555.                 for (tileCol = 0; tileCol < gSpriteWorldP->tileLayerArray[0]->numCols; tileCol++)
  556.                     SetTileBrightnessLevel(gSpriteWorldP, 0, tileRow, tileCol, 
  557.                                             backgroundTileMinimumLightLevel, false);
  558.         }
  559.         if ((theChar == '=') || (theChar == '+')) {
  560.             short tileRow, tileCol;
  561.         
  562.             backgroundTileMinimumLightLevel++;
  563.             if (backgroundTileMinimumLightLevel >= kNumberOfBrightnessLevels) 
  564.                 backgroundTileMinimumLightLevel = kNumberOfBrightnessLevels - 1;
  565.             
  566.             // force a redraw
  567.             for (tileRow = 0; tileRow < gSpriteWorldP->tileLayerArray[0]->numRows; tileRow++)
  568.                 for (tileCol = 0; tileCol < gSpriteWorldP->tileLayerArray[0]->numCols; tileCol++)
  569.                     SetTileBrightnessLevel(gSpriteWorldP, 0, tileRow, tileCol,
  570.                                             backgroundTileMinimumLightLevel, false);
  571.         }
  572.         
  573.         if (theChar == ' ')
  574.         {
  575.             SpritePtr     curSprite;
  576.             int         curLevel;
  577.             
  578.             // Increment the current translucency level (1 through kNumberOfTranslucencyLevels).
  579.             // If we go to high, wrap back down to opacity (level 0).
  580.             curLevel = SWGetSpriteTranslucencyLevel(srcSpriteP);
  581.             curLevel ++;
  582.                 
  583.                 
  584.             if (gSpriteWorldP->pixelDepth == 16) {
  585.                 if (curLevel >= kNumberOf16BitTranslucencyLevels) curLevel = 0;
  586.             } else {
  587.                 if (curLevel > gNumberOf8BitTranslucencyLevels) curLevel = 0;
  588.             }
  589.             
  590.             // Set all the diamonds to that translucency level
  591.             curSprite = gDiamondSpriteLayerP->headSpriteP;
  592.             while (curSprite != NULL) {
  593.                 SWSetSpriteTranslucencyLevel(curSprite, curLevel);
  594.                 curSprite = curSprite->nextSpriteP;
  595.             }
  596.             
  597.             // Set the ball to that translucency level
  598.             SWSetSpriteTranslucencyLevel(srcSpriteP, curLevel);
  599.                                 
  600.             // And draw our little box that says the current level.
  601.             DrawMyLevel(curLevel);
  602.         }
  603.     }
  604. }
  605.  
  606.  
  607. // A hack to draw the text that says the level of translucency
  608. void DrawMyLevel (short Number) {
  609.     GWorldPtr            oldGWld;
  610.     GDHandle            oldGDH;
  611.     Rect                tempRect;
  612.     
  613.     // Save the old state
  614.     GetGWorld( &oldGWld, &oldGDH );
  615.     
  616.     // Set the drawing port
  617.     SetGWorld(gSpriteWorldP->windowFrameP->framePort, nil);
  618.  
  619.     // Draw a green box to put the text on.
  620.     PenNormal();
  621.     ForeColor(greenColor);
  622.     tempRect.top = tempRect.left = 10;
  623.     tempRect.right = 95;
  624.     tempRect.bottom = 35;
  625.     PaintRect(&tempRect);
  626.     
  627.     // Draw the text
  628.     ForeColor(whiteColor);
  629.     BackColor(blackColor);
  630.     MoveTo(20, 30);
  631.     TextSize(9);
  632.     if (Number == 0) 
  633.         DrawString("\pOpaque");
  634.     else
  635.         DrawString("\pTranslucent");
  636.         
  637.     // And if it's translucent say how much
  638.     if (Number > 0) {
  639.         Str255         NumberString;    
  640.         NumToString(Number, NumberString);
  641.         DrawString("\p ");
  642.         DrawString(NumberString);
  643.     }
  644.     
  645.     // Restore the old state
  646.     SetGWorld( oldGWld, oldGDH );
  647. }
  648.  
  649. ///--------------------------------------------------------------------------------------
  650. //  DiamondSpriteMoveProc
  651. ///--------------------------------------------------------------------------------------
  652.  
  653. // Diamonds bounce around and set their light level based on the light level of
  654. // the tile beneath them.
  655.  
  656. SW_FUNC void    DiamondSpriteMoveProc(SpritePtr diamondSpriteP)
  657. {    
  658.     int hh, vv, row, col, tileLightLevel;
  659.     
  660.     // Move and bounce the diamond
  661.     SWOffsetSprite(diamondSpriteP, diamondSpriteP->horizMoveDelta, diamondSpriteP->vertMoveDelta);
  662.     SWBounceSprite(diamondSpriteP);
  663.     
  664.     // Find the center of the diamond
  665.     hh = diamondSpriteP->destFrameRect.left; 
  666.     vv = diamondSpriteP->destFrameRect.top;
  667.     hh += ((diamondSpriteP->destFrameRect.right - diamondSpriteP->destFrameRect.left) / 2);
  668.     vv += ((diamondSpriteP->destFrameRect.bottom - diamondSpriteP->destFrameRect.top) / 2);
  669.     
  670.     // Find the associated tile row and column
  671.     col = hh / gSpriteWorldP->tileWidth;
  672.     row = vv / gSpriteWorldP->tileHeight;
  673.     
  674.     // And set the sprite's light level to the tiles light level.
  675.     tileLightLevel = GetTileBrightnessLevel(gSpriteWorldP, 0, row, col);
  676.     SetSpriteBrightnessLevel(diamondSpriteP, tileLightLevel);
  677. }
  678.  
  679.