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