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