rnd-20090719-1-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
67   RedDiskReleasePhase = 0; // (re-)enable red disk release
68   UpdatedFlag = 0;
69   GameLoopRunning = 1;
70   LevelStatus = 0;
71
72   // ----------------------------------------------------------------------------
73   // --------------------- START OF GAME-BUSY LOOP ------------------------------
74   // ----------------------------------------------------------------------------
75
76 locRepeatMainGameLoop:                           // start repeating game loop
77
78   // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
79   // FS   synchronization
80   while (PauseMode != 0)
81   {
82     DoEvents();
83   }
84
85   do
86   {
87     DoEvents(); // user may klick on menus or move the window here ...
88   }
89   while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
90
91   //   never any additional code between here!
92   LastFrame = Clock.TickNow; // store the frame time
93   //   never any additional code between here!
94   if (! NoDisplayFlag) // copy the BackBuffer(=Stage) to visible screen
95     Stage.Blt();
96
97   // FS   end of synchronization
98   // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
99   if (EndFlag)
100     goto locExitMainGameLoop;
101
102   // If DemoFlag = 0 Then Call subCheckJoystick    ' check joystick
103   // bx = subCheckRightMouseButton()                ' check (right) mouse button
104   // If bx = 2 And LeadOutCounter < 1 Then KillMurphyFlag = 1 ' lead-out busy after quit? -> kill Murphy!
105
106   //  If DebugVersionFlag <> 0 Then ' debug mode on?
107   //    If Data_SubRest <> 0 Then Data_SubRest = Data_SubRest - 1
108   //    If keyEnter <> 0 Then GoTo loc_g_186F ' Was it the Enter key? -> yes--skip! No mouse!
109   //                                          ' fixes ENTER bug If no mouse driver!
110   //    If bx <> 1 Then GoTo loc_g_186F  ' Left button=Init game field
111   //                                    ' Also Enter If no mouse!
112   //    If Data_SubRest <> 0 Then GoTo loc_g_186F
113   //    Data_SubRest = 10
114   //    Call subRestoreFancy
115   //    Call subDisplayLevel         ' Paint (Init) game field
116   //    Call subConvertToEasySymbols ' Convert to easy symbols
117   //  End If
118
119   // loc_g_186F:
120
121   subProcessKeyboardInput();                 // Check keyboard, act on keys
122
123   // 'HACK:
124   //  TimerVar = TimerVar + 1
125   //  DoEvents
126   //  GoTo loc_g_186F
127   // 'END HACK
128   // If RecordDemoFlag = 1 Then GoTo RestartGameLoop
129
130   // ----------------------------------------------------------------------------
131   //
132
133   subDoGameStuff();                 // do all game stuff
134
135   //
136   // ----------------------------------------------------------------------------
137
138   //  Call subDisplayPlayingTime                 ' playing time on screen
139
140   subCheckRestoreRedDiskCountDisplay();    // Restore panel: red-disk hole
141
142   subRedDiskReleaseExplosion();       // Red Disk release and explode
143   subFollowUpExplosions();  // every explosion may cause up to 8 following explosions
144
145   bx = subCalculateScreenScrollPos();     // calculate screen start addrs
146
147   ScreenPosition = bx;
148
149   // Now new X and new Y are calculated, and bx = screen position = ScreenPosition
150   data_h_Ytmp = ScreenScrollYPos; // copy Y for next soft scroll
151   data_h_Xtmp = ScreenScrollXPos; // copy X for next soft scroll
152   if ((! UserDragFlag) && AutoScrollFlag)
153     ScrollTowards(ScreenScrollXPos, ScreenScrollYPos);
154
155   if (ForcedExitFlag != 0) // Forced Exit?' yes--exit!
156     goto locExitMainGameLoop;
157
158   TimerVar = TimerVar + 1;
159
160 #if 0
161   if (bCapturePane)
162     MainForm.SaveSnapshot(TimerVar);
163 #endif
164
165   //  If Not NoDisplayFlag Then
166   //    With MainForm.lblFrameCount
167   //      .Caption = TimerVar
168   //      .Refresh
169   //    End With
170   //  End If
171   if (ExitToMenuFlag == 1)
172     goto locExitMainGameLoop;
173
174   if (LeadOutCounter == 0) // no lead-out: game busy
175     goto locRepeatMainGameLoop;
176
177   // ----------------------------------------------------------------------------
178   // ---------------------- END OF GAME-BUSY LOOP -------------------------------
179   // ----------------------------------------------------------------------------
180   LeadOutCounter = LeadOutCounter - 1;             // do more lead-out after quit
181   if (LeadOutCounter != 0) // lead-out not ready: more
182     goto locRepeatMainGameLoop;
183
184   // lead-out done: exit now
185   // ---------------------- END OF GAME-BUSY LOOP (including lead-out) ----------
186
187 locExitMainGameLoop:
188   do
189   {
190     DoEvents(); // user may klick on menus or move the window here ...
191   }
192   while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
193
194   Stage.Blt(); // blit the last frame
195   GameLoopRunning = 0;
196
197 #if 0
198   MainForm.menStop_Click();
199   MainForm.PanelVisible = True;
200 #endif
201
202   // If DemoRecordingFlag <> 0 Then Call subCloseDemoRecordingFile ' Demo recording on? -> close opened demo file (w)
203   if (SavedGameFlag != 0) // after savegame: no update!
204   {
205     SavedGameFlag = 0;
206     return subMainGameLoop;
207   }
208
209   SavedGameFlag = 0;
210   if (UpdateTimeFlag == 0) // update time?
211     return subMainGameLoop;
212
213   if (UpdatedFlag == 0) // update playing time
214     subUpdatePlayingTime();
215
216
217   return subMainGameLoop;
218 } // subMainGameLoop
219
220 void subUpdatePlayingTime()
221 {
222 }
223
224 int subCalculateScreenScrollPos()
225 {
226   int subCalculateScreenScrollPos;
227
228   int ax, Ay;
229
230   if (ExplosionShake != 0)
231   {
232     subGetRandomNumber();
233   }
234
235   {
236     ax = MainForm.picPane.Width / 2;
237     Ay = MainForm.picPane.Height / 2;
238   }
239   ScreenScrollXPos = Stretch * (MurphyScreenXPos + 8) - ax;
240   ScreenScrollYPos = Stretch * (MurphyScreenYPos + 8) - Ay;
241
242   return subCalculateScreenScrollPos;
243 }
244