1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
5 #include "MainGameLoop.h"
7 // static char *VB_Name = "modMainGameLoop";
13 int LeadOutCounter, EnterRepeatCounter;
18 boolean AutoScrollFlag;
20 // ==========================================================================
23 // ==========================================================================
32 TickCountObject Clock;
38 // EP set level success byte: demo, not game
40 EP_GameDemoVar0DAA = 0; // demo
44 // EP set level success byte: game, not demo
46 EP_GameDemoVar0DAA = 1; // game
50 // If RecordDemoFlag = 1 Then
51 // RecordDemoFlag = 0 ' clear Demo Recording flag
52 // Call subDisplayPlayingTime ' playing time on screen
53 // ' Record key still pressed?' >= (Ctrl-)F1 and <= (Ctrl-)F10
54 // While &H3B <= KeyScanCode7 And KeyScanCode7 <= &H44
55 // ' yes -> wait until released
56 // ' should we DoEvents here???? ... depends on how ... but yes!
57 // ' ...or we can rather poll the keyboardstate inside this loop???
59 // Call subInitGameConditions ' Init game conditions (vars)
60 // If MusicOnFlag = 0 Then Call subMusicInit
61 // WasDemoFlag = 0 ' no demo anymore
62 // EP_GameDemoVar0DAA = 1 ' force game
65 // This was a bug in the original Supaplex: sometimes red disks could not
66 // be released. This happened If Murphy was killed DURING a red disk release
67 // and the next try started.
69 RedDiskReleasePhase = 0; // (re-)enable red disk release
74 // ----------------------------------------------------------------------------
75 // --------------------- START OF GAME-BUSY LOOP ------------------------------
76 // ----------------------------------------------------------------------------
78 locRepeatMainGameLoop: // start repeating game loop
80 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
82 while (PauseMode != 0)
89 DoEvents(); // user may klick on menus or move the window here ...
94 while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
97 // never any additional code between here!
99 LastFrame = Clock.TickNow(); // store the frame time
101 // never any additional code between here!
102 if (! NoDisplayFlag) // copy the BackBuffer(=Stage) to visible screen
105 // FS end of synchronization
106 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
108 goto locExitMainGameLoop;
110 // If DemoFlag = 0 Then Call subCheckJoystick ' check joystick
111 // bx = subCheckRightMouseButton() ' check (right) mouse button
112 // If bx = 2 And LeadOutCounter < 1 Then KillMurphyFlag = 1 ' lead-out busy after quit? -> kill Murphy!
114 // If DebugVersionFlag <> 0 Then ' debug mode on?
115 // If Data_SubRest <> 0 Then Data_SubRest = Data_SubRest - 1
116 // If keyEnter <> 0 Then GoTo loc_g_186F ' Was it the Enter key? -> yes--skip! No mouse!
117 // ' fixes ENTER bug If no mouse driver!
118 // If bx <> 1 Then GoTo loc_g_186F ' Left button=Init game field
119 // ' Also Enter If no mouse!
120 // If Data_SubRest <> 0 Then GoTo loc_g_186F
122 // Call subRestoreFancy
123 // Call subDisplayLevel ' Paint (Init) game field
124 // Call subConvertToEasySymbols ' Convert to easy symbols
129 subProcessKeyboardInput(); // Check keyboard, act on keys
132 // TimerVar = TimerVar + 1
136 // If RecordDemoFlag = 1 Then GoTo RestartGameLoop
138 // ----------------------------------------------------------------------------
141 subDoGameStuff(); // do all game stuff
144 // ----------------------------------------------------------------------------
146 // Call subDisplayPlayingTime ' playing time on screen
148 subCheckRestoreRedDiskCountDisplay(); // Restore panel: red-disk hole
150 subRedDiskReleaseExplosion(); // Red Disk release and explode
151 subFollowUpExplosions(); // every explosion may cause up to 8 following explosions
153 bx = subCalculateScreenScrollPos(); // calculate screen start addrs
157 // Now new X and new Y are calculated, and bx = screen position = ScreenPosition
158 data_h_Ytmp = ScreenScrollYPos; // copy Y for next soft scroll
159 data_h_Xtmp = ScreenScrollXPos; // copy X for next soft scroll
160 if ((! UserDragFlag) && AutoScrollFlag)
161 ScrollTowards(ScreenScrollXPos, ScreenScrollYPos);
163 if (ForcedExitFlag != 0) // Forced Exit?' yes--exit!
164 goto locExitMainGameLoop;
166 TimerVar = TimerVar + 1;
170 MainForm.SaveSnapshot(TimerVar);
173 // If Not NoDisplayFlag Then
174 // With MainForm.lblFrameCount
175 // .Caption = TimerVar
179 if (ExitToMenuFlag == 1)
180 goto locExitMainGameLoop;
182 if (LeadOutCounter == 0) // no lead-out: game busy
183 goto locRepeatMainGameLoop;
185 // ----------------------------------------------------------------------------
186 // ---------------------- END OF GAME-BUSY LOOP -------------------------------
187 // ----------------------------------------------------------------------------
188 LeadOutCounter = LeadOutCounter - 1; // do more lead-out after quit
189 if (LeadOutCounter != 0) // lead-out not ready: more
190 goto locRepeatMainGameLoop;
192 // lead-out done: exit now
193 // ---------------------- END OF GAME-BUSY LOOP (including lead-out) ----------
198 DoEvents(); // user may klick on menus or move the window here ...
203 while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
206 Stage.Blt(); // blit the last frame
210 MainForm.menStop_Click();
211 MainForm.PanelVisible = True;
214 // If DemoRecordingFlag <> 0 Then Call subCloseDemoRecordingFile ' Demo recording on? -> close opened demo file (w)
215 if (SavedGameFlag != 0) // after savegame: no update!
218 return subMainGameLoop;
222 if (UpdateTimeFlag == 0) // update time?
223 return subMainGameLoop;
225 if (UpdatedFlag == 0) // update playing time
226 subUpdatePlayingTime();
229 return subMainGameLoop;
232 void subUpdatePlayingTime()
236 int subCalculateScreenScrollPos()
238 int subCalculateScreenScrollPos;
242 if (ExplosionShake != 0)
244 subGetRandomNumber();
248 ax = MainForm.picPane.Width / 2;
249 Ay = MainForm.picPane.Height / 2;
251 ScreenScrollXPos = Stretch * (MurphyScreenXPos + 8) - ax;
252 ScreenScrollYPos = Stretch * (MurphyScreenYPos + 8) - Ay;
254 return subCalculateScreenScrollPos;