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