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