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