rnd-20090623-1-src
[rocksndiamonds.git] / src / game_sp / InitGameConditions.c
1 // ----------------------------------------------------------------------------
2 // InitGameConditions.c
3 // ----------------------------------------------------------------------------
4
5 #include "InitGameConditions.h"
6
7 static char *VB_Name = "modInitGameConditions";
8 // --- Option Explicit
9
10 // ==========================================================================
11 //                              SUBROUTINE
12 // Init game conditions (variables)
13 // ==========================================================================
14
15 int subInitGameConditions()
16 {
17   int subInitGameConditions;
18
19   bCapturePane = False;
20
21   MurphyVar0DAC = MurphyYPos;
22   MurphyVar0DAE = MurphyXPos;
23   MurphyVarFaceLeft = 0;
24   KillMurphyFlag = 0;            // no "kill Murphy"
25   ExitToMenuFlag = 0;
26   LeadOutCounter = 0;           // quit flag: lead-out counter
27   RedDiskCount = 0; // Red disk counter
28   ShowRedDiskCounter = 0; // show-red-disk time-out
29
30   YawnSleepCounter = 0; // Wake up sleeping Murphy
31
32   data_h_0DA7 = 0xFF;
33   data_h_0DA8 = 0xFF;
34   data_h_0DA9 = 0xFF;
35   data_h_0D9E = 1;
36   data_h_0D9F = 0;
37   data_h_0DA0 = 0;
38   data_h_0DA1 = 0;
39   data_h_0DA2 = 0;
40   data_h_0DA4 = 0;
41   data_h_0DA5 = 0;
42   data_h_0DA6 = 0;
43
44   ExplosionShake = 0; // Force explosion flag off
45
46   TerminalMaxCycles = 0x7F;
47   YellowDisksExploded = 0;
48
49   TimerVar = 0;
50   // ShowPanel = 1 ' Force Panel on
51   // MainForm.PanelVisible = True;
52   EnterRepeatCounter = 0; // restart Enter repeat counter
53   SnikSnaksElectronsFrozen = 0; // Snik-Snaks and Electr. move!
54
55   SplitMoveFlag = 0; // Reset Split-through-ports
56   RedDiskReleasePhase = 0; // (re-)enable red disk release
57   RedDiskReleaseMurphyPos = 0; // Red disk was released here
58
59
60   return subInitGameConditions;
61 } // subInitGameConditions
62
63
64 // ==========================================================================
65 //                              SUBROUTINE
66 // Locate Murphy and init location.
67 // ==========================================================================
68
69 int InitMurphyPos()
70 {
71   int InitMurphyPos;
72
73   int si;
74
75   for (si = 0; si <= LevelMax - 1; si++)
76   {
77     if (PlayField16[si] == fiMurphy)
78       break;
79   }
80
81   InitMurphyPosB(si);
82   MurphyPosIndex = si;
83
84   return InitMurphyPos;
85 } // InitMurphyPos
86
87 int InitMurphyPosB(int si)
88 {
89   int InitMurphyPosB;
90
91   MurphyYPos = GetStretchY(si) / Stretch;
92   MurphyXPos = GetStretchX(si) / Stretch;
93
94   MurphyScreenXPos = GetStretchX(si);          // Murphy's screen x-position
95   MurphyScreenYPos = GetStretchY(si);         // Murphy's screen y-position
96
97   // To Do: draw Murphy in location ax
98   StretchedSprites.BltEx(MurphyScreenXPos, MurphyScreenYPos, fiMurphy);
99
100   MurphyScreenXPos = MurphyScreenXPos / Stretch;
101   MurphyScreenYPos = MurphyScreenYPos / Stretch;
102
103   subCalculateScreenScrollPos();           // calculate screen start addrs
104   if (AutoScrollFlag)
105   {
106     if (bPlaying)
107     {
108       SoftScrollTo(ScreenScrollXPos, ScreenScrollYPos, 1000, 25);
109     }
110     else
111     {
112       ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
113     }
114   }
115
116   return InitMurphyPosB;
117 } // InitMurphyPosB
118
119 // ==========================================================================
120 //                              SUBROUTINE
121 // Convert to easy symbols and reset Infotron count If not ThenVer62
122 // ==========================================================================
123
124 int subConvertToEasySymbols()
125 {
126   int subConvertToEasySymbols;
127
128   int ax, bx, cx, dx, di, X, Y, i;
129   int ah, bh, ch, dh, al, bl, cl, dl, ZF;
130
131   bx = 0;
132   dx = 0;
133   cx = LevelMax + 1;
134   i = 0;
135
136 loc_g_26C9:
137   ax = PlayField16[i];
138   al = LowByte(ax);
139   if (al == 0xF1) // converted explosion?
140   {
141     MovLowByte(&PlayField16[i], 0x1F);      // restore explosions
142     goto loc_g_2778;
143   }
144
145   if (LowByte(GameBusyFlag) != 1) // free screen write?
146   {
147     if (ax == fiInfotron) // Infotron? -> yes--count!
148       goto loc_g_2704;
149
150     if (ax == fiSnikSnak) // Snik Snak? -> yes--rearrange
151       goto loc_g_2713;
152
153     if (ax == fiElectron) // Electron? -> yes--rearrange
154       goto loc_g_2741;
155   }
156
157   // test for fancy RAM Chips:
158   if (ax == fiRAMLeft || ax == fiRAMRight)
159     goto loc_g_2707;
160
161   if (ax == fiRAMTop || ax == fiRAMBottom)
162     goto loc_g_2707;
163
164   if (ax < fiHWFirst) // All but deco hardware?
165     goto loc_g_26F8;
166
167   if (ax < fiRAMTop) // Decorative hardware?
168     goto loc_g_270D;
169
170 loc_g_26F8:
171   if (ax < fiSpPortRight) // Gravity change ports only?
172     goto loc_g_2778;
173
174   if (ax < fiSnikSnak) // Gravity change port! 'loc_g_2702:
175     goto loc_g_276F;
176
177   goto loc_g_2778;
178
179 loc_g_2704:                                     // INFOTRON
180   dx = dx + 1;                      // Count Infotrons
181   goto loc_g_2778;
182
183 loc_g_2707:                                     // DECO RAM CHIPS
184   PlayField16[i] = fiRAM; // Convert to standard RAM chip
185   goto loc_g_2778;
186
187 loc_g_270D:                                     // DECO HARDWARE
188   PlayField16[i] = fiHardWare; // Convert to standard hardware
189   goto loc_g_2778;
190
191 loc_g_2713:                                     // SNIK-SNAK
192   if (PlayField16[i - 1] != 0) // 1 field left empty? -> no--try up
193     goto loc_g_271F;
194
195   MovHighByte(&PlayField16[i], 1); // turn left, step = NorthWest
196   goto loc_g_2778;
197
198 loc_g_271F:
199   if (PlayField16[i - FieldWidth] != 0) // 1 field up empty? -> no--try right
200     goto loc_g_2730;
201
202   PlayField16[i - FieldWidth] = 0x1011; // SnikSnak accessing from below, step = 0
203   PlayField16[i] = 0xFFFF;
204   goto loc_g_2778;
205
206 loc_g_2730:
207   if (PlayField16[i + 1] != 0) // 1 field right empty? -> point up
208     goto loc_g_2778;
209
210   PlayField16[i + 1] = 0x2811; // SnikSnak accessing from left, step = 0
211   PlayField16[i] = 0xFFFF;
212   goto loc_g_2778;
213
214 loc_g_2741:                                     // ELECTRON
215   if (PlayField16[i - 1] != 0) // 1 field left empty? -> no--try up
216     goto loc_g_274D;
217
218   MovHighByte(&PlayField16[i], 1);
219   goto loc_g_2778;
220
221 loc_g_274D:
222   if (PlayField16[i - FieldWidth] != 0) // 1 field up empty? -> no--try right
223     goto loc_g_275E;
224
225   PlayField16[i - FieldWidth] = 0x1018; // 1 field up
226   PlayField16[i] = 0xFFFF;
227   goto loc_g_2778;
228
229 loc_g_275E:
230   if (PlayField16[i + 1] != 0) // 1 field right empty? -> no--point down
231     goto loc_g_2778;
232
233   PlayField16[i + 1] = 0x2818;
234   PlayField16[i] = 0xFFFF;
235   goto loc_g_2778;
236
237 loc_g_276F:                                     // GRAVITY CHANGING PORTS
238   PlayField16[i] = (ax - 4) | 0x100;    // Convert to standard ports
239   goto loc_g_2778;
240
241 loc_g_2778:
242   i = i + 1;                   // Next field
243   bx = bx + 1;
244   cx = cx - 1;
245   if (0 < cx) // Until all done 'loc_g_2782:
246     goto loc_g_26C9;
247
248   subConvertToEasySymbols = dx; // return InfotronCount
249
250   return subConvertToEasySymbols;
251 } // subConvertToEasySymbols
252
253 // ==========================================================================
254 //                              SUBROUTINE
255 // Reset Infotron count.  Call immediately after subConvertToEasySymbols
256 // ==========================================================================
257
258 int ResetInfotronsNeeded(int dx)
259 {
260   int ResetInfotronsNeeded;
261
262   if (LInfo.InfotronsNeeded != 0) // Jump If equal (autodetect)
263   {
264     dx = LInfo.InfotronsNeeded;
265   }                            // loc_g_278D:
266
267   InfotronsNeeded = LowByte(dx);           // Remaining Infotrons needed
268   TotalInfotronsNeeded = InfotronsNeeded;          // Number of Infotrons needed
269   subDisplayInfotronsNeeded();
270
271   return ResetInfotronsNeeded;
272 } // ResetInfotronsNeeded
273
274
275 // ==========================================================================
276 //                              SUBROUTINE
277 // Fetch and initialize a level
278 // ==========================================================================
279
280 int subFetchAndInitLevelB()
281 {
282   int subFetchAndInitLevelB;
283
284   boolean UpdatePlayTime;
285
286   MovLowByte(&data_SPtorunavail, 0);   // no SP file
287   data_scr_demo = 0;
288   UpdatePlayTime = (0 == demo_stopped ?  True :  True);
289   demo_stopped = 0;
290   subFetchAndInitLevelA(UpdatePlayTime);
291
292   return subFetchAndInitLevelB;
293 } // subFetchAndInitLevelb
294
295 int subFetchAndInitLevelA(boolean UpdatePlayTime)
296 {
297   int subFetchAndInitLevelA;
298
299   if (UpdatePlayTime && (0 == demo_stopped))
300   {
301     subUpdatePlayingTime();                 // update playing time
302   }
303
304   D_ModeFlag = 0; // 1=debug D pressed (CPU use)
305   if (0 != demo_stopped) // 1=demo, 0=game
306     DemoFlag = 1;
307
308   GameBusyFlag = 0; // restore scissors too
309   subFetchAndInitLevel();   // Fetch and initialize a level
310   GameBusyFlag = 1; // no free screen write
311   if (1 <= demo_stopped)
312   {
313     if (1 == demo_stopped)
314     {
315       DemoFlag = 0; // 1=demo, 0=game
316       demo_stopped = demo_stopped + 1;
317     }
318     else
319     {
320       DemoFlag = 0; // 1=demo, 0=game
321     }
322   }
323
324   DemoKeyCode = 0; // delete last demo key!
325   if (DemoFlag != 0) // don't allow during game! only in Demo
326   {
327     DemoOffset = DemoPointer;           // init demo pointer
328     DemoKeyRepeatCounter = 1;
329     subGetNextDemoKey();                 // get next demo byte
330   }
331
332   return subFetchAndInitLevelA;
333 } // subFetchAndInitLevela
334
335 int subFetchAndInitLevel()
336 {
337   int subFetchAndInitLevel;
338
339   int InfoCountInLevel;
340
341   Trace("modInitGameConditions", "--> subFetchAndInitLevel");
342   Trace("modInitGameConditions", "Call ReadLevel");
343   ReadLevel();                   // Read LEVELS.DAT
344   Trace("modInitGameConditions", "ReadLevel return subFetchAndInitLeveled");
345
346   if (RecordDemoFlag == 1)
347   {
348     RecDemoRandomSeed = RandomSeed;
349     // Debug.Print "FetchRec: " & Hex(RandomSeed)
350   }
351
352   //  If DemoFlag = 1 Then
353   // Debug.Print "FetchPlay: " & Hex(RandomSeed)
354   //  End If
355   GameBusyFlag = -GameBusyFlag;   // make <>1
356   Trace("modInitGameConditions", "subConvertToEasySymbols");
357   InfoCountInLevel = subConvertToEasySymbols(); // Convert to easy symbols
358   GameBusyFlag = -GameBusyFlag;     // restore
359   Trace("modInitGameConditions", "subDisplayLevel");
360   subDisplayLevel();               // Paint (Init) game field
361   subDisplayPanel();                 // Paint (Init) Panel
362   ResetInfotronsNeeded(InfoCountInLevel);  // and reset Infotron count
363   Data_SubRstFlg = 1;
364   Trace("modInitGameConditions", "subInitGameConditions");
365   subInitGameConditions();                 // Init game conditions (vars)
366   InitMurphyPos();                 // Locate Murphy + screen pos
367   Trace("modInitGameConditions", "<-- subFetchAndInitLevel");
368
369   return subFetchAndInitLevel;
370 } // subFetchAndInitLevel