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