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