rnd-20100315-3-src
[rocksndiamonds.git] / src / game_sp / MainGameLoop.c
1 // ----------------------------------------------------------------------------
2 // MainGameLoop.c
3 // ----------------------------------------------------------------------------
4
5 #include "MainGameLoop.h"
6
7
8 int GameLoopRunning;
9 boolean bPlaying;
10 int LeadOutCounter, EnterRepeatCounter;
11 int ForcedExitFlag;
12 int ExitToMenuFlag;
13 int SavedGameFlag;
14 boolean UserDragFlag;
15 boolean AutoScrollFlag;
16
17
18 // ==========================================================================
19 //                              SUBROUTINE
20 // Play a game/demo
21 // ==========================================================================
22
23 void subMainGameLoop_Init()
24 {
25   if (DemoFlag != 0)
26   {
27     // EP set level success byte: demo, not game
28     WasDemoFlag = 1;
29     EP_GameDemoVar0DAA = 0; // demo
30   }
31   else // loc_g_1836:
32   {
33     // EP set level success byte: game, not demo
34     WasDemoFlag = 0;
35     EP_GameDemoVar0DAA = 1; // game
36   }
37
38   // This was a bug in the original Supaplex: sometimes red disks could not
39   // be released.  This happened if Murphy was killed DURING a red disk release
40   // and the next try started.
41
42   RedDiskReleasePhase = 0; // (re-)enable red disk release
43   UpdatedFlag = 0;
44   GameLoopRunning = 1;
45   LevelStatus = 0;
46 }
47
48 void subMainGameLoop_Main(byte action, boolean warp_mode)
49 {
50   // ---------------------------------------------------------------------------
51   // --------------------- START OF GAME-BUSY LOOP -----------------------------
52   // ---------------------------------------------------------------------------
53
54   if (EndFlag)
55   {
56     // (should never happen)
57
58     // printf("::: EndFlag == True\n");
59
60     goto locExitMainGameLoop;
61   }
62
63   subProcessKeyboardInput(action);      // check keyboard, act on keys
64
65   // ---------------------------------------------------------------------------
66   //
67
68   subDoGameStuff();                     // do all game stuff
69
70   //
71   // ---------------------------------------------------------------------------
72
73   subRedDiskReleaseExplosion();         // Red Disk release and explode
74   subFollowUpExplosions();              // every explosion may cause up to 8 following explosions
75
76   subCalculateScreenScrollPos();        // calculate screen start addrs
77
78   if ((! UserDragFlag) && AutoScrollFlag)
79     ScrollTowards(ScreenScrollXPos, ScreenScrollYPos);
80
81   if (ForcedExitFlag != 0)              // Forced Exit?' yes--exit!
82   {
83     // (should never happen)
84
85     // printf("::: ForcedExitFlag == True\n");
86
87     goto locExitMainGameLoop;
88   }
89
90   TimerVar = TimerVar + 1;
91
92 #if 1
93   if (ExitToMenuFlag == 1)
94   {
95     // happens when demo ends or when Murphy enters exit (to be checked)
96
97 #if 0
98     goto locExitMainGameLoop;
99 #endif
100   }
101 #else
102   if (ExitToMenuFlag == 1)
103     goto locExitMainGameLoop;
104 #endif
105
106   if (LeadOutCounter == 0) // no lead-out: game busy
107     return;
108
109   // ---------------------------------------------------------------------------
110   // ---------------------- END OF GAME-BUSY LOOP ------------------------------
111   // ---------------------------------------------------------------------------
112
113   LeadOutCounter = LeadOutCounter - 1;          // do more lead-out after quit
114
115   if (LeadOutCounter != 0)                      // lead-out not ready: more
116     return;
117
118   // lead-out done: exit now
119   // ---------------------- END OF GAME-BUSY LOOP (including lead-out) ---------
120
121 locExitMainGameLoop:
122
123 #if 1
124   printf("::: locExitMainGameLoop reached [%d]\n", LeadOutCounter);
125   printf("::: [KillMurphyFlag == %d]\n", KillMurphyFlag);
126 #endif
127
128 #if 1
129   /* if the game is not won when reaching this point, then it is lost */
130   if (!game_sp.LevelSolved)
131     game_sp.GameOver = TRUE;
132 #endif
133 }
134
135 void subCalculateScreenScrollPos()
136 {
137   int ax, Ay;
138
139 #if 1
140   int jump_pos = TILEX / 2;
141
142   if (MurphyScreenXPos < -jump_pos)
143   {
144     MurphyScreenXPos = FieldWidth * TILEX + MurphyScreenXPos;
145     MurphyScreenYPos -= TILEY;
146   }
147   else if (MurphyScreenXPos >= FieldWidth * TILEX - jump_pos)
148   {
149     MurphyScreenXPos = MurphyScreenXPos - FieldWidth * TILEX;
150     MurphyScreenYPos += TILEY;
151   }
152 #endif
153
154   if (ExplosionShake != 0)
155   {
156     subGetRandomNumber();
157
158     // printf("::: ExplosionShake [%d]\n", FrameCounter);
159   }
160
161   {
162     ax = MainForm.picPane.Width / 2;
163     Ay = MainForm.picPane.Height / 2;
164   }
165
166   ScreenScrollXPos = Stretch * (MurphyScreenXPos + TILEX / 2) - ax;
167   ScreenScrollYPos = Stretch * (MurphyScreenYPos + TILEY / 2) - Ay;
168 }