G4SetUpTakeDown.c

/*
    File:       G4SetUpTakeDown.c
 
    Contains:   xxx put contents here xxx
 
    Version:    xxx put version here xxx
 
    Copyright:  © 1998 by Apple Computer, Inc., all rights reserved.
 
    File Ownership:
 
        DRI:                xxx put dri here xxx
 
        Other Contact:      xxx put other contact here xxx
 
        Technology:         xxx put technology here xxx
 
    Writers:
 
        (sjb)   Steve Bollinger
 
    Change History (most recent first):
 
         <3>      7/1/98    sjb     Update to CWPro 2
*/
 
 
//============================================================================
//----------------------------------------------------------------------------
//                              SetUpTakeDown.c
//----------------------------------------------------------------------------
//============================================================================
 
// The below functions are grouped here becuase they are only called once whenÉ
// Glypha either starts up or quits.
 
#include "G4Externs.h"
#include <Palettes.h>                   // Need "Palettes.h" for the depth calls.
#include <Fonts.h>
 
#define kHandPictID             128     // These are all the resource ID's forÉ
#define kHandMaskID             129     // the various PICT's were going toÉ
#define kBackgroundPictID       130     // load up into offscreen pixmaps andÉ
#define kHelpPictID             131     // offscreen bitmaps.
#define kObeliskPictID          134
#define kPlayerPictID           135
#define kPlayerMaskID           136
#define kNumberPictID           137
#define kIdlePictID             138
#define kEnemyWalkPictID        139
#define kEnemyFlyPictID         140
#define kEnemyWalkMaskID        141
#define kEnemyFlyMaskID         142
#define kFlamePictID            143
#define kEggPictID              144
#define kEggMaskID              145
#define kPlatformPictID         146
#define kEyePictID              147
#define kEyeMaskID              148
#define kObeliskMaskPictID      149
#define kBannerPictID           150
 
 
 
Boolean DoWeHaveColor (void);           // Prototypes to below functions that areÉ
Boolean DoWeHaveSystem605 (void);       // called locally.  These aren't reallyÉ
short WhatsOurDepth (void);             // necessary, but I don't enjoy relying onÉ
Boolean CanWeDisplay8Bit (GDHandle);    // the compiler to second guess me.
void SwitchToDepth (short, Boolean);
 
void MyInitAttributes( DSpContextAttributes *inAttributes );
 
short       wasDepth;                   // Only global variable defined here.
 
#if GENERATINGPOWERPC
    DSpContextAttributes gTheContextAttributes;
    DSpContextReference gTheContext;
#endif
                                        // Other global variables defined elsewhere.
extern  Rect        mainWindowRect, backSrcRect, workSrcRect, obSrcRect, playerSrcRect;
extern  Rect        numberSrcRect, idleSrcRect, enemyWalkSrcRect, enemyFlySrcRect;
extern  Rect        obeliskRects[4], playerRects[11], numbersSrc[11], numbersDest[11];
extern  Rect        platformRects[6], touchDownRects[6], enemyRects[24], handSrcRect;
extern  Rect        flameSrcRect, flameDestRects[2], flameRects[4], platformCopyRects[9];
extern  Rect        enemyInitRects[5], eggSrcRect, platformSrcRect, helpSrcRect;
extern  Rect        handRects[2], grabZone, eyeSrcRect, bannerSrcRect, eyeRects[4];
extern  GDHandle    thisGDevice;
extern  CGrafPtr    origBackSrcMap, backSrcMap, workSrcMap, obeliskSrcMap, playerSrcMap;
extern  CGrafPtr    numberSrcMap, idleSrcMap, enemyWalkSrcMap, enemyFlySrcMap;
extern  CGrafPtr    flameSrcMap, eggSrcMap, platformSrcMap, helpSrcMap, handSrcMap;
extern  CGrafPtr    eyeSrcMap, bannerSrcMap;
extern  GrafPtr     playerMaskMap, enemyWalkMaskMap, enemyFlyMaskMap, eggMaskMap;
extern  GrafPtr     handMaskMap, eyeMaskMap, obeliskMaskMap;
extern  MenuHandle  appleMenu, gameMenu, optionsMenu;
extern  long        theScore, wasTensOfThousands;
extern  short       numLedges, beginOnLevel, levelOn, livesLeft;
extern  Boolean     quitting, playing, pausing, switchedOut, canPlay, whichList;
extern  Boolean     helpOpen, scoresOpen, openTheScores;
 
 
//==============================================================  Functions
//--------------------------------------------------------------  ToolBoxInit
 
