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