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