rnd-20091011-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   printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n", LevelNumber);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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
1426 #if 0
1427   printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1428          TimerVar,
1429          DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1430          (DemoKeyCode == keyNone        ? "(none)"              :
1431           DemoKeyCode == keyLeft        ? "left"                :
1432           DemoKeyCode == keyRight       ? "right"               :
1433           DemoKeyCode == keyUp          ? "up"                  :
1434           DemoKeyCode == keyDown        ? "down"                :
1435           DemoKeyCode == keySpace       ? "space"               :
1436           DemoKeyCode == keySpaceLeft   ? "space + left"        :
1437           DemoKeyCode == keySpaceRight  ? "space + right"       :
1438           DemoKeyCode == keySpaceUp     ? "space + up"          :
1439           DemoKeyCode == keySpaceDown   ? "space + down"        : "(unknown)"),
1440          DemoKeyCode,
1441          MurphyScreenXPos, MurphyScreenYPos,
1442          MurphyPosIndex % 60, MurphyPosIndex / 60,
1443          ClearPos);
1444 #endif
1445
1446 #if 0
1447   Delay(500);
1448 #endif
1449
1450 #if 1
1451     if (!(ClearPos < 0)) // clear field that murphy is leaving
1452       subCopyFieldToScreen(ClearPos, 0);
1453 #else
1454     if (! ClearPos < 0) // clear field that murphy is leaving
1455       subCopyFieldToScreen(ClearPos, 0);
1456 #endif
1457
1458 #if 0
1459     printf("::: ---------------> %d, %d [%d, %d]\n",
1460            MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1461 #endif
1462
1463     if (dx2 == fiInfotron) // special case of infotron moving left or right
1464     {
1465       tDeltaX = 0;
1466       tDeltaY = 0;
1467     }
1468     else
1469     {
1470       tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1471       tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1472     }
1473
1474     X = GetStretchX(dxPos) + tDeltaX;
1475     Y = GetStretchY(dxPos) + tDeltaY;
1476     Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1477     StretchedSprites.BltEx(X, Y, dx[Tmp]);
1478
1479 #if 1
1480     if (!(dx2 < 0))
1481 #else
1482     if (! dx2 < 0)
1483 #endif
1484     {
1485       tPos = dxPos + dx2Step;
1486       X = GetStretchX(tPos);
1487       Y = GetStretchY(tPos);
1488       if (dx2 == fiInfotron) // special case of infotron moving left or right
1489       {
1490         StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1491       }
1492       else // pushing something
1493       {
1494         StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1495       }
1496     }
1497
1498     // End of normal movement
1499     // ------------------------
1500   }
1501   else
1502   {
1503     // ++++++++++++++++++++++++++++++++
1504     // Begin of split movement (port)
1505 #if 1
1506     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1507     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1508 #else
1509     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1510     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1511 #endif
1512     subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1513     tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1514     tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1515     X = GetStretchX(dxPos) + tDeltaX;
1516     Y = GetStretchY(dxPos) + tDeltaY;
1517     StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1518     tPos = dxPos + dx2Step;
1519     X = GetStretchX(tPos);
1520     Y = GetStretchY(tPos);
1521     StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1522     StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1523     // End of split movement (port)
1524     // ------------------------------
1525   } // loc_g_6D1E:'loc_g_6D28:
1526
1527   SeqPos = SeqPos + 1;
1528   if (dx[SeqPos] > -1)
1529     return subAnimateMurphy;
1530
1531   // Follow-up after movement completed     'loc_g_6D35:
1532   MurphyXPos = MurphyXPos + MurphyDX;
1533   MurphyYPos = MurphyYPos + MurphyDY;
1534   bl = HighByte(PlayField16[*si]);  // animation phase
1535   MovHighByte(&PlayField16[*si], 0);
1536
1537   if (bl == 0x1)    // space, moving up
1538     goto loc_g_6EC8;
1539
1540   if (bl == 0x2)    // space, moving left
1541     goto loc_g_6EE6;
1542
1543   if (bl == 0x3)    // space, moving down
1544     goto loc_g_6F04;
1545
1546   if (bl == 0x4)    // space, moving right
1547     goto loc_g_71C4;
1548
1549   if (bl == 0x5)    // base , moving up
1550     goto loc_g_6EC8;
1551
1552   if (bl == 0x6)    // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1553     goto loc_g_6EE6;
1554
1555   if (bl == 0x7)    // base , moving down
1556     goto loc_g_6F04;
1557
1558   if (bl == 0x8)    // base , moving right
1559     goto loc_g_71C4;
1560
1561   if (bl == 0x9)    // infotron, moving up
1562     goto loc_g_6EBA;
1563
1564   if (bl == 0xA)      // infotron, moving left
1565     goto loc_g_6ED8;
1566
1567   if (bl == 0xB)    // infotron, moving down
1568     goto loc_g_6EF6;
1569
1570   if (bl == 0xC)      // infotron, moving right
1571     goto loc_g_71B6;
1572
1573   if (bl == 0xD)      // exit
1574     goto loc_g_6F77;
1575
1576   if (bl == 0xE)      // zonk, pushing left
1577     goto loc_g_6F18;
1578
1579   if (bl == 0xF)      // zonk, pushing right
1580     goto loc_g_6F3B;
1581
1582   if (bl == 0x10)   // base , touching up
1583     goto loc_g_71E2;
1584
1585   if (bl == 0x11)   // base , touching left
1586     goto loc_g_71FE;
1587
1588   if (bl == 0x12)   // base , touching down
1589     goto loc_g_721A;
1590
1591   if (bl == 0x13)   // base , touching right
1592     goto loc_g_7236;
1593
1594   if (bl == 0x14)   // infotron touching up
1595     goto loc_g_71D4;
1596
1597   if (bl == 0x15)   // infotron touching left
1598     goto loc_g_71F0;
1599
1600   if (bl == 0x16)   // infotron touching down
1601     goto loc_g_720C;
1602
1603   if (bl == 0x17)   // infotron touching right
1604     goto loc_g_7228;
1605
1606   if (bl == 0x18)     // port up
1607     goto loc_g_7244;
1608
1609   if (bl == 0x19)     // port left
1610     goto loc_g_7272;
1611
1612   if (bl == 0x1A)     // port down
1613     goto loc_g_729F;
1614
1615   if (bl == 0x1B)     // port right
1616     goto loc_g_72CD;
1617
1618   if (bl == 0x1C)   // red disk, moving up
1619     goto loc_g_72FA;
1620
1621   if (bl == 0x1D)   // red disk, moving left
1622     goto loc_g_7318;
1623
1624   if (bl == 0x1E)   // red disk, moving down
1625     goto loc_g_7333;
1626
1627   if (bl == 0x1F)   // red disk, moving right -> 9-Step-Bug!
1628     goto loc_g_7351;
1629
1630   if (bl == 0x20)   // red disk, touching up
1631     goto loc_g_736C;
1632
1633   if (bl == 0x21)   // red disk, touching left
1634     goto loc_g_7381;
1635
1636   if (bl == 0x22)   // red disk, touching down
1637     goto loc_g_7396;
1638
1639   if (bl == 0x23)   // red disk, touching right
1640     goto loc_g_73AB;
1641
1642   if (bl == 0x24)     // yellow disk, pushing up
1643     goto loc_g_73C0;
1644
1645   if (bl == 0x25)     // yellow disk, pushing left
1646     goto loc_g_73DD;
1647
1648   if (bl == 0x26)     // yellow disk, pushing right -> order of "down" exchanged with "right"!
1649     goto loc_g_7417;
1650
1651   if (bl == 0x27)     // yellow disk, pushing down  -> order of "down" exchanged with "right"!
1652     goto loc_g_73FA;
1653
1654   if (bl == 0x28)     // orange disk, pushing left
1655     goto loc_g_7434;
1656
1657   if (bl == 0x29)     // orange disk, pushing right
1658     goto loc_g_7451;
1659
1660   if (bl == 0x2A)   // red disk, release
1661     goto loc_g_747F;
1662
1663   ExitToMenuFlag = 1;
1664   return subAnimateMurphy;
1665
1666   // ==========================================================================
1667   //                       infotron, moving up
1668   // ==========================================================================
1669
1670 loc_g_6EBA:
1671   if (0 < LowByte(InfotronsNeeded))
1672     InfotronsNeeded = InfotronsNeeded - 1;
1673
1674   subDisplayInfotronsNeeded();
1675 loc_g_6EC8: // space, base
1676   PlayField16[*si] = fiMurphy;
1677   subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1678   return subAnimateMurphy;
1679
1680   // ==========================================================================
1681   //                       infotron, moving left
1682   // ==========================================================================
1683
1684 loc_g_6ED8:
1685   if (0 < LowByte(InfotronsNeeded))
1686     InfotronsNeeded = InfotronsNeeded - 1;
1687
1688   subDisplayInfotronsNeeded();
1689 loc_g_6EE6: // space, base
1690   PlayField16[*si] = fiMurphy;
1691   subAdjustZonksInfotronsAboveMurphy(*si + 1);
1692   return subAnimateMurphy;
1693
1694   // ==========================================================================
1695   //                       infotron, moving down
1696   // ==========================================================================
1697
1698 loc_g_6EF6:
1699   if (0 < LowByte(InfotronsNeeded))
1700     InfotronsNeeded = InfotronsNeeded - 1;
1701
1702   subDisplayInfotronsNeeded();
1703 loc_g_6F04: // space, base
1704   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1705     PlayField16[*si - FieldWidth] = 0;
1706
1707   PlayField16[*si] = fiMurphy;
1708   return subAnimateMurphy;
1709
1710   // ==========================================================================
1711   //                       infotron, moving right
1712   // ==========================================================================
1713
1714 loc_g_71B6:
1715   if (0 < LowByte(InfotronsNeeded))
1716     InfotronsNeeded = InfotronsNeeded - 1;
1717
1718   subDisplayInfotronsNeeded();
1719 loc_g_71C4: // space, base
1720   subAdjustZonksInfotronsAboveMurphy(*si - 1);
1721   PlayField16[*si] = fiMurphy;
1722   return subAnimateMurphy;
1723
1724   // ==========================================================================
1725   //                       infotron, touching up
1726   // ==========================================================================
1727
1728 loc_g_71D4:
1729   if (0 < LowByte(InfotronsNeeded))
1730     InfotronsNeeded = InfotronsNeeded - 1;
1731
1732   subDisplayInfotronsNeeded();
1733 loc_g_71E2: // base
1734   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1735     PlayField16[*si - FieldWidth] = 0;
1736
1737   return subAnimateMurphy;
1738
1739   // ==========================================================================
1740   //                       infotron, touching left
1741   // ==========================================================================
1742
1743 loc_g_71F0:
1744   if (0 < LowByte(InfotronsNeeded))
1745     InfotronsNeeded = InfotronsNeeded - 1;
1746
1747   subDisplayInfotronsNeeded();
1748 loc_g_71FE: // base
1749   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1750     PlayField16[*si - 1] = 0;
1751
1752   return subAnimateMurphy;
1753
1754   // ==========================================================================
1755   //                       infotron, touching down
1756   // ==========================================================================
1757
1758 loc_g_720C:
1759   if (0 < LowByte(InfotronsNeeded))
1760     InfotronsNeeded = InfotronsNeeded - 1;
1761
1762   subDisplayInfotronsNeeded();
1763 loc_g_721A: // base
1764   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1765     PlayField16[*si + FieldWidth] = 0;
1766
1767   return subAnimateMurphy;
1768
1769   // ==========================================================================
1770   //                       infotron, touching right
1771   // ==========================================================================
1772
1773 loc_g_7228:
1774   if (0 < LowByte(InfotronsNeeded))
1775     InfotronsNeeded = InfotronsNeeded - 1;
1776
1777   subDisplayInfotronsNeeded();
1778 loc_g_7236: // base
1779   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1780     PlayField16[*si + 1] = 0;
1781
1782   return subAnimateMurphy;
1783
1784   // ==========================================================================
1785   //                       zonk, pushing left
1786   // ==========================================================================
1787
1788 loc_g_6F18:
1789   if (LowByte(PlayField16[*si]) != fiExplosion)
1790     PlayField16[*si] = 0;
1791
1792   PlayField16[*si - 1] = fiMurphy;
1793   PlayField16[*si - 2] = fiZonk;
1794   subExplodeSnikSnaksBelow(*si - 2);
1795   *si = *si - 1;
1796   return subAnimateMurphy;
1797
1798   // ==========================================================================
1799   //                       zonk, pushing right
1800   // ==========================================================================
1801
1802 loc_g_6F3B:
1803   if (LowByte(PlayField16[*si]) != fiExplosion)
1804     PlayField16[*si] = 0;
1805
1806   PlayField16[*si + 1] = fiMurphy;
1807   PlayField16[*si + 2] = fiZonk;
1808   subExplodeSnikSnaksBelow(*si + 2);
1809   *si = *si + 1;
1810   return subAnimateMurphy;
1811
1812   // ==========================================================================
1813   //                       exit
1814   // ==========================================================================
1815
1816 loc_g_6F77:
1817   ExitToMenuFlag = 1;
1818   return subAnimateMurphy;
1819
1820   // ==========================================================================
1821   //               Push Zonk from right to left
1822   // ==========================================================================
1823
1824 loc_g_6F7E:
1825   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1826     return subAnimateMurphy;
1827
1828   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1829   PlayField16[*si - 1] = fiZonk;
1830   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1831     PlayField16[*si - 2] = 0;
1832
1833   subCopyFieldToScreen(*si, fiMurphy);
1834   return subAnimateMurphy;
1835
1836   // ==========================================================================
1837   //                       Push Zonk from left to right
1838   // ==========================================================================
1839
1840 loc_g_6FBC:
1841   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1842     return subAnimateMurphy;
1843
1844   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1845   PlayField16[*si + 1] = fiZonk;
1846   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1847     PlayField16[*si + 2] = 0;
1848
1849   subCopyFieldToScreen(*si, fiMurphy);
1850   return subAnimateMurphy;
1851
1852   // ==========================================================================
1853   //               Push orange disk from right to left
1854   // ==========================================================================
1855
1856 loc_g_6FFA:
1857   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1858     return subAnimateMurphy;
1859
1860   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1861   PlayField16[*si - 1] = fiOrangeDisk;
1862   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1863     PlayField16[*si - 2] = 0;
1864
1865   subCopyFieldToScreen(*si, fiMurphy);
1866   return subAnimateMurphy;
1867
1868   // ==========================================================================
1869   //               Push orange disk from left to right
1870   // ==========================================================================
1871
1872 loc_g_7038:
1873   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1874     return subAnimateMurphy;
1875
1876   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1877   PlayField16[*si + 1] = fiOrangeDisk;
1878   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1879     PlayField16[*si + 2] = 0;
1880
1881   subCopyFieldToScreen(*si, fiMurphy);
1882   return subAnimateMurphy;
1883
1884   // ==========================================================================
1885   //               Push yellow disk from down to up
1886   // ==========================================================================
1887
1888 loc_g_7076:
1889   if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1890     return subAnimateMurphy;
1891
1892   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1893   PlayField16[*si - FieldWidth] = fiYellowDisk;
1894   if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1895     PlayField16[*si - 2 * FieldWidth] = 0;
1896
1897   subCopyFieldToScreen(*si, fiMurphy);
1898   return subAnimateMurphy;
1899
1900   // ==========================================================================
1901   //               Push yellow disk from right to left
1902   // ==========================================================================
1903
1904 loc_g_70B4:
1905   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1906     return subAnimateMurphy;
1907
1908   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1909   PlayField16[*si - 1] = fiYellowDisk;
1910   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1911     PlayField16[*si - 2] = 0;
1912
1913   subCopyFieldToScreen(*si, fiMurphy);
1914   return subAnimateMurphy;
1915
1916   // ==========================================================================
1917   //               Push yellow disk from up to down
1918   // ==========================================================================
1919
1920 loc_g_70F2:
1921   if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1922     return subAnimateMurphy;
1923
1924   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1925   PlayField16[*si + FieldWidth] = fiYellowDisk;
1926   if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1927     PlayField16[*si + 2 * FieldWidth] = 0;
1928
1929   subCopyFieldToScreen(*si, fiMurphy);
1930   return subAnimateMurphy;
1931
1932   // ==========================================================================
1933   //               Push yellow disk from left to right
1934   // ==========================================================================
1935
1936 loc_g_7130:
1937   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1938     return subAnimateMurphy;
1939
1940   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1941   PlayField16[*si + 1] = fiYellowDisk;
1942   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1943     PlayField16[*si + 2] = 0;
1944
1945   subCopyFieldToScreen(*si, fiMurphy);
1946   return subAnimateMurphy;
1947
1948   // ==========================================================================
1949   //               time red disk release (space)
1950   // ==========================================================================
1951
1952 loc_g_716E:
1953   if (DemoKeyCode != keySpace)
1954   {
1955     PlayField16[*si] = fiMurphy;
1956     subCopyFieldToScreen(*si, fiMurphy);
1957     RedDiskReleasePhase = 0;
1958   }
1959   else if (MovingPictureSequencePhase == 0x20)
1960   {
1961     subCopyFieldToScreen(*si, 43);  // anxious murphy
1962     RedDiskReleasePhase = 1;
1963   }
1964
1965   return subAnimateMurphy;
1966
1967   // ==========================================================================
1968   // Special port down to up
1969   // ==========================================================================
1970
1971 loc_g_7244:
1972   if (LowByte(PlayField16[*si]) != fiExplosion)
1973     PlayField16[*si] = 0;
1974
1975   PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1976   SplitMoveFlag = 0;
1977   *si = *si - FieldWidth;
1978   if (HighByte(PlayField16[*si]) == 1)
1979     subSpPortTest(*si);
1980
1981   *si = *si - FieldWidth;
1982   return subAnimateMurphy;
1983
1984   // ==========================================================================
1985   // Special port right to left
1986   // ==========================================================================
1987
1988 loc_g_7272:
1989   if (LowByte(PlayField16[*si]) != fiExplosion)
1990     PlayField16[*si] = 0;
1991
1992   PlayField16[*si - 2] = fiMurphy;
1993   SplitMoveFlag = 0;
1994   *si = *si - 1;
1995   if (HighByte(PlayField16[*si]) == 1)
1996     subSpPortTest(*si);
1997
1998   *si = *si - 1;
1999   return subAnimateMurphy;
2000
2001   // ==========================================================================
2002   // Special port up to down
2003   // ==========================================================================
2004
2005 loc_g_729F:
2006   if (LowByte(PlayField16[*si]) != fiExplosion)
2007     PlayField16[*si] = 0;
2008
2009   PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2010   SplitMoveFlag = 0;
2011   *si = *si + FieldWidth;
2012   if (HighByte(PlayField16[*si]) == 1)
2013     subSpPortTest(*si);
2014
2015   *si = *si + FieldWidth;
2016   return subAnimateMurphy;
2017
2018   // ==========================================================================
2019   // Special port left to right
2020   // ==========================================================================
2021
2022 loc_g_72CD:
2023   if (LowByte(PlayField16[*si]) != fiExplosion)
2024     PlayField16[*si] = 0;
2025
2026   PlayField16[*si + 2] = fiMurphy;
2027   SplitMoveFlag = 0;
2028   *si = *si + 1;
2029   if (HighByte(PlayField16[*si]) == 1)
2030     subSpPortTest(*si);
2031
2032   *si = *si + 1;
2033   return subAnimateMurphy;
2034
2035   // ==========================================================================
2036   // Move Red Disk up
2037   // ==========================================================================
2038
2039 loc_g_72FA:
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 left
2050   // ==========================================================================
2051
2052 loc_g_7318:
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   // Move Red Disk down
2062   // ==========================================================================
2063
2064 loc_g_7333:
2065   if (LowByte(PlayField16[*si]) != fiExplosion)
2066     PlayField16[*si] = 0;
2067
2068   *si = *si + FieldWidth;
2069   PlayField16[*si] = fiMurphy;
2070   subEatRedDisk(*si); // inc+show Murphy's red disks
2071   return subAnimateMurphy;
2072
2073   // ==========================================================================
2074   // Move Red Disk right
2075   // ==========================================================================
2076
2077 loc_g_7351:
2078   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2079     PlayField16[*si - 1] = 0;
2080
2081   PlayField16[*si] = fiMurphy;
2082   subEatRedDisk(*si); // inc+show Murphy's red disks
2083   return subAnimateMurphy;
2084
2085   // ==========================================================================
2086   // Eat Red Disk up
2087   // ==========================================================================
2088
2089 loc_g_736C:
2090   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2091     PlayField16[*si - FieldWidth] = 0;
2092
2093   subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2094   return subAnimateMurphy;
2095
2096   // ==========================================================================
2097   // Eat Red Disk left
2098   // ==========================================================================
2099
2100 loc_g_7381:
2101   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2102     PlayField16[*si - 1] = 0;
2103
2104   subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2105   return subAnimateMurphy;
2106
2107   // ==========================================================================
2108   // Eat Red Disk down
2109   // ==========================================================================
2110
2111 loc_g_7396:
2112   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2113     PlayField16[*si + FieldWidth] = 0;
2114
2115   subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2116   return subAnimateMurphy;
2117
2118   // ==========================================================================
2119   // Eat Red Disk right
2120   // ==========================================================================
2121
2122 loc_g_73AB:
2123   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2124     PlayField16[*si + 1] = 0;
2125
2126   subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2127   return subAnimateMurphy;
2128
2129   // ==========================================================================
2130   //                       yellow disk, pushing up
2131   // ==========================================================================
2132
2133 loc_g_73C0:
2134   if (LowByte(PlayField16[*si]) != fiExplosion)
2135     PlayField16[*si] = 0;
2136
2137   *si = *si - FieldWidth;
2138   PlayField16[*si] = fiMurphy;
2139   PlayField16[*si - FieldWidth] = fiYellowDisk;
2140   return subAnimateMurphy;
2141
2142   // ==========================================================================
2143   //                       yellow disk, pushing left
2144   // ==========================================================================
2145
2146 loc_g_73DD:
2147   if (LowByte(PlayField16[*si]) != fiExplosion)
2148     PlayField16[*si] = 0;
2149
2150   *si = *si - 1;
2151   PlayField16[*si] = fiMurphy;
2152   PlayField16[*si - 1] = fiYellowDisk;
2153   return subAnimateMurphy;
2154
2155   // ==========================================================================
2156   //                       yellow disk, pushing down
2157   // ==========================================================================
2158
2159 loc_g_73FA:
2160   if (LowByte(PlayField16[*si]) != fiExplosion)
2161     PlayField16[*si] = 0;
2162
2163   *si = *si + FieldWidth;
2164   PlayField16[*si] = fiMurphy;
2165   PlayField16[*si + FieldWidth] = fiYellowDisk;
2166   return subAnimateMurphy;
2167
2168   // ==========================================================================
2169   //                       yellow disk pushing right
2170   // ==========================================================================
2171
2172 loc_g_7417:
2173   if (LowByte(PlayField16[*si]) != fiExplosion)
2174     PlayField16[*si] = 0;
2175
2176   *si = *si + 1;
2177   PlayField16[*si] = fiMurphy;
2178   PlayField16[*si + 1] = fiYellowDisk;
2179   return subAnimateMurphy;
2180
2181   // ==========================================================================
2182   //                       orange disk, pushing left
2183   // ==========================================================================
2184
2185 loc_g_7434:
2186   if (LowByte(PlayField16[*si]) != fiExplosion)
2187     PlayField16[*si] = 0;
2188
2189   *si = *si - 1;
2190   PlayField16[*si] = fiMurphy;
2191   PlayField16[*si - 1] = fiOrangeDisk;
2192   return subAnimateMurphy;
2193
2194   // ==========================================================================
2195   //                       orange disk, pushing right
2196   // ==========================================================================
2197
2198 loc_g_7451:
2199   if (LowByte(PlayField16[*si]) != fiExplosion)
2200     PlayField16[*si] = 0;
2201
2202   *si = *si + 1;
2203   PlayField16[*si] = fiMurphy;
2204   PlayField16[*si + 1] = fiOrangeDisk;
2205   if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2206   {
2207     MovHighByte(&PlayField16[*si + 1], 0x20);
2208     MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2209   }
2210
2211   return subAnimateMurphy;
2212
2213   // ==========================================================================
2214   //                     Release a red disk
2215   // ==========================================================================
2216
2217 loc_g_747F:
2218   PlayField16[*si] = fiMurphy;
2219   RedDiskReleasePhase = 2;
2220   RedDiskCount = RedDiskCount - 1;
2221   subDisplayRedDiskCount();
2222   subSoundFXPush();                 // Sound effects
2223
2224   return subAnimateMurphy;
2225 } // subAnimateMurphy
2226
2227 // ==========================================================================
2228 //                              SUBROUTINE
2229 // ==========================================================================
2230 int subExplodeSnikSnaksBelow(int si)
2231 {
2232   int subExplodeSnikSnaksBelow;
2233
2234   int ax;
2235
2236   ax = LowByte(PlayField16[si + FieldWidth]);
2237   if (ax == 0x11 || ax == 0xBB)
2238     ExplodeFieldSP(si + FieldWidth);
2239
2240   return subExplodeSnikSnaksBelow;
2241 } // subExplodeSnikSnaksBelow
2242
2243 // ==========================================================================
2244 //                              SUBROUTINE
2245 // Does pushing against an object kill Murphy?
2246 // ==========================================================================
2247 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2248 {
2249   static boolean subMoveKillsMurphy;
2250
2251   int al, ah;
2252
2253   al = LowByte(ax);
2254   ah = HighByte(ax);
2255   if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2256     goto loc_g_752E;
2257
2258   if (al == fiZonk)
2259     goto loc_g_74E7;
2260
2261   if (al == fiExplosion)
2262     goto loc_g_7530;
2263
2264   if (fiOrangeDisk <= al && al <= fiPortUp)
2265     goto loc_g_752E;
2266
2267   ExplodeFieldSP(si);                 // Explode
2268   subMoveKillsMurphy = True;
2269   return subMoveKillsMurphy;
2270
2271 loc_g_74E7: // zonk
2272   if (bl == keyLeft)
2273     goto loc_g_74F6;
2274
2275   if (bl == keyRight)
2276     goto loc_g_7512;
2277
2278   ExplodeFieldSP(si);                 // Explode
2279   subMoveKillsMurphy = True;
2280   return subMoveKillsMurphy;
2281
2282 loc_g_74F6: // zonk left
2283   ah = ah & 0xF0;
2284   if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2285     ExplodeFieldSP(si);
2286
2287   subMoveKillsMurphy = True;                           // Set carry flag
2288   return subMoveKillsMurphy;
2289
2290 loc_g_7512: // zonk right
2291   ah = ah & 0xF0;
2292   if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2293     ExplodeFieldSP(si);
2294
2295 loc_g_752E: // Marked fields and Ports
2296   subMoveKillsMurphy = True;                           // Set carry flag
2297   return subMoveKillsMurphy;
2298
2299 loc_g_7530: // explosion
2300   if ((ah & 0x80) != 0)
2301     goto loc_g_753A;
2302
2303   if (ah >= 4)
2304     goto loc_g_753F;
2305
2306 loc_g_753A:
2307   ExplodeFieldSP(si);                 // Explode
2308   subMoveKillsMurphy = True;                           // Set carry flag
2309   return subMoveKillsMurphy;
2310
2311 loc_g_753F:
2312   PlayField16[si] = 0;
2313   subMoveKillsMurphy = False;
2314
2315   return subMoveKillsMurphy;
2316 } // subMoveKillsMurphy
2317
2318 // ==========================================================================
2319 //                              SUBROUTINE
2320 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2321 // change conditions to port specs
2322 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2323 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2324 // ==========================================================================
2325 int subSpPortTest(int si)
2326 {
2327   int subSpPortTest;
2328
2329   int i, cx, bx;
2330
2331 #if 1
2332   cx = LInfo.SpecialPortCount; // number of special ports
2333
2334   for (i = 0; i < cx; i++)
2335   {
2336 #if 1
2337     /* this assumes that PortLocation is stored as big endian */
2338     bx = LInfo.SpecialPort[i].PortLocation;
2339 #else
2340     /* this assumes that PortLocation is stored as little endian */
2341     bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2342     MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2343 #endif
2344
2345     if (bx / 2 == si)
2346     {
2347       GravityFlag = LInfo.SpecialPort[i].Gravity;
2348       FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2349       SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2350
2351       // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2352
2353       break;
2354     }
2355   }
2356
2357 #else
2358
2359   cx = LInfo.SpecialPortCount; // number of special ports
2360   for (i = 1; i <= cx; i++)
2361   {
2362     {
2363       bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2364       MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2365       if (bx / 2 == si)
2366       {
2367         GravityFlag = LInfo.SpecialPort[i].Gravity;
2368         FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2369         SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2370         //        RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2371         i = cx + 1;
2372       }
2373     }
2374   }
2375 #endif
2376
2377   return subSpPortTest;
2378 } // subSpPortTest
2379
2380 void subCopyFieldToScreen(int si, int fi)
2381 {
2382   int X, Y;
2383
2384   // +++++++++++++++++++++++++++++++++++++++++
2385   X = GetStretchX(si);
2386   Y = GetStretchY(si);
2387   StretchedSprites.BltEx(X, Y, fi);
2388   // +++++++++++++++++++++++++++++++++++++++++
2389 }
2390
2391 static void subEatRedDisk(int si)
2392 {
2393   if (AllowRedDiskCheat == 0)
2394   {
2395     if (RedDiskReleasePhase != 0)
2396     {
2397       if (RedDiskReleaseMurphyPos == si)
2398         return;
2399     }
2400   }
2401
2402   RedDiskCount = (RedDiskCount + 1) % 256;
2403   subDisplayRedDiskCount();
2404 }
2405
2406 int subAdjustZonksInfotronsAboveMurphy(int si)
2407 {
2408   int subAdjustZonksInfotronsAboveMurphy;
2409
2410   int ax;
2411
2412   if (LowByte(PlayField16[si]) != fiExplosion)
2413     PlayField16[si] = 0;
2414
2415   ax = PlayField16[si - FieldWidth];
2416   if (ax == 0 || ax == 0x9999)
2417     goto loc_g_15A8;
2418
2419   if (ax == fiZonk || ax == fiInfotron)
2420   {
2421     MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2422   }
2423
2424   return subAdjustZonksInfotronsAboveMurphy;
2425
2426 loc_g_15A8: // empty above
2427   ax = PlayField16[si - FieldWidth - 1];
2428   if (ax == fiZonk || ax == fiInfotron)
2429     goto loc_g_15C5;
2430
2431 loc_g_15B6:
2432   ax = PlayField16[si - FieldWidth + 1];
2433   if (ax == fiZonk || ax == fiInfotron)
2434     goto loc_g_15E8;
2435
2436   return subAdjustZonksInfotronsAboveMurphy;
2437
2438 loc_g_15C5: // zonk/infotron above left
2439   ax = PlayField16[si - 1];
2440   if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2441     goto loc_g_15B6;
2442
2443   MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2444   PlayField16[si - FieldWidth] = 0x8888;
2445   return subAdjustZonksInfotronsAboveMurphy;
2446
2447 loc_g_15E8: // zonk/infotron above right
2448   ax = PlayField16[si + 1];
2449   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2450   {
2451     MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2452     PlayField16[si - FieldWidth] = 0x8888;
2453   }
2454
2455   return subAdjustZonksInfotronsAboveMurphy;
2456 } // subAdjustZonksInfotronsAboveMurphy