rnd-20090729-1-src
[rocksndiamonds.git] / src / game_sp / Murphy.c
1 // ----------------------------------------------------------------------------
2 // Murphy.c
3 // ----------------------------------------------------------------------------
4
5 #include "Murphy.h"
6
7 static void subEatRedDisk(int si);
8 static boolean subMoveKillsMurphy(int si, int ax, int bl);
9
10 // static char *VB_Name = "modMurphy";
11
12 // --- Option Explicit
13
14 #define LocalStretch                    (1)
15
16 // ==========================================================================
17 //                              SUBROUTINE
18 // Move Murphy in any direction
19 // ==========================================================================
20
21 int subAnimateMurphy(int *si)
22 {
23   int subAnimateMurphy;
24
25   // int ax, al, ah, bx, bl, i, X, Y;
26   // int tX, tY, tDeltaX, tDeltaY, tPos, Tmp;
27   int ax, al, bx, bl, i, X, Y;
28   int tDeltaX, tDeltaY, tPos, Tmp;
29
30   // Variables that hold information about the animation sequence
31   static int *dx = 0; // an array of image positions in moving.mpx, finalized with -1
32   static int dx2 = 0; // an additional image position of a second sprite, for instance: yellow disk if pushed
33   static int MurphyDX = 0, MurphyDY = 0; // murphys move steps
34   static int SeqPos = 0; // index into dx()
35   static int ClearPos = 0; // Position to clear before blitting sprites, none=-1
36   static int dxPos = 0; // field-position  to draw dx(SeqPos)
37   static int dx2Step = 0; // position of dx2 relative to dx-position
38
39   ax = PlayField16[*si];
40   al = LowByte(ax);
41
42 #if 1
43   printf("::: Murphy.c: subAnimateMurphy(): %d [%d, %d] %d, %d [%d]\n",
44          *si, *si % 60, *si / 60, ax, al, (al == fiMurphy));
45 #endif
46
47   if (al != fiMurphy)
48   {
49     MurphyMoveCounter = 0;             // We have no Murphy! Exit!
50     return subAnimateMurphy;
51   }
52
53   MurphyMoveCounter = 1;             // We have a Murphy!
54   MurphyExplodePos = *si;
55   if (ax != 3) // yes--go proceed moving murphy?
56     goto locProceedMovingMurphy;
57
58   // FS: reset moving sequence variables
59   MurphyDX = 0;
60   MurphyDY = 0;
61   ClearPos = *si;
62   dxPos = *si;
63   dx2 = -1;
64   SeqPos = 0;
65   // end of FS
66   ScratchGravity = 0; // scratch gravity off
67   if (GravityFlag != 0) // Gravity? (1=gravity on)
68   {
69     bl = LowByte(PlayField16[*si - FieldWidth]); // check above
70     if (! (bl == fiPortUp || bl == fiPortUpAndDown || bl == fiPortAllDirections))
71     {
72       if (PlayField16[*si + FieldWidth] == 0) // gravity on and space below!
73         ScratchGravity = 1;
74     }
75   } // loc_g_5E8B:
76
77   bl = DemoKeyCode;
78   if (bl != 0) // a key was pressed!
79     goto locKeyPressed5FCF;
80
81   RedDiskReleaseFlag = 1;
82   if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
83   {
84     MurphyDY = 2;
85     goto loc_g_6364;
86   }
87
88   ax = (TimerVar & 3);
89   if (ax != 0)
90     return subAnimateMurphy;
91
92   // ------------------------------------------------------------------
93   // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
94   YawnSleepCounter = YawnSleepCounter + 1;
95   if (YawnSleepCounter == 4)
96   {
97     subCopyFieldToScreen(*si, fiMurphy); // normal grin
98     return subAnimateMurphy;
99   } // loc_g_5ECE:
100
101   if (YawnSleepCounter <= 500) // loc_g_5ED7:
102     return subAnimateMurphy;
103
104   if (YawnSleepCounter <= 522)
105   {
106     bx = (YawnSleepCounter - 500) / 2;
107     subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
108     return subAnimateMurphy;
109   } // loc_g_5F00:
110
111   if (YawnSleepCounter <= 1000)
112     return subAnimateMurphy;
113
114   if (YawnSleepCounter <= 1022)
115   {
116     bx = (YawnSleepCounter - 1000) / 2;
117     subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again!
118     return subAnimateMurphy;
119   } // loc_g_5F32:
120
121   if (YawnSleepCounter <= 1600) // loc_g_5F3B:
122     return subAnimateMurphy;
123
124   if (YawnSleepCounter <= 1622)
125   {
126     bx = (YawnSleepCounter - 1600) / 2;
127     subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again! - third time
128     return subAnimateMurphy;
129   } // loc_g_5F64:
130
131   if (YawnSleepCounter > 1654)
132     return subAnimateMurphy;
133
134   if (PlayField16[*si - 1] == 0)
135   {
136     if (PlayField16[*si + 1] == 0)
137     {
138       YawnSleepCounter = 36;
139       return subAnimateMurphy;
140
141     }
142     else
143     {
144       bx = (YawnSleepCounter - 1622) / 16;
145       subCopyFieldToScreen(*si, aniMurphySleepRight + bx); // go to sleep
146       return subAnimateMurphy;
147     }
148   } // loc_g_5F81:
149
150   bx = (YawnSleepCounter - 1622) / 16;
151   subCopyFieldToScreen(*si, aniMurphySleepLeft + bx); // go to sleep
152   return subAnimateMurphy;
153
154   // end of YAWN-SLEEP-Sequence
155   // ------------------------------------------------------------------
156   // ==========================================================================
157   //                       (Direct Jump) a key was pressed
158   // ==========================================================================
159
160 locKeyPressed5FCF:
161   if (ScratchGravity == 0)
162     goto loc_g_6003;
163
164   if (PlayField16[*si + FieldWidth] != 0)
165     goto loc_g_6003;
166
167   if (bl == keyUp)
168   {
169     if (PlayField16[*si - FieldWidth] == fiBase)
170       goto loc_g_6003;
171
172   }
173   else if (bl == keyLeft)
174   {
175     if (PlayField16[*si - 1] == fiBase)
176       goto loc_g_6003;
177
178   }
179   else if (bl == keyRight)
180   {
181     if (PlayField16[*si + 1] == fiBase)
182       goto loc_g_6003;
183   } // loc_g_6001:
184
185   bl = keyDown;                      // force moving down!
186 loc_g_6003:
187   switch (bl)
188   {
189     case keyUp: // 1
190       RedDiskReleaseFlag = 0; // moving down to up ...
191       goto loc_g_6078;
192
193       break;
194
195     case keyLeft: // 2
196       RedDiskReleaseFlag = 0; // moving right to left ...
197       goto loc_g_60DA;
198
199       break;
200
201     case keyDown: // 3
202       RedDiskReleaseFlag = 0; // moving up to down ...
203       goto loc_g_6154;
204
205       break;
206
207     case keyRight: // 4
208       RedDiskReleaseFlag = 0; // moving left to right ...
209       goto loc_g_61B6;
210
211       break;
212
213     case keySpaceUp: // 5
214       RedDiskReleaseFlag = 0; // touching down to up ...
215       goto loc_g_622E;
216
217       break;
218
219     case keySpaceLeft: // 6
220       RedDiskReleaseFlag = 0; // touching right to left ...
221       goto loc_g_6258;
222
223       break;
224
225     case keySpaceDown: // 7
226       RedDiskReleaseFlag = 0; // touching up to down ...
227       goto loc_g_6288;
228
229       break;
230
231     case keySpaceRight: // 8
232       RedDiskReleaseFlag = 0; // touching left to right ...
233       goto loc_g_62B2;
234
235       break;
236
237     case keySpace: // 9
238       goto loc_g_62E2;                         // no move ...
239
240       break;
241
242     default:
243       RedDiskReleaseFlag = 0;
244       return subAnimateMurphy;
245       break;
246   }
247
248   // ==========================================================================
249   // moving down to up ...
250   // ==========================================================================
251
252 loc_g_6078:
253   // FS:
254   MurphyDY = -2;
255   // end of FS
256   ax = PlayField16[*si - FieldWidth];
257   al = LowByte(ax);
258   if (ax == fiSpace)
259     goto loc_g_6312;
260
261   if (ax == fiBase)
262     goto loc_g_63D3;
263
264   if (al == fiBug)
265     goto loc_g_63C2;
266
267   if (ax == fiInfotron)
268     goto loc_g_65C6;
269
270   if (ax == fiExit)
271     goto loc_g_6756;
272
273   if (al == fiTerminal)
274     goto loc_g_6817;
275
276   if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
277     goto loc_g_6916;
278
279   if (al == fiRedDisk)
280     goto loc_g_69A6;
281
282   if (al == fiYellowDisk)
283     goto loc_g_6AB8;
284
285   if (! subMoveKillsMurphy(*si - FieldWidth, ax, bl))
286     goto loc_g_6078;
287
288   return subAnimateMurphy;
289
290   // ==========================================================================
291   // moving right to left ...
292   // ==========================================================================
293
294 loc_g_60DA:
295   // FS:
296   MurphyDX = -2;
297   // end of FS
298   MurphyVarFaceLeft = 1;
299   ax = PlayField16[*si - 1];
300   al = LowByte(ax);
301   if (ax == fiSpace)
302     goto loc_g_6341;
303
304   if (ax == fiBase)
305     goto loc_g_641C;
306
307   if (al == fiBug)
308     goto loc_g_640B;
309
310   if (ax == fiInfotron)
311     goto loc_g_65FE;
312
313   if (ax == fiExit)
314     goto loc_g_6756;
315
316   if (ax == fiZonk)
317     goto loc_g_679B;
318
319   if (al == fiTerminal)
320     goto loc_g_684E;
321
322   if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
323     goto loc_g_693A;
324
325   if (ax == fiRedDisk)
326     goto loc_g_69CE;
327
328   if (ax == fiYellowDisk)
329     goto loc_g_6AF1;
330
331   if (ax == fiOrangeDisk)
332     goto loc_g_6B9B;
333
334   if (! subMoveKillsMurphy(*si - 1, ax, bl))
335     goto loc_g_60DA;
336
337   return subAnimateMurphy;
338
339   // ==========================================================================
340   // moving up to down ...
341   // ==========================================================================
342
343 loc_g_6154:
344   // FS:
345   MurphyDY = 2;
346   // end of FS
347   ax = PlayField16[*si + FieldWidth];
348   al = LowByte(ax);
349   if (ax == fiSpace)
350     goto loc_g_6364;
351
352   if (ax == fiBase)
353     goto loc_g_6459;
354
355   if (al == fiBug)
356     goto loc_g_6448;
357
358   if (ax == fiInfotron)
359     goto loc_g_662A;
360
361   if (ax == fiExit)
362     goto loc_g_6756;
363
364   if (al == fiTerminal)
365     goto loc_g_6884;
366
367   if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
368     goto loc_g_695E;
369
370   if (al == fiRedDisk)
371     goto loc_g_69F7;
372
373   if (al == fiYellowDisk)
374     goto loc_g_6B2A;
375
376   if (! subMoveKillsMurphy(*si + FieldWidth, ax, bl))
377     goto loc_g_6154;
378
379   return subAnimateMurphy;
380
381   // ==========================================================================
382   // moving left to right ...
383   // ==========================================================================
384
385 loc_g_61B6:
386   // FS:
387   MurphyDX = 2;
388   // end of FS
389   MurphyVarFaceLeft = 0;
390   ax = PlayField16[*si + 1];
391   al = LowByte(ax);
392   if (ax == fiSpace)
393     goto loc_g_6399;
394
395   if (ax == fiBase)
396     goto loc_g_64A2;
397
398   if (al == fiBug)
399     goto loc_g_6491;
400
401   if (ax == fiInfotron)
402     goto loc_g_6662;
403
404   if (ax == fiExit)
405     goto loc_g_6756;
406
407   if (ax == fiZonk)
408     goto loc_g_67D4;
409
410   if (al == fiTerminal)
411     goto loc_g_68BA;
412
413   if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
414     goto loc_g_6982;
415
416   if (al == fiRedDisk)
417     goto loc_g_6A1F;
418
419   if (al == fiYellowDisk)
420     goto loc_g_6B63;
421
422   if (ax == fiOrangeDisk)
423     goto loc_g_6BD3;
424
425   if (! subMoveKillsMurphy(*si + 1, ax, bl))
426     goto loc_g_61B6;
427
428   return subAnimateMurphy;
429
430   // ==========================================================================
431   // touching down to up ...
432   // ==========================================================================
433
434 loc_g_622E:
435   // FS:
436   ClearPos = -1;
437   dxPos = *si - FieldWidth;
438   // end of FS
439   ax = PlayField16[*si - FieldWidth];
440   al = LowByte(ax);
441   al = LowByte(ax);
442   if (ax == fiBase)
443     goto loc_g_64DF;
444
445   if (al == fiBug)
446     goto loc_g_64CE;
447
448   if (ax == fiInfotron)
449     goto loc_g_668E;
450
451   if (al == fiTerminal)
452     goto loc_g_6817;
453
454   if (al == fiRedDisk)
455     goto loc_g_6A48;
456
457   return subAnimateMurphy;
458
459   // ==========================================================================
460   // touching right to left ...
461   // ==========================================================================
462
463 loc_g_6258:
464   // FS:
465   ClearPos = -1;
466   dxPos = *si - 1;
467   // end of FS
468   MurphyVarFaceLeft = 1;
469   ax = PlayField16[*si - 1];
470   al = LowByte(ax);
471   if (ax == fiBase)
472     goto loc_g_651D;
473
474   if (al == fiBug)
475     goto loc_g_650C;
476
477   if (ax == fiInfotron)
478     goto loc_g_66C0;
479
480   if (al == fiTerminal)
481     goto loc_g_684E;
482
483   if (al == fiRedDisk)
484     goto loc_g_6A64;
485
486   return subAnimateMurphy;
487
488   // ==========================================================================
489   // touching up to down ...
490   // ==========================================================================
491
492 loc_g_6288:
493   // FS:
494   ClearPos = -1;
495   dxPos = *si + FieldWidth;
496   // end of FS
497   ax = PlayField16[*si + FieldWidth];
498   al = LowByte(ax);
499   if (ax == fiBase)
500     goto loc_g_655B;
501
502   if (al == fiBug)
503     goto loc_g_654A;
504
505   if (ax == fiInfotron)
506     goto loc_g_66F2;
507
508   if (al == fiTerminal)
509     goto loc_g_6884;
510
511   if (al == fiRedDisk)
512     goto loc_g_6A80;
513
514   return subAnimateMurphy;
515
516   // ==========================================================================
517   // touching left to right ...
518   // ==========================================================================
519
520 loc_g_62B2:
521   // FS:
522   ClearPos = -1;
523   dxPos = *si + 1;
524   // end of FS
525   MurphyVarFaceLeft = 0;
526   ax = PlayField16[*si + 1];
527   al = LowByte(ax);
528   if (ax == fiBase)
529     goto loc_g_6599;
530
531   if (al == fiBug)
532     goto loc_g_6588;
533
534   if (ax == fiInfotron)
535     goto loc_g_6724;
536
537   if (al == fiTerminal)
538     goto loc_g_68BA;
539
540   if (al == fiRedDisk)
541     goto loc_g_6A9C;
542
543   return subAnimateMurphy;
544
545   // ==========================================================================
546   // Release Red disk: no move ...
547   // ==========================================================================
548
549 loc_g_62E2:
550   // FS:
551   ClearPos = -1;
552   // end of FS
553   if (LowByte(RedDiskCount) == 0)
554     return subAnimateMurphy;
555
556   if (LowByte(RedDiskReleasePhase) != 0)
557     return subAnimateMurphy;
558
559   if (LowByte(RedDiskReleaseFlag) != 1)
560     return subAnimateMurphy;
561
562   MovHighByte(&PlayField16[*si], 0x2A);
563   MovingPictureSequencePhase = 0x40; // init picture move sequence
564   dx = aniRedDisk;
565   MovLowByte(&RedDiskReleasePhase, 1);
566   Mov(&RedDiskReleaseMurphyPos, *si);             // remember Murphy's location
567   goto loc_Split;
568
569   // ==========================================================================
570   // SPACE moving down to up
571   // ==========================================================================
572
573 loc_g_6312:
574   dx = (MurphyVarFaceLeft == 0 ?  aniMurphyEatUpRight :  aniMurphyEatUpRight);
575   PlayField16[*si - FieldWidth] = 0x103;
576   PlayField16[*si] = 0x300;
577   *si = *si - FieldWidth;
578   goto loc_StopNoSplit;
579
580   // ==========================================================================
581   // SPACE moving right to left
582   // ==========================================================================
583
584 loc_g_6341:
585   dx = aniMurphyEatLeft;
586   PlayField16[*si - 1] = 0x203;
587   PlayField16[*si] = 0x300;
588   *si = *si - 1;
589   goto loc_StopNoSplit;
590
591   // ==========================================================================
592   // SPACE moving up to down, and when gravity is pulling!
593   // ==========================================================================
594
595 loc_g_6364:
596   dx = (MurphyVarFaceLeft == 0 ?  aniMurphyEatUpRight :  aniMurphyEatUpRight);
597   PlayField16[*si + FieldWidth] = 0x303;
598   PlayField16[*si] = 0x300;
599   *si = *si + FieldWidth;
600   goto loc_StopNoSplit;
601
602   // ==========================================================================
603   // SPACE moving left to right
604   // ==========================================================================
605
606 loc_g_6399:
607   dx = aniMurphyEatRight;
608   PlayField16[*si + 1] = 0x403;
609   PlayField16[*si] = 0x300;
610   *si = *si + 1;
611   goto loc_StopNoSplit;
612
613   // ==========================================================================
614   // BUG moving down to up
615   // ==========================================================================
616
617 loc_g_63C2:
618   if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
619   {
620     ExplodeFieldSP(*si);                 // Explode
621     return subAnimateMurphy;
622   }
623
624   PlayField16[*si - FieldWidth] = fiBase;
625   // ==========================================================================
626   // BASE moving down to up
627   // ==========================================================================
628
629 loc_g_63D3:
630   subSoundFXBase();
631   dx = (MurphyVarFaceLeft == 0 ?  aniMurphyEatUpRight :  aniMurphyEatUpRight);
632   PlayField16[*si - FieldWidth] = 0x503;
633   PlayField16[*si] = 0x300;
634   *si = *si - FieldWidth;
635   goto loc_StopNoSplit;
636
637   // ==========================================================================
638   // BUG moving right to left
639   // ==========================================================================
640
641 loc_g_640B:
642   if (SgnHighByte(PlayField16[*si - 1]) >= 0)
643   {
644     ExplodeFieldSP(*si);                 // Explode
645     return subAnimateMurphy;
646   }
647
648   PlayField16[*si - 1] = fiBase;
649   // ==========================================================================
650   // BASE moving right to left
651   // ==========================================================================
652
653 loc_g_641C:
654   subSoundFXBase();
655   dx = aniMurphyEatLeft;
656   PlayField16[*si - 1] = 0x203;
657   PlayField16[*si] = 0x300;
658   *si = *si - 1;
659   goto loc_StopNoSplit;
660
661   // ==========================================================================
662   // BUG moving up to down
663   // ==========================================================================
664
665 loc_g_6448:
666   if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
667   {
668     ExplodeFieldSP(*si);                 // Explode
669     return subAnimateMurphy;
670   }
671
672   PlayField16[*si + FieldWidth] = fiBase;
673   // ==========================================================================
674   // BASE moving up to down
675   // ==========================================================================
676
677 loc_g_6459:
678   subSoundFXBase();
679   dx = (MurphyVarFaceLeft == 0 ?  aniMurphyEatUpRight :  aniMurphyEatUpRight);
680   PlayField16[*si + FieldWidth] = 0x703;
681   PlayField16[*si] = 0x300;
682   *si = *si + FieldWidth;
683   goto loc_StopNoSplit;
684
685   // ==========================================================================
686   // BUG moving left to right
687   // ==========================================================================
688
689 loc_g_6491:
690   if (SgnHighByte(PlayField16[*si + 1]) >= 0)
691   {
692     ExplodeFieldSP(*si);                 // Explode
693     return subAnimateMurphy;
694   }
695
696   PlayField16[*si + 1] = fiBase;
697   // ==========================================================================
698   // BASE moving left to right
699   // ==========================================================================
700
701 loc_g_64A2:
702   subSoundFXBase();
703   dx = aniMurphyEatRight;
704   PlayField16[*si + 1] = 0x803;
705   PlayField16[*si] = 0x300;
706   *si = *si + 1;
707   goto loc_StopNoSplit;
708
709   // ==========================================================================
710   // BUG touching down to up
711   // ==========================================================================
712
713 loc_g_64CE:
714   if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
715   {
716     ExplodeFieldSP(*si);                 // Explode
717     return subAnimateMurphy;
718   }
719
720   PlayField16[*si - FieldWidth] = fiBase;
721   // ==========================================================================
722   // BASE touching down to up
723   // ==========================================================================
724
725 loc_g_64DF:
726   subCopyFieldToScreen(*si, aniMurphyTouchUp);
727   subSoundFXBase();
728   dx = aniTouchBase;
729   dxPos = *si - FieldWidth;
730   MovHighByte(&PlayField16[*si], 0x10);
731   goto loc_StopNoSplit;
732
733   // ==========================================================================
734   // BUG touching right to left
735   // ==========================================================================
736
737 loc_g_650C:
738   if (SgnHighByte(PlayField16[*si - 1]) >= 0)
739   {
740     ExplodeFieldSP(*si);                 // Explode
741     return subAnimateMurphy;
742   }
743
744   PlayField16[*si - 1] = fiBase;
745   // ==========================================================================
746   // BASE touching right to left
747   // ==========================================================================
748
749 loc_g_651D:
750   subCopyFieldToScreen(*si, aniMurphyTouchLeft);
751   subSoundFXBase();
752   dx = aniTouchBase;
753   dxPos = *si - 1;
754   MovHighByte(&PlayField16[*si], 0x11);
755   goto loc_StopNoSplit;
756
757   // ==========================================================================
758   // BUG touching up to down
759   // ==========================================================================
760
761 loc_g_654A:
762   if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
763   {
764     ExplodeFieldSP(*si);                 // Explode
765     return subAnimateMurphy;
766   }
767
768   PlayField16[*si + FieldWidth] = fiBase;
769   // ==========================================================================
770   // BASE touching up to down
771   // ==========================================================================
772
773 loc_g_655B:
774   subCopyFieldToScreen(*si, aniMurphyTouchDown);
775   subSoundFXBase();
776   dx = aniTouchBase;
777   dxPos = *si + FieldWidth;
778   MovHighByte(&PlayField16[*si], 0x12);
779   goto loc_StopNoSplit;
780
781   // ==========================================================================
782   // BUG touching left to right
783   // ==========================================================================
784
785 loc_g_6588:
786   if (SgnHighByte(PlayField16[*si + 1]) >= 0)
787   {
788     ExplodeFieldSP(*si);                 // Explode
789     return subAnimateMurphy;
790   }
791
792   PlayField16[*si + 1] = fiBase;
793   // ==========================================================================
794   // BASE touching left to right
795   // ==========================================================================
796
797 loc_g_6599:
798   subCopyFieldToScreen(*si, aniMurphyTouchRight);
799   subSoundFXBase();
800   dx = aniTouchBase;
801   dxPos = *si + 1;
802   MovHighByte(&PlayField16[*si], 0x13);
803   goto loc_StopNoSplit;
804
805   // ==========================================================================
806   // INFOTRON moving down to up
807   // ==========================================================================
808
809 loc_g_65C6:
810   subSoundFXInfotron();
811   dx = (MurphyVarFaceLeft == 0 ?  aniMurphyEatUpRight :  aniMurphyEatUpRight);
812   PlayField16[*si - FieldWidth] = 0x903;
813   PlayField16[*si] = 0x300;
814   *si = *si - FieldWidth;
815   goto loc_StopNoSplit;
816
817   // ==========================================================================
818   // INFOTRON moving right to left
819   // ==========================================================================
820
821 loc_g_65FE:
822   subSoundFXInfotron();
823   dx = aniEatInfotronLeft;
824   dx2 = fiInfotron;
825   dx2Step = -1;
826   ClearPos = -1;
827   PlayField16[*si - 1] = 0xA03;
828   PlayField16[*si] = 0x300;
829   *si = *si - 1;
830   goto loc_StopNoSplit;
831
832   // ==========================================================================
833   // INFOTRON moving up to down
834   // ==========================================================================
835
836 loc_g_662A:
837   subSoundFXInfotron();
838   dx = (MurphyVarFaceLeft == 0 ?  aniMurphyEatUpRight :  aniMurphyEatUpRight);
839   PlayField16[*si + FieldWidth] = 0xB03;
840   PlayField16[*si] = 0x300;
841   *si = *si + FieldWidth;
842   goto loc_StopNoSplit;
843
844   // ==========================================================================
845   // INFOTRON moving left to right
846   // ==========================================================================
847
848 loc_g_6662:
849   subSoundFXInfotron();
850   dx = aniEatInfotronRight;
851   dx2 = fiInfotron;
852   dx2Step = 1;
853   ClearPos = -1;
854   PlayField16[*si + 1] = 0xC03;
855   PlayField16[*si] = 0x300;
856   *si = *si + 1;
857   goto loc_StopNoSplit;
858
859   // ==========================================================================
860   // INFOTRON touching down to up
861   // ==========================================================================
862
863 loc_g_668E:
864   subCopyFieldToScreen(*si, aniMurphyTouchUp);
865   subSoundFXInfotron();
866   dx = aniTouchInfotron;
867   MovHighByte(&PlayField16[*si], 0x14);
868   MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
869   goto loc_StopNoSplit;
870
871   // ==========================================================================
872   // INFOTRON touching right to left
873   // ==========================================================================
874
875 loc_g_66C0:
876   subCopyFieldToScreen(*si, aniMurphyTouchLeft);
877   subSoundFXInfotron();
878   dx = aniTouchInfotron;
879   MovHighByte(&PlayField16[*si], 0x15);
880   MovHighByte(&PlayField16[*si - 1], 0xFF);
881   goto loc_StopNoSplit;
882
883   // ==========================================================================
884   // INFOTRON touching up to down
885   // ==========================================================================
886
887 loc_g_66F2:
888   subCopyFieldToScreen(*si, aniMurphyTouchDown);
889   subSoundFXInfotron();
890   dx = aniTouchInfotron;
891   MovHighByte(&PlayField16[*si], 0x16);
892   MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
893   goto loc_StopNoSplit;
894
895   // ==========================================================================
896   // INFOTRON touching left to right
897   // ==========================================================================
898
899 loc_g_6724:
900   subCopyFieldToScreen(*si, aniMurphyTouchRight);
901   subSoundFXInfotron();
902   dx = aniTouchInfotron;
903   MovHighByte(&PlayField16[*si], 0x17);
904   MovHighByte(&PlayField16[*si + 1], 0xFF);
905   goto loc_StopNoSplit;
906
907   // ==========================================================================
908   // EXIT pressed from any direction
909   // ==========================================================================
910
911 loc_g_6756:
912   // FS
913   ClearPos = -1;
914   MurphyDX = 0;
915   MurphyDY = 0;
916   // end of FS
917   if (LowByte(InfotronsNeeded) != 0)
918     return subAnimateMurphy;
919
920   subSoundFXExit();
921   data_h_DemoDone = 1; // EP set level success bytes
922   LevelStatus = 1; // set Level Status DONE
923   EP_GameDemoVar0DAA = 0; // force demo for lead-out
924   if (SavedGameFlag == 0) // saved game running?
925   {
926     if (UpdateTimeFlag != 0)    // update time?
927     {
928       UpdatedFlag = 1; // prevent double update
929       subUpdatePlayingTime();    // update playing time
930     }
931   }
932
933 #if 0
934   subUpdateHallOfFame(); // update time + Hall-Of-Fame
935 #endif
936
937   LeadOutCounter = 0x40;          // quit: start lead-out
938   dx = aniMurphyExit;
939   MovHighByte(&PlayField16[*si], 0xD);
940   goto loc_StopNoSplit;
941
942   // ==========================================================================
943   // ZONK moving right to left
944   // ==========================================================================
945
946 loc_g_679B:
947   ax = PlayField16[*si - 2];
948   if (ax != 0)
949     return subAnimateMurphy;
950
951   MovHighByte(&PlayField16[*si - 2], 1);
952   subCopyFieldToScreen(*si, aniPushLeft); // draw pushing murphy
953   dx = aniZonkRollLeft;
954   dxPos = *si - 1;
955   dx2 = aniPushLeft;
956   dx2Step = 1;
957   MovHighByte(&PlayField16[*si], 0xE);
958   goto loc_MoveNoSplit;
959
960   // ==========================================================================
961   // ZONK moving left to right
962   // ==========================================================================
963
964 loc_g_67D4:
965   ax = PlayField16[*si + 2];
966   if (ax != 0)
967     return subAnimateMurphy;
968
969   ax = PlayField16[*si + FieldWidth + 1];
970   if (ax == 0) // zonk falls
971     return subAnimateMurphy;
972
973   MovHighByte(&PlayField16[*si + 2], 1);
974   subCopyFieldToScreen(*si, aniPushRight); // draw pushing murphy
975   dx = aniZonkRollRight;
976   dxPos = *si + 1;
977   dx2 = aniPushRight;
978   dx2Step = -1;
979   MovHighByte(&PlayField16[*si], 0xF);
980   goto loc_MoveNoSplit;
981
982   // ==========================================================================
983   // TERMINAL moving/touching down to up
984   // ==========================================================================
985
986 loc_g_6817:
987   subCopyFieldToScreen(*si, aniMurphyTouchUp);
988   if (YellowDisksExploded != 0)
989   {
990     YawnSleepCounter = 10; // stay hypnotized
991     return subAnimateMurphy;
992   } // loc_g_6838:
993
994   subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
995   TerminalState[*si - FieldWidth] = 8;
996   goto loc_g_68F0;
997
998   // ==========================================================================
999   // TERMINAL moving/touching right to left
1000   // ==========================================================================
1001
1002 loc_g_684E:
1003   subCopyFieldToScreen(*si, aniMurphyTouchLeft);
1004   if (YellowDisksExploded != 0)
1005   {
1006     YawnSleepCounter = 10; // stay hypnotized
1007     return subAnimateMurphy;
1008   } // loc_g_6838:
1009
1010   subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1011   TerminalState[*si - 1] = 8;
1012   goto loc_g_68F0;
1013
1014   // ==========================================================================
1015   // TERMINAL moving/touching up to down
1016   // ==========================================================================
1017
1018 loc_g_6884:
1019   subCopyFieldToScreen(*si, aniMurphyTouchDown);
1020   if (YellowDisksExploded != 0)
1021   {
1022     YawnSleepCounter = 10; // stay hypnotized
1023     return subAnimateMurphy;
1024   } // loc_g_6838:
1025
1026   subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1027   TerminalState[*si + FieldWidth] = 8;
1028   goto loc_g_68F0;
1029
1030   // ==========================================================================
1031   // TERMINAL moving/touching left to right
1032   // ==========================================================================
1033
1034 loc_g_68BA:
1035   subCopyFieldToScreen(*si, aniMurphyTouchRight);
1036   if (YellowDisksExploded != 0)
1037   {
1038     YawnSleepCounter = 10; // stay hypnotized
1039     return subAnimateMurphy;
1040   } // loc_g_6838:
1041
1042   subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1043   TerminalState[*si + 1] = 8;
1044   // ==========================================================================
1045   // common TERMINAL stuff moving/touching from all directions
1046   // ==========================================================================
1047
1048 loc_g_68F0:
1049   TerminalMaxCycles = 7;
1050   YellowDisksExploded = 1;
1051   for (i = 0; i <= LevelMax; i++)
1052   {
1053     if (PlayField16[i] == fiYellowDisk)
1054       ExplodeFieldSP (i);
1055   }
1056
1057   return subAnimateMurphy;
1058
1059   // ==========================================================================
1060   // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1061   // ==========================================================================
1062
1063 loc_g_6916:
1064   if (PlayField16[*si - 2 * FieldWidth] != 0)
1065     return subAnimateMurphy;
1066
1067   dx = aniSplitUpDown;
1068   dx2Step = -FieldWidth;
1069   PlayField16[*si] = 0x1803;
1070   PlayField16[*si - 2 * FieldWidth] = 0x300;
1071   goto loc_StopSplit;
1072
1073   // ==========================================================================
1074   // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1075   // ==========================================================================
1076
1077 loc_g_693A:
1078   if (PlayField16[*si - 2] != 0)
1079     return subAnimateMurphy;
1080
1081   dx = aniMurphyEatLeft;
1082   dx2Step = -1;
1083   PlayField16[*si] = 0x1903;
1084   PlayField16[*si - 2] = 0x300;
1085   goto loc_StopSplit;
1086
1087   // ==========================================================================
1088   // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1089   // ==========================================================================
1090
1091 loc_g_695E:
1092   if (PlayField16[*si + 2 * FieldWidth] != 0)
1093     return subAnimateMurphy;
1094
1095   dx = aniSplitUpDown;
1096   dx2Step = FieldWidth;
1097   PlayField16[*si] = 0x1A03;
1098   PlayField16[*si + 2 * FieldWidth] = 0x300;
1099   goto loc_StopSplit;
1100
1101   // ==========================================================================
1102   // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1103   // ==========================================================================
1104
1105 loc_g_6982:
1106   if (PlayField16[*si + 2] != 0)
1107     return subAnimateMurphy;
1108
1109   dx = aniMurphyEatRight;
1110   dx2Step = 1;
1111   PlayField16[*si] = 0x1B03;
1112   PlayField16[*si + 2] = 0x300;
1113
1114 loc_StopSplit:
1115   MovingPictureSequencePhase = 0; // stop picture move sequence
1116   SplitMoveFlag = 1; // port: split movement
1117   goto loc_Split;
1118
1119   // ==========================================================================
1120   // RED DISK moving down to up
1121   // ==========================================================================
1122
1123 loc_g_69A6:
1124   dx = (MurphyVarFaceLeft == 0 ?  aniMurphyEatUpRight :  aniMurphyEatUpRight);
1125   PlayField16[*si] = 0x1C03;
1126   PlayField16[*si - FieldWidth] = 0x300;
1127   goto loc_StopNoSplit;
1128
1129   // ==========================================================================
1130   // RED DISK moving right to left
1131   // ==========================================================================
1132
1133 loc_g_69CE:
1134   dx = aniMurphyEatLeft;
1135   PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1136   PlayField16[*si - 1] = 0x1D03;
1137   *si = *si - 1;
1138   goto loc_StopNoSplit;
1139
1140   // ==========================================================================
1141   // RED DISK moving up to down
1142   // ==========================================================================
1143
1144 loc_g_69F7:
1145   dx = (MurphyVarFaceLeft == 0 ?  aniMurphyEatUpRight :  aniMurphyEatUpRight);
1146   PlayField16[*si] = 0x1E03;
1147   PlayField16[*si + FieldWidth] = 0x300;
1148   goto loc_StopNoSplit;
1149
1150   // ==========================================================================
1151   // RED DISK moving left to right
1152   // ==========================================================================
1153
1154 loc_g_6A1F:
1155   //  dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1156   dx = aniMurphyEatRight;
1157   // --------------------------------------------------------------------------
1158   // BugFix
1159   // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1160   // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1161   // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1162   // We may not fix the table, because then the timing of the game changes
1163   // and several existing demo's do not run properly anymore.
1164   // We only correct Murphies x-location here, when the sequence starts.
1165   // Remember that this is not the real bug-fix, but we must live with
1166   // this existing bug and correct for the consequences of it.
1167   if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1168     MurphyScreenXPos = MurphyScreenXPos - 2;
1169
1170   SeqPos = -1;
1171   // FS: for me this means to blit the first animation frame twice
1172   // end of BugFix
1173   // --------------------------------------------------------------------------
1174   PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1175   PlayField16[*si + 1] = 0x1F03;
1176   *si = *si + 1;
1177   goto loc_StopNoSplit;
1178
1179   // ==========================================================================
1180   // RED DISK touching down to up
1181   // ==========================================================================
1182
1183 loc_g_6A48:
1184   dx = aniTouchRedDisk;
1185   MovHighByte(&PlayField16[*si], 0x20);
1186   MovHighByte(&PlayField16[*si - FieldWidth], 3);
1187   goto loc_StopNoSplit;
1188
1189   // ==========================================================================
1190   // RED DISK touching right to left
1191   // ==========================================================================
1192
1193 loc_g_6A64:
1194   dx = aniTouchRedDisk;
1195   MovHighByte(&PlayField16[*si], 0x21);
1196   MovHighByte(&PlayField16[*si - 1], 3);
1197   goto loc_StopNoSplit;
1198
1199   // ==========================================================================
1200   // RED DISK touching up to down
1201   // ==========================================================================
1202
1203 loc_g_6A80:
1204   dx = aniTouchRedDisk;
1205   MovHighByte(&PlayField16[*si], 0x22);
1206   MovHighByte(&PlayField16[*si + FieldWidth], 3);
1207   goto loc_StopNoSplit;
1208
1209   // ==========================================================================
1210   // RED DISK touching left to right
1211   // ==========================================================================
1212
1213 loc_g_6A9C:
1214   dx = aniTouchRedDisk;
1215   MovHighByte(&PlayField16[*si], 0x23);
1216   MovHighByte(&PlayField16[*si + 1], 3);
1217
1218 loc_StopNoSplit:
1219   MovingPictureSequencePhase = 0; // stop picture move sequence
1220   goto loc_NoSplit;
1221
1222   // ==========================================================================
1223   // YELLOW DISK moving down to up
1224   // ==========================================================================
1225
1226 loc_g_6AB8:
1227   if (PlayField16[*si - 2 * FieldWidth] != 0)
1228     return subAnimateMurphy;
1229
1230   PlayField16[*si - 2 * FieldWidth] = 0x1200;
1231   subCopyFieldToScreen(*si, aniPushRight);
1232   dx = aniYellowDisk;
1233   dxPos = *si - FieldWidth;
1234   dx2 = aniPushUpDown;
1235   dx2Step = FieldWidth;
1236   PlayField16[*si] = 0x2403;
1237   goto loc_MoveNoSplit;
1238
1239   // ==========================================================================
1240   // YELLOW DISK moving right to left
1241   // ==========================================================================
1242
1243 loc_g_6AF1:
1244   if (PlayField16[*si - 2] != 0)
1245     return subAnimateMurphy;
1246
1247   PlayField16[*si - 2] = 0x1200;
1248   subCopyFieldToScreen(*si, aniPushLeft);
1249   dx = aniYellowDisk;
1250   dxPos = *si - 1;
1251   dx2 = aniPushLeft;
1252   dx2Step = 1;
1253   PlayField16[*si] = 0x2503;
1254   goto loc_MoveNoSplit;
1255
1256   // ==========================================================================
1257   // YELLOW DISK moving up to down
1258   // ==========================================================================
1259
1260 loc_g_6B2A:
1261   if (PlayField16[*si + 2 * FieldWidth] != 0)
1262     return subAnimateMurphy;
1263
1264   PlayField16[*si + 2 * FieldWidth] = 0x1200;
1265   subCopyFieldToScreen(*si, aniPushRight);
1266   dx = aniYellowDisk;
1267   dxPos = *si + FieldWidth;
1268   dx2 = aniPushUpDown;
1269   dx2Step = -FieldWidth;
1270   PlayField16[*si] = 0x2703;
1271   goto loc_MoveNoSplit;
1272
1273   // ==========================================================================
1274   // YELLOW DISK moving left to right
1275   // ==========================================================================
1276
1277 loc_g_6B63:
1278   if (PlayField16[*si + 2] != 0)
1279     return subAnimateMurphy;
1280
1281   PlayField16[*si + 2] = 0x1200;
1282   subCopyFieldToScreen(*si, aniPushRight);
1283   dx = aniYellowDisk;
1284   dxPos = *si + 1;
1285   dx2 = aniPushRight;
1286   dx2Step = -1;
1287   PlayField16[*si] = 0x2603;
1288   goto loc_MoveNoSplit;
1289
1290   // ==========================================================================
1291   // ORANGE DISK moving right to left
1292   // ==========================================================================
1293
1294 loc_g_6B9B:
1295   if (PlayField16[*si - 2] != 0)
1296     return subAnimateMurphy;
1297
1298   PlayField16[*si - 2] = 0x800;
1299   subCopyFieldToScreen(*si, aniPushLeft);
1300   dx = aniOrangeDisk;
1301   dxPos = *si - 1;
1302   dx2 = aniPushLeft;
1303   dx2Step = 1;
1304   PlayField16[*si] = 0x2803;
1305   goto loc_MoveNoSplit;
1306
1307   // ==========================================================================
1308   // ORANGE DISK moving left to right
1309   // ==========================================================================
1310
1311 loc_g_6BD3:
1312   if (PlayField16[*si + 2] != 0)
1313     return subAnimateMurphy;
1314
1315   if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1316     return subAnimateMurphy;
1317
1318   PlayField16[*si + 2] = 0x100;
1319   subCopyFieldToScreen(*si, aniPushRight);
1320   dx = aniOrangeDisk;
1321   dxPos = *si + 1;
1322   dx2 = aniPushRight;
1323   dx2Step = -1;
1324   PlayField16[*si] = 0x2903;
1325   // ==========================================================================
1326   // Copy screen animation action table to action work space
1327   // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1328   // ==========================================================================
1329
1330 loc_MoveNoSplit:
1331   MovingPictureSequencePhase = 8; // init picture move sequence
1332
1333 loc_NoSplit:
1334   SplitMoveFlag = 0; // no port: no split movement
1335
1336 loc_Split:
1337   //  copy/store global move sequence info????????????????????????????????????
1338   //  ... dont think so ...(FS)
1339   // ==========================================================================
1340   // Proceed with all movements
1341   // ==========================================================================
1342
1343 locProceedMovingMurphy: // proceed moving murphy
1344   YawnSleepCounter = 0; // Wake up sleeping Murphy
1345   ax = MovingPictureSequencePhase;            // sequence busy?
1346   if (ax == 0)             // no -- start sequence!
1347     goto loc_g_6C8F;
1348
1349   ax = ax - 1;   // next picture of sequence
1350   MovingPictureSequencePhase = ax;            // store for later
1351   if (ax == 0) // Sound effects
1352     subSoundFXPush();
1353
1354   bl = HighByte(PlayField16[*si]);
1355   if (bl == 0xE)        // Push Zonk to left
1356     goto loc_g_6F7E;
1357
1358   if (bl == 0xF)        // Push Zonk to right
1359     goto loc_g_6FBC;
1360
1361   if (bl == 0x28)       // Push orange disk to left
1362     goto loc_g_6FFA;
1363
1364   if (bl == 0x29)       // Push orange disk to right
1365     goto loc_g_7038;
1366
1367   if (bl == 0x24)       // Push yellow disk up
1368     goto loc_g_7076;
1369
1370   if (bl == 0x25)       // Push yellow disk to left
1371     goto loc_g_70B4;
1372
1373   if (bl == 0x27)       // Push yellow disk down
1374     goto loc_g_70F2;
1375
1376   if (bl == 0x26)       // Push yellow disk to right
1377     goto loc_g_7130;
1378
1379   if (bl == 0x2A)       // Red disk release timer
1380     goto loc_g_716E;
1381
1382   return subAnimateMurphy;
1383
1384   // ==========================================================================
1385   // Paint frame of MOVING.DAT sequence
1386   // ==========================================================================
1387
1388 loc_g_6C8F:
1389   if (SplitMoveFlag == 0)
1390   {
1391     // ++++++++++++++++++++++++++
1392     // Begin of normal movement
1393     MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1394     MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1395     if (! ClearPos < 0) // clear field that murphy is leaving
1396       subCopyFieldToScreen(ClearPos, 0);
1397
1398     if (dx2 == fiInfotron) // special case of infotron moving left or right
1399     {
1400       tDeltaX = 0;
1401       tDeltaY = 0;
1402     }
1403     else
1404     {
1405       tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1406       tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1407     }
1408
1409     X = GetStretchX(dxPos) + tDeltaX;
1410     Y = GetStretchY(dxPos) + tDeltaY;
1411     Tmp = (SeqPos < 0 ?  0 :  0); // 9StepBugFix!(red disk move right)
1412     StretchedSprites.BltEx(X, Y, dx[Tmp]);
1413     if (! dx2 < 0)
1414     {
1415       tPos = dxPos + dx2Step;
1416       X = GetStretchX(tPos);
1417       Y = GetStretchY(tPos);
1418       if (dx2 == fiInfotron) // special case of infotron moving left or right
1419       {
1420         StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1421       }
1422       else // pushing something
1423       {
1424         StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1425       }
1426     }
1427
1428     // End of normal movement
1429     // ------------------------
1430   }
1431   else
1432   {
1433     // ++++++++++++++++++++++++++++++++
1434     // Begin of split movement (port)
1435     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1436     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1437     subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1438     tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1439     tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1440     X = GetStretchX(dxPos) + tDeltaX;
1441     Y = GetStretchY(dxPos) + tDeltaY;
1442     StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1443     tPos = dxPos + dx2Step;
1444     X = GetStretchX(tPos);
1445     Y = GetStretchY(tPos);
1446     StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1447     StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1448     // End of split movement (port)
1449     // ------------------------------
1450   } // loc_g_6D1E:'loc_g_6D28:
1451
1452   SeqPos = SeqPos + 1;
1453   if (dx[SeqPos] > -1)
1454     return subAnimateMurphy;
1455
1456   // Follow-up after movement completed     'loc_g_6D35:
1457   MurphyXPos = MurphyXPos + MurphyDX;
1458   MurphyYPos = MurphyYPos + MurphyDY;
1459   bl = HighByte(PlayField16[*si]);  // animation phase
1460   MovHighByte(&PlayField16[*si], 0);
1461
1462   if (bl == 0x1)    // space, moving up
1463     goto loc_g_6EC8;
1464
1465   if (bl == 0x2)    // space, moving left
1466     goto loc_g_6EE6;
1467
1468   if (bl == 0x3)    // space, moving down
1469     goto loc_g_6F04;
1470
1471   if (bl == 0x4)    // space, moving right
1472     goto loc_g_71C4;
1473
1474   if (bl == 0x5)    // base , moving up
1475     goto loc_g_6EC8;
1476
1477   if (bl == 0x6)    // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1478     goto loc_g_6EE6;
1479
1480   if (bl == 0x7)    // base , moving down
1481     goto loc_g_6F04;
1482
1483   if (bl == 0x8)    // base , moving right
1484     goto loc_g_71C4;
1485
1486   if (bl == 0x9)    // infotron, moving up
1487     goto loc_g_6EBA;
1488
1489   if (bl == 0xA)      // infotron, moving left
1490     goto loc_g_6ED8;
1491
1492   if (bl == 0xB)    // infotron, moving down
1493     goto loc_g_6EF6;
1494
1495   if (bl == 0xC)      // infotron, moving right
1496     goto loc_g_71B6;
1497
1498   if (bl == 0xD)      // exit
1499     goto loc_g_6F77;
1500
1501   if (bl == 0xE)      // zonk, pushing left
1502     goto loc_g_6F18;
1503
1504   if (bl == 0xF)      // zonk, pushing right
1505     goto loc_g_6F3B;
1506
1507   if (bl == 0x10)   // base , touching up
1508     goto loc_g_71E2;
1509
1510   if (bl == 0x11)   // base , touching left
1511     goto loc_g_71FE;
1512
1513   if (bl == 0x12)   // base , touching down
1514     goto loc_g_721A;
1515
1516   if (bl == 0x13)   // base , touching right
1517     goto loc_g_7236;
1518
1519   if (bl == 0x14)   // infotron touching up
1520     goto loc_g_71D4;
1521
1522   if (bl == 0x15)   // infotron touching left
1523     goto loc_g_71F0;
1524
1525   if (bl == 0x16)   // infotron touching down
1526     goto loc_g_720C;
1527
1528   if (bl == 0x17)   // infotron touching right
1529     goto loc_g_7228;
1530
1531   if (bl == 0x18)     // port up
1532     goto loc_g_7244;
1533
1534   if (bl == 0x19)     // port left
1535     goto loc_g_7272;
1536
1537   if (bl == 0x1A)     // port down
1538     goto loc_g_729F;
1539
1540   if (bl == 0x1B)     // port right
1541     goto loc_g_72CD;
1542
1543   if (bl == 0x1C)   // red disk, moving up
1544     goto loc_g_72FA;
1545
1546   if (bl == 0x1D)   // red disk, moving left
1547     goto loc_g_7318;
1548
1549   if (bl == 0x1E)   // red disk, moving down
1550     goto loc_g_7333;
1551
1552   if (bl == 0x1F)   // red disk, moving right -> 9-Step-Bug!
1553     goto loc_g_7351;
1554
1555   if (bl == 0x20)   // red disk, touching up
1556     goto loc_g_736C;
1557
1558   if (bl == 0x21)   // red disk, touching left
1559     goto loc_g_7381;
1560
1561   if (bl == 0x22)   // red disk, touching down
1562     goto loc_g_7396;
1563
1564   if (bl == 0x23)   // red disk, touching right
1565     goto loc_g_73AB;
1566
1567   if (bl == 0x24)     // yellow disk, pushing up
1568     goto loc_g_73C0;
1569
1570   if (bl == 0x25)     // yellow disk, pushing left
1571     goto loc_g_73DD;
1572
1573   if (bl == 0x26)     // yellow disk, pushing right -> order of "down" exchanged with "right"!
1574     goto loc_g_7417;
1575
1576   if (bl == 0x27)     // yellow disk, pushing down  -> order of "down" exchanged with "right"!
1577     goto loc_g_73FA;
1578
1579   if (bl == 0x28)     // orange disk, pushing left
1580     goto loc_g_7434;
1581
1582   if (bl == 0x29)     // orange disk, pushing right
1583     goto loc_g_7451;
1584
1585   if (bl == 0x2A)   // red disk, release
1586     goto loc_g_747F;
1587
1588   ExitToMenuFlag = 1;
1589   return subAnimateMurphy;
1590
1591   // ==========================================================================
1592   //                       infotron, moving up
1593   // ==========================================================================
1594
1595 loc_g_6EBA:
1596   if (0 < LowByte(InfotronsNeeded))
1597     InfotronsNeeded = InfotronsNeeded - 1;
1598
1599   subDisplayInfotronsNeeded();
1600 loc_g_6EC8: // space, base
1601   PlayField16[*si] = fiMurphy;
1602   subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1603   return subAnimateMurphy;
1604
1605   // ==========================================================================
1606   //                       infotron, moving left
1607   // ==========================================================================
1608
1609 loc_g_6ED8:
1610   if (0 < LowByte(InfotronsNeeded))
1611     InfotronsNeeded = InfotronsNeeded - 1;
1612
1613   subDisplayInfotronsNeeded();
1614 loc_g_6EE6: // space, base
1615   PlayField16[*si] = fiMurphy;
1616   subAdjustZonksInfotronsAboveMurphy(*si + 1);
1617   return subAnimateMurphy;
1618
1619   // ==========================================================================
1620   //                       infotron, moving down
1621   // ==========================================================================
1622
1623 loc_g_6EF6:
1624   if (0 < LowByte(InfotronsNeeded))
1625     InfotronsNeeded = InfotronsNeeded - 1;
1626
1627   subDisplayInfotronsNeeded();
1628 loc_g_6F04: // space, base
1629   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1630     PlayField16[*si - FieldWidth] = 0;
1631
1632   PlayField16[*si] = fiMurphy;
1633   return subAnimateMurphy;
1634
1635   // ==========================================================================
1636   //                       infotron, moving right
1637   // ==========================================================================
1638
1639 loc_g_71B6:
1640   if (0 < LowByte(InfotronsNeeded))
1641     InfotronsNeeded = InfotronsNeeded - 1;
1642
1643   subDisplayInfotronsNeeded();
1644 loc_g_71C4: // space, base
1645   subAdjustZonksInfotronsAboveMurphy(*si - 1);
1646   PlayField16[*si] = fiMurphy;
1647   return subAnimateMurphy;
1648
1649   // ==========================================================================
1650   //                       infotron, touching up
1651   // ==========================================================================
1652
1653 loc_g_71D4:
1654   if (0 < LowByte(InfotronsNeeded))
1655     InfotronsNeeded = InfotronsNeeded - 1;
1656
1657   subDisplayInfotronsNeeded();
1658 loc_g_71E2: // base
1659   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1660     PlayField16[*si - FieldWidth] = 0;
1661
1662   return subAnimateMurphy;
1663
1664   // ==========================================================================
1665   //                       infotron, touching left
1666   // ==========================================================================
1667
1668 loc_g_71F0:
1669   if (0 < LowByte(InfotronsNeeded))
1670     InfotronsNeeded = InfotronsNeeded - 1;
1671
1672   subDisplayInfotronsNeeded();
1673 loc_g_71FE: // base
1674   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1675     PlayField16[*si - 1] = 0;
1676
1677   return subAnimateMurphy;
1678
1679   // ==========================================================================
1680   //                       infotron, touching down
1681   // ==========================================================================
1682
1683 loc_g_720C:
1684   if (0 < LowByte(InfotronsNeeded))
1685     InfotronsNeeded = InfotronsNeeded - 1;
1686
1687   subDisplayInfotronsNeeded();
1688 loc_g_721A: // base
1689   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1690     PlayField16[*si + FieldWidth] = 0;
1691
1692   return subAnimateMurphy;
1693
1694   // ==========================================================================
1695   //                       infotron, touching right
1696   // ==========================================================================
1697
1698 loc_g_7228:
1699   if (0 < LowByte(InfotronsNeeded))
1700     InfotronsNeeded = InfotronsNeeded - 1;
1701
1702   subDisplayInfotronsNeeded();
1703 loc_g_7236: // base
1704   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1705     PlayField16[*si + 1] = 0;
1706
1707   return subAnimateMurphy;
1708
1709   // ==========================================================================
1710   //                       zonk, pushing left
1711   // ==========================================================================
1712
1713 loc_g_6F18:
1714   if (LowByte(PlayField16[*si]) != fiExplosion)
1715     PlayField16[*si] = 0;
1716
1717   PlayField16[*si - 1] = fiMurphy;
1718   PlayField16[*si - 2] = fiZonk;
1719   subExplodeSnikSnaksBelow(*si - 2);
1720   *si = *si - 1;
1721   return subAnimateMurphy;
1722
1723   // ==========================================================================
1724   //                       zonk, pushing right
1725   // ==========================================================================
1726
1727 loc_g_6F3B:
1728   if (LowByte(PlayField16[*si]) != fiExplosion)
1729     PlayField16[*si] = 0;
1730
1731   PlayField16[*si + 1] = fiMurphy;
1732   PlayField16[*si + 2] = fiZonk;
1733   subExplodeSnikSnaksBelow(*si + 2);
1734   *si = *si + 1;
1735   return subAnimateMurphy;
1736
1737   // ==========================================================================
1738   //                       exit
1739   // ==========================================================================
1740
1741 loc_g_6F77:
1742   ExitToMenuFlag = 1;
1743   return subAnimateMurphy;
1744
1745   // ==========================================================================
1746   //               Push Zonk from right to left
1747   // ==========================================================================
1748
1749 loc_g_6F7E:
1750   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1751     return subAnimateMurphy;
1752
1753   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1754   PlayField16[*si - 1] = fiZonk;
1755   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1756     PlayField16[*si - 2] = 0;
1757
1758   subCopyFieldToScreen(*si, fiMurphy);
1759   return subAnimateMurphy;
1760
1761   // ==========================================================================
1762   //                       Push Zonk from left to right
1763   // ==========================================================================
1764
1765 loc_g_6FBC:
1766   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1767     return subAnimateMurphy;
1768
1769   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1770   PlayField16[*si + 1] = fiZonk;
1771   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1772     PlayField16[*si + 2] = 0;
1773
1774   subCopyFieldToScreen(*si, fiMurphy);
1775   return subAnimateMurphy;
1776
1777   // ==========================================================================
1778   //               Push orange disk from right to left
1779   // ==========================================================================
1780
1781 loc_g_6FFA:
1782   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1783     return subAnimateMurphy;
1784
1785   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1786   PlayField16[*si - 1] = fiOrangeDisk;
1787   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1788     PlayField16[*si - 2] = 0;
1789
1790   subCopyFieldToScreen(*si, fiMurphy);
1791   return subAnimateMurphy;
1792
1793   // ==========================================================================
1794   //               Push orange disk from left to right
1795   // ==========================================================================
1796
1797 loc_g_7038:
1798   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1799     return subAnimateMurphy;
1800
1801   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1802   PlayField16[*si + 1] = fiOrangeDisk;
1803   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1804     PlayField16[*si + 2] = 0;
1805
1806   subCopyFieldToScreen(*si, fiMurphy);
1807   return subAnimateMurphy;
1808
1809   // ==========================================================================
1810   //               Push yellow disk from down to up
1811   // ==========================================================================
1812
1813 loc_g_7076:
1814   if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1815     return subAnimateMurphy;
1816
1817   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1818   PlayField16[*si - FieldWidth] = fiYellowDisk;
1819   if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1820     PlayField16[*si - 2 * FieldWidth] = 0;
1821
1822   subCopyFieldToScreen(*si, fiMurphy);
1823   return subAnimateMurphy;
1824
1825   // ==========================================================================
1826   //               Push yellow disk from right to left
1827   // ==========================================================================
1828
1829 loc_g_70B4:
1830   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1831     return subAnimateMurphy;
1832
1833   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1834   PlayField16[*si - 1] = fiYellowDisk;
1835   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1836     PlayField16[*si - 2] = 0;
1837
1838   subCopyFieldToScreen(*si, fiMurphy);
1839   return subAnimateMurphy;
1840
1841   // ==========================================================================
1842   //               Push yellow disk from up to down
1843   // ==========================================================================
1844
1845 loc_g_70F2:
1846   if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1847     return subAnimateMurphy;
1848
1849   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1850   PlayField16[*si + FieldWidth] = fiYellowDisk;
1851   if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1852     PlayField16[*si + 2 * FieldWidth] = 0;
1853
1854   subCopyFieldToScreen(*si, fiMurphy);
1855   return subAnimateMurphy;
1856
1857   // ==========================================================================
1858   //               Push yellow disk from left to right
1859   // ==========================================================================
1860
1861 loc_g_7130:
1862   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1863     return subAnimateMurphy;
1864
1865   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1866   PlayField16[*si + 1] = fiYellowDisk;
1867   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1868     PlayField16[*si + 2] = 0;
1869
1870   subCopyFieldToScreen(*si, fiMurphy);
1871   return subAnimateMurphy;
1872
1873   // ==========================================================================
1874   //               time red disk release (space)
1875   // ==========================================================================
1876
1877 loc_g_716E:
1878   if (DemoKeyCode != keySpace)
1879   {
1880     PlayField16[*si] = fiMurphy;
1881     subCopyFieldToScreen(*si, fiMurphy);
1882     RedDiskReleasePhase = 0;
1883   }
1884   else if (MovingPictureSequencePhase == 0x20)
1885   {
1886     subCopyFieldToScreen(*si, 43);  // anxious murphy
1887     RedDiskReleasePhase = 1;
1888   }
1889
1890   return subAnimateMurphy;
1891
1892   // ==========================================================================
1893   // Special port down to up
1894   // ==========================================================================
1895
1896 loc_g_7244:
1897   if (LowByte(PlayField16[*si]) != fiExplosion)
1898     PlayField16[*si] = 0;
1899
1900   PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1901   SplitMoveFlag = 0;
1902   *si = *si - FieldWidth;
1903   if (HighByte(PlayField16[*si]) == 1)
1904     subSpPortTest(*si);
1905
1906   *si = *si - FieldWidth;
1907   return subAnimateMurphy;
1908
1909   // ==========================================================================
1910   // Special port right to left
1911   // ==========================================================================
1912
1913 loc_g_7272:
1914   if (LowByte(PlayField16[*si]) != fiExplosion)
1915     PlayField16[*si] = 0;
1916
1917   PlayField16[*si - 2] = fiMurphy;
1918   SplitMoveFlag = 0;
1919   *si = *si - 1;
1920   if (HighByte(PlayField16[*si]) == 1)
1921     subSpPortTest(*si);
1922
1923   *si = *si - 1;
1924   return subAnimateMurphy;
1925
1926   // ==========================================================================
1927   // Special port up to down
1928   // ==========================================================================
1929
1930 loc_g_729F:
1931   if (LowByte(PlayField16[*si]) != fiExplosion)
1932     PlayField16[*si] = 0;
1933
1934   PlayField16[*si + 2 * FieldWidth] = fiMurphy;
1935   SplitMoveFlag = 0;
1936   *si = *si + FieldWidth;
1937   if (HighByte(PlayField16[*si]) == 1)
1938     subSpPortTest(*si);
1939
1940   *si = *si + FieldWidth;
1941   return subAnimateMurphy;
1942
1943   // ==========================================================================
1944   // Special port left to right
1945   // ==========================================================================
1946
1947 loc_g_72CD:
1948   if (LowByte(PlayField16[*si]) != fiExplosion)
1949     PlayField16[*si] = 0;
1950
1951   PlayField16[*si + 2] = fiMurphy;
1952   SplitMoveFlag = 0;
1953   *si = *si + 1;
1954   if (HighByte(PlayField16[*si]) == 1)
1955     subSpPortTest(*si);
1956
1957   *si = *si + 1;
1958   return subAnimateMurphy;
1959
1960   // ==========================================================================
1961   // Move Red Disk up
1962   // ==========================================================================
1963
1964 loc_g_72FA:
1965   if (LowByte(PlayField16[*si]) != fiExplosion)
1966     PlayField16[*si] = 0;
1967
1968   *si = *si - FieldWidth;
1969   PlayField16[*si] = fiMurphy;
1970   subEatRedDisk(*si); // inc+show Murphy's red disks
1971   return subAnimateMurphy;
1972
1973   // ==========================================================================
1974   // Move Red Disk left
1975   // ==========================================================================
1976
1977 loc_g_7318:
1978   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1979     PlayField16[*si + 1] = 0;
1980
1981   PlayField16[*si] = fiMurphy;
1982   subEatRedDisk(*si); // inc+show Murphy's red disks
1983   return subAnimateMurphy;
1984
1985   // ==========================================================================
1986   // Move Red Disk down
1987   // ==========================================================================
1988
1989 loc_g_7333:
1990   if (LowByte(PlayField16[*si]) != fiExplosion)
1991     PlayField16[*si] = 0;
1992
1993   *si = *si + FieldWidth;
1994   PlayField16[*si] = fiMurphy;
1995   subEatRedDisk(*si); // inc+show Murphy's red disks
1996   return subAnimateMurphy;
1997
1998   // ==========================================================================
1999   // Move Red Disk right
2000   // ==========================================================================
2001
2002 loc_g_7351:
2003   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2004     PlayField16[*si - 1] = 0;
2005
2006   PlayField16[*si] = fiMurphy;
2007   subEatRedDisk(*si); // inc+show Murphy's red disks
2008   return subAnimateMurphy;
2009
2010   // ==========================================================================
2011   // Eat Red Disk up
2012   // ==========================================================================
2013
2014 loc_g_736C:
2015   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2016     PlayField16[*si - FieldWidth] = 0;
2017
2018   subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2019   return subAnimateMurphy;
2020
2021   // ==========================================================================
2022   // Eat Red Disk left
2023   // ==========================================================================
2024
2025 loc_g_7381:
2026   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2027     PlayField16[*si - 1] = 0;
2028
2029   subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2030   return subAnimateMurphy;
2031
2032   // ==========================================================================
2033   // Eat Red Disk down
2034   // ==========================================================================
2035
2036 loc_g_7396:
2037   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2038     PlayField16[*si + FieldWidth] = 0;
2039
2040   subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2041   return subAnimateMurphy;
2042
2043   // ==========================================================================
2044   // Eat Red Disk right
2045   // ==========================================================================
2046
2047 loc_g_73AB:
2048   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2049     PlayField16[*si + 1] = 0;
2050
2051   subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2052   return subAnimateMurphy;
2053
2054   // ==========================================================================
2055   //                       yellow disk, pushing up
2056   // ==========================================================================
2057
2058 loc_g_73C0:
2059   if (LowByte(PlayField16[*si]) != fiExplosion)
2060     PlayField16[*si] = 0;
2061
2062   *si = *si - FieldWidth;
2063   PlayField16[*si] = fiMurphy;
2064   PlayField16[*si - FieldWidth] = fiYellowDisk;
2065   return subAnimateMurphy;
2066
2067   // ==========================================================================
2068   //                       yellow disk, pushing left
2069   // ==========================================================================
2070
2071 loc_g_73DD:
2072   if (LowByte(PlayField16[*si]) != fiExplosion)
2073     PlayField16[*si] = 0;
2074
2075   *si = *si - 1;
2076   PlayField16[*si] = fiMurphy;
2077   PlayField16[*si - 1] = fiYellowDisk;
2078   return subAnimateMurphy;
2079
2080   // ==========================================================================
2081   //                       yellow disk, pushing down
2082   // ==========================================================================
2083
2084 loc_g_73FA:
2085   if (LowByte(PlayField16[*si]) != fiExplosion)
2086     PlayField16[*si] = 0;
2087
2088   *si = *si + FieldWidth;
2089   PlayField16[*si] = fiMurphy;
2090   PlayField16[*si + FieldWidth] = fiYellowDisk;
2091   return subAnimateMurphy;
2092
2093   // ==========================================================================
2094   //                       yellow disk pushing right
2095   // ==========================================================================
2096
2097 loc_g_7417:
2098   if (LowByte(PlayField16[*si]) != fiExplosion)
2099     PlayField16[*si] = 0;
2100
2101   *si = *si + 1;
2102   PlayField16[*si] = fiMurphy;
2103   PlayField16[*si + 1] = fiYellowDisk;
2104   return subAnimateMurphy;
2105
2106   // ==========================================================================
2107   //                       orange disk, pushing left
2108   // ==========================================================================
2109
2110 loc_g_7434:
2111   if (LowByte(PlayField16[*si]) != fiExplosion)
2112     PlayField16[*si] = 0;
2113
2114   *si = *si - 1;
2115   PlayField16[*si] = fiMurphy;
2116   PlayField16[*si - 1] = fiOrangeDisk;
2117   return subAnimateMurphy;
2118
2119   // ==========================================================================
2120   //                       orange disk, pushing right
2121   // ==========================================================================
2122
2123 loc_g_7451:
2124   if (LowByte(PlayField16[*si]) != fiExplosion)
2125     PlayField16[*si] = 0;
2126
2127   *si = *si + 1;
2128   PlayField16[*si] = fiMurphy;
2129   PlayField16[*si + 1] = fiOrangeDisk;
2130   if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2131   {
2132     MovHighByte(&PlayField16[*si + 1], 0x20);
2133     MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2134   }
2135
2136   return subAnimateMurphy;
2137
2138   // ==========================================================================
2139   //                     Release a red disk
2140   // ==========================================================================
2141
2142 loc_g_747F:
2143   PlayField16[*si] = fiMurphy;
2144   RedDiskReleasePhase = 2;
2145   RedDiskCount = RedDiskCount - 1;
2146   subDisplayRedDiskCount();
2147   subSoundFXPush();                 // Sound effects
2148
2149   return subAnimateMurphy;
2150 } // subAnimateMurphy
2151
2152 // ==========================================================================
2153 //                              SUBROUTINE
2154 // ==========================================================================
2155 int subExplodeSnikSnaksBelow(int si)
2156 {
2157   int subExplodeSnikSnaksBelow;
2158
2159   int ax;
2160
2161   ax = LowByte(PlayField16[si + FieldWidth]);
2162   if (ax == 0x11 || ax == 0xBB)
2163     ExplodeFieldSP(si + FieldWidth);
2164
2165   return subExplodeSnikSnaksBelow;
2166 } // subExplodeSnikSnaksBelow
2167
2168 // ==========================================================================
2169 //                              SUBROUTINE
2170 // Does pushing against an object kill Murphy?
2171 // ==========================================================================
2172 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2173 {
2174   static boolean subMoveKillsMurphy;
2175
2176   int al, ah;
2177
2178   al = LowByte(ax);
2179   ah = HighByte(ax);
2180   if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2181     goto loc_g_752E;
2182
2183   if (al == fiZonk)
2184     goto loc_g_74E7;
2185
2186   if (al == fiExplosion)
2187     goto loc_g_7530;
2188
2189   if (fiOrangeDisk <= al && al <= fiPortUp)
2190     goto loc_g_752E;
2191
2192   ExplodeFieldSP(si);                 // Explode
2193   subMoveKillsMurphy = True;
2194   return subMoveKillsMurphy;
2195
2196 loc_g_74E7: // zonk
2197   if (bl == keyLeft)
2198     goto loc_g_74F6;
2199
2200   if (bl == keyRight)
2201     goto loc_g_7512;
2202
2203   ExplodeFieldSP(si);                 // Explode
2204   subMoveKillsMurphy = True;
2205   return subMoveKillsMurphy;
2206
2207 loc_g_74F6: // zonk left
2208   ah = ah & 0xF0;
2209   if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2210     ExplodeFieldSP(si);
2211
2212   subMoveKillsMurphy = True;                           // Set carry flag
2213   return subMoveKillsMurphy;
2214
2215 loc_g_7512: // zonk right
2216   ah = ah & 0xF0;
2217   if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2218     ExplodeFieldSP(si);
2219
2220 loc_g_752E: // Marked fields and Ports
2221   subMoveKillsMurphy = True;                           // Set carry flag
2222   return subMoveKillsMurphy;
2223
2224 loc_g_7530: // explosion
2225   if ((ah & 0x80) != 0)
2226     goto loc_g_753A;
2227
2228   if (ah >= 4)
2229     goto loc_g_753F;
2230
2231 loc_g_753A:
2232   ExplodeFieldSP(si);                 // Explode
2233   subMoveKillsMurphy = True;                           // Set carry flag
2234   return subMoveKillsMurphy;
2235
2236 loc_g_753F:
2237   PlayField16[si] = 0;
2238   subMoveKillsMurphy = False;
2239
2240   return subMoveKillsMurphy;
2241 } // subMoveKillsMurphy
2242
2243 // ==========================================================================
2244 //                              SUBROUTINE
2245 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2246 // change conditions to port specs
2247 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2248 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2249 // ==========================================================================
2250 int subSpPortTest(int si)
2251 {
2252   int subSpPortTest;
2253
2254   int i, cx, bx;
2255
2256   cx = LInfo.SpecialPortCount; // number of special ports
2257   for (i = 1; i <= cx; i++)
2258   {
2259     {
2260       bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2261       MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2262       if (bx / 2 == si)
2263       {
2264         GravityFlag = LInfo.SpecialPort[i].Gravity;
2265         FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2266         SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2267         //        RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2268         i = cx + 1;
2269       }
2270
2271     }
2272   }
2273
2274   return subSpPortTest;
2275 } // subSpPortTest
2276
2277 void subCopyFieldToScreen(int si, int fi)
2278 {
2279   int X, Y;
2280
2281   // +++++++++++++++++++++++++++++++++++++++++
2282   X = GetStretchX(si);
2283   Y = GetStretchY(si);
2284   StretchedSprites.BltEx(X, Y, fi);
2285   // +++++++++++++++++++++++++++++++++++++++++
2286 }
2287
2288 static void subEatRedDisk(int si)
2289 {
2290   if (AllowRedDiskCheat == 0)
2291   {
2292     if (RedDiskReleasePhase != 0)
2293     {
2294       if (RedDiskReleaseMurphyPos == si)
2295         return;
2296     }
2297   }
2298
2299   RedDiskCount = (RedDiskCount + 1) % 256;
2300   subDisplayRedDiskCount();
2301 }
2302
2303 int subAdjustZonksInfotronsAboveMurphy(int si)
2304 {
2305   int subAdjustZonksInfotronsAboveMurphy;
2306
2307   int ax;
2308
2309   if (LowByte(PlayField16[si]) != fiExplosion)
2310     PlayField16[si] = 0;
2311
2312   ax = PlayField16[si - FieldWidth];
2313   if (ax == 0 || ax == 0x9999)
2314     goto loc_g_15A8;
2315
2316   if (ax == fiZonk || ax == fiInfotron)
2317   {
2318     MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2319   }
2320
2321   return subAdjustZonksInfotronsAboveMurphy;
2322
2323 loc_g_15A8: // empty above
2324   ax = PlayField16[si - FieldWidth - 1];
2325   if (ax == fiZonk || ax == fiInfotron)
2326     goto loc_g_15C5;
2327
2328 loc_g_15B6:
2329   ax = PlayField16[si - FieldWidth + 1];
2330   if (ax == fiZonk || ax == fiInfotron)
2331     goto loc_g_15E8;
2332
2333   return subAdjustZonksInfotronsAboveMurphy;
2334
2335 loc_g_15C5: // zonk/infotron above left
2336   ax = PlayField16[si - 1];
2337   if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2338     goto loc_g_15B6;
2339
2340   MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2341   PlayField16[si - FieldWidth] = 0x8888;
2342   return subAdjustZonksInfotronsAboveMurphy;
2343
2344 loc_g_15E8: // zonk/infotron above right
2345   ax = PlayField16[si + 1];
2346   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2347   {
2348     MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2349     PlayField16[si - FieldWidth] = 0x8888;
2350   }
2351
2352   return subAdjustZonksInfotronsAboveMurphy;
2353 } // subAdjustZonksInfotronsAboveMurphy