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