home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Developer / SAT / SAT Invaders sample ƒ / main.c < prev    next >
Encoding:
Text File  |  1994-07-26  |  8.6 KB  |  345 lines  |  [TEXT/KAHL]

  1. //• C translation from Pascal source file: main.p
  2.  
  3. //• ================================================.
  4. //• =============== SATInvaders main unit ================.
  5. //• ================================================.
  6.  
  7. //• Example file for Ingemars Sprite Animation Toolkit.
  8. //• © Ingemar Ragnemalm 1992.
  9. //• See doc files for legal terms for using this code.
  10.  
  11. //• SATInvaders is a very simple game demonstrating how to use the Sprite Animation.
  12. //• Toolkit. It is intended as a minimal demonstration, without many features and options.
  13. //• that the other sample program, HeartQuest, has. No high scores or even score, only.
  14. //• one life, doesn't save settings, only one kind of enemy, no special effects like explosions.
  15. //• etc.
  16.  
  17. //• main SATInvaders.c
  18.  
  19. #include <TransSkel.h>
  20. #include <SAT.h>
  21. #include "InvadeSAT.h"
  22. //#include "GameGlobals.h"
  23. //• SoundConst, sPlayer, sEnemy, sShot, sMissile;
  24.  
  25. // All the following is now in InvadeSAT.h
  26. //extern void        InitEnemy(void);
  27. //extern pascal void        SetupEnemy(SpritePtr sp);
  28. //extern pascal void        HandleEnemy(SpritePtr me);
  29. //extern void        InitPlayer(void);
  30. //extern pascal void        SetupPlayer(SpritePtr player);
  31. //extern pascal void        HandlePlayer(SpritePtr me);
  32.  
  33. Boolean soundFlag, plotFastFlag;
  34.  
  35. //• --------------------------------------------------------------------.
  36. //•                     Game driver procedures                                .
  37. //• --------------------------------------------------------------------.
  38.  
  39. //• Setup a new level. This is called when the game starts and at each new level.
  40. void SetUpLevel (short level)
  41. {
  42.     short i, j;
  43.     SpritePtr sp;
  44.     
  45.     //• Clear the Sprite list.
  46.     while (gSAT.sRoot) KillSprite(gSAT.sRoot);
  47.     
  48.     missileCount = 0;     //• global count variable
  49.  
  50.     //• Create all the enemy sprites for the level, depending on the level number.
  51.     for (i = 0; i <= (level + 1); i++)
  52.         for (j = 0; j <= (level / 2) + 1; j++)
  53.             sp = NewSprite (-3, i * 40 + 2, j * 40 - 40 * (level / 2 + 1), &SetupEnemy);
  54.  
  55.     //• Make the player sprite.
  56.     sp = NewSprite (2, gSAT.offSizeH / 2, gSAT.offSizeV - 40, &SetupPlayer);
  57.  
  58.     //• Copy backScreen to offScreen to erase old sprites.
  59.     CopyBits (&(gSAT.backScreen->portBits), &(gSAT.offScreen->portBits), &(gSAT.offScreen->portRect), &(gSAT.offScreen->portRect), srcCopy, 0L);
  60.     PeekOffscreen ();
  61. }     //• SetUp Level.
  62.  
  63. //• Start a new game. Initialize level, score, number of lives, and call SetUp Level to make the first level.
  64. void StartGame ()
  65. {
  66.     level = 1;
  67.     SetUpLevel (level);
  68. }
  69.  
  70. void DoFileMenu (short item)
  71. {
  72.     switch (item)
  73.     {
  74.         case run: 
  75.         {
  76.         //• Test if we have Color QD, and if so, test bit depth! Alert if ((**features).PlotFast)
  77.             if (!((gSAT.initDepth == 1) || 
  78.                   (gSAT.initDepth == 4) || 
  79.                   (gSAT.initDepth == 8)) && plotFastFlag)
  80.             {
  81.                 ReportStr ("\pPlease uncheck 'Fast animation' or set the monitor to b/w, 4-bit or 8-bit mode in the Control Panel.");
  82.                 return;
  83.             }
  84.             if (SATDepthChangeTest())     //• Update if necessary.
  85.                 ;
  86.             StartGame ();
  87.             ShowWindow (gSAT.wind);
  88.             SelectWindow (gSAT.wind);
  89.             GameWindUpdate ();
  90.             MoveIt ();
  91.         }
  92.         break;
  93.         
  94.         case sound: 
  95.         {
  96.             soundFlag = ! soundFlag;
  97.             CheckItem (fileMenu, sound, soundFlag);
  98.             if (soundFlag)     //• Tell the sound package our settings, so we don't have to bother.
  99.                 SATSoundOn();
  100.             else
  101.                 SATSoundOff();
  102.         }
  103.         break;
  104.  
  105.         case fastAnimation: 
  106.         {
  107.             plotFastFlag = ! plotFastFlag;
  108.             CheckItem (fileMenu, fastAnimation, plotFastFlag);
  109.         }
  110.         break;
  111.         
  112.         case quit: 
  113.             SkelWhoa ();
  114.         break;
  115.     }
  116. }
  117.  
  118. MoveIt ()
  119. {
  120.     long t;
  121.     EventRecord theEvent;     //• för att testa musklick.
  122.  
  123.     stillRunning = true;     
  124.  
  125.     //• Hide cursor and menu bar
  126.     //• NOTE: No matter how we leave the MoveIt procedure, we should 
  127.     //• ShowCursor and ShowMBar!
  128.     HideCursor ();
  129.     HideMBar(gSAT.wind);
  130.     PeekOffscreen();    //• We must redraw the menu bar area. I'm lazy and redraw it all.
  131.  
  132.     //• Main loop! Keep running until the game is paused or ends.
  133.     while (stillRunning == true)
  134.     {
  135.         t = TickCount ();
  136.  
  137.         //• Here is the real heart of the loop: call Animator once per loop. 
  138.         //• It will call all the objects.
  139.         RunSAT (plotFastFlag);
  140.  
  141.         //• All the rest of the main loop is game specific, next level, 
  142.         //• bonus handling, etc.
  143.         if (globalSpeed.h == 0)
  144.         {
  145.             downCount--;
  146.             if (downCount <= 0)
  147.             {
  148.                 globalSpeed.h = - last_H;
  149.                 globalSpeed.v = 0;
  150.                 turnFlag = false;
  151.             };
  152.         }
  153.         else 
  154.             if (turnFlag)
  155.             {
  156.                 downCount = 10;
  157.                 last_H = globalSpeed.h;
  158.                 globalSpeed.h = 0;
  159.                 globalSpeed.v = 3;
  160.             };
  161.         if (! gSAT.anyMonsters)
  162.         {
  163.             SATSoundShutup  ();
  164.             level++;
  165.             SetUpLevel (level);
  166.         }     //• if not anyMonsters.
  167.  
  168.         //• Check for keys being pressed - but don't allow background 
  169.         //• processing.
  170.         //• If you want background processing, either use 
  171.         //• GetNextEvent+SystemTask or WaitNextEvent (the modern call).
  172.         if (GetOSEvent (keyDownMask, &theEvent))     //• keydown.
  173.             if ((theEvent.modifiers, cmdKey) != 0)
  174.                 switch ((char)(theEvent.message, charCodeMask))
  175.                 {
  176.                     case 'q': 
  177.                     {
  178.                         SkelWhoa ();
  179.                         //• Do all the things we have to do when we 
  180.                         //• leave MoveIt!.
  181.                         SATSoundShutup ();     //• Dispose of sound channel.
  182.                         FlushEvents (everyEvent, 0);     //• To forget events, like mouse clicks etc.
  183.                         ShowCursor ();
  184.                         ShowMBar();
  185.                         return;
  186.                     }
  187.                     break;
  188.                     case 's': 
  189.                     {
  190.                         DoFileMenu (sound);
  191.                     }
  192.                     break;
  193.                     
  194.                     default:
  195.                     break;
  196.                 };     //• switch.
  197.         
  198.         //• Delay, using TickCount so it doesn't matter how fast 
  199.         //• our Mac is.
  200.         while ((TickCount () - t) < 3);
  201.  
  202.     } //while stillRunning; (main loop).
  203.  
  204.     while (! SATSoundDone() )
  205.         SATSoundEvents ();     //• Wait for last sound to complete.
  206.  
  207.     ShowCursor ();
  208.     ShowMBar();
  209.     FlushEvents (everyEvent, 0);     //• To forget Events, like mouse clicks etc.
  210.  
  211.     ReportStr ("\pSorry, game over.");
  212.  
  213.     SATSoundShutup ();     //• Dispose of sound channel.
  214. }     //• MoveIt.
  215.  
  216. GameWindUpdate ()
  217. {
  218.     Str255 s;
  219.     Rect r;
  220.     CursHandle watch;
  221.  
  222.     watch = GetCursor (watchCursor); /* WatchCursor */
  223.     SetCursor (*watch);
  224.     if (SATDepthChangeTest() )
  225.     {
  226.         ;
  227.     }
  228.     ReleaseResource ((Handle) watch);
  229. //    InitCursor ();
  230.  
  231.      PeekOffscreen ();
  232. }
  233.  
  234. //• Process selection from File menu.
  235.  
  236. void GameWindIdle ()
  237. {
  238. }
  239.  
  240. GameWindInit ()
  241. {
  242.     Boolean dummy;
  243.     
  244.     //• Tell TransSkel to tell us when to update gSAT.wind.
  245.     dummy = SkelWindow (gSAT.wind, 0L, 0L, &GameWindUpdate, 0L, 0L, 0L, &GameWindIdle, false);
  246.  
  247.     //• Set up the two offScreen GrafPorts "offScreen" and "backScreen". SAT has a standard.
  248.     //• way to do this. Let SAT draw the background PICT for us, too.
  249.  
  250.     //• Call the Init routines for all the sprite units!.
  251.     InitEnemy ();
  252.     InitPlayer ();
  253.     InitMissile ();
  254.     InitShot ();
  255.  
  256.     ShowWindow (gSAT.wind);
  257.     SelectWindow (gSAT.wind);
  258.     //• Draw the contents of the window (to give the user something to 
  259.     //• look at during the rest of startup).
  260.      PeekOffscreen ();
  261. }
  262.  
  263. //• --------------------------------------------------------------------.
  264. //•             Menu handling procedures                        .
  265. //• --------------------------------------------------------------------.
  266.  
  267. //• Handle selection of "About…" item from Apple menu.
  268.  
  269. void DoAbout ()
  270. {
  271.     short ignore;
  272.  
  273.     ignore = Alert (aboutAlrt, 0L);
  274. }
  275.  
  276. //• Initialize menus.  Tell TransSkel to process the Apple menu.
  277. //• automatically, and associate the proper procedures with the.
  278. //• File menu.
  279.  
  280. void SetUpMenus ()
  281. {
  282.     SkelApple ("\pAbout SAT Invaders…", &DoAbout);
  283.     fileMenu = GetMenu (fileMenuRes);
  284.     SkelMenu (fileMenu, &DoFileMenu, 0L, false, true);
  285.     //• Set the following flags so they match the menu.
  286.     soundFlag = true;
  287.     plotFastFlag = true;
  288. }
  289.  
  290. //• Hide gamewindow on suspend, so the user can get access to disk icons etc.
  291.  
  292. void DoSuspendResume (Boolean b)
  293. {
  294.     if (b)
  295.     {
  296.         ShowWindow (gSAT.wind);
  297.         SelectWindow (gSAT.wind);
  298.     }
  299.     else
  300.         HideWindow (gSAT.wind);
  301. }
  302.  
  303. Boolean DoEvt (EventRecord e)
  304. {
  305.     if (e.what == osEvt)
  306.     {
  307.         if (((e.message, 8), 0xFF) == suspendResumeMessage)
  308.             DoSuspendResume ((e.message, 1) != 0);
  309.         return true;
  310.     }
  311.     else
  312.         return false;
  313. }     //• end DoEvent *.
  314.  
  315. //• --------------------------------------------------------------------.
  316. //•                             Main                                .
  317. //• --------------------------------------------------------------------.
  318. main ()
  319. {
  320.     Rect    gameArea;
  321.     
  322.     SkelInit (0L, 6);                //• Initialize.
  323.  
  324.     //• Init all the different parts of the game.
  325.     SetUpMenus ();        //• install menu handlers.
  326.     
  327.     SetRect(&gameArea, 0, 0, 512, 342);
  328.     //• We use CustomInitSAT to cover the full screen INCLUDING menu bar area!
  329.     CustomInitSAT(129, 128, &gameArea, nil, nil, true, true, true, true, true);
  330. //InitSAT (129, 128, 512, 322);
  331.  
  332.     GameWindInit ();    //• Init the game window.
  333.     LoadSounds ();        //• preload all sound resources.
  334.  
  335.     //• Set the randseed to something that is random enough.
  336.     randSeed = TickCount ();
  337.  
  338.     SkelEventHook (&DoEvt); //• handle MultiFinder-Events.
  339.  
  340.     SkelMain ();                //• loop 'til Quit selected.
  341.     SkelClobber ();                //• clean up.
  342.     SATSoundShutup ();            //• Terminate sounds.
  343. }
  344.  
  345.