1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
5 #include "MainGameLoop.h"
7 static char *VB_Name = "modMainGameLoop";
12 int LeadOutCounter, EnterRepeatCounter;
17 boolean AutoScrollFlag;
19 // ==========================================================================
22 // ==========================================================================
29 TickCountObject Clock;
34 // EP set level success byte: demo, not game
36 EP_GameDemoVar0DAA = 0; // demo
40 // EP set level success byte: game, not demo
42 EP_GameDemoVar0DAA = 1; // game
46 // If RecordDemoFlag = 1 Then
47 // RecordDemoFlag = 0 ' clear Demo Recording flag
48 // Call subDisplayPlayingTime ' playing time on screen
49 // ' Record key still pressed?' >= (Ctrl-)F1 and <= (Ctrl-)F10
50 // While &H3B <= KeyScanCode7 And KeyScanCode7 <= &H44
51 // ' yes -> wait until released
52 // ' should we DoEvents here???? ... depends on how ... but yes!
53 // ' ...or we can rather poll the keyboardstate inside this loop???
55 // Call subInitGameConditions ' Init game conditions (vars)
56 // If MusicOnFlag = 0 Then Call subMusicInit
57 // WasDemoFlag = 0 ' no demo anymore
58 // EP_GameDemoVar0DAA = 1 ' force game
61 // This was a bug in the original Supaplex: sometimes red disks could not
62 // be released. This happened If Murphy was killed DURING a red disk release
63 // and the next try started.
64 RedDiskReleasePhase = 0; // (re-)enable red disk release
68 // ----------------------------------------------------------------------------
69 // --------------------- START OF GAME-BUSY LOOP ------------------------------
70 // ----------------------------------------------------------------------------
72 locRepeatMainGameLoop: // start repeating game loop
74 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76 while (PauseMode != 0)
83 DoEvents(); // user may klick on menus or move the window here ...
85 while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
87 // never any additional code between here!
88 LastFrame = Clock.TickNow; // store the frame time
89 // never any additional code between here!
90 if (! NoDisplayFlag) // copy the BackBuffer(=Stage) to visible screen
93 // FS end of synchronization
94 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
96 goto locExitMainGameLoop;
98 // If DemoFlag = 0 Then Call subCheckJoystick ' check joystick
99 // bx = subCheckRightMouseButton() ' check (right) mouse button
100 // If bx = 2 And LeadOutCounter < 1 Then KillMurphyFlag = 1 ' lead-out busy after quit? -> kill Murphy!
102 // If DebugVersionFlag <> 0 Then ' debug mode on?
103 // If Data_SubRest <> 0 Then Data_SubRest = Data_SubRest - 1
104 // If keyEnter <> 0 Then GoTo loc_g_186F ' Was it the Enter key? -> yes--skip! No mouse!
105 // ' fixes ENTER bug If no mouse driver!
106 // If bx <> 1 Then GoTo loc_g_186F ' Left button=Init game field
107 // ' Also Enter If no mouse!
108 // If Data_SubRest <> 0 Then GoTo loc_g_186F
110 // Call subRestoreFancy
111 // Call subDisplayLevel ' Paint (Init) game field
112 // Call subConvertToEasySymbols ' Convert to easy symbols
116 subProcessKeyboardInput(); // Check keyboard, act on keys
118 // TimerVar = TimerVar + 1
122 // If RecordDemoFlag = 1 Then GoTo RestartGameLoop
124 // ----------------------------------------------------------------------------
126 subDoGameStuff(); // do all game stuff
128 // ----------------------------------------------------------------------------
130 // Call subDisplayPlayingTime ' playing time on screen
131 subCheckRestoreRedDiskCountDisplay(); // Restore panel: red-disk hole
133 subRedDiskReleaseExplosion(); // Red Disk release and explode
134 subFollowUpExplosions(); // every explosion may cause up to 8 following explosions
136 bx = subCalculateScreenScrollPos(); // calculate screen start addrs
138 // Now new X and new Y are calculated, and bx = screen position = ScreenPosition
139 data_h_Ytmp = ScreenScrollYPos; // copy Y for next soft scroll
140 data_h_Xtmp = ScreenScrollXPos; // copy X for next soft scroll
141 if ((! UserDragFlag) && AutoScrollFlag)
142 ScrollTowards(ScreenScrollXPos, ScreenScrollYPos);
144 if (ForcedExitFlag != 0) // Forced Exit?' yes--exit!
145 goto locExitMainGameLoop;
147 TimerVar = TimerVar + 1;
151 MainForm.SaveSnapshot(TimerVar);
154 // If Not NoDisplayFlag Then
155 // With MainForm.lblFrameCount
156 // .Caption = TimerVar
160 if (ExitToMenuFlag == 1)
161 goto locExitMainGameLoop;
163 if (LeadOutCounter == 0) // no lead-out: game busy
164 goto locRepeatMainGameLoop;
166 // ----------------------------------------------------------------------------
167 // ---------------------- END OF GAME-BUSY LOOP -------------------------------
168 // ----------------------------------------------------------------------------
169 LeadOutCounter = LeadOutCounter - 1; // do more lead-out after quit
170 if (LeadOutCounter != 0) // lead-out not ready: more
171 goto locRepeatMainGameLoop;
173 // lead-out done: exit now
174 // ---------------------- END OF GAME-BUSY LOOP (including lead-out) ----------
179 DoEvents(); // user may klick on menus or move the window here ...
181 while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
183 Stage.Blt(); // blit the last frame
187 MainForm.menStop_Click();
188 MainForm.PanelVisible = True;
191 // If DemoRecordingFlag <> 0 Then Call subCloseDemoRecordingFile ' Demo recording on? -> close opened demo file (w)
192 if (SavedGameFlag != 0) // after savegame: no update!
195 return subMainGameLoop;
199 if (UpdateTimeFlag == 0) // update time?
200 return subMainGameLoop;
202 if (UpdatedFlag == 0) // update playing time
203 subUpdatePlayingTime();
206 return subMainGameLoop;
209 void subUpdatePlayingTime()
213 int subCalculateScreenScrollPos()
215 int subCalculateScreenScrollPos;
219 if (ExplosionShake != 0)
221 subGetRandomNumber();
225 ax = MainForm.picPane.Width / 2;
226 Ay = MainForm.picPane.Height / 2;
228 ScreenScrollXPos = Stretch * (MurphyScreenXPos + 8) - ax;
229 ScreenScrollYPos = Stretch * (MurphyScreenYPos + 8) - Ay;
231 return subCalculateScreenScrollPos;