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