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