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