rnd-20100316-1-src
[rocksndiamonds.git] / src / game_sp / Zonk.c
1 // ----------------------------------------------------------------------------
2 // Zonk.c
3 // ----------------------------------------------------------------------------
4
5 #include "Zonk.h"
6
7 // static char *VB_Name = "modZonk";
8 // --- Option Explicit
9
10 // ==========================================================================
11 //                              SUBROUTINE
12 // Animate Zonks (falling)
13 // ==========================================================================
14
15 int subAnimateZonks(int si)
16 {
17   int subAnimateZonks;
18
19   int tFld;
20
21   // PseudoRegisters:
22   // int ax, bx, cx, dx, di, X, Y;
23   int ax, bx, dx, X, Y;
24   // int ah, bh, ch, dh, al, bl, cl, dl;
25   int al, bl;
26
27   tFld = PlayField16[si];
28   if ((tFld & 0xFF) != fiZonk)
29     return subAnimateZonks;
30
31   if (tFld == fiZonk)
32   {
33     if (FreezeZonks == 2) // Do Zonks fall? (debug)
34       return subAnimateZonks;
35
36     ax = PlayField16[si + FieldWidth]; // select case playfield16(si+60)
37     if (ax == 0)
38       goto loc_g_0D64;
39
40     if (ax == fiZonk)
41       goto loc_g_0D35;
42
43     if (ax == fiInfotron)
44       goto loc_g_0D35;
45
46     if (ax == fiRAM)
47       goto loc_g_0D35;
48
49     return subAnimateZonks;
50
51 loc_g_0D35: //        Case fiZonk, fiInfotron, fiRAM
52     ax = PlayField16[si + FieldWidth - 1];
53     if (ax == 0 || ax == 0x8888 || ax == 0xAAAA)
54       goto loc_g_0D6B;
55
56 loc_g_0D4C:
57     ax = PlayField16[si + FieldWidth + 1];
58     if (ax == 0 || ax == 0x8888 || ax == 0xAAAA)
59       goto loc_g_0D81;
60
61     return subAnimateZonks;
62
63 loc_g_0D64: //       Case fiSpace
64     MovHighByte(&PlayField16[si], 0x40);
65     goto loc_g_0DA5;
66
67 loc_g_0D6B: // roll left?
68     if (PlayField16[si - 1] == 0)
69       goto loc_g_0D74;
70
71     goto loc_g_0D4C;
72
73 loc_g_0D74:
74     MovHighByte(&PlayField16[si], 0x50);
75     PlayField16[si - 1] = 0x8888;
76     goto loc_g_0DA5;
77
78 loc_g_0D81: // roll right?
79     if (PlayField16[si + 1] == 0)
80       goto loc_g_0D98;
81
82     if (PlayField16[si + 1] != 0x9999) // wow right is different from left!
83       return subAnimateZonks;
84
85     if (LowByte(PlayField16[si - FieldWidth + 1]) != 1)
86       return subAnimateZonks;
87
88 loc_g_0D98:
89     MovHighByte(&PlayField16[si], 0x60);
90     PlayField16[si + 1] = 0x8888;
91   } // tFld = fiZonk
92
93 loc_g_0DA5:
94   // from now on the zonk is definitely moving,
95   // maybe the sequence is in an advanced frame
96   // or just beeing initialized due to the code above
97   bl = HighByte(PlayField16[si]);
98   bx = 0;
99   MovLowByte(&bx, bl);
100   al = bl & 0xF0;
101   if (al == 0x10) // zonk comes falling from above
102     goto loc_g_0DE8;
103
104   if (al == 0x20) // zonk comes rolling from right to left
105     goto loc_g_0F83;
106
107   if (al == 0x30) // zonk comes rolling from left to right
108     goto loc_g_0FE8;
109
110   if (FreezeZonks == 2)
111     return subAnimateZonks;
112
113   if (al == 0x40) // zonk falls straight down
114     goto loc_g_104D;
115
116   if (al == 0x50) // zonk rolls left
117     goto loc_g_107B;
118
119   if (al == 0x60) // zonk rolls right
120     goto loc_g_10E9;
121
122   if (al == 0x70) // intermediate state
123     goto loc_g_1157;
124
125   return subAnimateZonks;
126
127 loc_g_0DE8: // zonk comes falling from above
128   //      To Do: draw zonk falling from above
129   //      according to position in (bl And &H07)
130   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
131   X = GetStretchX(si);
132   Y = GetStretchY(si - FieldWidth);
133   dx = bl & 0x7;
134   DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
135   DDSpriteBuffer_BltImg(X, Y + TwoPixels * (dx + 1), aniZonk, dx);
136   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
137
138   bl = HighByte(PlayField16[si]) + 1;
139   if (bl == 0x16)
140   {
141     MovHighByte(&PlayField16[si], bl);
142     subCleanUpForZonksAbove(si - FieldWidth);
143     return subAnimateZonks;
144   } // loc_g_0E2B:
145
146   if (bl < 0x18)
147   {
148     MovHighByte(&PlayField16[si], bl);
149     return subAnimateZonks;
150   } // loc_g_0E35:
151
152   MovHighByte(&PlayField16[si], 0); // zonk arrived at the field
153   if ((FreezeZonks & 0xFF) == 2)
154     return subAnimateZonks;
155
156   // loc_g_0E42:     // now check if the zonk may go on falling somehow
157   ax = PlayField16[si + FieldWidth];
158   if (ax == 0) // below is empty!-> go on falling 'loc_g_0E4C:
159     goto loc_g_0EDD;
160
161   if (ax == 0x9999) // below is only temporarily used ' loc_g_0E57:
162     goto loc_g_0EDD;
163
164   if ((ax & 0xFF) == fiMurphy) // Murphy dies 'loc_g_0E61:
165     goto loc_g_0F14;
166
167   if ((ax & 0xFF) == fiSnikSnak) // SnikSnak dies 'loc_g_0E6B:
168     goto loc_g_0F6E;
169
170   if (ax == 0x2BB) // loc_g_0E76:
171     goto loc_g_0F36;
172
173   if (ax == 0x4BB) // loc_g_0E81:
174     goto loc_g_0F52;
175
176   if ((ax & 0xFF) == fiElectron) // Electron cracked! 'loc_g_0E8B:
177     goto loc_g_0F6E;
178
179   if (ax == fiOrangeDisk) // OrangeDisk explodes 'loc_g_0E95:
180     goto loc_g_0F75;
181
182 #if 1
183   // play the zonk sound, 'cause zonk hits something "hard"
184   subSoundFX(si, fiZonk, actImpact);
185 #else
186   subSoundFXZonk(); // play the zonk sound,'cause zonk hits something "hard"
187 #endif
188
189   if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM))
190     return subAnimateZonks;
191
192   // loc_g_0EAE: ' Zonk rolls somewhere
193   ax = PlayField16[si + FieldWidth - 1];
194   if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll left
195     goto loc_g_0EEA;
196
197   ax = PlayField16[si + FieldWidth + 1];
198   if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll right
199     goto loc_g_0F00;
200
201   return subAnimateZonks;
202
203 loc_g_0EDD:     // go on falling down?
204   PlayField16[si] = 0x7001; // go into intermediate waitstate
205   PlayField16[si + FieldWidth] = 0x9999; // mark as "zonk waiting to access"
206   return subAnimateZonks;
207
208 loc_g_0EEA:     // test if zonk may roll left
209   // This if(if true) jumps up far above
210   // to the according rountine for fixed zonks!
211   if (PlayField16[si - 1] != 0) // Remarkable!!! ' loc_g_0EF4:
212     goto loc_g_0D4C;
213
214   MovHighByte(&PlayField16[si], 0x50); // zonk rolls left
215   PlayField16[si - 1] = 0x8888; // mark as zonk accessing?
216   return subAnimateZonks;
217
218 loc_g_0F00:     // test if zonk may roll right
219   if (PlayField16[si + 1] != 0) // loc_g_0F08:
220     return subAnimateZonks;
221
222   MovHighByte(&PlayField16[si], 0x60); // zonk rolls right
223   PlayField16[si + 1] = 0x8888; // mark as zonk accessing?
224   return subAnimateZonks;
225
226 loc_g_0F14:     // Murphy dies, but not in any case
227   bl = HighByte(PlayField16[si + FieldWidth]);
228   if (bl == 0xE || bl == 0xF || bl == 0x28)
229     return subAnimateZonks;
230
231   if (bl == 0x29 || bl == 0x25 || bl == 0x26)
232     return subAnimateZonks;
233
234 loc_g_0F36:     // ??
235   ax = LowByte(PlayField16[si + FieldWidth - 1]);
236   if (ax == fiElectron) // loc_g_0F43:
237     PlayField16[si + FieldWidth] = fiElectron;
238
239   if (ax != 0x1F)
240     PlayField16[si + FieldWidth - 1] = 0;
241
242   goto loc_g_0F6E;
243
244 loc_g_0F52:     // ??
245   ax = LowByte(PlayField16[si + FieldWidth + 1]);
246   if (ax == fiElectron) // loc_g_0F5F:
247     PlayField16[si + FieldWidth] = fiElectron;
248
249   if (ax != 0x1F)
250     PlayField16[si + FieldWidth + 1] = 0;
251
252   goto loc_g_0F6E;
253
254 loc_g_0F6E:     // someone dies/explodes
255   si = si + FieldWidth;                 // 1 field down
256   ExplodeFieldSP(si);               // Explode
257   return subAnimateZonks;
258
259 loc_g_0F75:     // OrangeDisk explodes next cycle
260   si = si + FieldWidth;                 // 1 field down
261   PlayField8[si] = fiHardWare;
262   return subAnimateZonks;
263
264 loc_g_0F83: // zonk comes rolling from right to left
265   //  To Do: draw zonk rolling from right
266   //  according to position in (bl And &H07)
267   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
268   X = GetStretchX(si + 1);
269   Y = GetStretchY(si);
270   dx = (bl & 0x7) + 1;
271   DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
272   DDSpriteBuffer_BltImg(X - (TwoPixels * dx), Y, aniZonkRollLeft, dx - 1);
273   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
274
275   bl = HighByte(PlayField16[si]) + 1; // get and increment sequence#
276   if (bl == 0x24)
277     PlayField16[si + 1] = 0xAAAA;
278
279   if (bl == 0x26)
280   {
281     MovHighByte(&PlayField16[si], bl);
282     subCleanUpForZonksAbove(si + 1);
283   }
284   else if (bl < 0x28)
285   {
286     MovHighByte(&PlayField16[si], bl);
287   }
288   else
289   {
290     PlayField16[si] = 0xFFFF;
291     si = si + FieldWidth;                 // 1 field down
292     PlayField16[si] = 0x1001; // convert rolling zonk to a falling zonk
293   }
294
295   return subAnimateZonks;
296
297 loc_g_0FE8: // zonk comes rolling from left to right
298   //  To Do: draw zonk rolling from left
299   //  according to position in (bl And &H07)
300   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
301   X = GetStretchX(si - 1);
302   Y = GetStretchY(si);
303   dx = (bl & 0x7) + 1;
304   DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
305   DDSpriteBuffer_BltImg(X + (TwoPixels * dx), Y, aniZonkRollRight, dx - 1);
306   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
307
308   bl = HighByte(PlayField16[si]) + 1;
309   if (bl == 0x34)
310     PlayField16[si - 1] = 0xAAAA;
311
312   if (bl == 0x36)
313   {
314     MovHighByte(&PlayField16[si], bl);
315     subCleanUpForZonksAbove(si - 1);
316   }
317   else if (bl < 0x38)
318   {
319     MovHighByte(&PlayField16[si], bl);
320   }
321   else
322   {
323     PlayField16[si] = 0xFFFF;
324     si = si + FieldWidth;                   // 1 field down
325     PlayField16[si] = 0x1001; // convert rolling zonk to a falling zonk
326   }
327
328   return subAnimateZonks;
329
330 loc_g_104D: // zonk falls straight down
331   bl = bl + 1;
332   if (bl < 0x42)
333   {
334     MovHighByte(&PlayField16[si], bl);
335   }
336   else if (PlayField16[si + FieldWidth] != 0)
337   {
338     bl = bl - 1; // stay waiting
339     MovHighByte(&PlayField16[si], bl);
340   }
341   else
342   {
343     PlayField16[si] = 0xFFFF; // mark as "zonk leaving"
344     si = si + FieldWidth;                 // 1 field down
345     PlayField16[si] = 0x1001; // go falling
346   }
347
348   return subAnimateZonks;
349
350 loc_g_107B: // zonk rolls left
351   //  To Do: draw zonk rolling to left
352   //  according to position in (bl And &H0F)
353   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
354   X = GetStretchX(si);
355   Y = GetStretchY(si);
356   dx = (bl & 0xF) + 1;
357   DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
358   DDSpriteBuffer_BltImg(X - (TwoPixels * dx), Y, aniZonkRollLeft, dx - 1);
359   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
360
361   bl = HighByte(PlayField16[si]) + 1; // retrieve and increment sequence#
362   if (bl < 0x52)
363   {
364     MovHighByte(&PlayField16[si], bl);
365     return subAnimateZonks;
366   }
367
368   if (PlayField16[si + FieldWidth - 1] != 0)
369     goto loc_g_10E2;
370
371   if (PlayField16[si - 1] != 0)
372   {
373     if (PlayField16[si - 1] != 0x8888)
374       goto loc_g_10E2;
375   } // loc_g_10C8:
376
377   PlayField16[si] = 0xFFFF;
378   si = si - 1;                   // 1 field left
379   PlayField16[si] = 0x2201;
380   PlayField16[si + FieldWidth] = 0xFFFF;
381   return subAnimateZonks;
382
383 loc_g_10E2: // stay waiting
384   bl = bl - 1;
385   MovHighByte(&PlayField16[si], bl);
386   return subAnimateZonks;
387
388 loc_g_10E9: // zonk rolls right
389   //  To Do: draw zonk rolling to right
390   //  according to position in (bl And &H07)
391   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
392   X = GetStretchX(si);
393   Y = GetStretchY(si);
394   dx = (bl & 0x7) + 1;
395   DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
396   DDSpriteBuffer_BltImg(X + (TwoPixels * dx), Y, aniZonkRollRight, dx - 1);
397   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
398
399   bl = HighByte(PlayField16[si]) + 1;
400   if (bl < 0x62)
401   {
402     MovHighByte(&PlayField16[si], bl);
403     return subAnimateZonks;
404   }
405
406   if (PlayField16[si + FieldWidth + 1] != 0)
407     goto loc_g_1150;
408
409   if (PlayField16[si + 1] != 0)
410   {
411     if (PlayField16[si + 1] != 0x8888)
412       goto loc_g_1150;
413   }
414
415   PlayField16[si] = 0xFFFF;
416   si = si + 1;
417   PlayField16[si] = 0x3201;
418   PlayField16[si + FieldWidth] = 0xFFFF;
419   return subAnimateZonks;
420
421 loc_g_1150: // stay waiting
422   bl = bl - 1;
423   MovHighByte(&PlayField16[si], bl);
424   return subAnimateZonks;
425
426 loc_g_1157: // intermediate state
427   ax = PlayField16[si + FieldWidth];
428   if (ax == 0 || ax == 0x9999)
429   {
430     PlayField16[si] = 0xFFFF;
431     si = si + FieldWidth;                 // 1 field down
432     PlayField16[si] = 0x1001; // start falling down
433     goto loc_g_0DE8;
434   }
435
436   return subAnimateZonks;
437 } // subAnimateZonks endp
438
439 int subCleanUpForZonksAbove(int si)
440 {
441   int subCleanUpForZonksAbove;
442
443   int ax;
444
445   if (LowByte(PlayField16[si]) != fiExplosion)
446     PlayField16[si] = 0;
447
448   if (PlayField16[si - FieldWidth] != 0)
449   {
450     if (PlayField16[si - FieldWidth] != 0x9999)
451       return subCleanUpForZonksAbove;
452
453     if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiInfotron)
454       return subCleanUpForZonksAbove;
455   } // loc_g_1674:
456
457   if (PlayField16[si - FieldWidth - 1] != fiZonk)
458   {
459     if (PlayField16[si - FieldWidth + 1] != fiZonk)
460       return subCleanUpForZonksAbove;
461
462     goto loc_g_16A7;
463   }
464
465   ax = PlayField16[si - 1];
466   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
467   {
468     PlayField16[si - FieldWidth - 1] = 0x6001;
469     PlayField16[si - FieldWidth] = 0x8888;
470     return subCleanUpForZonksAbove;
471   }
472
473   if (PlayField16[si - FieldWidth + 1] != fiZonk)
474     return subCleanUpForZonksAbove;
475
476 loc_g_16A7:
477   ax = PlayField16[si + 1];
478   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
479   {
480     PlayField16[si - FieldWidth + 1] = 0x5001;
481     PlayField16[si - FieldWidth] = 0x8888;
482   }
483
484   return subCleanUpForZonksAbove;
485 } // subCleanUpForZonksAbove