1 // ----------------------------------------------------------------------------
2 // Explosions.c
3 // ----------------------------------------------------------------------------
4
5 #include "Explosions.h"
6
7
8 static void LetExplodeFieldSP(int tsi, int cx, int dh);
9 static void subExplodeInfotron(int tsi, int cx);
10 static void subExplodeZonk(int tsi, int cx);
11
12
13 // ==========================================================================
14 // SUBROUTINE
15 // Animate explosion
16 // ==========================================================================
17
subAnimateExplosion(int si)18 void subAnimateExplosion(int si)
19 {
20 int ax, bl;
21 #if 0
22 int X, Y;
23 #endif
24
25 if (LowByte(PlayField16[si]) != fiExplosion)
26 return;
27
28 ax = (TimerVar & 3);
29 if (ax != 0)
30 return;
31
32 bl = HighByte(PlayField16[si]);
33
34 if ((bl & 0x80) != 0) // infotron explosion!
35 goto loc_g_28D0;
36
37 bl = bl + 1;
38 MovHighByte(&PlayField16[si], bl);
39
40 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
41 #if 0
42 X = GetStretchX(si);
43 Y = GetStretchY(si);
44 #endif
45 GfxGraphic[GetX(si)][GetY(si)] = aniDefaultExplosion;
46 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
47
48 if (bl == 8)
49 {
50 PlayField16[si] = 0;
51 ExplosionShake = 0; // nothing explodes
52 // ExplosionShakeMurphy = 0; // nothing explodes
53
54 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
55 GfxGraphic[GetX(si)][GetY(si)] = aniSpace;
56 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
57 } // loc_ret_g_28CF:
58
59 return;
60
61 loc_g_28D0: // explosion produces infotron
62 bl = bl + 1;
63 if (bl == 0x89)
64 {
65 PlayField16[si] = fiInfotron;
66 MovLowByte(&ExplosionShake, 0); // nothing explodes
67 // MovLowByte(&ExplosionShakeMurphy, 0); // nothing explodes
68
69 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
70 GfxGraphic[GetX(si)][GetY(si)] = aniInfotron;
71 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
72
73 return;
74 } // loc_g_28E3:
75
76 MovHighByte(&PlayField16[si], bl);
77
78 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
79 #if 0
80 X = GetStretchX(si);
81 Y = GetStretchY(si);
82 #endif
83 GfxGraphic[GetX(si)][GetY(si)] = aniElectronExplosion;
84 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
85 }
86
87 // ==========================================================================
88 // SUBROUTINE
89 // Explode
90 // ==========================================================================
91
ExplodeFieldSP(int si)92 void ExplodeFieldSP(int si)
93 {
94 int ax, cx, dl;
95
96 ax = LowByte(PlayField16[si]);
97 if (ax == fiHardWare)
98 return;
99
100 ExplosionShake = 1; // something explodes
101
102 if (ax == fiMurphy)
103 {
104 #if 0
105 printf("::: Explosions.c: ExplodeFieldSP(): killing murphy\n");
106 #endif
107
108 KillMurphyFlag = 1;
109
110 #if 1
111 ExplosionShakeMurphy = 30; // Murphy explodes
112 #endif
113 }
114
115 if (ax == fiElectron)
116 {
117 cx = 0x801F; // produce infotrons
118 dl = 0xF3;
119 }
120 else // loc_g_2977:
121 {
122 cx = 0x1F; // normal explosion
123 dl = 0xD;
124 } // loc_g_297C:
125
126 LetExplodeFieldSP(si - FieldWidth - 1, cx, dl);
127 LetExplodeFieldSP(si - FieldWidth, cx, dl);
128 LetExplodeFieldSP(si - FieldWidth + 1, cx, dl);
129 LetExplodeFieldSP(si - 1, cx, dl);
130 PlayField16[si] = cx;
131 LetExplodeFieldSP(si + 1, cx, dl);
132 LetExplodeFieldSP(si + FieldWidth - 1, cx, dl);
133 LetExplodeFieldSP(si + FieldWidth, cx, dl);
134 LetExplodeFieldSP(si + FieldWidth + 1, cx, dl);
135
136 GfxGraphic[GetX(si)][GetY(si)] = -1; // restart for chain-explosions
137
138 // loc_g_2C3B:
139 subSoundFX(si, ax, actExploding);
140 }
141
LetExplodeFieldSP(int tsi,int cx,int dh)142 static void LetExplodeFieldSP(int tsi, int cx, int dh)
143 {
144 int al;
145
146 if (tsi < -FieldWidth)
147 return;
148
149 al = LowByte(PlayField16[tsi]);
150 switch (al)
151 {
152 case fiHardWare:
153 return;
154
155 break;
156
157 case fiOrangeDisk:
158 case fiYellowDisk:
159 case fiSnikSnak:
160 PlayField8[tsi] = dh;
161 PlayField16[tsi] = cx;
162 break;
163
164 case fiZonk:
165 subExplodeZonk(tsi, cx);
166 break;
167
168 case fiInfotron:
169 subExplodeInfotron(tsi, cx);
170 break;
171
172 case fiElectron:
173 PlayField8[tsi] = (-dh) & 0xFF;
174 PlayField16[tsi] = 0x801F;
175 break;
176
177 case fiMurphy:
178 #if 0
179 printf("::: Explosions.c: LetExplodeFieldSP(): killing murphy [%d]\n",
180 tsi);
181 #endif
182
183 KillMurphyFlag = 1;
184 PlayField8[tsi] = dh;
185 PlayField16[tsi] = cx;
186 break;
187
188 default:
189 PlayField16[tsi] = cx;
190 break;
191 }
192
193 GfxGraphic[GetX(tsi)][GetY(tsi)] = -1; // restart for chain-explosions
194 }
195
subExplodeZonk(int tsi,int cx)196 static void subExplodeZonk(int tsi, int cx)
197 {
198 int ah;
199
200 ah = HighByte(PlayField16[tsi]) & 0xF0;
201 PlayField16[tsi] = cx;
202 switch (ah)
203 {
204 case 0x10:
205 case 0x70:
206 subClearFieldDueToExplosion(tsi - FieldWidth);
207 tsi = tsi + FieldWidth;
208 if (PlayField16[tsi] == 0x9999)
209 subClearFieldDueToExplosion(tsi);
210
211 break;
212
213 case 0x20:
214 subClearFieldDueToExplosion(tsi + 1);
215 subClearFieldDueToExplosion(tsi + FieldWidth);
216 break;
217
218 case 0x30:
219 subClearFieldDueToExplosion(tsi - 1);
220 subClearFieldDueToExplosion(tsi + FieldWidth);
221 break;
222
223 case 0x50:
224 subClearFieldDueToExplosion(tsi - 1);
225 break;
226
227 case 0x60:
228 subClearFieldDueToExplosion(tsi + 1);
229 break;
230
231 case 0xFF000070: // !!! 0x70; this will never be reached! ...??
232 subClearFieldDueToExplosion(tsi + FieldWidth);
233 break;
234 }
235 }
236
subExplodeInfotron(int tsi,int cx)237 static void subExplodeInfotron(int tsi, int cx)
238 {
239 int ah;
240
241 ah = HighByte(PlayField16[tsi]) & 0xF0;
242 PlayField16[tsi] = cx;
243 switch (ah)
244 {
245 case 0x10:
246 case 0x70:
247 subClearFieldDueToExplosion(tsi - FieldWidth);
248 tsi = tsi + FieldWidth;
249 if (PlayField16[tsi] == 0x9999)
250 subClearFieldDueToExplosion(tsi);
251
252 break;
253
254 case 0x20:
255 subClearFieldDueToExplosion(tsi + 1);
256 tsi = tsi + FieldWidth; // differnt from zonk version
257 if (PlayField16[tsi] == 0x9999)
258 subClearFieldDueToExplosion(tsi);
259
260 break;
261
262 case 0x30:
263 subClearFieldDueToExplosion(tsi - 1);
264 tsi = tsi + FieldWidth; // differnt from zonk version
265 if (PlayField16[tsi] == 0x9999)
266 subClearFieldDueToExplosion(tsi);
267
268 break;
269
270 case 0x50:
271 subClearFieldDueToExplosion(tsi - 1);
272 break;
273
274 case 0x60:
275 subClearFieldDueToExplosion(tsi + 1);
276 break;
277
278 case 0xFF000070: // !!! 0x70; this will never be reached! ...??
279 subClearFieldDueToExplosion(tsi + FieldWidth);
280 break;
281 }
282 }
283
subClearFieldDueToExplosion(int si)284 void subClearFieldDueToExplosion(int si)
285 {
286 #if 0
287 int X, Y;
288 #endif
289
290 if (LowByte(PlayField16[si]) == fiExplosion)
291 return;
292
293 PlayField16[si] = 0;
294 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
295 #if 0
296 X = GetStretchX(si);
297 Y = GetStretchY(si);
298 #endif
299 GfxGraphic[GetX(si)][GetY(si)] = aniSpace;
300 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
301 }
302
subRedDiskReleaseExplosion()303 void subRedDiskReleaseExplosion()
304 {
305 int al, X, Y, si;
306
307 al = RedDiskReleasePhase; // Red disk release phase
308 if (al <= 1)
309 return;
310
311 si = RedDiskReleaseMurphyPos;
312 if (PlayField16[si] == 0) // Release red disk
313 PlayField16[si] = fiRedDisk;
314
315 // +++++++++++++++++++++++++++++++++++++++++
316 X = GetStretchX(si);
317 Y = GetStretchY(si);
318 #if 0
319 // !!! causes flicker -- fix in Murphy.c !!!
320 GfxGraphic[GetX(si)][GetY(si)] = aniRedDisk;
321 #else
322 DDSpriteBuffer_BltImg(X, Y, aniRedDisk, 0);
323 #endif
324 // +++++++++++++++++++++++++++++++++++++++++
325
326 RedDiskReleasePhase = RedDiskReleasePhase + 1;
327 if (RedDiskReleasePhase >= 0x28)
328 {
329 // si = RedDiskReleaseMurphyPos ' Red disk was released here
330 ExplodeFieldSP(si); // Explode
331 RedDiskReleasePhase = 0;
332 }
333 }
334
subFollowUpExplosions()335 void subFollowUpExplosions()
336 {
337 int ax, si;
338
339 // locloop_g_2919:
340 for (si = 0; si <= LevelMax; si++)
341 {
342 ax = ByteToInt(PlayField8[si]);
343 if (ax != 0)
344 {
345 if (ax < 0)
346 {
347 ax = ax + 1;
348 PlayField8[si] = ax & 0xFF;
349 if (ax == 0)
350 {
351 PlayField16[si] = 0xFF18;
352 ExplodeFieldSP(si); // Explode
353 }
354 }
355 else
356 {
357 ax = ax - 1;
358 PlayField8[si] = ax;
359 if (ax == 0)
360 ExplodeFieldSP(si);
361 }
362 }
363 }
364 }
365