c804191fd8e3c4e89165339744fbd9851eebd630
[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 #if 1
126   StretchedSprites.BltImg(X, Y, aniSpace, 0);
127   StretchedSprites.BltImg(X, Y + TwoPixels * (dx + 1), aniInfotron, dx);
128 #else
129   StretchedSprites.BltEx(X, Y, 0);
130   StretchedSprites.BltEx(X, Y + TwoPixels * (dx + 1), fiInfotron);
131 #endif
132   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
133   bl = HighByte(PlayField16[si]) + 1;
134   if (bl == 0x16)
135   {
136     MovHighByte(&PlayField16[si], bl);
137     subCleanUpForInfotronsAbove(si - FieldWidth);
138     return subAnimateInfotrons;
139   } // loc_g_1285:
140
141   if (bl < 0x18)
142   {
143     MovHighByte(&PlayField16[si], bl);
144     return subAnimateInfotrons;
145   } // loc_g_128F:
146
147   MovHighByte(&PlayField16[si], 0); // infotron arrived at the field
148
149   // now check if the zonk may go on falling somehow
150   ax = PlayField16[si + FieldWidth];
151   if (ax == 0) // below is empty!-> go on falling
152     goto loc_g_132D;
153
154   if (ax == 0x9999) // below is only temporarily used
155     goto loc_g_132D;
156
157   if ((ax & 0xFF) == fiMurphy) // Murphy dies
158     goto loc_g_1364;
159
160   if (ax == fiRedDisk) // red disk hit
161     goto loc_g_1386;
162
163   if ((ax & 0xFF) == fiSnikSnak) // SnikSnak dies
164     goto loc_g_1386;
165
166
167   if ((ax & 0xFF) == fiElectron) // Electron cracked!
168     goto loc_g_1386;
169
170   if (ax == fiYellowDisk) // yellow disk hit
171     goto loc_g_1386;
172
173   if (ax == fiOrangeDisk) // orange disk hit
174     goto loc_g_1386;
175
176 #if 1
177
178 #if 1
179   // play the infotron sound, 'cause infotron hits something "hard"
180   subSoundFX(si, fiInfotron, actImpact);
181 #else
182  // play the zonk sound, 'cause zonk hits something "hard"
183   subSoundFX(si, fiZonk, actImpact);
184 #endif
185
186 #else
187   subSoundFXZonk(); // play the zonk sound,'cause zonk hits something "hard"
188 #endif
189
190   if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM))
191     return subAnimateInfotrons;
192
193   // infotron rolls somewhere
194   ax = PlayField16[si + FieldWidth - 1];
195   if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll left
196     goto loc_g_133A;
197
198   ax = PlayField16[si + FieldWidth + 1];
199   if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll right
200     goto loc_g_1350;
201
202   return subAnimateInfotrons;
203
204 loc_g_132D:     // go on falling down?
205   PlayField16[si] = 0x7004; // go into intermediate waitstate
206   PlayField16[si + FieldWidth] = 0x9999; // mark as "zonk waiting to access"
207   return subAnimateInfotrons;
208
209 loc_g_133A:     // test if infotron may roll left
210   // This if(if true) jumps up far above
211   // to the according rountine for fixed infotrons!
212   if (PlayField16[si - 1] != 0) // Remarkable!!! ' loc_g_0EF4:
213     goto loc_g_11BD;
214
215   MovHighByte(&PlayField16[si], 0x50); // infotron rolls left
216   PlayField16[si - 1] = 0x8888;
217
218   return subAnimateInfotrons;
219
220 loc_g_1350:     // test if infotron may roll right
221   if (PlayField16[si + 1] != 0)
222     return subAnimateInfotrons;
223
224   MovHighByte(&PlayField16[si], 0x60); // infotron rolls right
225   PlayField16[si + 1] = 0x8888;
226
227   return subAnimateInfotrons;
228
229 loc_g_1364:     // Murphy dies, but not in any case
230   bl = HighByte(PlayField16[si + FieldWidth]);
231   if (bl == 0xE || bl == 0xF || bl == 0x28)
232     return subAnimateInfotrons;
233
234   if (bl == 0x29 || bl == 0x25 || bl == 0x26)
235     return subAnimateInfotrons;
236
237 loc_g_1386:     // someone dies/explodes immediately
238   si = si + FieldWidth;                 // 1 field down
239   ExplodeFieldSP(si);               // Explode
240   return subAnimateInfotrons;
241
242 loc_g_138D: // infotron comes rolling from right to left
243   //  To Do: draw infotron rolling from right
244   //  according to position in (bl And &H07)
245   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
246   X = GetStretchX(si + 1);
247   Y = GetStretchY(si);
248   dx = (bl & 0x7) + 1;
249 #if 1
250   StretchedSprites.BltImg(X, Y, aniSpace, 0);
251   StretchedSprites.BltImg(X - (TwoPixels * dx), Y, aniInfotronRollLeft, dx - 1);
252 #else
253   StretchedSprites.BltEx(X, Y, 0);
254   StretchedSprites.BltEx(X - (TwoPixels * dx), Y, aniFramesInfotronRollLeft[dx - 1]);
255 #endif
256   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
257   bl = HighByte(PlayField16[si]) + 1; // get and increment sequence#
258   if (bl == 0x24)
259     PlayField16[si + 1] = 0xAAAA;
260
261   if (bl == 0x26)
262   {
263     MovHighByte(&PlayField16[si], bl);
264     subCleanUpForInfotronsAbove(si + 1);
265   }
266   else if (bl < 0x28)
267   {
268     MovHighByte(&PlayField16[si], bl);
269   }
270   else
271   {
272     PlayField16[si] = 0x7004; // go into intermediate state
273   }
274
275   return subAnimateInfotrons;
276
277 loc_g_13E9: // infotron comes rolling from left to right
278   //  To Do: draw infotron rolling from left
279   //  according to position in (bl And &H07)
280   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
281   X = GetStretchX(si - 1);
282   Y = GetStretchY(si);
283   dx = (bl & 0x7) + 1;
284 #if 1
285   StretchedSprites.BltImg(X, Y, aniSpace, 0);
286   StretchedSprites.BltImg(X + (TwoPixels * dx), Y, aniInfotronRollRight, dx - 1);
287 #else
288   StretchedSprites.BltEx(X, Y, 0);
289   StretchedSprites.BltEx(X + (TwoPixels * dx), Y, aniFramesInfotronRollRight[dx - 1]);
290 #endif
291   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
292   bl = HighByte(PlayField16[si]) + 1;
293   if (bl == 0x34)
294     PlayField16[si - 1] = 0xAAAA;
295
296   if (bl == 0x36)
297   {
298     MovHighByte(&PlayField16[si], bl);
299     subCleanUpForInfotronsAbove(si - 1);
300   }
301   else if (bl < 0x38)
302   {
303     MovHighByte(&PlayField16[si], bl);
304   }
305   else
306   {
307     PlayField16[si] = 0x7004; // go into intermediate state
308   }
309
310   return subAnimateInfotrons;
311
312 loc_g_1444: // infotron falls straight down
313   bl = bl + 1;
314   if (bl < 0x42)
315   {
316     MovHighByte(&PlayField16[si], bl);
317   }
318   else if (PlayField16[si + FieldWidth] != 0)
319   {
320     bl = bl - 1; // stay waiting
321     MovHighByte(&PlayField16[si], bl);
322   }
323   else
324   {
325     PlayField16[si] = 0xFFFF;
326     si = si + FieldWidth;                 // 1 field down
327     PlayField16[si] = 0x1004; // go falling
328   }
329
330   return subAnimateInfotrons;
331
332 loc_g_1472: // infotron rolls left
333   //  To Do: draw infotron rolling to left
334   //  according to position in (bl And &H0F)
335   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
336   X = GetStretchX(si);
337   Y = GetStretchY(si);
338   dx = (bl & 0xF) + 1;
339 #if 1
340   StretchedSprites.BltImg(X, Y, aniSpace, 0);
341   StretchedSprites.BltImg(X - (TwoPixels * dx), Y, aniInfotronRollLeft, dx - 1);
342 #else
343   StretchedSprites.BltEx(X, Y, 0);
344   StretchedSprites.BltEx(X - (TwoPixels * dx), Y, aniFramesInfotronRollLeft[dx - 1]);
345 #endif
346   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
347   bl = HighByte(PlayField16[si]) + 1; // retrieve and increment sequence#
348   if (bl < 0x52)
349   {
350     MovHighByte(&PlayField16[si], bl);
351     return subAnimateInfotrons;
352   }
353
354   if (PlayField16[si + FieldWidth - 1] != 0)
355     goto loc_g_14D9;
356
357   if (PlayField16[si - 1] != 0)
358   {
359     if (PlayField16[si - 1] != 0x8888)
360       goto loc_g_14D9;
361   }
362
363   PlayField16[si] = 0xFFFF;
364   si = si - 1;                   // 1 field left
365   PlayField16[si] = 0x2204;
366   PlayField16[si + FieldWidth] = 0x9999;
367   return subAnimateInfotrons;
368
369 loc_g_14D9: // stay waiting
370   bl = bl - 1;
371   MovHighByte(&PlayField16[si], bl);
372   return subAnimateInfotrons;
373
374 loc_g_14E0: // infotron rolls right
375   //  To Do: draw infotron rolling to right
376   //  according to position in (bl And &H07)
377   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
378   X = GetStretchX(si);
379   Y = GetStretchY(si);
380   dx = (bl & 0x7) + 1;
381 #if 1
382   StretchedSprites.BltImg(X, Y, aniSpace, 0);
383   StretchedSprites.BltImg(X + (TwoPixels * dx), Y, aniInfotronRollRight, dx - 1);
384 #else
385   StretchedSprites.BltEx(X, Y, 0);
386   StretchedSprites.BltEx(X + (TwoPixels * dx), Y, aniFramesInfotronRollRight[dx - 1]);
387 #endif
388   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
389   bl = HighByte(PlayField16[si]) + 1;
390   if (bl < 0x62)
391   {
392     MovHighByte(&PlayField16[si], bl);
393     return subAnimateInfotrons;
394   }
395
396   if (PlayField16[si + FieldWidth + 1] != 0)
397     goto loc_g_1547;
398
399   if (PlayField16[si + 1] != 0)
400   {
401     if (PlayField16[si + 1] != 0x8888)
402       goto loc_g_1547;
403   }
404
405   PlayField16[si] = 0xFFFF;
406   si = si + 1;
407   PlayField16[si] = 0x3204;
408   PlayField16[si + FieldWidth] = 0x9999;
409   return subAnimateInfotrons;
410
411 loc_g_1547: // stay waiting
412   bl = bl - 1;
413   MovHighByte(&PlayField16[si], bl);
414   return subAnimateInfotrons;
415
416 loc_g_154E: // 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] = 0x1004; // start falling down
423     goto loc_g_1242;
424   }
425
426   return subAnimateInfotrons;
427 } // subAnimateInfotrons
428
429 int subCleanUpForInfotronsAbove(int si)
430 {
431   int subCleanUpForInfotronsAbove;
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 subCleanUpForInfotronsAbove;
442
443     if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiZonk)
444       return subCleanUpForInfotronsAbove;
445   }
446
447   if (PlayField16[si - FieldWidth - 1] == fiInfotron)
448     goto loc_g_16FE;
449
450 loc_g_16F6:
451   if (PlayField16[si - FieldWidth + 1] == fiInfotron)
452     goto loc_g_1722;
453
454   return subCleanUpForInfotronsAbove;
455
456 loc_g_16FE:
457   ax = PlayField16[si - 1];
458   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
459   {
460     PlayField16[si - FieldWidth - 1] = 0x6004;
461     PlayField16[si - FieldWidth] = 0x8888;
462     return subCleanUpForInfotronsAbove;
463   }
464
465   goto loc_g_16F6;
466
467 loc_g_1722:
468   ax = PlayField16[si + 1];
469   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
470   {
471     PlayField16[si - FieldWidth + 1] = 0x5004;
472     PlayField16[si - FieldWidth] = 0x8888;
473   }
474
475   return subCleanUpForInfotronsAbove;
476 } // subCleanUpForInfotronsAbove