rnd-20100313-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 #if 1
158   subSoundFX(si, ax, actExploding);
159 #else
160   subSoundFXExplosion();
161 #endif
162 } // ExplodeFieldSP
163
164 static void LetExplodeFieldSP(int tsi, int cx, int dh)
165 {
166   int al;
167
168   if (tsi < (-FieldWidth))
169     return;
170
171   al = LowByte(PlayField16[tsi]);
172 #if 0
173   printf("::: LetExplodeFieldSP: got %d [%d, %d] [%d]\n",
174          al, PlayField16[tsi], tsi, FrameCounter);
175 #endif
176   switch (al)
177   {
178     case fiHardWare:
179       return;
180
181       break;
182
183     case fiOrangeDisk:
184     case fiYellowDisk:
185     case fiSnikSnak:
186       PlayField8[tsi] = dh;
187       PlayField16[tsi] = cx;
188       break;
189
190     case fiZonk:
191       subExplodeZonk(tsi, cx);
192       break;
193
194     case fiInfotron:
195       subExplodeInfotron(tsi, cx);
196       break;
197
198     case fiElectron:
199       PlayField8[tsi] = (-dh) & 0xFF;
200       PlayField16[tsi] = 0x801F;
201       break;
202
203     case fiMurphy:
204 #if 1
205       printf("::: Explosions.c: LetExplodeFieldSP(): killing murphy [%d]\n",
206              tsi);
207 #endif
208
209       KillMurphyFlag = 1;
210       PlayField8[tsi] = dh;
211       PlayField16[tsi] = cx;
212       break;
213
214     default:
215       PlayField16[tsi] = cx;
216       break;
217   }
218
219   GfxGraphic[GetX(tsi)][GetY(tsi)] = -1;        // restart for chain-explosions
220 }
221
222 static int subExplodeZonk(int tsi, int cx)
223 {
224   static int subExplodeZonk;
225
226   int ah;
227
228   ah = HighByte(PlayField16[tsi]) & 0xF0;
229   PlayField16[tsi] = cx;
230   switch (ah)
231   {
232     case 0x10:
233     case 0x70:
234       subClearFieldDueToExplosion(tsi - FieldWidth);
235       tsi = tsi + FieldWidth;
236       if (PlayField16[tsi] == 0x9999)
237         subClearFieldDueToExplosion(tsi);
238
239       break;
240
241     case 0x20:
242       subClearFieldDueToExplosion(tsi + 1);
243       subClearFieldDueToExplosion(tsi + FieldWidth);
244       break;
245
246     case 0x30:
247       subClearFieldDueToExplosion(tsi - 1);
248       subClearFieldDueToExplosion(tsi + FieldWidth);
249       break;
250
251     case 0x50:
252       subClearFieldDueToExplosion(tsi - 1);
253       break;
254
255     case 0x60:
256       subClearFieldDueToExplosion(tsi + 1);
257       break;
258
259     case 0xFF000070: // !!! 0x70; this will never be reached! ...??
260       subClearFieldDueToExplosion(tsi + FieldWidth);
261       break;
262   }
263
264   return subExplodeZonk;
265 } // subExplodeZonk
266
267 static int subExplodeInfotron(int tsi, int cx)
268 {
269   static int subExplodeInfotron;
270
271   int ah;
272
273   ah = HighByte(PlayField16[tsi]) & 0xF0;
274   PlayField16[tsi] = cx;
275   switch (ah)
276   {
277     case 0x10:
278     case 0x70:
279       subClearFieldDueToExplosion(tsi - FieldWidth);
280       tsi = tsi + FieldWidth;
281       if (PlayField16[tsi] == 0x9999)
282         subClearFieldDueToExplosion(tsi);
283
284       break;
285
286     case 0x20:
287       subClearFieldDueToExplosion(tsi + 1);
288       tsi = tsi + FieldWidth; // differnt from zonk version
289       if (PlayField16[tsi] == 0x9999)
290         subClearFieldDueToExplosion(tsi);
291
292       break;
293
294     case 0x30:
295       subClearFieldDueToExplosion(tsi - 1);
296       tsi = tsi + FieldWidth; // differnt from zonk version
297       if (PlayField16[tsi] == 0x9999)
298         subClearFieldDueToExplosion(tsi);
299
300       break;
301
302     case 0x50:
303       subClearFieldDueToExplosion(tsi - 1);
304       break;
305
306     case 0x60:
307       subClearFieldDueToExplosion(tsi + 1);
308       break;
309
310     case 0xFF000070: // !!! 0x70; this will never be reached! ...??
311       subClearFieldDueToExplosion(tsi + FieldWidth);
312       break;
313   }
314
315   return subExplodeInfotron;
316 } // subExplodeInfotron
317
318 int subClearFieldDueToExplosion(int si)
319 {
320   int subClearFieldDueToExplosion;
321
322   int X, Y;
323
324   if (LowByte(PlayField16[si]) == fiExplosion)
325     return subClearFieldDueToExplosion;
326
327   PlayField16[si] = 0;
328   // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
329   X = GetStretchX(si);
330   Y = GetStretchY(si);
331 #if 1
332
333 #if 1
334   GfxGraphic[GetX(si)][GetY(si)] = aniSpace;
335 #else
336   StretchedSprites.BltImg(X, Y, aniSpace, 0);
337 #endif
338
339 #else
340   StretchedSprites.BltEx(X, Y, fiSpace);
341 #endif
342   // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
343
344   return subClearFieldDueToExplosion;
345 } // subClearFieldDueToExplosion
346
347 int subRedDiskReleaseExplosion()
348 {
349   int subRedDiskReleaseExplosion;
350
351   int al, X, Y, si;
352
353   al = RedDiskReleasePhase;            // Red disk release phase
354   if (al <= 1)
355     return subRedDiskReleaseExplosion;
356
357   si = RedDiskReleaseMurphyPos;
358   if (PlayField16[si] == 0) // Release red disk
359     PlayField16[si] = fiRedDisk;
360
361   // +++++++++++++++++++++++++++++++++++++++++
362   X = GetStretchX(si);
363   Y = GetStretchY(si);
364 #if 1
365
366 #if 0
367   // !!! causes flicker -- fix in Murphy.c !!!
368   GfxGraphic[GetX(si)][GetY(si)] = aniRedDisk;
369 #else
370   StretchedSprites.BltImg(X, Y, aniRedDisk, 0);
371 #endif
372
373 #else
374   StretchedSprites.BltEx(X, Y, fiRedDisk);
375 #endif
376   // +++++++++++++++++++++++++++++++++++++++++
377   RedDiskReleasePhase = RedDiskReleasePhase + 1;
378   if (RedDiskReleasePhase >= 0x28)
379   {
380     // si = RedDiskReleaseMurphyPos           ' Red disk was released here
381     ExplodeFieldSP(si);                 // Explode
382     RedDiskReleasePhase = 0;
383   }
384
385   return subRedDiskReleaseExplosion;
386 }
387
388 int subFollowUpExplosions()
389 {
390   int subFollowUpExplosions;
391
392   int ax, si;
393
394   // locloop_g_2919:
395   for (si = 0; si <= LevelMax; si++)
396   {
397     ax = ByteToInt(PlayField8[si]);
398     if (ax != 0)
399     {
400       if (ax < 0)
401       {
402         ax = ax + 1;
403         PlayField8[si] = ax & 0xFF;
404         if (ax == 0)
405         {
406           PlayField16[si] = 0xFF18;
407           ExplodeFieldSP(si);                 // Explode
408         }
409
410       }
411       else
412       {
413         ax = ax - 1;
414         PlayField8[si] = ax;
415         if (ax == 0)
416           ExplodeFieldSP(si);
417       }
418     }
419   }
420
421   return subFollowUpExplosions;
422 } // subFollowUpExplosions