rnd-20090623-4-src
[rocksndiamonds.git] / src / game_sp / MainGameLoop.c
1 // ----------------------------------------------------------------------------
2 // MainGameLoop.c
3 // ----------------------------------------------------------------------------
4
5 #include "MainGameLoop.h"
6
7 // static char *VB_Name = "modMainGameLoop";
8
9 // --- Option Explicit
10
11 int GameLoopRunning;
12 boolean bPlaying;
13 int LeadOutCounter, EnterRepeatCounter;
14 int ForcedExitFlag;
15 int ExitToMenuFlag;
16 int SavedGameFlag;
17 boolean UserDragFlag;
18 boolean AutoScrollFlag;
19
20 // ==========================================================================
21 //                              SUBROUTINE
22 // Play a game/demo
23 // ==========================================================================
24
25 int subMainGameLoop()
26 {
27   int subMainGameLoop;
28
29   // int al, bx;
30   int bx;
31   TickCountObject Clock;
32   currency LastFrame;
33
34   if (DemoFlag != 0)
35   {
36     // EP set level success byte: demo, not game
37     WasDemoFlag = 1;
38     EP_GameDemoVar0DAA = 0; // demo
39   }
40   else // loc_g_1836:
41   {
42     // EP set level success byte: game, not demo
43     WasDemoFlag = 0;
44     EP_GameDemoVar0DAA = 1; // game
45   }
46
47   // RestartGameLoop:
48   //  If RecordDemoFlag = 1 Then
49   //    RecordDemoFlag = 0 ' clear Demo Recording flag
50   //    Call subDisplayPlayingTime                 ' playing time on screen
51   //    ' Record key still pressed?' >= (Ctrl-)F1 and <= (Ctrl-)F10
52   //    While &H3B <= KeyScanCode7 And KeyScanCode7 <= &H44
53   //      ' yes -> wait until released
54   //      ' should we DoEvents here???? ... depends on how ... but yes!
55   //      ' ...or we can rather poll the keyboardstate inside this loop???
56   //    Wend
57   //    Call subInitGameConditions     ' Init game conditions (vars)
58   //    If MusicOnFlag = 0 Then Call subMusicInit
59   //    WasDemoFlag = 0          ' no demo anymore
60   //    EP_GameDemoVar0DAA = 1 ' force game
61   //  End If
62
63   // This was a bug in the original Supaplex: sometimes red disks could not
64   // be released.  This happened If Murphy was killed DURING a red disk release
65   // and the next try started.
66   RedDiskReleasePhase = 0; // (re-)enable red disk release
67   UpdatedFlag = 0;
68   GameLoopRunning = 1;
69   LevelStatus = 0;
70   // ----------------------------------------------------------------------------
71   // --------------------- START OF GAME-BUSY LOOP ------------------------------
72   // ----------------------------------------------------------------------------
73
74 locRepeatMainGameLoop:                           // start repeating game loop
75
76   // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77   // FS   synchronization
78   while (PauseMode != 0)
79   {
80     DoEvents();
81   }
82
83   do
84   {
85     DoEvents(); // user may klick on menus or move the window here ...
86   }
87   while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
88
89   //   never any additional code between here!
90   LastFrame = Clock.TickNow; // store the frame time
91   //   never any additional code between here!
92   if (! NoDisplayFlag) // copy the BackBuffer(=Stage) to visible screen
93     Stage.Blt();
94
95   // FS   end of synchronization
96   // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
97   if (EndFlag)
98     goto locExitMainGameLoop;
99
100   // If DemoFlag = 0 Then Call subCheckJoystick    ' check joystick
101   // bx = subCheckRightMouseButton()                ' check (right) mouse button
102   // If bx = 2 And LeadOutCounter < 1 Then KillMurphyFlag = 1 ' lead-out busy after quit? -> kill Murphy!
103
104   //  If DebugVersionFlag <> 0 Then ' debug mode on?
105   //    If Data_SubRest <> 0 Then Data_SubRest = Data_SubRest - 1
106   //    If keyEnter <> 0 Then GoTo loc_g_186F ' Was it the Enter key? -> yes--skip! No mouse!
107   //                                          ' fixes ENTER bug If no mouse driver!
108   //    If bx <> 1 Then GoTo loc_g_186F  ' Left button=Init game field
109   //                                    ' Also Enter If no mouse!
110   //    If Data_SubRest <> 0 Then GoTo loc_g_186F
111   //    Data_SubRest = 10
112   //    Call subRestoreFancy
113   //    Call subDisplayLevel         ' Paint (Init) game field
114   //    Call subConvertToEasySymbols ' Convert to easy symbols
115   //  End If
116
117   // loc_g_186F:
118
119   subProcessKeyboardInput();                 // Check keyboard, act on keys
120   // 'HACK:
121   //  TimerVar = TimerVar + 1
122   //  DoEvents
123   //  GoTo loc_g_186F
124   // 'END HACK
125   // If RecordDemoFlag = 1 Then GoTo RestartGameLoop
126
127   // ----------------------------------------------------------------------------
128   //
129   subDoGameStuff();                 // do all game stuff
130   //
131   // ----------------------------------------------------------------------------
132
133   //  Call subDisplayPlayingTime                 ' playing time on screen
134   subCheckRestoreRedDiskCountDisplay();    // Restore panel: red-disk hole
135
136   subRedDiskReleaseExplosion();       // Red Disk release and explode
137   subFollowUpExplosions();  // every explosion may cause up to 8 following explosions
138
139   bx = subCalculateScreenScrollPos();     // calculate screen start addrs
140   ScreenPosition = bx;
141   // Now new X and new Y are calculated, and bx = screen position = ScreenPosition
142   data_h_Ytmp = ScreenScrollYPos; // copy Y for next soft scroll
143   data_h_Xtmp = ScreenScrollXPos; // copy X for next soft scroll
144   if ((! UserDragFlag) && AutoScrollFlag)
145     ScrollTowards(ScreenScrollXPos, ScreenScrollYPos);
146
147   if (ForcedExitFlag != 0) // Forced Exit?' yes--exit!
148     goto locExitMainGameLoop;
149
150   TimerVar = TimerVar + 1;
151
152 #if 0
153   if (bCapturePane)
154     MainForm.SaveSnapshot(TimerVar);
155 #endif
156
157   //  If Not NoDisplayFlag Then
158   //    With MainForm.lblFrameCount
159   //      .Caption = TimerVar
160   //      .Refresh
161   //    End With
162   //  End If
163   if (ExitToMenuFlag == 1)
164     goto locExitMainGameLoop;
165
166   if (LeadOutCounter == 0) // no lead-out: game busy
167     goto locRepeatMainGameLoop;
168
169   // ----------------------------------------------------------------------------
170   // ---------------------- END OF GAME-BUSY LOOP -------------------------------
171   // ----------------------------------------------------------------------------
172   LeadOutCounter = LeadOutCounter - 1;             // do more lead-out after quit
173   if (LeadOutCounter != 0) // lead-out not ready: more
174     goto locRepeatMainGameLoop;
175
176   // lead-out done: exit now
177   // ---------------------- END OF GAME-BUSY LOOP (including lead-out) ----------
178
179 locExitMainGameLoop:
180   do
181   {
182     DoEvents(); // user may klick on menus or move the window here ...
183   }
184   while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
185
186   Stage.Blt(); // blit the last frame
187   GameLoopRunning = 0;
188
189 #if 0
190   MainForm.menStop_Click();
191   MainForm.PanelVisible = True;
192 #endif
193
194   // If DemoRecordingFlag <> 0 Then Call subCloseDemoRecordingFile ' Demo recording on? -> close opened demo file (w)
195   if (SavedGameFlag != 0) // after savegame: no update!
196   {
197     SavedGameFlag = 0;
198     return subMainGameLoop;
199   }
200
201   SavedGameFlag = 0;
202   if (UpdateTimeFlag == 0) // update time?
203     return subMainGameLoop;
204
205   if (UpdatedFlag == 0) // update playing time
206     subUpdatePlayingTime();
207
208
209   return subMainGameLoop;
210 } // subMainGameLoop
211
212 void subUpdatePlayingTime()
213 {
214 }
215
216 int subCalculateScreenScrollPos()
217 {
218   int subCalculateScreenScrollPos;
219
220   int ax, Ay;
221
222   if (ExplosionShake != 0)
223   {
224     subGetRandomNumber();
225   }
226
227   {
228     ax = MainForm.picPane.Width / 2;
229     Ay = MainForm.picPane.Height / 2;
230   }
231   ScreenScrollXPos = Stretch * (MurphyScreenXPos + 8) - ax;
232   ScreenScrollYPos = Stretch * (MurphyScreenYPos + 8) - Ay;
233
234   return subCalculateScreenScrollPos;
235 }
236