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