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("::: Murphy.c: !!! %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 printf("::: Murphy.c: !!!!!!!!!! GAME SOLVED !!!!!!!!!!\n");
939 data_h_DemoDone = 1; // EP set level success bytes
940 LevelStatus = 1; // set Level Status DONE
941 EP_GameDemoVar0DAA = 0; // force demo for lead-out
942 if (SavedGameFlag == 0) // saved game running?
944 if (UpdateTimeFlag != 0) // update time?
946 UpdatedFlag = 1; // prevent double update
947 subUpdatePlayingTime(); // update playing time
952 subUpdateHallOfFame(); // update time + Hall-Of-Fame
955 LeadOutCounter = 0x40; // quit: start lead-out
957 MovHighByte(&PlayField16[*si], 0xD);
958 goto loc_StopNoSplit;
960 // ==========================================================================
961 // ZONK moving right to left
962 // ==========================================================================
965 ax = PlayField16[*si - 2];
967 return subAnimateMurphy;
969 MovHighByte(&PlayField16[*si - 2], 1);
970 subCopyFieldToScreen(*si, aniPushLeft); // draw pushing murphy
971 dx = aniZonkRollLeft;
975 MovHighByte(&PlayField16[*si], 0xE);
976 goto loc_MoveNoSplit;
978 // ==========================================================================
979 // ZONK moving left to right
980 // ==========================================================================
983 ax = PlayField16[*si + 2];
985 return subAnimateMurphy;
987 ax = PlayField16[*si + FieldWidth + 1];
988 if (ax == 0) // zonk falls
989 return subAnimateMurphy;
991 MovHighByte(&PlayField16[*si + 2], 1);
992 subCopyFieldToScreen(*si, aniPushRight); // draw pushing murphy
993 dx = aniZonkRollRight;
997 MovHighByte(&PlayField16[*si], 0xF);
998 goto loc_MoveNoSplit;
1000 // ==========================================================================
1001 // TERMINAL moving/touching down to up
1002 // ==========================================================================
1005 subCopyFieldToScreen(*si, aniMurphyTouchUp);
1006 if (YellowDisksExploded != 0)
1008 YawnSleepCounter = 10; // stay hypnotized
1009 return subAnimateMurphy;
1012 subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1013 TerminalState[*si - FieldWidth] = 8;
1016 // ==========================================================================
1017 // TERMINAL moving/touching right to left
1018 // ==========================================================================
1021 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
1022 if (YellowDisksExploded != 0)
1024 YawnSleepCounter = 10; // stay hypnotized
1025 return subAnimateMurphy;
1028 subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1029 TerminalState[*si - 1] = 8;
1032 // ==========================================================================
1033 // TERMINAL moving/touching up to down
1034 // ==========================================================================
1037 subCopyFieldToScreen(*si, aniMurphyTouchDown);
1038 if (YellowDisksExploded != 0)
1040 YawnSleepCounter = 10; // stay hypnotized
1041 return subAnimateMurphy;
1044 subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1045 TerminalState[*si + FieldWidth] = 8;
1048 // ==========================================================================
1049 // TERMINAL moving/touching left to right
1050 // ==========================================================================
1053 subCopyFieldToScreen(*si, aniMurphyTouchRight);
1054 if (YellowDisksExploded != 0)
1056 YawnSleepCounter = 10; // stay hypnotized
1057 return subAnimateMurphy;
1060 subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1061 TerminalState[*si + 1] = 8;
1062 // ==========================================================================
1063 // common TERMINAL stuff moving/touching from all directions
1064 // ==========================================================================
1067 TerminalMaxCycles = 7;
1068 YellowDisksExploded = 1;
1069 for (i = 0; i <= LevelMax; i++)
1071 if (PlayField16[i] == fiYellowDisk)
1075 return subAnimateMurphy;
1077 // ==========================================================================
1078 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1079 // ==========================================================================
1082 if (PlayField16[*si - 2 * FieldWidth] != 0)
1083 return subAnimateMurphy;
1085 dx = aniSplitUpDown;
1086 dx2Step = -FieldWidth;
1087 PlayField16[*si] = 0x1803;
1088 PlayField16[*si - 2 * FieldWidth] = 0x300;
1091 // ==========================================================================
1092 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1093 // ==========================================================================
1096 if (PlayField16[*si - 2] != 0)
1097 return subAnimateMurphy;
1099 dx = aniMurphyEatLeft;
1101 PlayField16[*si] = 0x1903;
1102 PlayField16[*si - 2] = 0x300;
1105 // ==========================================================================
1106 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1107 // ==========================================================================
1110 if (PlayField16[*si + 2 * FieldWidth] != 0)
1111 return subAnimateMurphy;
1113 dx = aniSplitUpDown;
1114 dx2Step = FieldWidth;
1115 PlayField16[*si] = 0x1A03;
1116 PlayField16[*si + 2 * FieldWidth] = 0x300;
1119 // ==========================================================================
1120 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1121 // ==========================================================================
1124 if (PlayField16[*si + 2] != 0)
1125 return subAnimateMurphy;
1127 dx = aniMurphyEatRight;
1129 PlayField16[*si] = 0x1B03;
1130 PlayField16[*si + 2] = 0x300;
1133 MovingPictureSequencePhase = 0; // stop picture move sequence
1134 SplitMoveFlag = 1; // port: split movement
1137 // ==========================================================================
1138 // RED DISK moving down to up
1139 // ==========================================================================
1142 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1143 PlayField16[*si] = 0x1C03;
1144 PlayField16[*si - FieldWidth] = 0x300;
1145 goto loc_StopNoSplit;
1147 // ==========================================================================
1148 // RED DISK moving right to left
1149 // ==========================================================================
1152 dx = aniMurphyEatLeft;
1153 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1154 PlayField16[*si - 1] = 0x1D03;
1156 goto loc_StopNoSplit;
1158 // ==========================================================================
1159 // RED DISK moving up to down
1160 // ==========================================================================
1163 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1164 PlayField16[*si] = 0x1E03;
1165 PlayField16[*si + FieldWidth] = 0x300;
1166 goto loc_StopNoSplit;
1168 // ==========================================================================
1169 // RED DISK moving left to right
1170 // ==========================================================================
1173 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1174 dx = aniMurphyEatRight;
1175 // --------------------------------------------------------------------------
1177 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1178 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1179 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1180 // We may not fix the table, because then the timing of the game changes
1181 // and several existing demo's do not run properly anymore.
1182 // We only correct Murphies x-location here, when the sequence starts.
1183 // Remember that this is not the real bug-fix, but we must live with
1184 // this existing bug and correct for the consequences of it.
1187 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1188 MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1190 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1191 MurphyScreenXPos = MurphyScreenXPos - 2;
1195 // FS: for me this means to blit the first animation frame twice
1197 // --------------------------------------------------------------------------
1198 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1199 PlayField16[*si + 1] = 0x1F03;
1201 goto loc_StopNoSplit;
1203 // ==========================================================================
1204 // RED DISK touching down to up
1205 // ==========================================================================
1208 dx = aniTouchRedDisk;
1209 MovHighByte(&PlayField16[*si], 0x20);
1210 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1211 goto loc_StopNoSplit;
1213 // ==========================================================================
1214 // RED DISK touching right to left
1215 // ==========================================================================
1218 dx = aniTouchRedDisk;
1219 MovHighByte(&PlayField16[*si], 0x21);
1220 MovHighByte(&PlayField16[*si - 1], 3);
1221 goto loc_StopNoSplit;
1223 // ==========================================================================
1224 // RED DISK touching up to down
1225 // ==========================================================================
1228 dx = aniTouchRedDisk;
1229 MovHighByte(&PlayField16[*si], 0x22);
1230 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1231 goto loc_StopNoSplit;
1233 // ==========================================================================
1234 // RED DISK touching left to right
1235 // ==========================================================================
1238 dx = aniTouchRedDisk;
1239 MovHighByte(&PlayField16[*si], 0x23);
1240 MovHighByte(&PlayField16[*si + 1], 3);
1243 MovingPictureSequencePhase = 0; // stop picture move sequence
1246 // ==========================================================================
1247 // YELLOW DISK moving down to up
1248 // ==========================================================================
1251 if (PlayField16[*si - 2 * FieldWidth] != 0)
1252 return subAnimateMurphy;
1254 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1255 subCopyFieldToScreen(*si, aniPushRight);
1257 dxPos = *si - FieldWidth;
1258 dx2 = aniPushUpDown;
1259 dx2Step = FieldWidth;
1260 PlayField16[*si] = 0x2403;
1261 goto loc_MoveNoSplit;
1263 // ==========================================================================
1264 // YELLOW DISK moving right to left
1265 // ==========================================================================
1268 if (PlayField16[*si - 2] != 0)
1269 return subAnimateMurphy;
1271 PlayField16[*si - 2] = 0x1200;
1272 subCopyFieldToScreen(*si, aniPushLeft);
1277 PlayField16[*si] = 0x2503;
1278 goto loc_MoveNoSplit;
1280 // ==========================================================================
1281 // YELLOW DISK moving up to down
1282 // ==========================================================================
1285 if (PlayField16[*si + 2 * FieldWidth] != 0)
1286 return subAnimateMurphy;
1288 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1289 subCopyFieldToScreen(*si, aniPushRight);
1291 dxPos = *si + FieldWidth;
1292 dx2 = aniPushUpDown;
1293 dx2Step = -FieldWidth;
1294 PlayField16[*si] = 0x2703;
1295 goto loc_MoveNoSplit;
1297 // ==========================================================================
1298 // YELLOW DISK moving left to right
1299 // ==========================================================================
1302 if (PlayField16[*si + 2] != 0)
1303 return subAnimateMurphy;
1305 PlayField16[*si + 2] = 0x1200;
1306 subCopyFieldToScreen(*si, aniPushRight);
1311 PlayField16[*si] = 0x2603;
1312 goto loc_MoveNoSplit;
1314 // ==========================================================================
1315 // ORANGE DISK moving right to left
1316 // ==========================================================================
1319 if (PlayField16[*si - 2] != 0)
1320 return subAnimateMurphy;
1322 PlayField16[*si - 2] = 0x800;
1323 subCopyFieldToScreen(*si, aniPushLeft);
1328 PlayField16[*si] = 0x2803;
1329 goto loc_MoveNoSplit;
1331 // ==========================================================================
1332 // ORANGE DISK moving left to right
1333 // ==========================================================================
1336 if (PlayField16[*si + 2] != 0)
1337 return subAnimateMurphy;
1339 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1340 return subAnimateMurphy;
1342 PlayField16[*si + 2] = 0x100;
1343 subCopyFieldToScreen(*si, aniPushRight);
1348 PlayField16[*si] = 0x2903;
1349 // ==========================================================================
1350 // Copy screen animation action table to action work space
1351 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1352 // ==========================================================================
1355 MovingPictureSequencePhase = 8; // init picture move sequence
1358 SplitMoveFlag = 0; // no port: no split movement
1361 // copy/store global move sequence info????????????????????????????????????
1362 // ... dont think so ...(FS)
1363 // ==========================================================================
1364 // Proceed with all movements
1365 // ==========================================================================
1367 locProceedMovingMurphy: // proceed moving murphy
1368 YawnSleepCounter = 0; // Wake up sleeping Murphy
1369 ax = MovingPictureSequencePhase; // sequence busy?
1370 if (ax == 0) // no -- start sequence!
1373 ax = ax - 1; // next picture of sequence
1374 MovingPictureSequencePhase = ax; // store for later
1375 if (ax == 0) // Sound effects
1378 bl = HighByte(PlayField16[*si]);
1379 if (bl == 0xE) // Push Zonk to left
1382 if (bl == 0xF) // Push Zonk to right
1385 if (bl == 0x28) // Push orange disk to left
1388 if (bl == 0x29) // Push orange disk to right
1391 if (bl == 0x24) // Push yellow disk up
1394 if (bl == 0x25) // Push yellow disk to left
1397 if (bl == 0x27) // Push yellow disk down
1400 if (bl == 0x26) // Push yellow disk to right
1403 if (bl == 0x2A) // Red disk release timer
1406 return subAnimateMurphy;
1408 // ==========================================================================
1409 // Paint frame of MOVING.DAT sequence
1410 // ==========================================================================
1413 if (SplitMoveFlag == 0)
1415 // ++++++++++++++++++++++++++
1416 // Begin of normal movement
1418 MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1419 MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1421 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1422 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1426 if (!(ClearPos < 0)) // clear field that murphy is leaving
1427 subCopyFieldToScreen(ClearPos, 0);
1429 if (! ClearPos < 0) // clear field that murphy is leaving
1430 subCopyFieldToScreen(ClearPos, 0);
1434 printf("::: ---------------> %d, %d [%d, %d]\n",
1435 MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1438 if (dx2 == fiInfotron) // special case of infotron moving left or right
1445 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1446 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1449 X = GetStretchX(dxPos) + tDeltaX;
1450 Y = GetStretchY(dxPos) + tDeltaY;
1451 Tmp = (SeqPos < 0 ? 0 : 0); // 9StepBugFix!(red disk move right)
1452 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1460 tPos = dxPos + dx2Step;
1461 X = GetStretchX(tPos);
1462 Y = GetStretchY(tPos);
1463 if (dx2 == fiInfotron) // special case of infotron moving left or right
1465 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1467 else // pushing something
1469 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1473 // End of normal movement
1474 // ------------------------
1478 // ++++++++++++++++++++++++++++++++
1479 // Begin of split movement (port)
1481 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1482 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1484 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1485 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1487 subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1488 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1489 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1490 X = GetStretchX(dxPos) + tDeltaX;
1491 Y = GetStretchY(dxPos) + tDeltaY;
1492 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1493 tPos = dxPos + dx2Step;
1494 X = GetStretchX(tPos);
1495 Y = GetStretchY(tPos);
1496 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1497 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1498 // End of split movement (port)
1499 // ------------------------------
1500 } // loc_g_6D1E:'loc_g_6D28:
1502 SeqPos = SeqPos + 1;
1503 if (dx[SeqPos] > -1)
1504 return subAnimateMurphy;
1506 // Follow-up after movement completed 'loc_g_6D35:
1507 MurphyXPos = MurphyXPos + MurphyDX;
1508 MurphyYPos = MurphyYPos + MurphyDY;
1509 bl = HighByte(PlayField16[*si]); // animation phase
1510 MovHighByte(&PlayField16[*si], 0);
1512 if (bl == 0x1) // space, moving up
1515 if (bl == 0x2) // space, moving left
1518 if (bl == 0x3) // space, moving down
1521 if (bl == 0x4) // space, moving right
1524 if (bl == 0x5) // base , moving up
1527 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1530 if (bl == 0x7) // base , moving down
1533 if (bl == 0x8) // base , moving right
1536 if (bl == 0x9) // infotron, moving up
1539 if (bl == 0xA) // infotron, moving left
1542 if (bl == 0xB) // infotron, moving down
1545 if (bl == 0xC) // infotron, moving right
1548 if (bl == 0xD) // exit
1551 if (bl == 0xE) // zonk, pushing left
1554 if (bl == 0xF) // zonk, pushing right
1557 if (bl == 0x10) // base , touching up
1560 if (bl == 0x11) // base , touching left
1563 if (bl == 0x12) // base , touching down
1566 if (bl == 0x13) // base , touching right
1569 if (bl == 0x14) // infotron touching up
1572 if (bl == 0x15) // infotron touching left
1575 if (bl == 0x16) // infotron touching down
1578 if (bl == 0x17) // infotron touching right
1581 if (bl == 0x18) // port up
1584 if (bl == 0x19) // port left
1587 if (bl == 0x1A) // port down
1590 if (bl == 0x1B) // port right
1593 if (bl == 0x1C) // red disk, moving up
1596 if (bl == 0x1D) // red disk, moving left
1599 if (bl == 0x1E) // red disk, moving down
1602 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1605 if (bl == 0x20) // red disk, touching up
1608 if (bl == 0x21) // red disk, touching left
1611 if (bl == 0x22) // red disk, touching down
1614 if (bl == 0x23) // red disk, touching right
1617 if (bl == 0x24) // yellow disk, pushing up
1620 if (bl == 0x25) // yellow disk, pushing left
1623 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1626 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1629 if (bl == 0x28) // orange disk, pushing left
1632 if (bl == 0x29) // orange disk, pushing right
1635 if (bl == 0x2A) // red disk, release
1639 return subAnimateMurphy;
1641 // ==========================================================================
1642 // infotron, moving up
1643 // ==========================================================================
1646 if (0 < LowByte(InfotronsNeeded))
1647 InfotronsNeeded = InfotronsNeeded - 1;
1649 subDisplayInfotronsNeeded();
1650 loc_g_6EC8: // space, base
1651 PlayField16[*si] = fiMurphy;
1652 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1653 return subAnimateMurphy;
1655 // ==========================================================================
1656 // infotron, moving left
1657 // ==========================================================================
1660 if (0 < LowByte(InfotronsNeeded))
1661 InfotronsNeeded = InfotronsNeeded - 1;
1663 subDisplayInfotronsNeeded();
1664 loc_g_6EE6: // space, base
1665 PlayField16[*si] = fiMurphy;
1666 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1667 return subAnimateMurphy;
1669 // ==========================================================================
1670 // infotron, moving down
1671 // ==========================================================================
1674 if (0 < LowByte(InfotronsNeeded))
1675 InfotronsNeeded = InfotronsNeeded - 1;
1677 subDisplayInfotronsNeeded();
1678 loc_g_6F04: // space, base
1679 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1680 PlayField16[*si - FieldWidth] = 0;
1682 PlayField16[*si] = fiMurphy;
1683 return subAnimateMurphy;
1685 // ==========================================================================
1686 // infotron, moving right
1687 // ==========================================================================
1690 if (0 < LowByte(InfotronsNeeded))
1691 InfotronsNeeded = InfotronsNeeded - 1;
1693 subDisplayInfotronsNeeded();
1694 loc_g_71C4: // space, base
1695 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1696 PlayField16[*si] = fiMurphy;
1697 return subAnimateMurphy;
1699 // ==========================================================================
1700 // infotron, touching up
1701 // ==========================================================================
1704 if (0 < LowByte(InfotronsNeeded))
1705 InfotronsNeeded = InfotronsNeeded - 1;
1707 subDisplayInfotronsNeeded();
1709 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1710 PlayField16[*si - FieldWidth] = 0;
1712 return subAnimateMurphy;
1714 // ==========================================================================
1715 // infotron, touching left
1716 // ==========================================================================
1719 if (0 < LowByte(InfotronsNeeded))
1720 InfotronsNeeded = InfotronsNeeded - 1;
1722 subDisplayInfotronsNeeded();
1724 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1725 PlayField16[*si - 1] = 0;
1727 return subAnimateMurphy;
1729 // ==========================================================================
1730 // infotron, touching down
1731 // ==========================================================================
1734 if (0 < LowByte(InfotronsNeeded))
1735 InfotronsNeeded = InfotronsNeeded - 1;
1737 subDisplayInfotronsNeeded();
1739 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1740 PlayField16[*si + FieldWidth] = 0;
1742 return subAnimateMurphy;
1744 // ==========================================================================
1745 // infotron, touching right
1746 // ==========================================================================
1749 if (0 < LowByte(InfotronsNeeded))
1750 InfotronsNeeded = InfotronsNeeded - 1;
1752 subDisplayInfotronsNeeded();
1754 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1755 PlayField16[*si + 1] = 0;
1757 return subAnimateMurphy;
1759 // ==========================================================================
1760 // zonk, pushing left
1761 // ==========================================================================
1764 if (LowByte(PlayField16[*si]) != fiExplosion)
1765 PlayField16[*si] = 0;
1767 PlayField16[*si - 1] = fiMurphy;
1768 PlayField16[*si - 2] = fiZonk;
1769 subExplodeSnikSnaksBelow(*si - 2);
1771 return subAnimateMurphy;
1773 // ==========================================================================
1774 // zonk, pushing right
1775 // ==========================================================================
1778 if (LowByte(PlayField16[*si]) != fiExplosion)
1779 PlayField16[*si] = 0;
1781 PlayField16[*si + 1] = fiMurphy;
1782 PlayField16[*si + 2] = fiZonk;
1783 subExplodeSnikSnaksBelow(*si + 2);
1785 return subAnimateMurphy;
1787 // ==========================================================================
1789 // ==========================================================================
1793 return subAnimateMurphy;
1795 // ==========================================================================
1796 // Push Zonk from right to left
1797 // ==========================================================================
1800 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1801 return subAnimateMurphy;
1803 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1804 PlayField16[*si - 1] = fiZonk;
1805 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1806 PlayField16[*si - 2] = 0;
1808 subCopyFieldToScreen(*si, fiMurphy);
1809 return subAnimateMurphy;
1811 // ==========================================================================
1812 // Push Zonk from left to right
1813 // ==========================================================================
1816 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1817 return subAnimateMurphy;
1819 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1820 PlayField16[*si + 1] = fiZonk;
1821 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1822 PlayField16[*si + 2] = 0;
1824 subCopyFieldToScreen(*si, fiMurphy);
1825 return subAnimateMurphy;
1827 // ==========================================================================
1828 // Push orange disk from right to left
1829 // ==========================================================================
1832 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1833 return subAnimateMurphy;
1835 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1836 PlayField16[*si - 1] = fiOrangeDisk;
1837 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1838 PlayField16[*si - 2] = 0;
1840 subCopyFieldToScreen(*si, fiMurphy);
1841 return subAnimateMurphy;
1843 // ==========================================================================
1844 // Push orange disk from left to right
1845 // ==========================================================================
1848 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1849 return subAnimateMurphy;
1851 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1852 PlayField16[*si + 1] = fiOrangeDisk;
1853 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1854 PlayField16[*si + 2] = 0;
1856 subCopyFieldToScreen(*si, fiMurphy);
1857 return subAnimateMurphy;
1859 // ==========================================================================
1860 // Push yellow disk from down to up
1861 // ==========================================================================
1864 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1865 return subAnimateMurphy;
1867 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1868 PlayField16[*si - FieldWidth] = fiYellowDisk;
1869 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1870 PlayField16[*si - 2 * FieldWidth] = 0;
1872 subCopyFieldToScreen(*si, fiMurphy);
1873 return subAnimateMurphy;
1875 // ==========================================================================
1876 // Push yellow disk from right to left
1877 // ==========================================================================
1880 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1881 return subAnimateMurphy;
1883 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1884 PlayField16[*si - 1] = fiYellowDisk;
1885 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1886 PlayField16[*si - 2] = 0;
1888 subCopyFieldToScreen(*si, fiMurphy);
1889 return subAnimateMurphy;
1891 // ==========================================================================
1892 // Push yellow disk from up to down
1893 // ==========================================================================
1896 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1897 return subAnimateMurphy;
1899 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1900 PlayField16[*si + FieldWidth] = fiYellowDisk;
1901 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1902 PlayField16[*si + 2 * FieldWidth] = 0;
1904 subCopyFieldToScreen(*si, fiMurphy);
1905 return subAnimateMurphy;
1907 // ==========================================================================
1908 // Push yellow disk from left to right
1909 // ==========================================================================
1912 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1913 return subAnimateMurphy;
1915 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1916 PlayField16[*si + 1] = fiYellowDisk;
1917 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1918 PlayField16[*si + 2] = 0;
1920 subCopyFieldToScreen(*si, fiMurphy);
1921 return subAnimateMurphy;
1923 // ==========================================================================
1924 // time red disk release (space)
1925 // ==========================================================================
1928 if (DemoKeyCode != keySpace)
1930 PlayField16[*si] = fiMurphy;
1931 subCopyFieldToScreen(*si, fiMurphy);
1932 RedDiskReleasePhase = 0;
1934 else if (MovingPictureSequencePhase == 0x20)
1936 subCopyFieldToScreen(*si, 43); // anxious murphy
1937 RedDiskReleasePhase = 1;
1940 return subAnimateMurphy;
1942 // ==========================================================================
1943 // Special port down to up
1944 // ==========================================================================
1947 if (LowByte(PlayField16[*si]) != fiExplosion)
1948 PlayField16[*si] = 0;
1950 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1952 *si = *si - FieldWidth;
1953 if (HighByte(PlayField16[*si]) == 1)
1956 *si = *si - FieldWidth;
1957 return subAnimateMurphy;
1959 // ==========================================================================
1960 // Special port right to left
1961 // ==========================================================================
1964 if (LowByte(PlayField16[*si]) != fiExplosion)
1965 PlayField16[*si] = 0;
1967 PlayField16[*si - 2] = fiMurphy;
1970 if (HighByte(PlayField16[*si]) == 1)
1974 return subAnimateMurphy;
1976 // ==========================================================================
1977 // Special port up to down
1978 // ==========================================================================
1981 if (LowByte(PlayField16[*si]) != fiExplosion)
1982 PlayField16[*si] = 0;
1984 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
1986 *si = *si + FieldWidth;
1987 if (HighByte(PlayField16[*si]) == 1)
1990 *si = *si + FieldWidth;
1991 return subAnimateMurphy;
1993 // ==========================================================================
1994 // Special port left to right
1995 // ==========================================================================
1998 if (LowByte(PlayField16[*si]) != fiExplosion)
1999 PlayField16[*si] = 0;
2001 PlayField16[*si + 2] = fiMurphy;
2004 if (HighByte(PlayField16[*si]) == 1)
2008 return subAnimateMurphy;
2010 // ==========================================================================
2012 // ==========================================================================
2015 if (LowByte(PlayField16[*si]) != fiExplosion)
2016 PlayField16[*si] = 0;
2018 *si = *si - FieldWidth;
2019 PlayField16[*si] = fiMurphy;
2020 subEatRedDisk(*si); // inc+show Murphy's red disks
2021 return subAnimateMurphy;
2023 // ==========================================================================
2024 // Move Red Disk left
2025 // ==========================================================================
2028 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2029 PlayField16[*si + 1] = 0;
2031 PlayField16[*si] = fiMurphy;
2032 subEatRedDisk(*si); // inc+show Murphy's red disks
2033 return subAnimateMurphy;
2035 // ==========================================================================
2036 // Move Red Disk down
2037 // ==========================================================================
2040 if (LowByte(PlayField16[*si]) != fiExplosion)
2041 PlayField16[*si] = 0;
2043 *si = *si + FieldWidth;
2044 PlayField16[*si] = fiMurphy;
2045 subEatRedDisk(*si); // inc+show Murphy's red disks
2046 return subAnimateMurphy;
2048 // ==========================================================================
2049 // Move Red Disk right
2050 // ==========================================================================
2053 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2054 PlayField16[*si - 1] = 0;
2056 PlayField16[*si] = fiMurphy;
2057 subEatRedDisk(*si); // inc+show Murphy's red disks
2058 return subAnimateMurphy;
2060 // ==========================================================================
2062 // ==========================================================================
2065 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2066 PlayField16[*si - FieldWidth] = 0;
2068 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2069 return subAnimateMurphy;
2071 // ==========================================================================
2072 // Eat Red Disk left
2073 // ==========================================================================
2076 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2077 PlayField16[*si - 1] = 0;
2079 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2080 return subAnimateMurphy;
2082 // ==========================================================================
2083 // Eat Red Disk down
2084 // ==========================================================================
2087 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2088 PlayField16[*si + FieldWidth] = 0;
2090 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2091 return subAnimateMurphy;
2093 // ==========================================================================
2094 // Eat Red Disk right
2095 // ==========================================================================
2098 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2099 PlayField16[*si + 1] = 0;
2101 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2102 return subAnimateMurphy;
2104 // ==========================================================================
2105 // yellow disk, pushing up
2106 // ==========================================================================
2109 if (LowByte(PlayField16[*si]) != fiExplosion)
2110 PlayField16[*si] = 0;
2112 *si = *si - FieldWidth;
2113 PlayField16[*si] = fiMurphy;
2114 PlayField16[*si - FieldWidth] = fiYellowDisk;
2115 return subAnimateMurphy;
2117 // ==========================================================================
2118 // yellow disk, pushing left
2119 // ==========================================================================
2122 if (LowByte(PlayField16[*si]) != fiExplosion)
2123 PlayField16[*si] = 0;
2126 PlayField16[*si] = fiMurphy;
2127 PlayField16[*si - 1] = fiYellowDisk;
2128 return subAnimateMurphy;
2130 // ==========================================================================
2131 // yellow disk, pushing down
2132 // ==========================================================================
2135 if (LowByte(PlayField16[*si]) != fiExplosion)
2136 PlayField16[*si] = 0;
2138 *si = *si + FieldWidth;
2139 PlayField16[*si] = fiMurphy;
2140 PlayField16[*si + FieldWidth] = fiYellowDisk;
2141 return subAnimateMurphy;
2143 // ==========================================================================
2144 // yellow disk pushing right
2145 // ==========================================================================
2148 if (LowByte(PlayField16[*si]) != fiExplosion)
2149 PlayField16[*si] = 0;
2152 PlayField16[*si] = fiMurphy;
2153 PlayField16[*si + 1] = fiYellowDisk;
2154 return subAnimateMurphy;
2156 // ==========================================================================
2157 // orange disk, pushing left
2158 // ==========================================================================
2161 if (LowByte(PlayField16[*si]) != fiExplosion)
2162 PlayField16[*si] = 0;
2165 PlayField16[*si] = fiMurphy;
2166 PlayField16[*si - 1] = fiOrangeDisk;
2167 return subAnimateMurphy;
2169 // ==========================================================================
2170 // orange disk, pushing right
2171 // ==========================================================================
2174 if (LowByte(PlayField16[*si]) != fiExplosion)
2175 PlayField16[*si] = 0;
2178 PlayField16[*si] = fiMurphy;
2179 PlayField16[*si + 1] = fiOrangeDisk;
2180 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2182 MovHighByte(&PlayField16[*si + 1], 0x20);
2183 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2186 return subAnimateMurphy;
2188 // ==========================================================================
2189 // Release a red disk
2190 // ==========================================================================
2193 PlayField16[*si] = fiMurphy;
2194 RedDiskReleasePhase = 2;
2195 RedDiskCount = RedDiskCount - 1;
2196 subDisplayRedDiskCount();
2197 subSoundFXPush(); // Sound effects
2199 return subAnimateMurphy;
2200 } // subAnimateMurphy
2202 // ==========================================================================
2204 // ==========================================================================
2205 int subExplodeSnikSnaksBelow(int si)
2207 int subExplodeSnikSnaksBelow;
2211 ax = LowByte(PlayField16[si + FieldWidth]);
2212 if (ax == 0x11 || ax == 0xBB)
2213 ExplodeFieldSP(si + FieldWidth);
2215 return subExplodeSnikSnaksBelow;
2216 } // subExplodeSnikSnaksBelow
2218 // ==========================================================================
2220 // Does pushing against an object kill Murphy?
2221 // ==========================================================================
2222 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2224 static boolean subMoveKillsMurphy;
2230 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2236 if (al == fiExplosion)
2239 if (fiOrangeDisk <= al && al <= fiPortUp)
2242 ExplodeFieldSP(si); // Explode
2243 subMoveKillsMurphy = True;
2244 return subMoveKillsMurphy;
2253 ExplodeFieldSP(si); // Explode
2254 subMoveKillsMurphy = True;
2255 return subMoveKillsMurphy;
2257 loc_g_74F6: // zonk left
2259 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2262 subMoveKillsMurphy = True; // Set carry flag
2263 return subMoveKillsMurphy;
2265 loc_g_7512: // zonk right
2267 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2270 loc_g_752E: // Marked fields and Ports
2271 subMoveKillsMurphy = True; // Set carry flag
2272 return subMoveKillsMurphy;
2274 loc_g_7530: // explosion
2275 if ((ah & 0x80) != 0)
2282 ExplodeFieldSP(si); // Explode
2283 subMoveKillsMurphy = True; // Set carry flag
2284 return subMoveKillsMurphy;
2287 PlayField16[si] = 0;
2288 subMoveKillsMurphy = False;
2290 return subMoveKillsMurphy;
2291 } // subMoveKillsMurphy
2293 // ==========================================================================
2295 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2296 // change conditions to port specs
2297 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2298 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2299 // ==========================================================================
2300 int subSpPortTest(int si)
2306 cx = LInfo.SpecialPortCount; // number of special ports
2307 for (i = 1; i <= cx; i++)
2310 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2311 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2314 GravityFlag = LInfo.SpecialPort[i].Gravity;
2315 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2316 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2317 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2324 return subSpPortTest;
2327 void subCopyFieldToScreen(int si, int fi)
2331 // +++++++++++++++++++++++++++++++++++++++++
2332 X = GetStretchX(si);
2333 Y = GetStretchY(si);
2334 StretchedSprites.BltEx(X, Y, fi);
2335 // +++++++++++++++++++++++++++++++++++++++++
2338 static void subEatRedDisk(int si)
2340 if (AllowRedDiskCheat == 0)
2342 if (RedDiskReleasePhase != 0)
2344 if (RedDiskReleaseMurphyPos == si)
2349 RedDiskCount = (RedDiskCount + 1) % 256;
2350 subDisplayRedDiskCount();
2353 int subAdjustZonksInfotronsAboveMurphy(int si)
2355 int subAdjustZonksInfotronsAboveMurphy;
2359 if (LowByte(PlayField16[si]) != fiExplosion)
2360 PlayField16[si] = 0;
2362 ax = PlayField16[si - FieldWidth];
2363 if (ax == 0 || ax == 0x9999)
2366 if (ax == fiZonk || ax == fiInfotron)
2368 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2371 return subAdjustZonksInfotronsAboveMurphy;
2373 loc_g_15A8: // empty above
2374 ax = PlayField16[si - FieldWidth - 1];
2375 if (ax == fiZonk || ax == fiInfotron)
2379 ax = PlayField16[si - FieldWidth + 1];
2380 if (ax == fiZonk || ax == fiInfotron)
2383 return subAdjustZonksInfotronsAboveMurphy;
2385 loc_g_15C5: // zonk/infotron above left
2386 ax = PlayField16[si - 1];
2387 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2390 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2391 PlayField16[si - FieldWidth] = 0x8888;
2392 return subAdjustZonksInfotronsAboveMurphy;
2394 loc_g_15E8: // zonk/infotron above right
2395 ax = PlayField16[si + 1];
2396 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2398 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2399 PlayField16[si - FieldWidth] = 0x8888;
2402 return subAdjustZonksInfotronsAboveMurphy;
2403 } // subAdjustZonksInfotronsAboveMurphy