1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
8 static void subEatRedDisk(int si);
9 static boolean subMoveKillsMurphy(int si, int ax, int bl);
11 #define LocalStretch (2)
12 #define MurphyZoomFactor (ZoomFactor)
14 // ==========================================================================
16 // Move Murphy in any direction
17 // ==========================================================================
19 void subAnimateMurphy(int *si)
21 int ax, al, bl, i, X, Y;
23 int tDeltaX, tDeltaY, tPos, Tmp;
25 // Variables that hold information about the animation sequence
26 static int dx1 = 0; // image/animation token
27 static int dx2 = 0; // an additional image position of a second sprite, for instance: yellow disk if pushed
28 static int MurphyDX = 0, MurphyDY = 0; // murphys move steps
29 static int SeqPos = 0; // index into dx()
30 static int ClearPos = 0; // Position to clear before blitting sprites, none=-1
31 static int dxPos = 0; // field-position to draw dx(SeqPos)
32 static int dx2Step = 0; // position of dx2 relative to dx-position
33 static int dx1SequenceLength = 0;
35 ax = PlayField16[*si];
40 MurphyMoveCounter = 0; // We have no Murphy! Exit!
45 MurphyMoveCounter = 1; // We have a Murphy!
46 MurphyExplodePos = *si;
48 // (check if high byte of PlayField16 has stored movement information)
49 if (ax != fiMurphy) // yes--go proceed moving murphy?
50 goto locProceedMovingMurphy;
52 // FS: reset moving sequence variables
62 ScratchGravity = 0; // scratch gravity off
63 if (GravityFlag != 0) // Gravity? (1=gravity on)
65 bl = LowByte(PlayField16[*si - FieldWidth]); // check above
66 if (! (bl == fiPortUp ||
67 bl == fiPortUpAndDown ||
68 bl == fiPortAllDirections))
70 if (PlayField16[*si + FieldWidth] == 0) // gravity on and space below!
76 if (bl != 0) // a key was pressed!
77 goto locKeyPressed5FCF;
79 RedDiskReleaseFlag = 1;
80 if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
86 // ------------------------------------------------------------------
87 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
89 YawnSleepCounter = YawnSleepCounter + 1;
91 if (YawnSleepCounter < 16)
94 if (YawnSleepCounter < 2000)
97 // (default: single graphic, no animation)
98 subCopyAnimToScreen(*si, aniMurphy, YawnSleepCounter - 16);
103 if (YawnSleepCounter < 4000)
105 // yawn! and look depressed afterwards...
106 // (default: 12 animation frames with delay of 8)
107 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 2000);
112 if (YawnSleepCounter < 6400)
115 // (default: 12 animation frames with delay of 8)
116 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 4000);
121 // time1 = 6400 + 12 * 8; // (default: 6496 == 6400 + 12 * 8)
122 time1 = 6400 + 12 * 10;
124 if (YawnSleepCounter < time1)
126 // yawn again! - third time
127 // (default: 12 animation frames with delay of 8)
128 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 6400);
133 // time2 = 6496 + 3 * 64; // (default: 6688 == 6496 + 3 * 64)
134 time2 = 6496 + 3 * 100;
136 if (YawnSleepCounter > time2) // Murphy already went to sleep
139 if (PlayField16[*si - 1] == 0)
141 if (PlayField16[*si + 1] == 0)
143 // no sleep -- go back to "wait and start yawning" phase
144 YawnSleepCounter = 144;
150 // go to sleep (right side)
151 // (default: 3 animation frames with delay of 64)
152 subCopyAnimToScreen(*si, aniMurphySleepRight, YawnSleepCounter - time1);
158 // go to sleep (left side)
159 // (default: 3 animation frames with delay of 64)
160 subCopyAnimToScreen(*si, aniMurphySleepLeft, YawnSleepCounter - time1);
164 // end of YAWN-SLEEP-Sequence
166 // ------------------------------------------------------------------
167 // ==========================================================================
168 // (Direct Jump) a key was pressed
169 // ==========================================================================
172 if (ScratchGravity == 0)
175 if (PlayField16[*si + FieldWidth] != 0)
180 if (PlayField16[*si - FieldWidth] == fiBase)
184 else if (bl == keyLeft)
186 if (PlayField16[*si - 1] == fiBase)
190 else if (bl == keyRight)
192 if (PlayField16[*si + 1] == fiBase)
196 bl = keyDown; // force moving down!
201 RedDiskReleaseFlag = 0; // moving down to up ...
207 RedDiskReleaseFlag = 0; // moving right to left ...
213 RedDiskReleaseFlag = 0; // moving up to down ...
219 RedDiskReleaseFlag = 0; // moving left to right ...
224 case keySpaceUp: // 5
225 RedDiskReleaseFlag = 0; // touching down to up ...
230 case keySpaceLeft: // 6
231 RedDiskReleaseFlag = 0; // touching right to left ...
236 case keySpaceDown: // 7
237 RedDiskReleaseFlag = 0; // touching up to down ...
242 case keySpaceRight: // 8
243 RedDiskReleaseFlag = 0; // touching left to right ...
249 goto loc_g_62E2; // no move ...
254 RedDiskReleaseFlag = 0;
259 // ==========================================================================
260 // moving down to up ...
261 // ==========================================================================
267 ax = PlayField16[*si - FieldWidth];
278 if (ax == fiInfotron)
284 if (al == fiTerminal)
287 if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
293 if (al == fiYellowDisk)
296 if (! subMoveKillsMurphy(*si - FieldWidth, ax, bl))
301 // ==========================================================================
302 // moving right to left ...
303 // ==========================================================================
309 MurphyVarFaceLeft = 1;
310 ax = PlayField16[*si - 1];
321 if (ax == fiInfotron)
330 if (al == fiTerminal)
333 if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
339 if (ax == fiYellowDisk)
342 if (ax == fiOrangeDisk)
345 if (! subMoveKillsMurphy(*si - 1, ax, bl))
350 // ==========================================================================
351 // moving up to down ...
352 // ==========================================================================
358 ax = PlayField16[*si + FieldWidth];
369 if (ax == fiInfotron)
375 if (al == fiTerminal)
378 if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
384 if (al == fiYellowDisk)
387 if (! subMoveKillsMurphy(*si + FieldWidth, ax, bl))
392 // ==========================================================================
393 // moving left to right ...
394 // ==========================================================================
400 MurphyVarFaceLeft = 0;
401 ax = PlayField16[*si + 1];
412 if (ax == fiInfotron)
421 if (al == fiTerminal)
424 if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
430 if (al == fiYellowDisk)
433 if (ax == fiOrangeDisk)
436 if (! subMoveKillsMurphy(*si + 1, ax, bl))
441 // ==========================================================================
442 // touching down to up ...
443 // ==========================================================================
448 dxPos = *si - FieldWidth;
450 ax = PlayField16[*si - FieldWidth];
459 if (ax == fiInfotron)
462 if (al == fiTerminal)
470 // ==========================================================================
471 // touching right to left ...
472 // ==========================================================================
479 MurphyVarFaceLeft = 1;
480 ax = PlayField16[*si - 1];
488 if (ax == fiInfotron)
491 if (al == fiTerminal)
499 // ==========================================================================
500 // touching up to down ...
501 // ==========================================================================
506 dxPos = *si + FieldWidth;
508 ax = PlayField16[*si + FieldWidth];
516 if (ax == fiInfotron)
519 if (al == fiTerminal)
527 // ==========================================================================
528 // touching left to right ...
529 // ==========================================================================
536 MurphyVarFaceLeft = 0;
537 ax = PlayField16[*si + 1];
545 if (ax == fiInfotron)
548 if (al == fiTerminal)
556 // ==========================================================================
557 // Release Red disk: no move ...
558 // ==========================================================================
564 if (LowByte(RedDiskCount) == 0)
567 if (LowByte(RedDiskReleasePhase) != 0)
570 if (LowByte(RedDiskReleaseFlag) != 1)
573 MovHighByte(&PlayField16[*si], 0x2A);
574 MovingPictureSequencePhase = 0x40; // init picture move sequence
576 MovLowByte(&RedDiskReleasePhase, 1);
577 RedDiskReleaseMurphyPos = *si; // remember Murphy's location
580 // ==========================================================================
581 // SPACE moving down to up
582 // ==========================================================================
585 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyMoveUpRight : aniMurphyMoveUpLeft);
586 PlayField16[*si - FieldWidth] = 0x103;
587 PlayField16[*si] = 0x300;
588 *si = *si - FieldWidth;
589 goto loc_StopNoSplit;
591 // ==========================================================================
592 // SPACE moving right to left
593 // ==========================================================================
596 dx1 = aniMurphyMoveLeft;
597 PlayField16[*si - 1] = 0x203;
598 PlayField16[*si] = 0x300;
600 goto loc_StopNoSplit;
602 // ==========================================================================
603 // SPACE moving up to down, and when gravity is pulling!
604 // ==========================================================================
607 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyMoveUpRight : aniMurphyMoveUpLeft);
608 PlayField16[*si + FieldWidth] = 0x303;
609 PlayField16[*si] = 0x300;
610 *si = *si + FieldWidth;
611 goto loc_StopNoSplit;
613 // ==========================================================================
614 // SPACE moving left to right
615 // ==========================================================================
618 dx1 = aniMurphyMoveRight;
619 PlayField16[*si + 1] = 0x403;
620 PlayField16[*si] = 0x300;
622 goto loc_StopNoSplit;
624 // ==========================================================================
625 // BUG moving down to up
626 // ==========================================================================
629 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
631 ExplodeFieldSP(*si); // Explode
636 PlayField16[*si - FieldWidth] = fiBase;
637 // ==========================================================================
638 // BASE moving down to up
639 // ==========================================================================
642 subSoundFX(*si, fiBase, actDigging);
644 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyDigUpRight : aniMurphyDigUpLeft);
645 PlayField16[*si - FieldWidth] = 0x503;
646 PlayField16[*si] = 0x300;
647 *si = *si - FieldWidth;
648 goto loc_StopNoSplit;
650 // ==========================================================================
651 // BUG moving right to left
652 // ==========================================================================
655 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
657 ExplodeFieldSP(*si); // Explode
662 PlayField16[*si - 1] = fiBase;
663 // ==========================================================================
664 // BASE moving right to left
665 // ==========================================================================
668 subSoundFX(*si, fiBase, actDigging);
670 dx1 = aniMurphyDigLeft;
671 PlayField16[*si - 1] = 0x203;
672 PlayField16[*si] = 0x300;
674 goto loc_StopNoSplit;
676 // ==========================================================================
677 // BUG moving up to down
678 // ==========================================================================
681 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
683 ExplodeFieldSP(*si); // Explode
688 PlayField16[*si + FieldWidth] = fiBase;
689 // ==========================================================================
690 // BASE moving up to down
691 // ==========================================================================
694 subSoundFX(*si, fiBase, actDigging);
696 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyDigUpRight : aniMurphyDigUpLeft);
697 PlayField16[*si + FieldWidth] = 0x703;
698 PlayField16[*si] = 0x300;
699 *si = *si + FieldWidth;
700 goto loc_StopNoSplit;
702 // ==========================================================================
703 // BUG moving left to right
704 // ==========================================================================
707 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
709 ExplodeFieldSP(*si); // Explode
714 PlayField16[*si + 1] = fiBase;
715 // ==========================================================================
716 // BASE moving left to right
717 // ==========================================================================
720 subSoundFX(*si, fiBase, actDigging);
722 dx1 = aniMurphyDigRight;
723 PlayField16[*si + 1] = 0x803;
724 PlayField16[*si] = 0x300;
726 goto loc_StopNoSplit;
728 // ==========================================================================
729 // BUG touching down to up
730 // ==========================================================================
733 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
735 ExplodeFieldSP(*si); // Explode
740 PlayField16[*si - FieldWidth] = fiBase;
741 // ==========================================================================
742 // BASE touching down to up
743 // ==========================================================================
746 subCopyImageToScreen(*si, aniMurphyTouchUp);
747 subSoundFX(*si, fiBase, actDigging);
750 dxPos = *si - FieldWidth;
751 MovHighByte(&PlayField16[*si], 0x10);
752 goto loc_StopNoSplit;
754 // ==========================================================================
755 // BUG touching right to left
756 // ==========================================================================
759 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
761 ExplodeFieldSP(*si); // Explode
766 PlayField16[*si - 1] = fiBase;
767 // ==========================================================================
768 // BASE touching right to left
769 // ==========================================================================
772 subCopyImageToScreen(*si, aniMurphyTouchLeft);
773 subSoundFX(*si, fiBase, actDigging);
777 MovHighByte(&PlayField16[*si], 0x11);
778 goto loc_StopNoSplit;
780 // ==========================================================================
781 // BUG touching up to down
782 // ==========================================================================
785 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
787 ExplodeFieldSP(*si); // Explode
792 PlayField16[*si + FieldWidth] = fiBase;
793 // ==========================================================================
794 // BASE touching up to down
795 // ==========================================================================
798 subCopyImageToScreen(*si, aniMurphyTouchDown);
799 subSoundFX(*si, fiBase, actDigging);
802 dxPos = *si + FieldWidth;
803 MovHighByte(&PlayField16[*si], 0x12);
804 goto loc_StopNoSplit;
806 // ==========================================================================
807 // BUG touching left to right
808 // ==========================================================================
811 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
813 ExplodeFieldSP(*si); // Explode
818 PlayField16[*si + 1] = fiBase;
819 // ==========================================================================
820 // BASE touching left to right
821 // ==========================================================================
824 subCopyImageToScreen(*si, aniMurphyTouchRight);
825 subSoundFX(*si, fiBase, actDigging);
829 MovHighByte(&PlayField16[*si], 0x13);
830 goto loc_StopNoSplit;
832 // ==========================================================================
833 // INFOTRON moving down to up
834 // ==========================================================================
837 subSoundFX(*si, fiInfotron, actCollecting);
839 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
840 PlayField16[*si - FieldWidth] = 0x903;
841 PlayField16[*si] = 0x300;
842 *si = *si - FieldWidth;
843 goto loc_StopNoSplit;
845 // ==========================================================================
846 // INFOTRON moving right to left
847 // ==========================================================================
850 subSoundFX(*si, fiInfotron, actCollecting);
852 dx1 = aniEatInfotronLeft;
853 PlayField16[*si - 1] = 0xA03;
854 PlayField16[*si] = 0x300;
856 goto loc_StopNoSplit;
858 // ==========================================================================
859 // INFOTRON moving up to down
860 // ==========================================================================
863 subSoundFX(*si, fiInfotron, actCollecting);
865 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
866 PlayField16[*si + FieldWidth] = 0xB03;
867 PlayField16[*si] = 0x300;
868 *si = *si + FieldWidth;
869 goto loc_StopNoSplit;
871 // ==========================================================================
872 // INFOTRON moving left to right
873 // ==========================================================================
876 subSoundFX(*si, fiInfotron, actCollecting);
878 dx1 = aniEatInfotronRight;
879 PlayField16[*si + 1] = 0xC03;
880 PlayField16[*si] = 0x300;
882 goto loc_StopNoSplit;
884 // ==========================================================================
885 // INFOTRON touching down to up
886 // ==========================================================================
889 subCopyImageToScreen(*si, aniMurphyTouchUp);
890 subSoundFX(*si, fiInfotron, actCollecting);
892 dx1 = aniTouchInfotron;
893 MovHighByte(&PlayField16[*si], 0x14);
894 MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
895 goto loc_StopNoSplit;
897 // ==========================================================================
898 // INFOTRON touching right to left
899 // ==========================================================================
902 subCopyImageToScreen(*si, aniMurphyTouchLeft);
903 subSoundFX(*si, fiInfotron, actCollecting);
905 dx1 = aniTouchInfotron;
906 MovHighByte(&PlayField16[*si], 0x15);
907 MovHighByte(&PlayField16[*si - 1], 0xFF);
908 goto loc_StopNoSplit;
910 // ==========================================================================
911 // INFOTRON touching up to down
912 // ==========================================================================
915 subCopyImageToScreen(*si, aniMurphyTouchDown);
916 subSoundFX(*si, fiInfotron, actCollecting);
918 dx1 = aniTouchInfotron;
919 MovHighByte(&PlayField16[*si], 0x16);
920 MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
921 goto loc_StopNoSplit;
923 // ==========================================================================
924 // INFOTRON touching left to right
925 // ==========================================================================
928 subCopyImageToScreen(*si, aniMurphyTouchRight);
929 subSoundFX(*si, fiInfotron, actCollecting);
931 dx1 = aniTouchInfotron;
932 MovHighByte(&PlayField16[*si], 0x17);
933 MovHighByte(&PlayField16[*si + 1], 0xFF);
934 goto loc_StopNoSplit;
936 // ==========================================================================
937 // EXIT pressed from any direction
938 // ==========================================================================
946 if (LowByte(InfotronsNeeded) != 0)
949 game_sp.LevelSolved = TRUE;
951 subSoundFX(*si, fiExit, actPassing);
953 LeadOutCounter = 0x40; // quit: start lead-out
955 MovHighByte(&PlayField16[*si], 0xD);
956 goto loc_StopNoSplit;
958 // ==========================================================================
959 // ZONK moving right to left
960 // ==========================================================================
963 ax = PlayField16[*si - 2];
967 MovHighByte(&PlayField16[*si - 2], 1);
968 subCopyImageToScreen(*si, aniPushLeft); // draw pushing murphy
969 dx1 = aniZonkRollLeft;
973 MovHighByte(&PlayField16[*si], 0xE);
974 goto loc_MoveNoSplit;
976 // ==========================================================================
977 // ZONK moving left to right
978 // ==========================================================================
981 ax = PlayField16[*si + 2];
985 ax = PlayField16[*si + FieldWidth + 1];
986 if (ax == 0) // zonk falls
989 MovHighByte(&PlayField16[*si + 2], 1);
990 subCopyImageToScreen(*si, aniPushRight); // draw pushing murphy
991 dx1 = aniZonkRollRight;
995 MovHighByte(&PlayField16[*si], 0xF);
996 goto loc_MoveNoSplit;
998 // ==========================================================================
999 // TERMINAL moving/touching down to up
1000 // ==========================================================================
1003 subCopyImageToScreen(*si, aniMurphyTouchUp);
1004 if (YellowDisksExploded != 0)
1006 YawnSleepCounter = 40; // stay hypnotized
1011 // draw new terminal type
1012 GfxGraphic[GetX(*si - FieldWidth)][GetY(*si - FieldWidth)] = aniTerminalActive;
1013 TerminalState[*si - FieldWidth] = 8;
1016 // ==========================================================================
1017 // TERMINAL moving/touching right to left
1018 // ==========================================================================
1021 subCopyImageToScreen(*si, aniMurphyTouchLeft);
1022 if (YellowDisksExploded != 0)
1024 YawnSleepCounter = 40; // stay hypnotized
1029 // draw new terminal type
1030 GfxGraphic[GetX(*si - 1)][GetY(*si - 1)] = aniTerminalActive;
1031 TerminalState[*si - 1] = 8;
1034 // ==========================================================================
1035 // TERMINAL moving/touching up to down
1036 // ==========================================================================
1039 subCopyImageToScreen(*si, aniMurphyTouchDown);
1040 if (YellowDisksExploded != 0)
1042 YawnSleepCounter = 40; // stay hypnotized
1047 // draw new terminal type
1048 GfxGraphic[GetX(*si + FieldWidth)][GetY(*si + FieldWidth)] = aniTerminalActive;
1049 TerminalState[*si + FieldWidth] = 8;
1052 // ==========================================================================
1053 // TERMINAL moving/touching left to right
1054 // ==========================================================================
1057 subCopyImageToScreen(*si, aniMurphyTouchRight);
1058 if (YellowDisksExploded != 0)
1060 YawnSleepCounter = 40; // stay hypnotized
1065 // draw new terminal type
1066 GfxGraphic[GetX(*si + 1)][GetY(*si + 1)] = aniTerminalActive;
1067 TerminalState[*si + 1] = 8;
1068 // ==========================================================================
1069 // common TERMINAL stuff moving/touching from all directions
1070 // ==========================================================================
1073 TerminalMaxCycles = 7;
1074 YellowDisksExploded = 1;
1075 for (i = 0; i <= LevelMax; i++)
1077 if (PlayField16[i] == fiYellowDisk)
1083 // ==========================================================================
1084 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1085 // ==========================================================================
1088 if (PlayField16[*si - 2 * FieldWidth] != 0)
1091 dx1 = aniSplitUpDown;
1092 dx2Step = -FieldWidth;
1093 PlayField16[*si] = 0x1803;
1094 PlayField16[*si - 2 * FieldWidth] = 0x300;
1097 // ==========================================================================
1098 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1099 // ==========================================================================
1102 if (PlayField16[*si - 2] != 0)
1105 dx1 = aniMurphyMoveLeft;
1107 PlayField16[*si] = 0x1903;
1108 PlayField16[*si - 2] = 0x300;
1111 // ==========================================================================
1112 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1113 // ==========================================================================
1116 if (PlayField16[*si + 2 * FieldWidth] != 0)
1119 dx1 = aniSplitUpDown;
1120 dx2Step = FieldWidth;
1121 PlayField16[*si] = 0x1A03;
1122 PlayField16[*si + 2 * FieldWidth] = 0x300;
1125 // ==========================================================================
1126 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1127 // ==========================================================================
1130 if (PlayField16[*si + 2] != 0)
1133 dx1 = aniMurphyMoveRight;
1135 PlayField16[*si] = 0x1B03;
1136 PlayField16[*si + 2] = 0x300;
1139 MovingPictureSequencePhase = 0; // stop picture move sequence
1140 SplitMoveFlag = 1; // port: split movement
1143 // ==========================================================================
1144 // RED DISK moving down to up
1145 // ==========================================================================
1148 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1149 PlayField16[*si] = 0x1C03;
1150 PlayField16[*si - FieldWidth] = 0x300;
1151 goto loc_StopNoSplit;
1153 // ==========================================================================
1154 // RED DISK moving right to left
1155 // ==========================================================================
1158 dx1 = aniMurphyEatLeft;
1159 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1160 PlayField16[*si - 1] = 0x1D03;
1162 goto loc_StopNoSplit;
1164 // ==========================================================================
1165 // RED DISK moving up to down
1166 // ==========================================================================
1169 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1170 PlayField16[*si] = 0x1E03;
1171 PlayField16[*si + FieldWidth] = 0x300;
1172 goto loc_StopNoSplit;
1174 // ==========================================================================
1175 // RED DISK moving left to right
1176 // ==========================================================================
1179 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1180 dx1 = aniMurphyEatRight;
1181 // --------------------------------------------------------------------------
1183 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1184 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1185 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1186 // We may not fix the table, because then the timing of the game changes
1187 // and several existing demo's do not run properly anymore.
1188 // We only correct Murphies x-location here, when the sequence starts.
1189 // Remember that this is not the real bug-fix, but we must live with
1190 // this existing bug and correct for the consequences of it.
1192 if (AllowEatRightRedDiskBug == 0) // Murphy's screen x-position
1193 MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1196 // FS: for me this means to blit the first animation frame twice
1198 // --------------------------------------------------------------------------
1199 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1200 PlayField16[*si + 1] = 0x1F03;
1202 goto loc_StopNoSplit;
1204 // ==========================================================================
1205 // RED DISK touching down to up
1206 // ==========================================================================
1209 dx1 = aniTouchRedDisk;
1210 MovHighByte(&PlayField16[*si], 0x20);
1211 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1212 goto loc_StopNoSplit;
1214 // ==========================================================================
1215 // RED DISK touching right to left
1216 // ==========================================================================
1219 dx1 = aniTouchRedDisk;
1220 MovHighByte(&PlayField16[*si], 0x21);
1221 MovHighByte(&PlayField16[*si - 1], 3);
1222 goto loc_StopNoSplit;
1224 // ==========================================================================
1225 // RED DISK touching up to down
1226 // ==========================================================================
1229 dx1 = aniTouchRedDisk;
1230 MovHighByte(&PlayField16[*si], 0x22);
1231 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1232 goto loc_StopNoSplit;
1234 // ==========================================================================
1235 // RED DISK touching left to right
1236 // ==========================================================================
1239 dx1 = aniTouchRedDisk;
1240 MovHighByte(&PlayField16[*si], 0x23);
1241 MovHighByte(&PlayField16[*si + 1], 3);
1244 MovingPictureSequencePhase = 0; // stop picture move sequence
1247 // ==========================================================================
1248 // YELLOW DISK moving down to up
1249 // ==========================================================================
1252 if (PlayField16[*si - 2 * FieldWidth] != 0)
1255 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1256 dx1 = aniYellowDisk;
1257 dxPos = *si - FieldWidth;
1258 dx2 = (MurphyVarFaceLeft == 0 ? aniPushRight : aniPushLeft);
1259 dx2Step = FieldWidth;
1260 PlayField16[*si] = 0x2403;
1261 subCopyImageToScreen(*si, dx2);
1262 goto loc_MoveNoSplit;
1264 // ==========================================================================
1265 // YELLOW DISK moving right to left
1266 // ==========================================================================
1269 if (PlayField16[*si - 2] != 0)
1272 PlayField16[*si - 2] = 0x1200;
1273 subCopyImageToScreen(*si, aniPushLeft);
1274 dx1 = aniYellowDisk;
1278 PlayField16[*si] = 0x2503;
1279 goto loc_MoveNoSplit;
1281 // ==========================================================================
1282 // YELLOW DISK moving up to down
1283 // ==========================================================================
1286 if (PlayField16[*si + 2 * FieldWidth] != 0)
1289 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1290 dx1 = aniYellowDisk;
1291 dxPos = *si + FieldWidth;
1292 dx2 = (MurphyVarFaceLeft == 0 ? aniPushRight : aniPushLeft);
1293 dx2Step = -FieldWidth;
1294 PlayField16[*si] = 0x2703;
1295 subCopyImageToScreen(*si, dx2);
1296 goto loc_MoveNoSplit;
1298 // ==========================================================================
1299 // YELLOW DISK moving left to right
1300 // ==========================================================================
1303 if (PlayField16[*si + 2] != 0)
1306 PlayField16[*si + 2] = 0x1200;
1307 subCopyImageToScreen(*si, aniPushRight);
1308 dx1 = aniYellowDisk;
1312 PlayField16[*si] = 0x2603;
1313 goto loc_MoveNoSplit;
1315 // ==========================================================================
1316 // ORANGE DISK moving right to left
1317 // ==========================================================================
1320 if (PlayField16[*si - 2] != 0)
1323 PlayField16[*si - 2] = 0x800;
1324 subCopyImageToScreen(*si, aniPushLeft);
1325 dx1 = aniOrangeDisk;
1329 PlayField16[*si] = 0x2803;
1330 goto loc_MoveNoSplit;
1332 // ==========================================================================
1333 // ORANGE DISK moving left to right
1334 // ==========================================================================
1337 if (PlayField16[*si + 2] != 0)
1340 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1343 PlayField16[*si + 2] = 0x100;
1344 subCopyImageToScreen(*si, aniPushRight);
1345 dx1 = aniOrangeDisk;
1349 PlayField16[*si] = 0x2903;
1350 // ==========================================================================
1351 // Copy screen animation action table to action work space
1352 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1353 // ==========================================================================
1356 MovingPictureSequencePhase = 8; // init picture move sequence
1359 SplitMoveFlag = 0; // no port: no split movement
1362 // copy/store global move sequence info????????????????????????????????????
1363 // ... dont think so ...(FS)
1364 // ==========================================================================
1365 // Proceed with all movements
1366 // ==========================================================================
1368 locProceedMovingMurphy: // proceed moving murphy
1369 YawnSleepCounter = 0; // Wake up sleeping Murphy
1370 ax = MovingPictureSequencePhase; // sequence busy?
1371 if (ax == 0) // no -- start sequence!
1374 ax = ax - 1; // next picture of sequence
1375 MovingPictureSequencePhase = ax; // store for later
1377 if (ax == 0) // Sound effects
1379 switch (HighByte(PlayField16[*si]))
1383 subSoundFX(*si, fiZonk, actPushing);
1388 subSoundFX(*si, fiOrangeDisk, actPushing);
1395 subSoundFX(*si, fiYellowDisk, actPushing);
1403 bl = HighByte(PlayField16[*si]);
1404 if (bl == 0xE) // Push Zonk to left
1407 if (bl == 0xF) // Push Zonk to right
1410 if (bl == 0x28) // Push orange disk to left
1413 if (bl == 0x29) // Push orange disk to right
1416 if (bl == 0x24) // Push yellow disk up
1419 if (bl == 0x25) // Push yellow disk to left
1422 if (bl == 0x27) // Push yellow disk down
1425 if (bl == 0x26) // Push yellow disk to right
1428 if (bl == 0x2A) // Red disk release timer
1433 // ==========================================================================
1434 // Paint frame of MOVING.DAT sequence
1435 // ==========================================================================
1440 dx1SequenceLength = getSequenceLength(dx1);
1442 if (SplitMoveFlag == 0)
1444 // ++++++++++++++++++++++++++
1445 // Begin of normal movement
1446 MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1447 MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1449 if (!(ClearPos < 0)) // clear field that murphy is leaving
1450 subCopyImageToScreen(ClearPos, aniSpace);
1452 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1453 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1455 X = GetStretchX(dxPos) + tDeltaX;
1456 Y = GetStretchY(dxPos) + tDeltaY;
1457 Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1459 if (isSnappingSequence(dx1) && SeqPos == dx1SequenceLength - 1)
1462 DDSpriteBuffer_BltImg(X, Y, dx1, Tmp);
1463 GfxGraphic[GetX(*si)][GetY(*si)] = -1; // (Murphy's position)
1464 GfxGraphic[GetX(dxPos)][GetY(dxPos)] = -1; // (snapping position)
1468 tPos = dxPos + dx2Step;
1469 X = GetStretchX(tPos);
1470 Y = GetStretchY(tPos);
1472 // (SeqPos iterates from 0 to 7 while pushing)
1473 DDSpriteBuffer_BltImg(X + tDeltaX, Y + tDeltaY, dx2, SeqPos);
1476 // End of normal movement
1477 // ------------------------
1481 // ++++++++++++++++++++++++++++++++
1482 // Begin of split movement (port)
1483 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1484 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1485 subCopyImageToScreen(ClearPos, aniSpace); // clear the field that murphy leaves
1486 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1487 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1488 X = GetStretchX(dxPos) + tDeltaX;
1489 Y = GetStretchY(dxPos) + tDeltaY;
1490 DDSpriteBuffer_BltImg(X, Y, dx1, SeqPos); // plot first murphy
1492 tPos = dxPos + dx2Step;
1493 X = GetStretchX(tPos);
1494 Y = GetStretchY(tPos);
1495 DDSpriteBuffer_BltImg(X + tDeltaX, Y + tDeltaY, dx1, SeqPos); // plot second murphy
1496 DDSpriteBuffer_BltImg(X, Y, fiGraphic[LowByte(PlayField16[tPos])], 0); // replot the port on top
1497 // End of split movement (port)
1498 // ------------------------------
1499 } // loc_g_6D1E:'loc_g_6D28:
1501 SeqPos = SeqPos + 1;
1502 if (SeqPos < dx1SequenceLength)
1505 // Follow-up after movement completed 'loc_g_6D35:
1506 MurphyXPos = MurphyXPos + MurphyDX;
1507 MurphyYPos = MurphyYPos + MurphyDY;
1508 bl = HighByte(PlayField16[*si]); // animation phase
1509 MovHighByte(&PlayField16[*si], 0);
1511 if (bl == 0x1) // space, moving up
1514 if (bl == 0x2) // space, moving left
1517 if (bl == 0x3) // space, moving down
1520 if (bl == 0x4) // space, moving right
1523 if (bl == 0x5) // base , moving up
1526 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1529 if (bl == 0x7) // base , moving down
1532 if (bl == 0x8) // base , moving right
1535 if (bl == 0x9) // infotron, moving up
1538 if (bl == 0xA) // infotron, moving left
1541 if (bl == 0xB) // infotron, moving down
1544 if (bl == 0xC) // infotron, moving right
1547 if (bl == 0xD) // exit
1550 if (bl == 0xE) // zonk, pushing left
1553 if (bl == 0xF) // zonk, pushing right
1556 if (bl == 0x10) // base , touching up
1559 if (bl == 0x11) // base , touching left
1562 if (bl == 0x12) // base , touching down
1565 if (bl == 0x13) // base , touching right
1568 if (bl == 0x14) // infotron touching up
1571 if (bl == 0x15) // infotron touching left
1574 if (bl == 0x16) // infotron touching down
1577 if (bl == 0x17) // infotron touching right
1580 if (bl == 0x18) // port up
1583 if (bl == 0x19) // port left
1586 if (bl == 0x1A) // port down
1589 if (bl == 0x1B) // port right
1592 if (bl == 0x1C) // red disk, moving up
1595 if (bl == 0x1D) // red disk, moving left
1598 if (bl == 0x1E) // red disk, moving down
1601 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1604 if (bl == 0x20) // red disk, touching up
1607 if (bl == 0x21) // red disk, touching left
1610 if (bl == 0x22) // red disk, touching down
1613 if (bl == 0x23) // red disk, touching right
1616 if (bl == 0x24) // yellow disk, pushing up
1619 if (bl == 0x25) // yellow disk, pushing left
1622 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1625 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1628 if (bl == 0x28) // orange disk, pushing left
1631 if (bl == 0x29) // orange disk, pushing right
1634 if (bl == 0x2A) // red disk, release
1641 // ==========================================================================
1642 // infotron, moving up
1643 // ==========================================================================
1646 if (0 < LowByte(InfotronsNeeded))
1647 InfotronsNeeded = InfotronsNeeded - 1;
1649 loc_g_6EC8: // space, base
1650 PlayField16[*si] = fiMurphy;
1651 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1655 // ==========================================================================
1656 // infotron, moving left
1657 // ==========================================================================
1660 if (0 < LowByte(InfotronsNeeded))
1661 InfotronsNeeded = InfotronsNeeded - 1;
1663 loc_g_6EE6: // space, base
1664 PlayField16[*si] = fiMurphy;
1665 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1669 // ==========================================================================
1670 // infotron, moving down
1671 // ==========================================================================
1674 if (0 < LowByte(InfotronsNeeded))
1675 InfotronsNeeded = InfotronsNeeded - 1;
1677 loc_g_6F04: // space, base
1678 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1679 PlayField16[*si - FieldWidth] = 0;
1681 PlayField16[*si] = fiMurphy;
1685 // ==========================================================================
1686 // infotron, moving right
1687 // ==========================================================================
1690 if (0 < LowByte(InfotronsNeeded))
1691 InfotronsNeeded = InfotronsNeeded - 1;
1693 loc_g_71C4: // space, base
1694 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1695 PlayField16[*si] = fiMurphy;
1699 // ==========================================================================
1700 // infotron, touching up
1701 // ==========================================================================
1704 if (0 < LowByte(InfotronsNeeded))
1705 InfotronsNeeded = InfotronsNeeded - 1;
1708 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1709 PlayField16[*si - FieldWidth] = 0;
1713 // ==========================================================================
1714 // infotron, touching left
1715 // ==========================================================================
1718 if (0 < LowByte(InfotronsNeeded))
1719 InfotronsNeeded = InfotronsNeeded - 1;
1722 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1723 PlayField16[*si - 1] = 0;
1727 // ==========================================================================
1728 // infotron, touching down
1729 // ==========================================================================
1732 if (0 < LowByte(InfotronsNeeded))
1733 InfotronsNeeded = InfotronsNeeded - 1;
1736 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1737 PlayField16[*si + FieldWidth] = 0;
1741 // ==========================================================================
1742 // infotron, touching right
1743 // ==========================================================================
1746 if (0 < LowByte(InfotronsNeeded))
1747 InfotronsNeeded = InfotronsNeeded - 1;
1750 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1751 PlayField16[*si + 1] = 0;
1755 // ==========================================================================
1756 // zonk, pushing left
1757 // ==========================================================================
1760 if (LowByte(PlayField16[*si]) != fiExplosion)
1761 PlayField16[*si] = 0;
1763 PlayField16[*si - 1] = fiMurphy;
1764 PlayField16[*si - 2] = fiZonk;
1765 subExplodeSnikSnaksBelow(*si - 2);
1770 // ==========================================================================
1771 // zonk, pushing right
1772 // ==========================================================================
1775 if (LowByte(PlayField16[*si]) != fiExplosion)
1776 PlayField16[*si] = 0;
1778 PlayField16[*si + 1] = fiMurphy;
1779 PlayField16[*si + 2] = fiZonk;
1780 subExplodeSnikSnaksBelow(*si + 2);
1785 // ==========================================================================
1787 // ==========================================================================
1792 PlayField16[*si] = fiSpace; // remove Murphy from playfield after exiting
1796 // ==========================================================================
1797 // Push Zonk from right to left
1798 // ==========================================================================
1801 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1804 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1805 PlayField16[*si - 1] = fiZonk;
1806 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1807 PlayField16[*si - 2] = 0;
1809 subCopyImageToScreen(*si, aniMurphy);
1813 // ==========================================================================
1814 // Push Zonk from left to right
1815 // ==========================================================================
1818 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1821 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1822 PlayField16[*si + 1] = fiZonk;
1823 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1824 PlayField16[*si + 2] = 0;
1826 subCopyImageToScreen(*si, aniMurphy);
1830 // ==========================================================================
1831 // Push orange disk from right to left
1832 // ==========================================================================
1835 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1838 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1839 PlayField16[*si - 1] = fiOrangeDisk;
1840 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1841 PlayField16[*si - 2] = 0;
1843 subCopyImageToScreen(*si, aniMurphy);
1847 // ==========================================================================
1848 // Push orange disk from left to right
1849 // ==========================================================================
1852 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1855 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1856 PlayField16[*si + 1] = fiOrangeDisk;
1857 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1858 PlayField16[*si + 2] = 0;
1860 subCopyImageToScreen(*si, aniMurphy);
1864 // ==========================================================================
1865 // Push yellow disk from down to up
1866 // ==========================================================================
1869 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1872 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1873 PlayField16[*si - FieldWidth] = fiYellowDisk;
1874 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1875 PlayField16[*si - 2 * FieldWidth] = 0;
1877 subCopyImageToScreen(*si, aniMurphy);
1881 // ==========================================================================
1882 // Push yellow disk from right to left
1883 // ==========================================================================
1886 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1889 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1890 PlayField16[*si - 1] = fiYellowDisk;
1891 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1892 PlayField16[*si - 2] = 0;
1894 subCopyImageToScreen(*si, aniMurphy);
1898 // ==========================================================================
1899 // Push yellow disk from up to down
1900 // ==========================================================================
1903 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1906 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1907 PlayField16[*si + FieldWidth] = fiYellowDisk;
1908 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1909 PlayField16[*si + 2 * FieldWidth] = 0;
1911 subCopyImageToScreen(*si, aniMurphy);
1915 // ==========================================================================
1916 // Push yellow disk from left to right
1917 // ==========================================================================
1920 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1923 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1924 PlayField16[*si + 1] = fiYellowDisk;
1925 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1926 PlayField16[*si + 2] = 0;
1928 subCopyImageToScreen(*si, aniMurphy);
1932 // ==========================================================================
1933 // time red disk release (space)
1934 // ==========================================================================
1937 if (DemoKeyCode != keySpace)
1939 PlayField16[*si] = fiMurphy;
1940 subCopyImageToScreen(*si, aniMurphy);
1941 RedDiskReleasePhase = 0;
1943 else if (MovingPictureSequencePhase == 0x20)
1945 // anxious murphy, dropping red disk
1946 subCopyImageToScreen(*si, aniMurphyDropping);
1947 RedDiskReleasePhase = 1;
1952 // ==========================================================================
1953 // Special port down to up
1954 // ==========================================================================
1957 if (LowByte(PlayField16[*si]) != fiExplosion)
1958 PlayField16[*si] = 0;
1960 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1962 *si = *si - FieldWidth;
1963 if (HighByte(PlayField16[*si]) == 1)
1966 *si = *si - FieldWidth;
1970 // ==========================================================================
1971 // Special port right to left
1972 // ==========================================================================
1975 if (LowByte(PlayField16[*si]) != fiExplosion)
1976 PlayField16[*si] = 0;
1978 PlayField16[*si - 2] = fiMurphy;
1981 if (HighByte(PlayField16[*si]) == 1)
1988 // ==========================================================================
1989 // Special port up to down
1990 // ==========================================================================
1993 if (LowByte(PlayField16[*si]) != fiExplosion)
1994 PlayField16[*si] = 0;
1996 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
1998 *si = *si + FieldWidth;
1999 if (HighByte(PlayField16[*si]) == 1)
2002 *si = *si + FieldWidth;
2006 // ==========================================================================
2007 // Special port left to right
2008 // ==========================================================================
2011 if (LowByte(PlayField16[*si]) != fiExplosion)
2012 PlayField16[*si] = 0;
2014 PlayField16[*si + 2] = fiMurphy;
2017 if (HighByte(PlayField16[*si]) == 1)
2024 // ==========================================================================
2026 // ==========================================================================
2029 if (LowByte(PlayField16[*si]) != fiExplosion)
2030 PlayField16[*si] = 0;
2032 *si = *si - FieldWidth;
2033 PlayField16[*si] = fiMurphy;
2034 subEatRedDisk(*si); // inc+show Murphy's red disks
2038 // ==========================================================================
2039 // Move Red Disk left
2040 // ==========================================================================
2043 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2044 PlayField16[*si + 1] = 0;
2046 PlayField16[*si] = fiMurphy;
2047 subEatRedDisk(*si); // inc+show Murphy's red disks
2051 // ==========================================================================
2052 // Move Red Disk down
2053 // ==========================================================================
2056 if (LowByte(PlayField16[*si]) != fiExplosion)
2057 PlayField16[*si] = 0;
2059 *si = *si + FieldWidth;
2060 PlayField16[*si] = fiMurphy;
2061 subEatRedDisk(*si); // inc+show Murphy's red disks
2065 // ==========================================================================
2066 // Move Red Disk right
2067 // ==========================================================================
2070 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2071 PlayField16[*si - 1] = 0;
2073 PlayField16[*si] = fiMurphy;
2074 subEatRedDisk(*si); // inc+show Murphy's red disks
2078 // ==========================================================================
2080 // ==========================================================================
2083 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2084 PlayField16[*si - FieldWidth] = 0;
2086 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2090 // ==========================================================================
2091 // Eat Red Disk left
2092 // ==========================================================================
2095 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2096 PlayField16[*si - 1] = 0;
2098 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2102 // ==========================================================================
2103 // Eat Red Disk down
2104 // ==========================================================================
2107 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2108 PlayField16[*si + FieldWidth] = 0;
2110 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2114 // ==========================================================================
2115 // Eat Red Disk right
2116 // ==========================================================================
2119 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2120 PlayField16[*si + 1] = 0;
2122 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2126 // ==========================================================================
2127 // yellow disk, pushing up
2128 // ==========================================================================
2131 if (LowByte(PlayField16[*si]) != fiExplosion)
2132 PlayField16[*si] = 0;
2134 *si = *si - FieldWidth;
2135 PlayField16[*si] = fiMurphy;
2136 PlayField16[*si - FieldWidth] = fiYellowDisk;
2140 // ==========================================================================
2141 // yellow disk, pushing left
2142 // ==========================================================================
2145 if (LowByte(PlayField16[*si]) != fiExplosion)
2146 PlayField16[*si] = 0;
2149 PlayField16[*si] = fiMurphy;
2150 PlayField16[*si - 1] = fiYellowDisk;
2154 // ==========================================================================
2155 // yellow disk, pushing down
2156 // ==========================================================================
2159 if (LowByte(PlayField16[*si]) != fiExplosion)
2160 PlayField16[*si] = 0;
2162 *si = *si + FieldWidth;
2163 PlayField16[*si] = fiMurphy;
2164 PlayField16[*si + FieldWidth] = fiYellowDisk;
2168 // ==========================================================================
2169 // yellow disk pushing right
2170 // ==========================================================================
2173 if (LowByte(PlayField16[*si]) != fiExplosion)
2174 PlayField16[*si] = 0;
2177 PlayField16[*si] = fiMurphy;
2178 PlayField16[*si + 1] = fiYellowDisk;
2182 // ==========================================================================
2183 // orange disk, pushing left
2184 // ==========================================================================
2187 if (LowByte(PlayField16[*si]) != fiExplosion)
2188 PlayField16[*si] = 0;
2191 PlayField16[*si] = fiMurphy;
2192 PlayField16[*si - 1] = fiOrangeDisk;
2196 // ==========================================================================
2197 // orange disk, pushing right
2198 // ==========================================================================
2201 if (LowByte(PlayField16[*si]) != fiExplosion)
2202 PlayField16[*si] = 0;
2205 PlayField16[*si] = fiMurphy;
2206 PlayField16[*si + 1] = fiOrangeDisk;
2207 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2209 MovHighByte(&PlayField16[*si + 1], 0x20);
2210 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2215 // ==========================================================================
2216 // Release a red disk
2217 // ==========================================================================
2220 PlayField16[*si] = fiMurphy;
2221 RedDiskReleasePhase = 2;
2222 RedDiskCount = RedDiskCount - 1;
2224 subSoundFX(*si, fiRedDisk, actDropping);
2225 } // subAnimateMurphy
2227 // ==========================================================================
2229 // ==========================================================================
2230 void subExplodeSnikSnaksBelow(int si)
2234 ax = LowByte(PlayField16[si + FieldWidth]);
2235 if (ax == 0x11 || ax == 0xBB)
2236 ExplodeFieldSP(si + FieldWidth);
2237 } // subExplodeSnikSnaksBelow
2239 // ==========================================================================
2241 // Does pushing against an object kill Murphy?
2242 // ==========================================================================
2243 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2245 static boolean subMoveKillsMurphy;
2251 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2257 if (al == fiExplosion)
2260 if (fiOrangeDisk <= al && al <= fiPortUp)
2263 ExplodeFieldSP(si); // Explode
2264 subMoveKillsMurphy = True;
2265 return subMoveKillsMurphy;
2274 ExplodeFieldSP(si); // Explode
2275 subMoveKillsMurphy = True;
2276 return subMoveKillsMurphy;
2278 loc_g_74F6: // zonk left
2280 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2283 subMoveKillsMurphy = True; // Set carry flag
2284 return subMoveKillsMurphy;
2286 loc_g_7512: // zonk right
2288 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2291 loc_g_752E: // Marked fields and Ports
2292 subMoveKillsMurphy = True; // Set carry flag
2293 return subMoveKillsMurphy;
2295 loc_g_7530: // explosion
2296 if ((ah & 0x80) != 0)
2303 ExplodeFieldSP(si); // Explode
2304 subMoveKillsMurphy = True; // Set carry flag
2305 return subMoveKillsMurphy;
2308 PlayField16[si] = 0;
2309 subMoveKillsMurphy = False;
2311 return subMoveKillsMurphy;
2312 } // subMoveKillsMurphy
2314 // ==========================================================================
2316 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2317 // change conditions to port specs
2318 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2319 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2320 // ==========================================================================
2322 void subSpPortTest(int si)
2326 for (i = 0; i < LInfo.SpecialPortCount; i++)
2328 if (LInfo.SpecialPort[i].PortLocation / 2 == si)
2330 GravityFlag = LInfo.SpecialPort[i].Gravity;
2331 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2332 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2339 void subCopyAnimToScreen(int si, int graphic, int sync_frame)
2343 // +++++++++++++++++++++++++++++++++++++++++
2344 X = GetStretchX(si);
2345 Y = GetStretchY(si);
2346 DDSpriteBuffer_BltImg(X, Y, graphic, sync_frame);
2347 // +++++++++++++++++++++++++++++++++++++++++
2350 void subCopyImageToScreen(int si, int graphic)
2352 subCopyAnimToScreen(si, graphic, 0);
2355 static void subEatRedDisk(int si)
2357 if (AllowRedDiskCheat == 0)
2359 if (RedDiskReleasePhase != 0)
2361 if (RedDiskReleaseMurphyPos == si)
2366 RedDiskCount = (RedDiskCount + 1) % 256;
2369 void subAdjustZonksInfotronsAboveMurphy(int si)
2373 if (LowByte(PlayField16[si]) != fiExplosion)
2374 PlayField16[si] = 0;
2376 ax = PlayField16[si - FieldWidth];
2377 if (ax == 0 || ax == 0x9999)
2380 if (ax == fiZonk || ax == fiInfotron)
2382 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2387 loc_g_15A8: // empty above
2388 ax = PlayField16[si - FieldWidth - 1];
2389 if (ax == fiZonk || ax == fiInfotron)
2393 ax = PlayField16[si - FieldWidth + 1];
2394 if (ax == fiZonk || ax == fiInfotron)
2399 loc_g_15C5: // zonk/infotron above left
2400 ax = PlayField16[si - 1];
2401 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2404 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2405 PlayField16[si - FieldWidth] = 0x8888;
2409 loc_g_15E8: // zonk/infotron above right
2410 ax = PlayField16[si + 1];
2411 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2413 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2414 PlayField16[si - FieldWidth] = 0x8888;