rnd-20090721-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   StretchedSprites.BltEx(MurphyScreenXPos, MurphyScreenYPos, fiMurphy);
100
101   MurphyScreenXPos = MurphyScreenXPos / Stretch;
102   MurphyScreenYPos = MurphyScreenYPos / Stretch;
103
104   subCalculateScreenScrollPos();           // calculate screen start addrs
105
106   printf("::: InitGameConditions.c: ScreenScroll{X,Y}Pos %d, %d\n",
107          ScreenScrollXPos, ScreenScrollYPos);
108
109   if (AutoScrollFlag)
110   {
111     if (bPlaying)
112     {
113       SoftScrollTo(ScreenScrollXPos, ScreenScrollYPos, 1000, 25);
114     }
115     else
116     {
117       ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
118     }
119   }
120
121   return InitMurphyPosB;
122 } // InitMurphyPosB
123
124 // ==========================================================================
125 //                              SUBROUTINE
126 // Convert to easy symbols and reset Infotron count If not ThenVer62
127 // ==========================================================================
128
129 int subConvertToEasySymbols()
130 {
131   int subConvertToEasySymbols;
132
133   // int ax, bx, cx, dx, di, X, Y, i;
134   // int ah, bh, ch, dh, al, bl, cl, dl, ZF;
135   int ax, bx, cx, dx, i;
136   int al;
137
138   bx = 0;
139   dx = 0;
140   cx = LevelMax + 1;
141   i = 0;
142
143 loc_g_26C9:
144   ax = PlayField16[i];
145   al = LowByte(ax);
146   if (al == 0xF1) // converted explosion?
147   {
148     MovLowByte(&PlayField16[i], 0x1F);      // restore explosions
149     goto loc_g_2778;
150   }
151
152   if (LowByte(GameBusyFlag) != 1) // free screen write?
153   {
154     if (ax == fiInfotron) // Infotron? -> yes--count!
155       goto loc_g_2704;
156
157     if (ax == fiSnikSnak) // Snik Snak? -> yes--rearrange
158       goto loc_g_2713;
159
160     if (ax == fiElectron) // Electron? -> yes--rearrange
161       goto loc_g_2741;
162   }
163
164   // test for fancy RAM Chips:
165   if (ax == fiRAMLeft || ax == fiRAMRight)
166     goto loc_g_2707;
167
168   if (ax == fiRAMTop || ax == fiRAMBottom)
169     goto loc_g_2707;
170
171   if (ax < fiHWFirst) // All but deco hardware?
172     goto loc_g_26F8;
173
174   if (ax < fiRAMTop) // Decorative hardware?
175     goto loc_g_270D;
176
177 loc_g_26F8:
178   if (ax < fiSpPortRight) // Gravity change ports only?
179     goto loc_g_2778;
180
181   if (ax < fiSnikSnak) // Gravity change port! 'loc_g_2702:
182     goto loc_g_276F;
183
184   goto loc_g_2778;
185
186 loc_g_2704:                                     // INFOTRON
187   dx = dx + 1;                      // Count Infotrons
188   goto loc_g_2778;
189
190 loc_g_2707:                                     // DECO RAM CHIPS
191   PlayField16[i] = fiRAM; // Convert to standard RAM chip
192   goto loc_g_2778;
193
194 loc_g_270D:                                     // DECO HARDWARE
195   PlayField16[i] = fiHardWare; // Convert to standard hardware
196   goto loc_g_2778;
197
198 loc_g_2713:                                     // SNIK-SNAK
199   if (PlayField16[i - 1] != 0) // 1 field left empty? -> no--try up
200     goto loc_g_271F;
201
202   MovHighByte(&PlayField16[i], 1); // turn left, step = NorthWest
203   goto loc_g_2778;
204
205 loc_g_271F:
206   if (PlayField16[i - FieldWidth] != 0) // 1 field up empty? -> no--try right
207     goto loc_g_2730;
208
209   PlayField16[i - FieldWidth] = 0x1011; // SnikSnak accessing from below, step = 0
210   PlayField16[i] = 0xFFFF;
211   goto loc_g_2778;
212
213 loc_g_2730:
214   if (PlayField16[i + 1] != 0) // 1 field right empty? -> point up
215     goto loc_g_2778;
216
217   PlayField16[i + 1] = 0x2811; // SnikSnak accessing from left, step = 0
218   PlayField16[i] = 0xFFFF;
219   goto loc_g_2778;
220
221 loc_g_2741:                                     // ELECTRON
222   if (PlayField16[i - 1] != 0) // 1 field left empty? -> no--try up
223     goto loc_g_274D;
224
225   MovHighByte(&PlayField16[i], 1);
226   goto loc_g_2778;
227
228 loc_g_274D:
229   if (PlayField16[i - FieldWidth] != 0) // 1 field up empty? -> no--try right
230     goto loc_g_275E;
231
232   PlayField16[i - FieldWidth] = 0x1018; // 1 field up
233   PlayField16[i] = 0xFFFF;
234   goto loc_g_2778;
235
236 loc_g_275E:
237   if (PlayField16[i + 1] != 0) // 1 field right empty? -> no--point down
238     goto loc_g_2778;
239
240   PlayField16[i + 1] = 0x2818;
241   PlayField16[i] = 0xFFFF;
242   goto loc_g_2778;
243
244 loc_g_276F:                                     // GRAVITY CHANGING PORTS
245   PlayField16[i] = (ax - 4) | 0x100;    // Convert to standard ports
246   goto loc_g_2778;
247
248 loc_g_2778:
249   i = i + 1;                   // Next field
250   bx = bx + 1;
251   cx = cx - 1;
252   if (0 < cx) // Until all done 'loc_g_2782:
253     goto loc_g_26C9;
254
255   subConvertToEasySymbols = dx; // return InfotronCount
256
257   return subConvertToEasySymbols;
258 } // subConvertToEasySymbols
259
260 // ==========================================================================
261 //                              SUBROUTINE
262 // Reset Infotron count.  Call immediately after subConvertToEasySymbols
263 // ==========================================================================
264
265 int ResetInfotronsNeeded(int dx)
266 {
267   int ResetInfotronsNeeded;
268
269   if (LInfo.InfotronsNeeded != 0) // Jump If equal (autodetect)
270   {
271     dx = LInfo.InfotronsNeeded;
272   }                            // loc_g_278D:
273
274   InfotronsNeeded = LowByte(dx);           // Remaining Infotrons needed
275   TotalInfotronsNeeded = InfotronsNeeded;          // Number of Infotrons needed
276   subDisplayInfotronsNeeded();
277
278   return ResetInfotronsNeeded;
279 } // ResetInfotronsNeeded
280
281
282 // ==========================================================================
283 //                              SUBROUTINE
284 // Fetch and initialize a level
285 // ==========================================================================
286
287 int subFetchAndInitLevelB()
288 {
289   int subFetchAndInitLevelB;
290
291   boolean UpdatePlayTime;
292
293   MovLowByte(&data_SPtorunavail, 0);   // no SP file
294   data_scr_demo = 0;
295   UpdatePlayTime = (0 == demo_stopped ?  True :  True);
296   demo_stopped = 0;
297   subFetchAndInitLevelA(UpdatePlayTime);
298
299   return subFetchAndInitLevelB;
300 } // subFetchAndInitLevelb
301
302 int subFetchAndInitLevelA(boolean UpdatePlayTime)
303 {
304   int subFetchAndInitLevelA;
305
306   if (UpdatePlayTime && (0 == demo_stopped))
307   {
308     subUpdatePlayingTime();                 // update playing time
309   }
310
311   D_ModeFlag = 0; // 1=debug D pressed (CPU use)
312   if (0 != demo_stopped) // 1=demo, 0=game
313     DemoFlag = 1;
314
315   GameBusyFlag = 0; // restore scissors too
316
317   subFetchAndInitLevel();   // Fetch and initialize a level
318
319   GameBusyFlag = 1; // no free screen write
320
321   if (1 <= demo_stopped)
322   {
323     if (1 == demo_stopped)
324     {
325       DemoFlag = 0; // 1=demo, 0=game
326       demo_stopped = demo_stopped + 1;
327     }
328     else
329     {
330       DemoFlag = 0; // 1=demo, 0=game
331     }
332   }
333
334   DemoKeyCode = 0; // delete last demo key!
335   if (DemoFlag != 0) // don't allow during game! only in Demo
336   {
337     DemoOffset = DemoPointer;           // init demo pointer
338     DemoKeyRepeatCounter = 1;
339     subGetNextDemoKey();                 // get next demo byte
340   }
341
342   return subFetchAndInitLevelA;
343 } // subFetchAndInitLevela
344
345 int subFetchAndInitLevel()
346 {
347   int subFetchAndInitLevel;
348
349   int InfoCountInLevel;
350
351   Trace("modInitGameConditions", "--> subFetchAndInitLevel");
352   Trace("modInitGameConditions", "Call ReadLevel");
353
354   ReadLevel();                   // Read LEVELS.DAT
355
356   Trace("modInitGameConditions", "ReadLevel return subFetchAndInitLeveled");
357
358   if (RecordDemoFlag == 1)
359   {
360     RecDemoRandomSeed = RandomSeed;
361     // Debug.Print "FetchRec: " & Hex(RandomSeed)
362   }
363
364   //  If DemoFlag = 1 Then
365   // Debug.Print "FetchPlay: " & Hex(RandomSeed)
366   //  End If
367   GameBusyFlag = -GameBusyFlag;   // make <>1
368
369   Trace("modInitGameConditions", "subConvertToEasySymbols");
370
371   InfoCountInLevel = subConvertToEasySymbols(); // Convert to easy symbols
372   GameBusyFlag = -GameBusyFlag;     // restore
373
374   Trace("modInitGameConditions", "subDisplayLevel");
375
376   subDisplayLevel();               // Paint (Init) game field
377   subDisplayPanel();                 // Paint (Init) Panel
378
379   ResetInfotronsNeeded(InfoCountInLevel);  // and reset Infotron count
380
381   Data_SubRstFlg = 1;
382
383   Trace("modInitGameConditions", "subInitGameConditions");
384
385   subInitGameConditions();                 // Init game conditions (vars)
386
387   InitMurphyPos();                 // Locate Murphy + screen pos
388
389   Trace("modInitGameConditions", "<-- subFetchAndInitLevel");
390
391   return subFetchAndInitLevel;
392 } // subFetchAndInitLevel