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