// Here's the first function you ever call in Glypha (or any Mac program forÉ
// that matter).  The calls herein MUST be called before you do anything else.
// Otherwise, you'll get all sorts of System Errors.
 
void ToolBoxInit (void)
{
    InitGraf(&qd.thePort);      // Initialize QuickDraw variables for our program.
    InitFonts();                // Initialize fonts.
    FlushEvents(everyEvent, 0); // Clear event queue of any pending events.
    InitWindows();              // Initialize the Window Manager.
    InitMenus();                // Ditto for the Menu Manager.
    TEInit();                   // blah, blah Text Edit.
    InitDialogs(0L);            // blah, blah Dialog Manager.
    InitCursor();               // Set the cursor to the arrow cursor and init.
    
    MaxApplZone();              // Grab application memory.
    
    MoreMasters();              // Allocate a block of master pointers.
    MoreMasters();              // And allocate more.
    MoreMasters();              // And more.
    MoreMasters();              // Hey, lets do it again too.
    
    switchedOut = FALSE;        // We "should" be the foreground app at this time.
    GetDateTime((unsigned long *)&qd.randSeed);     // Randomize random seed.
}
 
//--------------------------------------------------------------  DoWeHaveColor  
 
// Simple function that returns TRUE if we're running on a Mac thatÉ
// is running Color Quickdraw.
 
Boolean DoWeHaveColor (void)
{
    SysEnvRec       thisWorld;
    
    SysEnvirons(2, &thisWorld);     // Call the old SysEnvirons() function.
    return (thisWorld.hasColorQD);  // And return whether it has Color QuickDraw.
}
 
//--------------------------------------------------------------  DoWeHaveSystem605  
 
// Another simple "environment" function.  Returns TRUE if the Mac we're runningÉ
// on has System 6.0.5 or more recent.  (6.0.5 introduced the ability to switchÉ
// color depths.)
 
Boolean DoWeHaveSystem605 (void)
{
    SysEnvRec       thisWorld;
    Boolean         haveIt;
    
    SysEnvirons(2, &thisWorld);     // Call the old SysEnvirons() function.
    if (thisWorld.systemVersion >= 0x0605)
        haveIt = TRUE;              // Check the System version for 6.0.5É
    else                            // or more recent
        haveIt = FALSE;
    return (haveIt);
}
 
//--------------------------------------------------------------  WhatsOurDepth  
 
// Function returns the current bit depth.  For example, 4 = 16 colors, 8 = 256É
// colors.  Note, this function assumes System 6.0.5 or more recent and ColorÉ
// Quickdraw capable.  You should haved called the previous two functions beforeÉ
// attempting this call.
 
short WhatsOurDepth (void)
{
    short           thisDepth;
    char            wasState;
    
    if (thisGDevice != 0L)                          // Make sure we have device handle.
    {
        wasState = HGetState((Handle)thisGDevice);  // Remember the handle's state.
        HLock((Handle)thisGDevice);                 // Lock the device handle down.
                                                    // Get it's depth (pixelSize).
        thisDepth = (**(**thisGDevice).gdPMap).pixelSize;
        HSetState((Handle)thisGDevice, wasState);   // Restore handle's state.
    }
    else
        RedAlert("\pUnknown Error.");               // Post generic error message.
    
    return (thisDepth);                             // Return screen depth.
}
 
//--------------------------------------------------------------  CanWeDisplay8Bit  
 
// Simple function that returns TRUE if the current device (monitor) isÉ
// capable of displaying 256 colors (or grays).  This function, the one above,É
// and many following functions assume we have System 6.0.5 or more recent andÉ
// are capable of Color QuickDraw.
 
