rnd-20100214-1-src
[rocksndiamonds.git] / src / game_sp / Electrons.c
1 // ----------------------------------------------------------------------------
2 // Electrons.c
3 // ----------------------------------------------------------------------------
4
5 #include "Electrons.h"
6
7 // static char *VB_Name = "modElectron";
8
9 // --- Option Explicit
10 // ==========================================================================
11 //                              SUBROUTINE
12 // Animate/move Electrons
13 // ==========================================================================
14
15 int subAnimateElectrons(int si)
16 {
17   int subAnimateElectrons;
18
19   int bx, Tmp;
20
21   if (SnikSnaksElectronsFrozen == 1)
22     return subAnimateElectrons;
23
24   if (LowByte(PlayField16[si]) != fiElectron)
25     return subAnimateElectrons;
26
27   bx = HighByte(PlayField16[si]);
28   Tmp = bx / 8;
29   switch (Tmp)
30   {
31     case 0:
32       subElectronTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc.
33       break;
34
35     case 1:
36       subElectronTurnRight(si, bx); // turn right
37       break;
38
39     case 2:
40       subElectronFromBelow(si, bx); // access si from below
41       break;
42
43     case 3:
44       subElectronFromRight(si, bx); // access si from right
45       break;
46
47     case 4:
48       subElectronFromAbove(si, bx); // access si from above
49       break;
50
51     case 5:
52       subElectronFromLeft(si, bx); // access si from left
53       break;
54   }
55
56   return subAnimateElectrons;
57 } // subAnimateElectrons
58
59 int subDrawAnimatedElectrons(int si)
60 {
61   int subDrawAnimatedElectrons;
62
63   int bx, Tmp;
64
65   // If SnikSnaksElectronsFrozen = 1 Then Exit Function
66   if (LowByte(PlayField16[si]) != fiElectron)
67     return subDrawAnimatedElectrons;
68
69   bx = HighByte(PlayField16[si]);
70   Tmp = bx / 8;
71   switch (Tmp)
72   {
73     case 0:
74       subDrawElectronTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc.
75       break;
76
77     case 1:
78       subDrawElectronTurnRight(si, bx); // turn right
79       break;
80
81     case 2:
82       subDrawElectronFromBelow(si, bx); // access si from below
83       break;
84
85     case 3:
86       subDrawElectronFromRight(si, bx); // access si from right
87       break;
88
89     case 4:
90       subDrawElectronFromAbove(si, bx); // access si from above
91       break;
92
93     case 5:
94       subDrawElectronFromLeft(si, bx); // access si from left
95       break;
96   }
97
98   return subDrawAnimatedElectrons;
99 } // subDrawAnimatedElectrons
100
101 int subElectronTurnLeft(int si, int bx)
102 {
103   int subElectronTurnLeft;
104
105   // int ax, ah, bl, dx, X, Y;
106   int ax, bl, X, Y;
107
108   ax = (TimerVar & 3);
109   if (ax != 0)
110   {
111     if (ax == 3)
112       goto loc_g_7ACD;
113
114     return subElectronTurnLeft;
115   } // loc_g_7A9F:
116
117   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
118   X = GetStretchX(si);
119   Y = GetStretchY(si);
120   StretchedSprites.BltEx(X, Y, aniFramesElectron[bx]);
121   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
122   bx = (bx + 1) & 0x7;
123   MovHighByte(&PlayField16[si], bx);
124   return subElectronTurnLeft;
125
126 loc_g_7ACD:
127   bl = HighByte(PlayField16[si]);
128   if (bl == 0)
129     goto loc_g_7AE6;
130
131   if (bl == 2)
132     goto loc_g_7B05;
133
134   if (bl == 4)
135     goto loc_g_7B24;
136
137   if (bl == 6)
138     goto loc_g_7B43;
139
140   return subElectronTurnLeft;
141
142 loc_g_7AE6: // pointing up
143   ax = PlayField16[si - FieldWidth];
144   if (ax == 0) // above is empty -> go up
145     goto loc_g_7AF5;
146
147   if (LowByte(ax) == fiMurphy) // above is murphy -> explode
148     ExplodeFieldSP(si);
149
150   return subElectronTurnLeft;
151
152 loc_g_7AF5: // above is empty -> go up
153   PlayField16[si] = 0x1BB;
154   si = si - FieldWidth; // 1 field up
155   PlayField16[si] = 0x1018;
156   return subElectronTurnLeft;
157
158 loc_g_7B05: // pointing left
159   ax = PlayField16[si - 1];
160   if (ax == 0) // left is empty -> go there
161     goto loc_g_7B14;
162
163   if (LowByte(ax) == fiMurphy) // left is murphy -> explode
164     ExplodeFieldSP(si);
165
166   return subElectronTurnLeft;
167
168 loc_g_7B14: // left is empty -> go there
169   PlayField16[si] = 0x2BB;
170   si = si - 1; // 1 field left
171   PlayField16[si] = 0x1818;
172   return subElectronTurnLeft;
173
174 loc_g_7B24: // pointing down
175   ax = PlayField16[si + FieldWidth];
176   if (ax == 0) // below is empty -> go down
177     goto loc_g_7B33;
178
179   if (LowByte(ax) == fiMurphy) // below is murphy -> explode
180     ExplodeFieldSP(si);
181
182   return subElectronTurnLeft;
183
184 loc_g_7B33: // below is empty -> go down
185   PlayField16[si] = 0x3BB;
186   si = si + FieldWidth; // 1 field down
187   PlayField16[si] = 0x2018;
188   return subElectronTurnLeft;
189
190 loc_g_7B43: // pointing Right
191   ax = PlayField16[si + 1];
192   if (ax == 0) // right is empty -> go there
193     goto loc_g_7B55;
194
195   if (LowByte(ax) == fiMurphy) // right is murphy -> explode
196     ExplodeFieldSP(si);
197
198   return subElectronTurnLeft;
199
200 loc_g_7B55: // right is empty -> go there
201   PlayField16[si] = 0x4BB;
202   si = si + 1; // 1 field right
203   PlayField16[si] = 0x2818;
204
205   return subElectronTurnLeft;
206 } // subElectronTurnLeft
207
208 int subElectronTurnRight(int si, int bx)
209 {
210   int subElectronTurnRight;
211
212   // int ax, ah, bl, dx, X, Y;
213   int ax, bl, X, Y;
214
215   ax = (TimerVar & 3);
216   if (ax != 0)
217   {
218     if (ax == 3)
219       goto loc_g_7BA3;
220
221     return subElectronTurnRight;
222   } // loc_g_7B73:
223
224   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
225   X = GetStretchX(si);
226   Y = GetStretchY(si);
227   StretchedSprites.BltEx(X, Y, aniFramesElectron[0x10 - bx]);
228   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
229   bx = ((bx + 1) & 0x7) | 8;
230   MovHighByte(&PlayField16[si], bx);
231   return subElectronTurnRight;
232
233 loc_g_7BA3:
234   bl = HighByte(PlayField16[si]);
235   if (bl == 0x8)
236     goto loc_g_7BBC;
237
238   if (bl == 0xA)
239     goto loc_g_7C19;
240
241   if (bl == 0xC)
242     goto loc_g_7BFA;
243
244   if (bl == 0xE)
245     goto loc_g_7BDB;
246
247   return subElectronTurnRight;
248
249 loc_g_7BBC: // pointing up
250   ax = PlayField16[si - FieldWidth];
251   if (ax == 0) // above is empty -> go up
252     goto loc_g_7BCB;
253
254   if (LowByte(ax) == fiMurphy) // above is murphy -> explode
255     ExplodeFieldSP(si);
256
257   return subElectronTurnRight;
258
259 loc_g_7BCB: // above is empty -> go up
260   PlayField16[si] = 0x1BB;
261   si = si - FieldWidth; // 1 field up
262   PlayField16[si] = 0x1018;
263   return subElectronTurnRight;
264
265 loc_g_7BDB: // pointing left
266   ax = PlayField16[si - 1];
267   if (ax == 0) // left is empty -> go there
268     goto loc_g_7BEA;
269
270   if (LowByte(ax) == fiMurphy) // left is murphy -> explode
271     ExplodeFieldSP(si);
272
273   return subElectronTurnRight;
274
275 loc_g_7BEA: // left is empty -> go there
276   PlayField16[si] = 0x2BB;
277   si = si - 1; // 1 field left
278   PlayField16[si] = 0x1818;
279   return subElectronTurnRight;
280
281 loc_g_7BFA: // pointing down
282   ax = PlayField16[si + FieldWidth];
283   if (ax == 0) // below is empty -> go down
284     goto loc_g_7C09;
285
286   if (LowByte(ax) == fiMurphy) // below is murphy -> explode
287     ExplodeFieldSP(si);
288
289   return subElectronTurnRight;
290
291 loc_g_7C09: // below is empty -> go down
292   PlayField16[si] = 0x3BB;
293   si = si + FieldWidth; // 1 field down
294   PlayField16[si] = 0x2018;
295   return subElectronTurnRight;
296
297 loc_g_7C19: // pointing Right
298   ax = PlayField16[si + 1];
299   if (ax == 0) // right is empty -> go there
300     goto loc_g_7C2B;
301
302   if (LowByte(ax) == fiMurphy) // right is murphy -> explode
303     ExplodeFieldSP(si);
304
305   return subElectronTurnRight;
306
307 loc_g_7C2B: // right is empty -> go there
308   PlayField16[si] = 0x4BB;
309   si = si + 1; // 1 field right
310   PlayField16[si] = 0x2818;
311
312   return subElectronTurnRight;
313 } // subElectronTurnRight
314
315 int subElectronFromBelow(int si, int bx)
316 {
317   int subElectronFromBelow;
318
319   // int ax, ah, bl, dx, X, Y;
320   int ax, bl, X, Y;
321
322   bx = bx - 0xF;  // get and increment sequence#
323   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
324   X = GetStretchX(si);
325   Y = GetStretchY(si + FieldWidth);
326   StretchedSprites.BltEx(X, Y, 0);
327   StretchedSprites.BltEx(X, Y - bx * TwoPixels, aniFramesElectron[bx]);
328   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
329   bl = LowByte(bx);
330   if (bl == 7 && LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
331   {
332     PlayField16[si + FieldWidth] = 0; // electron left that field
333   }
334
335   if (bl < 8) // electron still goes up
336   {
337     bl = bl + 0x10;
338     MovHighByte(&PlayField16[si], bl);
339     return subElectronFromBelow;
340   } // loc_g_7C84
341
342   PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field
343   ax = PlayField16[si - 1]; // check left field
344   if (ax == 0 || LowByte(ax) == fiMurphy) // check for empty or murphy
345   {
346     MovHighByte(&PlayField16[si], 1); // start to turn left
347     return subElectronFromBelow;
348   } // loc_g_7CA4:
349
350   ax = PlayField16[si - FieldWidth]; // cannot turn left -> check above
351   if (ax == 0) // check if empty
352   {
353     PlayField16[si] = 0x1BB; // mark as "electron leaving"
354     si = si - FieldWidth; // go up!
355     PlayField16[si] = 0x1018;
356     return subElectronFromBelow;
357   }
358
359   if (LowByte(ax) == fiMurphy) // check for murphy above
360   {
361     ExplodeFieldSP(si); // Explode
362     return subElectronFromBelow;
363   } // loc_g_7CC6:
364
365   ax = PlayField16[si + 1]; // check right field
366   if (ax == 0 || LowByte(ax) == fiMurphy) // check for empty or murphy
367   {
368     MovHighByte(&PlayField16[si], 9); // start to turn right
369     return subElectronFromBelow;
370   } // loc_g_7CE0:
371
372   // else: no way to go, start turning around
373   MovHighByte(&PlayField16[si], 1);
374
375   return subElectronFromBelow;
376 } // subElectronFromBelow
377
378 int subElectronFromRight(int si, int bx)
379 {
380   int subElectronFromRight;
381
382   // int ax, ah, bl, dx, X, Y;
383   int ax, bl, X, Y;
384
385   bx = bx - 0x17;  // get and increment sequence#
386   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
387   X = GetStretchX(si + 1);
388   Y = GetStretchY(si);
389   StretchedSprites.BltEx(X, Y, 0);
390   StretchedSprites.BltEx(X - bx * TwoPixels, Y, aniFramesElectron[bx]);
391   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
392   bl = LowByte(bx);
393   if (bl == 7 && LowByte(PlayField16[si + 1]) != fiExplosion)
394   {
395     PlayField16[si + 1] = 0; // electron left that field
396   } // loc_g_7D1D:
397
398   if (bl < 8) // sniksnak still goes left
399   {
400     bl = bl + 0x18;
401     MovHighByte(&PlayField16[si], bl);
402     return subElectronFromRight;
403   } // loc_g_7D2A:
404
405   PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field
406   ax = PlayField16[si + FieldWidth]; // check below
407   if (ax == 0 || LowByte(ax) == fiMurphy) // empty or murphy?
408   {
409     MovHighByte(&PlayField16[si], 3); // yes -> turn left down
410     return subElectronFromRight;
411   } // loc_g_7D4A:
412
413   ax = PlayField16[si - 1]; // check left, etc ... see the comments on subElectronFromBelow()
414   if (ax == 0)
415   {
416     PlayField16[si] = 0x2BB;
417     si = si - 1;                // 1 field left
418     PlayField16[si] = 0x1818;
419     return subElectronFromRight;
420   } // loc_g_7D61:
421
422   if (LowByte(ax) == fiMurphy)
423   {
424     ExplodeFieldSP(si);      // Explode
425     return subElectronFromRight;
426   } // loc_g_7D6C:
427
428   ax = PlayField16[si - FieldWidth]; // check above
429   if (ax == 0 || LowByte(ax) == fiMurphy)
430   {
431     MovHighByte(&PlayField16[si], 0xF);
432     return subElectronFromRight;
433   } // loc_g_7D86:
434
435   MovHighByte(&PlayField16[si], 3);
436
437   return subElectronFromRight;
438 } // subElectronFromRight
439
440 int subElectronFromAbove(int si, int bx)
441 {
442   int subElectronFromAbove;
443
444   // int ax, ah, bl, dx, X, Y;
445   int ax, bl, X, Y;
446
447   bx = bx - 0x1F;  // get and increment sequence#
448   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
449   X = GetStretchX(si);
450   Y = GetStretchY(si - FieldWidth);
451   StretchedSprites.BltEx(X, Y, 0);
452   StretchedSprites.BltEx(X, Y + bx * TwoPixels, aniFramesElectron[bx]);
453   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
454   bl = LowByte(bx);
455   if (bl == 7 && LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
456   {
457     PlayField16[si - FieldWidth] = 0; // electron left that field
458   }
459
460   if (bl < 8) // electron still goes down
461   {
462     bl = bl + 0x20;
463     MovHighByte(&PlayField16[si], bl);
464     return subElectronFromAbove;
465   } // loc_g_7DD7
466
467   PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field
468   ax = PlayField16[si + 1]; // check right
469   if (ax == 0 || LowByte(ax) == fiMurphy)
470   {
471     MovHighByte(&PlayField16[si], 5);
472     return subElectronFromAbove;
473   } // loc_g_7DF7:
474
475   ax = PlayField16[si + FieldWidth]; // check below
476   if (ax == 0)
477   {
478     PlayField16[si] = 0x3BB;
479     si = si + FieldWidth;                 // 1 field down
480     PlayField16[si] = 0x2018;
481     return subElectronFromAbove;
482   } // loc_g_7E0E:
483
484   if (LowByte(ax) == fiMurphy)
485   {
486     ExplodeFieldSP(si);        // Explode
487     return subElectronFromAbove;
488   } // loc_g_7E19:
489
490   ax = PlayField16[si - 1]; // check left
491   if (ax == 0 || LowByte(ax) == fiMurphy)
492   {
493     MovHighByte(&PlayField16[si], 0xD);
494     return subElectronFromAbove;
495   } // loc_g_7E33:
496
497   MovHighByte(&PlayField16[si], 5);
498
499   return subElectronFromAbove;
500 } // subElectronFromAbove
501
502 int subElectronFromLeft(int si, int bx)
503 {
504   int subElectronFromLeft;
505
506   // int ax, ah, bl, dx, X, Y;
507   int ax, bl, X, Y;
508
509   bx = bx - 0x27;  // get and increment sequence#
510   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
511   X = GetStretchX(si - 1);
512   Y = GetStretchY(si);
513   StretchedSprites.BltEx(X, Y, 0);
514   StretchedSprites.BltEx(X + bx * TwoPixels, Y, aniFramesElectron[bx]);
515   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
516   bl = LowByte(bx);
517   if (bl == 7 && LowByte(PlayField16[si - 1]) != fiExplosion)
518   {
519     PlayField16[si - 1] = 0; // electron left that field
520   }
521
522   if (bl < 8) // electron still goes right
523   {
524     bl = bl + 0x28;
525     MovHighByte(&PlayField16[si], bl);
526     return subElectronFromLeft;
527   } // loc_g_7E7E:
528
529   PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field
530   ax = PlayField16[si - FieldWidth]; // check above
531   if (ax == 0 || LowByte(ax) == fiMurphy)
532   {
533     MovHighByte(&PlayField16[si], 7);
534     return subElectronFromLeft;
535   } // loc_g_7E9E:
536
537   ax = PlayField16[si + 1]; // check right(straight on)
538   if (ax == 0)
539   {
540     PlayField16[si] = 0x4BB;
541     si = si + 1;                   // 1 field right
542     PlayField16[si] = 0x2818;
543     return subElectronFromLeft;
544   } // loc_g_7EB5:
545
546   if (LowByte(ax) == fiMurphy)
547   {
548     ExplodeFieldSP(si);    // Explode
549     return subElectronFromLeft;
550   } // loc_g_7EC0:
551
552   ax = PlayField16[si + FieldWidth]; // check below
553   if (ax == 0 || LowByte(ax) == fiMurphy)
554   {
555     MovHighByte(&PlayField16[si], 0xB);
556     return subElectronFromLeft;
557   } // loc_g_7A69:
558
559   MovHighByte(&PlayField16[si], 7);
560
561   return subElectronFromLeft;
562 } // subElectronFromLeft
563
564 int subDrawElectronTurnLeft(int si, int bx)
565 {
566   int subDrawElectronTurnLeft;
567
568   int X, Y;
569
570   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
571   X = GetStretchX(si);
572   Y = GetStretchY(si);
573   StretchedSprites.BltEx(X, Y, aniFramesElectron[bx]);
574   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
575
576   return subDrawElectronTurnLeft;
577 }
578
579 int subDrawElectronTurnRight(int si, int bx)
580 {
581   int subDrawElectronTurnRight;
582
583   int X, Y;
584
585   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
586   X = GetStretchX(si);
587   Y = GetStretchY(si);
588   StretchedSprites.BltEx(X, Y, aniFramesElectron[0x10 - bx]);
589   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
590
591   return subDrawElectronTurnRight;
592 }
593
594 int subDrawElectronFromBelow(int si, int bx)
595 {
596   int subDrawElectronFromBelow;
597
598   int X, Y;
599
600   bx = bx - 0xF;  // get and increment sequence#
601   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
602   X = GetStretchX(si);
603   Y = GetStretchY(si + FieldWidth);
604   StretchedSprites.BltEx(X, Y, 0);
605   StretchedSprites.BltEx(X, Y - bx * TwoPixels, aniFramesElectron[bx]);
606   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
607
608   return subDrawElectronFromBelow;
609 }
610
611 int subDrawElectronFromRight(int si, int bx)
612 {
613   int subDrawElectronFromRight;
614
615   int X, Y;
616
617   bx = bx - 0x17;  // get and increment sequence#
618   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
619   X = GetStretchX(si + 1);
620   Y = GetStretchY(si);
621   StretchedSprites.BltEx(X, Y, 0);
622   StretchedSprites.BltEx(X - bx * TwoPixels, Y, aniFramesElectron[bx]);
623   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
624
625   return subDrawElectronFromRight;
626 }
627
628 int subDrawElectronFromAbove(int si, int bx)
629 {
630   int subDrawElectronFromAbove;
631
632   int X, Y;
633
634   bx = bx - 0x1F;  // get and increment sequence#
635   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
636   X = GetStretchX(si);
637   Y = GetStretchY(si - FieldWidth);
638   StretchedSprites.BltEx(X, Y, 0);
639   StretchedSprites.BltEx(X, Y + bx * TwoPixels, aniFramesElectron[bx]);
640   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
641
642   return subDrawElectronFromAbove;
643 }
644
645 int subDrawElectronFromLeft(int si, int bx)
646 {
647   int subDrawElectronFromLeft;
648
649   int X, Y;
650
651   bx = bx - 0x27;  // get and increment sequence#
652   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
653   X = GetStretchX(si - 1);
654   Y = GetStretchY(si);
655   StretchedSprites.BltEx(X, Y, 0);
656   StretchedSprites.BltEx(X + bx * TwoPixels, Y, aniFramesElectron[bx]);
657   // +++++++++++++++++++++++++++++++++++++++++++++++++++++
658
659   return subDrawElectronFromLeft;
660 }