rnd-20090623-4-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     KillMurphyFlag = 1;
87
88   if (ax == fiElectron)
89   {
90     cx = 0x801F; // produce infotrons
91     dl = 0xF3;
92   }
93   else // loc_g_2977:
94   {
95     cx = 0x1F; // normal explosion
96     dl = 0xD;
97   } // loc_g_297C:
98
99   LetExplodeFieldSP(si - FieldWidth - 1, cx, dl);
100   LetExplodeFieldSP(si - FieldWidth, cx, dl);
101   LetExplodeFieldSP(si - FieldWidth + 1, cx, dl);
102   LetExplodeFieldSP(si - 1, cx, dl);
103   PlayField16[si] = cx;
104   LetExplodeFieldSP(si + 1, cx, dl);
105   LetExplodeFieldSP(si + FieldWidth - 1, cx, dl);
106   LetExplodeFieldSP(si + FieldWidth, cx, dl);
107   LetExplodeFieldSP(si + FieldWidth + 1, cx, dl);
108
109   // loc_g_2C3B:
110   subSoundFXExplosion();
111 } // ExplodeFieldSP
112
113 static void LetExplodeFieldSP(int tsi, int cx, int dh)
114 {
115   int al;
116
117   if (tsi < (-FieldWidth))
118     return;
119
120   al = LowByte(PlayField16[tsi]);
121   switch (al)
122   {
123     case fiHardWare:
124       return;
125
126       break;
127
128     case fiOrangeDisk:
129     case fiYellowDisk:
130     case fiSnikSnak:
131       PlayField8[tsi] = dh;
132       PlayField16[tsi] = cx;
133       break;
134
135     case fiZonk:
136       subExplodeZonk(tsi, cx);
137       break;
138
139     case fiInfotron:
140       subExplodeInfotron(tsi, cx);
141       break;
142
143     case fiElectron:
144       PlayField8[tsi] = (-dh) & 0xFF;
145       PlayField16[tsi] = 0x801F;
146       break;
147
148     case fiMurphy:
149       KillMurphyFlag = 1;
150       PlayField8[tsi] = dh;
151       PlayField16[tsi] = cx;
152       break;
153
154     default:
155       PlayField16[tsi] = cx;
156       break;
157   }
158 }
159
160 static int subExplodeZonk(int tsi, int cx)
161 {
162   static int subExplodeZonk;
163
164   int ah;
165
166   ah = HighByte(PlayField16[tsi]) & 0xF0;
167   PlayField16[tsi] = cx;
168   switch (ah)
169   {
170     case 0x10:
171     case 0x70:
172       subClearFieldDueToExplosion(tsi - FieldWidth);
173       tsi = tsi + FieldWidth;
174       if (PlayField16[tsi] == 0x9999)
175         subClearFieldDueToExplosion(tsi);
176
177       break;
178
179     case 0x20:
180       subClearFieldDueToExplosion(tsi + 1);
181       subClearFieldDueToExplosion(tsi + FieldWidth);
182       break;
183
184     case 0x30:
185       subClearFieldDueToExplosion(tsi - 1);
186       subClearFieldDueToExplosion(tsi + FieldWidth);
187       break;
188
189     case 0x50:
190       subClearFieldDueToExplosion(tsi - 1);
191       break;
192
193     case 0x60:
194       subClearFieldDueToExplosion(tsi + 1);
195       break;
196
197     case 0xFF000070: // !!! 0x70; this will never be reached! ...??
198       subClearFieldDueToExplosion(tsi + FieldWidth);
199       break;
200   }
201
202   return subExplodeZonk;
203 } // subExplodeZonk
204
205 static int subExplodeInfotron(int tsi, int cx)
206 {
207   static int subExplodeInfotron;
208
209   int ah;
210
211   ah = HighByte(PlayField16[tsi]) & 0xF0;
212   PlayField16[tsi] = cx;
213   switch (ah)
214   {
215     case 0x10:
216     case 0x70:
217       subClearFieldDueToExplosion(tsi - FieldWidth);
218       tsi = tsi + FieldWidth;
219       if (PlayField16[tsi] == 0x9999)
220         subClearFieldDueToExplosion(tsi);
221
222       break;
223
224     case 0x20:
225       subClearFieldDueToExplosion(tsi + 1);
226       tsi = tsi + FieldWidth; // differnt from zonk version
227       if (PlayField16[tsi] == 0x9999)
228         subClearFieldDueToExplosion(tsi);
229
230       break;
231
232     case 0x30:
233       subClearFieldDueToExplosion(tsi - 1);
234       tsi = tsi + FieldWidth; // differnt from zonk version
235       if (PlayField16[tsi] == 0x9999)
236         subClearFieldDueToExplosion(tsi);
237
238       break;
239
240     case 0x50:
241       subClearFieldDueToExplosion(tsi - 1);
242       break;
243
244     case 0x60:
245       subClearFieldDueToExplosion(tsi + 1);
246       break;
247
248     case 0xFF000070: // !!! 0x70; this will never be reached! ...??
249       subClearFieldDueToExplosion(tsi + FieldWidth);
250       break;
251   }
252
253   return subExplodeInfotron;
254 } // subExplodeInfotron
255
256 int subClearFieldDueToExplosion(int si)
257 {
258   int subClearFieldDueToExplosion;
259
260   int X, Y;
261
262   if (LowByte(PlayField16[si]) == fiExplosion)
263     return subClearFieldDueToExplosion;
264
265   PlayField16[si] = 0;
266   // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
267   X = GetStretchX(si);
268   Y = GetStretchY(si);
269   StretchedSprites.BltEx(X, Y, fiSpace);
270   // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
271
272   return subClearFieldDueToExplosion;
273 } // subClearFieldDueToExplosion
274
275 int subRedDiskReleaseExplosion()
276 {
277   int subRedDiskReleaseExplosion;
278
279   int al, X, Y, si;
280
281   al = RedDiskReleasePhase;            // Red disk release phase
282   if (al <= 1)
283     return subRedDiskReleaseExplosion;
284
285   si = RedDiskReleaseMurphyPos;
286   if (PlayField16[si] == 0) // Release red disk
287     PlayField16[si] = fiRedDisk;
288
289   // +++++++++++++++++++++++++++++++++++++++++
290   X = GetStretchX(si);
291   Y = GetStretchY(si);
292   StretchedSprites.BltEx(X, Y, fiRedDisk);
293   // +++++++++++++++++++++++++++++++++++++++++
294   RedDiskReleasePhase = RedDiskReleasePhase + 1;
295   if (RedDiskReleasePhase >= 0x28)
296   {
297     // si = RedDiskReleaseMurphyPos           ' Red disk was released here
298     ExplodeFieldSP(si);                 // Explode
299     RedDiskReleasePhase = 0;
300   }
301
302   return subRedDiskReleaseExplosion;
303 }
304
305 int subFollowUpExplosions()
306 {
307   int subFollowUpExplosions;
308
309   int ax, si;
310
311   // locloop_g_2919:
312   for (si = 0; si <= LevelMax; si++)
313   {
314     ax = ByteToInt(PlayField8[si]);
315     if (ax != 0)
316     {
317       if (ax < 0)
318       {
319         ax = ax + 1;
320         PlayField8[si] = ax & 0xFF;
321         if (ax == 0)
322         {
323           PlayField16[si] = 0xFF18;
324           ExplodeFieldSP(si);                 // Explode
325         }
326
327       }
328       else
329       {
330         ax = ax - 1;
331         PlayField8[si] = ax;
332         if (ax == 0)
333           ExplodeFieldSP(si);
334       }
335     }
336   }
337
338   return subFollowUpExplosions;
339 } // subFollowUpExplosions