Boolean CanWeDisplay8Bit (GDHandle theDevice)
{
    short       canDepth;
    Boolean     canDo;
    
    canDo = FALSE;      // Assume intially that we can't display 8 bit.
                        // Call HasDepth() to see if monitor supports 8 bit.
    canDepth = HasDepth(theDevice, 8, 1, 0);
    if (canDepth != 0)  // If HasDepth() returned anything other than 0É
        canDo = TRUE;   // we can indeed switch it to 8 bit.
    
    return (canDo);     // Return the result.
}
 
//--------------------------------------------------------------  SwitchToDepth
 
// This handy function forces the device (monitor) in question to switchÉ
// to a specific depth.  We'll call this function if we need to switch toÉ
// 8-bit (256 colors).  We should have called the above function first inÉ
// order to be sure that we CAN in fact switch this monitor to 8-bit.
 
void SwitchToDepth (short newDepth, Boolean doColor)
{
    OSErr           theErr;
    short           colorFlag;
    char            tagByte;
    
    if (doColor)                    // We can switch to either colors or grays.
        colorFlag = 1;
    else
        colorFlag = 0;
    
    if (thisGDevice != 0L)          // Make sure we have a device.
    {                               // Remember handle's state (as usual).
        tagByte = HGetState((Handle)thisGDevice);
        HLock((Handle)thisGDevice); // Lock it.
                                    // Call SetDepth() (System 6.0.5 or more recent).
        theErr = SetDepth(thisGDevice, newDepth, 1, colorFlag);
                                    // Restore handle's state.
        HSetState((Handle)thisGDevice, tagByte);
        if (theErr != noErr)        // If call failed, go to error dialog.
            RedAlert("\pUnknown Error.");
    }
    else                            // Call error dialog if no device handle.
        RedAlert("\pUnknown Error.");
}
 
//--------------------------------------------------------------  CheckEnvirons
 
// This is the "wrapper" function that calls all the above functions.
// After calling ToolBoxInit(), Glypha will call this function to seeÉ
// if the current Mac we're running on is capable of running Glypha.
 
void CheckEnvirons (void)
{   
#if GENERATINGPOWERPC
    OSStatus theError;
    
    // DSp_SetDebugMode( true );
    
    // 640x480x8
    MyInitAttributes( &gTheContextAttributes );
    gTheContextAttributes.displayWidth          = 640;
    gTheContextAttributes.displayHeight         = 480;
    gTheContextAttributes.colorNeeds            = kDSpColorNeeds_Require;
    gTheContextAttributes.backBufferDepthMask   = kDSpDepthMask_8;
    gTheContextAttributes.displayDepthMask      = kDSpDepthMask_8;
    gTheContextAttributes.backBufferBestDepth   = 8;
    gTheContextAttributes.displayBestDepth      = 8;
    gTheContextAttributes.pageCount             = 2;
    theError = DSpFindBestContext( &gTheContextAttributes, &gTheContext );
    if( theError )
        RedAlert("\pUnable to find a suitable device\n");
    
    FindOurDevice();
    gTheContextAttributes.pageCount             = 2;
    gTheContextAttributes.contextOptions        = 0 | kDSpContextOption_DontSyncVBL;
    
#else       
    if (!DoWeHaveColor())           // We absolutely need Color QuickDraw.
        RedAlert("\pGlypha IV only runs in 256 colors.");
    
    if (!DoWeHaveSystem605())       // We absolutely need System 6.0.5. or more recent.
        RedAlert("\pGlypha IV requires System 6.0.5 or better to run.");
    
    FindOurDevice();
    
    wasDepth = WhatsOurDepth();     // Find out our monitor's depth.
    if (wasDepth != 8)              // If it's not 8-bit we'll need to switch depths.
    {                               // Test 1st to see if monitor capable of 8-bit.
        if (CanWeDisplay8Bit(thisGDevice))
            SwitchToDepth(8, TRUE); // If so, switch to 256 colors.
        else                        // If not, we have to quit.
            RedAlert("\pGlypha IV only runs in 256 colors.");
    }
#endif
}
 
//--------------------------------------------------------------  OpenMainWindow
 
