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