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