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