1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
5 #include "MainGameLoop.h"
7 // static char *VB_Name = "modMainGameLoop";
13 int LeadOutCounter, EnterRepeatCounter;
18 boolean AutoScrollFlag;
20 // ==========================================================================
23 // ==========================================================================
32 TickCountObject Clock;
39 printf("::: playing demo ...\n");
42 // EP set level success byte: demo, not game
44 EP_GameDemoVar0DAA = 0; // demo
49 printf("::: playing game ...\n");
52 // EP set level success byte: game, not demo
54 EP_GameDemoVar0DAA = 1; // game
58 // If RecordDemoFlag = 1 Then
59 // RecordDemoFlag = 0 ' clear Demo Recording flag
60 // Call subDisplayPlayingTime ' playing time on screen
61 // ' Record key still pressed?' >= (Ctrl-)F1 and <= (Ctrl-)F10
62 // While &H3B <= KeyScanCode7 And KeyScanCode7 <= &H44
63 // ' yes -> wait until released
64 // ' should we DoEvents here???? ... depends on how ... but yes!
65 // ' ...or we can rather poll the keyboardstate inside this loop???
67 // Call subInitGameConditions ' Init game conditions (vars)
68 // If MusicOnFlag = 0 Then Call subMusicInit
69 // WasDemoFlag = 0 ' no demo anymore
70 // EP_GameDemoVar0DAA = 1 ' force game
73 // This was a bug in the original Supaplex: sometimes red disks could not
74 // be released. This happened If Murphy was killed DURING a red disk release
75 // and the next try started.
77 RedDiskReleasePhase = 0; // (re-)enable red disk release
82 // ----------------------------------------------------------------------------
83 // --------------------- START OF GAME-BUSY LOOP ------------------------------
84 // ----------------------------------------------------------------------------
86 locRepeatMainGameLoop: // start repeating game loop
88 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
90 while (PauseMode != 0)
97 DoEvents(); // user may klick on menus or move the window here ...
102 while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
105 // never any additional code between here!
107 LastFrame = Clock.TickNow(); // store the frame time
109 // never any additional code between here!
110 if (! NoDisplayFlag) // copy the BackBuffer(=Stage) to visible screen
113 // FS end of synchronization
114 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
116 goto locExitMainGameLoop;
118 // If DemoFlag = 0 Then Call subCheckJoystick ' check joystick
119 // bx = subCheckRightMouseButton() ' check (right) mouse button
120 // If bx = 2 And LeadOutCounter < 1 Then KillMurphyFlag = 1 ' lead-out busy after quit? -> kill Murphy!
122 // If DebugVersionFlag <> 0 Then ' debug mode on?
123 // If Data_SubRest <> 0 Then Data_SubRest = Data_SubRest - 1
124 // If keyEnter <> 0 Then GoTo loc_g_186F ' Was it the Enter key? -> yes--skip! No mouse!
125 // ' fixes ENTER bug If no mouse driver!
126 // If bx <> 1 Then GoTo loc_g_186F ' Left button=Init game field
127 // ' Also Enter If no mouse!
128 // If Data_SubRest <> 0 Then GoTo loc_g_186F
130 // Call subRestoreFancy
131 // Call subDisplayLevel ' Paint (Init) game field
132 // Call subConvertToEasySymbols ' Convert to easy symbols
137 subProcessKeyboardInput(); // Check keyboard, act on keys
140 // TimerVar = TimerVar + 1
144 // If RecordDemoFlag = 1 Then GoTo RestartGameLoop
146 // ----------------------------------------------------------------------------
150 printf("::: >>>>>>>>>> MainGameLoop.c: subDoGameStuff() START\n");
153 subDoGameStuff(); // do all game stuff
156 printf("::: <<<<<<<<<< MainGameLoop.c: subDoGameStuff() END\n");
160 // ----------------------------------------------------------------------------
162 // Call subDisplayPlayingTime ' playing time on screen
164 subCheckRestoreRedDiskCountDisplay(); // Restore panel: red-disk hole
166 subRedDiskReleaseExplosion(); // Red Disk release and explode
167 subFollowUpExplosions(); // every explosion may cause up to 8 following explosions
169 bx = subCalculateScreenScrollPos(); // calculate screen start addrs
173 // Now new X and new Y are calculated, and bx = screen position = ScreenPosition
174 data_h_Ytmp = ScreenScrollYPos; // copy Y for next soft scroll
175 data_h_Xtmp = ScreenScrollXPos; // copy X for next soft scroll
176 if ((! UserDragFlag) && AutoScrollFlag)
179 printf("::: MainGameLoop.c: subMainGameLoop(): %d, %d\n", ScreenScrollXPos, ScreenScrollYPos);
182 ScrollTowards(ScreenScrollXPos, ScreenScrollYPos);
185 if (ForcedExitFlag != 0) // Forced Exit?' yes--exit!
186 goto locExitMainGameLoop;
188 TimerVar = TimerVar + 1;
192 MainForm.SaveSnapshot(TimerVar);
195 // If Not NoDisplayFlag Then
196 // With MainForm.lblFrameCount
197 // .Caption = TimerVar
201 if (ExitToMenuFlag == 1)
202 goto locExitMainGameLoop;
204 if (LeadOutCounter == 0) // no lead-out: game busy
205 goto locRepeatMainGameLoop;
207 // ----------------------------------------------------------------------------
208 // ---------------------- END OF GAME-BUSY LOOP -------------------------------
209 // ----------------------------------------------------------------------------
210 LeadOutCounter = LeadOutCounter - 1; // do more lead-out after quit
211 if (LeadOutCounter != 0) // lead-out not ready: more
212 goto locRepeatMainGameLoop;
214 // lead-out done: exit now
215 // ---------------------- END OF GAME-BUSY LOOP (including lead-out) ----------
220 DoEvents(); // user may klick on menus or move the window here ...
225 while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
228 Stage.Blt(); // blit the last frame
232 MainForm.menStop_Click();
233 MainForm.PanelVisible = True;
236 // If DemoRecordingFlag <> 0 Then Call subCloseDemoRecordingFile ' Demo recording on? -> close opened demo file (w)
237 if (SavedGameFlag != 0) // after savegame: no update!
240 return subMainGameLoop;
244 if (UpdateTimeFlag == 0) // update time?
245 return subMainGameLoop;
247 if (UpdatedFlag == 0) // update playing time
248 subUpdatePlayingTime();
251 return subMainGameLoop;
254 void subUpdatePlayingTime()
258 int subCalculateScreenScrollPos()
260 int subCalculateScreenScrollPos;
264 if (ExplosionShake != 0)
266 subGetRandomNumber();
270 ax = MainForm.picPane.Width / 2;
271 Ay = MainForm.picPane.Height / 2;
275 ScreenScrollXPos = Stretch * (MurphyScreenXPos + 16) - ax;
276 ScreenScrollYPos = Stretch * (MurphyScreenYPos + 16) - Ay;
278 ScreenScrollXPos = Stretch * (MurphyScreenXPos + 8) - ax;
279 ScreenScrollYPos = Stretch * (MurphyScreenYPos + 8) - Ay;
283 printf("::: MainGameLoop.c: subCalculateScreenScrollPos(): %d, %d [%d, %d] -> %d, %d\n",
284 MainForm.picPane.Width, MainForm.picPane.Height,
285 MurphyScreenXPos, MurphyScreenYPos,
286 ScreenScrollXPos, ScreenScrollYPos);
289 return subCalculateScreenScrollPos;