added several new event types that can trigger global animations
[rocksndiamonds.git] / src / game_sp / MainGameLoop.c
1 // ----------------------------------------------------------------------------
2 // MainGameLoop.c
3 // ----------------------------------------------------------------------------
4
5 #include "MainGameLoop.h"
6
7
8 boolean bPlaying;
9 int LeadOutCounter;
10 int ExitToMenuFlag;
11 boolean AutoScrollFlag;
12
13
14 // ==========================================================================
15 //                              SUBROUTINE
16 // Play a game/demo
17 // ==========================================================================
18
19 void subMainGameLoop_Init(void)
20 {
21   // This was a bug in the original Supaplex: sometimes red disks could not
22   // be released.  This happened if Murphy was killed DURING a red disk release
23   // and the next try started.
24
25   RedDiskReleasePhase = 0; // (re-)enable red disk release
26 }
27
28 void subMainGameLoop_Main(byte action, boolean warp_mode)
29 {
30   // ---------------------------------------------------------------------------
31   // --------------------- START OF GAME-BUSY LOOP -----------------------------
32   // ---------------------------------------------------------------------------
33
34   subProcessKeyboardInput(action);      // check keyboard, act on keys
35
36   // ---------------------------------------------------------------------------
37   //
38
39   subDoGameStuff();                     // do all game stuff
40
41   //
42   // ---------------------------------------------------------------------------
43
44   subRedDiskReleaseExplosion();         // Red Disk release and explode
45   subFollowUpExplosions();              // every explosion may cause up to 8 following explosions
46
47   subCalculateScreenScrollPos();        // calculate screen start addrs
48
49   if (AutoScrollFlag)
50     ScrollTowards(ScreenScrollXPos, ScreenScrollYPos);
51
52   TimerVar = TimerVar + 1;
53
54   if (ExplosionShakeMurphy > 0)
55     ExplosionShakeMurphy--;
56
57   if (ExitToMenuFlag == 1)
58   {
59     // happens when demo ends or when Murphy enters exit (to be checked)
60   }
61
62   if (LeadOutCounter == 0) // no lead-out: game busy
63     return;
64
65   // ---------------------------------------------------------------------------
66   // ---------------------- END OF GAME-BUSY LOOP ------------------------------
67   // ---------------------------------------------------------------------------
68
69   LeadOutCounter = LeadOutCounter - 1;          // do more lead-out after quit
70
71   if (LeadOutCounter != 0)                      // lead-out not ready: more
72     return;
73
74   // lead-out done: exit now
75   // ---------------------- END OF GAME-BUSY LOOP (including lead-out) ---------
76
77   // if the game is not won when reaching this point, then it is lost
78   if (!game_sp.level_solved)
79     game_sp.game_over = TRUE;
80 }
81
82 void subCalculateScreenScrollPos(void)
83 {
84   int jump_pos = TILEX / 2;
85
86   // handle wrap-around
87   if (MurphyScreenXPos < -jump_pos)
88   {
89     MurphyScreenXPos = FieldWidth * TILEX + MurphyScreenXPos;
90     MurphyScreenYPos -= TILEY;
91   }
92   else if (MurphyScreenXPos >= FieldWidth * TILEX - jump_pos)
93   {
94     MurphyScreenXPos = MurphyScreenXPos - FieldWidth * TILEX;
95     MurphyScreenYPos += TILEY;
96   }
97
98   if (ExplosionShake != 0)
99   {
100     subGetRandomNumber();
101
102     // printf("::: ExplosionShake [%d]\n", FrameCounter);
103   }
104
105   ScreenScrollXPos = MurphyScreenXPos - (SCR_FIELDX / 2) * TILESIZE;
106   ScreenScrollYPos = MurphyScreenYPos - (SCR_FIELDY / 2) * TILESIZE;
107 }