1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
8 static void subEatRedDisk(int si);
9 static boolean subMoveKillsMurphy(int si, int ax, int bl);
13 #define LocalStretch (2)
14 #define MurphyZoomFactor (ZoomFactor)
18 #define LocalStretch (1)
19 #define MurphyZoomFactor (1)
23 // ==========================================================================
25 // Move Murphy in any direction
26 // ==========================================================================
28 void subAnimateMurphy(int *si)
30 int ax, al, bl, i, X, Y;
32 int tDeltaX, tDeltaY, tPos, Tmp;
34 // Variables that hold information about the animation sequence
35 static int dx1 = 0; // image/animation token
36 static int dx2 = 0; // an additional image position of a second sprite, for instance: yellow disk if pushed
37 static int MurphyDX = 0, MurphyDY = 0; // murphys move steps
38 static int SeqPos = 0; // index into dx()
39 static int ClearPos = 0; // Position to clear before blitting sprites, none=-1
40 static int dxPos = 0; // field-position to draw dx(SeqPos)
41 static int dx2Step = 0; // position of dx2 relative to dx-position
42 static int dx1SequenceLength = 0;
44 ax = PlayField16[*si];
49 MurphyMoveCounter = 0; // We have no Murphy! Exit!
54 MurphyMoveCounter = 1; // We have a Murphy!
55 MurphyExplodePos = *si;
57 // (check if high byte of PlayField16 has stored movement information)
58 if (ax != fiMurphy) // yes--go proceed moving murphy?
59 goto locProceedMovingMurphy;
61 // FS: reset moving sequence variables
71 ScratchGravity = 0; // scratch gravity off
72 if (GravityFlag != 0) // Gravity? (1=gravity on)
74 bl = LowByte(PlayField16[*si - FieldWidth]); // check above
75 if (! (bl == fiPortUp ||
76 bl == fiPortUpAndDown ||
77 bl == fiPortAllDirections))
79 if (PlayField16[*si + FieldWidth] == 0) // gravity on and space below!
85 printf("::: RedDiskReleaseFlag == %d\n", RedDiskReleaseFlag);
89 if (bl != 0) // a key was pressed!
90 goto locKeyPressed5FCF;
92 RedDiskReleaseFlag = 1;
93 if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
107 // ------------------------------------------------------------------
108 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
110 YawnSleepCounter = YawnSleepCounter + 1;
112 if (YawnSleepCounter < 16)
115 if (YawnSleepCounter < 2000)
118 // (default: single graphic, no animation)
119 subCopyAnimToScreen(*si, aniMurphy, YawnSleepCounter - 16);
124 if (YawnSleepCounter < 4000)
126 // yawn! and look depressed afterwards...
127 // (default: 12 animation frames with delay of 8)
128 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 2000);
133 if (YawnSleepCounter < 6400)
136 // (default: 12 animation frames with delay of 8)
137 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 4000);
142 // time1 = 6400 + 12 * 8; // (default: 6496 == 6400 + 12 * 8)
143 time1 = 6400 + 12 * 10;
145 if (YawnSleepCounter < time1)
147 // yawn again! - third time
148 // (default: 12 animation frames with delay of 8)
149 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 6400);
154 // time2 = 6496 + 3 * 64; // (default: 6688 == 6496 + 3 * 64)
155 time2 = 6496 + 3 * 100;
157 if (YawnSleepCounter > time2) // Murphy already went to sleep
160 if (PlayField16[*si - 1] == 0)
162 if (PlayField16[*si + 1] == 0)
164 // no sleep -- go back to "wait and start yawning" phase
165 YawnSleepCounter = 144;
171 // go to sleep (right side)
172 // (default: 3 animation frames with delay of 64)
173 subCopyAnimToScreen(*si, aniMurphySleepRight, YawnSleepCounter - time1);
179 // go to sleep (left side)
180 // (default: 3 animation frames with delay of 64)
181 subCopyAnimToScreen(*si, aniMurphySleepLeft, YawnSleepCounter - time1);
185 // end of YAWN-SLEEP-Sequence
193 // ------------------------------------------------------------------
194 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
195 YawnSleepCounter = YawnSleepCounter + 1;
196 if (YawnSleepCounter == 4)
198 subCopyFieldToScreen(*si, fiMurphy); // normal grin
202 if (YawnSleepCounter <= 500) // loc_g_5ED7:
205 if (YawnSleepCounter <= 522)
207 bx = (YawnSleepCounter - 500) / 2;
208 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
212 if (YawnSleepCounter <= 1000)
215 if (YawnSleepCounter <= 1022)
217 bx = (YawnSleepCounter - 1000) / 2;
218 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again!
222 if (YawnSleepCounter <= 1600) // loc_g_5F3B:
225 if (YawnSleepCounter <= 1622)
227 bx = (YawnSleepCounter - 1600) / 2;
228 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again! - third time
232 if (YawnSleepCounter > 1654)
235 if (PlayField16[*si - 1] == 0)
237 if (PlayField16[*si + 1] == 0)
239 YawnSleepCounter = 36;
245 bx = (YawnSleepCounter - 1622) / 16;
246 subCopyFieldToScreen(*si, aniMurphySleepRight + bx); // go to sleep
251 bx = (YawnSleepCounter - 1622) / 16;
252 subCopyFieldToScreen(*si, aniMurphySleepLeft + bx); // go to sleep
256 // end of YAWN-SLEEP-Sequence
260 // ------------------------------------------------------------------
261 // ==========================================================================
262 // (Direct Jump) a key was pressed
263 // ==========================================================================
266 if (ScratchGravity == 0)
269 if (PlayField16[*si + FieldWidth] != 0)
274 if (PlayField16[*si - FieldWidth] == fiBase)
278 else if (bl == keyLeft)
280 if (PlayField16[*si - 1] == fiBase)
284 else if (bl == keyRight)
286 if (PlayField16[*si + 1] == fiBase)
290 bl = keyDown; // force moving down!
295 RedDiskReleaseFlag = 0; // moving down to up ...
301 RedDiskReleaseFlag = 0; // moving right to left ...
307 RedDiskReleaseFlag = 0; // moving up to down ...
313 RedDiskReleaseFlag = 0; // moving left to right ...
318 case keySpaceUp: // 5
319 RedDiskReleaseFlag = 0; // touching down to up ...
324 case keySpaceLeft: // 6
325 RedDiskReleaseFlag = 0; // touching right to left ...
330 case keySpaceDown: // 7
331 RedDiskReleaseFlag = 0; // touching up to down ...
336 case keySpaceRight: // 8
337 RedDiskReleaseFlag = 0; // touching left to right ...
343 goto loc_g_62E2; // no move ...
348 RedDiskReleaseFlag = 0;
353 // ==========================================================================
354 // moving down to up ...
355 // ==========================================================================
361 ax = PlayField16[*si - FieldWidth];
372 if (ax == fiInfotron)
378 if (al == fiTerminal)
381 if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
387 if (al == fiYellowDisk)
390 if (! subMoveKillsMurphy(*si - FieldWidth, ax, bl))
395 // ==========================================================================
396 // moving right to left ...
397 // ==========================================================================
403 MurphyVarFaceLeft = 1;
404 ax = PlayField16[*si - 1];
415 if (ax == fiInfotron)
424 if (al == fiTerminal)
427 if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
433 if (ax == fiYellowDisk)
436 if (ax == fiOrangeDisk)
439 if (! subMoveKillsMurphy(*si - 1, ax, bl))
444 // ==========================================================================
445 // moving up to down ...
446 // ==========================================================================
452 ax = PlayField16[*si + FieldWidth];
463 if (ax == fiInfotron)
469 if (al == fiTerminal)
472 if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
478 if (al == fiYellowDisk)
481 if (! subMoveKillsMurphy(*si + FieldWidth, ax, bl))
486 // ==========================================================================
487 // moving left to right ...
488 // ==========================================================================
494 MurphyVarFaceLeft = 0;
495 ax = PlayField16[*si + 1];
506 if (ax == fiInfotron)
515 if (al == fiTerminal)
518 if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
524 if (al == fiYellowDisk)
527 if (ax == fiOrangeDisk)
530 if (! subMoveKillsMurphy(*si + 1, ax, bl))
535 // ==========================================================================
536 // touching down to up ...
537 // ==========================================================================
542 dxPos = *si - FieldWidth;
544 ax = PlayField16[*si - FieldWidth];
553 if (ax == fiInfotron)
556 if (al == fiTerminal)
564 // ==========================================================================
565 // touching right to left ...
566 // ==========================================================================
573 MurphyVarFaceLeft = 1;
574 ax = PlayField16[*si - 1];
582 if (ax == fiInfotron)
585 if (al == fiTerminal)
593 // ==========================================================================
594 // touching up to down ...
595 // ==========================================================================
600 dxPos = *si + FieldWidth;
602 ax = PlayField16[*si + FieldWidth];
610 if (ax == fiInfotron)
613 if (al == fiTerminal)
621 // ==========================================================================
622 // touching left to right ...
623 // ==========================================================================
630 MurphyVarFaceLeft = 0;
631 ax = PlayField16[*si + 1];
639 if (ax == fiInfotron)
642 if (al == fiTerminal)
650 // ==========================================================================
651 // Release Red disk: no move ...
652 // ==========================================================================
658 if (LowByte(RedDiskCount) == 0)
661 if (LowByte(RedDiskReleasePhase) != 0)
664 if (LowByte(RedDiskReleaseFlag) != 1)
667 MovHighByte(&PlayField16[*si], 0x2A);
668 MovingPictureSequencePhase = 0x40; // init picture move sequence
670 MovLowByte(&RedDiskReleasePhase, 1);
671 RedDiskReleaseMurphyPos = *si; // remember Murphy's location
674 // ==========================================================================
675 // SPACE moving down to up
676 // ==========================================================================
679 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyMoveUpRight : aniMurphyMoveUpLeft);
680 PlayField16[*si - FieldWidth] = 0x103;
681 PlayField16[*si] = 0x300;
682 *si = *si - FieldWidth;
683 goto loc_StopNoSplit;
685 // ==========================================================================
686 // SPACE moving right to left
687 // ==========================================================================
690 dx1 = aniMurphyMoveLeft;
691 PlayField16[*si - 1] = 0x203;
692 PlayField16[*si] = 0x300;
694 goto loc_StopNoSplit;
696 // ==========================================================================
697 // SPACE moving up to down, and when gravity is pulling!
698 // ==========================================================================
701 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyMoveUpRight : aniMurphyMoveUpLeft);
702 PlayField16[*si + FieldWidth] = 0x303;
703 PlayField16[*si] = 0x300;
704 *si = *si + FieldWidth;
705 goto loc_StopNoSplit;
707 // ==========================================================================
708 // SPACE moving left to right
709 // ==========================================================================
712 dx1 = aniMurphyMoveRight;
713 PlayField16[*si + 1] = 0x403;
714 PlayField16[*si] = 0x300;
716 goto loc_StopNoSplit;
718 // ==========================================================================
719 // BUG moving down to up
720 // ==========================================================================
723 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
725 ExplodeFieldSP(*si); // Explode
730 PlayField16[*si - FieldWidth] = fiBase;
731 // ==========================================================================
732 // BASE moving down to up
733 // ==========================================================================
736 subSoundFX(*si, fiBase, actDigging);
738 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyDigUpRight : aniMurphyDigUpLeft);
739 PlayField16[*si - FieldWidth] = 0x503;
740 PlayField16[*si] = 0x300;
741 *si = *si - FieldWidth;
742 goto loc_StopNoSplit;
744 // ==========================================================================
745 // BUG moving right to left
746 // ==========================================================================
749 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
751 ExplodeFieldSP(*si); // Explode
756 PlayField16[*si - 1] = fiBase;
757 // ==========================================================================
758 // BASE moving right to left
759 // ==========================================================================
762 subSoundFX(*si, fiBase, actDigging);
764 dx1 = aniMurphyDigLeft;
765 PlayField16[*si - 1] = 0x203;
766 PlayField16[*si] = 0x300;
768 goto loc_StopNoSplit;
770 // ==========================================================================
771 // BUG moving up to down
772 // ==========================================================================
775 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
777 ExplodeFieldSP(*si); // Explode
782 PlayField16[*si + FieldWidth] = fiBase;
783 // ==========================================================================
784 // BASE moving up to down
785 // ==========================================================================
788 subSoundFX(*si, fiBase, actDigging);
790 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyDigUpRight : aniMurphyDigUpLeft);
791 PlayField16[*si + FieldWidth] = 0x703;
792 PlayField16[*si] = 0x300;
793 *si = *si + FieldWidth;
794 goto loc_StopNoSplit;
796 // ==========================================================================
797 // BUG moving left to right
798 // ==========================================================================
801 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
803 ExplodeFieldSP(*si); // Explode
808 PlayField16[*si + 1] = fiBase;
809 // ==========================================================================
810 // BASE moving left to right
811 // ==========================================================================
814 subSoundFX(*si, fiBase, actDigging);
816 dx1 = aniMurphyDigRight;
817 PlayField16[*si + 1] = 0x803;
818 PlayField16[*si] = 0x300;
820 goto loc_StopNoSplit;
822 // ==========================================================================
823 // BUG touching down to up
824 // ==========================================================================
827 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
829 ExplodeFieldSP(*si); // Explode
834 PlayField16[*si - FieldWidth] = fiBase;
835 // ==========================================================================
836 // BASE touching down to up
837 // ==========================================================================
840 subCopyImageToScreen(*si, aniMurphyTouchUp);
841 subSoundFX(*si, fiBase, actDigging);
844 dxPos = *si - FieldWidth;
845 MovHighByte(&PlayField16[*si], 0x10);
846 goto loc_StopNoSplit;
848 // ==========================================================================
849 // BUG touching right to left
850 // ==========================================================================
853 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
855 ExplodeFieldSP(*si); // Explode
860 PlayField16[*si - 1] = fiBase;
861 // ==========================================================================
862 // BASE touching right to left
863 // ==========================================================================
866 subCopyImageToScreen(*si, aniMurphyTouchLeft);
867 subSoundFX(*si, fiBase, actDigging);
871 MovHighByte(&PlayField16[*si], 0x11);
872 goto loc_StopNoSplit;
874 // ==========================================================================
875 // BUG touching up to down
876 // ==========================================================================
879 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
881 ExplodeFieldSP(*si); // Explode
886 PlayField16[*si + FieldWidth] = fiBase;
887 // ==========================================================================
888 // BASE touching up to down
889 // ==========================================================================
892 subCopyImageToScreen(*si, aniMurphyTouchDown);
893 subSoundFX(*si, fiBase, actDigging);
896 dxPos = *si + FieldWidth;
897 MovHighByte(&PlayField16[*si], 0x12);
898 goto loc_StopNoSplit;
900 // ==========================================================================
901 // BUG touching left to right
902 // ==========================================================================
905 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
907 ExplodeFieldSP(*si); // Explode
912 PlayField16[*si + 1] = fiBase;
913 // ==========================================================================
914 // BASE touching left to right
915 // ==========================================================================
918 subCopyImageToScreen(*si, aniMurphyTouchRight);
919 subSoundFX(*si, fiBase, actDigging);
923 MovHighByte(&PlayField16[*si], 0x13);
924 goto loc_StopNoSplit;
926 // ==========================================================================
927 // INFOTRON moving down to up
928 // ==========================================================================
931 subSoundFX(*si, fiInfotron, actCollecting);
933 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
934 PlayField16[*si - FieldWidth] = 0x903;
935 PlayField16[*si] = 0x300;
936 *si = *si - FieldWidth;
937 goto loc_StopNoSplit;
939 // ==========================================================================
940 // INFOTRON moving right to left
941 // ==========================================================================
944 subSoundFX(*si, fiInfotron, actCollecting);
946 dx1 = aniEatInfotronLeft;
952 PlayField16[*si - 1] = 0xA03;
953 PlayField16[*si] = 0x300;
955 goto loc_StopNoSplit;
957 // ==========================================================================
958 // INFOTRON moving up to down
959 // ==========================================================================
962 subSoundFX(*si, fiInfotron, actCollecting);
964 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
965 PlayField16[*si + FieldWidth] = 0xB03;
966 PlayField16[*si] = 0x300;
967 *si = *si + FieldWidth;
968 goto loc_StopNoSplit;
970 // ==========================================================================
971 // INFOTRON moving left to right
972 // ==========================================================================
975 subSoundFX(*si, fiInfotron, actCollecting);
977 dx1 = aniEatInfotronRight;
983 PlayField16[*si + 1] = 0xC03;
984 PlayField16[*si] = 0x300;
986 goto loc_StopNoSplit;
988 // ==========================================================================
989 // INFOTRON touching down to up
990 // ==========================================================================
993 subCopyImageToScreen(*si, aniMurphyTouchUp);
994 subSoundFX(*si, fiInfotron, actCollecting);
996 dx1 = aniTouchInfotron;
997 MovHighByte(&PlayField16[*si], 0x14);
998 MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
999 goto loc_StopNoSplit;
1001 // ==========================================================================
1002 // INFOTRON touching right to left
1003 // ==========================================================================
1006 subCopyImageToScreen(*si, aniMurphyTouchLeft);
1007 subSoundFX(*si, fiInfotron, actCollecting);
1009 dx1 = aniTouchInfotron;
1010 MovHighByte(&PlayField16[*si], 0x15);
1011 MovHighByte(&PlayField16[*si - 1], 0xFF);
1012 goto loc_StopNoSplit;
1014 // ==========================================================================
1015 // INFOTRON touching up to down
1016 // ==========================================================================
1019 subCopyImageToScreen(*si, aniMurphyTouchDown);
1020 subSoundFX(*si, fiInfotron, actCollecting);
1022 dx1 = aniTouchInfotron;
1023 MovHighByte(&PlayField16[*si], 0x16);
1024 MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
1025 goto loc_StopNoSplit;
1027 // ==========================================================================
1028 // INFOTRON touching left to right
1029 // ==========================================================================
1032 subCopyImageToScreen(*si, aniMurphyTouchRight);
1033 subSoundFX(*si, fiInfotron, actCollecting);
1035 dx1 = aniTouchInfotron;
1036 MovHighByte(&PlayField16[*si], 0x17);
1037 MovHighByte(&PlayField16[*si + 1], 0xFF);
1038 goto loc_StopNoSplit;
1040 // ==========================================================================
1041 // EXIT pressed from any direction
1042 // ==========================================================================
1050 if (LowByte(InfotronsNeeded) != 0)
1054 if (!game_sp.LevelSolved)
1055 printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n", level_nr);
1059 game_sp.LevelSolved = TRUE;
1062 subSoundFX(*si, fiExit, actPassing);
1064 LeadOutCounter = 0x40; // quit: start lead-out
1065 dx1 = aniMurphyExit;
1066 MovHighByte(&PlayField16[*si], 0xD);
1067 goto loc_StopNoSplit;
1069 // ==========================================================================
1070 // ZONK moving right to left
1071 // ==========================================================================
1074 ax = PlayField16[*si - 2];
1078 MovHighByte(&PlayField16[*si - 2], 1);
1079 subCopyImageToScreen(*si, aniPushLeft); // draw pushing murphy
1080 dx1 = aniZonkRollLeft;
1084 MovHighByte(&PlayField16[*si], 0xE);
1085 goto loc_MoveNoSplit;
1087 // ==========================================================================
1088 // ZONK moving left to right
1089 // ==========================================================================
1092 ax = PlayField16[*si + 2];
1096 ax = PlayField16[*si + FieldWidth + 1];
1097 if (ax == 0) // zonk falls
1100 MovHighByte(&PlayField16[*si + 2], 1);
1101 subCopyImageToScreen(*si, aniPushRight); // draw pushing murphy
1102 dx1 = aniZonkRollRight;
1106 MovHighByte(&PlayField16[*si], 0xF);
1107 goto loc_MoveNoSplit;
1109 // ==========================================================================
1110 // TERMINAL moving/touching down to up
1111 // ==========================================================================
1114 subCopyImageToScreen(*si, aniMurphyTouchUp);
1115 if (YellowDisksExploded != 0)
1117 YawnSleepCounter = 40; // stay hypnotized
1123 // draw new terminal type
1125 GfxGraphic[GetX(*si - FieldWidth)][GetY(*si - FieldWidth)] = aniTerminalActive;
1127 subCopyImageToScreen(*si - FieldWidth, aniTerminalActive);
1130 subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1132 TerminalState[*si - FieldWidth] = 8;
1135 // ==========================================================================
1136 // TERMINAL moving/touching right to left
1137 // ==========================================================================
1140 subCopyImageToScreen(*si, aniMurphyTouchLeft);
1141 if (YellowDisksExploded != 0)
1143 YawnSleepCounter = 40; // stay hypnotized
1149 // draw new terminal type
1151 GfxGraphic[GetX(*si - 1)][GetY(*si - 1)] = aniTerminalActive;
1153 subCopyImageToScreen(*si - 1, aniTerminalActive);
1156 subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1158 TerminalState[*si - 1] = 8;
1161 // ==========================================================================
1162 // TERMINAL moving/touching up to down
1163 // ==========================================================================
1166 subCopyImageToScreen(*si, aniMurphyTouchDown);
1167 if (YellowDisksExploded != 0)
1169 YawnSleepCounter = 40; // stay hypnotized
1175 // draw new terminal type
1177 GfxGraphic[GetX(*si + FieldWidth)][GetY(*si + FieldWidth)] = aniTerminalActive;
1179 subCopyImageToScreen(*si + FieldWidth, aniTerminalActive);
1182 subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1184 TerminalState[*si + FieldWidth] = 8;
1187 // ==========================================================================
1188 // TERMINAL moving/touching left to right
1189 // ==========================================================================
1192 subCopyImageToScreen(*si, aniMurphyTouchRight);
1193 if (YellowDisksExploded != 0)
1195 YawnSleepCounter = 40; // stay hypnotized
1201 // draw new terminal type
1203 GfxGraphic[GetX(*si + 1)][GetY(*si + 1)] = aniTerminalActive;
1205 subCopyImageToScreen(*si + 1, aniTerminalActive);
1208 subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1210 TerminalState[*si + 1] = 8;
1211 // ==========================================================================
1212 // common TERMINAL stuff moving/touching from all directions
1213 // ==========================================================================
1216 TerminalMaxCycles = 7;
1217 YellowDisksExploded = 1;
1218 for (i = 0; i <= LevelMax; i++)
1220 if (PlayField16[i] == fiYellowDisk)
1226 // ==========================================================================
1227 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1228 // ==========================================================================
1231 if (PlayField16[*si - 2 * FieldWidth] != 0)
1234 dx1 = aniSplitUpDown;
1235 dx2Step = -FieldWidth;
1236 PlayField16[*si] = 0x1803;
1237 PlayField16[*si - 2 * FieldWidth] = 0x300;
1240 // ==========================================================================
1241 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1242 // ==========================================================================
1245 if (PlayField16[*si - 2] != 0)
1248 dx1 = aniMurphyMoveLeft;
1250 PlayField16[*si] = 0x1903;
1251 PlayField16[*si - 2] = 0x300;
1254 // ==========================================================================
1255 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1256 // ==========================================================================
1259 if (PlayField16[*si + 2 * FieldWidth] != 0)
1262 dx1 = aniSplitUpDown;
1263 dx2Step = FieldWidth;
1264 PlayField16[*si] = 0x1A03;
1265 PlayField16[*si + 2 * FieldWidth] = 0x300;
1268 // ==========================================================================
1269 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1270 // ==========================================================================
1273 if (PlayField16[*si + 2] != 0)
1276 dx1 = aniMurphyMoveRight;
1278 PlayField16[*si] = 0x1B03;
1279 PlayField16[*si + 2] = 0x300;
1282 MovingPictureSequencePhase = 0; // stop picture move sequence
1283 SplitMoveFlag = 1; // port: split movement
1286 // ==========================================================================
1287 // RED DISK moving down to up
1288 // ==========================================================================
1291 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1292 PlayField16[*si] = 0x1C03;
1293 PlayField16[*si - FieldWidth] = 0x300;
1294 goto loc_StopNoSplit;
1296 // ==========================================================================
1297 // RED DISK moving right to left
1298 // ==========================================================================
1301 dx1 = aniMurphyEatLeft;
1302 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1303 PlayField16[*si - 1] = 0x1D03;
1305 goto loc_StopNoSplit;
1307 // ==========================================================================
1308 // RED DISK moving up to down
1309 // ==========================================================================
1312 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1313 PlayField16[*si] = 0x1E03;
1314 PlayField16[*si + FieldWidth] = 0x300;
1315 goto loc_StopNoSplit;
1317 // ==========================================================================
1318 // RED DISK moving left to right
1319 // ==========================================================================
1322 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1323 dx1 = aniMurphyEatRight;
1324 // --------------------------------------------------------------------------
1326 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1327 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1328 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1329 // We may not fix the table, because then the timing of the game changes
1330 // and several existing demo's do not run properly anymore.
1331 // We only correct Murphies x-location here, when the sequence starts.
1332 // Remember that this is not the real bug-fix, but we must live with
1333 // this existing bug and correct for the consequences of it.
1335 if (AllowEatRightRedDiskBug == 0) // Murphy's screen x-position
1336 MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1339 // FS: for me this means to blit the first animation frame twice
1341 // --------------------------------------------------------------------------
1342 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1343 PlayField16[*si + 1] = 0x1F03;
1345 goto loc_StopNoSplit;
1347 // ==========================================================================
1348 // RED DISK touching down to up
1349 // ==========================================================================
1352 dx1 = aniTouchRedDisk;
1353 MovHighByte(&PlayField16[*si], 0x20);
1354 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1355 goto loc_StopNoSplit;
1357 // ==========================================================================
1358 // RED DISK touching right to left
1359 // ==========================================================================
1362 dx1 = aniTouchRedDisk;
1363 MovHighByte(&PlayField16[*si], 0x21);
1364 MovHighByte(&PlayField16[*si - 1], 3);
1365 goto loc_StopNoSplit;
1367 // ==========================================================================
1368 // RED DISK touching up to down
1369 // ==========================================================================
1372 dx1 = aniTouchRedDisk;
1373 MovHighByte(&PlayField16[*si], 0x22);
1374 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1375 goto loc_StopNoSplit;
1377 // ==========================================================================
1378 // RED DISK touching left to right
1379 // ==========================================================================
1382 dx1 = aniTouchRedDisk;
1383 MovHighByte(&PlayField16[*si], 0x23);
1384 MovHighByte(&PlayField16[*si + 1], 3);
1387 MovingPictureSequencePhase = 0; // stop picture move sequence
1390 // ==========================================================================
1391 // YELLOW DISK moving down to up
1392 // ==========================================================================
1395 if (PlayField16[*si - 2 * FieldWidth] != 0)
1398 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1399 dx1 = aniYellowDisk;
1400 dxPos = *si - FieldWidth;
1401 dx2 = (MurphyVarFaceLeft == 0 ? aniPushRight : aniPushLeft);
1402 dx2Step = FieldWidth;
1403 PlayField16[*si] = 0x2403;
1404 subCopyImageToScreen(*si, dx2);
1405 goto loc_MoveNoSplit;
1407 // ==========================================================================
1408 // YELLOW DISK moving right to left
1409 // ==========================================================================
1412 if (PlayField16[*si - 2] != 0)
1415 PlayField16[*si - 2] = 0x1200;
1416 subCopyImageToScreen(*si, aniPushLeft);
1417 dx1 = aniYellowDisk;
1421 PlayField16[*si] = 0x2503;
1422 goto loc_MoveNoSplit;
1424 // ==========================================================================
1425 // YELLOW DISK moving up to down
1426 // ==========================================================================
1429 if (PlayField16[*si + 2 * FieldWidth] != 0)
1432 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1433 dx1 = aniYellowDisk;
1434 dxPos = *si + FieldWidth;
1435 dx2 = (MurphyVarFaceLeft == 0 ? aniPushRight : aniPushLeft);
1436 dx2Step = -FieldWidth;
1437 PlayField16[*si] = 0x2703;
1438 subCopyImageToScreen(*si, dx2);
1439 goto loc_MoveNoSplit;
1441 // ==========================================================================
1442 // YELLOW DISK moving left to right
1443 // ==========================================================================
1446 if (PlayField16[*si + 2] != 0)
1449 PlayField16[*si + 2] = 0x1200;
1450 subCopyImageToScreen(*si, aniPushRight);
1451 dx1 = aniYellowDisk;
1455 PlayField16[*si] = 0x2603;
1456 goto loc_MoveNoSplit;
1458 // ==========================================================================
1459 // ORANGE DISK moving right to left
1460 // ==========================================================================
1463 if (PlayField16[*si - 2] != 0)
1466 PlayField16[*si - 2] = 0x800;
1467 subCopyImageToScreen(*si, aniPushLeft);
1468 dx1 = aniOrangeDisk;
1472 PlayField16[*si] = 0x2803;
1473 goto loc_MoveNoSplit;
1475 // ==========================================================================
1476 // ORANGE DISK moving left to right
1477 // ==========================================================================
1480 if (PlayField16[*si + 2] != 0)
1483 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1486 PlayField16[*si + 2] = 0x100;
1487 subCopyImageToScreen(*si, aniPushRight);
1488 dx1 = aniOrangeDisk;
1492 PlayField16[*si] = 0x2903;
1493 // ==========================================================================
1494 // Copy screen animation action table to action work space
1495 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1496 // ==========================================================================
1499 MovingPictureSequencePhase = 8; // init picture move sequence
1502 SplitMoveFlag = 0; // no port: no split movement
1505 // copy/store global move sequence info????????????????????????????????????
1506 // ... dont think so ...(FS)
1507 // ==========================================================================
1508 // Proceed with all movements
1509 // ==========================================================================
1511 locProceedMovingMurphy: // proceed moving murphy
1512 YawnSleepCounter = 0; // Wake up sleeping Murphy
1513 ax = MovingPictureSequencePhase; // sequence busy?
1514 if (ax == 0) // no -- start sequence!
1517 ax = ax - 1; // next picture of sequence
1518 MovingPictureSequencePhase = ax; // store for later
1520 if (ax == 0) // Sound effects
1522 switch (HighByte(PlayField16[*si]))
1526 subSoundFX(*si, fiZonk, actPushing);
1531 subSoundFX(*si, fiOrangeDisk, actPushing);
1538 subSoundFX(*si, fiYellowDisk, actPushing);
1546 bl = HighByte(PlayField16[*si]);
1547 if (bl == 0xE) // Push Zonk to left
1550 if (bl == 0xF) // Push Zonk to right
1553 if (bl == 0x28) // Push orange disk to left
1556 if (bl == 0x29) // Push orange disk to right
1559 if (bl == 0x24) // Push yellow disk up
1562 if (bl == 0x25) // Push yellow disk to left
1565 if (bl == 0x27) // Push yellow disk down
1568 if (bl == 0x26) // Push yellow disk to right
1571 if (bl == 0x2A) // Red disk release timer
1576 // ==========================================================================
1577 // Paint frame of MOVING.DAT sequence
1578 // ==========================================================================
1584 dx1SequenceLength = getSequenceLength(dx1);
1587 if (SplitMoveFlag == 0)
1589 // ++++++++++++++++++++++++++
1590 // Begin of normal movement
1591 MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1592 MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1594 if (!(ClearPos < 0)) // clear field that murphy is leaving
1595 subCopyImageToScreen(ClearPos, aniSpace);
1598 // !!! special two-tile animation currently not used !!!
1599 if (dx2 == fiInfotron) // special case of infotron moving left or right
1607 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1608 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1611 X = GetStretchX(dxPos) + tDeltaX;
1612 Y = GetStretchY(dxPos) + tDeltaY;
1613 Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1616 if (isSnappingSequence(dx1) && SeqPos == dx1SequenceLength - 1)
1621 DDSpriteBuffer_BltImg(X, Y, dx1, Tmp);
1622 GfxGraphic[GetX(*si)][GetY(*si)] = -1; // (Murphy's position)
1623 GfxGraphic[GetX(dxPos)][GetY(dxPos)] = -1; // (snapping position)
1624 // printf("::: Tmp: %d\n", Tmp);
1626 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1631 tPos = dxPos + dx2Step;
1632 X = GetStretchX(tPos);
1633 Y = GetStretchY(tPos);
1635 // !!! special two-tile animation currently not used !!!
1636 if (dx2 == fiInfotron) // special case of infotron moving left or right
1638 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1640 else // pushing something
1643 // (SeqPos iterates from 0 to 7 while pushing)
1644 DDSpriteBuffer_BltImg(X + tDeltaX, Y + tDeltaY, dx2, SeqPos);
1648 // End of normal movement
1649 // ------------------------
1653 // ++++++++++++++++++++++++++++++++
1654 // Begin of split movement (port)
1655 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1656 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1657 subCopyImageToScreen(ClearPos, aniSpace); // clear the field that murphy leaves
1658 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1659 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1660 X = GetStretchX(dxPos) + tDeltaX;
1661 Y = GetStretchY(dxPos) + tDeltaY;
1662 DDSpriteBuffer_BltImg(X, Y, dx1, SeqPos); // plot first murphy
1664 tPos = dxPos + dx2Step;
1665 X = GetStretchX(tPos);
1666 Y = GetStretchY(tPos);
1667 DDSpriteBuffer_BltImg(X + tDeltaX, Y + tDeltaY, dx1, SeqPos); // plot second murphy
1668 DDSpriteBuffer_BltImg(X, Y, fiGraphic[LowByte(PlayField16[tPos])], 0); // replot the port on top
1669 // End of split movement (port)
1670 // ------------------------------
1671 } // loc_g_6D1E:'loc_g_6D28:
1673 SeqPos = SeqPos + 1;
1675 if (SeqPos < dx1SequenceLength)
1678 if (dx[SeqPos] > -1)
1682 // Follow-up after movement completed 'loc_g_6D35:
1683 MurphyXPos = MurphyXPos + MurphyDX;
1684 MurphyYPos = MurphyYPos + MurphyDY;
1685 bl = HighByte(PlayField16[*si]); // animation phase
1686 MovHighByte(&PlayField16[*si], 0);
1688 if (bl == 0x1) // space, moving up
1691 if (bl == 0x2) // space, moving left
1694 if (bl == 0x3) // space, moving down
1697 if (bl == 0x4) // space, moving right
1700 if (bl == 0x5) // base , moving up
1703 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1706 if (bl == 0x7) // base , moving down
1709 if (bl == 0x8) // base , moving right
1712 if (bl == 0x9) // infotron, moving up
1715 if (bl == 0xA) // infotron, moving left
1718 if (bl == 0xB) // infotron, moving down
1721 if (bl == 0xC) // infotron, moving right
1724 if (bl == 0xD) // exit
1727 if (bl == 0xE) // zonk, pushing left
1730 if (bl == 0xF) // zonk, pushing right
1733 if (bl == 0x10) // base , touching up
1736 if (bl == 0x11) // base , touching left
1739 if (bl == 0x12) // base , touching down
1742 if (bl == 0x13) // base , touching right
1745 if (bl == 0x14) // infotron touching up
1748 if (bl == 0x15) // infotron touching left
1751 if (bl == 0x16) // infotron touching down
1754 if (bl == 0x17) // infotron touching right
1757 if (bl == 0x18) // port up
1760 if (bl == 0x19) // port left
1763 if (bl == 0x1A) // port down
1766 if (bl == 0x1B) // port right
1769 if (bl == 0x1C) // red disk, moving up
1772 if (bl == 0x1D) // red disk, moving left
1775 if (bl == 0x1E) // red disk, moving down
1778 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1781 if (bl == 0x20) // red disk, touching up
1784 if (bl == 0x21) // red disk, touching left
1787 if (bl == 0x22) // red disk, touching down
1790 if (bl == 0x23) // red disk, touching right
1793 if (bl == 0x24) // yellow disk, pushing up
1796 if (bl == 0x25) // yellow disk, pushing left
1799 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1802 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1805 if (bl == 0x28) // orange disk, pushing left
1808 if (bl == 0x29) // orange disk, pushing right
1811 if (bl == 0x2A) // red disk, release
1818 // ==========================================================================
1819 // infotron, moving up
1820 // ==========================================================================
1823 if (0 < LowByte(InfotronsNeeded))
1824 InfotronsNeeded = InfotronsNeeded - 1;
1826 loc_g_6EC8: // space, base
1827 PlayField16[*si] = fiMurphy;
1828 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1832 // ==========================================================================
1833 // infotron, moving left
1834 // ==========================================================================
1837 if (0 < LowByte(InfotronsNeeded))
1838 InfotronsNeeded = InfotronsNeeded - 1;
1840 loc_g_6EE6: // space, base
1841 PlayField16[*si] = fiMurphy;
1842 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1846 // ==========================================================================
1847 // infotron, moving down
1848 // ==========================================================================
1851 if (0 < LowByte(InfotronsNeeded))
1852 InfotronsNeeded = InfotronsNeeded - 1;
1854 loc_g_6F04: // space, base
1855 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1856 PlayField16[*si - FieldWidth] = 0;
1858 PlayField16[*si] = fiMurphy;
1862 // ==========================================================================
1863 // infotron, moving right
1864 // ==========================================================================
1867 if (0 < LowByte(InfotronsNeeded))
1868 InfotronsNeeded = InfotronsNeeded - 1;
1870 loc_g_71C4: // space, base
1871 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1872 PlayField16[*si] = fiMurphy;
1876 // ==========================================================================
1877 // infotron, touching up
1878 // ==========================================================================
1881 if (0 < LowByte(InfotronsNeeded))
1882 InfotronsNeeded = InfotronsNeeded - 1;
1885 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1886 PlayField16[*si - FieldWidth] = 0;
1890 // ==========================================================================
1891 // infotron, touching left
1892 // ==========================================================================
1895 if (0 < LowByte(InfotronsNeeded))
1896 InfotronsNeeded = InfotronsNeeded - 1;
1899 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1900 PlayField16[*si - 1] = 0;
1904 // ==========================================================================
1905 // infotron, touching down
1906 // ==========================================================================
1909 if (0 < LowByte(InfotronsNeeded))
1910 InfotronsNeeded = InfotronsNeeded - 1;
1913 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1914 PlayField16[*si + FieldWidth] = 0;
1918 // ==========================================================================
1919 // infotron, touching right
1920 // ==========================================================================
1923 if (0 < LowByte(InfotronsNeeded))
1924 InfotronsNeeded = InfotronsNeeded - 1;
1927 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1928 PlayField16[*si + 1] = 0;
1932 // ==========================================================================
1933 // zonk, pushing left
1934 // ==========================================================================
1937 if (LowByte(PlayField16[*si]) != fiExplosion)
1938 PlayField16[*si] = 0;
1940 PlayField16[*si - 1] = fiMurphy;
1941 PlayField16[*si - 2] = fiZonk;
1942 subExplodeSnikSnaksBelow(*si - 2);
1947 // ==========================================================================
1948 // zonk, pushing right
1949 // ==========================================================================
1952 if (LowByte(PlayField16[*si]) != fiExplosion)
1953 PlayField16[*si] = 0;
1955 PlayField16[*si + 1] = fiMurphy;
1956 PlayField16[*si + 2] = fiZonk;
1957 subExplodeSnikSnaksBelow(*si + 2);
1962 // ==========================================================================
1964 // ==========================================================================
1970 PlayField16[*si] = fiSpace; // remove Murphy from playfield after exiting
1975 // ==========================================================================
1976 // Push Zonk from right to left
1977 // ==========================================================================
1980 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1983 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1984 PlayField16[*si - 1] = fiZonk;
1985 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1986 PlayField16[*si - 2] = 0;
1988 subCopyImageToScreen(*si, aniMurphy);
1992 // ==========================================================================
1993 // Push Zonk from left to right
1994 // ==========================================================================
1997 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
2000 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
2001 PlayField16[*si + 1] = fiZonk;
2002 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2003 PlayField16[*si + 2] = 0;
2005 subCopyImageToScreen(*si, aniMurphy);
2009 // ==========================================================================
2010 // Push orange disk from right to left
2011 // ==========================================================================
2014 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
2017 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2018 PlayField16[*si - 1] = fiOrangeDisk;
2019 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2020 PlayField16[*si - 2] = 0;
2022 subCopyImageToScreen(*si, aniMurphy);
2026 // ==========================================================================
2027 // Push orange disk from left to right
2028 // ==========================================================================
2031 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
2034 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2035 PlayField16[*si + 1] = fiOrangeDisk;
2036 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2037 PlayField16[*si + 2] = 0;
2039 subCopyImageToScreen(*si, aniMurphy);
2043 // ==========================================================================
2044 // Push yellow disk from down to up
2045 // ==========================================================================
2048 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
2051 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2052 PlayField16[*si - FieldWidth] = fiYellowDisk;
2053 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
2054 PlayField16[*si - 2 * FieldWidth] = 0;
2056 subCopyImageToScreen(*si, aniMurphy);
2060 // ==========================================================================
2061 // Push yellow disk from right to left
2062 // ==========================================================================
2065 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
2068 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2069 PlayField16[*si - 1] = fiYellowDisk;
2070 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2071 PlayField16[*si - 2] = 0;
2073 subCopyImageToScreen(*si, aniMurphy);
2077 // ==========================================================================
2078 // Push yellow disk from up to down
2079 // ==========================================================================
2082 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
2085 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2086 PlayField16[*si + FieldWidth] = fiYellowDisk;
2087 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
2088 PlayField16[*si + 2 * FieldWidth] = 0;
2090 subCopyImageToScreen(*si, aniMurphy);
2094 // ==========================================================================
2095 // Push yellow disk from left to right
2096 // ==========================================================================
2099 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
2102 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2103 PlayField16[*si + 1] = fiYellowDisk;
2104 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2105 PlayField16[*si + 2] = 0;
2107 subCopyImageToScreen(*si, aniMurphy);
2111 // ==========================================================================
2112 // time red disk release (space)
2113 // ==========================================================================
2116 if (DemoKeyCode != keySpace)
2118 PlayField16[*si] = fiMurphy;
2119 subCopyImageToScreen(*si, aniMurphy);
2120 RedDiskReleasePhase = 0;
2122 else if (MovingPictureSequencePhase == 0x20)
2124 // anxious murphy, dropping red disk
2125 subCopyImageToScreen(*si, aniMurphyDropping);
2126 RedDiskReleasePhase = 1;
2131 // ==========================================================================
2132 // Special port down to up
2133 // ==========================================================================
2136 if (LowByte(PlayField16[*si]) != fiExplosion)
2137 PlayField16[*si] = 0;
2139 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
2141 *si = *si - FieldWidth;
2142 if (HighByte(PlayField16[*si]) == 1)
2145 *si = *si - FieldWidth;
2149 // ==========================================================================
2150 // Special port right to left
2151 // ==========================================================================
2154 if (LowByte(PlayField16[*si]) != fiExplosion)
2155 PlayField16[*si] = 0;
2157 PlayField16[*si - 2] = fiMurphy;
2160 if (HighByte(PlayField16[*si]) == 1)
2167 // ==========================================================================
2168 // Special port up to down
2169 // ==========================================================================
2172 if (LowByte(PlayField16[*si]) != fiExplosion)
2173 PlayField16[*si] = 0;
2175 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2177 *si = *si + FieldWidth;
2178 if (HighByte(PlayField16[*si]) == 1)
2181 *si = *si + FieldWidth;
2185 // ==========================================================================
2186 // Special port left to right
2187 // ==========================================================================
2190 if (LowByte(PlayField16[*si]) != fiExplosion)
2191 PlayField16[*si] = 0;
2193 PlayField16[*si + 2] = fiMurphy;
2196 if (HighByte(PlayField16[*si]) == 1)
2203 // ==========================================================================
2205 // ==========================================================================
2208 if (LowByte(PlayField16[*si]) != fiExplosion)
2209 PlayField16[*si] = 0;
2211 *si = *si - FieldWidth;
2212 PlayField16[*si] = fiMurphy;
2213 subEatRedDisk(*si); // inc+show Murphy's red disks
2217 // ==========================================================================
2218 // Move Red Disk left
2219 // ==========================================================================
2222 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2223 PlayField16[*si + 1] = 0;
2225 PlayField16[*si] = fiMurphy;
2226 subEatRedDisk(*si); // inc+show Murphy's red disks
2230 // ==========================================================================
2231 // Move Red Disk down
2232 // ==========================================================================
2235 if (LowByte(PlayField16[*si]) != fiExplosion)
2236 PlayField16[*si] = 0;
2238 *si = *si + FieldWidth;
2239 PlayField16[*si] = fiMurphy;
2240 subEatRedDisk(*si); // inc+show Murphy's red disks
2244 // ==========================================================================
2245 // Move Red Disk right
2246 // ==========================================================================
2249 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2250 PlayField16[*si - 1] = 0;
2252 PlayField16[*si] = fiMurphy;
2253 subEatRedDisk(*si); // inc+show Murphy's red disks
2257 // ==========================================================================
2259 // ==========================================================================
2262 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2263 PlayField16[*si - FieldWidth] = 0;
2265 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2269 // ==========================================================================
2270 // Eat Red Disk left
2271 // ==========================================================================
2274 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2275 PlayField16[*si - 1] = 0;
2277 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2281 // ==========================================================================
2282 // Eat Red Disk down
2283 // ==========================================================================
2286 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2287 PlayField16[*si + FieldWidth] = 0;
2289 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2293 // ==========================================================================
2294 // Eat Red Disk right
2295 // ==========================================================================
2298 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2299 PlayField16[*si + 1] = 0;
2301 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2305 // ==========================================================================
2306 // yellow disk, pushing up
2307 // ==========================================================================
2310 if (LowByte(PlayField16[*si]) != fiExplosion)
2311 PlayField16[*si] = 0;
2313 *si = *si - FieldWidth;
2314 PlayField16[*si] = fiMurphy;
2315 PlayField16[*si - FieldWidth] = fiYellowDisk;
2319 // ==========================================================================
2320 // yellow disk, pushing left
2321 // ==========================================================================
2324 if (LowByte(PlayField16[*si]) != fiExplosion)
2325 PlayField16[*si] = 0;
2328 PlayField16[*si] = fiMurphy;
2329 PlayField16[*si - 1] = fiYellowDisk;
2333 // ==========================================================================
2334 // yellow disk, pushing down
2335 // ==========================================================================
2338 if (LowByte(PlayField16[*si]) != fiExplosion)
2339 PlayField16[*si] = 0;
2341 *si = *si + FieldWidth;
2342 PlayField16[*si] = fiMurphy;
2343 PlayField16[*si + FieldWidth] = fiYellowDisk;
2347 // ==========================================================================
2348 // yellow disk pushing right
2349 // ==========================================================================
2352 if (LowByte(PlayField16[*si]) != fiExplosion)
2353 PlayField16[*si] = 0;
2356 PlayField16[*si] = fiMurphy;
2357 PlayField16[*si + 1] = fiYellowDisk;
2361 // ==========================================================================
2362 // orange disk, pushing left
2363 // ==========================================================================
2366 if (LowByte(PlayField16[*si]) != fiExplosion)
2367 PlayField16[*si] = 0;
2370 PlayField16[*si] = fiMurphy;
2371 PlayField16[*si - 1] = fiOrangeDisk;
2375 // ==========================================================================
2376 // orange disk, pushing right
2377 // ==========================================================================
2380 if (LowByte(PlayField16[*si]) != fiExplosion)
2381 PlayField16[*si] = 0;
2384 PlayField16[*si] = fiMurphy;
2385 PlayField16[*si + 1] = fiOrangeDisk;
2386 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2388 MovHighByte(&PlayField16[*si + 1], 0x20);
2389 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2394 // ==========================================================================
2395 // Release a red disk
2396 // ==========================================================================
2399 PlayField16[*si] = fiMurphy;
2400 RedDiskReleasePhase = 2;
2401 RedDiskCount = RedDiskCount - 1;
2403 subSoundFX(*si, fiRedDisk, actDropping);
2404 } // subAnimateMurphy
2406 // ==========================================================================
2408 // ==========================================================================
2409 void subExplodeSnikSnaksBelow(int si)
2413 ax = LowByte(PlayField16[si + FieldWidth]);
2414 if (ax == 0x11 || ax == 0xBB)
2415 ExplodeFieldSP(si + FieldWidth);
2416 } // subExplodeSnikSnaksBelow
2418 // ==========================================================================
2420 // Does pushing against an object kill Murphy?
2421 // ==========================================================================
2422 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2424 static boolean subMoveKillsMurphy;
2430 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2436 if (al == fiExplosion)
2439 if (fiOrangeDisk <= al && al <= fiPortUp)
2442 ExplodeFieldSP(si); // Explode
2443 subMoveKillsMurphy = True;
2444 return subMoveKillsMurphy;
2453 ExplodeFieldSP(si); // Explode
2454 subMoveKillsMurphy = True;
2455 return subMoveKillsMurphy;
2457 loc_g_74F6: // zonk left
2459 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2462 subMoveKillsMurphy = True; // Set carry flag
2463 return subMoveKillsMurphy;
2465 loc_g_7512: // zonk right
2467 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2470 loc_g_752E: // Marked fields and Ports
2471 subMoveKillsMurphy = True; // Set carry flag
2472 return subMoveKillsMurphy;
2474 loc_g_7530: // explosion
2475 if ((ah & 0x80) != 0)
2482 ExplodeFieldSP(si); // Explode
2483 subMoveKillsMurphy = True; // Set carry flag
2484 return subMoveKillsMurphy;
2487 PlayField16[si] = 0;
2488 subMoveKillsMurphy = False;
2490 return subMoveKillsMurphy;
2491 } // subMoveKillsMurphy
2493 // ==========================================================================
2495 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2496 // change conditions to port specs
2497 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2498 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2499 // ==========================================================================
2501 void subSpPortTest(int si)
2505 for (i = 0; i < LInfo.SpecialPortCount; i++)
2507 if (LInfo.SpecialPort[i].PortLocation / 2 == si)
2509 GravityFlag = LInfo.SpecialPort[i].Gravity;
2510 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2511 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2518 void subCopyAnimToScreen(int si, int graphic, int sync_frame)
2522 // +++++++++++++++++++++++++++++++++++++++++
2523 X = GetStretchX(si);
2524 Y = GetStretchY(si);
2525 DDSpriteBuffer_BltImg(X, Y, graphic, sync_frame);
2526 // +++++++++++++++++++++++++++++++++++++++++
2529 void subCopyImageToScreen(int si, int graphic)
2531 subCopyAnimToScreen(si, graphic, 0);
2534 static void subEatRedDisk(int si)
2536 if (AllowRedDiskCheat == 0)
2538 if (RedDiskReleasePhase != 0)
2540 if (RedDiskReleaseMurphyPos == si)
2545 RedDiskCount = (RedDiskCount + 1) % 256;
2548 void subAdjustZonksInfotronsAboveMurphy(int si)
2552 if (LowByte(PlayField16[si]) != fiExplosion)
2553 PlayField16[si] = 0;
2555 ax = PlayField16[si - FieldWidth];
2556 if (ax == 0 || ax == 0x9999)
2559 if (ax == fiZonk || ax == fiInfotron)
2561 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2566 loc_g_15A8: // empty above
2567 ax = PlayField16[si - FieldWidth - 1];
2568 if (ax == fiZonk || ax == fiInfotron)
2572 ax = PlayField16[si - FieldWidth + 1];
2573 if (ax == fiZonk || ax == fiInfotron)
2578 loc_g_15C5: // zonk/infotron above left
2579 ax = PlayField16[si - 1];
2580 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2583 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2584 PlayField16[si - FieldWidth] = 0x8888;
2588 loc_g_15E8: // zonk/infotron above right
2589 ax = PlayField16[si + 1];
2590 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2592 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2593 PlayField16[si - FieldWidth] = 0x8888;