// This is a simple function that merely opens up a large black window andÉ
// centers it in the monitor.  It assumes a 'WIND' (window) resource, which if youÉ
// look at the resource file in ResEdit, you'll find it also has a 'WCTB'É
// (window color table) resource.  The 'WCTB' resource specifies a contentÉ
// color of black - thus this window comes up black.
 
void OpenMainWindow (void)
{
#if GENERATINGPOWERPC
    OSStatus theError;
    
    theError = DSpContext_Reserve( gTheContext, &gTheContextAttributes );
    if( theError )
        RedAlert("\pUnable to create the display!");
 
    theError = DSpContext_FadeGammaOut( NULL, NULL );   
    if( theError )
        RedAlert("\pUnable to fade the display!");
 
    theError = DSpContext_SetState( gTheContext, kDSpContextState_Active );
    if( theError )
        RedAlert("\pUnable to set the display!");
 
    // this is our fake main window, it is really a CGrafPtr so don't try to
    // use it with the Window Manager, and DON'T try to dispose of it.  In
    // a page flipping scenario, it would change with every call to SwapDisplayBuffers(),
    // but since Glypha is designed to work with DoubleBuffering we know the front
    // buffer will remain the same.
    SetRect(&mainWindowRect, 0, 0, 640, 480);           // Our window size.
    
#else
    SetRect(&mainWindowRect, 0, 0, 640, 460);           // Our window size.
    mainWindow = GetNewCWindow(128, 0L, kPutInFront);   // Load window from resource.
                                                        // Make it the right size.
    SizeWindow((GrafPtr)mainWindow, mainWindowRect.right - mainWindowRect.left, 
            mainWindowRect.bottom - mainWindowRect.top, FALSE);
                                                        // Center the window.
    MoveWindow((GrafPtr)mainWindow, (qd.screenBits.bounds.right - 640) / 2, 
            ((qd.screenBits.bounds.bottom - 480) / 2) + LMGetMBarHeight(), TRUE);
    ShowWindow((GrafPtr)mainWindow);                    // Now display it.
    SetPort((GrafPtr)mainWindow);                       // Make its port current.
    ClipRect(&mainWindowRect);                          // Set its clip region.
    CopyRgn(mainWindow->clipRgn, mainWindow->visRgn);   // Set its visRgn.
    ForeColor(blackColor);                              // Set its pen color to black.
    BackColor(whiteColor);                              // Set background color white.
#endif
}
 
//--------------------------------------------------------------  InitMenubar
 
// This function loads up the menus and displays the menu bar.
 
void InitMenubar (void)
{
    appleMenu = GetMenu(128);       // Get the Apple menu (AboutÉ).
    if (appleMenu == 0L)            // See that it loaded okay.
        RedAlert("\pCouldn't Load Menus Error");
    AppendResMenu(appleMenu, 'DRVR');   // Add Desk Accesories.
    InsertMenu(appleMenu, 0);       // Add to menu bar.
    
    gameMenu = GetMenu(129);        // Next load the Game menu.
    if (gameMenu == 0L)             // Make sure it loaded as well.
        RedAlert("\pCouldn't Load Menus Error");
    InsertMenu(gameMenu, 0);        // And add it next to the menu bar.
    
    optionsMenu = GetMenu(130);     // Finally load the Options menu.
    if (optionsMenu == 0L)
        RedAlert("\pCouldn't Load Menus Error");
    InsertMenu(optionsMenu, 0);     // And insert it.
    
    DrawMenuBar();                  // Now display the menu bar.
}
 
//--------------------------------------------------------------  InitVariables
 
// This function is called only once.  It initializes all the global variablesÉ
// used by Glypha.  It may not in fact be necessary to initialize many of theseÉ
// (your compiler should ensure that all globals are set to zero when your appÉ
// launches), but it's a good idea to NEVER TRUST YOUR COMPILER.
 
