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