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 *dx = 0; // an array of image positions in moving.mpx, finalized with -1
36 static int dx1 = 0; // same as "*dx" above, but as image/animation token
37 static int dx2 = 0; // an additional image position of a second sprite, for instance: yellow disk if pushed
38 static int MurphyDX = 0, MurphyDY = 0; // murphys move steps
39 static int SeqPos = 0; // index into dx()
40 static int ClearPos = 0; // Position to clear before blitting sprites, none=-1
41 static int dxPos = 0; // field-position to draw dx(SeqPos)
42 static int dx2Step = 0; // position of dx2 relative to dx-position
43 static int dx1SequenceLength = 0;
45 ax = PlayField16[*si];
50 MurphyMoveCounter = 0; // We have no Murphy! Exit!
55 MurphyMoveCounter = 1; // We have a Murphy!
56 MurphyExplodePos = *si;
58 // (check if high byte of PlayField16 has stored movement information)
59 if (ax != fiMurphy) // yes--go proceed moving murphy?
60 goto locProceedMovingMurphy;
62 // FS: reset moving sequence variables
72 ScratchGravity = 0; // scratch gravity off
73 if (GravityFlag != 0) // Gravity? (1=gravity on)
75 bl = LowByte(PlayField16[*si - FieldWidth]); // check above
76 if (! (bl == fiPortUp ||
77 bl == fiPortUpAndDown ||
78 bl == fiPortAllDirections))
80 if (PlayField16[*si + FieldWidth] == 0) // gravity on and space below!
86 if (bl != 0) // a key was pressed!
87 goto locKeyPressed5FCF;
90 printf("::: Murphy.c: !!! %d [%d]\n", DemoKeyCode, GravityFlag);
93 RedDiskReleaseFlag = 1;
94 if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
108 // ------------------------------------------------------------------
109 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
111 YawnSleepCounter = YawnSleepCounter + 1;
113 if (YawnSleepCounter < 16)
116 if (YawnSleepCounter < 2000)
119 // (default: single graphic, no animation)
120 subCopyAnimToScreen(*si, aniMurphy, YawnSleepCounter - 16);
125 if (YawnSleepCounter < 4000)
127 // yawn! and look depressed afterwards...
128 // (default: 12 animation frames with delay of 8)
129 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 2000);
134 if (YawnSleepCounter < 6400)
137 // (default: 12 animation frames with delay of 8)
138 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 4000);
143 // time1 = 6400 + 12 * 8; // (default: 6496 == 6400 + 12 * 8)
144 time1 = 6400 + 12 * 10;
146 if (YawnSleepCounter < time1)
148 // yawn again! - third time
149 // (default: 12 animation frames with delay of 8)
150 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 6400);
155 // time2 = 6496 + 3 * 64; // (default: 6688 == 6496 + 3 * 64)
156 time2 = 6496 + 3 * 100;
158 if (YawnSleepCounter > time2) // Murphy already went to sleep
161 if (PlayField16[*si - 1] == 0)
163 if (PlayField16[*si + 1] == 0)
165 // no sleep -- go back to "wait and start yawning" phase
166 YawnSleepCounter = 144;
172 // go to sleep (right side)
173 // (default: 3 animation frames with delay of 64)
174 subCopyAnimToScreen(*si, aniMurphySleepRight, YawnSleepCounter - time1);
180 // go to sleep (left side)
181 // (default: 3 animation frames with delay of 64)
182 subCopyAnimToScreen(*si, aniMurphySleepLeft, YawnSleepCounter - time1);
186 // end of YAWN-SLEEP-Sequence
194 // ------------------------------------------------------------------
195 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
196 YawnSleepCounter = YawnSleepCounter + 1;
197 if (YawnSleepCounter == 4)
199 subCopyFieldToScreen(*si, fiMurphy); // normal grin
203 if (YawnSleepCounter <= 500) // loc_g_5ED7:
206 if (YawnSleepCounter <= 522)
208 bx = (YawnSleepCounter - 500) / 2;
209 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
213 if (YawnSleepCounter <= 1000)
216 if (YawnSleepCounter <= 1022)
218 bx = (YawnSleepCounter - 1000) / 2;
219 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again!
223 if (YawnSleepCounter <= 1600) // loc_g_5F3B:
226 if (YawnSleepCounter <= 1622)
228 bx = (YawnSleepCounter - 1600) / 2;
229 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again! - third time
233 if (YawnSleepCounter > 1654)
236 if (PlayField16[*si - 1] == 0)
238 if (PlayField16[*si + 1] == 0)
240 YawnSleepCounter = 36;
246 bx = (YawnSleepCounter - 1622) / 16;
247 subCopyFieldToScreen(*si, aniMurphySleepRight + bx); // go to sleep
252 bx = (YawnSleepCounter - 1622) / 16;
253 subCopyFieldToScreen(*si, aniMurphySleepLeft + bx); // go to sleep
257 // end of YAWN-SLEEP-Sequence
261 // ------------------------------------------------------------------
262 // ==========================================================================
263 // (Direct Jump) a key was pressed
264 // ==========================================================================
267 if (ScratchGravity == 0)
270 if (PlayField16[*si + FieldWidth] != 0)
275 if (PlayField16[*si - FieldWidth] == fiBase)
279 else if (bl == keyLeft)
281 if (PlayField16[*si - 1] == fiBase)
285 else if (bl == keyRight)
287 if (PlayField16[*si + 1] == fiBase)
291 bl = keyDown; // force moving down!
296 RedDiskReleaseFlag = 0; // moving down to up ...
302 RedDiskReleaseFlag = 0; // moving right to left ...
308 RedDiskReleaseFlag = 0; // moving up to down ...
314 RedDiskReleaseFlag = 0; // moving left to right ...
319 case keySpaceUp: // 5
320 RedDiskReleaseFlag = 0; // touching down to up ...
325 case keySpaceLeft: // 6
326 RedDiskReleaseFlag = 0; // touching right to left ...
331 case keySpaceDown: // 7
332 RedDiskReleaseFlag = 0; // touching up to down ...
337 case keySpaceRight: // 8
338 RedDiskReleaseFlag = 0; // touching left to right ...
344 goto loc_g_62E2; // no move ...
349 RedDiskReleaseFlag = 0;
354 // ==========================================================================
355 // moving down to up ...
356 // ==========================================================================
362 ax = PlayField16[*si - FieldWidth];
373 if (ax == fiInfotron)
379 if (al == fiTerminal)
382 if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
388 if (al == fiYellowDisk)
391 if (! subMoveKillsMurphy(*si - FieldWidth, ax, bl))
396 // ==========================================================================
397 // moving right to left ...
398 // ==========================================================================
404 MurphyVarFaceLeft = 1;
405 ax = PlayField16[*si - 1];
416 if (ax == fiInfotron)
425 if (al == fiTerminal)
428 if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
434 if (ax == fiYellowDisk)
437 if (ax == fiOrangeDisk)
440 if (! subMoveKillsMurphy(*si - 1, ax, bl))
445 // ==========================================================================
446 // moving up to down ...
447 // ==========================================================================
453 ax = PlayField16[*si + FieldWidth];
464 if (ax == fiInfotron)
470 if (al == fiTerminal)
473 if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
479 if (al == fiYellowDisk)
482 if (! subMoveKillsMurphy(*si + FieldWidth, ax, bl))
487 // ==========================================================================
488 // moving left to right ...
489 // ==========================================================================
495 MurphyVarFaceLeft = 0;
496 ax = PlayField16[*si + 1];
507 if (ax == fiInfotron)
516 if (al == fiTerminal)
519 if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
525 if (al == fiYellowDisk)
528 if (ax == fiOrangeDisk)
531 if (! subMoveKillsMurphy(*si + 1, ax, bl))
536 // ==========================================================================
537 // touching down to up ...
538 // ==========================================================================
543 dxPos = *si - FieldWidth;
545 ax = PlayField16[*si - FieldWidth];
554 if (ax == fiInfotron)
557 if (al == fiTerminal)
565 // ==========================================================================
566 // touching right to left ...
567 // ==========================================================================
574 MurphyVarFaceLeft = 1;
575 ax = PlayField16[*si - 1];
583 if (ax == fiInfotron)
586 if (al == fiTerminal)
594 // ==========================================================================
595 // touching up to down ...
596 // ==========================================================================
601 dxPos = *si + FieldWidth;
603 ax = PlayField16[*si + FieldWidth];
611 if (ax == fiInfotron)
614 if (al == fiTerminal)
622 // ==========================================================================
623 // touching left to right ...
624 // ==========================================================================
631 MurphyVarFaceLeft = 0;
632 ax = PlayField16[*si + 1];
640 if (ax == fiInfotron)
643 if (al == fiTerminal)
651 // ==========================================================================
652 // Release Red disk: no move ...
653 // ==========================================================================
659 if (LowByte(RedDiskCount) == 0)
662 if (LowByte(RedDiskReleasePhase) != 0)
665 if (LowByte(RedDiskReleaseFlag) != 1)
668 MovHighByte(&PlayField16[*si], 0x2A);
669 MovingPictureSequencePhase = 0x40; // init picture move sequence
670 dx = aniFramesRedDisk;
672 MovLowByte(&RedDiskReleasePhase, 1);
673 RedDiskReleaseMurphyPos = *si; // remember Murphy's location
676 // ==========================================================================
677 // SPACE moving down to up
678 // ==========================================================================
681 dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
682 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyMoveUpRight : aniMurphyMoveUpLeft);
683 PlayField16[*si - FieldWidth] = 0x103;
684 PlayField16[*si] = 0x300;
685 *si = *si - FieldWidth;
686 goto loc_StopNoSplit;
688 // ==========================================================================
689 // SPACE moving right to left
690 // ==========================================================================
693 dx = aniFramesMurphyEatLeft;
694 dx1 = aniMurphyMoveLeft;
695 PlayField16[*si - 1] = 0x203;
696 PlayField16[*si] = 0x300;
698 goto loc_StopNoSplit;
700 // ==========================================================================
701 // SPACE moving up to down, and when gravity is pulling!
702 // ==========================================================================
705 dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
706 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyMoveUpRight : aniMurphyMoveUpLeft);
707 PlayField16[*si + FieldWidth] = 0x303;
708 PlayField16[*si] = 0x300;
709 *si = *si + FieldWidth;
710 goto loc_StopNoSplit;
712 // ==========================================================================
713 // SPACE moving left to right
714 // ==========================================================================
717 dx = aniFramesMurphyEatRight;
718 dx1 = aniMurphyMoveRight;
719 PlayField16[*si + 1] = 0x403;
720 PlayField16[*si] = 0x300;
722 goto loc_StopNoSplit;
724 // ==========================================================================
725 // BUG moving down to up
726 // ==========================================================================
729 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
731 ExplodeFieldSP(*si); // Explode
736 PlayField16[*si - FieldWidth] = fiBase;
737 // ==========================================================================
738 // BASE moving down to up
739 // ==========================================================================
743 subSoundFX(*si, fiBase, actDigging);
748 dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
749 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyDigUpRight : aniMurphyDigUpLeft);
750 PlayField16[*si - FieldWidth] = 0x503;
751 PlayField16[*si] = 0x300;
752 *si = *si - FieldWidth;
753 goto loc_StopNoSplit;
755 // ==========================================================================
756 // BUG moving right to left
757 // ==========================================================================
760 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
762 ExplodeFieldSP(*si); // Explode
767 PlayField16[*si - 1] = fiBase;
768 // ==========================================================================
769 // BASE moving right to left
770 // ==========================================================================
774 subSoundFX(*si, fiBase, actDigging);
779 dx = aniFramesMurphyEatLeft;
780 dx1 = aniMurphyDigLeft;
781 PlayField16[*si - 1] = 0x203;
782 PlayField16[*si] = 0x300;
784 goto loc_StopNoSplit;
786 // ==========================================================================
787 // BUG moving up to down
788 // ==========================================================================
791 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
793 ExplodeFieldSP(*si); // Explode
798 PlayField16[*si + FieldWidth] = fiBase;
799 // ==========================================================================
800 // BASE moving up to down
801 // ==========================================================================
805 subSoundFX(*si, fiBase, actDigging);
810 dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
811 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyDigUpRight : aniMurphyDigUpLeft);
812 PlayField16[*si + FieldWidth] = 0x703;
813 PlayField16[*si] = 0x300;
814 *si = *si + FieldWidth;
815 goto loc_StopNoSplit;
817 // ==========================================================================
818 // BUG moving left to right
819 // ==========================================================================
822 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
824 ExplodeFieldSP(*si); // Explode
829 PlayField16[*si + 1] = fiBase;
830 // ==========================================================================
831 // BASE moving left to right
832 // ==========================================================================
836 subSoundFX(*si, fiBase, actDigging);
841 dx = aniFramesMurphyEatRight;
842 dx1 = aniMurphyDigRight;
843 PlayField16[*si + 1] = 0x803;
844 PlayField16[*si] = 0x300;
846 goto loc_StopNoSplit;
848 // ==========================================================================
849 // BUG touching down to up
850 // ==========================================================================
853 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
855 ExplodeFieldSP(*si); // Explode
860 PlayField16[*si - FieldWidth] = fiBase;
861 // ==========================================================================
862 // BASE touching down to up
863 // ==========================================================================
866 subCopyImageToScreen(*si, aniMurphyTouchUp);
868 subSoundFX(*si, fiBase, actDigging);
873 dx = aniFramesTouchBase;
875 dxPos = *si - FieldWidth;
876 MovHighByte(&PlayField16[*si], 0x10);
877 goto loc_StopNoSplit;
879 // ==========================================================================
880 // BUG touching right to left
881 // ==========================================================================
884 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
886 ExplodeFieldSP(*si); // Explode
891 PlayField16[*si - 1] = fiBase;
892 // ==========================================================================
893 // BASE touching right to left
894 // ==========================================================================
897 subCopyImageToScreen(*si, aniMurphyTouchLeft);
899 subSoundFX(*si, fiBase, actDigging);
904 dx = aniFramesTouchBase;
907 MovHighByte(&PlayField16[*si], 0x11);
908 goto loc_StopNoSplit;
910 // ==========================================================================
911 // BUG touching up to down
912 // ==========================================================================
915 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
917 ExplodeFieldSP(*si); // Explode
922 PlayField16[*si + FieldWidth] = fiBase;
923 // ==========================================================================
924 // BASE touching up to down
925 // ==========================================================================
928 subCopyImageToScreen(*si, aniMurphyTouchDown);
930 subSoundFX(*si, fiBase, actDigging);
935 dx = aniFramesTouchBase;
937 dxPos = *si + FieldWidth;
938 MovHighByte(&PlayField16[*si], 0x12);
939 goto loc_StopNoSplit;
941 // ==========================================================================
942 // BUG touching left to right
943 // ==========================================================================
946 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
948 ExplodeFieldSP(*si); // Explode
953 PlayField16[*si + 1] = fiBase;
954 // ==========================================================================
955 // BASE touching left to right
956 // ==========================================================================
959 subCopyImageToScreen(*si, aniMurphyTouchRight);
961 subSoundFX(*si, fiBase, actDigging);
966 dx = aniFramesTouchBase;
969 MovHighByte(&PlayField16[*si], 0x13);
970 goto loc_StopNoSplit;
972 // ==========================================================================
973 // INFOTRON moving down to up
974 // ==========================================================================
978 subSoundFX(*si, fiInfotron, actCollecting);
980 subSoundFXInfotron();
983 dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
984 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
985 PlayField16[*si - FieldWidth] = 0x903;
986 PlayField16[*si] = 0x300;
987 *si = *si - FieldWidth;
988 goto loc_StopNoSplit;
990 // ==========================================================================
991 // INFOTRON moving right to left
992 // ==========================================================================
996 subSoundFX(*si, fiInfotron, actCollecting);
998 subSoundFXInfotron();
1001 dx = aniFramesEatInfotronLeft;
1002 dx1 = aniEatInfotronLeft;
1008 PlayField16[*si - 1] = 0xA03;
1009 PlayField16[*si] = 0x300;
1011 goto loc_StopNoSplit;
1013 // ==========================================================================
1014 // INFOTRON moving up to down
1015 // ==========================================================================
1019 subSoundFX(*si, fiInfotron, actCollecting);
1021 subSoundFXInfotron();
1024 dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
1025 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1026 PlayField16[*si + FieldWidth] = 0xB03;
1027 PlayField16[*si] = 0x300;
1028 *si = *si + FieldWidth;
1029 goto loc_StopNoSplit;
1031 // ==========================================================================
1032 // INFOTRON moving left to right
1033 // ==========================================================================
1037 subSoundFX(*si, fiInfotron, actCollecting);
1039 subSoundFXInfotron();
1042 dx = aniFramesEatInfotronRight;
1043 dx1 = aniEatInfotronRight;
1049 PlayField16[*si + 1] = 0xC03;
1050 PlayField16[*si] = 0x300;
1052 goto loc_StopNoSplit;
1054 // ==========================================================================
1055 // INFOTRON touching down to up
1056 // ==========================================================================
1059 subCopyImageToScreen(*si, aniMurphyTouchUp);
1061 subSoundFX(*si, fiInfotron, actCollecting);
1063 subSoundFXInfotron();
1066 dx = aniFramesTouchInfotron;
1067 dx1 = aniTouchInfotron;
1068 MovHighByte(&PlayField16[*si], 0x14);
1069 MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
1070 goto loc_StopNoSplit;
1072 // ==========================================================================
1073 // INFOTRON touching right to left
1074 // ==========================================================================
1077 subCopyImageToScreen(*si, aniMurphyTouchLeft);
1079 subSoundFX(*si, fiInfotron, actCollecting);
1081 subSoundFXInfotron();
1084 dx = aniFramesTouchInfotron;
1085 dx1 = aniTouchInfotron;
1086 MovHighByte(&PlayField16[*si], 0x15);
1087 MovHighByte(&PlayField16[*si - 1], 0xFF);
1088 goto loc_StopNoSplit;
1090 // ==========================================================================
1091 // INFOTRON touching up to down
1092 // ==========================================================================
1095 subCopyImageToScreen(*si, aniMurphyTouchDown);
1097 subSoundFX(*si, fiInfotron, actCollecting);
1099 subSoundFXInfotron();
1102 dx = aniFramesTouchInfotron;
1103 dx1 = aniTouchInfotron;
1104 MovHighByte(&PlayField16[*si], 0x16);
1105 MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
1106 goto loc_StopNoSplit;
1108 // ==========================================================================
1109 // INFOTRON touching left to right
1110 // ==========================================================================
1113 subCopyImageToScreen(*si, aniMurphyTouchRight);
1115 subSoundFX(*si, fiInfotron, actCollecting);
1117 subSoundFXInfotron();
1120 dx = aniFramesTouchInfotron;
1121 dx1 = aniTouchInfotron;
1122 MovHighByte(&PlayField16[*si], 0x17);
1123 MovHighByte(&PlayField16[*si + 1], 0xFF);
1124 goto loc_StopNoSplit;
1126 // ==========================================================================
1127 // EXIT pressed from any direction
1128 // ==========================================================================
1136 if (LowByte(InfotronsNeeded) != 0)
1140 if (!game_sp.LevelSolved)
1141 printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n",LevelNumber);
1145 game_sp.LevelSolved = TRUE;
1149 subSoundFX(*si, fiExit, actPassing);
1154 data_h_DemoDone = 1; // EP set level success bytes
1155 LevelStatus = 1; // set Level Status DONE
1156 EP_GameDemoVar0DAA = 0; // force demo for lead-out
1157 if (SavedGameFlag == 0) // saved game running?
1159 if (UpdateTimeFlag != 0) // update time?
1161 UpdatedFlag = 1; // prevent double update
1166 subUpdateHallOfFame(); // update time + Hall-Of-Fame
1169 LeadOutCounter = 0x40; // quit: start lead-out
1170 dx = aniFramesMurphyExit;
1171 dx1 = aniMurphyExit;
1172 MovHighByte(&PlayField16[*si], 0xD);
1173 goto loc_StopNoSplit;
1175 // ==========================================================================
1176 // ZONK moving right to left
1177 // ==========================================================================
1180 ax = PlayField16[*si - 2];
1184 MovHighByte(&PlayField16[*si - 2], 1);
1185 subCopyImageToScreen(*si, aniPushLeft); // draw pushing murphy
1186 dx = aniFramesZonkRollLeft;
1187 dx1 = aniZonkRollLeft;
1191 MovHighByte(&PlayField16[*si], 0xE);
1192 goto loc_MoveNoSplit;
1194 // ==========================================================================
1195 // ZONK moving left to right
1196 // ==========================================================================
1199 ax = PlayField16[*si + 2];
1203 ax = PlayField16[*si + FieldWidth + 1];
1204 if (ax == 0) // zonk falls
1207 MovHighByte(&PlayField16[*si + 2], 1);
1208 subCopyImageToScreen(*si, aniPushRight); // draw pushing murphy
1209 dx = aniFramesZonkRollRight;
1210 dx1 = aniZonkRollRight;
1214 MovHighByte(&PlayField16[*si], 0xF);
1215 goto loc_MoveNoSplit;
1217 // ==========================================================================
1218 // TERMINAL moving/touching down to up
1219 // ==========================================================================
1222 subCopyImageToScreen(*si, aniMurphyTouchUp);
1223 if (YellowDisksExploded != 0)
1225 YawnSleepCounter = 40; // stay hypnotized
1231 // draw new terminal type
1233 GfxGraphic[GetX(*si - FieldWidth)][GetY(*si - FieldWidth)] = aniTerminalActive;
1235 subCopyImageToScreen(*si - FieldWidth, aniTerminalActive);
1238 subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1240 TerminalState[*si - FieldWidth] = 8;
1243 // ==========================================================================
1244 // TERMINAL moving/touching right to left
1245 // ==========================================================================
1248 subCopyImageToScreen(*si, aniMurphyTouchLeft);
1249 if (YellowDisksExploded != 0)
1251 YawnSleepCounter = 40; // stay hypnotized
1257 // draw new terminal type
1259 GfxGraphic[GetX(*si - 1)][GetY(*si - 1)] = aniTerminalActive;
1261 subCopyImageToScreen(*si - 1, aniTerminalActive);
1264 subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1266 TerminalState[*si - 1] = 8;
1269 // ==========================================================================
1270 // TERMINAL moving/touching up to down
1271 // ==========================================================================
1274 subCopyImageToScreen(*si, aniMurphyTouchDown);
1275 if (YellowDisksExploded != 0)
1277 YawnSleepCounter = 40; // stay hypnotized
1283 // draw new terminal type
1285 GfxGraphic[GetX(*si + FieldWidth)][GetY(*si + FieldWidth)] = aniTerminalActive;
1287 subCopyImageToScreen(*si + FieldWidth, aniTerminalActive);
1290 subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1292 TerminalState[*si + FieldWidth] = 8;
1295 // ==========================================================================
1296 // TERMINAL moving/touching left to right
1297 // ==========================================================================
1300 subCopyImageToScreen(*si, aniMurphyTouchRight);
1301 if (YellowDisksExploded != 0)
1303 YawnSleepCounter = 40; // stay hypnotized
1309 // draw new terminal type
1311 GfxGraphic[GetX(*si + 1)][GetY(*si + 1)] = aniTerminalActive;
1313 subCopyImageToScreen(*si + 1, aniTerminalActive);
1316 subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1318 TerminalState[*si + 1] = 8;
1319 // ==========================================================================
1320 // common TERMINAL stuff moving/touching from all directions
1321 // ==========================================================================
1324 TerminalMaxCycles = 7;
1325 YellowDisksExploded = 1;
1326 for (i = 0; i <= LevelMax; i++)
1328 if (PlayField16[i] == fiYellowDisk)
1334 // ==========================================================================
1335 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1336 // ==========================================================================
1339 if (PlayField16[*si - 2 * FieldWidth] != 0)
1342 dx = aniFramesSplitUpDown;
1343 dx1 = aniSplitUpDown;
1344 dx2Step = -FieldWidth;
1345 PlayField16[*si] = 0x1803;
1346 PlayField16[*si - 2 * FieldWidth] = 0x300;
1349 // ==========================================================================
1350 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1351 // ==========================================================================
1354 if (PlayField16[*si - 2] != 0)
1357 dx = aniFramesMurphyEatLeft;
1358 dx1 = aniMurphyMoveLeft;
1360 PlayField16[*si] = 0x1903;
1361 PlayField16[*si - 2] = 0x300;
1364 // ==========================================================================
1365 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1366 // ==========================================================================
1369 if (PlayField16[*si + 2 * FieldWidth] != 0)
1372 dx = aniFramesSplitUpDown;
1373 dx1 = aniSplitUpDown;
1374 dx2Step = FieldWidth;
1375 PlayField16[*si] = 0x1A03;
1376 PlayField16[*si + 2 * FieldWidth] = 0x300;
1379 // ==========================================================================
1380 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1381 // ==========================================================================
1384 if (PlayField16[*si + 2] != 0)
1387 dx = aniFramesMurphyEatRight;
1388 dx1 = aniMurphyMoveRight;
1390 PlayField16[*si] = 0x1B03;
1391 PlayField16[*si + 2] = 0x300;
1394 MovingPictureSequencePhase = 0; // stop picture move sequence
1395 SplitMoveFlag = 1; // port: split movement
1398 // ==========================================================================
1399 // RED DISK moving down to up
1400 // ==========================================================================
1403 dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
1404 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1405 PlayField16[*si] = 0x1C03;
1406 PlayField16[*si - FieldWidth] = 0x300;
1407 goto loc_StopNoSplit;
1409 // ==========================================================================
1410 // RED DISK moving right to left
1411 // ==========================================================================
1414 dx = aniFramesMurphyEatLeft;
1415 dx1 = aniMurphyEatLeft;
1416 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1417 PlayField16[*si - 1] = 0x1D03;
1419 goto loc_StopNoSplit;
1421 // ==========================================================================
1422 // RED DISK moving up to down
1423 // ==========================================================================
1426 dx = (MurphyVarFaceLeft == 0 ? aniFramesMurphyEatUpRight : aniFramesMurphyEatUpLeft);
1427 dx1 = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1428 PlayField16[*si] = 0x1E03;
1429 PlayField16[*si + FieldWidth] = 0x300;
1430 goto loc_StopNoSplit;
1432 // ==========================================================================
1433 // RED DISK moving left to right
1434 // ==========================================================================
1437 // dx = aniFramesMurphyEatRightRedDisk 'this sequence is 9 steps long!
1438 dx = aniFramesMurphyEatRight;
1439 dx1 = aniMurphyEatRight;
1440 // --------------------------------------------------------------------------
1442 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1443 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1444 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1445 // We may not fix the table, because then the timing of the game changes
1446 // and several existing demo's do not run properly anymore.
1447 // We only correct Murphies x-location here, when the sequence starts.
1448 // Remember that this is not the real bug-fix, but we must live with
1449 // this existing bug and correct for the consequences of it.
1452 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1453 MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1455 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1456 MurphyScreenXPos = MurphyScreenXPos - 2;
1460 // FS: for me this means to blit the first animation frame twice
1462 // --------------------------------------------------------------------------
1463 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1464 PlayField16[*si + 1] = 0x1F03;
1466 goto loc_StopNoSplit;
1468 // ==========================================================================
1469 // RED DISK touching down to up
1470 // ==========================================================================
1473 dx = aniFramesTouchRedDisk;
1474 dx1 = aniTouchRedDisk;
1475 MovHighByte(&PlayField16[*si], 0x20);
1476 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1477 goto loc_StopNoSplit;
1479 // ==========================================================================
1480 // RED DISK touching right to left
1481 // ==========================================================================
1484 dx = aniFramesTouchRedDisk;
1485 dx1 = aniTouchRedDisk;
1486 MovHighByte(&PlayField16[*si], 0x21);
1487 MovHighByte(&PlayField16[*si - 1], 3);
1488 goto loc_StopNoSplit;
1490 // ==========================================================================
1491 // RED DISK touching up to down
1492 // ==========================================================================
1495 dx = aniFramesTouchRedDisk;
1496 dx1 = aniTouchRedDisk;
1497 MovHighByte(&PlayField16[*si], 0x22);
1498 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1499 goto loc_StopNoSplit;
1501 // ==========================================================================
1502 // RED DISK touching left to right
1503 // ==========================================================================
1506 dx = aniFramesTouchRedDisk;
1507 dx1 = aniTouchRedDisk;
1508 MovHighByte(&PlayField16[*si], 0x23);
1509 MovHighByte(&PlayField16[*si + 1], 3);
1512 MovingPictureSequencePhase = 0; // stop picture move sequence
1515 // ==========================================================================
1516 // YELLOW DISK moving down to up
1517 // ==========================================================================
1520 if (PlayField16[*si - 2 * FieldWidth] != 0)
1523 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1525 subCopyImageToScreen(*si, aniPushRight);
1527 dx = aniFramesYellowDisk;
1528 dx1 = aniYellowDisk;
1529 dxPos = *si - FieldWidth;
1531 dx2 = (MurphyVarFaceLeft == 0 ? aniPushRight : aniPushLeft);
1533 dx2 = aniPushUpDown;
1535 dx2Step = FieldWidth;
1536 PlayField16[*si] = 0x2403;
1538 subCopyImageToScreen(*si, dx2);
1540 goto loc_MoveNoSplit;
1542 // ==========================================================================
1543 // YELLOW DISK moving right to left
1544 // ==========================================================================
1547 if (PlayField16[*si - 2] != 0)
1550 PlayField16[*si - 2] = 0x1200;
1551 subCopyImageToScreen(*si, aniPushLeft);
1552 dx = aniFramesYellowDisk;
1553 dx1 = aniYellowDisk;
1557 PlayField16[*si] = 0x2503;
1558 goto loc_MoveNoSplit;
1560 // ==========================================================================
1561 // YELLOW DISK moving up to down
1562 // ==========================================================================
1565 if (PlayField16[*si + 2 * FieldWidth] != 0)
1568 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1570 subCopyImageToScreen(*si, aniPushRight);
1572 dx = aniFramesYellowDisk;
1573 dx1 = aniYellowDisk;
1574 dxPos = *si + FieldWidth;
1576 dx2 = (MurphyVarFaceLeft == 0 ? aniPushRight : aniPushLeft);
1578 dx2 = aniPushUpDown;
1580 dx2Step = -FieldWidth;
1581 PlayField16[*si] = 0x2703;
1583 subCopyImageToScreen(*si, dx2);
1585 goto loc_MoveNoSplit;
1587 // ==========================================================================
1588 // YELLOW DISK moving left to right
1589 // ==========================================================================
1592 if (PlayField16[*si + 2] != 0)
1595 PlayField16[*si + 2] = 0x1200;
1596 subCopyImageToScreen(*si, aniPushRight);
1597 dx = aniFramesYellowDisk;
1598 dx1 = aniYellowDisk;
1602 PlayField16[*si] = 0x2603;
1603 goto loc_MoveNoSplit;
1605 // ==========================================================================
1606 // ORANGE DISK moving right to left
1607 // ==========================================================================
1610 if (PlayField16[*si - 2] != 0)
1613 PlayField16[*si - 2] = 0x800;
1614 subCopyImageToScreen(*si, aniPushLeft);
1615 dx = aniFramesOrangeDisk;
1616 dx1 = aniOrangeDisk;
1620 PlayField16[*si] = 0x2803;
1621 goto loc_MoveNoSplit;
1623 // ==========================================================================
1624 // ORANGE DISK moving left to right
1625 // ==========================================================================
1628 if (PlayField16[*si + 2] != 0)
1631 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1634 PlayField16[*si + 2] = 0x100;
1635 subCopyImageToScreen(*si, aniPushRight);
1636 dx = aniFramesOrangeDisk;
1637 dx1 = aniOrangeDisk;
1641 PlayField16[*si] = 0x2903;
1642 // ==========================================================================
1643 // Copy screen animation action table to action work space
1644 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1645 // ==========================================================================
1648 MovingPictureSequencePhase = 8; // init picture move sequence
1651 SplitMoveFlag = 0; // no port: no split movement
1654 // copy/store global move sequence info????????????????????????????????????
1655 // ... dont think so ...(FS)
1656 // ==========================================================================
1657 // Proceed with all movements
1658 // ==========================================================================
1660 locProceedMovingMurphy: // proceed moving murphy
1661 YawnSleepCounter = 0; // Wake up sleeping Murphy
1662 ax = MovingPictureSequencePhase; // sequence busy?
1663 if (ax == 0) // no -- start sequence!
1666 ax = ax - 1; // next picture of sequence
1667 MovingPictureSequencePhase = ax; // store for later
1669 if (ax == 0) // Sound effects
1672 switch (HighByte(PlayField16[*si]))
1676 subSoundFX(*si, fiZonk, actPushing);
1681 subSoundFX(*si, fiOrangeDisk, actPushing);
1688 subSoundFX(*si, fiYellowDisk, actPushing);
1699 bl = HighByte(PlayField16[*si]);
1700 if (bl == 0xE) // Push Zonk to left
1703 if (bl == 0xF) // Push Zonk to right
1706 if (bl == 0x28) // Push orange disk to left
1709 if (bl == 0x29) // Push orange disk to right
1712 if (bl == 0x24) // Push yellow disk up
1715 if (bl == 0x25) // Push yellow disk to left
1718 if (bl == 0x27) // Push yellow disk down
1721 if (bl == 0x26) // Push yellow disk to right
1724 if (bl == 0x2A) // Red disk release timer
1729 // ==========================================================================
1730 // Paint frame of MOVING.DAT sequence
1731 // ==========================================================================
1737 dx1SequenceLength = getSequenceLength(dx1);
1740 if (SplitMoveFlag == 0)
1742 // ++++++++++++++++++++++++++
1743 // Begin of normal movement
1745 MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1746 MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1748 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1749 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1754 printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1756 DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1757 (DemoKeyCode == keyNone ? "(none)" :
1758 DemoKeyCode == keyLeft ? "left" :
1759 DemoKeyCode == keyRight ? "right" :
1760 DemoKeyCode == keyUp ? "up" :
1761 DemoKeyCode == keyDown ? "down" :
1762 DemoKeyCode == keySpace ? "space" :
1763 DemoKeyCode == keySpaceLeft ? "space + left" :
1764 DemoKeyCode == keySpaceRight ? "space + right" :
1765 DemoKeyCode == keySpaceUp ? "space + up" :
1766 DemoKeyCode == keySpaceDown ? "space + down" : "(unknown)"),
1768 MurphyScreenXPos, MurphyScreenYPos,
1769 MurphyPosIndex % 60, MurphyPosIndex / 60,
1778 if (!(ClearPos < 0)) // clear field that murphy is leaving
1779 subCopyImageToScreen(ClearPos, aniSpace);
1781 if (! ClearPos < 0) // clear field that murphy is leaving
1782 subCopyFieldToScreen(ClearPos, 0);
1786 printf("::: ---------------> %d, %d [%d, %d]\n",
1787 MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1791 // !!! special two-tile animation currently not used !!!
1792 if (dx2 == fiInfotron) // special case of infotron moving left or right
1800 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1801 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1804 X = GetStretchX(dxPos) + tDeltaX;
1805 Y = GetStretchY(dxPos) + tDeltaY;
1806 Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1809 if (isSnappingSequence(dx1) && SeqPos == dx1SequenceLength - 1)
1814 StretchedSprites.BltImg(X, Y, dx1, Tmp);
1815 GfxGraphic[GetX(*si)][GetY(*si)] = -1; // (Murphy's position)
1816 GfxGraphic[GetX(dxPos)][GetY(dxPos)] = -1; // (snapping position)
1817 // printf("::: Tmp: %d\n", Tmp);
1819 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1828 tPos = dxPos + dx2Step;
1829 X = GetStretchX(tPos);
1830 Y = GetStretchY(tPos);
1832 // !!! special two-tile animation currently not used !!!
1833 if (dx2 == fiInfotron) // special case of infotron moving left or right
1835 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1837 else // pushing something
1841 // (SeqPos iterates from 0 to 7 while pushing)
1842 StretchedSprites.BltImg(X + tDeltaX, Y + tDeltaY, dx2, SeqPos);
1843 // printf("::: SeqPos: %d\n", SeqPos);
1845 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1850 // End of normal movement
1851 // ------------------------
1855 // ++++++++++++++++++++++++++++++++
1856 // Begin of split movement (port)
1858 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1859 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1861 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1862 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1864 subCopyImageToScreen(ClearPos, aniSpace); // clear the field that murphy leaves
1865 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1866 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1867 X = GetStretchX(dxPos) + tDeltaX;
1868 Y = GetStretchY(dxPos) + tDeltaY;
1870 StretchedSprites.BltImg(X, Y, dx1, SeqPos); // plot first murphy
1872 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1874 tPos = dxPos + dx2Step;
1875 X = GetStretchX(tPos);
1876 Y = GetStretchY(tPos);
1878 StretchedSprites.BltImg(X + tDeltaX, Y + tDeltaY, dx1, SeqPos); // plot second murphy
1879 StretchedSprites.BltImg(X, Y, fiGraphic[LowByte(PlayField16[tPos])], 0); // replot the port on top
1881 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1882 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1884 // End of split movement (port)
1885 // ------------------------------
1886 } // loc_g_6D1E:'loc_g_6D28:
1888 SeqPos = SeqPos + 1;
1890 if (SeqPos < dx1SequenceLength)
1893 if (dx[SeqPos] > -1)
1897 // Follow-up after movement completed 'loc_g_6D35:
1898 MurphyXPos = MurphyXPos + MurphyDX;
1899 MurphyYPos = MurphyYPos + MurphyDY;
1900 bl = HighByte(PlayField16[*si]); // animation phase
1901 MovHighByte(&PlayField16[*si], 0);
1903 if (bl == 0x1) // space, moving up
1906 if (bl == 0x2) // space, moving left
1909 if (bl == 0x3) // space, moving down
1912 if (bl == 0x4) // space, moving right
1915 if (bl == 0x5) // base , moving up
1918 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1921 if (bl == 0x7) // base , moving down
1924 if (bl == 0x8) // base , moving right
1927 if (bl == 0x9) // infotron, moving up
1930 if (bl == 0xA) // infotron, moving left
1933 if (bl == 0xB) // infotron, moving down
1936 if (bl == 0xC) // infotron, moving right
1939 if (bl == 0xD) // exit
1942 if (bl == 0xE) // zonk, pushing left
1945 if (bl == 0xF) // zonk, pushing right
1948 if (bl == 0x10) // base , touching up
1951 if (bl == 0x11) // base , touching left
1954 if (bl == 0x12) // base , touching down
1957 if (bl == 0x13) // base , touching right
1960 if (bl == 0x14) // infotron touching up
1963 if (bl == 0x15) // infotron touching left
1966 if (bl == 0x16) // infotron touching down
1969 if (bl == 0x17) // infotron touching right
1972 if (bl == 0x18) // port up
1975 if (bl == 0x19) // port left
1978 if (bl == 0x1A) // port down
1981 if (bl == 0x1B) // port right
1984 if (bl == 0x1C) // red disk, moving up
1987 if (bl == 0x1D) // red disk, moving left
1990 if (bl == 0x1E) // red disk, moving down
1993 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1996 if (bl == 0x20) // red disk, touching up
1999 if (bl == 0x21) // red disk, touching left
2002 if (bl == 0x22) // red disk, touching down
2005 if (bl == 0x23) // red disk, touching right
2008 if (bl == 0x24) // yellow disk, pushing up
2011 if (bl == 0x25) // yellow disk, pushing left
2014 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
2017 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
2020 if (bl == 0x28) // orange disk, pushing left
2023 if (bl == 0x29) // orange disk, pushing right
2026 if (bl == 0x2A) // red disk, release
2033 // ==========================================================================
2034 // infotron, moving up
2035 // ==========================================================================
2038 if (0 < LowByte(InfotronsNeeded))
2039 InfotronsNeeded = InfotronsNeeded - 1;
2041 loc_g_6EC8: // space, base
2042 PlayField16[*si] = fiMurphy;
2043 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
2047 // ==========================================================================
2048 // infotron, moving left
2049 // ==========================================================================
2052 if (0 < LowByte(InfotronsNeeded))
2053 InfotronsNeeded = InfotronsNeeded - 1;
2055 loc_g_6EE6: // space, base
2056 PlayField16[*si] = fiMurphy;
2057 subAdjustZonksInfotronsAboveMurphy(*si + 1);
2061 // ==========================================================================
2062 // infotron, moving down
2063 // ==========================================================================
2066 if (0 < LowByte(InfotronsNeeded))
2067 InfotronsNeeded = InfotronsNeeded - 1;
2069 loc_g_6F04: // space, base
2070 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2071 PlayField16[*si - FieldWidth] = 0;
2073 PlayField16[*si] = fiMurphy;
2077 // ==========================================================================
2078 // infotron, moving right
2079 // ==========================================================================
2082 if (0 < LowByte(InfotronsNeeded))
2083 InfotronsNeeded = InfotronsNeeded - 1;
2085 loc_g_71C4: // space, base
2086 subAdjustZonksInfotronsAboveMurphy(*si - 1);
2087 PlayField16[*si] = fiMurphy;
2091 // ==========================================================================
2092 // infotron, touching up
2093 // ==========================================================================
2096 if (0 < LowByte(InfotronsNeeded))
2097 InfotronsNeeded = InfotronsNeeded - 1;
2100 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2101 PlayField16[*si - FieldWidth] = 0;
2105 // ==========================================================================
2106 // infotron, touching left
2107 // ==========================================================================
2110 if (0 < LowByte(InfotronsNeeded))
2111 InfotronsNeeded = InfotronsNeeded - 1;
2114 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2115 PlayField16[*si - 1] = 0;
2119 // ==========================================================================
2120 // infotron, touching down
2121 // ==========================================================================
2124 if (0 < LowByte(InfotronsNeeded))
2125 InfotronsNeeded = InfotronsNeeded - 1;
2128 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2129 PlayField16[*si + FieldWidth] = 0;
2133 // ==========================================================================
2134 // infotron, touching right
2135 // ==========================================================================
2138 if (0 < LowByte(InfotronsNeeded))
2139 InfotronsNeeded = InfotronsNeeded - 1;
2142 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2143 PlayField16[*si + 1] = 0;
2147 // ==========================================================================
2148 // zonk, pushing left
2149 // ==========================================================================
2152 if (LowByte(PlayField16[*si]) != fiExplosion)
2153 PlayField16[*si] = 0;
2155 PlayField16[*si - 1] = fiMurphy;
2156 PlayField16[*si - 2] = fiZonk;
2157 subExplodeSnikSnaksBelow(*si - 2);
2162 // ==========================================================================
2163 // zonk, pushing right
2164 // ==========================================================================
2167 if (LowByte(PlayField16[*si]) != fiExplosion)
2168 PlayField16[*si] = 0;
2170 PlayField16[*si + 1] = fiMurphy;
2171 PlayField16[*si + 2] = fiZonk;
2172 subExplodeSnikSnaksBelow(*si + 2);
2177 // ==========================================================================
2179 // ==========================================================================
2185 PlayField16[*si] = fiSpace; // remove Murphy from playfield after exiting
2190 // ==========================================================================
2191 // Push Zonk from right to left
2192 // ==========================================================================
2195 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
2198 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
2199 PlayField16[*si - 1] = fiZonk;
2200 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2201 PlayField16[*si - 2] = 0;
2203 subCopyImageToScreen(*si, aniMurphy);
2207 // ==========================================================================
2208 // Push Zonk from left to right
2209 // ==========================================================================
2212 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
2215 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
2216 PlayField16[*si + 1] = fiZonk;
2217 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2218 PlayField16[*si + 2] = 0;
2220 subCopyImageToScreen(*si, aniMurphy);
2224 // ==========================================================================
2225 // Push orange disk from right to left
2226 // ==========================================================================
2229 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
2232 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2233 PlayField16[*si - 1] = fiOrangeDisk;
2234 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2235 PlayField16[*si - 2] = 0;
2237 subCopyImageToScreen(*si, aniMurphy);
2241 // ==========================================================================
2242 // Push orange disk from left to right
2243 // ==========================================================================
2246 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
2249 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2250 PlayField16[*si + 1] = fiOrangeDisk;
2251 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2252 PlayField16[*si + 2] = 0;
2254 subCopyImageToScreen(*si, aniMurphy);
2258 // ==========================================================================
2259 // Push yellow disk from down to up
2260 // ==========================================================================
2263 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
2266 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2267 PlayField16[*si - FieldWidth] = fiYellowDisk;
2268 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
2269 PlayField16[*si - 2 * FieldWidth] = 0;
2271 subCopyImageToScreen(*si, aniMurphy);
2275 // ==========================================================================
2276 // Push yellow disk from right to left
2277 // ==========================================================================
2280 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
2283 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2284 PlayField16[*si - 1] = fiYellowDisk;
2285 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2286 PlayField16[*si - 2] = 0;
2288 subCopyImageToScreen(*si, aniMurphy);
2292 // ==========================================================================
2293 // Push yellow disk from up to down
2294 // ==========================================================================
2297 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
2300 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2301 PlayField16[*si + FieldWidth] = fiYellowDisk;
2302 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
2303 PlayField16[*si + 2 * FieldWidth] = 0;
2305 subCopyImageToScreen(*si, aniMurphy);
2309 // ==========================================================================
2310 // Push yellow disk from left to right
2311 // ==========================================================================
2314 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
2317 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2318 PlayField16[*si + 1] = fiYellowDisk;
2319 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2320 PlayField16[*si + 2] = 0;
2322 subCopyImageToScreen(*si, aniMurphy);
2326 // ==========================================================================
2327 // time red disk release (space)
2328 // ==========================================================================
2331 if (DemoKeyCode != keySpace)
2333 PlayField16[*si] = fiMurphy;
2334 subCopyImageToScreen(*si, aniMurphy);
2335 RedDiskReleasePhase = 0;
2337 else if (MovingPictureSequencePhase == 0x20)
2340 // anxious murphy, dropping red disk
2341 subCopyImageToScreen(*si, aniMurphyDropping);
2343 subCopyFieldToScreen(*si, 43); // anxious murphy
2345 RedDiskReleasePhase = 1;
2350 // ==========================================================================
2351 // Special port down to up
2352 // ==========================================================================
2355 if (LowByte(PlayField16[*si]) != fiExplosion)
2356 PlayField16[*si] = 0;
2358 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
2360 *si = *si - FieldWidth;
2361 if (HighByte(PlayField16[*si]) == 1)
2364 *si = *si - FieldWidth;
2368 // ==========================================================================
2369 // Special port right to left
2370 // ==========================================================================
2373 if (LowByte(PlayField16[*si]) != fiExplosion)
2374 PlayField16[*si] = 0;
2376 PlayField16[*si - 2] = fiMurphy;
2379 if (HighByte(PlayField16[*si]) == 1)
2386 // ==========================================================================
2387 // Special port up to down
2388 // ==========================================================================
2391 if (LowByte(PlayField16[*si]) != fiExplosion)
2392 PlayField16[*si] = 0;
2394 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2396 *si = *si + FieldWidth;
2397 if (HighByte(PlayField16[*si]) == 1)
2400 *si = *si + FieldWidth;
2404 // ==========================================================================
2405 // Special port left to right
2406 // ==========================================================================
2409 if (LowByte(PlayField16[*si]) != fiExplosion)
2410 PlayField16[*si] = 0;
2412 PlayField16[*si + 2] = fiMurphy;
2415 if (HighByte(PlayField16[*si]) == 1)
2422 // ==========================================================================
2424 // ==========================================================================
2427 if (LowByte(PlayField16[*si]) != fiExplosion)
2428 PlayField16[*si] = 0;
2430 *si = *si - FieldWidth;
2431 PlayField16[*si] = fiMurphy;
2432 subEatRedDisk(*si); // inc+show Murphy's red disks
2436 // ==========================================================================
2437 // Move Red Disk left
2438 // ==========================================================================
2441 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2442 PlayField16[*si + 1] = 0;
2444 PlayField16[*si] = fiMurphy;
2445 subEatRedDisk(*si); // inc+show Murphy's red disks
2449 // ==========================================================================
2450 // Move Red Disk down
2451 // ==========================================================================
2454 if (LowByte(PlayField16[*si]) != fiExplosion)
2455 PlayField16[*si] = 0;
2457 *si = *si + FieldWidth;
2458 PlayField16[*si] = fiMurphy;
2459 subEatRedDisk(*si); // inc+show Murphy's red disks
2463 // ==========================================================================
2464 // Move Red Disk right
2465 // ==========================================================================
2468 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2469 PlayField16[*si - 1] = 0;
2471 PlayField16[*si] = fiMurphy;
2472 subEatRedDisk(*si); // inc+show Murphy's red disks
2476 // ==========================================================================
2478 // ==========================================================================
2481 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2482 PlayField16[*si - FieldWidth] = 0;
2484 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2488 // ==========================================================================
2489 // Eat Red Disk left
2490 // ==========================================================================
2493 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2494 PlayField16[*si - 1] = 0;
2496 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2500 // ==========================================================================
2501 // Eat Red Disk down
2502 // ==========================================================================
2505 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2506 PlayField16[*si + FieldWidth] = 0;
2508 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2512 // ==========================================================================
2513 // Eat Red Disk right
2514 // ==========================================================================
2517 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2518 PlayField16[*si + 1] = 0;
2520 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2524 // ==========================================================================
2525 // yellow disk, pushing up
2526 // ==========================================================================
2529 if (LowByte(PlayField16[*si]) != fiExplosion)
2530 PlayField16[*si] = 0;
2532 *si = *si - FieldWidth;
2533 PlayField16[*si] = fiMurphy;
2534 PlayField16[*si - FieldWidth] = fiYellowDisk;
2538 // ==========================================================================
2539 // yellow disk, pushing left
2540 // ==========================================================================
2543 if (LowByte(PlayField16[*si]) != fiExplosion)
2544 PlayField16[*si] = 0;
2547 PlayField16[*si] = fiMurphy;
2548 PlayField16[*si - 1] = fiYellowDisk;
2552 // ==========================================================================
2553 // yellow disk, pushing down
2554 // ==========================================================================
2557 if (LowByte(PlayField16[*si]) != fiExplosion)
2558 PlayField16[*si] = 0;
2560 *si = *si + FieldWidth;
2561 PlayField16[*si] = fiMurphy;
2562 PlayField16[*si + FieldWidth] = fiYellowDisk;
2566 // ==========================================================================
2567 // yellow disk pushing right
2568 // ==========================================================================
2571 if (LowByte(PlayField16[*si]) != fiExplosion)
2572 PlayField16[*si] = 0;
2575 PlayField16[*si] = fiMurphy;
2576 PlayField16[*si + 1] = fiYellowDisk;
2580 // ==========================================================================
2581 // orange disk, pushing left
2582 // ==========================================================================
2585 if (LowByte(PlayField16[*si]) != fiExplosion)
2586 PlayField16[*si] = 0;
2589 PlayField16[*si] = fiMurphy;
2590 PlayField16[*si - 1] = fiOrangeDisk;
2594 // ==========================================================================
2595 // orange disk, pushing right
2596 // ==========================================================================
2599 if (LowByte(PlayField16[*si]) != fiExplosion)
2600 PlayField16[*si] = 0;
2603 PlayField16[*si] = fiMurphy;
2604 PlayField16[*si + 1] = fiOrangeDisk;
2605 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2607 MovHighByte(&PlayField16[*si + 1], 0x20);
2608 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2613 // ==========================================================================
2614 // Release a red disk
2615 // ==========================================================================
2618 PlayField16[*si] = fiMurphy;
2619 RedDiskReleasePhase = 2;
2620 RedDiskCount = RedDiskCount - 1;
2623 subSoundFX(*si, fiRedDisk, actDropping);
2625 subSoundFXPush(); // Sound effects
2627 } // subAnimateMurphy
2629 // ==========================================================================
2631 // ==========================================================================
2632 void subExplodeSnikSnaksBelow(int si)
2636 ax = LowByte(PlayField16[si + FieldWidth]);
2637 if (ax == 0x11 || ax == 0xBB)
2638 ExplodeFieldSP(si + FieldWidth);
2639 } // subExplodeSnikSnaksBelow
2641 // ==========================================================================
2643 // Does pushing against an object kill Murphy?
2644 // ==========================================================================
2645 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2647 static boolean subMoveKillsMurphy;
2653 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2659 if (al == fiExplosion)
2662 if (fiOrangeDisk <= al && al <= fiPortUp)
2665 ExplodeFieldSP(si); // Explode
2666 subMoveKillsMurphy = True;
2667 return subMoveKillsMurphy;
2676 ExplodeFieldSP(si); // Explode
2677 subMoveKillsMurphy = True;
2678 return subMoveKillsMurphy;
2680 loc_g_74F6: // zonk left
2682 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2685 subMoveKillsMurphy = True; // Set carry flag
2686 return subMoveKillsMurphy;
2688 loc_g_7512: // zonk right
2690 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2693 loc_g_752E: // Marked fields and Ports
2694 subMoveKillsMurphy = True; // Set carry flag
2695 return subMoveKillsMurphy;
2697 loc_g_7530: // explosion
2698 if ((ah & 0x80) != 0)
2705 ExplodeFieldSP(si); // Explode
2706 subMoveKillsMurphy = True; // Set carry flag
2707 return subMoveKillsMurphy;
2710 PlayField16[si] = 0;
2711 subMoveKillsMurphy = False;
2713 return subMoveKillsMurphy;
2714 } // subMoveKillsMurphy
2716 // ==========================================================================
2718 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2719 // change conditions to port specs
2720 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2721 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2722 // ==========================================================================
2723 int subSpPortTest(int si)
2730 cx = LInfo.SpecialPortCount; // number of special ports
2732 for (i = 0; i < cx; i++)
2735 /* this assumes that PortLocation is stored as big endian */
2736 bx = LInfo.SpecialPort[i].PortLocation;
2738 /* this assumes that PortLocation is stored as little endian */
2739 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2740 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2745 GravityFlag = LInfo.SpecialPort[i].Gravity;
2746 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2747 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2749 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2757 cx = LInfo.SpecialPortCount; // number of special ports
2758 for (i = 1; i <= cx; i++)
2761 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2762 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2765 GravityFlag = LInfo.SpecialPort[i].Gravity;
2766 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2767 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2768 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2775 return subSpPortTest;
2780 void subCopyFieldToScreen(int si, int fi)
2784 // +++++++++++++++++++++++++++++++++++++++++
2785 X = GetStretchX(si);
2786 Y = GetStretchY(si);
2787 StretchedSprites.BltEx(X, Y, fi);
2788 // +++++++++++++++++++++++++++++++++++++++++
2793 void subCopyAnimToScreen(int si, int graphic, int sync_frame)
2797 // +++++++++++++++++++++++++++++++++++++++++
2798 X = GetStretchX(si);
2799 Y = GetStretchY(si);
2800 StretchedSprites.BltImg(X, Y, graphic, sync_frame);
2801 // +++++++++++++++++++++++++++++++++++++++++
2804 void subCopyImageToScreen(int si, int graphic)
2806 subCopyAnimToScreen(si, graphic, 0);
2809 static void subEatRedDisk(int si)
2811 if (AllowRedDiskCheat == 0)
2813 if (RedDiskReleasePhase != 0)
2815 if (RedDiskReleaseMurphyPos == si)
2820 RedDiskCount = (RedDiskCount + 1) % 256;
2823 void subAdjustZonksInfotronsAboveMurphy(int si)
2827 if (LowByte(PlayField16[si]) != fiExplosion)
2828 PlayField16[si] = 0;
2830 ax = PlayField16[si - FieldWidth];
2831 if (ax == 0 || ax == 0x9999)
2834 if (ax == fiZonk || ax == fiInfotron)
2836 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2841 loc_g_15A8: // empty above
2842 ax = PlayField16[si - FieldWidth - 1];
2843 if (ax == fiZonk || ax == fiInfotron)
2847 ax = PlayField16[si - FieldWidth + 1];
2848 if (ax == fiZonk || ax == fiInfotron)
2853 loc_g_15C5: // zonk/infotron above left
2854 ax = PlayField16[si - 1];
2855 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2858 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2859 PlayField16[si - FieldWidth] = 0x8888;
2863 loc_g_15E8: // zonk/infotron above right
2864 ax = PlayField16[si + 1];
2865 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2867 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2868 PlayField16[si - FieldWidth] = 0x8888;
2870 } // subAdjustZonksInfotronsAboveMurphy