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