0a73d7541a01ad675e4fdb1c0a95374768a9c207
[rocksndiamonds.git] / src / game_sp / Explosions.c
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
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
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
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
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
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
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
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
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 }