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