1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
7 static void subEatRedDisk(int si);
8 static boolean subMoveKillsMurphy(int si, int ax, int bl);
10 // static char *VB_Name = "modMurphy";
12 // --- Option Explicit
16 #define LocalStretch (2)
17 #define MurphyZoomFactor (ZoomFactor)
21 #define LocalStretch (1)
22 #define MurphyZoomFactor (1)
26 // ==========================================================================
28 // Move Murphy in any direction
29 // ==========================================================================
31 void subAnimateMurphy(int *si)
33 // int ax, al, ah, bx, bl, i, X, Y;
34 // int tX, tY, tDeltaX, tDeltaY, tPos, Tmp;
36 int ax, al, bl, i, X, Y;
39 int ax, al, bx, bl, i, X, Y;
41 int tDeltaX, tDeltaY, tPos, Tmp;
43 // Variables that hold information about the animation sequence
44 static int *dx = 0; // an array of image positions in moving.mpx, finalized with -1
45 static int dx2 = 0; // an additional image position of a second sprite, for instance: yellow disk if pushed
46 static int MurphyDX = 0, MurphyDY = 0; // murphys move steps
47 static int SeqPos = 0; // index into dx()
48 static int ClearPos = 0; // Position to clear before blitting sprites, none=-1
49 static int dxPos = 0; // field-position to draw dx(SeqPos)
50 static int dx2Step = 0; // position of dx2 relative to dx-position
52 ax = PlayField16[*si];
56 printf("::: Murphy.c: subAnimateMurphy(): %d [%d, %d] %d, %d [%d]\n",
57 *si, *si % 60, *si / 60, ax, al, (al == fiMurphy));
61 printf("::: Murphy.c: subAnimateMurphy(): %d [%d] [%d]\n",
62 YawnSleepCounter, FrameCounter, TimerVar);
67 MurphyMoveCounter = 0; // We have no Murphy! Exit!
72 MurphyMoveCounter = 1; // We have a Murphy!
73 MurphyExplodePos = *si;
74 if (ax != 3) // yes--go proceed moving murphy?
75 goto locProceedMovingMurphy;
77 // FS: reset moving sequence variables
85 ScratchGravity = 0; // scratch gravity off
86 if (GravityFlag != 0) // Gravity? (1=gravity on)
88 bl = LowByte(PlayField16[*si - FieldWidth]); // check above
89 if (! (bl == fiPortUp || bl == fiPortUpAndDown || bl == fiPortAllDirections))
91 if (PlayField16[*si + FieldWidth] == 0) // gravity on and space below!
97 if (bl != 0) // a key was pressed!
98 goto locKeyPressed5FCF;
101 printf("::: Murphy.c: !!! %d [%d]\n", DemoKeyCode, GravityFlag);
104 RedDiskReleaseFlag = 1;
105 if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
119 // ------------------------------------------------------------------
120 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
122 YawnSleepCounter = YawnSleepCounter + 1;
124 if (YawnSleepCounter < 16)
127 if (YawnSleepCounter < 2000)
130 // (default: single graphic, no animation)
131 subCopyAnimToScreen(*si, aniMurphy, YawnSleepCounter - 16);
136 if (YawnSleepCounter < 4000)
138 // yawn! and look depressed afterwards...
139 // (default: 12 animation frames with delay of 8)
140 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 2000);
145 if (YawnSleepCounter < 6400)
148 // (default: 12 animation frames with delay of 8)
149 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 4000);
154 // time1 = 6400 + 12 * 8; // (default: 6496 == 6400 + 12 * 8)
155 time1 = 6400 + 12 * 10;
157 if (YawnSleepCounter < time1)
159 // yawn again! - third time
160 // (default: 12 animation frames with delay of 8)
161 subCopyAnimToScreen(*si, aniMurphyYawn, YawnSleepCounter - 6400);
166 // time2 = 6496 + 3 * 64; // (default: 6688 == 6496 + 3 * 64)
167 time2 = 6496 + 3 * 100;
169 if (YawnSleepCounter > time2) // Murphy already went to sleep
172 if (PlayField16[*si - 1] == 0)
174 if (PlayField16[*si + 1] == 0)
176 // no sleep -- go back to "wait and start yawning" phase
177 YawnSleepCounter = 144;
183 // go to sleep (right side)
184 // (default: 3 animation frames with delay of 64)
185 subCopyAnimToScreen(*si, aniMurphySleepRight, YawnSleepCounter - time1);
191 // go to sleep (left side)
192 // (default: 3 animation frames with delay of 64)
193 subCopyAnimToScreen(*si, aniMurphySleepLeft, YawnSleepCounter - time1);
197 // end of YAWN-SLEEP-Sequence
205 // ------------------------------------------------------------------
206 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
207 YawnSleepCounter = YawnSleepCounter + 1;
208 if (YawnSleepCounter == 4)
210 subCopyFieldToScreen(*si, fiMurphy); // normal grin
214 if (YawnSleepCounter <= 500) // loc_g_5ED7:
217 if (YawnSleepCounter <= 522)
219 bx = (YawnSleepCounter - 500) / 2;
220 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
224 if (YawnSleepCounter <= 1000)
227 if (YawnSleepCounter <= 1022)
229 bx = (YawnSleepCounter - 1000) / 2;
230 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again!
234 if (YawnSleepCounter <= 1600) // loc_g_5F3B:
237 if (YawnSleepCounter <= 1622)
239 bx = (YawnSleepCounter - 1600) / 2;
240 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again! - third time
244 if (YawnSleepCounter > 1654)
247 if (PlayField16[*si - 1] == 0)
249 if (PlayField16[*si + 1] == 0)
251 YawnSleepCounter = 36;
257 bx = (YawnSleepCounter - 1622) / 16;
258 subCopyFieldToScreen(*si, aniMurphySleepRight + bx); // go to sleep
263 bx = (YawnSleepCounter - 1622) / 16;
264 subCopyFieldToScreen(*si, aniMurphySleepLeft + bx); // go to sleep
268 // end of YAWN-SLEEP-Sequence
272 // ------------------------------------------------------------------
273 // ==========================================================================
274 // (Direct Jump) a key was pressed
275 // ==========================================================================
278 if (ScratchGravity == 0)
281 if (PlayField16[*si + FieldWidth] != 0)
286 if (PlayField16[*si - FieldWidth] == fiBase)
290 else if (bl == keyLeft)
292 if (PlayField16[*si - 1] == fiBase)
296 else if (bl == keyRight)
298 if (PlayField16[*si + 1] == fiBase)
302 bl = keyDown; // force moving down!
307 RedDiskReleaseFlag = 0; // moving down to up ...
313 RedDiskReleaseFlag = 0; // moving right to left ...
319 RedDiskReleaseFlag = 0; // moving up to down ...
325 RedDiskReleaseFlag = 0; // moving left to right ...
330 case keySpaceUp: // 5
331 RedDiskReleaseFlag = 0; // touching down to up ...
336 case keySpaceLeft: // 6
337 RedDiskReleaseFlag = 0; // touching right to left ...
342 case keySpaceDown: // 7
343 RedDiskReleaseFlag = 0; // touching up to down ...
348 case keySpaceRight: // 8
349 RedDiskReleaseFlag = 0; // touching left to right ...
355 goto loc_g_62E2; // no move ...
360 RedDiskReleaseFlag = 0;
365 // ==========================================================================
366 // moving down to up ...
367 // ==========================================================================
373 ax = PlayField16[*si - FieldWidth];
384 if (ax == fiInfotron)
390 if (al == fiTerminal)
393 if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
399 if (al == fiYellowDisk)
402 if (! subMoveKillsMurphy(*si - FieldWidth, ax, bl))
407 // ==========================================================================
408 // moving right to left ...
409 // ==========================================================================
415 MurphyVarFaceLeft = 1;
416 ax = PlayField16[*si - 1];
427 if (ax == fiInfotron)
436 if (al == fiTerminal)
439 if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
445 if (ax == fiYellowDisk)
448 if (ax == fiOrangeDisk)
451 if (! subMoveKillsMurphy(*si - 1, ax, bl))
456 // ==========================================================================
457 // moving up to down ...
458 // ==========================================================================
464 ax = PlayField16[*si + FieldWidth];
475 if (ax == fiInfotron)
481 if (al == fiTerminal)
484 if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
490 if (al == fiYellowDisk)
493 if (! subMoveKillsMurphy(*si + FieldWidth, ax, bl))
498 // ==========================================================================
499 // moving left to right ...
500 // ==========================================================================
506 MurphyVarFaceLeft = 0;
507 ax = PlayField16[*si + 1];
518 if (ax == fiInfotron)
527 if (al == fiTerminal)
530 if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
536 if (al == fiYellowDisk)
539 if (ax == fiOrangeDisk)
542 if (! subMoveKillsMurphy(*si + 1, ax, bl))
547 // ==========================================================================
548 // touching down to up ...
549 // ==========================================================================
554 dxPos = *si - FieldWidth;
556 ax = PlayField16[*si - FieldWidth];
565 if (ax == fiInfotron)
568 if (al == fiTerminal)
576 // ==========================================================================
577 // touching right to left ...
578 // ==========================================================================
585 MurphyVarFaceLeft = 1;
586 ax = PlayField16[*si - 1];
594 if (ax == fiInfotron)
597 if (al == fiTerminal)
605 // ==========================================================================
606 // touching up to down ...
607 // ==========================================================================
612 dxPos = *si + FieldWidth;
614 ax = PlayField16[*si + FieldWidth];
622 if (ax == fiInfotron)
625 if (al == fiTerminal)
633 // ==========================================================================
634 // touching left to right ...
635 // ==========================================================================
642 MurphyVarFaceLeft = 0;
643 ax = PlayField16[*si + 1];
651 if (ax == fiInfotron)
654 if (al == fiTerminal)
662 // ==========================================================================
663 // Release Red disk: no move ...
664 // ==========================================================================
670 if (LowByte(RedDiskCount) == 0)
673 if (LowByte(RedDiskReleasePhase) != 0)
676 if (LowByte(RedDiskReleaseFlag) != 1)
679 MovHighByte(&PlayField16[*si], 0x2A);
680 MovingPictureSequencePhase = 0x40; // init picture move sequence
682 MovLowByte(&RedDiskReleasePhase, 1);
683 Mov(&RedDiskReleaseMurphyPos, *si); // remember Murphy's location
686 // ==========================================================================
687 // SPACE moving down to up
688 // ==========================================================================
691 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
692 PlayField16[*si - FieldWidth] = 0x103;
693 PlayField16[*si] = 0x300;
694 *si = *si - FieldWidth;
695 goto loc_StopNoSplit;
697 // ==========================================================================
698 // SPACE moving right to left
699 // ==========================================================================
702 dx = aniMurphyEatLeft;
703 PlayField16[*si - 1] = 0x203;
704 PlayField16[*si] = 0x300;
706 goto loc_StopNoSplit;
708 // ==========================================================================
709 // SPACE moving up to down, and when gravity is pulling!
710 // ==========================================================================
713 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
714 PlayField16[*si + FieldWidth] = 0x303;
715 PlayField16[*si] = 0x300;
716 *si = *si + FieldWidth;
717 goto loc_StopNoSplit;
719 // ==========================================================================
720 // SPACE moving left to right
721 // ==========================================================================
724 dx = aniMurphyEatRight;
725 PlayField16[*si + 1] = 0x403;
726 PlayField16[*si] = 0x300;
728 goto loc_StopNoSplit;
730 // ==========================================================================
731 // BUG moving down to up
732 // ==========================================================================
735 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
737 ExplodeFieldSP(*si); // Explode
742 PlayField16[*si - FieldWidth] = fiBase;
743 // ==========================================================================
744 // BASE moving down to up
745 // ==========================================================================
749 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
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 dx = aniMurphyEatLeft;
775 PlayField16[*si - 1] = 0x203;
776 PlayField16[*si] = 0x300;
778 goto loc_StopNoSplit;
780 // ==========================================================================
781 // BUG moving up to down
782 // ==========================================================================
785 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
787 ExplodeFieldSP(*si); // Explode
792 PlayField16[*si + FieldWidth] = fiBase;
793 // ==========================================================================
794 // BASE moving up to down
795 // ==========================================================================
799 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
800 PlayField16[*si + FieldWidth] = 0x703;
801 PlayField16[*si] = 0x300;
802 *si = *si + FieldWidth;
803 goto loc_StopNoSplit;
805 // ==========================================================================
806 // BUG moving left to right
807 // ==========================================================================
810 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
812 ExplodeFieldSP(*si); // Explode
817 PlayField16[*si + 1] = fiBase;
818 // ==========================================================================
819 // BASE moving left to right
820 // ==========================================================================
824 dx = aniMurphyEatRight;
825 PlayField16[*si + 1] = 0x803;
826 PlayField16[*si] = 0x300;
828 goto loc_StopNoSplit;
830 // ==========================================================================
831 // BUG touching down to up
832 // ==========================================================================
835 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
837 ExplodeFieldSP(*si); // Explode
842 PlayField16[*si - FieldWidth] = fiBase;
843 // ==========================================================================
844 // BASE touching down to up
845 // ==========================================================================
848 subCopyImageToScreen(*si, aniMurphyTouchUp);
851 dxPos = *si - FieldWidth;
852 MovHighByte(&PlayField16[*si], 0x10);
853 goto loc_StopNoSplit;
855 // ==========================================================================
856 // BUG touching right to left
857 // ==========================================================================
860 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
862 ExplodeFieldSP(*si); // Explode
867 PlayField16[*si - 1] = fiBase;
868 // ==========================================================================
869 // BASE touching right to left
870 // ==========================================================================
873 subCopyImageToScreen(*si, aniMurphyTouchLeft);
877 MovHighByte(&PlayField16[*si], 0x11);
878 goto loc_StopNoSplit;
880 // ==========================================================================
881 // BUG touching up to down
882 // ==========================================================================
885 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
887 ExplodeFieldSP(*si); // Explode
892 PlayField16[*si + FieldWidth] = fiBase;
893 // ==========================================================================
894 // BASE touching up to down
895 // ==========================================================================
898 subCopyImageToScreen(*si, aniMurphyTouchDown);
901 dxPos = *si + FieldWidth;
902 MovHighByte(&PlayField16[*si], 0x12);
903 goto loc_StopNoSplit;
905 // ==========================================================================
906 // BUG touching left to right
907 // ==========================================================================
910 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
912 ExplodeFieldSP(*si); // Explode
917 PlayField16[*si + 1] = fiBase;
918 // ==========================================================================
919 // BASE touching left to right
920 // ==========================================================================
923 subCopyImageToScreen(*si, aniMurphyTouchRight);
927 MovHighByte(&PlayField16[*si], 0x13);
928 goto loc_StopNoSplit;
930 // ==========================================================================
931 // INFOTRON moving down to up
932 // ==========================================================================
935 subSoundFXInfotron();
936 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
937 PlayField16[*si - FieldWidth] = 0x903;
938 PlayField16[*si] = 0x300;
939 *si = *si - FieldWidth;
940 goto loc_StopNoSplit;
942 // ==========================================================================
943 // INFOTRON moving right to left
944 // ==========================================================================
947 subSoundFXInfotron();
948 dx = aniEatInfotronLeft;
952 PlayField16[*si - 1] = 0xA03;
953 PlayField16[*si] = 0x300;
955 goto loc_StopNoSplit;
957 // ==========================================================================
958 // INFOTRON moving up to down
959 // ==========================================================================
962 subSoundFXInfotron();
963 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
964 PlayField16[*si + FieldWidth] = 0xB03;
965 PlayField16[*si] = 0x300;
966 *si = *si + FieldWidth;
967 goto loc_StopNoSplit;
969 // ==========================================================================
970 // INFOTRON moving left to right
971 // ==========================================================================
974 subSoundFXInfotron();
975 dx = aniEatInfotronRight;
979 PlayField16[*si + 1] = 0xC03;
980 PlayField16[*si] = 0x300;
982 goto loc_StopNoSplit;
984 // ==========================================================================
985 // INFOTRON touching down to up
986 // ==========================================================================
989 subCopyImageToScreen(*si, aniMurphyTouchUp);
990 subSoundFXInfotron();
991 dx = aniTouchInfotron;
992 MovHighByte(&PlayField16[*si], 0x14);
993 MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
994 goto loc_StopNoSplit;
996 // ==========================================================================
997 // INFOTRON touching right to left
998 // ==========================================================================
1001 subCopyImageToScreen(*si, aniMurphyTouchLeft);
1002 subSoundFXInfotron();
1003 dx = aniTouchInfotron;
1004 MovHighByte(&PlayField16[*si], 0x15);
1005 MovHighByte(&PlayField16[*si - 1], 0xFF);
1006 goto loc_StopNoSplit;
1008 // ==========================================================================
1009 // INFOTRON touching up to down
1010 // ==========================================================================
1013 subCopyImageToScreen(*si, aniMurphyTouchDown);
1014 subSoundFXInfotron();
1015 dx = aniTouchInfotron;
1016 MovHighByte(&PlayField16[*si], 0x16);
1017 MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
1018 goto loc_StopNoSplit;
1020 // ==========================================================================
1021 // INFOTRON touching left to right
1022 // ==========================================================================
1025 subCopyImageToScreen(*si, aniMurphyTouchRight);
1026 subSoundFXInfotron();
1027 dx = aniTouchInfotron;
1028 MovHighByte(&PlayField16[*si], 0x17);
1029 MovHighByte(&PlayField16[*si + 1], 0xFF);
1030 goto loc_StopNoSplit;
1032 // ==========================================================================
1033 // EXIT pressed from any direction
1034 // ==========================================================================
1042 if (LowByte(InfotronsNeeded) != 0)
1046 if (!game_sp_info.LevelSolved)
1047 printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n",LevelNumber);
1051 game_sp_info.LevelSolved = TRUE;
1055 data_h_DemoDone = 1; // EP set level success bytes
1056 LevelStatus = 1; // set Level Status DONE
1057 EP_GameDemoVar0DAA = 0; // force demo for lead-out
1058 if (SavedGameFlag == 0) // saved game running?
1060 if (UpdateTimeFlag != 0) // update time?
1062 UpdatedFlag = 1; // prevent double update
1063 subUpdatePlayingTime(); // update playing time
1068 subUpdateHallOfFame(); // update time + Hall-Of-Fame
1071 LeadOutCounter = 0x40; // quit: start lead-out
1073 MovHighByte(&PlayField16[*si], 0xD);
1074 goto loc_StopNoSplit;
1076 // ==========================================================================
1077 // ZONK moving right to left
1078 // ==========================================================================
1081 ax = PlayField16[*si - 2];
1085 MovHighByte(&PlayField16[*si - 2], 1);
1086 subCopyImageToScreen(*si, aniPushLeft); // draw pushing murphy
1087 dx = aniZonkRollLeft;
1091 MovHighByte(&PlayField16[*si], 0xE);
1092 goto loc_MoveNoSplit;
1094 // ==========================================================================
1095 // ZONK moving left to right
1096 // ==========================================================================
1099 ax = PlayField16[*si + 2];
1103 ax = PlayField16[*si + FieldWidth + 1];
1104 if (ax == 0) // zonk falls
1107 MovHighByte(&PlayField16[*si + 2], 1);
1108 subCopyImageToScreen(*si, aniPushRight); // draw pushing murphy
1109 dx = aniZonkRollRight;
1113 MovHighByte(&PlayField16[*si], 0xF);
1114 goto loc_MoveNoSplit;
1116 // ==========================================================================
1117 // TERMINAL moving/touching down to up
1118 // ==========================================================================
1121 subCopyImageToScreen(*si, aniMurphyTouchUp);
1122 if (YellowDisksExploded != 0)
1124 YawnSleepCounter = 40; // stay hypnotized
1130 // draw new terminal type
1131 subCopyImageToScreen(*si - FieldWidth, aniTerminalActive);
1133 subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1135 TerminalState[*si - FieldWidth] = 8;
1138 // ==========================================================================
1139 // TERMINAL moving/touching right to left
1140 // ==========================================================================
1143 subCopyImageToScreen(*si, aniMurphyTouchLeft);
1144 if (YellowDisksExploded != 0)
1146 YawnSleepCounter = 40; // stay hypnotized
1152 // draw new terminal type
1153 subCopyImageToScreen(*si - 1, aniTerminalActive);
1155 subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1157 TerminalState[*si - 1] = 8;
1160 // ==========================================================================
1161 // TERMINAL moving/touching up to down
1162 // ==========================================================================
1165 subCopyImageToScreen(*si, aniMurphyTouchDown);
1166 if (YellowDisksExploded != 0)
1168 YawnSleepCounter = 40; // stay hypnotized
1174 // draw new terminal type
1175 subCopyImageToScreen(*si + FieldWidth, aniTerminalActive);
1177 subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1179 TerminalState[*si + FieldWidth] = 8;
1182 // ==========================================================================
1183 // TERMINAL moving/touching left to right
1184 // ==========================================================================
1187 subCopyImageToScreen(*si, aniMurphyTouchRight);
1188 if (YellowDisksExploded != 0)
1190 YawnSleepCounter = 40; // stay hypnotized
1196 // draw new terminal type
1197 subCopyImageToScreen(*si + 1, aniTerminalActive);
1199 subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1201 TerminalState[*si + 1] = 8;
1202 // ==========================================================================
1203 // common TERMINAL stuff moving/touching from all directions
1204 // ==========================================================================
1207 TerminalMaxCycles = 7;
1208 YellowDisksExploded = 1;
1209 for (i = 0; i <= LevelMax; i++)
1211 if (PlayField16[i] == fiYellowDisk)
1217 // ==========================================================================
1218 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1219 // ==========================================================================
1222 if (PlayField16[*si - 2 * FieldWidth] != 0)
1225 dx = aniSplitUpDown;
1226 dx2Step = -FieldWidth;
1227 PlayField16[*si] = 0x1803;
1228 PlayField16[*si - 2 * FieldWidth] = 0x300;
1231 // ==========================================================================
1232 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1233 // ==========================================================================
1236 if (PlayField16[*si - 2] != 0)
1239 dx = aniMurphyEatLeft;
1241 PlayField16[*si] = 0x1903;
1242 PlayField16[*si - 2] = 0x300;
1245 // ==========================================================================
1246 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1247 // ==========================================================================
1250 if (PlayField16[*si + 2 * FieldWidth] != 0)
1253 dx = aniSplitUpDown;
1254 dx2Step = FieldWidth;
1255 PlayField16[*si] = 0x1A03;
1256 PlayField16[*si + 2 * FieldWidth] = 0x300;
1259 // ==========================================================================
1260 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1261 // ==========================================================================
1264 if (PlayField16[*si + 2] != 0)
1267 dx = aniMurphyEatRight;
1269 PlayField16[*si] = 0x1B03;
1270 PlayField16[*si + 2] = 0x300;
1273 MovingPictureSequencePhase = 0; // stop picture move sequence
1274 SplitMoveFlag = 1; // port: split movement
1277 // ==========================================================================
1278 // RED DISK moving down to up
1279 // ==========================================================================
1282 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1283 PlayField16[*si] = 0x1C03;
1284 PlayField16[*si - FieldWidth] = 0x300;
1285 goto loc_StopNoSplit;
1287 // ==========================================================================
1288 // RED DISK moving right to left
1289 // ==========================================================================
1292 dx = aniMurphyEatLeft;
1293 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1294 PlayField16[*si - 1] = 0x1D03;
1296 goto loc_StopNoSplit;
1298 // ==========================================================================
1299 // RED DISK moving up to down
1300 // ==========================================================================
1303 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1304 PlayField16[*si] = 0x1E03;
1305 PlayField16[*si + FieldWidth] = 0x300;
1306 goto loc_StopNoSplit;
1308 // ==========================================================================
1309 // RED DISK moving left to right
1310 // ==========================================================================
1313 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1314 dx = aniMurphyEatRight;
1315 // --------------------------------------------------------------------------
1317 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1318 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1319 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1320 // We may not fix the table, because then the timing of the game changes
1321 // and several existing demo's do not run properly anymore.
1322 // We only correct Murphies x-location here, when the sequence starts.
1323 // Remember that this is not the real bug-fix, but we must live with
1324 // this existing bug and correct for the consequences of it.
1327 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1328 MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1330 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1331 MurphyScreenXPos = MurphyScreenXPos - 2;
1335 // FS: for me this means to blit the first animation frame twice
1337 // --------------------------------------------------------------------------
1338 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1339 PlayField16[*si + 1] = 0x1F03;
1341 goto loc_StopNoSplit;
1343 // ==========================================================================
1344 // RED DISK touching down to up
1345 // ==========================================================================
1348 dx = aniTouchRedDisk;
1349 MovHighByte(&PlayField16[*si], 0x20);
1350 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1351 goto loc_StopNoSplit;
1353 // ==========================================================================
1354 // RED DISK touching right to left
1355 // ==========================================================================
1358 dx = aniTouchRedDisk;
1359 MovHighByte(&PlayField16[*si], 0x21);
1360 MovHighByte(&PlayField16[*si - 1], 3);
1361 goto loc_StopNoSplit;
1363 // ==========================================================================
1364 // RED DISK touching up to down
1365 // ==========================================================================
1368 dx = aniTouchRedDisk;
1369 MovHighByte(&PlayField16[*si], 0x22);
1370 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1371 goto loc_StopNoSplit;
1373 // ==========================================================================
1374 // RED DISK touching left to right
1375 // ==========================================================================
1378 dx = aniTouchRedDisk;
1379 MovHighByte(&PlayField16[*si], 0x23);
1380 MovHighByte(&PlayField16[*si + 1], 3);
1383 MovingPictureSequencePhase = 0; // stop picture move sequence
1386 // ==========================================================================
1387 // YELLOW DISK moving down to up
1388 // ==========================================================================
1391 if (PlayField16[*si - 2 * FieldWidth] != 0)
1394 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1395 subCopyImageToScreen(*si, aniPushRight);
1397 dxPos = *si - FieldWidth;
1398 dx2 = aniPushUpDown;
1399 dx2Step = FieldWidth;
1400 PlayField16[*si] = 0x2403;
1401 goto loc_MoveNoSplit;
1403 // ==========================================================================
1404 // YELLOW DISK moving right to left
1405 // ==========================================================================
1408 if (PlayField16[*si - 2] != 0)
1411 PlayField16[*si - 2] = 0x1200;
1412 subCopyImageToScreen(*si, aniPushLeft);
1417 PlayField16[*si] = 0x2503;
1418 goto loc_MoveNoSplit;
1420 // ==========================================================================
1421 // YELLOW DISK moving up to down
1422 // ==========================================================================
1425 if (PlayField16[*si + 2 * FieldWidth] != 0)
1428 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1429 subCopyImageToScreen(*si, aniPushRight);
1431 dxPos = *si + FieldWidth;
1432 dx2 = aniPushUpDown;
1433 dx2Step = -FieldWidth;
1434 PlayField16[*si] = 0x2703;
1435 goto loc_MoveNoSplit;
1437 // ==========================================================================
1438 // YELLOW DISK moving left to right
1439 // ==========================================================================
1442 if (PlayField16[*si + 2] != 0)
1445 PlayField16[*si + 2] = 0x1200;
1446 subCopyImageToScreen(*si, aniPushRight);
1451 PlayField16[*si] = 0x2603;
1452 goto loc_MoveNoSplit;
1454 // ==========================================================================
1455 // ORANGE DISK moving right to left
1456 // ==========================================================================
1459 if (PlayField16[*si - 2] != 0)
1462 PlayField16[*si - 2] = 0x800;
1463 subCopyImageToScreen(*si, aniPushLeft);
1468 PlayField16[*si] = 0x2803;
1469 goto loc_MoveNoSplit;
1471 // ==========================================================================
1472 // ORANGE DISK moving left to right
1473 // ==========================================================================
1476 if (PlayField16[*si + 2] != 0)
1479 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1482 PlayField16[*si + 2] = 0x100;
1483 subCopyImageToScreen(*si, aniPushRight);
1488 PlayField16[*si] = 0x2903;
1489 // ==========================================================================
1490 // Copy screen animation action table to action work space
1491 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1492 // ==========================================================================
1495 MovingPictureSequencePhase = 8; // init picture move sequence
1498 SplitMoveFlag = 0; // no port: no split movement
1501 // copy/store global move sequence info????????????????????????????????????
1502 // ... dont think so ...(FS)
1503 // ==========================================================================
1504 // Proceed with all movements
1505 // ==========================================================================
1507 locProceedMovingMurphy: // proceed moving murphy
1508 YawnSleepCounter = 0; // Wake up sleeping Murphy
1509 ax = MovingPictureSequencePhase; // sequence busy?
1510 if (ax == 0) // no -- start sequence!
1513 ax = ax - 1; // next picture of sequence
1514 MovingPictureSequencePhase = ax; // store for later
1515 if (ax == 0) // Sound effects
1518 bl = HighByte(PlayField16[*si]);
1519 if (bl == 0xE) // Push Zonk to left
1522 if (bl == 0xF) // Push Zonk to right
1525 if (bl == 0x28) // Push orange disk to left
1528 if (bl == 0x29) // Push orange disk to right
1531 if (bl == 0x24) // Push yellow disk up
1534 if (bl == 0x25) // Push yellow disk to left
1537 if (bl == 0x27) // Push yellow disk down
1540 if (bl == 0x26) // Push yellow disk to right
1543 if (bl == 0x2A) // Red disk release timer
1548 // ==========================================================================
1549 // Paint frame of MOVING.DAT sequence
1550 // ==========================================================================
1553 if (SplitMoveFlag == 0)
1555 // ++++++++++++++++++++++++++
1556 // Begin of normal movement
1558 MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1559 MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1561 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1562 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1567 printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1569 DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1570 (DemoKeyCode == keyNone ? "(none)" :
1571 DemoKeyCode == keyLeft ? "left" :
1572 DemoKeyCode == keyRight ? "right" :
1573 DemoKeyCode == keyUp ? "up" :
1574 DemoKeyCode == keyDown ? "down" :
1575 DemoKeyCode == keySpace ? "space" :
1576 DemoKeyCode == keySpaceLeft ? "space + left" :
1577 DemoKeyCode == keySpaceRight ? "space + right" :
1578 DemoKeyCode == keySpaceUp ? "space + up" :
1579 DemoKeyCode == keySpaceDown ? "space + down" : "(unknown)"),
1581 MurphyScreenXPos, MurphyScreenYPos,
1582 MurphyPosIndex % 60, MurphyPosIndex / 60,
1591 if (!(ClearPos < 0)) // clear field that murphy is leaving
1592 subCopyImageToScreen(ClearPos, aniSpace);
1594 if (! ClearPos < 0) // clear field that murphy is leaving
1595 subCopyFieldToScreen(ClearPos, 0);
1599 printf("::: ---------------> %d, %d [%d, %d]\n",
1600 MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1603 if (dx2 == fiInfotron) // special case of infotron moving left or right
1610 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1611 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1614 X = GetStretchX(dxPos) + tDeltaX;
1615 Y = GetStretchY(dxPos) + tDeltaY;
1616 Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1617 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1625 tPos = dxPos + dx2Step;
1626 X = GetStretchX(tPos);
1627 Y = GetStretchY(tPos);
1628 if (dx2 == fiInfotron) // special case of infotron moving left or right
1630 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1632 else // pushing something
1635 // (SeqPos iterates from 0 to 7 while pushing)
1636 StretchedSprites.BltImg(X + tDeltaX, Y + tDeltaY, dx2, SeqPos);
1638 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1643 // End of normal movement
1644 // ------------------------
1648 // ++++++++++++++++++++++++++++++++
1649 // Begin of split movement (port)
1651 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1652 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1654 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1655 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
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 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1663 tPos = dxPos + dx2Step;
1664 X = GetStretchX(tPos);
1665 Y = GetStretchY(tPos);
1666 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1667 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1668 // End of split movement (port)
1669 // ------------------------------
1670 } // loc_g_6D1E:'loc_g_6D28:
1672 SeqPos = SeqPos + 1;
1673 if (dx[SeqPos] > -1)
1676 // Follow-up after movement completed 'loc_g_6D35:
1677 MurphyXPos = MurphyXPos + MurphyDX;
1678 MurphyYPos = MurphyYPos + MurphyDY;
1679 bl = HighByte(PlayField16[*si]); // animation phase
1680 MovHighByte(&PlayField16[*si], 0);
1682 if (bl == 0x1) // space, moving up
1685 if (bl == 0x2) // space, moving left
1688 if (bl == 0x3) // space, moving down
1691 if (bl == 0x4) // space, moving right
1694 if (bl == 0x5) // base , moving up
1697 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1700 if (bl == 0x7) // base , moving down
1703 if (bl == 0x8) // base , moving right
1706 if (bl == 0x9) // infotron, moving up
1709 if (bl == 0xA) // infotron, moving left
1712 if (bl == 0xB) // infotron, moving down
1715 if (bl == 0xC) // infotron, moving right
1718 if (bl == 0xD) // exit
1721 if (bl == 0xE) // zonk, pushing left
1724 if (bl == 0xF) // zonk, pushing right
1727 if (bl == 0x10) // base , touching up
1730 if (bl == 0x11) // base , touching left
1733 if (bl == 0x12) // base , touching down
1736 if (bl == 0x13) // base , touching right
1739 if (bl == 0x14) // infotron touching up
1742 if (bl == 0x15) // infotron touching left
1745 if (bl == 0x16) // infotron touching down
1748 if (bl == 0x17) // infotron touching right
1751 if (bl == 0x18) // port up
1754 if (bl == 0x19) // port left
1757 if (bl == 0x1A) // port down
1760 if (bl == 0x1B) // port right
1763 if (bl == 0x1C) // red disk, moving up
1766 if (bl == 0x1D) // red disk, moving left
1769 if (bl == 0x1E) // red disk, moving down
1772 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1775 if (bl == 0x20) // red disk, touching up
1778 if (bl == 0x21) // red disk, touching left
1781 if (bl == 0x22) // red disk, touching down
1784 if (bl == 0x23) // red disk, touching right
1787 if (bl == 0x24) // yellow disk, pushing up
1790 if (bl == 0x25) // yellow disk, pushing left
1793 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1796 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1799 if (bl == 0x28) // orange disk, pushing left
1802 if (bl == 0x29) // orange disk, pushing right
1805 if (bl == 0x2A) // red disk, release
1812 // ==========================================================================
1813 // infotron, moving up
1814 // ==========================================================================
1817 if (0 < LowByte(InfotronsNeeded))
1818 InfotronsNeeded = InfotronsNeeded - 1;
1820 subDisplayInfotronsNeeded();
1821 loc_g_6EC8: // space, base
1822 PlayField16[*si] = fiMurphy;
1823 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1827 // ==========================================================================
1828 // infotron, moving left
1829 // ==========================================================================
1832 if (0 < LowByte(InfotronsNeeded))
1833 InfotronsNeeded = InfotronsNeeded - 1;
1835 subDisplayInfotronsNeeded();
1836 loc_g_6EE6: // space, base
1837 PlayField16[*si] = fiMurphy;
1838 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1842 // ==========================================================================
1843 // infotron, moving down
1844 // ==========================================================================
1847 if (0 < LowByte(InfotronsNeeded))
1848 InfotronsNeeded = InfotronsNeeded - 1;
1850 subDisplayInfotronsNeeded();
1851 loc_g_6F04: // space, base
1852 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1853 PlayField16[*si - FieldWidth] = 0;
1855 PlayField16[*si] = fiMurphy;
1859 // ==========================================================================
1860 // infotron, moving right
1861 // ==========================================================================
1864 if (0 < LowByte(InfotronsNeeded))
1865 InfotronsNeeded = InfotronsNeeded - 1;
1867 subDisplayInfotronsNeeded();
1868 loc_g_71C4: // space, base
1869 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1870 PlayField16[*si] = fiMurphy;
1874 // ==========================================================================
1875 // infotron, touching up
1876 // ==========================================================================
1879 if (0 < LowByte(InfotronsNeeded))
1880 InfotronsNeeded = InfotronsNeeded - 1;
1882 subDisplayInfotronsNeeded();
1884 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1885 PlayField16[*si - FieldWidth] = 0;
1889 // ==========================================================================
1890 // infotron, touching left
1891 // ==========================================================================
1894 if (0 < LowByte(InfotronsNeeded))
1895 InfotronsNeeded = InfotronsNeeded - 1;
1897 subDisplayInfotronsNeeded();
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;
1912 subDisplayInfotronsNeeded();
1914 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1915 PlayField16[*si + FieldWidth] = 0;
1919 // ==========================================================================
1920 // infotron, touching right
1921 // ==========================================================================
1924 if (0 < LowByte(InfotronsNeeded))
1925 InfotronsNeeded = InfotronsNeeded - 1;
1927 subDisplayInfotronsNeeded();
1929 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1930 PlayField16[*si + 1] = 0;
1934 // ==========================================================================
1935 // zonk, pushing left
1936 // ==========================================================================
1939 if (LowByte(PlayField16[*si]) != fiExplosion)
1940 PlayField16[*si] = 0;
1942 PlayField16[*si - 1] = fiMurphy;
1943 PlayField16[*si - 2] = fiZonk;
1944 subExplodeSnikSnaksBelow(*si - 2);
1949 // ==========================================================================
1950 // zonk, pushing right
1951 // ==========================================================================
1954 if (LowByte(PlayField16[*si]) != fiExplosion)
1955 PlayField16[*si] = 0;
1957 PlayField16[*si + 1] = fiMurphy;
1958 PlayField16[*si + 2] = fiZonk;
1959 subExplodeSnikSnaksBelow(*si + 2);
1964 // ==========================================================================
1966 // ==========================================================================
1972 PlayField16[*si] = fiSpace; // remove Murphy from playfield after exiting
1977 // ==========================================================================
1978 // Push Zonk from right to left
1979 // ==========================================================================
1982 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1985 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1986 PlayField16[*si - 1] = fiZonk;
1987 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1988 PlayField16[*si - 2] = 0;
1990 subCopyImageToScreen(*si, aniMurphy);
1994 // ==========================================================================
1995 // Push Zonk from left to right
1996 // ==========================================================================
1999 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
2002 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
2003 PlayField16[*si + 1] = fiZonk;
2004 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2005 PlayField16[*si + 2] = 0;
2007 subCopyImageToScreen(*si, aniMurphy);
2011 // ==========================================================================
2012 // Push orange disk from right to left
2013 // ==========================================================================
2016 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
2019 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2020 PlayField16[*si - 1] = fiOrangeDisk;
2021 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2022 PlayField16[*si - 2] = 0;
2024 subCopyImageToScreen(*si, aniMurphy);
2028 // ==========================================================================
2029 // Push orange disk from left to right
2030 // ==========================================================================
2033 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
2036 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2037 PlayField16[*si + 1] = fiOrangeDisk;
2038 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2039 PlayField16[*si + 2] = 0;
2041 subCopyImageToScreen(*si, aniMurphy);
2045 // ==========================================================================
2046 // Push yellow disk from down to up
2047 // ==========================================================================
2050 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
2053 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2054 PlayField16[*si - FieldWidth] = fiYellowDisk;
2055 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
2056 PlayField16[*si - 2 * FieldWidth] = 0;
2058 subCopyImageToScreen(*si, aniMurphy);
2062 // ==========================================================================
2063 // Push yellow disk from right to left
2064 // ==========================================================================
2067 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
2070 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2071 PlayField16[*si - 1] = fiYellowDisk;
2072 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2073 PlayField16[*si - 2] = 0;
2075 subCopyImageToScreen(*si, aniMurphy);
2079 // ==========================================================================
2080 // Push yellow disk from up to down
2081 // ==========================================================================
2084 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
2087 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2088 PlayField16[*si + FieldWidth] = fiYellowDisk;
2089 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
2090 PlayField16[*si + 2 * FieldWidth] = 0;
2092 subCopyImageToScreen(*si, aniMurphy);
2096 // ==========================================================================
2097 // Push yellow disk from left to right
2098 // ==========================================================================
2101 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
2104 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2105 PlayField16[*si + 1] = fiYellowDisk;
2106 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2107 PlayField16[*si + 2] = 0;
2109 subCopyImageToScreen(*si, aniMurphy);
2113 // ==========================================================================
2114 // time red disk release (space)
2115 // ==========================================================================
2118 if (DemoKeyCode != keySpace)
2120 PlayField16[*si] = fiMurphy;
2121 subCopyImageToScreen(*si, aniMurphy);
2122 RedDiskReleasePhase = 0;
2124 else if (MovingPictureSequencePhase == 0x20)
2127 // anxious murphy, dropping red disk
2128 subCopyImageToScreen(*si, aniMurphyDropping);
2130 subCopyFieldToScreen(*si, 43); // anxious murphy
2132 RedDiskReleasePhase = 1;
2137 // ==========================================================================
2138 // Special port down to up
2139 // ==========================================================================
2142 if (LowByte(PlayField16[*si]) != fiExplosion)
2143 PlayField16[*si] = 0;
2145 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
2147 *si = *si - FieldWidth;
2148 if (HighByte(PlayField16[*si]) == 1)
2151 *si = *si - FieldWidth;
2155 // ==========================================================================
2156 // Special port right to left
2157 // ==========================================================================
2160 if (LowByte(PlayField16[*si]) != fiExplosion)
2161 PlayField16[*si] = 0;
2163 PlayField16[*si - 2] = fiMurphy;
2166 if (HighByte(PlayField16[*si]) == 1)
2173 // ==========================================================================
2174 // Special port up to down
2175 // ==========================================================================
2178 if (LowByte(PlayField16[*si]) != fiExplosion)
2179 PlayField16[*si] = 0;
2181 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2183 *si = *si + FieldWidth;
2184 if (HighByte(PlayField16[*si]) == 1)
2187 *si = *si + FieldWidth;
2191 // ==========================================================================
2192 // Special port left to right
2193 // ==========================================================================
2196 if (LowByte(PlayField16[*si]) != fiExplosion)
2197 PlayField16[*si] = 0;
2199 PlayField16[*si + 2] = fiMurphy;
2202 if (HighByte(PlayField16[*si]) == 1)
2209 // ==========================================================================
2211 // ==========================================================================
2214 if (LowByte(PlayField16[*si]) != fiExplosion)
2215 PlayField16[*si] = 0;
2217 *si = *si - FieldWidth;
2218 PlayField16[*si] = fiMurphy;
2219 subEatRedDisk(*si); // inc+show Murphy's red disks
2223 // ==========================================================================
2224 // Move Red Disk left
2225 // ==========================================================================
2228 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2229 PlayField16[*si + 1] = 0;
2231 PlayField16[*si] = fiMurphy;
2232 subEatRedDisk(*si); // inc+show Murphy's red disks
2236 // ==========================================================================
2237 // Move Red Disk down
2238 // ==========================================================================
2241 if (LowByte(PlayField16[*si]) != fiExplosion)
2242 PlayField16[*si] = 0;
2244 *si = *si + FieldWidth;
2245 PlayField16[*si] = fiMurphy;
2246 subEatRedDisk(*si); // inc+show Murphy's red disks
2250 // ==========================================================================
2251 // Move Red Disk right
2252 // ==========================================================================
2255 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2256 PlayField16[*si - 1] = 0;
2258 PlayField16[*si] = fiMurphy;
2259 subEatRedDisk(*si); // inc+show Murphy's red disks
2263 // ==========================================================================
2265 // ==========================================================================
2268 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2269 PlayField16[*si - FieldWidth] = 0;
2271 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2275 // ==========================================================================
2276 // Eat Red Disk left
2277 // ==========================================================================
2280 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2281 PlayField16[*si - 1] = 0;
2283 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2287 // ==========================================================================
2288 // Eat Red Disk down
2289 // ==========================================================================
2292 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2293 PlayField16[*si + FieldWidth] = 0;
2295 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2299 // ==========================================================================
2300 // Eat Red Disk right
2301 // ==========================================================================
2304 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2305 PlayField16[*si + 1] = 0;
2307 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2311 // ==========================================================================
2312 // yellow disk, pushing up
2313 // ==========================================================================
2316 if (LowByte(PlayField16[*si]) != fiExplosion)
2317 PlayField16[*si] = 0;
2319 *si = *si - FieldWidth;
2320 PlayField16[*si] = fiMurphy;
2321 PlayField16[*si - FieldWidth] = fiYellowDisk;
2325 // ==========================================================================
2326 // yellow disk, pushing left
2327 // ==========================================================================
2330 if (LowByte(PlayField16[*si]) != fiExplosion)
2331 PlayField16[*si] = 0;
2334 PlayField16[*si] = fiMurphy;
2335 PlayField16[*si - 1] = fiYellowDisk;
2339 // ==========================================================================
2340 // yellow disk, pushing down
2341 // ==========================================================================
2344 if (LowByte(PlayField16[*si]) != fiExplosion)
2345 PlayField16[*si] = 0;
2347 *si = *si + FieldWidth;
2348 PlayField16[*si] = fiMurphy;
2349 PlayField16[*si + FieldWidth] = fiYellowDisk;
2353 // ==========================================================================
2354 // yellow disk pushing right
2355 // ==========================================================================
2358 if (LowByte(PlayField16[*si]) != fiExplosion)
2359 PlayField16[*si] = 0;
2362 PlayField16[*si] = fiMurphy;
2363 PlayField16[*si + 1] = fiYellowDisk;
2367 // ==========================================================================
2368 // orange disk, pushing left
2369 // ==========================================================================
2372 if (LowByte(PlayField16[*si]) != fiExplosion)
2373 PlayField16[*si] = 0;
2376 PlayField16[*si] = fiMurphy;
2377 PlayField16[*si - 1] = fiOrangeDisk;
2381 // ==========================================================================
2382 // orange disk, pushing right
2383 // ==========================================================================
2386 if (LowByte(PlayField16[*si]) != fiExplosion)
2387 PlayField16[*si] = 0;
2390 PlayField16[*si] = fiMurphy;
2391 PlayField16[*si + 1] = fiOrangeDisk;
2392 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2394 MovHighByte(&PlayField16[*si + 1], 0x20);
2395 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2400 // ==========================================================================
2401 // Release a red disk
2402 // ==========================================================================
2405 PlayField16[*si] = fiMurphy;
2406 RedDiskReleasePhase = 2;
2407 RedDiskCount = RedDiskCount - 1;
2408 subDisplayRedDiskCount();
2409 subSoundFXPush(); // Sound effects
2410 } // subAnimateMurphy
2412 // ==========================================================================
2414 // ==========================================================================
2415 void subExplodeSnikSnaksBelow(int si)
2419 ax = LowByte(PlayField16[si + FieldWidth]);
2420 if (ax == 0x11 || ax == 0xBB)
2421 ExplodeFieldSP(si + FieldWidth);
2422 } // subExplodeSnikSnaksBelow
2424 // ==========================================================================
2426 // Does pushing against an object kill Murphy?
2427 // ==========================================================================
2428 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2430 static boolean subMoveKillsMurphy;
2436 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2442 if (al == fiExplosion)
2445 if (fiOrangeDisk <= al && al <= fiPortUp)
2448 ExplodeFieldSP(si); // Explode
2449 subMoveKillsMurphy = True;
2450 return subMoveKillsMurphy;
2459 ExplodeFieldSP(si); // Explode
2460 subMoveKillsMurphy = True;
2461 return subMoveKillsMurphy;
2463 loc_g_74F6: // zonk left
2465 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2468 subMoveKillsMurphy = True; // Set carry flag
2469 return subMoveKillsMurphy;
2471 loc_g_7512: // zonk right
2473 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2476 loc_g_752E: // Marked fields and Ports
2477 subMoveKillsMurphy = True; // Set carry flag
2478 return subMoveKillsMurphy;
2480 loc_g_7530: // explosion
2481 if ((ah & 0x80) != 0)
2488 ExplodeFieldSP(si); // Explode
2489 subMoveKillsMurphy = True; // Set carry flag
2490 return subMoveKillsMurphy;
2493 PlayField16[si] = 0;
2494 subMoveKillsMurphy = False;
2496 return subMoveKillsMurphy;
2497 } // subMoveKillsMurphy
2499 // ==========================================================================
2501 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2502 // change conditions to port specs
2503 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2504 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2505 // ==========================================================================
2506 int subSpPortTest(int si)
2513 cx = LInfo.SpecialPortCount; // number of special ports
2515 for (i = 0; i < cx; i++)
2518 /* this assumes that PortLocation is stored as big endian */
2519 bx = LInfo.SpecialPort[i].PortLocation;
2521 /* this assumes that PortLocation is stored as little endian */
2522 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2523 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2528 GravityFlag = LInfo.SpecialPort[i].Gravity;
2529 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2530 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2532 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2540 cx = LInfo.SpecialPortCount; // number of special ports
2541 for (i = 1; i <= cx; i++)
2544 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2545 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2548 GravityFlag = LInfo.SpecialPort[i].Gravity;
2549 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2550 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2551 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2558 return subSpPortTest;
2561 void subCopyFieldToScreen(int si, int fi)
2565 // +++++++++++++++++++++++++++++++++++++++++
2566 X = GetStretchX(si);
2567 Y = GetStretchY(si);
2568 StretchedSprites.BltEx(X, Y, fi);
2569 // +++++++++++++++++++++++++++++++++++++++++
2572 void subCopyAnimToScreen(int si, int graphic, int sync_frame)
2576 // +++++++++++++++++++++++++++++++++++++++++
2577 X = GetStretchX(si);
2578 Y = GetStretchY(si);
2579 StretchedSprites.BltImg(X, Y, graphic, sync_frame);
2580 // +++++++++++++++++++++++++++++++++++++++++
2583 void subCopyImageToScreen(int si, int graphic)
2585 subCopyAnimToScreen(si, graphic, 0);
2588 static void subEatRedDisk(int si)
2590 if (AllowRedDiskCheat == 0)
2592 if (RedDiskReleasePhase != 0)
2594 if (RedDiskReleaseMurphyPos == si)
2599 RedDiskCount = (RedDiskCount + 1) % 256;
2600 subDisplayRedDiskCount();
2603 void subAdjustZonksInfotronsAboveMurphy(int si)
2607 if (LowByte(PlayField16[si]) != fiExplosion)
2608 PlayField16[si] = 0;
2610 ax = PlayField16[si - FieldWidth];
2611 if (ax == 0 || ax == 0x9999)
2614 if (ax == fiZonk || ax == fiInfotron)
2616 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2621 loc_g_15A8: // empty above
2622 ax = PlayField16[si - FieldWidth - 1];
2623 if (ax == fiZonk || ax == fiInfotron)
2627 ax = PlayField16[si - FieldWidth + 1];
2628 if (ax == fiZonk || ax == fiInfotron)
2633 loc_g_15C5: // zonk/infotron above left
2634 ax = PlayField16[si - 1];
2635 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2638 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2639 PlayField16[si - FieldWidth] = 0x8888;
2643 loc_g_15E8: // zonk/infotron above right
2644 ax = PlayField16[si + 1];
2645 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2647 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2648 PlayField16[si - FieldWidth] = 0x8888;
2650 } // subAdjustZonksInfotronsAboveMurphy