rnd-20100315-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 #if 1
135   StretchedSprites.BltImg(X, Y, aniSpace, 0);
136   StretchedSprites.BltImg(X, Y + TwoPixels * (dx + 1), aniZonk, dx);
137 #else
138   StretchedSprites.BltEx(X, Y, 0);
139   StretchedSprites.BltEx(X, Y + TwoPixels * (dx + 1), fiZonk);
140 #endif
141   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
142   bl = HighByte(PlayField16[si]) + 1;
143   if (bl == 0x16)
144   {
145     MovHighByte(&PlayField16[si], bl);
146     subCleanUpForZonksAbove(si - FieldWidth);
147     return subAnimateZonks;
148   } // loc_g_0E2B:
149
150   if (bl < 0x18)
151   {
152     MovHighByte(&PlayField16[si], bl);
153     return subAnimateZonks;
154   } // loc_g_0E35:
155
156   MovHighByte(&PlayField16[si], 0); // zonk arrived at the field
157   if ((FreezeZonks & 0xFF) == 2)
158     return subAnimateZonks;
159
160   // loc_g_0E42:     // now check if the zonk may go on falling somehow
161   ax = PlayField16[si + FieldWidth];
162   if (ax == 0) // below is empty!-> go on falling 'loc_g_0E4C:
163     goto loc_g_0EDD;
164
165   if (ax == 0x9999) // below is only temporarily used ' loc_g_0E57:
166     goto loc_g_0EDD;
167
168   if ((ax & 0xFF) == fiMurphy) // Murphy dies 'loc_g_0E61:
169     goto loc_g_0F14;
170
171   if ((ax & 0xFF) == fiSnikSnak) // SnikSnak dies 'loc_g_0E6B:
172     goto loc_g_0F6E;
173
174   if (ax == 0x2BB) // loc_g_0E76:
175     goto loc_g_0F36;
176
177   if (ax == 0x4BB) // loc_g_0E81:
178     goto loc_g_0F52;
179
180   if ((ax & 0xFF) == fiElectron) // Electron cracked! 'loc_g_0E8B:
181     goto loc_g_0F6E;
182
183   if (ax == fiOrangeDisk) // OrangeDisk explodes 'loc_g_0E95:
184     goto loc_g_0F75;
185
186 #if 1
187   // play the zonk sound, 'cause zonk hits something "hard"
188   subSoundFX(si, fiZonk, actImpact);
189 #else
190   subSoundFXZonk(); // play the zonk sound,'cause zonk hits something "hard"
191 #endif
192
193   if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM))
194     return subAnimateZonks;
195
196   // loc_g_0EAE: ' Zonk rolls somewhere
197   ax = PlayField16[si + FieldWidth - 1];
198   if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll left
199     goto loc_g_0EEA;
200
201   ax = PlayField16[si + FieldWidth + 1];
202   if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll right
203     goto loc_g_0F00;
204
205   return subAnimateZonks;
206
207 loc_g_0EDD:     // go on falling down?
208   PlayField16[si] = 0x7001; // go into intermediate waitstate
209   PlayField16[si + FieldWidth] = 0x9999; // mark as "zonk waiting to access"
210   return subAnimateZonks;
211
212 loc_g_0EEA:     // test if zonk may roll left
213   // This if(if true) jumps up far above
214   // to the according rountine for fixed zonks!
215   if (PlayField16[si - 1] != 0) // Remarkable!!! ' loc_g_0EF4:
216     goto loc_g_0D4C;
217
218   MovHighByte(&PlayField16[si], 0x50); // zonk rolls left
219   PlayField16[si - 1] = 0x8888; // mark as zonk accessing?
220   return subAnimateZonks;
221
222 loc_g_0F00:     // test if zonk may roll right
223   if (PlayField16[si + 1] != 0) // loc_g_0F08:
224     return subAnimateZonks;
225
226   MovHighByte(&PlayField16[si], 0x60); // zonk rolls right
227   PlayField16[si + 1] = 0x8888; // mark as zonk accessing?
228   return subAnimateZonks;
229
230 loc_g_0F14:     // Murphy dies, but not in any case
231   bl = HighByte(PlayField16[si + FieldWidth]);
232   if (bl == 0xE || bl == 0xF || bl == 0x28)
233     return subAnimateZonks;
234
235   if (bl == 0x29 || bl == 0x25 || bl == 0x26)
236     return subAnimateZonks;
237
238 loc_g_0F36:     // ??
239   ax = LowByte(PlayField16[si + FieldWidth - 1]);
240   if (ax == fiElectron) // loc_g_0F43:
241     PlayField16[si + FieldWidth] = fiElectron;
242
243   if (ax != 0x1F)
244     PlayField16[si + FieldWidth - 1] = 0;
245
246   goto loc_g_0F6E;
247
248 loc_g_0F52:     // ??
249   ax = LowByte(PlayField16[si + FieldWidth + 1]);
250   if (ax == fiElectron) // loc_g_0F5F:
251     PlayField16[si + FieldWidth] = fiElectron;
252
253   if (ax != 0x1F)
254     PlayField16[si + FieldWidth + 1] = 0;
255
256   goto loc_g_0F6E;
257
258 loc_g_0F6E:     // someone dies/explodes
259   si = si + FieldWidth;                 // 1 field down
260   ExplodeFieldSP(si);               // Explode
261   return subAnimateZonks;
262
263 loc_g_0F75:     // OrangeDisk explodes next cycle
264   si = si + FieldWidth;                 // 1 field down
265   PlayField8[si] = fiHardWare;
266   return subAnimateZonks;
267
268 loc_g_0F83: // zonk comes rolling from right to left
269   //  To Do: draw zonk rolling from right
270   //  according to position in (bl And &H07)
271   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
272   X = GetStretchX(si + 1);
273   Y = GetStretchY(si);
274   dx = (bl & 0x7) + 1;
275 #if 1
276   StretchedSprites.BltImg(X, Y, aniSpace, 0);
277   StretchedSprites.BltImg(X - (TwoPixels * dx), Y, aniZonkRollLeft, dx - 1);
278 #else
279   StretchedSprites.BltEx(X, Y, 0);
280   StretchedSprites.BltEx(X - (TwoPixels * dx), Y, aniFramesZonkRollLeft[dx - 1]);
281 #endif
282   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
283   bl = HighByte(PlayField16[si]) + 1; // get and increment sequence#
284   if (bl == 0x24)
285     PlayField16[si + 1] = 0xAAAA;
286
287   if (bl == 0x26)
288   {
289     MovHighByte(&PlayField16[si], bl);
290     subCleanUpForZonksAbove(si + 1);
291   }
292   else if (bl < 0x28)
293   {
294     MovHighByte(&PlayField16[si], bl);
295   }
296   else
297   {
298     PlayField16[si] = 0xFFFF;
299     si = si + FieldWidth;                 // 1 field down
300     PlayField16[si] = 0x1001; // convert rolling zonk to a falling zonk
301   }
302
303   return subAnimateZonks;
304
305 loc_g_0FE8: // zonk comes rolling from left to right
306   //  To Do: draw zonk rolling from left
307   //  according to position in (bl And &H07)
308   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
309   X = GetStretchX(si - 1);
310   Y = GetStretchY(si);
311   dx = (bl & 0x7) + 1;
312 #if 1
313   StretchedSprites.BltImg(X, Y, aniSpace, 0);
314   StretchedSprites.BltImg(X + (TwoPixels * dx), Y, aniZonkRollRight, dx - 1);
315 #else
316   StretchedSprites.BltEx(X, Y, 0);
317   StretchedSprites.BltEx(X + (TwoPixels * dx), Y, aniFramesZonkRollRight[dx - 1]);
318 #endif
319   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
320   bl = HighByte(PlayField16[si]) + 1;
321   if (bl == 0x34)
322     PlayField16[si - 1] = 0xAAAA;
323
324   if (bl == 0x36)
325   {
326     MovHighByte(&PlayField16[si], bl);
327     subCleanUpForZonksAbove(si - 1);
328   }
329   else if (bl < 0x38)
330   {
331     MovHighByte(&PlayField16[si], bl);
332   }
333   else
334   {
335     PlayField16[si] = 0xFFFF;
336     si = si + FieldWidth;                   // 1 field down
337     PlayField16[si] = 0x1001; // convert rolling zonk to a falling zonk
338   }
339
340   return subAnimateZonks;
341
342 loc_g_104D: // zonk falls straight down
343   bl = bl + 1;
344   if (bl < 0x42)
345   {
346     MovHighByte(&PlayField16[si], bl);
347   }
348   else if (PlayField16[si + FieldWidth] != 0)
349   {
350     bl = bl - 1; // stay waiting
351     MovHighByte(&PlayField16[si], bl);
352   }
353   else
354   {
355     PlayField16[si] = 0xFFFF; // mark as "zonk leaving"
356     si = si + FieldWidth;                 // 1 field down
357     PlayField16[si] = 0x1001; // go falling
358   }
359
360   return subAnimateZonks;
361
362 loc_g_107B: // zonk rolls left
363   //  To Do: draw zonk rolling to left
364   //  according to position in (bl And &H0F)
365   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
366   X = GetStretchX(si);
367   Y = GetStretchY(si);
368   dx = (bl & 0xF) + 1;
369 #if 1
370   StretchedSprites.BltImg(X, Y, aniSpace, 0);
371   StretchedSprites.BltImg(X - (TwoPixels * dx), Y, aniZonkRollLeft, dx - 1);
372 #else
373   StretchedSprites.BltEx(X, Y, 0);
374   StretchedSprites.BltEx(X - (TwoPixels * dx), Y, aniFramesZonkRollLeft[dx - 1]);
375 #endif
376   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
377   bl = HighByte(PlayField16[si]) + 1; // retrieve and increment sequence#
378   if (bl < 0x52)
379   {
380     MovHighByte(&PlayField16[si], bl);
381     return subAnimateZonks;
382   }
383
384   if (PlayField16[si + FieldWidth - 1] != 0)
385     goto loc_g_10E2;
386
387   if (PlayField16[si - 1] != 0)
388   {
389     if (PlayField16[si - 1] != 0x8888)
390       goto loc_g_10E2;
391   } // loc_g_10C8:
392
393   PlayField16[si] = 0xFFFF;
394   si = si - 1;                   // 1 field left
395   PlayField16[si] = 0x2201;
396   PlayField16[si + FieldWidth] = 0xFFFF;
397   return subAnimateZonks;
398
399 loc_g_10E2: // stay waiting
400   bl = bl - 1;
401   MovHighByte(&PlayField16[si], bl);
402   return subAnimateZonks;
403
404 loc_g_10E9: // zonk rolls right
405   //  To Do: draw zonk rolling to right
406   //  according to position in (bl And &H07)
407   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
408   X = GetStretchX(si);
409   Y = GetStretchY(si);
410   dx = (bl & 0x7) + 1;
411 #if 1
412   StretchedSprites.BltImg(X, Y, aniSpace, 0);
413   StretchedSprites.BltImg(X + (TwoPixels * dx), Y, aniZonkRollRight, dx - 1);
414 #else
415   StretchedSprites.BltEx(X, Y, 0);
416   StretchedSprites.BltEx(X + (TwoPixels * dx), Y, aniFramesZonkRollRight[dx - 1]);
417 #endif
418   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
419   bl = HighByte(PlayField16[si]) + 1;
420   if (bl < 0x62)
421   {
422     MovHighByte(&PlayField16[si], bl);
423     return subAnimateZonks;
424   }
425
426   if (PlayField16[si + FieldWidth + 1] != 0)
427     goto loc_g_1150;
428
429   if (PlayField16[si + 1] != 0)
430   {
431     if (PlayField16[si + 1] != 0x8888)
432       goto loc_g_1150;
433   }
434
435   PlayField16[si] = 0xFFFF;
436   si = si + 1;
437   PlayField16[si] = 0x3201;
438   PlayField16[si + FieldWidth] = 0xFFFF;
439   return subAnimateZonks;
440
441 loc_g_1150: // stay waiting
442   bl = bl - 1;
443   MovHighByte(&PlayField16[si], bl);
444   return subAnimateZonks;
445
446 loc_g_1157: // intermediate state
447   ax = PlayField16[si + FieldWidth];
448   if (ax == 0 || ax == 0x9999)
449   {
450     PlayField16[si] = 0xFFFF;
451     si = si + FieldWidth;                 // 1 field down
452     PlayField16[si] = 0x1001; // start falling down
453     goto loc_g_0DE8;
454   }
455
456   return subAnimateZonks;
457 } // subAnimateZonks endp
458
459 int subCleanUpForZonksAbove(int si)
460 {
461   int subCleanUpForZonksAbove;
462
463   int ax;
464
465   if (LowByte(PlayField16[si]) != fiExplosion)
466     PlayField16[si] = 0;
467
468   if (PlayField16[si - FieldWidth] != 0)
469   {
470     if (PlayField16[si - FieldWidth] != 0x9999)
471       return subCleanUpForZonksAbove;
472
473     if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiInfotron)
474       return subCleanUpForZonksAbove;
475   } // loc_g_1674:
476
477   if (PlayField16[si - FieldWidth - 1] != fiZonk)
478   {
479     if (PlayField16[si - FieldWidth + 1] != fiZonk)
480       return subCleanUpForZonksAbove;
481
482     goto loc_g_16A7;
483   }
484
485   ax = PlayField16[si - 1];
486   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
487   {
488     PlayField16[si - FieldWidth - 1] = 0x6001;
489     PlayField16[si - FieldWidth] = 0x8888;
490     return subCleanUpForZonksAbove;
491   }
492
493   if (PlayField16[si - FieldWidth + 1] != fiZonk)
494     return subCleanUpForZonksAbove;
495
496 loc_g_16A7:
497   ax = PlayField16[si + 1];
498   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
499   {
500     PlayField16[si - FieldWidth + 1] = 0x5001;
501     PlayField16[si - FieldWidth] = 0x8888;
502   }
503
504   return subCleanUpForZonksAbove;
505 } // subCleanUpForZonksAbove