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