rnd-20100224-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   subSoundFXBase();
759   dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
760   dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyDigUpRight : aniMurphyDigUpLeft);
761   PlayField16[*si - FieldWidth] = 0x503;
762   PlayField16[*si] = 0x300;
763   *si = *si - FieldWidth;
764   goto loc_StopNoSplit;
765
766   // ==========================================================================
767   // BUG moving right to left
768   // ==========================================================================
769
770 loc_g_640B:
771   if (SgnHighByte(PlayField16[*si - 1]) >= 0)
772   {
773     ExplodeFieldSP(*si);                 // Explode
774
775     return;
776   }
777
778   PlayField16[*si - 1] = fiBase;
779   // ==========================================================================
780   // BASE moving right to left
781   // ==========================================================================
782
783 loc_g_641C:
784   subSoundFXBase();
785   dx = aniFramesMurphyEatLeft;
786   dx1 = aniMurphyDigLeft;
787   PlayField16[*si - 1] = 0x203;
788   PlayField16[*si] = 0x300;
789   *si = *si - 1;
790   goto loc_StopNoSplit;
791
792   // ==========================================================================
793   // BUG moving up to down
794   // ==========================================================================
795
796 loc_g_6448:
797   if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
798   {
799     ExplodeFieldSP(*si);                 // Explode
800
801     return;
802   }
803
804   PlayField16[*si + FieldWidth] = fiBase;
805   // ==========================================================================
806   // BASE moving up to down
807   // ==========================================================================
808
809 loc_g_6459:
810   subSoundFXBase();
811   dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
812   dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyDigUpRight : aniMurphyDigUpLeft);
813   PlayField16[*si + FieldWidth] = 0x703;
814   PlayField16[*si] = 0x300;
815   *si = *si + FieldWidth;
816   goto loc_StopNoSplit;
817
818   // ==========================================================================
819   // BUG moving left to right
820   // ==========================================================================
821
822 loc_g_6491:
823   if (SgnHighByte(PlayField16[*si + 1]) >= 0)
824   {
825     ExplodeFieldSP(*si);                 // Explode
826
827     return;
828   }
829
830   PlayField16[*si + 1] = fiBase;
831   // ==========================================================================
832   // BASE moving left to right
833   // ==========================================================================
834
835 loc_g_64A2:
836   subSoundFXBase();
837   dx = aniFramesMurphyEatRight;
838   dx1 = aniMurphyDigRight;
839   PlayField16[*si + 1] = 0x803;
840   PlayField16[*si] = 0x300;
841   *si = *si + 1;
842   goto loc_StopNoSplit;
843
844   // ==========================================================================
845   // BUG touching down to up
846   // ==========================================================================
847
848 loc_g_64CE:
849   if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
850   {
851     ExplodeFieldSP(*si);                 // Explode
852
853     return;
854   }
855
856   PlayField16[*si - FieldWidth] = fiBase;
857   // ==========================================================================
858   // BASE touching down to up
859   // ==========================================================================
860
861 loc_g_64DF:
862   subCopyImageToScreen(*si, aniMurphyTouchUp);
863   subSoundFXBase();
864   dx = aniFramesTouchBase;
865   dx1 = aniTouchBase;
866   dxPos = *si - FieldWidth;
867   MovHighByte(&PlayField16[*si], 0x10);
868   goto loc_StopNoSplit;
869
870   // ==========================================================================
871   // BUG touching right to left
872   // ==========================================================================
873
874 loc_g_650C:
875   if (SgnHighByte(PlayField16[*si - 1]) >= 0)
876   {
877     ExplodeFieldSP(*si);                 // Explode
878
879     return;
880   }
881
882   PlayField16[*si - 1] = fiBase;
883   // ==========================================================================
884   // BASE touching right to left
885   // ==========================================================================
886
887 loc_g_651D:
888   subCopyImageToScreen(*si, aniMurphyTouchLeft);
889   subSoundFXBase();
890   dx = aniFramesTouchBase;
891   dx1 = aniTouchBase;
892   dxPos = *si - 1;
893   MovHighByte(&PlayField16[*si], 0x11);
894   goto loc_StopNoSplit;
895
896   // ==========================================================================
897   // BUG touching up to down
898   // ==========================================================================
899
900 loc_g_654A:
901   if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
902   {
903     ExplodeFieldSP(*si);                 // Explode
904
905     return;
906   }
907
908   PlayField16[*si + FieldWidth] = fiBase;
909   // ==========================================================================
910   // BASE touching up to down
911   // ==========================================================================
912
913 loc_g_655B:
914   subCopyImageToScreen(*si, aniMurphyTouchDown);
915   subSoundFXBase();
916   dx = aniFramesTouchBase;
917   dx1 = aniTouchBase;
918   dxPos = *si + FieldWidth;
919   MovHighByte(&PlayField16[*si], 0x12);
920   goto loc_StopNoSplit;
921
922   // ==========================================================================
923   // BUG touching left to right
924   // ==========================================================================
925
926 loc_g_6588:
927   if (SgnHighByte(PlayField16[*si + 1]) >= 0)
928   {
929     ExplodeFieldSP(*si);                 // Explode
930
931     return;
932   }
933
934   PlayField16[*si + 1] = fiBase;
935   // ==========================================================================
936   // BASE touching left to right
937   // ==========================================================================
938
939 loc_g_6599:
940   subCopyImageToScreen(*si, aniMurphyTouchRight);
941   subSoundFXBase();
942   dx = aniFramesTouchBase;
943   dx1 = aniTouchBase;
944   dxPos = *si + 1;
945   MovHighByte(&PlayField16[*si], 0x13);
946   goto loc_StopNoSplit;
947
948   // ==========================================================================
949   // INFOTRON moving down to up
950   // ==========================================================================
951
952 loc_g_65C6:
953   subSoundFXInfotron();
954   dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
955   dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
956   PlayField16[*si - FieldWidth] = 0x903;
957   PlayField16[*si] = 0x300;
958   *si = *si - FieldWidth;
959   goto loc_StopNoSplit;
960
961   // ==========================================================================
962   // INFOTRON moving right to left
963   // ==========================================================================
964
965 loc_g_65FE:
966   subSoundFXInfotron();
967   dx = aniFramesEatInfotronLeft;
968   dx1 = aniEatInfotronLeft;
969 #if 0
970   dx2 = fiInfotron;
971   dx2Step = -1;
972   ClearPos = -1;
973 #endif
974   PlayField16[*si - 1] = 0xA03;
975   PlayField16[*si] = 0x300;
976   *si = *si - 1;
977   goto loc_StopNoSplit;
978
979   // ==========================================================================
980   // INFOTRON moving up to down
981   // ==========================================================================
982
983 loc_g_662A:
984   subSoundFXInfotron();
985   dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
986   dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
987   PlayField16[*si + FieldWidth] = 0xB03;
988   PlayField16[*si] = 0x300;
989   *si = *si + FieldWidth;
990   goto loc_StopNoSplit;
991
992   // ==========================================================================
993   // INFOTRON moving left to right
994   // ==========================================================================
995
996 loc_g_6662:
997   subSoundFXInfotron();
998   dx = aniFramesEatInfotronRight;
999   dx1 = aniEatInfotronRight;
1000 #if 0
1001   dx2 = fiInfotron;
1002   dx2Step = 1;
1003   ClearPos = -1;
1004 #endif
1005   PlayField16[*si + 1] = 0xC03;
1006   PlayField16[*si] = 0x300;
1007   *si = *si + 1;
1008   goto loc_StopNoSplit;
1009
1010   // ==========================================================================
1011   // INFOTRON touching down to up
1012   // ==========================================================================
1013
1014 loc_g_668E:
1015   subCopyImageToScreen(*si, aniMurphyTouchUp);
1016   subSoundFXInfotron();
1017   dx = aniFramesTouchInfotron;
1018   dx1 = aniTouchInfotron;
1019   MovHighByte(&PlayField16[*si], 0x14);
1020   MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
1021   goto loc_StopNoSplit;
1022
1023   // ==========================================================================
1024   // INFOTRON touching right to left
1025   // ==========================================================================
1026
1027 loc_g_66C0:
1028   subCopyImageToScreen(*si, aniMurphyTouchLeft);
1029   subSoundFXInfotron();
1030   dx = aniFramesTouchInfotron;
1031   dx1 = aniTouchInfotron;
1032   MovHighByte(&PlayField16[*si], 0x15);
1033   MovHighByte(&PlayField16[*si - 1], 0xFF);
1034   goto loc_StopNoSplit;
1035
1036   // ==========================================================================
1037   // INFOTRON touching up to down
1038   // ==========================================================================
1039
1040 loc_g_66F2:
1041   subCopyImageToScreen(*si, aniMurphyTouchDown);
1042   subSoundFXInfotron();
1043   dx = aniFramesTouchInfotron;
1044   dx1 = aniTouchInfotron;
1045   MovHighByte(&PlayField16[*si], 0x16);
1046   MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
1047   goto loc_StopNoSplit;
1048
1049   // ==========================================================================
1050   // INFOTRON touching left to right
1051   // ==========================================================================
1052
1053 loc_g_6724:
1054   subCopyImageToScreen(*si, aniMurphyTouchRight);
1055   subSoundFXInfotron();
1056   dx = aniFramesTouchInfotron;
1057   dx1 = aniTouchInfotron;
1058   MovHighByte(&PlayField16[*si], 0x17);
1059   MovHighByte(&PlayField16[*si + 1], 0xFF);
1060   goto loc_StopNoSplit;
1061
1062   // ==========================================================================
1063   // EXIT pressed from any direction
1064   // ==========================================================================
1065
1066 loc_g_6756:
1067   // FS
1068   ClearPos = -1;
1069   MurphyDX = 0;
1070   MurphyDY = 0;
1071   // end of FS
1072   if (LowByte(InfotronsNeeded) != 0)
1073     return;
1074
1075 #if 1
1076   if (!game_sp.LevelSolved)
1077     printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n",LevelNumber);
1078 #endif
1079
1080 #if 1
1081   game_sp.LevelSolved = TRUE;
1082 #endif
1083
1084   subSoundFXExit();
1085   data_h_DemoDone = 1; // EP set level success bytes
1086   LevelStatus = 1; // set Level Status DONE
1087   EP_GameDemoVar0DAA = 0; // force demo for lead-out
1088   if (SavedGameFlag == 0) // saved game running?
1089   {
1090     if (UpdateTimeFlag != 0)    // update time?
1091     {
1092       UpdatedFlag = 1; // prevent double update
1093       subUpdatePlayingTime();    // update playing time
1094     }
1095   }
1096
1097 #if 0
1098   subUpdateHallOfFame(); // update time + Hall-Of-Fame
1099 #endif
1100
1101   LeadOutCounter = 0x40;          // quit: start lead-out
1102   dx = aniFramesMurphyExit;
1103   dx1 = aniMurphyExit;
1104   MovHighByte(&PlayField16[*si], 0xD);
1105   goto loc_StopNoSplit;
1106
1107   // ==========================================================================
1108   // ZONK moving right to left
1109   // ==========================================================================
1110
1111 loc_g_679B:
1112   ax = PlayField16[*si - 2];
1113   if (ax != 0)
1114     return;
1115
1116   MovHighByte(&PlayField16[*si - 2], 1);
1117   subCopyImageToScreen(*si, aniPushLeft); // draw pushing murphy
1118   dx = aniFramesZonkRollLeft;
1119   dx1 = aniZonkRollLeft;
1120   dxPos = *si - 1;
1121   dx2 = aniPushLeft;
1122   dx2Step = 1;
1123   MovHighByte(&PlayField16[*si], 0xE);
1124   goto loc_MoveNoSplit;
1125
1126   // ==========================================================================
1127   // ZONK moving left to right
1128   // ==========================================================================
1129
1130 loc_g_67D4:
1131   ax = PlayField16[*si + 2];
1132   if (ax != 0)
1133     return;
1134
1135   ax = PlayField16[*si + FieldWidth + 1];
1136   if (ax == 0) // zonk falls
1137     return;
1138
1139   MovHighByte(&PlayField16[*si + 2], 1);
1140   subCopyImageToScreen(*si, aniPushRight); // draw pushing murphy
1141   dx = aniFramesZonkRollRight;
1142   dx1 = aniZonkRollRight;
1143   dxPos = *si + 1;
1144   dx2 = aniPushRight;
1145   dx2Step = -1;
1146   MovHighByte(&PlayField16[*si], 0xF);
1147   goto loc_MoveNoSplit;
1148
1149   // ==========================================================================
1150   // TERMINAL moving/touching down to up
1151   // ==========================================================================
1152
1153 loc_g_6817:
1154   subCopyImageToScreen(*si, aniMurphyTouchUp);
1155   if (YellowDisksExploded != 0)
1156   {
1157     YawnSleepCounter = 40; // stay hypnotized
1158
1159     return;
1160   } // loc_g_6838:
1161
1162 #if 1
1163   // draw new terminal type
1164 #if 1
1165   GfxGraphic[GetX(*si - FieldWidth)][GetY(*si - FieldWidth)] = aniTerminalActive;
1166 #else
1167   subCopyImageToScreen(*si - FieldWidth, aniTerminalActive);
1168 #endif
1169 #else
1170   subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1171 #endif
1172   TerminalState[*si - FieldWidth] = 8;
1173   goto loc_g_68F0;
1174
1175   // ==========================================================================
1176   // TERMINAL moving/touching right to left
1177   // ==========================================================================
1178
1179 loc_g_684E:
1180   subCopyImageToScreen(*si, aniMurphyTouchLeft);
1181   if (YellowDisksExploded != 0)
1182   {
1183     YawnSleepCounter = 40; // stay hypnotized
1184
1185     return;
1186   } // loc_g_6838:
1187
1188 #if 1
1189   // draw new terminal type
1190 #if 1
1191   GfxGraphic[GetX(*si - 1)][GetY(*si - 1)] = aniTerminalActive;
1192 #else
1193   subCopyImageToScreen(*si - 1, aniTerminalActive);
1194 #endif
1195 #else
1196   subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1197 #endif
1198   TerminalState[*si - 1] = 8;
1199   goto loc_g_68F0;
1200
1201   // ==========================================================================
1202   // TERMINAL moving/touching up to down
1203   // ==========================================================================
1204
1205 loc_g_6884:
1206   subCopyImageToScreen(*si, aniMurphyTouchDown);
1207   if (YellowDisksExploded != 0)
1208   {
1209     YawnSleepCounter = 40; // stay hypnotized
1210
1211     return;
1212   } // loc_g_6838:
1213
1214 #if 1
1215   // draw new terminal type
1216 #if 1
1217   GfxGraphic[GetX(*si + FieldWidth)][GetY(*si + FieldWidth)] = aniTerminalActive;
1218 #else
1219   subCopyImageToScreen(*si + FieldWidth, aniTerminalActive);
1220 #endif
1221 #else
1222   subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1223 #endif
1224   TerminalState[*si + FieldWidth] = 8;
1225   goto loc_g_68F0;
1226
1227   // ==========================================================================
1228   // TERMINAL moving/touching left to right
1229   // ==========================================================================
1230
1231 loc_g_68BA:
1232   subCopyImageToScreen(*si, aniMurphyTouchRight);
1233   if (YellowDisksExploded != 0)
1234   {
1235     YawnSleepCounter = 40; // stay hypnotized
1236
1237     return;
1238   } // loc_g_6838:
1239
1240 #if 1
1241   // draw new terminal type
1242 #if 1
1243   GfxGraphic[GetX(*si + 1)][GetY(*si + 1)] = aniTerminalActive;
1244 #else
1245   subCopyImageToScreen(*si + 1, aniTerminalActive);
1246 #endif
1247 #else
1248   subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1249 #endif
1250   TerminalState[*si + 1] = 8;
1251   // ==========================================================================
1252   // common TERMINAL stuff moving/touching from all directions
1253   // ==========================================================================
1254
1255 loc_g_68F0:
1256   TerminalMaxCycles = 7;
1257   YellowDisksExploded = 1;
1258   for (i = 0; i <= LevelMax; i++)
1259   {
1260     if (PlayField16[i] == fiYellowDisk)
1261       ExplodeFieldSP (i);
1262   }
1263
1264   return;
1265
1266   // ==========================================================================
1267   // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1268   // ==========================================================================
1269
1270 loc_g_6916:
1271   if (PlayField16[*si - 2 * FieldWidth] != 0)
1272     return;
1273
1274   dx = aniFramesSplitUpDown;
1275   dx1 = aniSplitUpDown;
1276   dx2Step = -FieldWidth;
1277   PlayField16[*si] = 0x1803;
1278   PlayField16[*si - 2 * FieldWidth] = 0x300;
1279   goto loc_StopSplit;
1280
1281   // ==========================================================================
1282   // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1283   // ==========================================================================
1284
1285 loc_g_693A:
1286   if (PlayField16[*si - 2] != 0)
1287     return;
1288
1289   dx = aniFramesMurphyEatLeft;
1290   dx1 = aniMurphyMoveLeft;
1291   dx2Step = -1;
1292   PlayField16[*si] = 0x1903;
1293   PlayField16[*si - 2] = 0x300;
1294   goto loc_StopSplit;
1295
1296   // ==========================================================================
1297   // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1298   // ==========================================================================
1299
1300 loc_g_695E:
1301   if (PlayField16[*si + 2 * FieldWidth] != 0)
1302     return;
1303
1304   dx = aniFramesSplitUpDown;
1305   dx1 = aniSplitUpDown;
1306   dx2Step = FieldWidth;
1307   PlayField16[*si] = 0x1A03;
1308   PlayField16[*si + 2 * FieldWidth] = 0x300;
1309   goto loc_StopSplit;
1310
1311   // ==========================================================================
1312   // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1313   // ==========================================================================
1314
1315 loc_g_6982:
1316   if (PlayField16[*si + 2] != 0)
1317     return;
1318
1319   dx = aniFramesMurphyEatRight;
1320   dx1 = aniMurphyMoveRight;
1321   dx2Step = 1;
1322   PlayField16[*si] = 0x1B03;
1323   PlayField16[*si + 2] = 0x300;
1324
1325 loc_StopSplit:
1326   MovingPictureSequencePhase = 0; // stop picture move sequence
1327   SplitMoveFlag = 1; // port: split movement
1328   goto loc_Split;
1329
1330   // ==========================================================================
1331   // RED DISK moving down to up
1332   // ==========================================================================
1333
1334 loc_g_69A6:
1335   dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
1336   dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1337   PlayField16[*si] = 0x1C03;
1338   PlayField16[*si - FieldWidth] = 0x300;
1339   goto loc_StopNoSplit;
1340
1341   // ==========================================================================
1342   // RED DISK moving right to left
1343   // ==========================================================================
1344
1345 loc_g_69CE:
1346   dx = aniFramesMurphyEatLeft;
1347   dx1 = aniMurphyEatLeft;
1348   PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1349   PlayField16[*si - 1] = 0x1D03;
1350   *si = *si - 1;
1351   goto loc_StopNoSplit;
1352
1353   // ==========================================================================
1354   // RED DISK moving up to down
1355   // ==========================================================================
1356
1357 loc_g_69F7:
1358   dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
1359   dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1360   PlayField16[*si] = 0x1E03;
1361   PlayField16[*si + FieldWidth] = 0x300;
1362   goto loc_StopNoSplit;
1363
1364   // ==========================================================================
1365   // RED DISK moving left to right
1366   // ==========================================================================
1367
1368 loc_g_6A1F:
1369   //  dx = aniFramesMurphyEatRightRedDisk 'this sequence is 9 steps long!
1370   dx = aniFramesMurphyEatRight;
1371   dx1 = aniMurphyEatRight;
1372   // --------------------------------------------------------------------------
1373   // BugFix
1374   // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1375   // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1376   // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1377   // We may not fix the table, because then the timing of the game changes
1378   // and several existing demo's do not run properly anymore.
1379   // We only correct Murphies x-location here, when the sequence starts.
1380   // Remember that this is not the real bug-fix, but we must live with
1381   // this existing bug and correct for the consequences of it.
1382
1383 #if 1
1384   if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1385     MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1386 #else
1387   if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1388     MurphyScreenXPos = MurphyScreenXPos - 2;
1389 #endif
1390
1391   SeqPos = -1;
1392   // FS: for me this means to blit the first animation frame twice
1393   // end of BugFix
1394   // --------------------------------------------------------------------------
1395   PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1396   PlayField16[*si + 1] = 0x1F03;
1397   *si = *si + 1;
1398   goto loc_StopNoSplit;
1399
1400   // ==========================================================================
1401   // RED DISK touching down to up
1402   // ==========================================================================
1403
1404 loc_g_6A48:
1405   dx = aniFramesTouchRedDisk;
1406   dx1 = aniTouchRedDisk;
1407   MovHighByte(&PlayField16[*si], 0x20);
1408   MovHighByte(&PlayField16[*si - FieldWidth], 3);
1409   goto loc_StopNoSplit;
1410
1411   // ==========================================================================
1412   // RED DISK touching right to left
1413   // ==========================================================================
1414
1415 loc_g_6A64:
1416   dx = aniFramesTouchRedDisk;
1417   dx1 = aniTouchRedDisk;
1418   MovHighByte(&PlayField16[*si], 0x21);
1419   MovHighByte(&PlayField16[*si - 1], 3);
1420   goto loc_StopNoSplit;
1421
1422   // ==========================================================================
1423   // RED DISK touching up to down
1424   // ==========================================================================
1425
1426 loc_g_6A80:
1427   dx = aniFramesTouchRedDisk;
1428   dx1 = aniTouchRedDisk;
1429   MovHighByte(&PlayField16[*si], 0x22);
1430   MovHighByte(&PlayField16[*si + FieldWidth], 3);
1431   goto loc_StopNoSplit;
1432
1433   // ==========================================================================
1434   // RED DISK touching left to right
1435   // ==========================================================================
1436
1437 loc_g_6A9C:
1438   dx = aniFramesTouchRedDisk;
1439   dx1 = aniTouchRedDisk;
1440   MovHighByte(&PlayField16[*si], 0x23);
1441   MovHighByte(&PlayField16[*si + 1], 3);
1442
1443 loc_StopNoSplit:
1444   MovingPictureSequencePhase = 0; // stop picture move sequence
1445   goto loc_NoSplit;
1446
1447   // ==========================================================================
1448   // YELLOW DISK moving down to up
1449   // ==========================================================================
1450
1451 loc_g_6AB8:
1452   if (PlayField16[*si - 2 * FieldWidth] != 0)
1453     return;
1454
1455   PlayField16[*si - 2 * FieldWidth] = 0x1200;
1456 #if 0
1457   subCopyImageToScreen(*si, aniPushRight);
1458 #endif
1459   dx = aniFramesYellowDisk;
1460   dx1 = aniYellowDisk;
1461   dxPos = *si - FieldWidth;
1462 #if 1
1463   dx2 = (MurphyVarFaceLeft == 0 ? aniPushRight : aniPushLeft);
1464 #else
1465   dx2 = aniPushUpDown;
1466 #endif
1467   dx2Step = FieldWidth;
1468   PlayField16[*si] = 0x2403;
1469 #if 1
1470   subCopyImageToScreen(*si, dx2);
1471 #endif
1472   goto loc_MoveNoSplit;
1473
1474   // ==========================================================================
1475   // YELLOW DISK moving right to left
1476   // ==========================================================================
1477
1478 loc_g_6AF1:
1479   if (PlayField16[*si - 2] != 0)
1480     return;
1481
1482   PlayField16[*si - 2] = 0x1200;
1483   subCopyImageToScreen(*si, aniPushLeft);
1484   dx = aniFramesYellowDisk;
1485   dx1 = aniYellowDisk;
1486   dxPos = *si - 1;
1487   dx2 = aniPushLeft;
1488   dx2Step = 1;
1489   PlayField16[*si] = 0x2503;
1490   goto loc_MoveNoSplit;
1491
1492   // ==========================================================================
1493   // YELLOW DISK moving up to down
1494   // ==========================================================================
1495
1496 loc_g_6B2A:
1497   if (PlayField16[*si + 2 * FieldWidth] != 0)
1498     return;
1499
1500   PlayField16[*si + 2 * FieldWidth] = 0x1200;
1501 #if 0
1502   subCopyImageToScreen(*si, aniPushRight);
1503 #endif
1504   dx = aniFramesYellowDisk;
1505   dx1 = aniYellowDisk;
1506   dxPos = *si + FieldWidth;
1507 #if 1
1508   dx2 = (MurphyVarFaceLeft == 0 ? aniPushRight : aniPushLeft);
1509 #else
1510   dx2 = aniPushUpDown;
1511 #endif
1512   dx2Step = -FieldWidth;
1513   PlayField16[*si] = 0x2703;
1514 #if 1
1515   subCopyImageToScreen(*si, dx2);
1516 #endif
1517   goto loc_MoveNoSplit;
1518
1519   // ==========================================================================
1520   // YELLOW DISK moving left to right
1521   // ==========================================================================
1522
1523 loc_g_6B63:
1524   if (PlayField16[*si + 2] != 0)
1525     return;
1526
1527   PlayField16[*si + 2] = 0x1200;
1528   subCopyImageToScreen(*si, aniPushRight);
1529   dx = aniFramesYellowDisk;
1530   dx1 = aniYellowDisk;
1531   dxPos = *si + 1;
1532   dx2 = aniPushRight;
1533   dx2Step = -1;
1534   PlayField16[*si] = 0x2603;
1535   goto loc_MoveNoSplit;
1536
1537   // ==========================================================================
1538   // ORANGE DISK moving right to left
1539   // ==========================================================================
1540
1541 loc_g_6B9B:
1542   if (PlayField16[*si - 2] != 0)
1543     return;
1544
1545   PlayField16[*si - 2] = 0x800;
1546   subCopyImageToScreen(*si, aniPushLeft);
1547   dx = aniFramesOrangeDisk;
1548   dx1 = aniOrangeDisk;
1549   dxPos = *si - 1;
1550   dx2 = aniPushLeft;
1551   dx2Step = 1;
1552   PlayField16[*si] = 0x2803;
1553   goto loc_MoveNoSplit;
1554
1555   // ==========================================================================
1556   // ORANGE DISK moving left to right
1557   // ==========================================================================
1558
1559 loc_g_6BD3:
1560   if (PlayField16[*si + 2] != 0)
1561     return;
1562
1563   if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1564     return;
1565
1566   PlayField16[*si + 2] = 0x100;
1567   subCopyImageToScreen(*si, aniPushRight);
1568   dx = aniFramesOrangeDisk;
1569   dx1 = aniOrangeDisk;
1570   dxPos = *si + 1;
1571   dx2 = aniPushRight;
1572   dx2Step = -1;
1573   PlayField16[*si] = 0x2903;
1574   // ==========================================================================
1575   // Copy screen animation action table to action work space
1576   // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1577   // ==========================================================================
1578
1579 loc_MoveNoSplit:
1580   MovingPictureSequencePhase = 8; // init picture move sequence
1581
1582 loc_NoSplit:
1583   SplitMoveFlag = 0; // no port: no split movement
1584
1585 loc_Split:
1586   //  copy/store global move sequence info????????????????????????????????????
1587   //  ... dont think so ...(FS)
1588   // ==========================================================================
1589   // Proceed with all movements
1590   // ==========================================================================
1591
1592 locProceedMovingMurphy: // proceed moving murphy
1593   YawnSleepCounter = 0; // Wake up sleeping Murphy
1594   ax = MovingPictureSequencePhase;            // sequence busy?
1595   if (ax == 0)             // no -- start sequence!
1596     goto loc_g_6C8F;
1597
1598   ax = ax - 1;   // next picture of sequence
1599   MovingPictureSequencePhase = ax;            // store for later
1600   if (ax == 0) // Sound effects
1601     subSoundFXPush();
1602
1603   bl = HighByte(PlayField16[*si]);
1604   if (bl == 0xE)        // Push Zonk to left
1605     goto loc_g_6F7E;
1606
1607   if (bl == 0xF)        // Push Zonk to right
1608     goto loc_g_6FBC;
1609
1610   if (bl == 0x28)       // Push orange disk to left
1611     goto loc_g_6FFA;
1612
1613   if (bl == 0x29)       // Push orange disk to right
1614     goto loc_g_7038;
1615
1616   if (bl == 0x24)       // Push yellow disk up
1617     goto loc_g_7076;
1618
1619   if (bl == 0x25)       // Push yellow disk to left
1620     goto loc_g_70B4;
1621
1622   if (bl == 0x27)       // Push yellow disk down
1623     goto loc_g_70F2;
1624
1625   if (bl == 0x26)       // Push yellow disk to right
1626     goto loc_g_7130;
1627
1628   if (bl == 0x2A)       // Red disk release timer
1629     goto loc_g_716E;
1630
1631   return;
1632
1633   // ==========================================================================
1634   // Paint frame of MOVING.DAT sequence
1635   // ==========================================================================
1636
1637 loc_g_6C8F:
1638
1639 #if 1
1640   if (SeqPos <= 0)
1641     dx1SequenceLength = getSequenceLength(dx1);
1642 #endif
1643
1644   if (SplitMoveFlag == 0)
1645   {
1646     // ++++++++++++++++++++++++++
1647     // Begin of normal movement
1648 #if 1
1649     MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1650     MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1651 #else
1652     MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1653     MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1654 #endif
1655
1656
1657 #if 0
1658   printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1659          TimerVar,
1660          DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1661          (DemoKeyCode == keyNone        ? "(none)"              :
1662           DemoKeyCode == keyLeft        ? "left"                :
1663           DemoKeyCode == keyRight       ? "right"               :
1664           DemoKeyCode == keyUp          ? "up"                  :
1665           DemoKeyCode == keyDown        ? "down"                :
1666           DemoKeyCode == keySpace       ? "space"               :
1667           DemoKeyCode == keySpaceLeft   ? "space + left"        :
1668           DemoKeyCode == keySpaceRight  ? "space + right"       :
1669           DemoKeyCode == keySpaceUp     ? "space + up"          :
1670           DemoKeyCode == keySpaceDown   ? "space + down"        : "(unknown)"),
1671          DemoKeyCode,
1672          MurphyScreenXPos, MurphyScreenYPos,
1673          MurphyPosIndex % 60, MurphyPosIndex / 60,
1674          ClearPos);
1675 #endif
1676
1677 #if 0
1678   Delay(500);
1679 #endif
1680
1681 #if 1
1682     if (!(ClearPos < 0)) // clear field that murphy is leaving
1683       subCopyImageToScreen(ClearPos, aniSpace);
1684 #else
1685     if (! ClearPos < 0) // clear field that murphy is leaving
1686       subCopyFieldToScreen(ClearPos, 0);
1687 #endif
1688
1689 #if 0
1690     printf("::: ---------------> %d, %d [%d, %d]\n",
1691            MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1692 #endif
1693
1694 #if 0
1695     // !!! special two-tile animation currently not used !!!
1696     if (dx2 == fiInfotron) // special case of infotron moving left or right
1697     {
1698       tDeltaX = 0;
1699       tDeltaY = 0;
1700     }
1701     else
1702 #endif
1703     {
1704       tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1705       tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1706     }
1707
1708     X = GetStretchX(dxPos) + tDeltaX;
1709     Y = GetStretchY(dxPos) + tDeltaY;
1710     Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1711
1712 #if 1
1713     if (isSnappingSequence(dx1) && SeqPos == dx1SequenceLength - 1)
1714       dx1 = aniSpace;
1715 #endif
1716
1717 #if 1
1718     StretchedSprites.BltImg(X, Y, dx1, Tmp);
1719     GfxGraphic[GetX(*si)][GetY(*si)] = -1;      // (Murphy's position)
1720     GfxGraphic[GetX(dxPos)][GetY(dxPos)] = -1;  // (snapping position)
1721     // printf("::: Tmp: %d\n", Tmp);
1722 #else
1723     StretchedSprites.BltEx(X, Y, dx[Tmp]);
1724 #endif
1725
1726 #if 1
1727     if (!(dx2 < 0))
1728 #else
1729     if (! dx2 < 0)
1730 #endif
1731     {
1732       tPos = dxPos + dx2Step;
1733       X = GetStretchX(tPos);
1734       Y = GetStretchY(tPos);
1735 #if 0
1736     // !!! special two-tile animation currently not used !!!
1737       if (dx2 == fiInfotron) // special case of infotron moving left or right
1738       {
1739         StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1740       }
1741       else // pushing something
1742 #endif
1743       {
1744 #if 1
1745         // (SeqPos iterates from 0 to 7 while pushing)
1746         StretchedSprites.BltImg(X + tDeltaX, Y + tDeltaY, dx2, SeqPos);
1747         // printf("::: SeqPos: %d\n", SeqPos);
1748 #else
1749         StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1750 #endif
1751       }
1752     }
1753
1754     // End of normal movement
1755     // ------------------------
1756   }
1757   else
1758   {
1759     // ++++++++++++++++++++++++++++++++
1760     // Begin of split movement (port)
1761 #if 1
1762     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1763     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1764 #else
1765     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1766     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1767 #endif
1768     subCopyImageToScreen(ClearPos, aniSpace); // clear the field that murphy leaves
1769     tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1770     tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1771     X = GetStretchX(dxPos) + tDeltaX;
1772     Y = GetStretchY(dxPos) + tDeltaY;
1773 #if 1
1774     StretchedSprites.BltImg(X, Y, dx1, SeqPos); // plot first murphy
1775 #else
1776     StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1777 #endif
1778     tPos = dxPos + dx2Step;
1779     X = GetStretchX(tPos);
1780     Y = GetStretchY(tPos);
1781 #if 1
1782     StretchedSprites.BltImg(X + tDeltaX, Y + tDeltaY, dx1, SeqPos); // plot second murphy
1783     StretchedSprites.BltImg(X, Y, fiGraphic[LowByte(PlayField16[tPos])], 0); // replot the port on top
1784 #else
1785     StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1786     StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1787 #endif
1788     // End of split movement (port)
1789     // ------------------------------
1790   } // loc_g_6D1E:'loc_g_6D28:
1791
1792   SeqPos = SeqPos + 1;
1793 #if 1
1794   if (SeqPos < dx1SequenceLength)
1795     return;
1796 #else
1797   if (dx[SeqPos] > -1)
1798     return;
1799 #endif
1800
1801   // Follow-up after movement completed     'loc_g_6D35:
1802   MurphyXPos = MurphyXPos + MurphyDX;
1803   MurphyYPos = MurphyYPos + MurphyDY;
1804   bl = HighByte(PlayField16[*si]);  // animation phase
1805   MovHighByte(&PlayField16[*si], 0);
1806
1807   if (bl == 0x1)    // space, moving up
1808     goto loc_g_6EC8;
1809
1810   if (bl == 0x2)    // space, moving left
1811     goto loc_g_6EE6;
1812
1813   if (bl == 0x3)    // space, moving down
1814     goto loc_g_6F04;
1815
1816   if (bl == 0x4)    // space, moving right
1817     goto loc_g_71C4;
1818
1819   if (bl == 0x5)    // base , moving up
1820     goto loc_g_6EC8;
1821
1822   if (bl == 0x6)    // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1823     goto loc_g_6EE6;
1824
1825   if (bl == 0x7)    // base , moving down
1826     goto loc_g_6F04;
1827
1828   if (bl == 0x8)    // base , moving right
1829     goto loc_g_71C4;
1830
1831   if (bl == 0x9)    // infotron, moving up
1832     goto loc_g_6EBA;
1833
1834   if (bl == 0xA)      // infotron, moving left
1835     goto loc_g_6ED8;
1836
1837   if (bl == 0xB)    // infotron, moving down
1838     goto loc_g_6EF6;
1839
1840   if (bl == 0xC)      // infotron, moving right
1841     goto loc_g_71B6;
1842
1843   if (bl == 0xD)      // exit
1844     goto loc_g_6F77;
1845
1846   if (bl == 0xE)      // zonk, pushing left
1847     goto loc_g_6F18;
1848
1849   if (bl == 0xF)      // zonk, pushing right
1850     goto loc_g_6F3B;
1851
1852   if (bl == 0x10)   // base , touching up
1853     goto loc_g_71E2;
1854
1855   if (bl == 0x11)   // base , touching left
1856     goto loc_g_71FE;
1857
1858   if (bl == 0x12)   // base , touching down
1859     goto loc_g_721A;
1860
1861   if (bl == 0x13)   // base , touching right
1862     goto loc_g_7236;
1863
1864   if (bl == 0x14)   // infotron touching up
1865     goto loc_g_71D4;
1866
1867   if (bl == 0x15)   // infotron touching left
1868     goto loc_g_71F0;
1869
1870   if (bl == 0x16)   // infotron touching down
1871     goto loc_g_720C;
1872
1873   if (bl == 0x17)   // infotron touching right
1874     goto loc_g_7228;
1875
1876   if (bl == 0x18)     // port up
1877     goto loc_g_7244;
1878
1879   if (bl == 0x19)     // port left
1880     goto loc_g_7272;
1881
1882   if (bl == 0x1A)     // port down
1883     goto loc_g_729F;
1884
1885   if (bl == 0x1B)     // port right
1886     goto loc_g_72CD;
1887
1888   if (bl == 0x1C)   // red disk, moving up
1889     goto loc_g_72FA;
1890
1891   if (bl == 0x1D)   // red disk, moving left
1892     goto loc_g_7318;
1893
1894   if (bl == 0x1E)   // red disk, moving down
1895     goto loc_g_7333;
1896
1897   if (bl == 0x1F)   // red disk, moving right -> 9-Step-Bug!
1898     goto loc_g_7351;
1899
1900   if (bl == 0x20)   // red disk, touching up
1901     goto loc_g_736C;
1902
1903   if (bl == 0x21)   // red disk, touching left
1904     goto loc_g_7381;
1905
1906   if (bl == 0x22)   // red disk, touching down
1907     goto loc_g_7396;
1908
1909   if (bl == 0x23)   // red disk, touching right
1910     goto loc_g_73AB;
1911
1912   if (bl == 0x24)     // yellow disk, pushing up
1913     goto loc_g_73C0;
1914
1915   if (bl == 0x25)     // yellow disk, pushing left
1916     goto loc_g_73DD;
1917
1918   if (bl == 0x26)     // yellow disk, pushing right -> order of "down" exchanged with "right"!
1919     goto loc_g_7417;
1920
1921   if (bl == 0x27)     // yellow disk, pushing down  -> order of "down" exchanged with "right"!
1922     goto loc_g_73FA;
1923
1924   if (bl == 0x28)     // orange disk, pushing left
1925     goto loc_g_7434;
1926
1927   if (bl == 0x29)     // orange disk, pushing right
1928     goto loc_g_7451;
1929
1930   if (bl == 0x2A)   // red disk, release
1931     goto loc_g_747F;
1932
1933   ExitToMenuFlag = 1;
1934
1935   return;
1936
1937   // ==========================================================================
1938   //                       infotron, moving up
1939   // ==========================================================================
1940
1941 loc_g_6EBA:
1942   if (0 < LowByte(InfotronsNeeded))
1943     InfotronsNeeded = InfotronsNeeded - 1;
1944
1945   subDisplayInfotronsNeeded();
1946 loc_g_6EC8: // space, base
1947   PlayField16[*si] = fiMurphy;
1948   subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1949
1950   return;
1951
1952   // ==========================================================================
1953   //                       infotron, moving left
1954   // ==========================================================================
1955
1956 loc_g_6ED8:
1957   if (0 < LowByte(InfotronsNeeded))
1958     InfotronsNeeded = InfotronsNeeded - 1;
1959
1960   subDisplayInfotronsNeeded();
1961 loc_g_6EE6: // space, base
1962   PlayField16[*si] = fiMurphy;
1963   subAdjustZonksInfotronsAboveMurphy(*si + 1);
1964
1965   return;
1966
1967   // ==========================================================================
1968   //                       infotron, moving down
1969   // ==========================================================================
1970
1971 loc_g_6EF6:
1972   if (0 < LowByte(InfotronsNeeded))
1973     InfotronsNeeded = InfotronsNeeded - 1;
1974
1975   subDisplayInfotronsNeeded();
1976 loc_g_6F04: // space, base
1977   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1978     PlayField16[*si - FieldWidth] = 0;
1979
1980   PlayField16[*si] = fiMurphy;
1981
1982   return;
1983
1984   // ==========================================================================
1985   //                       infotron, moving right
1986   // ==========================================================================
1987
1988 loc_g_71B6:
1989   if (0 < LowByte(InfotronsNeeded))
1990     InfotronsNeeded = InfotronsNeeded - 1;
1991
1992   subDisplayInfotronsNeeded();
1993 loc_g_71C4: // space, base
1994   subAdjustZonksInfotronsAboveMurphy(*si - 1);
1995   PlayField16[*si] = fiMurphy;
1996
1997   return;
1998
1999   // ==========================================================================
2000   //                       infotron, touching up
2001   // ==========================================================================
2002
2003 loc_g_71D4:
2004   if (0 < LowByte(InfotronsNeeded))
2005     InfotronsNeeded = InfotronsNeeded - 1;
2006
2007   subDisplayInfotronsNeeded();
2008 loc_g_71E2: // base
2009   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2010     PlayField16[*si - FieldWidth] = 0;
2011
2012   return;
2013
2014   // ==========================================================================
2015   //                       infotron, touching left
2016   // ==========================================================================
2017
2018 loc_g_71F0:
2019   if (0 < LowByte(InfotronsNeeded))
2020     InfotronsNeeded = InfotronsNeeded - 1;
2021
2022   subDisplayInfotronsNeeded();
2023 loc_g_71FE: // base
2024   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2025     PlayField16[*si - 1] = 0;
2026
2027   return;
2028
2029   // ==========================================================================
2030   //                       infotron, touching down
2031   // ==========================================================================
2032
2033 loc_g_720C:
2034   if (0 < LowByte(InfotronsNeeded))
2035     InfotronsNeeded = InfotronsNeeded - 1;
2036
2037   subDisplayInfotronsNeeded();
2038 loc_g_721A: // base
2039   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2040     PlayField16[*si + FieldWidth] = 0;
2041
2042   return;
2043
2044   // ==========================================================================
2045   //                       infotron, touching right
2046   // ==========================================================================
2047
2048 loc_g_7228:
2049   if (0 < LowByte(InfotronsNeeded))
2050     InfotronsNeeded = InfotronsNeeded - 1;
2051
2052   subDisplayInfotronsNeeded();
2053 loc_g_7236: // base
2054   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2055     PlayField16[*si + 1] = 0;
2056
2057   return;
2058
2059   // ==========================================================================
2060   //                       zonk, pushing left
2061   // ==========================================================================
2062
2063 loc_g_6F18:
2064   if (LowByte(PlayField16[*si]) != fiExplosion)
2065     PlayField16[*si] = 0;
2066
2067   PlayField16[*si - 1] = fiMurphy;
2068   PlayField16[*si - 2] = fiZonk;
2069   subExplodeSnikSnaksBelow(*si - 2);
2070   *si = *si - 1;
2071
2072   return;
2073
2074   // ==========================================================================
2075   //                       zonk, pushing right
2076   // ==========================================================================
2077
2078 loc_g_6F3B:
2079   if (LowByte(PlayField16[*si]) != fiExplosion)
2080     PlayField16[*si] = 0;
2081
2082   PlayField16[*si + 1] = fiMurphy;
2083   PlayField16[*si + 2] = fiZonk;
2084   subExplodeSnikSnaksBelow(*si + 2);
2085   *si = *si + 1;
2086
2087   return;
2088
2089   // ==========================================================================
2090   //                       exit
2091   // ==========================================================================
2092
2093 loc_g_6F77:
2094   ExitToMenuFlag = 1;
2095
2096 #if 1
2097   PlayField16[*si] = fiSpace;   // remove Murphy from playfield after exiting
2098 #endif
2099
2100   return;
2101
2102   // ==========================================================================
2103   //               Push Zonk from right to left
2104   // ==========================================================================
2105
2106 loc_g_6F7E:
2107   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
2108     return;
2109
2110   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
2111   PlayField16[*si - 1] = fiZonk;
2112   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2113     PlayField16[*si - 2] = 0;
2114
2115   subCopyImageToScreen(*si, aniMurphy);
2116
2117   return;
2118
2119   // ==========================================================================
2120   //                       Push Zonk from left to right
2121   // ==========================================================================
2122
2123 loc_g_6FBC:
2124   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
2125     return;
2126
2127   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
2128   PlayField16[*si + 1] = fiZonk;
2129   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2130     PlayField16[*si + 2] = 0;
2131
2132   subCopyImageToScreen(*si, aniMurphy);
2133
2134   return;
2135
2136   // ==========================================================================
2137   //               Push orange disk from right to left
2138   // ==========================================================================
2139
2140 loc_g_6FFA:
2141   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
2142     return;
2143
2144   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2145   PlayField16[*si - 1] = fiOrangeDisk;
2146   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2147     PlayField16[*si - 2] = 0;
2148
2149   subCopyImageToScreen(*si, aniMurphy);
2150
2151   return;
2152
2153   // ==========================================================================
2154   //               Push orange disk from left to right
2155   // ==========================================================================
2156
2157 loc_g_7038:
2158   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
2159     return;
2160
2161   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2162   PlayField16[*si + 1] = fiOrangeDisk;
2163   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2164     PlayField16[*si + 2] = 0;
2165
2166   subCopyImageToScreen(*si, aniMurphy);
2167
2168   return;
2169
2170   // ==========================================================================
2171   //               Push yellow disk from down to up
2172   // ==========================================================================
2173
2174 loc_g_7076:
2175   if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
2176     return;
2177
2178   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2179   PlayField16[*si - FieldWidth] = fiYellowDisk;
2180   if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
2181     PlayField16[*si - 2 * FieldWidth] = 0;
2182
2183   subCopyImageToScreen(*si, aniMurphy);
2184
2185   return;
2186
2187   // ==========================================================================
2188   //               Push yellow disk from right to left
2189   // ==========================================================================
2190
2191 loc_g_70B4:
2192   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
2193     return;
2194
2195   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2196   PlayField16[*si - 1] = fiYellowDisk;
2197   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2198     PlayField16[*si - 2] = 0;
2199
2200   subCopyImageToScreen(*si, aniMurphy);
2201
2202   return;
2203
2204   // ==========================================================================
2205   //               Push yellow disk from up to down
2206   // ==========================================================================
2207
2208 loc_g_70F2:
2209   if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
2210     return;
2211
2212   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2213   PlayField16[*si + FieldWidth] = fiYellowDisk;
2214   if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
2215     PlayField16[*si + 2 * FieldWidth] = 0;
2216
2217   subCopyImageToScreen(*si, aniMurphy);
2218
2219   return;
2220
2221   // ==========================================================================
2222   //               Push yellow disk from left to right
2223   // ==========================================================================
2224
2225 loc_g_7130:
2226   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
2227     return;
2228
2229   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2230   PlayField16[*si + 1] = fiYellowDisk;
2231   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2232     PlayField16[*si + 2] = 0;
2233
2234   subCopyImageToScreen(*si, aniMurphy);
2235
2236   return;
2237
2238   // ==========================================================================
2239   //               time red disk release (space)
2240   // ==========================================================================
2241
2242 loc_g_716E:
2243   if (DemoKeyCode != keySpace)
2244   {
2245     PlayField16[*si] = fiMurphy;
2246     subCopyImageToScreen(*si, aniMurphy);
2247     RedDiskReleasePhase = 0;
2248   }
2249   else if (MovingPictureSequencePhase == 0x20)
2250   {
2251 #if 1
2252     // anxious murphy, dropping red disk
2253     subCopyImageToScreen(*si, aniMurphyDropping);
2254 #else
2255     subCopyFieldToScreen(*si, 43);  // anxious murphy
2256 #endif
2257     RedDiskReleasePhase = 1;
2258   }
2259
2260   return;
2261
2262   // ==========================================================================
2263   // Special port down to up
2264   // ==========================================================================
2265
2266 loc_g_7244:
2267   if (LowByte(PlayField16[*si]) != fiExplosion)
2268     PlayField16[*si] = 0;
2269
2270   PlayField16[*si - 2 * FieldWidth] = fiMurphy;
2271   SplitMoveFlag = 0;
2272   *si = *si - FieldWidth;
2273   if (HighByte(PlayField16[*si]) == 1)
2274     subSpPortTest(*si);
2275
2276   *si = *si - FieldWidth;
2277
2278   return;
2279
2280   // ==========================================================================
2281   // Special port right to left
2282   // ==========================================================================
2283
2284 loc_g_7272:
2285   if (LowByte(PlayField16[*si]) != fiExplosion)
2286     PlayField16[*si] = 0;
2287
2288   PlayField16[*si - 2] = fiMurphy;
2289   SplitMoveFlag = 0;
2290   *si = *si - 1;
2291   if (HighByte(PlayField16[*si]) == 1)
2292     subSpPortTest(*si);
2293
2294   *si = *si - 1;
2295
2296   return;
2297
2298   // ==========================================================================
2299   // Special port up to down
2300   // ==========================================================================
2301
2302 loc_g_729F:
2303   if (LowByte(PlayField16[*si]) != fiExplosion)
2304     PlayField16[*si] = 0;
2305
2306   PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2307   SplitMoveFlag = 0;
2308   *si = *si + FieldWidth;
2309   if (HighByte(PlayField16[*si]) == 1)
2310     subSpPortTest(*si);
2311
2312   *si = *si + FieldWidth;
2313
2314   return;
2315
2316   // ==========================================================================
2317   // Special port left to right
2318   // ==========================================================================
2319
2320 loc_g_72CD:
2321   if (LowByte(PlayField16[*si]) != fiExplosion)
2322     PlayField16[*si] = 0;
2323
2324   PlayField16[*si + 2] = fiMurphy;
2325   SplitMoveFlag = 0;
2326   *si = *si + 1;
2327   if (HighByte(PlayField16[*si]) == 1)
2328     subSpPortTest(*si);
2329
2330   *si = *si + 1;
2331
2332   return;
2333
2334   // ==========================================================================
2335   // Move Red Disk up
2336   // ==========================================================================
2337
2338 loc_g_72FA:
2339   if (LowByte(PlayField16[*si]) != fiExplosion)
2340     PlayField16[*si] = 0;
2341
2342   *si = *si - FieldWidth;
2343   PlayField16[*si] = fiMurphy;
2344   subEatRedDisk(*si); // inc+show Murphy's red disks
2345
2346   return;
2347
2348   // ==========================================================================
2349   // Move Red Disk left
2350   // ==========================================================================
2351
2352 loc_g_7318:
2353   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2354     PlayField16[*si + 1] = 0;
2355
2356   PlayField16[*si] = fiMurphy;
2357   subEatRedDisk(*si); // inc+show Murphy's red disks
2358
2359   return;
2360
2361   // ==========================================================================
2362   // Move Red Disk down
2363   // ==========================================================================
2364
2365 loc_g_7333:
2366   if (LowByte(PlayField16[*si]) != fiExplosion)
2367     PlayField16[*si] = 0;
2368
2369   *si = *si + FieldWidth;
2370   PlayField16[*si] = fiMurphy;
2371   subEatRedDisk(*si); // inc+show Murphy's red disks
2372
2373   return;
2374
2375   // ==========================================================================
2376   // Move Red Disk right
2377   // ==========================================================================
2378
2379 loc_g_7351:
2380   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2381     PlayField16[*si - 1] = 0;
2382
2383   PlayField16[*si] = fiMurphy;
2384   subEatRedDisk(*si); // inc+show Murphy's red disks
2385
2386   return;
2387
2388   // ==========================================================================
2389   // Eat Red Disk up
2390   // ==========================================================================
2391
2392 loc_g_736C:
2393   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2394     PlayField16[*si - FieldWidth] = 0;
2395
2396   subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2397
2398   return;
2399
2400   // ==========================================================================
2401   // Eat Red Disk left
2402   // ==========================================================================
2403
2404 loc_g_7381:
2405   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2406     PlayField16[*si - 1] = 0;
2407
2408   subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2409
2410   return;
2411
2412   // ==========================================================================
2413   // Eat Red Disk down
2414   // ==========================================================================
2415
2416 loc_g_7396:
2417   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2418     PlayField16[*si + FieldWidth] = 0;
2419
2420   subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2421
2422   return;
2423
2424   // ==========================================================================
2425   // Eat Red Disk right
2426   // ==========================================================================
2427
2428 loc_g_73AB:
2429   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2430     PlayField16[*si + 1] = 0;
2431
2432   subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2433
2434   return;
2435
2436   // ==========================================================================
2437   //                       yellow disk, pushing up
2438   // ==========================================================================
2439
2440 loc_g_73C0:
2441   if (LowByte(PlayField16[*si]) != fiExplosion)
2442     PlayField16[*si] = 0;
2443
2444   *si = *si - FieldWidth;
2445   PlayField16[*si] = fiMurphy;
2446   PlayField16[*si - FieldWidth] = fiYellowDisk;
2447
2448   return;
2449
2450   // ==========================================================================
2451   //                       yellow disk, pushing left
2452   // ==========================================================================
2453
2454 loc_g_73DD:
2455   if (LowByte(PlayField16[*si]) != fiExplosion)
2456     PlayField16[*si] = 0;
2457
2458   *si = *si - 1;
2459   PlayField16[*si] = fiMurphy;
2460   PlayField16[*si - 1] = fiYellowDisk;
2461
2462   return;
2463
2464   // ==========================================================================
2465   //                       yellow disk, pushing down
2466   // ==========================================================================
2467
2468 loc_g_73FA:
2469   if (LowByte(PlayField16[*si]) != fiExplosion)
2470     PlayField16[*si] = 0;
2471
2472   *si = *si + FieldWidth;
2473   PlayField16[*si] = fiMurphy;
2474   PlayField16[*si + FieldWidth] = fiYellowDisk;
2475
2476   return;
2477
2478   // ==========================================================================
2479   //                       yellow disk pushing right
2480   // ==========================================================================
2481
2482 loc_g_7417:
2483   if (LowByte(PlayField16[*si]) != fiExplosion)
2484     PlayField16[*si] = 0;
2485
2486   *si = *si + 1;
2487   PlayField16[*si] = fiMurphy;
2488   PlayField16[*si + 1] = fiYellowDisk;
2489
2490   return;
2491
2492   // ==========================================================================
2493   //                       orange disk, pushing left
2494   // ==========================================================================
2495
2496 loc_g_7434:
2497   if (LowByte(PlayField16[*si]) != fiExplosion)
2498     PlayField16[*si] = 0;
2499
2500   *si = *si - 1;
2501   PlayField16[*si] = fiMurphy;
2502   PlayField16[*si - 1] = fiOrangeDisk;
2503
2504   return;
2505
2506   // ==========================================================================
2507   //                       orange disk, pushing right
2508   // ==========================================================================
2509
2510 loc_g_7451:
2511   if (LowByte(PlayField16[*si]) != fiExplosion)
2512     PlayField16[*si] = 0;
2513
2514   *si = *si + 1;
2515   PlayField16[*si] = fiMurphy;
2516   PlayField16[*si + 1] = fiOrangeDisk;
2517   if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2518   {
2519     MovHighByte(&PlayField16[*si + 1], 0x20);
2520     MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2521   }
2522
2523   return;
2524
2525   // ==========================================================================
2526   //                     Release a red disk
2527   // ==========================================================================
2528
2529 loc_g_747F:
2530   PlayField16[*si] = fiMurphy;
2531   RedDiskReleasePhase = 2;
2532   RedDiskCount = RedDiskCount - 1;
2533   subDisplayRedDiskCount();
2534   subSoundFXPush();                 // Sound effects
2535 } // subAnimateMurphy
2536
2537 // ==========================================================================
2538 //                              SUBROUTINE
2539 // ==========================================================================
2540 void subExplodeSnikSnaksBelow(int si)
2541 {
2542   int ax;
2543
2544   ax = LowByte(PlayField16[si + FieldWidth]);
2545   if (ax == 0x11 || ax == 0xBB)
2546     ExplodeFieldSP(si + FieldWidth);
2547 } // subExplodeSnikSnaksBelow
2548
2549 // ==========================================================================
2550 //                              SUBROUTINE
2551 // Does pushing against an object kill Murphy?
2552 // ==========================================================================
2553 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2554 {
2555   static boolean subMoveKillsMurphy;
2556
2557   int al, ah;
2558
2559   al = LowByte(ax);
2560   ah = HighByte(ax);
2561   if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2562     goto loc_g_752E;
2563
2564   if (al == fiZonk)
2565     goto loc_g_74E7;
2566
2567   if (al == fiExplosion)
2568     goto loc_g_7530;
2569
2570   if (fiOrangeDisk <= al && al <= fiPortUp)
2571     goto loc_g_752E;
2572
2573   ExplodeFieldSP(si);                 // Explode
2574   subMoveKillsMurphy = True;
2575   return subMoveKillsMurphy;
2576
2577 loc_g_74E7: // zonk
2578   if (bl == keyLeft)
2579     goto loc_g_74F6;
2580
2581   if (bl == keyRight)
2582     goto loc_g_7512;
2583
2584   ExplodeFieldSP(si);                 // Explode
2585   subMoveKillsMurphy = True;
2586   return subMoveKillsMurphy;
2587
2588 loc_g_74F6: // zonk left
2589   ah = ah & 0xF0;
2590   if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2591     ExplodeFieldSP(si);
2592
2593   subMoveKillsMurphy = True;                           // Set carry flag
2594   return subMoveKillsMurphy;
2595
2596 loc_g_7512: // zonk right
2597   ah = ah & 0xF0;
2598   if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2599     ExplodeFieldSP(si);
2600
2601 loc_g_752E: // Marked fields and Ports
2602   subMoveKillsMurphy = True;                           // Set carry flag
2603   return subMoveKillsMurphy;
2604
2605 loc_g_7530: // explosion
2606   if ((ah & 0x80) != 0)
2607     goto loc_g_753A;
2608
2609   if (ah >= 4)
2610     goto loc_g_753F;
2611
2612 loc_g_753A:
2613   ExplodeFieldSP(si);                 // Explode
2614   subMoveKillsMurphy = True;                           // Set carry flag
2615   return subMoveKillsMurphy;
2616
2617 loc_g_753F:
2618   PlayField16[si] = 0;
2619   subMoveKillsMurphy = False;
2620
2621   return subMoveKillsMurphy;
2622 } // subMoveKillsMurphy
2623
2624 // ==========================================================================
2625 //                              SUBROUTINE
2626 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2627 // change conditions to port specs
2628 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2629 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2630 // ==========================================================================
2631 int subSpPortTest(int si)
2632 {
2633   int subSpPortTest;
2634
2635   int i, cx, bx;
2636
2637 #if 1
2638   cx = LInfo.SpecialPortCount; // number of special ports
2639
2640   for (i = 0; i < cx; i++)
2641   {
2642 #if 1
2643     /* this assumes that PortLocation is stored as big endian */
2644     bx = LInfo.SpecialPort[i].PortLocation;
2645 #else
2646     /* this assumes that PortLocation is stored as little endian */
2647     bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2648     MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2649 #endif
2650
2651     if (bx / 2 == si)
2652     {
2653       GravityFlag = LInfo.SpecialPort[i].Gravity;
2654       FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2655       SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2656
2657       // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2658
2659       break;
2660     }
2661   }
2662
2663 #else
2664
2665   cx = LInfo.SpecialPortCount; // number of special ports
2666   for (i = 1; i <= cx; i++)
2667   {
2668     {
2669       bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2670       MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2671       if (bx / 2 == si)
2672       {
2673         GravityFlag = LInfo.SpecialPort[i].Gravity;
2674         FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2675         SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2676         //        RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2677         i = cx + 1;
2678       }
2679     }
2680   }
2681 #endif
2682
2683   return subSpPortTest;
2684 } // subSpPortTest
2685
2686 #if 0
2687
2688 void subCopyFieldToScreen(int si, int fi)
2689 {
2690   int X, Y;
2691
2692   // +++++++++++++++++++++++++++++++++++++++++
2693   X = GetStretchX(si);
2694   Y = GetStretchY(si);
2695   StretchedSprites.BltEx(X, Y, fi);
2696   // +++++++++++++++++++++++++++++++++++++++++
2697 }
2698
2699 #endif
2700
2701 void subCopyAnimToScreen(int si, int graphic, int sync_frame)
2702 {
2703   int X, Y;
2704
2705   // +++++++++++++++++++++++++++++++++++++++++
2706   X = GetStretchX(si);
2707   Y = GetStretchY(si);
2708   StretchedSprites.BltImg(X, Y, graphic, sync_frame);
2709   // +++++++++++++++++++++++++++++++++++++++++
2710 }
2711
2712 void subCopyImageToScreen(int si, int graphic)
2713 {
2714   subCopyAnimToScreen(si, graphic, 0);
2715 }
2716
2717 static void subEatRedDisk(int si)
2718 {
2719   if (AllowRedDiskCheat == 0)
2720   {
2721     if (RedDiskReleasePhase != 0)
2722     {
2723       if (RedDiskReleaseMurphyPos == si)
2724         return;
2725     }
2726   }
2727
2728   RedDiskCount = (RedDiskCount + 1) % 256;
2729   subDisplayRedDiskCount();
2730 }
2731
2732 void subAdjustZonksInfotronsAboveMurphy(int si)
2733 {
2734   int ax;
2735
2736   if (LowByte(PlayField16[si]) != fiExplosion)
2737     PlayField16[si] = 0;
2738
2739   ax = PlayField16[si - FieldWidth];
2740   if (ax == 0 || ax == 0x9999)
2741     goto loc_g_15A8;
2742
2743   if (ax == fiZonk || ax == fiInfotron)
2744   {
2745     MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2746   }
2747
2748   return;
2749
2750 loc_g_15A8: // empty above
2751   ax = PlayField16[si - FieldWidth - 1];
2752   if (ax == fiZonk || ax == fiInfotron)
2753     goto loc_g_15C5;
2754
2755 loc_g_15B6:
2756   ax = PlayField16[si - FieldWidth + 1];
2757   if (ax == fiZonk || ax == fiInfotron)
2758     goto loc_g_15E8;
2759
2760   return;
2761
2762 loc_g_15C5: // zonk/infotron above left
2763   ax = PlayField16[si - 1];
2764   if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2765     goto loc_g_15B6;
2766
2767   MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2768   PlayField16[si - FieldWidth] = 0x8888;
2769
2770   return;
2771
2772 loc_g_15E8: // zonk/infotron above right
2773   ax = PlayField16[si + 1];
2774   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2775   {
2776     MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2777     PlayField16[si - FieldWidth] = 0x8888;
2778   }
2779 } // subAdjustZonksInfotronsAboveMurphy