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