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