rnd-20091012-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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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   if (!game_sp_info.LevelSolved)
936     printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n",LevelNumber);
937 #endif
938
939   game_sp_info.LevelSolved = TRUE;
940
941   subSoundFXExit();
942   data_h_DemoDone = 1; // EP set level success bytes
943   LevelStatus = 1; // set Level Status DONE
944   EP_GameDemoVar0DAA = 0; // force demo for lead-out
945   if (SavedGameFlag == 0) // saved game running?
946   {
947     if (UpdateTimeFlag != 0)    // update time?
948     {
949       UpdatedFlag = 1; // prevent double update
950       subUpdatePlayingTime();    // update playing time
951     }
952   }
953
954 #if 0
955   subUpdateHallOfFame(); // update time + Hall-Of-Fame
956 #endif
957
958   LeadOutCounter = 0x40;          // quit: start lead-out
959   dx = aniMurphyExit;
960   MovHighByte(&PlayField16[*si], 0xD);
961   goto loc_StopNoSplit;
962
963   // ==========================================================================
964   // ZONK moving right to left
965   // ==========================================================================
966
967 loc_g_679B:
968   ax = PlayField16[*si - 2];
969   if (ax != 0)
970     return subAnimateMurphy;
971
972   MovHighByte(&PlayField16[*si - 2], 1);
973   subCopyFieldToScreen(*si, aniPushLeft); // draw pushing murphy
974   dx = aniZonkRollLeft;
975   dxPos = *si - 1;
976   dx2 = aniPushLeft;
977   dx2Step = 1;
978   MovHighByte(&PlayField16[*si], 0xE);
979   goto loc_MoveNoSplit;
980
981   // ==========================================================================
982   // ZONK moving left to right
983   // ==========================================================================
984
985 loc_g_67D4:
986   ax = PlayField16[*si + 2];
987   if (ax != 0)
988     return subAnimateMurphy;
989
990   ax = PlayField16[*si + FieldWidth + 1];
991   if (ax == 0) // zonk falls
992     return subAnimateMurphy;
993
994   MovHighByte(&PlayField16[*si + 2], 1);
995   subCopyFieldToScreen(*si, aniPushRight); // draw pushing murphy
996   dx = aniZonkRollRight;
997   dxPos = *si + 1;
998   dx2 = aniPushRight;
999   dx2Step = -1;
1000   MovHighByte(&PlayField16[*si], 0xF);
1001   goto loc_MoveNoSplit;
1002
1003   // ==========================================================================
1004   // TERMINAL moving/touching down to up
1005   // ==========================================================================
1006
1007 loc_g_6817:
1008   subCopyFieldToScreen(*si, aniMurphyTouchUp);
1009   if (YellowDisksExploded != 0)
1010   {
1011     YawnSleepCounter = 10; // stay hypnotized
1012     return subAnimateMurphy;
1013   } // loc_g_6838:
1014
1015   subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1016   TerminalState[*si - FieldWidth] = 8;
1017   goto loc_g_68F0;
1018
1019   // ==========================================================================
1020   // TERMINAL moving/touching right to left
1021   // ==========================================================================
1022
1023 loc_g_684E:
1024   subCopyFieldToScreen(*si, aniMurphyTouchLeft);
1025   if (YellowDisksExploded != 0)
1026   {
1027     YawnSleepCounter = 10; // stay hypnotized
1028     return subAnimateMurphy;
1029   } // loc_g_6838:
1030
1031   subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1032   TerminalState[*si - 1] = 8;
1033   goto loc_g_68F0;
1034
1035   // ==========================================================================
1036   // TERMINAL moving/touching up to down
1037   // ==========================================================================
1038
1039 loc_g_6884:
1040   subCopyFieldToScreen(*si, aniMurphyTouchDown);
1041   if (YellowDisksExploded != 0)
1042   {
1043     YawnSleepCounter = 10; // stay hypnotized
1044     return subAnimateMurphy;
1045   } // loc_g_6838:
1046
1047   subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1048   TerminalState[*si + FieldWidth] = 8;
1049   goto loc_g_68F0;
1050
1051   // ==========================================================================
1052   // TERMINAL moving/touching left to right
1053   // ==========================================================================
1054
1055 loc_g_68BA:
1056   subCopyFieldToScreen(*si, aniMurphyTouchRight);
1057   if (YellowDisksExploded != 0)
1058   {
1059     YawnSleepCounter = 10; // stay hypnotized
1060     return subAnimateMurphy;
1061   } // loc_g_6838:
1062
1063   subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1064   TerminalState[*si + 1] = 8;
1065   // ==========================================================================
1066   // common TERMINAL stuff moving/touching from all directions
1067   // ==========================================================================
1068
1069 loc_g_68F0:
1070   TerminalMaxCycles = 7;
1071   YellowDisksExploded = 1;
1072   for (i = 0; i <= LevelMax; i++)
1073   {
1074     if (PlayField16[i] == fiYellowDisk)
1075       ExplodeFieldSP (i);
1076   }
1077
1078   return subAnimateMurphy;
1079
1080   // ==========================================================================
1081   // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1082   // ==========================================================================
1083
1084 loc_g_6916:
1085   if (PlayField16[*si - 2 * FieldWidth] != 0)
1086     return subAnimateMurphy;
1087
1088   dx = aniSplitUpDown;
1089   dx2Step = -FieldWidth;
1090   PlayField16[*si] = 0x1803;
1091   PlayField16[*si - 2 * FieldWidth] = 0x300;
1092   goto loc_StopSplit;
1093
1094   // ==========================================================================
1095   // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1096   // ==========================================================================
1097
1098 loc_g_693A:
1099   if (PlayField16[*si - 2] != 0)
1100     return subAnimateMurphy;
1101
1102   dx = aniMurphyEatLeft;
1103   dx2Step = -1;
1104   PlayField16[*si] = 0x1903;
1105   PlayField16[*si - 2] = 0x300;
1106   goto loc_StopSplit;
1107
1108   // ==========================================================================
1109   // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1110   // ==========================================================================
1111
1112 loc_g_695E:
1113   if (PlayField16[*si + 2 * FieldWidth] != 0)
1114     return subAnimateMurphy;
1115
1116   dx = aniSplitUpDown;
1117   dx2Step = FieldWidth;
1118   PlayField16[*si] = 0x1A03;
1119   PlayField16[*si + 2 * FieldWidth] = 0x300;
1120   goto loc_StopSplit;
1121
1122   // ==========================================================================
1123   // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1124   // ==========================================================================
1125
1126 loc_g_6982:
1127   if (PlayField16[*si + 2] != 0)
1128     return subAnimateMurphy;
1129
1130   dx = aniMurphyEatRight;
1131   dx2Step = 1;
1132   PlayField16[*si] = 0x1B03;
1133   PlayField16[*si + 2] = 0x300;
1134
1135 loc_StopSplit:
1136   MovingPictureSequencePhase = 0; // stop picture move sequence
1137   SplitMoveFlag = 1; // port: split movement
1138   goto loc_Split;
1139
1140   // ==========================================================================
1141   // RED DISK moving down to up
1142   // ==========================================================================
1143
1144 loc_g_69A6:
1145   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1146   PlayField16[*si] = 0x1C03;
1147   PlayField16[*si - FieldWidth] = 0x300;
1148   goto loc_StopNoSplit;
1149
1150   // ==========================================================================
1151   // RED DISK moving right to left
1152   // ==========================================================================
1153
1154 loc_g_69CE:
1155   dx = aniMurphyEatLeft;
1156   PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1157   PlayField16[*si - 1] = 0x1D03;
1158   *si = *si - 1;
1159   goto loc_StopNoSplit;
1160
1161   // ==========================================================================
1162   // RED DISK moving up to down
1163   // ==========================================================================
1164
1165 loc_g_69F7:
1166   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1167   PlayField16[*si] = 0x1E03;
1168   PlayField16[*si + FieldWidth] = 0x300;
1169   goto loc_StopNoSplit;
1170
1171   // ==========================================================================
1172   // RED DISK moving left to right
1173   // ==========================================================================
1174
1175 loc_g_6A1F:
1176   //  dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1177   dx = aniMurphyEatRight;
1178   // --------------------------------------------------------------------------
1179   // BugFix
1180   // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1181   // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1182   // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1183   // We may not fix the table, because then the timing of the game changes
1184   // and several existing demo's do not run properly anymore.
1185   // We only correct Murphies x-location here, when the sequence starts.
1186   // Remember that this is not the real bug-fix, but we must live with
1187   // this existing bug and correct for the consequences of it.
1188
1189 #if 1
1190   if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1191     MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1192 #else
1193   if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1194     MurphyScreenXPos = MurphyScreenXPos - 2;
1195 #endif
1196
1197   SeqPos = -1;
1198   // FS: for me this means to blit the first animation frame twice
1199   // end of BugFix
1200   // --------------------------------------------------------------------------
1201   PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1202   PlayField16[*si + 1] = 0x1F03;
1203   *si = *si + 1;
1204   goto loc_StopNoSplit;
1205
1206   // ==========================================================================
1207   // RED DISK touching down to up
1208   // ==========================================================================
1209
1210 loc_g_6A48:
1211   dx = aniTouchRedDisk;
1212   MovHighByte(&PlayField16[*si], 0x20);
1213   MovHighByte(&PlayField16[*si - FieldWidth], 3);
1214   goto loc_StopNoSplit;
1215
1216   // ==========================================================================
1217   // RED DISK touching right to left
1218   // ==========================================================================
1219
1220 loc_g_6A64:
1221   dx = aniTouchRedDisk;
1222   MovHighByte(&PlayField16[*si], 0x21);
1223   MovHighByte(&PlayField16[*si - 1], 3);
1224   goto loc_StopNoSplit;
1225
1226   // ==========================================================================
1227   // RED DISK touching up to down
1228   // ==========================================================================
1229
1230 loc_g_6A80:
1231   dx = aniTouchRedDisk;
1232   MovHighByte(&PlayField16[*si], 0x22);
1233   MovHighByte(&PlayField16[*si + FieldWidth], 3);
1234   goto loc_StopNoSplit;
1235
1236   // ==========================================================================
1237   // RED DISK touching left to right
1238   // ==========================================================================
1239
1240 loc_g_6A9C:
1241   dx = aniTouchRedDisk;
1242   MovHighByte(&PlayField16[*si], 0x23);
1243   MovHighByte(&PlayField16[*si + 1], 3);
1244
1245 loc_StopNoSplit:
1246   MovingPictureSequencePhase = 0; // stop picture move sequence
1247   goto loc_NoSplit;
1248
1249   // ==========================================================================
1250   // YELLOW DISK moving down to up
1251   // ==========================================================================
1252
1253 loc_g_6AB8:
1254   if (PlayField16[*si - 2 * FieldWidth] != 0)
1255     return subAnimateMurphy;
1256
1257   PlayField16[*si - 2 * FieldWidth] = 0x1200;
1258   subCopyFieldToScreen(*si, aniPushRight);
1259   dx = aniYellowDisk;
1260   dxPos = *si - FieldWidth;
1261   dx2 = aniPushUpDown;
1262   dx2Step = FieldWidth;
1263   PlayField16[*si] = 0x2403;
1264   goto loc_MoveNoSplit;
1265
1266   // ==========================================================================
1267   // YELLOW DISK moving right to left
1268   // ==========================================================================
1269
1270 loc_g_6AF1:
1271   if (PlayField16[*si - 2] != 0)
1272     return subAnimateMurphy;
1273
1274   PlayField16[*si - 2] = 0x1200;
1275   subCopyFieldToScreen(*si, aniPushLeft);
1276   dx = aniYellowDisk;
1277   dxPos = *si - 1;
1278   dx2 = aniPushLeft;
1279   dx2Step = 1;
1280   PlayField16[*si] = 0x2503;
1281   goto loc_MoveNoSplit;
1282
1283   // ==========================================================================
1284   // YELLOW DISK moving up to down
1285   // ==========================================================================
1286
1287 loc_g_6B2A:
1288   if (PlayField16[*si + 2 * FieldWidth] != 0)
1289     return subAnimateMurphy;
1290
1291   PlayField16[*si + 2 * FieldWidth] = 0x1200;
1292   subCopyFieldToScreen(*si, aniPushRight);
1293   dx = aniYellowDisk;
1294   dxPos = *si + FieldWidth;
1295   dx2 = aniPushUpDown;
1296   dx2Step = -FieldWidth;
1297   PlayField16[*si] = 0x2703;
1298   goto loc_MoveNoSplit;
1299
1300   // ==========================================================================
1301   // YELLOW DISK moving left to right
1302   // ==========================================================================
1303
1304 loc_g_6B63:
1305   if (PlayField16[*si + 2] != 0)
1306     return subAnimateMurphy;
1307
1308   PlayField16[*si + 2] = 0x1200;
1309   subCopyFieldToScreen(*si, aniPushRight);
1310   dx = aniYellowDisk;
1311   dxPos = *si + 1;
1312   dx2 = aniPushRight;
1313   dx2Step = -1;
1314   PlayField16[*si] = 0x2603;
1315   goto loc_MoveNoSplit;
1316
1317   // ==========================================================================
1318   // ORANGE DISK moving right to left
1319   // ==========================================================================
1320
1321 loc_g_6B9B:
1322   if (PlayField16[*si - 2] != 0)
1323     return subAnimateMurphy;
1324
1325   PlayField16[*si - 2] = 0x800;
1326   subCopyFieldToScreen(*si, aniPushLeft);
1327   dx = aniOrangeDisk;
1328   dxPos = *si - 1;
1329   dx2 = aniPushLeft;
1330   dx2Step = 1;
1331   PlayField16[*si] = 0x2803;
1332   goto loc_MoveNoSplit;
1333
1334   // ==========================================================================
1335   // ORANGE DISK moving left to right
1336   // ==========================================================================
1337
1338 loc_g_6BD3:
1339   if (PlayField16[*si + 2] != 0)
1340     return subAnimateMurphy;
1341
1342   if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1343     return subAnimateMurphy;
1344
1345   PlayField16[*si + 2] = 0x100;
1346   subCopyFieldToScreen(*si, aniPushRight);
1347   dx = aniOrangeDisk;
1348   dxPos = *si + 1;
1349   dx2 = aniPushRight;
1350   dx2Step = -1;
1351   PlayField16[*si] = 0x2903;
1352   // ==========================================================================
1353   // Copy screen animation action table to action work space
1354   // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1355   // ==========================================================================
1356
1357 loc_MoveNoSplit:
1358   MovingPictureSequencePhase = 8; // init picture move sequence
1359
1360 loc_NoSplit:
1361   SplitMoveFlag = 0; // no port: no split movement
1362
1363 loc_Split:
1364   //  copy/store global move sequence info????????????????????????????????????
1365   //  ... dont think so ...(FS)
1366   // ==========================================================================
1367   // Proceed with all movements
1368   // ==========================================================================
1369
1370 locProceedMovingMurphy: // proceed moving murphy
1371   YawnSleepCounter = 0; // Wake up sleeping Murphy
1372   ax = MovingPictureSequencePhase;            // sequence busy?
1373   if (ax == 0)             // no -- start sequence!
1374     goto loc_g_6C8F;
1375
1376   ax = ax - 1;   // next picture of sequence
1377   MovingPictureSequencePhase = ax;            // store for later
1378   if (ax == 0) // Sound effects
1379     subSoundFXPush();
1380
1381   bl = HighByte(PlayField16[*si]);
1382   if (bl == 0xE)        // Push Zonk to left
1383     goto loc_g_6F7E;
1384
1385   if (bl == 0xF)        // Push Zonk to right
1386     goto loc_g_6FBC;
1387
1388   if (bl == 0x28)       // Push orange disk to left
1389     goto loc_g_6FFA;
1390
1391   if (bl == 0x29)       // Push orange disk to right
1392     goto loc_g_7038;
1393
1394   if (bl == 0x24)       // Push yellow disk up
1395     goto loc_g_7076;
1396
1397   if (bl == 0x25)       // Push yellow disk to left
1398     goto loc_g_70B4;
1399
1400   if (bl == 0x27)       // Push yellow disk down
1401     goto loc_g_70F2;
1402
1403   if (bl == 0x26)       // Push yellow disk to right
1404     goto loc_g_7130;
1405
1406   if (bl == 0x2A)       // Red disk release timer
1407     goto loc_g_716E;
1408
1409   return subAnimateMurphy;
1410
1411   // ==========================================================================
1412   // Paint frame of MOVING.DAT sequence
1413   // ==========================================================================
1414
1415 loc_g_6C8F:
1416   if (SplitMoveFlag == 0)
1417   {
1418     // ++++++++++++++++++++++++++
1419     // Begin of normal movement
1420 #if 1
1421     MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1422     MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1423 #else
1424     MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1425     MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1426 #endif
1427
1428
1429 #if 0
1430   printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1431          TimerVar,
1432          DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1433          (DemoKeyCode == keyNone        ? "(none)"              :
1434           DemoKeyCode == keyLeft        ? "left"                :
1435           DemoKeyCode == keyRight       ? "right"               :
1436           DemoKeyCode == keyUp          ? "up"                  :
1437           DemoKeyCode == keyDown        ? "down"                :
1438           DemoKeyCode == keySpace       ? "space"               :
1439           DemoKeyCode == keySpaceLeft   ? "space + left"        :
1440           DemoKeyCode == keySpaceRight  ? "space + right"       :
1441           DemoKeyCode == keySpaceUp     ? "space + up"          :
1442           DemoKeyCode == keySpaceDown   ? "space + down"        : "(unknown)"),
1443          DemoKeyCode,
1444          MurphyScreenXPos, MurphyScreenYPos,
1445          MurphyPosIndex % 60, MurphyPosIndex / 60,
1446          ClearPos);
1447 #endif
1448
1449 #if 0
1450   Delay(500);
1451 #endif
1452
1453 #if 1
1454     if (!(ClearPos < 0)) // clear field that murphy is leaving
1455       subCopyFieldToScreen(ClearPos, 0);
1456 #else
1457     if (! ClearPos < 0) // clear field that murphy is leaving
1458       subCopyFieldToScreen(ClearPos, 0);
1459 #endif
1460
1461 #if 0
1462     printf("::: ---------------> %d, %d [%d, %d]\n",
1463            MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1464 #endif
1465
1466     if (dx2 == fiInfotron) // special case of infotron moving left or right
1467     {
1468       tDeltaX = 0;
1469       tDeltaY = 0;
1470     }
1471     else
1472     {
1473       tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1474       tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1475     }
1476
1477     X = GetStretchX(dxPos) + tDeltaX;
1478     Y = GetStretchY(dxPos) + tDeltaY;
1479     Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1480     StretchedSprites.BltEx(X, Y, dx[Tmp]);
1481
1482 #if 1
1483     if (!(dx2 < 0))
1484 #else
1485     if (! dx2 < 0)
1486 #endif
1487     {
1488       tPos = dxPos + dx2Step;
1489       X = GetStretchX(tPos);
1490       Y = GetStretchY(tPos);
1491       if (dx2 == fiInfotron) // special case of infotron moving left or right
1492       {
1493         StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1494       }
1495       else // pushing something
1496       {
1497         StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1498       }
1499     }
1500
1501     // End of normal movement
1502     // ------------------------
1503   }
1504   else
1505   {
1506     // ++++++++++++++++++++++++++++++++
1507     // Begin of split movement (port)
1508 #if 1
1509     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1510     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1511 #else
1512     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1513     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1514 #endif
1515     subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1516     tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1517     tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1518     X = GetStretchX(dxPos) + tDeltaX;
1519     Y = GetStretchY(dxPos) + tDeltaY;
1520     StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1521     tPos = dxPos + dx2Step;
1522     X = GetStretchX(tPos);
1523     Y = GetStretchY(tPos);
1524     StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1525     StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1526     // End of split movement (port)
1527     // ------------------------------
1528   } // loc_g_6D1E:'loc_g_6D28:
1529
1530   SeqPos = SeqPos + 1;
1531   if (dx[SeqPos] > -1)
1532     return subAnimateMurphy;
1533
1534   // Follow-up after movement completed     'loc_g_6D35:
1535   MurphyXPos = MurphyXPos + MurphyDX;
1536   MurphyYPos = MurphyYPos + MurphyDY;
1537   bl = HighByte(PlayField16[*si]);  // animation phase
1538   MovHighByte(&PlayField16[*si], 0);
1539
1540   if (bl == 0x1)    // space, moving up
1541     goto loc_g_6EC8;
1542
1543   if (bl == 0x2)    // space, moving left
1544     goto loc_g_6EE6;
1545
1546   if (bl == 0x3)    // space, moving down
1547     goto loc_g_6F04;
1548
1549   if (bl == 0x4)    // space, moving right
1550     goto loc_g_71C4;
1551
1552   if (bl == 0x5)    // base , moving up
1553     goto loc_g_6EC8;
1554
1555   if (bl == 0x6)    // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1556     goto loc_g_6EE6;
1557
1558   if (bl == 0x7)    // base , moving down
1559     goto loc_g_6F04;
1560
1561   if (bl == 0x8)    // base , moving right
1562     goto loc_g_71C4;
1563
1564   if (bl == 0x9)    // infotron, moving up
1565     goto loc_g_6EBA;
1566
1567   if (bl == 0xA)      // infotron, moving left
1568     goto loc_g_6ED8;
1569
1570   if (bl == 0xB)    // infotron, moving down
1571     goto loc_g_6EF6;
1572
1573   if (bl == 0xC)      // infotron, moving right
1574     goto loc_g_71B6;
1575
1576   if (bl == 0xD)      // exit
1577     goto loc_g_6F77;
1578
1579   if (bl == 0xE)      // zonk, pushing left
1580     goto loc_g_6F18;
1581
1582   if (bl == 0xF)      // zonk, pushing right
1583     goto loc_g_6F3B;
1584
1585   if (bl == 0x10)   // base , touching up
1586     goto loc_g_71E2;
1587
1588   if (bl == 0x11)   // base , touching left
1589     goto loc_g_71FE;
1590
1591   if (bl == 0x12)   // base , touching down
1592     goto loc_g_721A;
1593
1594   if (bl == 0x13)   // base , touching right
1595     goto loc_g_7236;
1596
1597   if (bl == 0x14)   // infotron touching up
1598     goto loc_g_71D4;
1599
1600   if (bl == 0x15)   // infotron touching left
1601     goto loc_g_71F0;
1602
1603   if (bl == 0x16)   // infotron touching down
1604     goto loc_g_720C;
1605
1606   if (bl == 0x17)   // infotron touching right
1607     goto loc_g_7228;
1608
1609   if (bl == 0x18)     // port up
1610     goto loc_g_7244;
1611
1612   if (bl == 0x19)     // port left
1613     goto loc_g_7272;
1614
1615   if (bl == 0x1A)     // port down
1616     goto loc_g_729F;
1617
1618   if (bl == 0x1B)     // port right
1619     goto loc_g_72CD;
1620
1621   if (bl == 0x1C)   // red disk, moving up
1622     goto loc_g_72FA;
1623
1624   if (bl == 0x1D)   // red disk, moving left
1625     goto loc_g_7318;
1626
1627   if (bl == 0x1E)   // red disk, moving down
1628     goto loc_g_7333;
1629
1630   if (bl == 0x1F)   // red disk, moving right -> 9-Step-Bug!
1631     goto loc_g_7351;
1632
1633   if (bl == 0x20)   // red disk, touching up
1634     goto loc_g_736C;
1635
1636   if (bl == 0x21)   // red disk, touching left
1637     goto loc_g_7381;
1638
1639   if (bl == 0x22)   // red disk, touching down
1640     goto loc_g_7396;
1641
1642   if (bl == 0x23)   // red disk, touching right
1643     goto loc_g_73AB;
1644
1645   if (bl == 0x24)     // yellow disk, pushing up
1646     goto loc_g_73C0;
1647
1648   if (bl == 0x25)     // yellow disk, pushing left
1649     goto loc_g_73DD;
1650
1651   if (bl == 0x26)     // yellow disk, pushing right -> order of "down" exchanged with "right"!
1652     goto loc_g_7417;
1653
1654   if (bl == 0x27)     // yellow disk, pushing down  -> order of "down" exchanged with "right"!
1655     goto loc_g_73FA;
1656
1657   if (bl == 0x28)     // orange disk, pushing left
1658     goto loc_g_7434;
1659
1660   if (bl == 0x29)     // orange disk, pushing right
1661     goto loc_g_7451;
1662
1663   if (bl == 0x2A)   // red disk, release
1664     goto loc_g_747F;
1665
1666   ExitToMenuFlag = 1;
1667   return subAnimateMurphy;
1668
1669   // ==========================================================================
1670   //                       infotron, moving up
1671   // ==========================================================================
1672
1673 loc_g_6EBA:
1674   if (0 < LowByte(InfotronsNeeded))
1675     InfotronsNeeded = InfotronsNeeded - 1;
1676
1677   subDisplayInfotronsNeeded();
1678 loc_g_6EC8: // space, base
1679   PlayField16[*si] = fiMurphy;
1680   subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1681   return subAnimateMurphy;
1682
1683   // ==========================================================================
1684   //                       infotron, moving left
1685   // ==========================================================================
1686
1687 loc_g_6ED8:
1688   if (0 < LowByte(InfotronsNeeded))
1689     InfotronsNeeded = InfotronsNeeded - 1;
1690
1691   subDisplayInfotronsNeeded();
1692 loc_g_6EE6: // space, base
1693   PlayField16[*si] = fiMurphy;
1694   subAdjustZonksInfotronsAboveMurphy(*si + 1);
1695   return subAnimateMurphy;
1696
1697   // ==========================================================================
1698   //                       infotron, moving down
1699   // ==========================================================================
1700
1701 loc_g_6EF6:
1702   if (0 < LowByte(InfotronsNeeded))
1703     InfotronsNeeded = InfotronsNeeded - 1;
1704
1705   subDisplayInfotronsNeeded();
1706 loc_g_6F04: // space, base
1707   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1708     PlayField16[*si - FieldWidth] = 0;
1709
1710   PlayField16[*si] = fiMurphy;
1711   return subAnimateMurphy;
1712
1713   // ==========================================================================
1714   //                       infotron, moving right
1715   // ==========================================================================
1716
1717 loc_g_71B6:
1718   if (0 < LowByte(InfotronsNeeded))
1719     InfotronsNeeded = InfotronsNeeded - 1;
1720
1721   subDisplayInfotronsNeeded();
1722 loc_g_71C4: // space, base
1723   subAdjustZonksInfotronsAboveMurphy(*si - 1);
1724   PlayField16[*si] = fiMurphy;
1725   return subAnimateMurphy;
1726
1727   // ==========================================================================
1728   //                       infotron, touching up
1729   // ==========================================================================
1730
1731 loc_g_71D4:
1732   if (0 < LowByte(InfotronsNeeded))
1733     InfotronsNeeded = InfotronsNeeded - 1;
1734
1735   subDisplayInfotronsNeeded();
1736 loc_g_71E2: // base
1737   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1738     PlayField16[*si - FieldWidth] = 0;
1739
1740   return subAnimateMurphy;
1741
1742   // ==========================================================================
1743   //                       infotron, touching left
1744   // ==========================================================================
1745
1746 loc_g_71F0:
1747   if (0 < LowByte(InfotronsNeeded))
1748     InfotronsNeeded = InfotronsNeeded - 1;
1749
1750   subDisplayInfotronsNeeded();
1751 loc_g_71FE: // base
1752   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1753     PlayField16[*si - 1] = 0;
1754
1755   return subAnimateMurphy;
1756
1757   // ==========================================================================
1758   //                       infotron, touching down
1759   // ==========================================================================
1760
1761 loc_g_720C:
1762   if (0 < LowByte(InfotronsNeeded))
1763     InfotronsNeeded = InfotronsNeeded - 1;
1764
1765   subDisplayInfotronsNeeded();
1766 loc_g_721A: // base
1767   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1768     PlayField16[*si + FieldWidth] = 0;
1769
1770   return subAnimateMurphy;
1771
1772   // ==========================================================================
1773   //                       infotron, touching right
1774   // ==========================================================================
1775
1776 loc_g_7228:
1777   if (0 < LowByte(InfotronsNeeded))
1778     InfotronsNeeded = InfotronsNeeded - 1;
1779
1780   subDisplayInfotronsNeeded();
1781 loc_g_7236: // base
1782   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1783     PlayField16[*si + 1] = 0;
1784
1785   return subAnimateMurphy;
1786
1787   // ==========================================================================
1788   //                       zonk, pushing left
1789   // ==========================================================================
1790
1791 loc_g_6F18:
1792   if (LowByte(PlayField16[*si]) != fiExplosion)
1793     PlayField16[*si] = 0;
1794
1795   PlayField16[*si - 1] = fiMurphy;
1796   PlayField16[*si - 2] = fiZonk;
1797   subExplodeSnikSnaksBelow(*si - 2);
1798   *si = *si - 1;
1799   return subAnimateMurphy;
1800
1801   // ==========================================================================
1802   //                       zonk, pushing right
1803   // ==========================================================================
1804
1805 loc_g_6F3B:
1806   if (LowByte(PlayField16[*si]) != fiExplosion)
1807     PlayField16[*si] = 0;
1808
1809   PlayField16[*si + 1] = fiMurphy;
1810   PlayField16[*si + 2] = fiZonk;
1811   subExplodeSnikSnaksBelow(*si + 2);
1812   *si = *si + 1;
1813   return subAnimateMurphy;
1814
1815   // ==========================================================================
1816   //                       exit
1817   // ==========================================================================
1818
1819 loc_g_6F77:
1820   ExitToMenuFlag = 1;
1821   return subAnimateMurphy;
1822
1823   // ==========================================================================
1824   //               Push Zonk from right to left
1825   // ==========================================================================
1826
1827 loc_g_6F7E:
1828   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1829     return subAnimateMurphy;
1830
1831   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1832   PlayField16[*si - 1] = fiZonk;
1833   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1834     PlayField16[*si - 2] = 0;
1835
1836   subCopyFieldToScreen(*si, fiMurphy);
1837   return subAnimateMurphy;
1838
1839   // ==========================================================================
1840   //                       Push Zonk from left to right
1841   // ==========================================================================
1842
1843 loc_g_6FBC:
1844   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1845     return subAnimateMurphy;
1846
1847   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1848   PlayField16[*si + 1] = fiZonk;
1849   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1850     PlayField16[*si + 2] = 0;
1851
1852   subCopyFieldToScreen(*si, fiMurphy);
1853   return subAnimateMurphy;
1854
1855   // ==========================================================================
1856   //               Push orange disk from right to left
1857   // ==========================================================================
1858
1859 loc_g_6FFA:
1860   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1861     return subAnimateMurphy;
1862
1863   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1864   PlayField16[*si - 1] = fiOrangeDisk;
1865   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1866     PlayField16[*si - 2] = 0;
1867
1868   subCopyFieldToScreen(*si, fiMurphy);
1869   return subAnimateMurphy;
1870
1871   // ==========================================================================
1872   //               Push orange disk from left to right
1873   // ==========================================================================
1874
1875 loc_g_7038:
1876   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1877     return subAnimateMurphy;
1878
1879   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1880   PlayField16[*si + 1] = fiOrangeDisk;
1881   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1882     PlayField16[*si + 2] = 0;
1883
1884   subCopyFieldToScreen(*si, fiMurphy);
1885   return subAnimateMurphy;
1886
1887   // ==========================================================================
1888   //               Push yellow disk from down to up
1889   // ==========================================================================
1890
1891 loc_g_7076:
1892   if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1893     return subAnimateMurphy;
1894
1895   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1896   PlayField16[*si - FieldWidth] = fiYellowDisk;
1897   if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1898     PlayField16[*si - 2 * FieldWidth] = 0;
1899
1900   subCopyFieldToScreen(*si, fiMurphy);
1901   return subAnimateMurphy;
1902
1903   // ==========================================================================
1904   //               Push yellow disk from right to left
1905   // ==========================================================================
1906
1907 loc_g_70B4:
1908   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1909     return subAnimateMurphy;
1910
1911   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1912   PlayField16[*si - 1] = fiYellowDisk;
1913   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1914     PlayField16[*si - 2] = 0;
1915
1916   subCopyFieldToScreen(*si, fiMurphy);
1917   return subAnimateMurphy;
1918
1919   // ==========================================================================
1920   //               Push yellow disk from up to down
1921   // ==========================================================================
1922
1923 loc_g_70F2:
1924   if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1925     return subAnimateMurphy;
1926
1927   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1928   PlayField16[*si + FieldWidth] = fiYellowDisk;
1929   if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1930     PlayField16[*si + 2 * FieldWidth] = 0;
1931
1932   subCopyFieldToScreen(*si, fiMurphy);
1933   return subAnimateMurphy;
1934
1935   // ==========================================================================
1936   //               Push yellow disk from left to right
1937   // ==========================================================================
1938
1939 loc_g_7130:
1940   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1941     return subAnimateMurphy;
1942
1943   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1944   PlayField16[*si + 1] = fiYellowDisk;
1945   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1946     PlayField16[*si + 2] = 0;
1947
1948   subCopyFieldToScreen(*si, fiMurphy);
1949   return subAnimateMurphy;
1950
1951   // ==========================================================================
1952   //               time red disk release (space)
1953   // ==========================================================================
1954
1955 loc_g_716E:
1956   if (DemoKeyCode != keySpace)
1957   {
1958     PlayField16[*si] = fiMurphy;
1959     subCopyFieldToScreen(*si, fiMurphy);
1960     RedDiskReleasePhase = 0;
1961   }
1962   else if (MovingPictureSequencePhase == 0x20)
1963   {
1964     subCopyFieldToScreen(*si, 43);  // anxious murphy
1965     RedDiskReleasePhase = 1;
1966   }
1967
1968   return subAnimateMurphy;
1969
1970   // ==========================================================================
1971   // Special port down to up
1972   // ==========================================================================
1973
1974 loc_g_7244:
1975   if (LowByte(PlayField16[*si]) != fiExplosion)
1976     PlayField16[*si] = 0;
1977
1978   PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1979   SplitMoveFlag = 0;
1980   *si = *si - FieldWidth;
1981   if (HighByte(PlayField16[*si]) == 1)
1982     subSpPortTest(*si);
1983
1984   *si = *si - FieldWidth;
1985   return subAnimateMurphy;
1986
1987   // ==========================================================================
1988   // Special port right to left
1989   // ==========================================================================
1990
1991 loc_g_7272:
1992   if (LowByte(PlayField16[*si]) != fiExplosion)
1993     PlayField16[*si] = 0;
1994
1995   PlayField16[*si - 2] = fiMurphy;
1996   SplitMoveFlag = 0;
1997   *si = *si - 1;
1998   if (HighByte(PlayField16[*si]) == 1)
1999     subSpPortTest(*si);
2000
2001   *si = *si - 1;
2002   return subAnimateMurphy;
2003
2004   // ==========================================================================
2005   // Special port up to down
2006   // ==========================================================================
2007
2008 loc_g_729F:
2009   if (LowByte(PlayField16[*si]) != fiExplosion)
2010     PlayField16[*si] = 0;
2011
2012   PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2013   SplitMoveFlag = 0;
2014   *si = *si + FieldWidth;
2015   if (HighByte(PlayField16[*si]) == 1)
2016     subSpPortTest(*si);
2017
2018   *si = *si + FieldWidth;
2019   return subAnimateMurphy;
2020
2021   // ==========================================================================
2022   // Special port left to right
2023   // ==========================================================================
2024
2025 loc_g_72CD:
2026   if (LowByte(PlayField16[*si]) != fiExplosion)
2027     PlayField16[*si] = 0;
2028
2029   PlayField16[*si + 2] = fiMurphy;
2030   SplitMoveFlag = 0;
2031   *si = *si + 1;
2032   if (HighByte(PlayField16[*si]) == 1)
2033     subSpPortTest(*si);
2034
2035   *si = *si + 1;
2036   return subAnimateMurphy;
2037
2038   // ==========================================================================
2039   // Move Red Disk up
2040   // ==========================================================================
2041
2042 loc_g_72FA:
2043   if (LowByte(PlayField16[*si]) != fiExplosion)
2044     PlayField16[*si] = 0;
2045
2046   *si = *si - FieldWidth;
2047   PlayField16[*si] = fiMurphy;
2048   subEatRedDisk(*si); // inc+show Murphy's red disks
2049   return subAnimateMurphy;
2050
2051   // ==========================================================================
2052   // Move Red Disk left
2053   // ==========================================================================
2054
2055 loc_g_7318:
2056   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2057     PlayField16[*si + 1] = 0;
2058
2059   PlayField16[*si] = fiMurphy;
2060   subEatRedDisk(*si); // inc+show Murphy's red disks
2061   return subAnimateMurphy;
2062
2063   // ==========================================================================
2064   // Move Red Disk down
2065   // ==========================================================================
2066
2067 loc_g_7333:
2068   if (LowByte(PlayField16[*si]) != fiExplosion)
2069     PlayField16[*si] = 0;
2070
2071   *si = *si + FieldWidth;
2072   PlayField16[*si] = fiMurphy;
2073   subEatRedDisk(*si); // inc+show Murphy's red disks
2074   return subAnimateMurphy;
2075
2076   // ==========================================================================
2077   // Move Red Disk right
2078   // ==========================================================================
2079
2080 loc_g_7351:
2081   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2082     PlayField16[*si - 1] = 0;
2083
2084   PlayField16[*si] = fiMurphy;
2085   subEatRedDisk(*si); // inc+show Murphy's red disks
2086   return subAnimateMurphy;
2087
2088   // ==========================================================================
2089   // Eat Red Disk up
2090   // ==========================================================================
2091
2092 loc_g_736C:
2093   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2094     PlayField16[*si - FieldWidth] = 0;
2095
2096   subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2097   return subAnimateMurphy;
2098
2099   // ==========================================================================
2100   // Eat Red Disk left
2101   // ==========================================================================
2102
2103 loc_g_7381:
2104   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2105     PlayField16[*si - 1] = 0;
2106
2107   subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2108   return subAnimateMurphy;
2109
2110   // ==========================================================================
2111   // Eat Red Disk down
2112   // ==========================================================================
2113
2114 loc_g_7396:
2115   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2116     PlayField16[*si + FieldWidth] = 0;
2117
2118   subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2119   return subAnimateMurphy;
2120
2121   // ==========================================================================
2122   // Eat Red Disk right
2123   // ==========================================================================
2124
2125 loc_g_73AB:
2126   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2127     PlayField16[*si + 1] = 0;
2128
2129   subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2130   return subAnimateMurphy;
2131
2132   // ==========================================================================
2133   //                       yellow disk, pushing up
2134   // ==========================================================================
2135
2136 loc_g_73C0:
2137   if (LowByte(PlayField16[*si]) != fiExplosion)
2138     PlayField16[*si] = 0;
2139
2140   *si = *si - FieldWidth;
2141   PlayField16[*si] = fiMurphy;
2142   PlayField16[*si - FieldWidth] = fiYellowDisk;
2143   return subAnimateMurphy;
2144
2145   // ==========================================================================
2146   //                       yellow disk, pushing left
2147   // ==========================================================================
2148
2149 loc_g_73DD:
2150   if (LowByte(PlayField16[*si]) != fiExplosion)
2151     PlayField16[*si] = 0;
2152
2153   *si = *si - 1;
2154   PlayField16[*si] = fiMurphy;
2155   PlayField16[*si - 1] = fiYellowDisk;
2156   return subAnimateMurphy;
2157
2158   // ==========================================================================
2159   //                       yellow disk, pushing down
2160   // ==========================================================================
2161
2162 loc_g_73FA:
2163   if (LowByte(PlayField16[*si]) != fiExplosion)
2164     PlayField16[*si] = 0;
2165
2166   *si = *si + FieldWidth;
2167   PlayField16[*si] = fiMurphy;
2168   PlayField16[*si + FieldWidth] = fiYellowDisk;
2169   return subAnimateMurphy;
2170
2171   // ==========================================================================
2172   //                       yellow disk pushing right
2173   // ==========================================================================
2174
2175 loc_g_7417:
2176   if (LowByte(PlayField16[*si]) != fiExplosion)
2177     PlayField16[*si] = 0;
2178
2179   *si = *si + 1;
2180   PlayField16[*si] = fiMurphy;
2181   PlayField16[*si + 1] = fiYellowDisk;
2182   return subAnimateMurphy;
2183
2184   // ==========================================================================
2185   //                       orange disk, pushing left
2186   // ==========================================================================
2187
2188 loc_g_7434:
2189   if (LowByte(PlayField16[*si]) != fiExplosion)
2190     PlayField16[*si] = 0;
2191
2192   *si = *si - 1;
2193   PlayField16[*si] = fiMurphy;
2194   PlayField16[*si - 1] = fiOrangeDisk;
2195   return subAnimateMurphy;
2196
2197   // ==========================================================================
2198   //                       orange disk, pushing right
2199   // ==========================================================================
2200
2201 loc_g_7451:
2202   if (LowByte(PlayField16[*si]) != fiExplosion)
2203     PlayField16[*si] = 0;
2204
2205   *si = *si + 1;
2206   PlayField16[*si] = fiMurphy;
2207   PlayField16[*si + 1] = fiOrangeDisk;
2208   if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2209   {
2210     MovHighByte(&PlayField16[*si + 1], 0x20);
2211     MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2212   }
2213
2214   return subAnimateMurphy;
2215
2216   // ==========================================================================
2217   //                     Release a red disk
2218   // ==========================================================================
2219
2220 loc_g_747F:
2221   PlayField16[*si] = fiMurphy;
2222   RedDiskReleasePhase = 2;
2223   RedDiskCount = RedDiskCount - 1;
2224   subDisplayRedDiskCount();
2225   subSoundFXPush();                 // Sound effects
2226
2227   return subAnimateMurphy;
2228 } // subAnimateMurphy
2229
2230 // ==========================================================================
2231 //                              SUBROUTINE
2232 // ==========================================================================
2233 int subExplodeSnikSnaksBelow(int si)
2234 {
2235   int subExplodeSnikSnaksBelow;
2236
2237   int ax;
2238
2239   ax = LowByte(PlayField16[si + FieldWidth]);
2240   if (ax == 0x11 || ax == 0xBB)
2241     ExplodeFieldSP(si + FieldWidth);
2242
2243   return subExplodeSnikSnaksBelow;
2244 } // subExplodeSnikSnaksBelow
2245
2246 // ==========================================================================
2247 //                              SUBROUTINE
2248 // Does pushing against an object kill Murphy?
2249 // ==========================================================================
2250 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2251 {
2252   static boolean subMoveKillsMurphy;
2253
2254   int al, ah;
2255
2256   al = LowByte(ax);
2257   ah = HighByte(ax);
2258   if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2259     goto loc_g_752E;
2260
2261   if (al == fiZonk)
2262     goto loc_g_74E7;
2263
2264   if (al == fiExplosion)
2265     goto loc_g_7530;
2266
2267   if (fiOrangeDisk <= al && al <= fiPortUp)
2268     goto loc_g_752E;
2269
2270   ExplodeFieldSP(si);                 // Explode
2271   subMoveKillsMurphy = True;
2272   return subMoveKillsMurphy;
2273
2274 loc_g_74E7: // zonk
2275   if (bl == keyLeft)
2276     goto loc_g_74F6;
2277
2278   if (bl == keyRight)
2279     goto loc_g_7512;
2280
2281   ExplodeFieldSP(si);                 // Explode
2282   subMoveKillsMurphy = True;
2283   return subMoveKillsMurphy;
2284
2285 loc_g_74F6: // zonk left
2286   ah = ah & 0xF0;
2287   if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2288     ExplodeFieldSP(si);
2289
2290   subMoveKillsMurphy = True;                           // Set carry flag
2291   return subMoveKillsMurphy;
2292
2293 loc_g_7512: // zonk right
2294   ah = ah & 0xF0;
2295   if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2296     ExplodeFieldSP(si);
2297
2298 loc_g_752E: // Marked fields and Ports
2299   subMoveKillsMurphy = True;                           // Set carry flag
2300   return subMoveKillsMurphy;
2301
2302 loc_g_7530: // explosion
2303   if ((ah & 0x80) != 0)
2304     goto loc_g_753A;
2305
2306   if (ah >= 4)
2307     goto loc_g_753F;
2308
2309 loc_g_753A:
2310   ExplodeFieldSP(si);                 // Explode
2311   subMoveKillsMurphy = True;                           // Set carry flag
2312   return subMoveKillsMurphy;
2313
2314 loc_g_753F:
2315   PlayField16[si] = 0;
2316   subMoveKillsMurphy = False;
2317
2318   return subMoveKillsMurphy;
2319 } // subMoveKillsMurphy
2320
2321 // ==========================================================================
2322 //                              SUBROUTINE
2323 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2324 // change conditions to port specs
2325 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2326 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2327 // ==========================================================================
2328 int subSpPortTest(int si)
2329 {
2330   int subSpPortTest;
2331
2332   int i, cx, bx;
2333
2334 #if 1
2335   cx = LInfo.SpecialPortCount; // number of special ports
2336
2337   for (i = 0; i < cx; i++)
2338   {
2339 #if 1
2340     /* this assumes that PortLocation is stored as big endian */
2341     bx = LInfo.SpecialPort[i].PortLocation;
2342 #else
2343     /* this assumes that PortLocation is stored as little endian */
2344     bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2345     MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2346 #endif
2347
2348     if (bx / 2 == si)
2349     {
2350       GravityFlag = LInfo.SpecialPort[i].Gravity;
2351       FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2352       SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2353
2354       // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2355
2356       break;
2357     }
2358   }
2359
2360 #else
2361
2362   cx = LInfo.SpecialPortCount; // number of special ports
2363   for (i = 1; i <= cx; i++)
2364   {
2365     {
2366       bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2367       MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2368       if (bx / 2 == si)
2369       {
2370         GravityFlag = LInfo.SpecialPort[i].Gravity;
2371         FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2372         SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2373         //        RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2374         i = cx + 1;
2375       }
2376     }
2377   }
2378 #endif
2379
2380   return subSpPortTest;
2381 } // subSpPortTest
2382
2383 void subCopyFieldToScreen(int si, int fi)
2384 {
2385   int X, Y;
2386
2387   // +++++++++++++++++++++++++++++++++++++++++
2388   X = GetStretchX(si);
2389   Y = GetStretchY(si);
2390   StretchedSprites.BltEx(X, Y, fi);
2391   // +++++++++++++++++++++++++++++++++++++++++
2392 }
2393
2394 static void subEatRedDisk(int si)
2395 {
2396   if (AllowRedDiskCheat == 0)
2397   {
2398     if (RedDiskReleasePhase != 0)
2399     {
2400       if (RedDiskReleaseMurphyPos == si)
2401         return;
2402     }
2403   }
2404
2405   RedDiskCount = (RedDiskCount + 1) % 256;
2406   subDisplayRedDiskCount();
2407 }
2408
2409 int subAdjustZonksInfotronsAboveMurphy(int si)
2410 {
2411   int subAdjustZonksInfotronsAboveMurphy;
2412
2413   int ax;
2414
2415   if (LowByte(PlayField16[si]) != fiExplosion)
2416     PlayField16[si] = 0;
2417
2418   ax = PlayField16[si - FieldWidth];
2419   if (ax == 0 || ax == 0x9999)
2420     goto loc_g_15A8;
2421
2422   if (ax == fiZonk || ax == fiInfotron)
2423   {
2424     MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2425   }
2426
2427   return subAdjustZonksInfotronsAboveMurphy;
2428
2429 loc_g_15A8: // empty above
2430   ax = PlayField16[si - FieldWidth - 1];
2431   if (ax == fiZonk || ax == fiInfotron)
2432     goto loc_g_15C5;
2433
2434 loc_g_15B6:
2435   ax = PlayField16[si - FieldWidth + 1];
2436   if (ax == fiZonk || ax == fiInfotron)
2437     goto loc_g_15E8;
2438
2439   return subAdjustZonksInfotronsAboveMurphy;
2440
2441 loc_g_15C5: // zonk/infotron above left
2442   ax = PlayField16[si - 1];
2443   if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2444     goto loc_g_15B6;
2445
2446   MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2447   PlayField16[si - FieldWidth] = 0x8888;
2448   return subAdjustZonksInfotronsAboveMurphy;
2449
2450 loc_g_15E8: // zonk/infotron above right
2451   ax = PlayField16[si + 1];
2452   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2453   {
2454     MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2455     PlayField16[si - FieldWidth] = 0x8888;
2456   }
2457
2458   return subAdjustZonksInfotronsAboveMurphy;
2459 } // subAdjustZonksInfotronsAboveMurphy