void InitVariables (void)
{
    short       i;
    OSStatus    theError;
        
    quitting = FALSE;   // I won't describe every one of these, many areÉ
    playing = FALSE;    // self explanatory.  Suffice it to say that firstÉ
    pausing = FALSE;    // I'm initializing all the Boolean variables.
    canPlay = FALSE;
    whichList = TRUE;
    helpOpen = FALSE;
    scoresOpen = FALSE;
    openTheScores = FALSE;
    
    numLedges = 3;                  // Number of ledges in the "arena".
    beginOnLevel = 1;               // First level to begin playing.
    levelOn = 0;                    // Level number player is on.
    livesLeft = kInitNumLives;      // Number of player lives.
    theScore = 0L;                  // Player's score (notice it's a long!).
    wasTensOfThousands = 0L;        // For tracking when player gets an extra life.
    GenerateLightning(320, 240);    // Initialize a lightning bolt.
    
    backSrcRect = mainWindowRect;   // Create background offscreen pixmap.
    ZeroRectCorner(&backSrcRect);
    backSrcMap = 0L;
    CreateOffScreenPixMap(&backSrcRect, &backSrcMap);
    LoadGraphic(kBackgroundPictID);
    
    origBackSrcMap = 0L;
    CreateOffScreenPixMap(&backSrcRect, &origBackSrcMap);
    LoadGraphic(kBackgroundPictID);
 
#if GENERATINGPOWERPC
    theError = DSpContext_GetBackBuffer( gTheContext, kDSpBufferKind_Normal, &workSrcMap );
    if( theError )
    {
        DSpContext_Release( gTheContext );
        RedAlert("\pUnable to get back buffer");
    }
#else   
    workSrcRect = mainWindowRect;   // Create "work" offscreen pixmap.
    ZeroRectCorner(&workSrcRect);
    workSrcMap = 0L;
    CreateOffScreenPixMap(&workSrcRect, &workSrcMap);
#endif
 
    SetRect(&obSrcRect, 0, 0, 20, 418);
    obeliskSrcMap = 0L;             // Create pixmap to hold "obelisk" graphics.
    CreateOffScreenPixMap(&obSrcRect, &obeliskSrcMap);
    LoadGraphic(kObeliskPictID);
    SetRect(&obeliskRects[0], 0, 0, 20, 209);
    OffsetRect(&obeliskRects[0], 0, 0);
    SetRect(&obeliskRects[1], 0, 0, 20, 209);
    OffsetRect(&obeliskRects[1], 0, 209);
    SetRect(&obeliskRects[2], 0, 0, 20, 209);
    OffsetRect(&obeliskRects[2], 161, 250);
    SetRect(&obeliskRects[3], 0, 0, 20, 209);
    OffsetRect(&obeliskRects[3], 457, 250);
    
    obeliskMaskMap = 0L;                // Create pixmap to hold "obelisk" mask
    CreateOffScreenBitMap(&obSrcRect, &obeliskMaskMap);
    LoadGraphic(kObeliskMaskPictID);
    
    
    SetRect(&playerSrcRect, 0, 0, 48, 436);
    playerSrcMap = 0L;              // Create pixmap to hold "player" graphics.
    CreateOffScreenPixMap(&playerSrcRect, &playerSrcMap);
    LoadGraphic(kPlayerPictID);
    playerMaskMap = 0L;
    CreateOffScreenBitMap(&playerSrcRect, &playerMaskMap);
    LoadGraphic(kPlayerMaskID);
    
    SetRect(&enemyWalkSrcRect, 0, 0, 48, 576);
    enemyWalkSrcMap = 0L;           // Create pixmap to hold "enemy" graphics.
    CreateOffScreenPixMap(&enemyWalkSrcRect, &enemyWalkSrcMap);
    LoadGraphic(kEnemyWalkPictID);
    enemyWalkMaskMap = 0L;
    CreateOffScreenBitMap(&enemyWalkSrcRect, &enemyWalkMaskMap);
    LoadGraphic(kEnemyWalkMaskID);
    SetRect(&enemyFlySrcRect, 0, 0, 64, 480);
    enemyFlySrcMap = 0L;
    CreateOffScreenPixMap(&enemyFlySrcRect, &enemyFlySrcMap);
    LoadGraphic(kEnemyFlyPictID);
    enemyFlyMaskMap = 0L;
    CreateOffScreenBitMap(&enemyFlySrcRect, &enemyFlyMaskMap);
    LoadGraphic(kEnemyFlyMaskID);
    for (i = 0; i < 12; i++)
    {                               // Set up enemy source rectangles.
        SetRect(&enemyRects[i], 0, 0, 48, 48);
        OffsetRect(&enemyRects[i], 0, 48 * i);
    }
    for (i = 0; i < 12; i++)
    {
        SetRect(&enemyRects[i + 12], 0, 0, 64, 40);
        OffsetRect(&enemyRects[i + 12], 0, 40 * i);
    }
    SetRect(&enemyInitRects[0], 0, 0, 48, 1);
    OffsetRect(&enemyInitRects[0], 72, 284);
    SetRect(&enemyInitRects[1], 0, 0, 48, 1);
    OffsetRect(&enemyInitRects[1], 520, 284);
    SetRect(&enemyInitRects[2], 0, 0, 48, 1);
    OffsetRect(&enemyInitRects[2], 72, 105);
    SetRect(&enemyInitRects[3], 0, 0, 48, 1);
    OffsetRect(&enemyInitRects[3], 520, 105);
    SetRect(&enemyInitRects[4], 0, 0, 48, 1);
    OffsetRect(&enemyInitRects[4], 296, 190);
    
    SetRect(&eggSrcRect, 0, 0, 24, 24);
    eggSrcMap = 0L;                 // Create pixmap to hold "egg" graphics.
    CreateOffScreenPixMap(&eggSrcRect, &eggSrcMap);
    LoadGraphic(kEggPictID);
    eggMaskMap = 0L;
    CreateOffScreenBitMap(&eggSrcRect, &eggMaskMap);
    LoadGraphic(kEggMaskID);
 
    bannerSrcMap = 0L;                  // Create pixmap to hold banner graphics.
    SetRect(&bannerSrcRect,0,0,1280,20);
    CreateOffScreenPixMap(&bannerSrcRect, &bannerSrcMap);
    LoadGraphic(kBannerPictID);
    
    SetRect(&eyeSrcRect, 0, 0, 48, 124);
    eyeSrcMap = 0L;                 // Create pixmap to hold "eye" graphics.
    CreateOffScreenPixMap(&eyeSrcRect, &eyeSrcMap);
    LoadGraphic(kEyePictID);
    eyeMaskMap = 0L;
    CreateOffScreenBitMap(&eyeSrcRect, &eyeMaskMap);
    LoadGraphic(kEyeMaskID);
    for (i = 0; i < 4; i++)
    {
        SetRect(&eyeRects[i], 0, 0, 48, 31);
        OffsetRect(&eyeRects[i], 0, i * 31);
    }
    
    SetRect(&handSrcRect, 0, 0, 56, 114);
    handSrcMap = 0L;                // Create pixmap to hold "mummy hand" graphics.
    CreateOffScreenPixMap(&handSrcRect, &handSrcMap);
    LoadGraphic(kHandPictID);
    handMaskMap = 0L;
    CreateOffScreenBitMap(&handSrcRect, &handMaskMap);
    LoadGraphic(kHandMaskID);
    SetRect(&handRects[0], 0, 0, 56, 57);
    OffsetRect(&handRects[0], 0, 0);
    SetRect(&handRects[1], 0, 0, 56, 57);
    OffsetRect(&handRects[1], 0, 57);
    SetRect(&grabZone, 0, 0, 96, 108);
    OffsetRect(&grabZone, 48, 352);
    
    SetRect(&idleSrcRect, 0, 0, 48, 48);
    idleSrcMap = 0L;                // Create pixmap to hold "shielded player".
    CreateOffScreenPixMap(&idleSrcRect, &idleSrcMap);
    LoadGraphic(kIdlePictID);
    
    SetRect(&flameSrcRect, 0, 0, 16, 64);
    flameSrcMap = 0L;               // Create pixmap to hold "torch" graphics.
    CreateOffScreenPixMap(&flameSrcRect, &flameSrcMap);
    LoadGraphic(kFlamePictID);
    SetRect(&flameDestRects[0], 0, 0, 16, 16);
    OffsetRect(&flameDestRects[0], 87, 325);
    SetRect(&flameDestRects[1], 0, 0, 16, 16);
    OffsetRect(&flameDestRects[1], 535, 325);
    for (i = 0; i < 4; i++)
    {
        SetRect(&flameRects[i], 0, 0, 16, 16);
        OffsetRect(&flameRects[i], 0, i * 16);
    }
    
    SetRect(&numberSrcRect, 0, 0, 8, 121);
    numberSrcMap = 0L;              // Create pixmap to hold "score numbers".
    CreateOffScreenPixMap(&numberSrcRect, &numberSrcMap);
    LoadGraphic(kNumberPictID);
    for (i = 0; i < 11; i++)
    {
        SetRect(&numbersSrc[i], 0, 0, 8, 11);
        OffsetRect(&numbersSrc[i], 0, 11 * i);
    }
    SetRect(&numbersDest[0], 0, 0, 8, 11);  // # of lives digit 1
    OffsetRect(&numbersDest[0], 229, 443);
    SetRect(&numbersDest[1], 0, 0, 8, 11);  // # of lives digit 2
    OffsetRect(&numbersDest[1], 237, 443);
    SetRect(&numbersDest[2], 0, 0, 8, 11);  // score digit 1
    OffsetRect(&numbersDest[2], 293, 443);
    SetRect(&numbersDest[3], 0, 0, 8, 11);  // score digit 2
    OffsetRect(&numbersDest[3], 301, 443);
    SetRect(&numbersDest[4], 0, 0, 8, 11);  // score digit 3
    OffsetRect(&numbersDest[4], 309, 443);
    SetRect(&numbersDest[5], 0, 0, 8, 11);  // score digit 4
    OffsetRect(&numbersDest[5], 317, 443);
    SetRect(&numbersDest[6], 0, 0, 8, 11);  // score digit 5
    OffsetRect(&numbersDest[6], 325, 443);
    SetRect(&numbersDest[7], 0, 0, 8, 11);  // score digit 6
    OffsetRect(&numbersDest[7], 333, 443);
    SetRect(&numbersDest[8], 0, 0, 8, 11);  // # of level digit 1
    OffsetRect(&numbersDest[8], 381, 443);
    SetRect(&numbersDest[9], 0, 0, 8, 11);  // # of level digit 2
    OffsetRect(&numbersDest[9], 389, 443);
    SetRect(&numbersDest[10], 0, 0, 8, 11); // # of level digit 3
    OffsetRect(&numbersDest[10], 397, 443);
    
    SetRect(&playerRects[0], 0, 0, 48, 37);
    OffsetRect(&playerRects[0], 0, 0);
    SetRect(&playerRects[1], 0, 0, 48, 37);
    OffsetRect(&playerRects[1], 0, 37);
    SetRect(&playerRects[2], 0, 0, 48, 37);
    OffsetRect(&playerRects[2], 0, 74);
    SetRect(&playerRects[3], 0, 0, 48, 37);
    OffsetRect(&playerRects[3], 0, 111);
    SetRect(&playerRects[4], 0, 0, 48, 48);
    OffsetRect(&playerRects[4], 0, 148);
    SetRect(&playerRects[5], 0, 0, 48, 48);
    OffsetRect(&playerRects[5], 0, 196);
    SetRect(&playerRects[6], 0, 0, 48, 48);
    OffsetRect(&playerRects[6], 0, 244);
    SetRect(&playerRects[7], 0, 0, 48, 48);
    OffsetRect(&playerRects[7], 0, 292);
    SetRect(&playerRects[8], 0, 0, 48, 37);     // falling bones rt.
    OffsetRect(&playerRects[8], 0, 340);
    SetRect(&playerRects[9], 0, 0, 48, 37);     // falling bones lf.
    OffsetRect(&playerRects[9], 0, 377);
    SetRect(&playerRects[10], 0, 0, 48, 22);    // pile of bones
    OffsetRect(&playerRects[10], 0, 414);
    
    SetRect(&platformSrcRect, 0, 0, 191, 192);
    platformSrcMap = 0L;    // Create pixmap to hold "platform" graphic.
    CreateOffScreenPixMap(&platformSrcRect, &platformSrcMap);
    LoadGraphic(kPlatformPictID);
    for (i = 0; i < 6; i++)
    {
        SetRect(&platformCopyRects[i], 0, 0, 191, 32);
        OffsetRect(&platformCopyRects[i], 0, 32 * i);
    }
    SetRect(&platformCopyRects[6], 233, 190, 424, 222);
    SetRect(&platformCopyRects[7], 0, 105, 191, 137);
    SetRect(&platformCopyRects[8], 449, 105, 640, 137);
                            // These are the platforms.  See diagram for numbering.
    SetRect(&platformRects[0], 206, 424, 433, 438);     //_______________
    SetRect(&platformRects[1], -256, 284, 149, 298);    //
    SetRect(&platformRects[2], 490, 284, 896, 298);     //--3--     --4--
    SetRect(&platformRects[3], -256, 105, 149, 119);    //     --5--
    SetRect(&platformRects[4], 490, 105, 896, 119);     //--1--     --2--
    SetRect(&platformRects[5], 233, 190, 407, 204);     //_____--0--_____
    
    for (i = 0; i < 6; i++)
    {                       // "Hot rects" to sense if player landing on platform.
        touchDownRects[i] = platformRects[i];
        touchDownRects[i].left += 23;
        touchDownRects[i].right -= 23;
        touchDownRects[i].bottom = touchDownRects[i].top;
        touchDownRects[i].top = touchDownRects[i].bottom - 11;
    }
    
    SetRect(&helpSrcRect, 0, 0, 231, 398);
    helpSrcMap = 0L;        // Create pixmap to hold "help screen" graphic.
    CreateOffScreenPixMap(&helpSrcRect, &helpSrcMap);
    LoadGraphic(kHelpPictID);
 
}
 
