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