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