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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n", LevelNumber);
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 : aniMurphyEatUpLeft);
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 : aniMurphyEatUpLeft);
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;
1427 printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1429 DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1430 (DemoKeyCode == keyNone ? "(none)" :
1431 DemoKeyCode == keyLeft ? "left" :
1432 DemoKeyCode == keyRight ? "right" :
1433 DemoKeyCode == keyUp ? "up" :
1434 DemoKeyCode == keyDown ? "down" :
1435 DemoKeyCode == keySpace ? "space" :
1436 DemoKeyCode == keySpaceLeft ? "space + left" :
1437 DemoKeyCode == keySpaceRight ? "space + right" :
1438 DemoKeyCode == keySpaceUp ? "space + up" :
1439 DemoKeyCode == keySpaceDown ? "space + down" : "(unknown)"),
1441 MurphyScreenXPos, MurphyScreenYPos,
1442 MurphyPosIndex % 60, MurphyPosIndex / 60,
1451 if (!(ClearPos < 0)) // clear field that murphy is leaving
1452 subCopyFieldToScreen(ClearPos, 0);
1454 if (! ClearPos < 0) // clear field that murphy is leaving
1455 subCopyFieldToScreen(ClearPos, 0);
1459 printf("::: ---------------> %d, %d [%d, %d]\n",
1460 MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1463 if (dx2 == fiInfotron) // special case of infotron moving left or right
1470 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1471 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1474 X = GetStretchX(dxPos) + tDeltaX;
1475 Y = GetStretchY(dxPos) + tDeltaY;
1476 Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1477 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1485 tPos = dxPos + dx2Step;
1486 X = GetStretchX(tPos);
1487 Y = GetStretchY(tPos);
1488 if (dx2 == fiInfotron) // special case of infotron moving left or right
1490 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1492 else // pushing something
1494 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1498 // End of normal movement
1499 // ------------------------
1503 // ++++++++++++++++++++++++++++++++
1504 // Begin of split movement (port)
1506 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1507 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1509 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1510 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1512 subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1513 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1514 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1515 X = GetStretchX(dxPos) + tDeltaX;
1516 Y = GetStretchY(dxPos) + tDeltaY;
1517 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1518 tPos = dxPos + dx2Step;
1519 X = GetStretchX(tPos);
1520 Y = GetStretchY(tPos);
1521 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1522 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1523 // End of split movement (port)
1524 // ------------------------------
1525 } // loc_g_6D1E:'loc_g_6D28:
1527 SeqPos = SeqPos + 1;
1528 if (dx[SeqPos] > -1)
1529 return subAnimateMurphy;
1531 // Follow-up after movement completed 'loc_g_6D35:
1532 MurphyXPos = MurphyXPos + MurphyDX;
1533 MurphyYPos = MurphyYPos + MurphyDY;
1534 bl = HighByte(PlayField16[*si]); // animation phase
1535 MovHighByte(&PlayField16[*si], 0);
1537 if (bl == 0x1) // space, moving up
1540 if (bl == 0x2) // space, moving left
1543 if (bl == 0x3) // space, moving down
1546 if (bl == 0x4) // space, moving right
1549 if (bl == 0x5) // base , moving up
1552 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1555 if (bl == 0x7) // base , moving down
1558 if (bl == 0x8) // base , moving right
1561 if (bl == 0x9) // infotron, moving up
1564 if (bl == 0xA) // infotron, moving left
1567 if (bl == 0xB) // infotron, moving down
1570 if (bl == 0xC) // infotron, moving right
1573 if (bl == 0xD) // exit
1576 if (bl == 0xE) // zonk, pushing left
1579 if (bl == 0xF) // zonk, pushing right
1582 if (bl == 0x10) // base , touching up
1585 if (bl == 0x11) // base , touching left
1588 if (bl == 0x12) // base , touching down
1591 if (bl == 0x13) // base , touching right
1594 if (bl == 0x14) // infotron touching up
1597 if (bl == 0x15) // infotron touching left
1600 if (bl == 0x16) // infotron touching down
1603 if (bl == 0x17) // infotron touching right
1606 if (bl == 0x18) // port up
1609 if (bl == 0x19) // port left
1612 if (bl == 0x1A) // port down
1615 if (bl == 0x1B) // port right
1618 if (bl == 0x1C) // red disk, moving up
1621 if (bl == 0x1D) // red disk, moving left
1624 if (bl == 0x1E) // red disk, moving down
1627 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1630 if (bl == 0x20) // red disk, touching up
1633 if (bl == 0x21) // red disk, touching left
1636 if (bl == 0x22) // red disk, touching down
1639 if (bl == 0x23) // red disk, touching right
1642 if (bl == 0x24) // yellow disk, pushing up
1645 if (bl == 0x25) // yellow disk, pushing left
1648 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1651 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1654 if (bl == 0x28) // orange disk, pushing left
1657 if (bl == 0x29) // orange disk, pushing right
1660 if (bl == 0x2A) // red disk, release
1664 return subAnimateMurphy;
1666 // ==========================================================================
1667 // infotron, moving up
1668 // ==========================================================================
1671 if (0 < LowByte(InfotronsNeeded))
1672 InfotronsNeeded = InfotronsNeeded - 1;
1674 subDisplayInfotronsNeeded();
1675 loc_g_6EC8: // space, base
1676 PlayField16[*si] = fiMurphy;
1677 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1678 return subAnimateMurphy;
1680 // ==========================================================================
1681 // infotron, moving left
1682 // ==========================================================================
1685 if (0 < LowByte(InfotronsNeeded))
1686 InfotronsNeeded = InfotronsNeeded - 1;
1688 subDisplayInfotronsNeeded();
1689 loc_g_6EE6: // space, base
1690 PlayField16[*si] = fiMurphy;
1691 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1692 return subAnimateMurphy;
1694 // ==========================================================================
1695 // infotron, moving down
1696 // ==========================================================================
1699 if (0 < LowByte(InfotronsNeeded))
1700 InfotronsNeeded = InfotronsNeeded - 1;
1702 subDisplayInfotronsNeeded();
1703 loc_g_6F04: // space, base
1704 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1705 PlayField16[*si - FieldWidth] = 0;
1707 PlayField16[*si] = fiMurphy;
1708 return subAnimateMurphy;
1710 // ==========================================================================
1711 // infotron, moving right
1712 // ==========================================================================
1715 if (0 < LowByte(InfotronsNeeded))
1716 InfotronsNeeded = InfotronsNeeded - 1;
1718 subDisplayInfotronsNeeded();
1719 loc_g_71C4: // space, base
1720 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1721 PlayField16[*si] = fiMurphy;
1722 return subAnimateMurphy;
1724 // ==========================================================================
1725 // infotron, touching up
1726 // ==========================================================================
1729 if (0 < LowByte(InfotronsNeeded))
1730 InfotronsNeeded = InfotronsNeeded - 1;
1732 subDisplayInfotronsNeeded();
1734 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1735 PlayField16[*si - FieldWidth] = 0;
1737 return subAnimateMurphy;
1739 // ==========================================================================
1740 // infotron, touching left
1741 // ==========================================================================
1744 if (0 < LowByte(InfotronsNeeded))
1745 InfotronsNeeded = InfotronsNeeded - 1;
1747 subDisplayInfotronsNeeded();
1749 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1750 PlayField16[*si - 1] = 0;
1752 return subAnimateMurphy;
1754 // ==========================================================================
1755 // infotron, touching down
1756 // ==========================================================================
1759 if (0 < LowByte(InfotronsNeeded))
1760 InfotronsNeeded = InfotronsNeeded - 1;
1762 subDisplayInfotronsNeeded();
1764 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1765 PlayField16[*si + FieldWidth] = 0;
1767 return subAnimateMurphy;
1769 // ==========================================================================
1770 // infotron, touching right
1771 // ==========================================================================
1774 if (0 < LowByte(InfotronsNeeded))
1775 InfotronsNeeded = InfotronsNeeded - 1;
1777 subDisplayInfotronsNeeded();
1779 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1780 PlayField16[*si + 1] = 0;
1782 return subAnimateMurphy;
1784 // ==========================================================================
1785 // zonk, pushing left
1786 // ==========================================================================
1789 if (LowByte(PlayField16[*si]) != fiExplosion)
1790 PlayField16[*si] = 0;
1792 PlayField16[*si - 1] = fiMurphy;
1793 PlayField16[*si - 2] = fiZonk;
1794 subExplodeSnikSnaksBelow(*si - 2);
1796 return subAnimateMurphy;
1798 // ==========================================================================
1799 // zonk, pushing right
1800 // ==========================================================================
1803 if (LowByte(PlayField16[*si]) != fiExplosion)
1804 PlayField16[*si] = 0;
1806 PlayField16[*si + 1] = fiMurphy;
1807 PlayField16[*si + 2] = fiZonk;
1808 subExplodeSnikSnaksBelow(*si + 2);
1810 return subAnimateMurphy;
1812 // ==========================================================================
1814 // ==========================================================================
1818 return subAnimateMurphy;
1820 // ==========================================================================
1821 // Push Zonk from right to left
1822 // ==========================================================================
1825 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1826 return subAnimateMurphy;
1828 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1829 PlayField16[*si - 1] = fiZonk;
1830 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1831 PlayField16[*si - 2] = 0;
1833 subCopyFieldToScreen(*si, fiMurphy);
1834 return subAnimateMurphy;
1836 // ==========================================================================
1837 // Push Zonk from left to right
1838 // ==========================================================================
1841 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1842 return subAnimateMurphy;
1844 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1845 PlayField16[*si + 1] = fiZonk;
1846 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1847 PlayField16[*si + 2] = 0;
1849 subCopyFieldToScreen(*si, fiMurphy);
1850 return subAnimateMurphy;
1852 // ==========================================================================
1853 // Push orange disk from right to left
1854 // ==========================================================================
1857 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1858 return subAnimateMurphy;
1860 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1861 PlayField16[*si - 1] = fiOrangeDisk;
1862 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1863 PlayField16[*si - 2] = 0;
1865 subCopyFieldToScreen(*si, fiMurphy);
1866 return subAnimateMurphy;
1868 // ==========================================================================
1869 // Push orange disk from left to right
1870 // ==========================================================================
1873 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1874 return subAnimateMurphy;
1876 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1877 PlayField16[*si + 1] = fiOrangeDisk;
1878 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1879 PlayField16[*si + 2] = 0;
1881 subCopyFieldToScreen(*si, fiMurphy);
1882 return subAnimateMurphy;
1884 // ==========================================================================
1885 // Push yellow disk from down to up
1886 // ==========================================================================
1889 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1890 return subAnimateMurphy;
1892 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1893 PlayField16[*si - FieldWidth] = fiYellowDisk;
1894 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1895 PlayField16[*si - 2 * FieldWidth] = 0;
1897 subCopyFieldToScreen(*si, fiMurphy);
1898 return subAnimateMurphy;
1900 // ==========================================================================
1901 // Push yellow disk from right to left
1902 // ==========================================================================
1905 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1906 return subAnimateMurphy;
1908 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1909 PlayField16[*si - 1] = fiYellowDisk;
1910 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1911 PlayField16[*si - 2] = 0;
1913 subCopyFieldToScreen(*si, fiMurphy);
1914 return subAnimateMurphy;
1916 // ==========================================================================
1917 // Push yellow disk from up to down
1918 // ==========================================================================
1921 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1922 return subAnimateMurphy;
1924 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1925 PlayField16[*si + FieldWidth] = fiYellowDisk;
1926 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1927 PlayField16[*si + 2 * FieldWidth] = 0;
1929 subCopyFieldToScreen(*si, fiMurphy);
1930 return subAnimateMurphy;
1932 // ==========================================================================
1933 // Push yellow disk from left to right
1934 // ==========================================================================
1937 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1938 return subAnimateMurphy;
1940 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1941 PlayField16[*si + 1] = fiYellowDisk;
1942 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1943 PlayField16[*si + 2] = 0;
1945 subCopyFieldToScreen(*si, fiMurphy);
1946 return subAnimateMurphy;
1948 // ==========================================================================
1949 // time red disk release (space)
1950 // ==========================================================================
1953 if (DemoKeyCode != keySpace)
1955 PlayField16[*si] = fiMurphy;
1956 subCopyFieldToScreen(*si, fiMurphy);
1957 RedDiskReleasePhase = 0;
1959 else if (MovingPictureSequencePhase == 0x20)
1961 subCopyFieldToScreen(*si, 43); // anxious murphy
1962 RedDiskReleasePhase = 1;
1965 return subAnimateMurphy;
1967 // ==========================================================================
1968 // Special port down to up
1969 // ==========================================================================
1972 if (LowByte(PlayField16[*si]) != fiExplosion)
1973 PlayField16[*si] = 0;
1975 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1977 *si = *si - FieldWidth;
1978 if (HighByte(PlayField16[*si]) == 1)
1981 *si = *si - FieldWidth;
1982 return subAnimateMurphy;
1984 // ==========================================================================
1985 // Special port right to left
1986 // ==========================================================================
1989 if (LowByte(PlayField16[*si]) != fiExplosion)
1990 PlayField16[*si] = 0;
1992 PlayField16[*si - 2] = fiMurphy;
1995 if (HighByte(PlayField16[*si]) == 1)
1999 return subAnimateMurphy;
2001 // ==========================================================================
2002 // Special port up to down
2003 // ==========================================================================
2006 if (LowByte(PlayField16[*si]) != fiExplosion)
2007 PlayField16[*si] = 0;
2009 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2011 *si = *si + FieldWidth;
2012 if (HighByte(PlayField16[*si]) == 1)
2015 *si = *si + FieldWidth;
2016 return subAnimateMurphy;
2018 // ==========================================================================
2019 // Special port left to right
2020 // ==========================================================================
2023 if (LowByte(PlayField16[*si]) != fiExplosion)
2024 PlayField16[*si] = 0;
2026 PlayField16[*si + 2] = fiMurphy;
2029 if (HighByte(PlayField16[*si]) == 1)
2033 return subAnimateMurphy;
2035 // ==========================================================================
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 left
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 // ==========================================================================
2061 // Move Red Disk down
2062 // ==========================================================================
2065 if (LowByte(PlayField16[*si]) != fiExplosion)
2066 PlayField16[*si] = 0;
2068 *si = *si + FieldWidth;
2069 PlayField16[*si] = fiMurphy;
2070 subEatRedDisk(*si); // inc+show Murphy's red disks
2071 return subAnimateMurphy;
2073 // ==========================================================================
2074 // Move Red Disk right
2075 // ==========================================================================
2078 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2079 PlayField16[*si - 1] = 0;
2081 PlayField16[*si] = fiMurphy;
2082 subEatRedDisk(*si); // inc+show Murphy's red disks
2083 return subAnimateMurphy;
2085 // ==========================================================================
2087 // ==========================================================================
2090 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2091 PlayField16[*si - FieldWidth] = 0;
2093 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2094 return subAnimateMurphy;
2096 // ==========================================================================
2097 // Eat Red Disk left
2098 // ==========================================================================
2101 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2102 PlayField16[*si - 1] = 0;
2104 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2105 return subAnimateMurphy;
2107 // ==========================================================================
2108 // Eat Red Disk down
2109 // ==========================================================================
2112 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2113 PlayField16[*si + FieldWidth] = 0;
2115 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2116 return subAnimateMurphy;
2118 // ==========================================================================
2119 // Eat Red Disk right
2120 // ==========================================================================
2123 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2124 PlayField16[*si + 1] = 0;
2126 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2127 return subAnimateMurphy;
2129 // ==========================================================================
2130 // yellow disk, pushing up
2131 // ==========================================================================
2134 if (LowByte(PlayField16[*si]) != fiExplosion)
2135 PlayField16[*si] = 0;
2137 *si = *si - FieldWidth;
2138 PlayField16[*si] = fiMurphy;
2139 PlayField16[*si - FieldWidth] = fiYellowDisk;
2140 return subAnimateMurphy;
2142 // ==========================================================================
2143 // yellow disk, pushing left
2144 // ==========================================================================
2147 if (LowByte(PlayField16[*si]) != fiExplosion)
2148 PlayField16[*si] = 0;
2151 PlayField16[*si] = fiMurphy;
2152 PlayField16[*si - 1] = fiYellowDisk;
2153 return subAnimateMurphy;
2155 // ==========================================================================
2156 // yellow disk, pushing down
2157 // ==========================================================================
2160 if (LowByte(PlayField16[*si]) != fiExplosion)
2161 PlayField16[*si] = 0;
2163 *si = *si + FieldWidth;
2164 PlayField16[*si] = fiMurphy;
2165 PlayField16[*si + FieldWidth] = fiYellowDisk;
2166 return subAnimateMurphy;
2168 // ==========================================================================
2169 // yellow disk pushing right
2170 // ==========================================================================
2173 if (LowByte(PlayField16[*si]) != fiExplosion)
2174 PlayField16[*si] = 0;
2177 PlayField16[*si] = fiMurphy;
2178 PlayField16[*si + 1] = fiYellowDisk;
2179 return subAnimateMurphy;
2181 // ==========================================================================
2182 // orange disk, pushing left
2183 // ==========================================================================
2186 if (LowByte(PlayField16[*si]) != fiExplosion)
2187 PlayField16[*si] = 0;
2190 PlayField16[*si] = fiMurphy;
2191 PlayField16[*si - 1] = fiOrangeDisk;
2192 return subAnimateMurphy;
2194 // ==========================================================================
2195 // orange disk, pushing right
2196 // ==========================================================================
2199 if (LowByte(PlayField16[*si]) != fiExplosion)
2200 PlayField16[*si] = 0;
2203 PlayField16[*si] = fiMurphy;
2204 PlayField16[*si + 1] = fiOrangeDisk;
2205 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2207 MovHighByte(&PlayField16[*si + 1], 0x20);
2208 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2211 return subAnimateMurphy;
2213 // ==========================================================================
2214 // Release a red disk
2215 // ==========================================================================
2218 PlayField16[*si] = fiMurphy;
2219 RedDiskReleasePhase = 2;
2220 RedDiskCount = RedDiskCount - 1;
2221 subDisplayRedDiskCount();
2222 subSoundFXPush(); // Sound effects
2224 return subAnimateMurphy;
2225 } // subAnimateMurphy
2227 // ==========================================================================
2229 // ==========================================================================
2230 int subExplodeSnikSnaksBelow(int si)
2232 int subExplodeSnikSnaksBelow;
2236 ax = LowByte(PlayField16[si + FieldWidth]);
2237 if (ax == 0x11 || ax == 0xBB)
2238 ExplodeFieldSP(si + FieldWidth);
2240 return subExplodeSnikSnaksBelow;
2241 } // subExplodeSnikSnaksBelow
2243 // ==========================================================================
2245 // Does pushing against an object kill Murphy?
2246 // ==========================================================================
2247 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2249 static boolean subMoveKillsMurphy;
2255 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2261 if (al == fiExplosion)
2264 if (fiOrangeDisk <= al && al <= fiPortUp)
2267 ExplodeFieldSP(si); // Explode
2268 subMoveKillsMurphy = True;
2269 return subMoveKillsMurphy;
2278 ExplodeFieldSP(si); // Explode
2279 subMoveKillsMurphy = True;
2280 return subMoveKillsMurphy;
2282 loc_g_74F6: // zonk left
2284 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2287 subMoveKillsMurphy = True; // Set carry flag
2288 return subMoveKillsMurphy;
2290 loc_g_7512: // zonk right
2292 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2295 loc_g_752E: // Marked fields and Ports
2296 subMoveKillsMurphy = True; // Set carry flag
2297 return subMoveKillsMurphy;
2299 loc_g_7530: // explosion
2300 if ((ah & 0x80) != 0)
2307 ExplodeFieldSP(si); // Explode
2308 subMoveKillsMurphy = True; // Set carry flag
2309 return subMoveKillsMurphy;
2312 PlayField16[si] = 0;
2313 subMoveKillsMurphy = False;
2315 return subMoveKillsMurphy;
2316 } // subMoveKillsMurphy
2318 // ==========================================================================
2320 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2321 // change conditions to port specs
2322 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2323 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2324 // ==========================================================================
2325 int subSpPortTest(int si)
2332 cx = LInfo.SpecialPortCount; // number of special ports
2334 for (i = 0; i < cx; i++)
2337 /* this assumes that PortLocation is stored as big endian */
2338 bx = LInfo.SpecialPort[i].PortLocation;
2340 /* this assumes that PortLocation is stored as little endian */
2341 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2342 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2347 GravityFlag = LInfo.SpecialPort[i].Gravity;
2348 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2349 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2351 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2359 cx = LInfo.SpecialPortCount; // number of special ports
2360 for (i = 1; i <= cx; i++)
2363 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2364 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2367 GravityFlag = LInfo.SpecialPort[i].Gravity;
2368 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2369 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2370 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2377 return subSpPortTest;
2380 void subCopyFieldToScreen(int si, int fi)
2384 // +++++++++++++++++++++++++++++++++++++++++
2385 X = GetStretchX(si);
2386 Y = GetStretchY(si);
2387 StretchedSprites.BltEx(X, Y, fi);
2388 // +++++++++++++++++++++++++++++++++++++++++
2391 static void subEatRedDisk(int si)
2393 if (AllowRedDiskCheat == 0)
2395 if (RedDiskReleasePhase != 0)
2397 if (RedDiskReleaseMurphyPos == si)
2402 RedDiskCount = (RedDiskCount + 1) % 256;
2403 subDisplayRedDiskCount();
2406 int subAdjustZonksInfotronsAboveMurphy(int si)
2408 int subAdjustZonksInfotronsAboveMurphy;
2412 if (LowByte(PlayField16[si]) != fiExplosion)
2413 PlayField16[si] = 0;
2415 ax = PlayField16[si - FieldWidth];
2416 if (ax == 0 || ax == 0x9999)
2419 if (ax == fiZonk || ax == fiInfotron)
2421 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2424 return subAdjustZonksInfotronsAboveMurphy;
2426 loc_g_15A8: // empty above
2427 ax = PlayField16[si - FieldWidth - 1];
2428 if (ax == fiZonk || ax == fiInfotron)
2432 ax = PlayField16[si - FieldWidth + 1];
2433 if (ax == fiZonk || ax == fiInfotron)
2436 return subAdjustZonksInfotronsAboveMurphy;
2438 loc_g_15C5: // zonk/infotron above left
2439 ax = PlayField16[si - 1];
2440 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2443 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2444 PlayField16[si - FieldWidth] = 0x8888;
2445 return subAdjustZonksInfotronsAboveMurphy;
2447 loc_g_15E8: // zonk/infotron above right
2448 ax = PlayField16[si + 1];
2449 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2451 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2452 PlayField16[si - FieldWidth] = 0x8888;
2455 return subAdjustZonksInfotronsAboveMurphy;
2456 } // subAdjustZonksInfotronsAboveMurphy