//--------------------------------------------------------------  ShutItDown
 
#define kFadeSteps      25
#define kFadeStepSize   (100/kFadeSteps)
 
void ShutItDown (void)
{
#if GENERATINGPOWERPC
    unsigned long theFinalTick;
    
    DSpContext_FadeGammaOut( NULL, NULL );
    DSpContext_SetState( gTheContext, kDSpContextState_Inactive );
    
    Delay( 30, &theFinalTick );
 
    DSpContext_FadeGammaIn( NULL, NULL );
    
    DSpContext_Release( gTheContext );
    DSpShutdown();
    
#else
    if (wasDepth != WhatsOurDepth())    // Need only switch if wasn't 8-bit.
        SwitchToDepth(wasDepth, TRUE);  // Switch back to out "old" depth.
#endif
}
 
/*
********************************************************************************
**
** Name: MyInitAttributes
**
** Description:
**
**  Initialize a context attributes structure so that there is no garbage
**  data in it.  This is important to do because DS will return an error
**  if some fields are set incorrectly (including the "reserved" fields not
**  being set to zero), and some things can actually cause a crash (such
**  as a bogus color table handle).
**
********************************************************************************
*/
void
MyInitAttributes(
    DSpContextAttributes *inAttributes      /* attr structure to init */
)
{
    if( NULL == inAttributes )
        DebugStr("\pStimpy! You Idiot!");
        
    inAttributes->frequency                 = 0;
    inAttributes->displayWidth              = 0;
    inAttributes->displayHeight             = 0;
    inAttributes->reserved1                 = 0;
    inAttributes->reserved2                 = 0;
    inAttributes->colorNeeds                = 0;
    inAttributes->colorTable                = NULL;
    inAttributes->contextOptions            = 0;
    inAttributes->backBufferDepthMask       = 0;
    inAttributes->displayDepthMask          = 0;
    inAttributes->backBufferBestDepth       = 0;
    inAttributes->displayBestDepth          = 0;
    inAttributes->pageCount                 = 0;
    inAttributes->gameMustConfirmSwitch     = false;
    inAttributes->reserved3[0]              = 0;
    inAttributes->reserved3[1]              = 0;
    inAttributes->reserved3[2]              = 0;
    inAttributes->reserved3[3]              = 0;
}