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 int subAnimateMurphy(int *si)
35 // int ax, al, ah, bx, bl, i, X, Y;
36 // int tX, tY, tDeltaX, tDeltaY, tPos, Tmp;
37 int ax, al, bx, bl, i, X, Y;
38 int tDeltaX, tDeltaY, tPos, Tmp;
40 // Variables that hold information about the animation sequence
41 static int *dx = 0; // an array of image positions in moving.mpx, finalized with -1
42 static int dx2 = 0; // an additional image position of a second sprite, for instance: yellow disk if pushed
43 static int MurphyDX = 0, MurphyDY = 0; // murphys move steps
44 static int SeqPos = 0; // index into dx()
45 static int ClearPos = 0; // Position to clear before blitting sprites, none=-1
46 static int dxPos = 0; // field-position to draw dx(SeqPos)
47 static int dx2Step = 0; // position of dx2 relative to dx-position
49 ax = PlayField16[*si];
53 printf("::: Murphy.c: subAnimateMurphy(): %d [%d, %d] %d, %d [%d]\n",
54 *si, *si % 60, *si / 60, ax, al, (al == fiMurphy));
59 MurphyMoveCounter = 0; // We have no Murphy! Exit!
60 return subAnimateMurphy;
63 MurphyMoveCounter = 1; // We have a Murphy!
64 MurphyExplodePos = *si;
65 if (ax != 3) // yes--go proceed moving murphy?
66 goto locProceedMovingMurphy;
68 // FS: reset moving sequence variables
76 ScratchGravity = 0; // scratch gravity off
77 if (GravityFlag != 0) // Gravity? (1=gravity on)
79 bl = LowByte(PlayField16[*si - FieldWidth]); // check above
80 if (! (bl == fiPortUp || bl == fiPortUpAndDown || bl == fiPortAllDirections))
82 if (PlayField16[*si + FieldWidth] == 0) // gravity on and space below!
88 if (bl != 0) // a key was pressed!
89 goto locKeyPressed5FCF;
92 printf("::: !!! %d [%d]\n", DemoKeyCode, GravityFlag);
95 RedDiskReleaseFlag = 1;
96 if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
104 return subAnimateMurphy;
106 // ------------------------------------------------------------------
107 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
108 YawnSleepCounter = YawnSleepCounter + 1;
109 if (YawnSleepCounter == 4)
111 subCopyFieldToScreen(*si, fiMurphy); // normal grin
112 return subAnimateMurphy;
115 if (YawnSleepCounter <= 500) // loc_g_5ED7:
116 return subAnimateMurphy;
118 if (YawnSleepCounter <= 522)
120 bx = (YawnSleepCounter - 500) / 2;
121 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
122 return subAnimateMurphy;
125 if (YawnSleepCounter <= 1000)
126 return subAnimateMurphy;
128 if (YawnSleepCounter <= 1022)
130 bx = (YawnSleepCounter - 1000) / 2;
131 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again!
132 return subAnimateMurphy;
135 if (YawnSleepCounter <= 1600) // loc_g_5F3B:
136 return subAnimateMurphy;
138 if (YawnSleepCounter <= 1622)
140 bx = (YawnSleepCounter - 1600) / 2;
141 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again! - third time
142 return subAnimateMurphy;
145 if (YawnSleepCounter > 1654)
146 return subAnimateMurphy;
148 if (PlayField16[*si - 1] == 0)
150 if (PlayField16[*si + 1] == 0)
152 YawnSleepCounter = 36;
153 return subAnimateMurphy;
158 bx = (YawnSleepCounter - 1622) / 16;
159 subCopyFieldToScreen(*si, aniMurphySleepRight + bx); // go to sleep
160 return subAnimateMurphy;
164 bx = (YawnSleepCounter - 1622) / 16;
165 subCopyFieldToScreen(*si, aniMurphySleepLeft + bx); // go to sleep
166 return subAnimateMurphy;
168 // end of YAWN-SLEEP-Sequence
169 // ------------------------------------------------------------------
170 // ==========================================================================
171 // (Direct Jump) a key was pressed
172 // ==========================================================================
175 if (ScratchGravity == 0)
178 if (PlayField16[*si + FieldWidth] != 0)
183 if (PlayField16[*si - FieldWidth] == fiBase)
187 else if (bl == keyLeft)
189 if (PlayField16[*si - 1] == fiBase)
193 else if (bl == keyRight)
195 if (PlayField16[*si + 1] == fiBase)
199 bl = keyDown; // force moving down!
204 RedDiskReleaseFlag = 0; // moving down to up ...
210 RedDiskReleaseFlag = 0; // moving right to left ...
216 RedDiskReleaseFlag = 0; // moving up to down ...
222 RedDiskReleaseFlag = 0; // moving left to right ...
227 case keySpaceUp: // 5
228 RedDiskReleaseFlag = 0; // touching down to up ...
233 case keySpaceLeft: // 6
234 RedDiskReleaseFlag = 0; // touching right to left ...
239 case keySpaceDown: // 7
240 RedDiskReleaseFlag = 0; // touching up to down ...
245 case keySpaceRight: // 8
246 RedDiskReleaseFlag = 0; // touching left to right ...
252 goto loc_g_62E2; // no move ...
257 RedDiskReleaseFlag = 0;
258 return subAnimateMurphy;
262 // ==========================================================================
263 // moving down to up ...
264 // ==========================================================================
270 ax = PlayField16[*si - FieldWidth];
281 if (ax == fiInfotron)
287 if (al == fiTerminal)
290 if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
296 if (al == fiYellowDisk)
299 if (! subMoveKillsMurphy(*si - FieldWidth, ax, bl))
302 return subAnimateMurphy;
304 // ==========================================================================
305 // moving right to left ...
306 // ==========================================================================
312 MurphyVarFaceLeft = 1;
313 ax = PlayField16[*si - 1];
324 if (ax == fiInfotron)
333 if (al == fiTerminal)
336 if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
342 if (ax == fiYellowDisk)
345 if (ax == fiOrangeDisk)
348 if (! subMoveKillsMurphy(*si - 1, ax, bl))
351 return subAnimateMurphy;
353 // ==========================================================================
354 // moving up to down ...
355 // ==========================================================================
361 ax = PlayField16[*si + FieldWidth];
372 if (ax == fiInfotron)
378 if (al == fiTerminal)
381 if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
387 if (al == fiYellowDisk)
390 if (! subMoveKillsMurphy(*si + FieldWidth, ax, bl))
393 return subAnimateMurphy;
395 // ==========================================================================
396 // moving left to right ...
397 // ==========================================================================
403 MurphyVarFaceLeft = 0;
404 ax = PlayField16[*si + 1];
415 if (ax == fiInfotron)
424 if (al == fiTerminal)
427 if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
433 if (al == fiYellowDisk)
436 if (ax == fiOrangeDisk)
439 if (! subMoveKillsMurphy(*si + 1, ax, bl))
442 return subAnimateMurphy;
444 // ==========================================================================
445 // touching down to up ...
446 // ==========================================================================
451 dxPos = *si - FieldWidth;
453 ax = PlayField16[*si - FieldWidth];
462 if (ax == fiInfotron)
465 if (al == fiTerminal)
471 return subAnimateMurphy;
473 // ==========================================================================
474 // touching right to left ...
475 // ==========================================================================
482 MurphyVarFaceLeft = 1;
483 ax = PlayField16[*si - 1];
491 if (ax == fiInfotron)
494 if (al == fiTerminal)
500 return subAnimateMurphy;
502 // ==========================================================================
503 // touching up to down ...
504 // ==========================================================================
509 dxPos = *si + FieldWidth;
511 ax = PlayField16[*si + FieldWidth];
519 if (ax == fiInfotron)
522 if (al == fiTerminal)
528 return subAnimateMurphy;
530 // ==========================================================================
531 // touching left to right ...
532 // ==========================================================================
539 MurphyVarFaceLeft = 0;
540 ax = PlayField16[*si + 1];
548 if (ax == fiInfotron)
551 if (al == fiTerminal)
557 return subAnimateMurphy;
559 // ==========================================================================
560 // Release Red disk: no move ...
561 // ==========================================================================
567 if (LowByte(RedDiskCount) == 0)
568 return subAnimateMurphy;
570 if (LowByte(RedDiskReleasePhase) != 0)
571 return subAnimateMurphy;
573 if (LowByte(RedDiskReleaseFlag) != 1)
574 return subAnimateMurphy;
576 MovHighByte(&PlayField16[*si], 0x2A);
577 MovingPictureSequencePhase = 0x40; // init picture move sequence
579 MovLowByte(&RedDiskReleasePhase, 1);
580 Mov(&RedDiskReleaseMurphyPos, *si); // remember Murphy's location
583 // ==========================================================================
584 // SPACE moving down to up
585 // ==========================================================================
588 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
589 PlayField16[*si - FieldWidth] = 0x103;
590 PlayField16[*si] = 0x300;
591 *si = *si - FieldWidth;
592 goto loc_StopNoSplit;
594 // ==========================================================================
595 // SPACE moving right to left
596 // ==========================================================================
599 dx = aniMurphyEatLeft;
600 PlayField16[*si - 1] = 0x203;
601 PlayField16[*si] = 0x300;
603 goto loc_StopNoSplit;
605 // ==========================================================================
606 // SPACE moving up to down, and when gravity is pulling!
607 // ==========================================================================
610 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
611 PlayField16[*si + FieldWidth] = 0x303;
612 PlayField16[*si] = 0x300;
613 *si = *si + FieldWidth;
614 goto loc_StopNoSplit;
616 // ==========================================================================
617 // SPACE moving left to right
618 // ==========================================================================
621 dx = aniMurphyEatRight;
622 PlayField16[*si + 1] = 0x403;
623 PlayField16[*si] = 0x300;
625 goto loc_StopNoSplit;
627 // ==========================================================================
628 // BUG moving down to up
629 // ==========================================================================
632 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
634 ExplodeFieldSP(*si); // Explode
635 return subAnimateMurphy;
638 PlayField16[*si - FieldWidth] = fiBase;
639 // ==========================================================================
640 // BASE moving down to up
641 // ==========================================================================
645 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
646 PlayField16[*si - FieldWidth] = 0x503;
647 PlayField16[*si] = 0x300;
648 *si = *si - FieldWidth;
649 goto loc_StopNoSplit;
651 // ==========================================================================
652 // BUG moving right to left
653 // ==========================================================================
656 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
658 ExplodeFieldSP(*si); // Explode
659 return subAnimateMurphy;
662 PlayField16[*si - 1] = fiBase;
663 // ==========================================================================
664 // BASE moving right to left
665 // ==========================================================================
669 dx = aniMurphyEatLeft;
670 PlayField16[*si - 1] = 0x203;
671 PlayField16[*si] = 0x300;
673 goto loc_StopNoSplit;
675 // ==========================================================================
676 // BUG moving up to down
677 // ==========================================================================
680 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
682 ExplodeFieldSP(*si); // Explode
683 return subAnimateMurphy;
686 PlayField16[*si + FieldWidth] = fiBase;
687 // ==========================================================================
688 // BASE moving up to down
689 // ==========================================================================
693 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
694 PlayField16[*si + FieldWidth] = 0x703;
695 PlayField16[*si] = 0x300;
696 *si = *si + FieldWidth;
697 goto loc_StopNoSplit;
699 // ==========================================================================
700 // BUG moving left to right
701 // ==========================================================================
704 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
706 ExplodeFieldSP(*si); // Explode
707 return subAnimateMurphy;
710 PlayField16[*si + 1] = fiBase;
711 // ==========================================================================
712 // BASE moving left to right
713 // ==========================================================================
717 dx = aniMurphyEatRight;
718 PlayField16[*si + 1] = 0x803;
719 PlayField16[*si] = 0x300;
721 goto loc_StopNoSplit;
723 // ==========================================================================
724 // BUG touching down to up
725 // ==========================================================================
728 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
730 ExplodeFieldSP(*si); // Explode
731 return subAnimateMurphy;
734 PlayField16[*si - FieldWidth] = fiBase;
735 // ==========================================================================
736 // BASE touching down to up
737 // ==========================================================================
740 subCopyFieldToScreen(*si, aniMurphyTouchUp);
743 dxPos = *si - FieldWidth;
744 MovHighByte(&PlayField16[*si], 0x10);
745 goto loc_StopNoSplit;
747 // ==========================================================================
748 // BUG touching right to left
749 // ==========================================================================
752 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
754 ExplodeFieldSP(*si); // Explode
755 return subAnimateMurphy;
758 PlayField16[*si - 1] = fiBase;
759 // ==========================================================================
760 // BASE touching right to left
761 // ==========================================================================
764 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
768 MovHighByte(&PlayField16[*si], 0x11);
769 goto loc_StopNoSplit;
771 // ==========================================================================
772 // BUG touching up to down
773 // ==========================================================================
776 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
778 ExplodeFieldSP(*si); // Explode
779 return subAnimateMurphy;
782 PlayField16[*si + FieldWidth] = fiBase;
783 // ==========================================================================
784 // BASE touching up to down
785 // ==========================================================================
788 subCopyFieldToScreen(*si, aniMurphyTouchDown);
791 dxPos = *si + FieldWidth;
792 MovHighByte(&PlayField16[*si], 0x12);
793 goto loc_StopNoSplit;
795 // ==========================================================================
796 // BUG touching left to right
797 // ==========================================================================
800 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
802 ExplodeFieldSP(*si); // Explode
803 return subAnimateMurphy;
806 PlayField16[*si + 1] = fiBase;
807 // ==========================================================================
808 // BASE touching left to right
809 // ==========================================================================
812 subCopyFieldToScreen(*si, aniMurphyTouchRight);
816 MovHighByte(&PlayField16[*si], 0x13);
817 goto loc_StopNoSplit;
819 // ==========================================================================
820 // INFOTRON moving down to up
821 // ==========================================================================
824 subSoundFXInfotron();
825 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
826 PlayField16[*si - FieldWidth] = 0x903;
827 PlayField16[*si] = 0x300;
828 *si = *si - FieldWidth;
829 goto loc_StopNoSplit;
831 // ==========================================================================
832 // INFOTRON moving right to left
833 // ==========================================================================
836 subSoundFXInfotron();
837 dx = aniEatInfotronLeft;
841 PlayField16[*si - 1] = 0xA03;
842 PlayField16[*si] = 0x300;
844 goto loc_StopNoSplit;
846 // ==========================================================================
847 // INFOTRON moving up to down
848 // ==========================================================================
851 subSoundFXInfotron();
852 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
853 PlayField16[*si + FieldWidth] = 0xB03;
854 PlayField16[*si] = 0x300;
855 *si = *si + FieldWidth;
856 goto loc_StopNoSplit;
858 // ==========================================================================
859 // INFOTRON moving left to right
860 // ==========================================================================
863 subSoundFXInfotron();
864 dx = aniEatInfotronRight;
868 PlayField16[*si + 1] = 0xC03;
869 PlayField16[*si] = 0x300;
871 goto loc_StopNoSplit;
873 // ==========================================================================
874 // INFOTRON touching down to up
875 // ==========================================================================
878 subCopyFieldToScreen(*si, aniMurphyTouchUp);
879 subSoundFXInfotron();
880 dx = aniTouchInfotron;
881 MovHighByte(&PlayField16[*si], 0x14);
882 MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
883 goto loc_StopNoSplit;
885 // ==========================================================================
886 // INFOTRON touching right to left
887 // ==========================================================================
890 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
891 subSoundFXInfotron();
892 dx = aniTouchInfotron;
893 MovHighByte(&PlayField16[*si], 0x15);
894 MovHighByte(&PlayField16[*si - 1], 0xFF);
895 goto loc_StopNoSplit;
897 // ==========================================================================
898 // INFOTRON touching up to down
899 // ==========================================================================
902 subCopyFieldToScreen(*si, aniMurphyTouchDown);
903 subSoundFXInfotron();
904 dx = aniTouchInfotron;
905 MovHighByte(&PlayField16[*si], 0x16);
906 MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
907 goto loc_StopNoSplit;
909 // ==========================================================================
910 // INFOTRON touching left to right
911 // ==========================================================================
914 subCopyFieldToScreen(*si, aniMurphyTouchRight);
915 subSoundFXInfotron();
916 dx = aniTouchInfotron;
917 MovHighByte(&PlayField16[*si], 0x17);
918 MovHighByte(&PlayField16[*si + 1], 0xFF);
919 goto loc_StopNoSplit;
921 // ==========================================================================
922 // EXIT pressed from any direction
923 // ==========================================================================
931 if (LowByte(InfotronsNeeded) != 0)
932 return subAnimateMurphy;
935 data_h_DemoDone = 1; // EP set level success bytes
936 LevelStatus = 1; // set Level Status DONE
937 EP_GameDemoVar0DAA = 0; // force demo for lead-out
938 if (SavedGameFlag == 0) // saved game running?
940 if (UpdateTimeFlag != 0) // update time?
942 UpdatedFlag = 1; // prevent double update
943 subUpdatePlayingTime(); // update playing time
948 subUpdateHallOfFame(); // update time + Hall-Of-Fame
951 LeadOutCounter = 0x40; // quit: start lead-out
953 MovHighByte(&PlayField16[*si], 0xD);
954 goto loc_StopNoSplit;
956 // ==========================================================================
957 // ZONK moving right to left
958 // ==========================================================================
961 ax = PlayField16[*si - 2];
963 return subAnimateMurphy;
965 MovHighByte(&PlayField16[*si - 2], 1);
966 subCopyFieldToScreen(*si, aniPushLeft); // draw pushing murphy
967 dx = aniZonkRollLeft;
971 MovHighByte(&PlayField16[*si], 0xE);
972 goto loc_MoveNoSplit;
974 // ==========================================================================
975 // ZONK moving left to right
976 // ==========================================================================
979 ax = PlayField16[*si + 2];
981 return subAnimateMurphy;
983 ax = PlayField16[*si + FieldWidth + 1];
984 if (ax == 0) // zonk falls
985 return subAnimateMurphy;
987 MovHighByte(&PlayField16[*si + 2], 1);
988 subCopyFieldToScreen(*si, aniPushRight); // draw pushing murphy
989 dx = aniZonkRollRight;
993 MovHighByte(&PlayField16[*si], 0xF);
994 goto loc_MoveNoSplit;
996 // ==========================================================================
997 // TERMINAL moving/touching down to up
998 // ==========================================================================
1001 subCopyFieldToScreen(*si, aniMurphyTouchUp);
1002 if (YellowDisksExploded != 0)
1004 YawnSleepCounter = 10; // stay hypnotized
1005 return subAnimateMurphy;
1008 subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1009 TerminalState[*si - FieldWidth] = 8;
1012 // ==========================================================================
1013 // TERMINAL moving/touching right to left
1014 // ==========================================================================
1017 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
1018 if (YellowDisksExploded != 0)
1020 YawnSleepCounter = 10; // stay hypnotized
1021 return subAnimateMurphy;
1024 subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1025 TerminalState[*si - 1] = 8;
1028 // ==========================================================================
1029 // TERMINAL moving/touching up to down
1030 // ==========================================================================
1033 subCopyFieldToScreen(*si, aniMurphyTouchDown);
1034 if (YellowDisksExploded != 0)
1036 YawnSleepCounter = 10; // stay hypnotized
1037 return subAnimateMurphy;
1040 subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1041 TerminalState[*si + FieldWidth] = 8;
1044 // ==========================================================================
1045 // TERMINAL moving/touching left to right
1046 // ==========================================================================
1049 subCopyFieldToScreen(*si, aniMurphyTouchRight);
1050 if (YellowDisksExploded != 0)
1052 YawnSleepCounter = 10; // stay hypnotized
1053 return subAnimateMurphy;
1056 subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1057 TerminalState[*si + 1] = 8;
1058 // ==========================================================================
1059 // common TERMINAL stuff moving/touching from all directions
1060 // ==========================================================================
1063 TerminalMaxCycles = 7;
1064 YellowDisksExploded = 1;
1065 for (i = 0; i <= LevelMax; i++)
1067 if (PlayField16[i] == fiYellowDisk)
1071 return subAnimateMurphy;
1073 // ==========================================================================
1074 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1075 // ==========================================================================
1078 if (PlayField16[*si - 2 * FieldWidth] != 0)
1079 return subAnimateMurphy;
1081 dx = aniSplitUpDown;
1082 dx2Step = -FieldWidth;
1083 PlayField16[*si] = 0x1803;
1084 PlayField16[*si - 2 * FieldWidth] = 0x300;
1087 // ==========================================================================
1088 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1089 // ==========================================================================
1092 if (PlayField16[*si - 2] != 0)
1093 return subAnimateMurphy;
1095 dx = aniMurphyEatLeft;
1097 PlayField16[*si] = 0x1903;
1098 PlayField16[*si - 2] = 0x300;
1101 // ==========================================================================
1102 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1103 // ==========================================================================
1106 if (PlayField16[*si + 2 * FieldWidth] != 0)
1107 return subAnimateMurphy;
1109 dx = aniSplitUpDown;
1110 dx2Step = FieldWidth;
1111 PlayField16[*si] = 0x1A03;
1112 PlayField16[*si + 2 * FieldWidth] = 0x300;
1115 // ==========================================================================
1116 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1117 // ==========================================================================
1120 if (PlayField16[*si + 2] != 0)
1121 return subAnimateMurphy;
1123 dx = aniMurphyEatRight;
1125 PlayField16[*si] = 0x1B03;
1126 PlayField16[*si + 2] = 0x300;
1129 MovingPictureSequencePhase = 0; // stop picture move sequence
1130 SplitMoveFlag = 1; // port: split movement
1133 // ==========================================================================
1134 // RED DISK moving down to up
1135 // ==========================================================================
1138 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1139 PlayField16[*si] = 0x1C03;
1140 PlayField16[*si - FieldWidth] = 0x300;
1141 goto loc_StopNoSplit;
1143 // ==========================================================================
1144 // RED DISK moving right to left
1145 // ==========================================================================
1148 dx = aniMurphyEatLeft;
1149 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1150 PlayField16[*si - 1] = 0x1D03;
1152 goto loc_StopNoSplit;
1154 // ==========================================================================
1155 // RED DISK moving up to down
1156 // ==========================================================================
1159 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1160 PlayField16[*si] = 0x1E03;
1161 PlayField16[*si + FieldWidth] = 0x300;
1162 goto loc_StopNoSplit;
1164 // ==========================================================================
1165 // RED DISK moving left to right
1166 // ==========================================================================
1169 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1170 dx = aniMurphyEatRight;
1171 // --------------------------------------------------------------------------
1173 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1174 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1175 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1176 // We may not fix the table, because then the timing of the game changes
1177 // and several existing demo's do not run properly anymore.
1178 // We only correct Murphies x-location here, when the sequence starts.
1179 // Remember that this is not the real bug-fix, but we must live with
1180 // this existing bug and correct for the consequences of it.
1183 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1184 MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1186 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1187 MurphyScreenXPos = MurphyScreenXPos - 2;
1191 // FS: for me this means to blit the first animation frame twice
1193 // --------------------------------------------------------------------------
1194 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1195 PlayField16[*si + 1] = 0x1F03;
1197 goto loc_StopNoSplit;
1199 // ==========================================================================
1200 // RED DISK touching down to up
1201 // ==========================================================================
1204 dx = aniTouchRedDisk;
1205 MovHighByte(&PlayField16[*si], 0x20);
1206 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1207 goto loc_StopNoSplit;
1209 // ==========================================================================
1210 // RED DISK touching right to left
1211 // ==========================================================================
1214 dx = aniTouchRedDisk;
1215 MovHighByte(&PlayField16[*si], 0x21);
1216 MovHighByte(&PlayField16[*si - 1], 3);
1217 goto loc_StopNoSplit;
1219 // ==========================================================================
1220 // RED DISK touching up to down
1221 // ==========================================================================
1224 dx = aniTouchRedDisk;
1225 MovHighByte(&PlayField16[*si], 0x22);
1226 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1227 goto loc_StopNoSplit;
1229 // ==========================================================================
1230 // RED DISK touching left to right
1231 // ==========================================================================
1234 dx = aniTouchRedDisk;
1235 MovHighByte(&PlayField16[*si], 0x23);
1236 MovHighByte(&PlayField16[*si + 1], 3);
1239 MovingPictureSequencePhase = 0; // stop picture move sequence
1242 // ==========================================================================
1243 // YELLOW DISK moving down to up
1244 // ==========================================================================
1247 if (PlayField16[*si - 2 * FieldWidth] != 0)
1248 return subAnimateMurphy;
1250 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1251 subCopyFieldToScreen(*si, aniPushRight);
1253 dxPos = *si - FieldWidth;
1254 dx2 = aniPushUpDown;
1255 dx2Step = FieldWidth;
1256 PlayField16[*si] = 0x2403;
1257 goto loc_MoveNoSplit;
1259 // ==========================================================================
1260 // YELLOW DISK moving right to left
1261 // ==========================================================================
1264 if (PlayField16[*si - 2] != 0)
1265 return subAnimateMurphy;
1267 PlayField16[*si - 2] = 0x1200;
1268 subCopyFieldToScreen(*si, aniPushLeft);
1273 PlayField16[*si] = 0x2503;
1274 goto loc_MoveNoSplit;
1276 // ==========================================================================
1277 // YELLOW DISK moving up to down
1278 // ==========================================================================
1281 if (PlayField16[*si + 2 * FieldWidth] != 0)
1282 return subAnimateMurphy;
1284 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1285 subCopyFieldToScreen(*si, aniPushRight);
1287 dxPos = *si + FieldWidth;
1288 dx2 = aniPushUpDown;
1289 dx2Step = -FieldWidth;
1290 PlayField16[*si] = 0x2703;
1291 goto loc_MoveNoSplit;
1293 // ==========================================================================
1294 // YELLOW DISK moving left to right
1295 // ==========================================================================
1298 if (PlayField16[*si + 2] != 0)
1299 return subAnimateMurphy;
1301 PlayField16[*si + 2] = 0x1200;
1302 subCopyFieldToScreen(*si, aniPushRight);
1307 PlayField16[*si] = 0x2603;
1308 goto loc_MoveNoSplit;
1310 // ==========================================================================
1311 // ORANGE DISK moving right to left
1312 // ==========================================================================
1315 if (PlayField16[*si - 2] != 0)
1316 return subAnimateMurphy;
1318 PlayField16[*si - 2] = 0x800;
1319 subCopyFieldToScreen(*si, aniPushLeft);
1324 PlayField16[*si] = 0x2803;
1325 goto loc_MoveNoSplit;
1327 // ==========================================================================
1328 // ORANGE DISK moving left to right
1329 // ==========================================================================
1332 if (PlayField16[*si + 2] != 0)
1333 return subAnimateMurphy;
1335 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1336 return subAnimateMurphy;
1338 PlayField16[*si + 2] = 0x100;
1339 subCopyFieldToScreen(*si, aniPushRight);
1344 PlayField16[*si] = 0x2903;
1345 // ==========================================================================
1346 // Copy screen animation action table to action work space
1347 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1348 // ==========================================================================
1351 MovingPictureSequencePhase = 8; // init picture move sequence
1354 SplitMoveFlag = 0; // no port: no split movement
1357 // copy/store global move sequence info????????????????????????????????????
1358 // ... dont think so ...(FS)
1359 // ==========================================================================
1360 // Proceed with all movements
1361 // ==========================================================================
1363 locProceedMovingMurphy: // proceed moving murphy
1364 YawnSleepCounter = 0; // Wake up sleeping Murphy
1365 ax = MovingPictureSequencePhase; // sequence busy?
1366 if (ax == 0) // no -- start sequence!
1369 ax = ax - 1; // next picture of sequence
1370 MovingPictureSequencePhase = ax; // store for later
1371 if (ax == 0) // Sound effects
1374 bl = HighByte(PlayField16[*si]);
1375 if (bl == 0xE) // Push Zonk to left
1378 if (bl == 0xF) // Push Zonk to right
1381 if (bl == 0x28) // Push orange disk to left
1384 if (bl == 0x29) // Push orange disk to right
1387 if (bl == 0x24) // Push yellow disk up
1390 if (bl == 0x25) // Push yellow disk to left
1393 if (bl == 0x27) // Push yellow disk down
1396 if (bl == 0x26) // Push yellow disk to right
1399 if (bl == 0x2A) // Red disk release timer
1402 return subAnimateMurphy;
1404 // ==========================================================================
1405 // Paint frame of MOVING.DAT sequence
1406 // ==========================================================================
1409 if (SplitMoveFlag == 0)
1411 // ++++++++++++++++++++++++++
1412 // Begin of normal movement
1414 MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1415 MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1417 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1418 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1420 if (! ClearPos < 0) // clear field that murphy is leaving
1421 subCopyFieldToScreen(ClearPos, 0);
1424 printf("::: ---------------> %d, %d [%d, %d]\n",
1425 MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1428 if (dx2 == fiInfotron) // special case of infotron moving left or right
1435 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1436 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1439 X = GetStretchX(dxPos) + tDeltaX;
1440 Y = GetStretchY(dxPos) + tDeltaY;
1441 Tmp = (SeqPos < 0 ? 0 : 0); // 9StepBugFix!(red disk move right)
1442 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1445 tPos = dxPos + dx2Step;
1446 X = GetStretchX(tPos);
1447 Y = GetStretchY(tPos);
1448 if (dx2 == fiInfotron) // special case of infotron moving left or right
1450 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1452 else // pushing something
1454 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1458 // End of normal movement
1459 // ------------------------
1463 // ++++++++++++++++++++++++++++++++
1464 // Begin of split movement (port)
1466 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1467 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1469 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1470 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1472 subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1473 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1474 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1475 X = GetStretchX(dxPos) + tDeltaX;
1476 Y = GetStretchY(dxPos) + tDeltaY;
1477 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1478 tPos = dxPos + dx2Step;
1479 X = GetStretchX(tPos);
1480 Y = GetStretchY(tPos);
1481 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1482 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1483 // End of split movement (port)
1484 // ------------------------------
1485 } // loc_g_6D1E:'loc_g_6D28:
1487 SeqPos = SeqPos + 1;
1488 if (dx[SeqPos] > -1)
1489 return subAnimateMurphy;
1491 // Follow-up after movement completed 'loc_g_6D35:
1492 MurphyXPos = MurphyXPos + MurphyDX;
1493 MurphyYPos = MurphyYPos + MurphyDY;
1494 bl = HighByte(PlayField16[*si]); // animation phase
1495 MovHighByte(&PlayField16[*si], 0);
1497 if (bl == 0x1) // space, moving up
1500 if (bl == 0x2) // space, moving left
1503 if (bl == 0x3) // space, moving down
1506 if (bl == 0x4) // space, moving right
1509 if (bl == 0x5) // base , moving up
1512 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1515 if (bl == 0x7) // base , moving down
1518 if (bl == 0x8) // base , moving right
1521 if (bl == 0x9) // infotron, moving up
1524 if (bl == 0xA) // infotron, moving left
1527 if (bl == 0xB) // infotron, moving down
1530 if (bl == 0xC) // infotron, moving right
1533 if (bl == 0xD) // exit
1536 if (bl == 0xE) // zonk, pushing left
1539 if (bl == 0xF) // zonk, pushing right
1542 if (bl == 0x10) // base , touching up
1545 if (bl == 0x11) // base , touching left
1548 if (bl == 0x12) // base , touching down
1551 if (bl == 0x13) // base , touching right
1554 if (bl == 0x14) // infotron touching up
1557 if (bl == 0x15) // infotron touching left
1560 if (bl == 0x16) // infotron touching down
1563 if (bl == 0x17) // infotron touching right
1566 if (bl == 0x18) // port up
1569 if (bl == 0x19) // port left
1572 if (bl == 0x1A) // port down
1575 if (bl == 0x1B) // port right
1578 if (bl == 0x1C) // red disk, moving up
1581 if (bl == 0x1D) // red disk, moving left
1584 if (bl == 0x1E) // red disk, moving down
1587 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1590 if (bl == 0x20) // red disk, touching up
1593 if (bl == 0x21) // red disk, touching left
1596 if (bl == 0x22) // red disk, touching down
1599 if (bl == 0x23) // red disk, touching right
1602 if (bl == 0x24) // yellow disk, pushing up
1605 if (bl == 0x25) // yellow disk, pushing left
1608 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1611 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1614 if (bl == 0x28) // orange disk, pushing left
1617 if (bl == 0x29) // orange disk, pushing right
1620 if (bl == 0x2A) // red disk, release
1624 return subAnimateMurphy;
1626 // ==========================================================================
1627 // infotron, moving up
1628 // ==========================================================================
1631 if (0 < LowByte(InfotronsNeeded))
1632 InfotronsNeeded = InfotronsNeeded - 1;
1634 subDisplayInfotronsNeeded();
1635 loc_g_6EC8: // space, base
1636 PlayField16[*si] = fiMurphy;
1637 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1638 return subAnimateMurphy;
1640 // ==========================================================================
1641 // infotron, moving left
1642 // ==========================================================================
1645 if (0 < LowByte(InfotronsNeeded))
1646 InfotronsNeeded = InfotronsNeeded - 1;
1648 subDisplayInfotronsNeeded();
1649 loc_g_6EE6: // space, base
1650 PlayField16[*si] = fiMurphy;
1651 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1652 return subAnimateMurphy;
1654 // ==========================================================================
1655 // infotron, moving down
1656 // ==========================================================================
1659 if (0 < LowByte(InfotronsNeeded))
1660 InfotronsNeeded = InfotronsNeeded - 1;
1662 subDisplayInfotronsNeeded();
1663 loc_g_6F04: // space, base
1664 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1665 PlayField16[*si - FieldWidth] = 0;
1667 PlayField16[*si] = fiMurphy;
1668 return subAnimateMurphy;
1670 // ==========================================================================
1671 // infotron, moving right
1672 // ==========================================================================
1675 if (0 < LowByte(InfotronsNeeded))
1676 InfotronsNeeded = InfotronsNeeded - 1;
1678 subDisplayInfotronsNeeded();
1679 loc_g_71C4: // space, base
1680 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1681 PlayField16[*si] = fiMurphy;
1682 return subAnimateMurphy;
1684 // ==========================================================================
1685 // infotron, touching up
1686 // ==========================================================================
1689 if (0 < LowByte(InfotronsNeeded))
1690 InfotronsNeeded = InfotronsNeeded - 1;
1692 subDisplayInfotronsNeeded();
1694 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1695 PlayField16[*si - FieldWidth] = 0;
1697 return subAnimateMurphy;
1699 // ==========================================================================
1700 // infotron, touching left
1701 // ==========================================================================
1704 if (0 < LowByte(InfotronsNeeded))
1705 InfotronsNeeded = InfotronsNeeded - 1;
1707 subDisplayInfotronsNeeded();
1709 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1710 PlayField16[*si - 1] = 0;
1712 return subAnimateMurphy;
1714 // ==========================================================================
1715 // infotron, touching down
1716 // ==========================================================================
1719 if (0 < LowByte(InfotronsNeeded))
1720 InfotronsNeeded = InfotronsNeeded - 1;
1722 subDisplayInfotronsNeeded();
1724 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1725 PlayField16[*si + FieldWidth] = 0;
1727 return subAnimateMurphy;
1729 // ==========================================================================
1730 // infotron, touching right
1731 // ==========================================================================
1734 if (0 < LowByte(InfotronsNeeded))
1735 InfotronsNeeded = InfotronsNeeded - 1;
1737 subDisplayInfotronsNeeded();
1739 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1740 PlayField16[*si + 1] = 0;
1742 return subAnimateMurphy;
1744 // ==========================================================================
1745 // zonk, pushing left
1746 // ==========================================================================
1749 if (LowByte(PlayField16[*si]) != fiExplosion)
1750 PlayField16[*si] = 0;
1752 PlayField16[*si - 1] = fiMurphy;
1753 PlayField16[*si - 2] = fiZonk;
1754 subExplodeSnikSnaksBelow(*si - 2);
1756 return subAnimateMurphy;
1758 // ==========================================================================
1759 // zonk, pushing right
1760 // ==========================================================================
1763 if (LowByte(PlayField16[*si]) != fiExplosion)
1764 PlayField16[*si] = 0;
1766 PlayField16[*si + 1] = fiMurphy;
1767 PlayField16[*si + 2] = fiZonk;
1768 subExplodeSnikSnaksBelow(*si + 2);
1770 return subAnimateMurphy;
1772 // ==========================================================================
1774 // ==========================================================================
1778 return subAnimateMurphy;
1780 // ==========================================================================
1781 // Push Zonk from right to left
1782 // ==========================================================================
1785 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1786 return subAnimateMurphy;
1788 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1789 PlayField16[*si - 1] = fiZonk;
1790 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1791 PlayField16[*si - 2] = 0;
1793 subCopyFieldToScreen(*si, fiMurphy);
1794 return subAnimateMurphy;
1796 // ==========================================================================
1797 // Push Zonk from left to right
1798 // ==========================================================================
1801 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1802 return subAnimateMurphy;
1804 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1805 PlayField16[*si + 1] = fiZonk;
1806 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1807 PlayField16[*si + 2] = 0;
1809 subCopyFieldToScreen(*si, fiMurphy);
1810 return subAnimateMurphy;
1812 // ==========================================================================
1813 // Push orange disk from right to left
1814 // ==========================================================================
1817 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1818 return subAnimateMurphy;
1820 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1821 PlayField16[*si - 1] = fiOrangeDisk;
1822 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1823 PlayField16[*si - 2] = 0;
1825 subCopyFieldToScreen(*si, fiMurphy);
1826 return subAnimateMurphy;
1828 // ==========================================================================
1829 // Push orange disk from left to right
1830 // ==========================================================================
1833 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1834 return subAnimateMurphy;
1836 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1837 PlayField16[*si + 1] = fiOrangeDisk;
1838 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1839 PlayField16[*si + 2] = 0;
1841 subCopyFieldToScreen(*si, fiMurphy);
1842 return subAnimateMurphy;
1844 // ==========================================================================
1845 // Push yellow disk from down to up
1846 // ==========================================================================
1849 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1850 return subAnimateMurphy;
1852 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1853 PlayField16[*si - FieldWidth] = fiYellowDisk;
1854 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1855 PlayField16[*si - 2 * FieldWidth] = 0;
1857 subCopyFieldToScreen(*si, fiMurphy);
1858 return subAnimateMurphy;
1860 // ==========================================================================
1861 // Push yellow disk from right to left
1862 // ==========================================================================
1865 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1866 return subAnimateMurphy;
1868 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1869 PlayField16[*si - 1] = fiYellowDisk;
1870 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1871 PlayField16[*si - 2] = 0;
1873 subCopyFieldToScreen(*si, fiMurphy);
1874 return subAnimateMurphy;
1876 // ==========================================================================
1877 // Push yellow disk from up to down
1878 // ==========================================================================
1881 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1882 return subAnimateMurphy;
1884 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1885 PlayField16[*si + FieldWidth] = fiYellowDisk;
1886 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1887 PlayField16[*si + 2 * FieldWidth] = 0;
1889 subCopyFieldToScreen(*si, fiMurphy);
1890 return subAnimateMurphy;
1892 // ==========================================================================
1893 // Push yellow disk from left to right
1894 // ==========================================================================
1897 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1898 return subAnimateMurphy;
1900 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1901 PlayField16[*si + 1] = fiYellowDisk;
1902 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1903 PlayField16[*si + 2] = 0;
1905 subCopyFieldToScreen(*si, fiMurphy);
1906 return subAnimateMurphy;
1908 // ==========================================================================
1909 // time red disk release (space)
1910 // ==========================================================================
1913 if (DemoKeyCode != keySpace)
1915 PlayField16[*si] = fiMurphy;
1916 subCopyFieldToScreen(*si, fiMurphy);
1917 RedDiskReleasePhase = 0;
1919 else if (MovingPictureSequencePhase == 0x20)
1921 subCopyFieldToScreen(*si, 43); // anxious murphy
1922 RedDiskReleasePhase = 1;
1925 return subAnimateMurphy;
1927 // ==========================================================================
1928 // Special port down to up
1929 // ==========================================================================
1932 if (LowByte(PlayField16[*si]) != fiExplosion)
1933 PlayField16[*si] = 0;
1935 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1937 *si = *si - FieldWidth;
1938 if (HighByte(PlayField16[*si]) == 1)
1941 *si = *si - FieldWidth;
1942 return subAnimateMurphy;
1944 // ==========================================================================
1945 // Special port right to left
1946 // ==========================================================================
1949 if (LowByte(PlayField16[*si]) != fiExplosion)
1950 PlayField16[*si] = 0;
1952 PlayField16[*si - 2] = fiMurphy;
1955 if (HighByte(PlayField16[*si]) == 1)
1959 return subAnimateMurphy;
1961 // ==========================================================================
1962 // Special port up to down
1963 // ==========================================================================
1966 if (LowByte(PlayField16[*si]) != fiExplosion)
1967 PlayField16[*si] = 0;
1969 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
1971 *si = *si + FieldWidth;
1972 if (HighByte(PlayField16[*si]) == 1)
1975 *si = *si + FieldWidth;
1976 return subAnimateMurphy;
1978 // ==========================================================================
1979 // Special port left to right
1980 // ==========================================================================
1983 if (LowByte(PlayField16[*si]) != fiExplosion)
1984 PlayField16[*si] = 0;
1986 PlayField16[*si + 2] = fiMurphy;
1989 if (HighByte(PlayField16[*si]) == 1)
1993 return subAnimateMurphy;
1995 // ==========================================================================
1997 // ==========================================================================
2000 if (LowByte(PlayField16[*si]) != fiExplosion)
2001 PlayField16[*si] = 0;
2003 *si = *si - FieldWidth;
2004 PlayField16[*si] = fiMurphy;
2005 subEatRedDisk(*si); // inc+show Murphy's red disks
2006 return subAnimateMurphy;
2008 // ==========================================================================
2009 // Move Red Disk left
2010 // ==========================================================================
2013 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2014 PlayField16[*si + 1] = 0;
2016 PlayField16[*si] = fiMurphy;
2017 subEatRedDisk(*si); // inc+show Murphy's red disks
2018 return subAnimateMurphy;
2020 // ==========================================================================
2021 // Move Red Disk down
2022 // ==========================================================================
2025 if (LowByte(PlayField16[*si]) != fiExplosion)
2026 PlayField16[*si] = 0;
2028 *si = *si + FieldWidth;
2029 PlayField16[*si] = fiMurphy;
2030 subEatRedDisk(*si); // inc+show Murphy's red disks
2031 return subAnimateMurphy;
2033 // ==========================================================================
2034 // Move Red Disk right
2035 // ==========================================================================
2038 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2039 PlayField16[*si - 1] = 0;
2041 PlayField16[*si] = fiMurphy;
2042 subEatRedDisk(*si); // inc+show Murphy's red disks
2043 return subAnimateMurphy;
2045 // ==========================================================================
2047 // ==========================================================================
2050 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2051 PlayField16[*si - FieldWidth] = 0;
2053 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2054 return subAnimateMurphy;
2056 // ==========================================================================
2057 // Eat Red Disk left
2058 // ==========================================================================
2061 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2062 PlayField16[*si - 1] = 0;
2064 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2065 return subAnimateMurphy;
2067 // ==========================================================================
2068 // Eat Red Disk down
2069 // ==========================================================================
2072 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2073 PlayField16[*si + FieldWidth] = 0;
2075 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2076 return subAnimateMurphy;
2078 // ==========================================================================
2079 // Eat Red Disk right
2080 // ==========================================================================
2083 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2084 PlayField16[*si + 1] = 0;
2086 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2087 return subAnimateMurphy;
2089 // ==========================================================================
2090 // yellow disk, pushing up
2091 // ==========================================================================
2094 if (LowByte(PlayField16[*si]) != fiExplosion)
2095 PlayField16[*si] = 0;
2097 *si = *si - FieldWidth;
2098 PlayField16[*si] = fiMurphy;
2099 PlayField16[*si - FieldWidth] = fiYellowDisk;
2100 return subAnimateMurphy;
2102 // ==========================================================================
2103 // yellow disk, pushing left
2104 // ==========================================================================
2107 if (LowByte(PlayField16[*si]) != fiExplosion)
2108 PlayField16[*si] = 0;
2111 PlayField16[*si] = fiMurphy;
2112 PlayField16[*si - 1] = fiYellowDisk;
2113 return subAnimateMurphy;
2115 // ==========================================================================
2116 // yellow disk, pushing down
2117 // ==========================================================================
2120 if (LowByte(PlayField16[*si]) != fiExplosion)
2121 PlayField16[*si] = 0;
2123 *si = *si + FieldWidth;
2124 PlayField16[*si] = fiMurphy;
2125 PlayField16[*si + FieldWidth] = fiYellowDisk;
2126 return subAnimateMurphy;
2128 // ==========================================================================
2129 // yellow disk pushing right
2130 // ==========================================================================
2133 if (LowByte(PlayField16[*si]) != fiExplosion)
2134 PlayField16[*si] = 0;
2137 PlayField16[*si] = fiMurphy;
2138 PlayField16[*si + 1] = fiYellowDisk;
2139 return subAnimateMurphy;
2141 // ==========================================================================
2142 // orange disk, pushing left
2143 // ==========================================================================
2146 if (LowByte(PlayField16[*si]) != fiExplosion)
2147 PlayField16[*si] = 0;
2150 PlayField16[*si] = fiMurphy;
2151 PlayField16[*si - 1] = fiOrangeDisk;
2152 return subAnimateMurphy;
2154 // ==========================================================================
2155 // orange disk, pushing right
2156 // ==========================================================================
2159 if (LowByte(PlayField16[*si]) != fiExplosion)
2160 PlayField16[*si] = 0;
2163 PlayField16[*si] = fiMurphy;
2164 PlayField16[*si + 1] = fiOrangeDisk;
2165 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2167 MovHighByte(&PlayField16[*si + 1], 0x20);
2168 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2171 return subAnimateMurphy;
2173 // ==========================================================================
2174 // Release a red disk
2175 // ==========================================================================
2178 PlayField16[*si] = fiMurphy;
2179 RedDiskReleasePhase = 2;
2180 RedDiskCount = RedDiskCount - 1;
2181 subDisplayRedDiskCount();
2182 subSoundFXPush(); // Sound effects
2184 return subAnimateMurphy;
2185 } // subAnimateMurphy
2187 // ==========================================================================
2189 // ==========================================================================
2190 int subExplodeSnikSnaksBelow(int si)
2192 int subExplodeSnikSnaksBelow;
2196 ax = LowByte(PlayField16[si + FieldWidth]);
2197 if (ax == 0x11 || ax == 0xBB)
2198 ExplodeFieldSP(si + FieldWidth);
2200 return subExplodeSnikSnaksBelow;
2201 } // subExplodeSnikSnaksBelow
2203 // ==========================================================================
2205 // Does pushing against an object kill Murphy?
2206 // ==========================================================================
2207 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2209 static boolean subMoveKillsMurphy;
2215 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2221 if (al == fiExplosion)
2224 if (fiOrangeDisk <= al && al <= fiPortUp)
2227 ExplodeFieldSP(si); // Explode
2228 subMoveKillsMurphy = True;
2229 return subMoveKillsMurphy;
2238 ExplodeFieldSP(si); // Explode
2239 subMoveKillsMurphy = True;
2240 return subMoveKillsMurphy;
2242 loc_g_74F6: // zonk left
2244 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2247 subMoveKillsMurphy = True; // Set carry flag
2248 return subMoveKillsMurphy;
2250 loc_g_7512: // zonk right
2252 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2255 loc_g_752E: // Marked fields and Ports
2256 subMoveKillsMurphy = True; // Set carry flag
2257 return subMoveKillsMurphy;
2259 loc_g_7530: // explosion
2260 if ((ah & 0x80) != 0)
2267 ExplodeFieldSP(si); // Explode
2268 subMoveKillsMurphy = True; // Set carry flag
2269 return subMoveKillsMurphy;
2272 PlayField16[si] = 0;
2273 subMoveKillsMurphy = False;
2275 return subMoveKillsMurphy;
2276 } // subMoveKillsMurphy
2278 // ==========================================================================
2280 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2281 // change conditions to port specs
2282 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2283 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2284 // ==========================================================================
2285 int subSpPortTest(int si)
2291 cx = LInfo.SpecialPortCount; // number of special ports
2292 for (i = 1; i <= cx; i++)
2295 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2296 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2299 GravityFlag = LInfo.SpecialPort[i].Gravity;
2300 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2301 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2302 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2309 return subSpPortTest;
2312 void subCopyFieldToScreen(int si, int fi)
2316 // +++++++++++++++++++++++++++++++++++++++++
2317 X = GetStretchX(si);
2318 Y = GetStretchY(si);
2319 StretchedSprites.BltEx(X, Y, fi);
2320 // +++++++++++++++++++++++++++++++++++++++++
2323 static void subEatRedDisk(int si)
2325 if (AllowRedDiskCheat == 0)
2327 if (RedDiskReleasePhase != 0)
2329 if (RedDiskReleaseMurphyPos == si)
2334 RedDiskCount = (RedDiskCount + 1) % 256;
2335 subDisplayRedDiskCount();
2338 int subAdjustZonksInfotronsAboveMurphy(int si)
2340 int subAdjustZonksInfotronsAboveMurphy;
2344 if (LowByte(PlayField16[si]) != fiExplosion)
2345 PlayField16[si] = 0;
2347 ax = PlayField16[si - FieldWidth];
2348 if (ax == 0 || ax == 0x9999)
2351 if (ax == fiZonk || ax == fiInfotron)
2353 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2356 return subAdjustZonksInfotronsAboveMurphy;
2358 loc_g_15A8: // empty above
2359 ax = PlayField16[si - FieldWidth - 1];
2360 if (ax == fiZonk || ax == fiInfotron)
2364 ax = PlayField16[si - FieldWidth + 1];
2365 if (ax == fiZonk || ax == fiInfotron)
2368 return subAdjustZonksInfotronsAboveMurphy;
2370 loc_g_15C5: // zonk/infotron above left
2371 ax = PlayField16[si - 1];
2372 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2375 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2376 PlayField16[si - FieldWidth] = 0x8888;
2377 return subAdjustZonksInfotronsAboveMurphy;
2379 loc_g_15E8: // zonk/infotron above right
2380 ax = PlayField16[si + 1];
2381 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2383 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2384 PlayField16[si - FieldWidth] = 0x8888;
2387 return subAdjustZonksInfotronsAboveMurphy;
2388 } // subAdjustZonksInfotronsAboveMurphy