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 Examples / Shark Attack / Sources & Headers / Application.c next >
Encoding:
C/C++ Source or Header  |  2000-10-06  |  13.6 KB  |  600 lines  |  [TEXT/CWIE]

  1. ///--------------------------------------------------------------------------------------
  2. // Application.c
  3. ///--------------------------------------------------------------------------------------
  4. #ifndef __RESOURCES__
  5. #include <Resources.h>
  6. #endif
  7.  
  8. #ifndef __DEVICES__
  9. #include <Devices.h>
  10. #endif
  11.  
  12. #ifndef __TOOLUTILS__
  13. #include <ToolUtils.h>
  14. #endif
  15.  
  16. #include <Palettes.h>
  17. #include <Menus.h>
  18. #include <SWIncludes.h>
  19. #include <SWGameUtils.h>
  20. #include <SWApplication.h>
  21.  
  22. #include "Application.h"
  23. #include "Shark Attack.h"
  24. #include "NewSprite.h"
  25. #include "Level.h"
  26. #include "SWSounds.h"
  27. #include "MyUtils.h"
  28. #include "Stats.h"
  29. #include "Special Effects.h"
  30. #include "GlobalVariables.h"
  31.  
  32. #ifndef checkMark
  33. #define checkMark    '\022'
  34. #endif
  35.  
  36. #define        kMaxNumFishOnTitleScreen        4
  37.  
  38.  
  39. CTabHandle    gSavedEntriesH;
  40.  
  41.  
  42. ///--------------------------------------------------------------------------------------
  43. // Main
  44. ///--------------------------------------------------------------------------------------
  45.  
  46. void    main( void )
  47. {
  48.     OSErr     err;
  49.     short    resRefNum;
  50.     
  51.     Initialize(kNumberOfMoreMastersCalls);
  52.     Randomize();
  53.     
  54.     if (SWHasSystem7())
  55.     {
  56.         gTempRgn = NewRgn();    // Create temp region
  57.         AllowKeyUpEvents();
  58.         SetCursor(*GetCursor(watchCursor));
  59.         HideControlStrip();
  60.         
  61.         SWSetCleanUpFunction(MyCleanUpFunction);
  62.         
  63.         if ( !IsNewSoundManagerInstalled() )
  64.         {
  65.             SetCursor(&qd.arrow);
  66.             StopAlert(130, NULL);
  67.             ExitToShell();
  68.         }
  69.         
  70.         SaveSystemVolume();
  71.         
  72.         err = CreateSoundChannels(4);
  73.         FatalError(err);
  74.         err = LoadSounds(128, kNumSounds);
  75.         FatalError(err);
  76.         
  77.             // Open the Shark Attack Graphics file.
  78.         resRefNum = OpenResFile("\pShark Attack Graphics");
  79.         if (ResError() != noErr)
  80.         {
  81.             SetCursor(&qd.arrow);
  82.             StopAlert(131, NULL);
  83.             ExitToShell();
  84.         }
  85.         
  86.         CreateWindow();
  87.         LoadPixPats();
  88.         SetUpSpriteWorld();
  89.         InitStats();
  90.         SetUpWindowRegions();
  91.         LoadSprites();
  92.         
  93.         CreateMenuBar();
  94.         SetupTitleScreen();
  95.         SetCursor(&qd.arrow);
  96.         
  97.         while (1)
  98.         {
  99.             ProcessEvents();
  100.             AnimateTitleScreen();
  101.         }
  102.     }
  103.     else
  104.     {
  105.         CantRunOnThisMachine();
  106.     }
  107. }
  108.  
  109.  
  110. ///--------------------------------------------------------------------------------------
  111. // ExitSharkAttack    - Clean up and quit
  112. ///--------------------------------------------------------------------------------------
  113.  
  114. void     ExitSharkAttack( void )
  115. {
  116.     // We don't even bother disposing this stuff, since the system will
  117.     // clean it up anyway. They are commented out so you can see what would
  118.     // need to be done if you did want to dispose everything yourself.
  119.  
  120. /*        
  121.     SWDisposeSpriteWorld(&gSpriteWorldP);
  122.     SWExitSpriteWorld();
  123.     SWDisposeWindowFrame(&gStatsWindowFrameP);
  124.     SWDisposeFrame(&gStatsBackFrameP);
  125.     SWDisposeFrame(&gStatsNumberFrameP);
  126.     DisposeSprites();    // This would dispose the master sprites not included in the SpriteWorld
  127.     DisposeSounds();
  128.     DisposeRgn(gTempRgn);
  129.     
  130.     DisposePixPat(gBackgroundPixPatH);
  131.     DisposePixPat(gTitleWaterPixPatH);
  132.     ReleaseResource((Handle)gGameWaterPictH);
  133. */
  134.  
  135.     DisposeSoundChannels();
  136.     SWShowMenuBar(gWindowP);
  137.     RestoreControlStrip();
  138.     RestoreEventMask();
  139.     
  140.         // By hiding the window before quitting, we can avoid the brief discoloration
  141.         // of the window caused when switching back to the system palette. Also, by
  142.         // restoring the system palette ourselves, we can do it faster than ExitToShell.
  143.     HideWindow(gWindowP);
  144.     RestoreSystemPalette();
  145.     
  146.     RestoreSystemVolume();
  147.     
  148.     ExitToShell();
  149. }
  150.  
  151.  
  152. ///--------------------------------------------------------------------------------------
  153. //  MyCleanUpFunction - called if an error occurs, to clean up before quitting
  154. ///--------------------------------------------------------------------------------------
  155.  
  156. void    MyCleanUpFunction( void )
  157. {
  158.     SWShowMenuBar(gWindowP);
  159.     
  160.     RestoreControlStrip();
  161.     RestoreEventMask();    
  162. }
  163.  
  164.  
  165. ///--------------------------------------------------------------------------------------
  166. // CreateMenuBar
  167. ///--------------------------------------------------------------------------------------
  168.  
  169. void    CreateMenuBar()
  170. {
  171.     Handle menuBarH;
  172.  
  173.     menuBarH = GetNewMBar(128);
  174.  
  175.     if (menuBarH != NULL)
  176.     {
  177.         SetMenuBar(menuBarH);
  178.         AppendResMenu(GetMenuHandle(mApple), 'DRVR');
  179.         DrawMenuBar();
  180.     }
  181.     else
  182.     {
  183.         CantFindResource();
  184.     }
  185.     
  186.     UpdateVolumeMenu();
  187. }
  188.  
  189.  
  190. ///--------------------------------------------------------------------------------------
  191. // CreateWindow
  192. ///--------------------------------------------------------------------------------------
  193.  
  194. void     CreateWindow( void )
  195. {
  196.     gWindowP = GetNewCWindow(128, NULL, (WindowPtr)-1L);
  197.  
  198.     if (gWindowP != NULL)
  199.     {
  200.         SizeWindow(gWindowP, qd.screenBits.bounds.right, 
  201.                         qd.screenBits.bounds.bottom, false);
  202.         MoveWindow(gWindowP, 0, 0, false);
  203.         ShowWindow(gWindowP);
  204.         
  205.         SetPort(gWindowP);
  206.         ForeColor(blackColor);
  207.         BackColor(whiteColor);
  208.     }
  209.     else
  210.         CantFindResource();
  211. }
  212.  
  213.  
  214. ///--------------------------------------------------------------------------------------
  215. // LoadPixPats
  216. ///--------------------------------------------------------------------------------------
  217.  
  218. void     LoadPixPats( void )
  219. {
  220.     gBackgroundPixPatH = GetPixPat(128);
  221.     if (gBackgroundPixPatH == NULL)
  222.         CantFindResource();
  223.     
  224.     gTitleWaterPixPatH = GetPixPat(129);
  225.     if (gTitleWaterPixPatH == NULL)
  226.         CantFindResource();
  227.     
  228.     gGameWaterPictH = GetPicture(129);
  229.     if (gGameWaterPictH == NULL)
  230.         CantFindResource();
  231. }
  232.  
  233.  
  234. ///--------------------------------------------------------------------------------------
  235. // SetUpWindowRegions - calculate the gOrigWindRgn and gPixPatWindRgn
  236. ///--------------------------------------------------------------------------------------
  237.  
  238. void     SetUpWindowRegions( void )
  239. {
  240.     Rect    windRect;
  241.     
  242.     SetPort(gWindowP);
  243.     
  244.     gOrigWindRgn = NewRgn();
  245.     gPixPatWindRgn = NewRgn();
  246.     GetClip(gOrigWindRgn);
  247.     GetClip(gPixPatWindRgn);
  248.     
  249.         // Subtract the SpriteWorld's windRect from the gPixPatWindRgn
  250.     windRect = gSpriteWorldP->windRect;
  251.     RectRgn(gPixPatWindRgn, &windRect);
  252.     DiffRgn(gOrigWindRgn, gPixPatWindRgn, gPixPatWindRgn);
  253. }
  254.  
  255.  
  256. ///--------------------------------------------------------------------------------------
  257. // ProcessEvents
  258. ///--------------------------------------------------------------------------------------
  259.  
  260. void    ProcessEvents( void )
  261. {
  262.     EventRecord        event;
  263.     
  264.     if ( WaitNextEvent(everyEvent, &event, kSleep, nil) )
  265.     {
  266.         switch ( event.what )
  267.         {
  268.             case mouseDown:
  269.                 HandleMouseDown( &event );
  270.                 break;
  271.             case keyDown:
  272.                 if ( (event.modifiers & cmdKey) != 0 )
  273.                 {
  274.                     HandleMenuChoice( MenuKey(event.message & charCodeMask) );
  275.                     break;
  276.                 }
  277.             case keyUp:
  278.                 ProcessKeyEvent(&event);    // This function is in Shark Attack.c
  279.                 break;
  280.             case updateEvt:
  281.                 UpdateWindow(&event);
  282.                 break; 
  283.             case osEvt:
  284.                 if ( event.message >> 24 == mouseMovedMessage )
  285.                 {
  286.                     // Mouse-moved event
  287.                 }
  288.                 else if ( event.message >> 24 == suspendResumeMessage )
  289.                 {
  290.                     if ( event.message & resumeFlag )
  291.                     {
  292.                             // Resume
  293.                         ShowWindow(gWindowP);
  294.                     }
  295.                     else
  296.                     {
  297.                             // Suspend
  298.                         HideWindow(gWindowP);
  299.                         RestoreSystemPalette();
  300.                     }
  301.                 }
  302.                 break;
  303.         }
  304.     }
  305. }
  306.  
  307.  
  308. ///--------------------------------------------------------------------------------------
  309. // SetupTitleScreen
  310. ///--------------------------------------------------------------------------------------
  311.  
  312. void    SetupTitleScreen( void )
  313. {
  314.     gGameIsPaused = false;
  315.     
  316.         // Add the "Shark Attack" text to the SpriteWorld
  317.     AddTitleSprite();
  318.     
  319.         // Don't copy to the screen, because we'll get an updateEvent to do that
  320.     SWUpdateSpriteWorld(gSpriteWorldP, false);
  321.     ShowWindow(gWindowP);
  322. }
  323.  
  324.  
  325. ///--------------------------------------------------------------------------------------
  326. // AnimateTitleScreen
  327. ///--------------------------------------------------------------------------------------
  328.  
  329. void    AnimateTitleScreen( void )
  330. {
  331.     SWProcessSpriteWorld(gSpriteWorldP);
  332.     SWAnimateSpriteWorld(gSpriteWorldP);
  333.     
  334.         // Add fish periodically
  335.     if (gSpriteWorldP->frameHasOccurred)
  336.     {
  337.         if (gNumFishOnScreen < kMaxNumFishOnTitleScreen)
  338.         {
  339.             if (gFishDelay > 0)
  340.             {
  341.                 gFishDelay--;
  342.             }
  343.             else if (GetRandom(0, kFishRandomness) == 0)
  344.             {
  345.                 gFishDelay = kMinNewFishDelay;
  346.                 AddFish();
  347.             }
  348.         }
  349.     }
  350. }
  351.  
  352.  
  353. ///--------------------------------------------------------------------------------------
  354. // HandleMouseDown
  355. ///--------------------------------------------------------------------------------------
  356.  
  357. void    HandleMouseDown( EventRecord *eventPtr )
  358. {
  359.     WindowPtr        whichWindow;
  360.     short int        thePart;
  361.     long            menuChoice;
  362.     
  363.     thePart = FindWindow(eventPtr->where, &whichWindow);
  364.     
  365.     switch (thePart)
  366.     {
  367.         case inMenuBar:
  368.             menuChoice = MenuSelect(eventPtr->where);
  369.             HandleMenuChoice(menuChoice);
  370.             break;
  371.         case inSysWindow:
  372.             SystemClick(eventPtr, whichWindow);
  373.             break;
  374.     }
  375. }
  376.  
  377.  
  378. ///--------------------------------------------------------------------------------------
  379. // UpdateWindow
  380. ///--------------------------------------------------------------------------------------
  381.  
  382. void    UpdateWindow( EventRecord *eventPtr )
  383. {
  384.     if ( (WindowPtr)eventPtr->message == gWindowP )
  385.     {
  386.         BeginUpdate(gWindowP);
  387.         SetPort(gWindowP);
  388.         
  389.             // Draw the background pattern
  390.         SetClip(gPixPatWindRgn);
  391.         FillCRect(&gWindowP->portRect, gBackgroundPixPatH);
  392.         SetClip(gOrigWindRgn);
  393.         
  394.             // Update the SpriteWorld's worldRect
  395.         SWUpdateWindow(gSpriteWorldP);
  396.         
  397.             // Update stats area if a game is paused
  398.         if (gGameIsPaused)
  399.             UpdateStatsArea();
  400.         
  401.         EndUpdate(gWindowP);
  402.     }
  403. }
  404.  
  405.  
  406. ///--------------------------------------------------------------------------------------
  407. // HandleMenuChoice
  408. ///--------------------------------------------------------------------------------------
  409.  
  410. void    HandleMenuChoice( long menuChoice )
  411. {
  412.     short    menu;
  413.     short    item;
  414.     
  415.     if ( menuChoice != 0 )
  416.     {
  417.         menu = HiWord( menuChoice );
  418.         item = LoWord( menuChoice );
  419.         
  420.         switch ( menu )
  421.         {
  422.             case mApple:
  423.                 HandleAppleChoice( item );
  424.                 break;
  425.             case mFile:
  426.                 HandleFileChoice( item );
  427.                 break;
  428.             case mVolume:
  429.                 HandleVolumeChoice( item);
  430.                 break;
  431.         }
  432.         HiliteMenu( 0 );
  433.     }
  434. }
  435.  
  436.  
  437. ///--------------------------------------------------------------------------------------
  438. // HandleAppleChoice
  439. ///--------------------------------------------------------------------------------------
  440.  
  441. void    HandleAppleChoice( short item )
  442. {
  443.     MenuHandle    appleMenu;
  444.     Str255        accName;
  445.     short        accNumber;
  446.     OSErr        err;
  447.     
  448.     switch ( item )
  449.     {
  450.         case iAbout:
  451.             err = DoAboutBox();
  452.             FatalError(err);
  453.             break;
  454.         default:
  455.             appleMenu = GetMenuHandle(mApple);
  456.             GetMenuItemText(appleMenu, item, accName);
  457.             accNumber = OpenDeskAcc(accName);
  458.             break;
  459.     }
  460. }
  461.  
  462.  
  463. ///--------------------------------------------------------------------------------------
  464. // HandleFileChoice
  465. ///--------------------------------------------------------------------------------------
  466.  
  467. void    HandleFileChoice(short item)
  468. {
  469.     Boolean        stereoIsOn;
  470.     short        markChar;
  471.     
  472.     switch ( item )
  473.     {
  474.         case iNewGame:
  475.             NewGame();
  476.             break;
  477.         case iEndGame:
  478.             gGameOver = true;
  479.             gGameIsPaused = false;
  480.             break;
  481.         case iStereoSound:
  482.             GetItemMark(GetMenuHandle(mFile), iStereoSound, &markChar);
  483.             stereoIsOn = (markChar != checkMark);
  484.             CheckItem(GetMenuHandle(mFile), iStereoSound, stereoIsOn);
  485.             SetStereoMode(stereoIsOn);
  486.             break;
  487.         case iPauseGame:
  488.             gGameIsPaused = false;
  489.             break;
  490.         case iQuit:
  491.             ExitSharkAttack();
  492.             break;
  493.     }
  494. }
  495.  
  496.  
  497. ///--------------------------------------------------------------------------------------
  498. // HandleVolumeChoice
  499. ///--------------------------------------------------------------------------------------
  500.  
  501. void    HandleVolumeChoice(short menuItem)
  502. {
  503.     SetSystemVolume(menuItem-1);
  504.     PlaySound(kHitFishSnd, 2, kReplaceSameSound);
  505.     UpdateVolumeMenu();
  506. }
  507.  
  508.  
  509. ///--------------------------------------------------------------------------------------
  510. // UpdateVolumeMenu - place the check mark by the appropriate item
  511. ///--------------------------------------------------------------------------------------
  512.  
  513. void    UpdateVolumeMenu( void )
  514. {
  515.     short    volume, menuItem, n;
  516.     
  517.         // Get the current system volume
  518.     GetSystemVolume(&volume);
  519.     menuItem = volume+1;
  520.     
  521.         // Place the check by the corresponding item
  522.     for (n = 0; n <= 8; n++)
  523.         CheckItem(GetMenuHandle(mVolume), n, (menuItem == n) );
  524. }
  525.  
  526.  
  527. ///--------------------------------------------------------------------------------------
  528. // DoAboutBox
  529. ///--------------------------------------------------------------------------------------
  530.  
  531. OSErr    DoAboutBox(void)
  532. {
  533.     PicHandle     aboutPictH;
  534.     WindowPtr    aboutWindP;
  535.     OSErr        err = noErr;
  536.     
  537.     aboutPictH = GetPicture(kAboutPictResID);
  538.     if (aboutPictH == NULL)
  539.         err = ResError() ? ResError() : resNotFound;
  540.  
  541.     if (err == noErr)
  542.     {
  543.         aboutWindP = GetNewCWindow(kAboutWindResID, NULL, (WindowPtr)-1L);
  544.         if (aboutWindP == NULL)
  545.             err = ResError() ? ResError() : resNotFound;
  546.     }
  547.     
  548.     if (err == noErr)
  549.     {
  550.         PlaySound(kFishDeadSnd, 2, kFindEmptyChannel);
  551.             
  552.         SetWindowPic(aboutWindP, aboutPictH);
  553.         ShowWindow(aboutWindP);
  554.         
  555.         AboutBoxEventLoop();
  556.         
  557.             // First we clear the picture from the window
  558.         SetWindowPic(aboutWindP, NULL);
  559.             // Then we dispose it through the resource manager
  560.         ReleaseResource((Handle)aboutPictH);
  561.             // Finally we can dispose the window with no effect on the windowPic
  562.         DisposeWindow(aboutWindP);
  563.     }
  564.     
  565.     return err;
  566. }
  567.  
  568.  
  569. ///--------------------------------------------------------------------------------------
  570. // AboutBoxEventLoop
  571. ///--------------------------------------------------------------------------------------
  572.  
  573. void    AboutBoxEventLoop( void )
  574. {
  575.     EventRecord        event;
  576.     Boolean            done = false;
  577.     
  578.     do
  579.     {
  580.         if ( WaitNextEvent(everyEvent, &event, kSleep, nil) )
  581.         {
  582.             switch ( event.what )
  583.             {
  584.                 case mouseDown:
  585.                     done = true;
  586.                     break;
  587.                 case updateEvt:                // Update the window behind the About Box.
  588.                     UpdateWindow(&event);    // The About Box will update automatically,
  589.                     break;                     // since it has a windowPic installed.
  590.             }
  591.         }
  592.         else
  593.         {
  594.             if (!gGameIsPaused)        // Run animation if the game hasn't started yet
  595.                 AnimateTitleScreen();
  596.         }
  597.     } while (!done);
  598. }
  599.  
  600.