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 if (!game_sp_info.LevelSolved)
936 printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n",LevelNumber);
939 game_sp_info.LevelSolved = TRUE;
942 data_h_DemoDone = 1; // EP set level success bytes
943 LevelStatus = 1; // set Level Status DONE
944 EP_GameDemoVar0DAA = 0; // force demo for lead-out
945 if (SavedGameFlag == 0) // saved game running?
947 if (UpdateTimeFlag != 0) // update time?
949 UpdatedFlag = 1; // prevent double update
950 subUpdatePlayingTime(); // update playing time
955 subUpdateHallOfFame(); // update time + Hall-Of-Fame
958 LeadOutCounter = 0x40; // quit: start lead-out
960 MovHighByte(&PlayField16[*si], 0xD);
961 goto loc_StopNoSplit;
963 // ==========================================================================
964 // ZONK moving right to left
965 // ==========================================================================
968 ax = PlayField16[*si - 2];
970 return subAnimateMurphy;
972 MovHighByte(&PlayField16[*si - 2], 1);
973 subCopyFieldToScreen(*si, aniPushLeft); // draw pushing murphy
974 dx = aniZonkRollLeft;
978 MovHighByte(&PlayField16[*si], 0xE);
979 goto loc_MoveNoSplit;
981 // ==========================================================================
982 // ZONK moving left to right
983 // ==========================================================================
986 ax = PlayField16[*si + 2];
988 return subAnimateMurphy;
990 ax = PlayField16[*si + FieldWidth + 1];
991 if (ax == 0) // zonk falls
992 return subAnimateMurphy;
994 MovHighByte(&PlayField16[*si + 2], 1);
995 subCopyFieldToScreen(*si, aniPushRight); // draw pushing murphy
996 dx = aniZonkRollRight;
1000 MovHighByte(&PlayField16[*si], 0xF);
1001 goto loc_MoveNoSplit;
1003 // ==========================================================================
1004 // TERMINAL moving/touching down to up
1005 // ==========================================================================
1008 subCopyFieldToScreen(*si, aniMurphyTouchUp);
1009 if (YellowDisksExploded != 0)
1011 YawnSleepCounter = 10; // stay hypnotized
1012 return subAnimateMurphy;
1015 subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1016 TerminalState[*si - FieldWidth] = 8;
1019 // ==========================================================================
1020 // TERMINAL moving/touching right to left
1021 // ==========================================================================
1024 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
1025 if (YellowDisksExploded != 0)
1027 YawnSleepCounter = 10; // stay hypnotized
1028 return subAnimateMurphy;
1031 subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1032 TerminalState[*si - 1] = 8;
1035 // ==========================================================================
1036 // TERMINAL moving/touching up to down
1037 // ==========================================================================
1040 subCopyFieldToScreen(*si, aniMurphyTouchDown);
1041 if (YellowDisksExploded != 0)
1043 YawnSleepCounter = 10; // stay hypnotized
1044 return subAnimateMurphy;
1047 subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1048 TerminalState[*si + FieldWidth] = 8;
1051 // ==========================================================================
1052 // TERMINAL moving/touching left to right
1053 // ==========================================================================
1056 subCopyFieldToScreen(*si, aniMurphyTouchRight);
1057 if (YellowDisksExploded != 0)
1059 YawnSleepCounter = 10; // stay hypnotized
1060 return subAnimateMurphy;
1063 subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1064 TerminalState[*si + 1] = 8;
1065 // ==========================================================================
1066 // common TERMINAL stuff moving/touching from all directions
1067 // ==========================================================================
1070 TerminalMaxCycles = 7;
1071 YellowDisksExploded = 1;
1072 for (i = 0; i <= LevelMax; i++)
1074 if (PlayField16[i] == fiYellowDisk)
1078 return subAnimateMurphy;
1080 // ==========================================================================
1081 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1082 // ==========================================================================
1085 if (PlayField16[*si - 2 * FieldWidth] != 0)
1086 return subAnimateMurphy;
1088 dx = aniSplitUpDown;
1089 dx2Step = -FieldWidth;
1090 PlayField16[*si] = 0x1803;
1091 PlayField16[*si - 2 * FieldWidth] = 0x300;
1094 // ==========================================================================
1095 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1096 // ==========================================================================
1099 if (PlayField16[*si - 2] != 0)
1100 return subAnimateMurphy;
1102 dx = aniMurphyEatLeft;
1104 PlayField16[*si] = 0x1903;
1105 PlayField16[*si - 2] = 0x300;
1108 // ==========================================================================
1109 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1110 // ==========================================================================
1113 if (PlayField16[*si + 2 * FieldWidth] != 0)
1114 return subAnimateMurphy;
1116 dx = aniSplitUpDown;
1117 dx2Step = FieldWidth;
1118 PlayField16[*si] = 0x1A03;
1119 PlayField16[*si + 2 * FieldWidth] = 0x300;
1122 // ==========================================================================
1123 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1124 // ==========================================================================
1127 if (PlayField16[*si + 2] != 0)
1128 return subAnimateMurphy;
1130 dx = aniMurphyEatRight;
1132 PlayField16[*si] = 0x1B03;
1133 PlayField16[*si + 2] = 0x300;
1136 MovingPictureSequencePhase = 0; // stop picture move sequence
1137 SplitMoveFlag = 1; // port: split movement
1140 // ==========================================================================
1141 // RED DISK moving down to up
1142 // ==========================================================================
1145 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1146 PlayField16[*si] = 0x1C03;
1147 PlayField16[*si - FieldWidth] = 0x300;
1148 goto loc_StopNoSplit;
1150 // ==========================================================================
1151 // RED DISK moving right to left
1152 // ==========================================================================
1155 dx = aniMurphyEatLeft;
1156 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1157 PlayField16[*si - 1] = 0x1D03;
1159 goto loc_StopNoSplit;
1161 // ==========================================================================
1162 // RED DISK moving up to down
1163 // ==========================================================================
1166 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1167 PlayField16[*si] = 0x1E03;
1168 PlayField16[*si + FieldWidth] = 0x300;
1169 goto loc_StopNoSplit;
1171 // ==========================================================================
1172 // RED DISK moving left to right
1173 // ==========================================================================
1176 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1177 dx = aniMurphyEatRight;
1178 // --------------------------------------------------------------------------
1180 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1181 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1182 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1183 // We may not fix the table, because then the timing of the game changes
1184 // and several existing demo's do not run properly anymore.
1185 // We only correct Murphies x-location here, when the sequence starts.
1186 // Remember that this is not the real bug-fix, but we must live with
1187 // this existing bug and correct for the consequences of it.
1190 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1191 MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1193 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1194 MurphyScreenXPos = MurphyScreenXPos - 2;
1198 // FS: for me this means to blit the first animation frame twice
1200 // --------------------------------------------------------------------------
1201 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1202 PlayField16[*si + 1] = 0x1F03;
1204 goto loc_StopNoSplit;
1206 // ==========================================================================
1207 // RED DISK touching down to up
1208 // ==========================================================================
1211 dx = aniTouchRedDisk;
1212 MovHighByte(&PlayField16[*si], 0x20);
1213 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1214 goto loc_StopNoSplit;
1216 // ==========================================================================
1217 // RED DISK touching right to left
1218 // ==========================================================================
1221 dx = aniTouchRedDisk;
1222 MovHighByte(&PlayField16[*si], 0x21);
1223 MovHighByte(&PlayField16[*si - 1], 3);
1224 goto loc_StopNoSplit;
1226 // ==========================================================================
1227 // RED DISK touching up to down
1228 // ==========================================================================
1231 dx = aniTouchRedDisk;
1232 MovHighByte(&PlayField16[*si], 0x22);
1233 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1234 goto loc_StopNoSplit;
1236 // ==========================================================================
1237 // RED DISK touching left to right
1238 // ==========================================================================
1241 dx = aniTouchRedDisk;
1242 MovHighByte(&PlayField16[*si], 0x23);
1243 MovHighByte(&PlayField16[*si + 1], 3);
1246 MovingPictureSequencePhase = 0; // stop picture move sequence
1249 // ==========================================================================
1250 // YELLOW DISK moving down to up
1251 // ==========================================================================
1254 if (PlayField16[*si - 2 * FieldWidth] != 0)
1255 return subAnimateMurphy;
1257 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1258 subCopyFieldToScreen(*si, aniPushRight);
1260 dxPos = *si - FieldWidth;
1261 dx2 = aniPushUpDown;
1262 dx2Step = FieldWidth;
1263 PlayField16[*si] = 0x2403;
1264 goto loc_MoveNoSplit;
1266 // ==========================================================================
1267 // YELLOW DISK moving right to left
1268 // ==========================================================================
1271 if (PlayField16[*si - 2] != 0)
1272 return subAnimateMurphy;
1274 PlayField16[*si - 2] = 0x1200;
1275 subCopyFieldToScreen(*si, aniPushLeft);
1280 PlayField16[*si] = 0x2503;
1281 goto loc_MoveNoSplit;
1283 // ==========================================================================
1284 // YELLOW DISK moving up to down
1285 // ==========================================================================
1288 if (PlayField16[*si + 2 * FieldWidth] != 0)
1289 return subAnimateMurphy;
1291 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1292 subCopyFieldToScreen(*si, aniPushRight);
1294 dxPos = *si + FieldWidth;
1295 dx2 = aniPushUpDown;
1296 dx2Step = -FieldWidth;
1297 PlayField16[*si] = 0x2703;
1298 goto loc_MoveNoSplit;
1300 // ==========================================================================
1301 // YELLOW DISK moving left to right
1302 // ==========================================================================
1305 if (PlayField16[*si + 2] != 0)
1306 return subAnimateMurphy;
1308 PlayField16[*si + 2] = 0x1200;
1309 subCopyFieldToScreen(*si, aniPushRight);
1314 PlayField16[*si] = 0x2603;
1315 goto loc_MoveNoSplit;
1317 // ==========================================================================
1318 // ORANGE DISK moving right to left
1319 // ==========================================================================
1322 if (PlayField16[*si - 2] != 0)
1323 return subAnimateMurphy;
1325 PlayField16[*si - 2] = 0x800;
1326 subCopyFieldToScreen(*si, aniPushLeft);
1331 PlayField16[*si] = 0x2803;
1332 goto loc_MoveNoSplit;
1334 // ==========================================================================
1335 // ORANGE DISK moving left to right
1336 // ==========================================================================
1339 if (PlayField16[*si + 2] != 0)
1340 return subAnimateMurphy;
1342 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1343 return subAnimateMurphy;
1345 PlayField16[*si + 2] = 0x100;
1346 subCopyFieldToScreen(*si, aniPushRight);
1351 PlayField16[*si] = 0x2903;
1352 // ==========================================================================
1353 // Copy screen animation action table to action work space
1354 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1355 // ==========================================================================
1358 MovingPictureSequencePhase = 8; // init picture move sequence
1361 SplitMoveFlag = 0; // no port: no split movement
1364 // copy/store global move sequence info????????????????????????????????????
1365 // ... dont think so ...(FS)
1366 // ==========================================================================
1367 // Proceed with all movements
1368 // ==========================================================================
1370 locProceedMovingMurphy: // proceed moving murphy
1371 YawnSleepCounter = 0; // Wake up sleeping Murphy
1372 ax = MovingPictureSequencePhase; // sequence busy?
1373 if (ax == 0) // no -- start sequence!
1376 ax = ax - 1; // next picture of sequence
1377 MovingPictureSequencePhase = ax; // store for later
1378 if (ax == 0) // Sound effects
1381 bl = HighByte(PlayField16[*si]);
1382 if (bl == 0xE) // Push Zonk to left
1385 if (bl == 0xF) // Push Zonk to right
1388 if (bl == 0x28) // Push orange disk to left
1391 if (bl == 0x29) // Push orange disk to right
1394 if (bl == 0x24) // Push yellow disk up
1397 if (bl == 0x25) // Push yellow disk to left
1400 if (bl == 0x27) // Push yellow disk down
1403 if (bl == 0x26) // Push yellow disk to right
1406 if (bl == 0x2A) // Red disk release timer
1409 return subAnimateMurphy;
1411 // ==========================================================================
1412 // Paint frame of MOVING.DAT sequence
1413 // ==========================================================================
1416 if (SplitMoveFlag == 0)
1418 // ++++++++++++++++++++++++++
1419 // Begin of normal movement
1421 MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1422 MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1424 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1425 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1430 printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1432 DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1433 (DemoKeyCode == keyNone ? "(none)" :
1434 DemoKeyCode == keyLeft ? "left" :
1435 DemoKeyCode == keyRight ? "right" :
1436 DemoKeyCode == keyUp ? "up" :
1437 DemoKeyCode == keyDown ? "down" :
1438 DemoKeyCode == keySpace ? "space" :
1439 DemoKeyCode == keySpaceLeft ? "space + left" :
1440 DemoKeyCode == keySpaceRight ? "space + right" :
1441 DemoKeyCode == keySpaceUp ? "space + up" :
1442 DemoKeyCode == keySpaceDown ? "space + down" : "(unknown)"),
1444 MurphyScreenXPos, MurphyScreenYPos,
1445 MurphyPosIndex % 60, MurphyPosIndex / 60,
1454 if (!(ClearPos < 0)) // clear field that murphy is leaving
1455 subCopyFieldToScreen(ClearPos, 0);
1457 if (! ClearPos < 0) // clear field that murphy is leaving
1458 subCopyFieldToScreen(ClearPos, 0);
1462 printf("::: ---------------> %d, %d [%d, %d]\n",
1463 MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1466 if (dx2 == fiInfotron) // special case of infotron moving left or right
1473 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1474 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1477 X = GetStretchX(dxPos) + tDeltaX;
1478 Y = GetStretchY(dxPos) + tDeltaY;
1479 Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1480 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1488 tPos = dxPos + dx2Step;
1489 X = GetStretchX(tPos);
1490 Y = GetStretchY(tPos);
1491 if (dx2 == fiInfotron) // special case of infotron moving left or right
1493 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1495 else // pushing something
1497 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1501 // End of normal movement
1502 // ------------------------
1506 // ++++++++++++++++++++++++++++++++
1507 // Begin of split movement (port)
1509 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1510 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1512 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1513 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1515 subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1516 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1517 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1518 X = GetStretchX(dxPos) + tDeltaX;
1519 Y = GetStretchY(dxPos) + tDeltaY;
1520 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1521 tPos = dxPos + dx2Step;
1522 X = GetStretchX(tPos);
1523 Y = GetStretchY(tPos);
1524 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1525 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1526 // End of split movement (port)
1527 // ------------------------------
1528 } // loc_g_6D1E:'loc_g_6D28:
1530 SeqPos = SeqPos + 1;
1531 if (dx[SeqPos] > -1)
1532 return subAnimateMurphy;
1534 // Follow-up after movement completed 'loc_g_6D35:
1535 MurphyXPos = MurphyXPos + MurphyDX;
1536 MurphyYPos = MurphyYPos + MurphyDY;
1537 bl = HighByte(PlayField16[*si]); // animation phase
1538 MovHighByte(&PlayField16[*si], 0);
1540 if (bl == 0x1) // space, moving up
1543 if (bl == 0x2) // space, moving left
1546 if (bl == 0x3) // space, moving down
1549 if (bl == 0x4) // space, moving right
1552 if (bl == 0x5) // base , moving up
1555 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1558 if (bl == 0x7) // base , moving down
1561 if (bl == 0x8) // base , moving right
1564 if (bl == 0x9) // infotron, moving up
1567 if (bl == 0xA) // infotron, moving left
1570 if (bl == 0xB) // infotron, moving down
1573 if (bl == 0xC) // infotron, moving right
1576 if (bl == 0xD) // exit
1579 if (bl == 0xE) // zonk, pushing left
1582 if (bl == 0xF) // zonk, pushing right
1585 if (bl == 0x10) // base , touching up
1588 if (bl == 0x11) // base , touching left
1591 if (bl == 0x12) // base , touching down
1594 if (bl == 0x13) // base , touching right
1597 if (bl == 0x14) // infotron touching up
1600 if (bl == 0x15) // infotron touching left
1603 if (bl == 0x16) // infotron touching down
1606 if (bl == 0x17) // infotron touching right
1609 if (bl == 0x18) // port up
1612 if (bl == 0x19) // port left
1615 if (bl == 0x1A) // port down
1618 if (bl == 0x1B) // port right
1621 if (bl == 0x1C) // red disk, moving up
1624 if (bl == 0x1D) // red disk, moving left
1627 if (bl == 0x1E) // red disk, moving down
1630 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1633 if (bl == 0x20) // red disk, touching up
1636 if (bl == 0x21) // red disk, touching left
1639 if (bl == 0x22) // red disk, touching down
1642 if (bl == 0x23) // red disk, touching right
1645 if (bl == 0x24) // yellow disk, pushing up
1648 if (bl == 0x25) // yellow disk, pushing left
1651 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1654 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1657 if (bl == 0x28) // orange disk, pushing left
1660 if (bl == 0x29) // orange disk, pushing right
1663 if (bl == 0x2A) // red disk, release
1667 return subAnimateMurphy;
1669 // ==========================================================================
1670 // infotron, moving up
1671 // ==========================================================================
1674 if (0 < LowByte(InfotronsNeeded))
1675 InfotronsNeeded = InfotronsNeeded - 1;
1677 subDisplayInfotronsNeeded();
1678 loc_g_6EC8: // space, base
1679 PlayField16[*si] = fiMurphy;
1680 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1681 return subAnimateMurphy;
1683 // ==========================================================================
1684 // infotron, moving left
1685 // ==========================================================================
1688 if (0 < LowByte(InfotronsNeeded))
1689 InfotronsNeeded = InfotronsNeeded - 1;
1691 subDisplayInfotronsNeeded();
1692 loc_g_6EE6: // space, base
1693 PlayField16[*si] = fiMurphy;
1694 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1695 return subAnimateMurphy;
1697 // ==========================================================================
1698 // infotron, moving down
1699 // ==========================================================================
1702 if (0 < LowByte(InfotronsNeeded))
1703 InfotronsNeeded = InfotronsNeeded - 1;
1705 subDisplayInfotronsNeeded();
1706 loc_g_6F04: // space, base
1707 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1708 PlayField16[*si - FieldWidth] = 0;
1710 PlayField16[*si] = fiMurphy;
1711 return subAnimateMurphy;
1713 // ==========================================================================
1714 // infotron, moving right
1715 // ==========================================================================
1718 if (0 < LowByte(InfotronsNeeded))
1719 InfotronsNeeded = InfotronsNeeded - 1;
1721 subDisplayInfotronsNeeded();
1722 loc_g_71C4: // space, base
1723 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1724 PlayField16[*si] = fiMurphy;
1725 return subAnimateMurphy;
1727 // ==========================================================================
1728 // infotron, touching up
1729 // ==========================================================================
1732 if (0 < LowByte(InfotronsNeeded))
1733 InfotronsNeeded = InfotronsNeeded - 1;
1735 subDisplayInfotronsNeeded();
1737 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1738 PlayField16[*si - FieldWidth] = 0;
1740 return subAnimateMurphy;
1742 // ==========================================================================
1743 // infotron, touching left
1744 // ==========================================================================
1747 if (0 < LowByte(InfotronsNeeded))
1748 InfotronsNeeded = InfotronsNeeded - 1;
1750 subDisplayInfotronsNeeded();
1752 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1753 PlayField16[*si - 1] = 0;
1755 return subAnimateMurphy;
1757 // ==========================================================================
1758 // infotron, touching down
1759 // ==========================================================================
1762 if (0 < LowByte(InfotronsNeeded))
1763 InfotronsNeeded = InfotronsNeeded - 1;
1765 subDisplayInfotronsNeeded();
1767 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1768 PlayField16[*si + FieldWidth] = 0;
1770 return subAnimateMurphy;
1772 // ==========================================================================
1773 // infotron, touching right
1774 // ==========================================================================
1777 if (0 < LowByte(InfotronsNeeded))
1778 InfotronsNeeded = InfotronsNeeded - 1;
1780 subDisplayInfotronsNeeded();
1782 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1783 PlayField16[*si + 1] = 0;
1785 return subAnimateMurphy;
1787 // ==========================================================================
1788 // zonk, pushing left
1789 // ==========================================================================
1792 if (LowByte(PlayField16[*si]) != fiExplosion)
1793 PlayField16[*si] = 0;
1795 PlayField16[*si - 1] = fiMurphy;
1796 PlayField16[*si - 2] = fiZonk;
1797 subExplodeSnikSnaksBelow(*si - 2);
1799 return subAnimateMurphy;
1801 // ==========================================================================
1802 // zonk, pushing right
1803 // ==========================================================================
1806 if (LowByte(PlayField16[*si]) != fiExplosion)
1807 PlayField16[*si] = 0;
1809 PlayField16[*si + 1] = fiMurphy;
1810 PlayField16[*si + 2] = fiZonk;
1811 subExplodeSnikSnaksBelow(*si + 2);
1813 return subAnimateMurphy;
1815 // ==========================================================================
1817 // ==========================================================================
1821 return subAnimateMurphy;
1823 // ==========================================================================
1824 // Push Zonk from right to left
1825 // ==========================================================================
1828 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1829 return subAnimateMurphy;
1831 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1832 PlayField16[*si - 1] = fiZonk;
1833 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1834 PlayField16[*si - 2] = 0;
1836 subCopyFieldToScreen(*si, fiMurphy);
1837 return subAnimateMurphy;
1839 // ==========================================================================
1840 // Push Zonk from left to right
1841 // ==========================================================================
1844 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1845 return subAnimateMurphy;
1847 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1848 PlayField16[*si + 1] = fiZonk;
1849 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1850 PlayField16[*si + 2] = 0;
1852 subCopyFieldToScreen(*si, fiMurphy);
1853 return subAnimateMurphy;
1855 // ==========================================================================
1856 // Push orange disk from right to left
1857 // ==========================================================================
1860 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1861 return subAnimateMurphy;
1863 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1864 PlayField16[*si - 1] = fiOrangeDisk;
1865 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1866 PlayField16[*si - 2] = 0;
1868 subCopyFieldToScreen(*si, fiMurphy);
1869 return subAnimateMurphy;
1871 // ==========================================================================
1872 // Push orange disk from left to right
1873 // ==========================================================================
1876 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1877 return subAnimateMurphy;
1879 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1880 PlayField16[*si + 1] = fiOrangeDisk;
1881 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1882 PlayField16[*si + 2] = 0;
1884 subCopyFieldToScreen(*si, fiMurphy);
1885 return subAnimateMurphy;
1887 // ==========================================================================
1888 // Push yellow disk from down to up
1889 // ==========================================================================
1892 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1893 return subAnimateMurphy;
1895 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1896 PlayField16[*si - FieldWidth] = fiYellowDisk;
1897 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1898 PlayField16[*si - 2 * FieldWidth] = 0;
1900 subCopyFieldToScreen(*si, fiMurphy);
1901 return subAnimateMurphy;
1903 // ==========================================================================
1904 // Push yellow disk from right to left
1905 // ==========================================================================
1908 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1909 return subAnimateMurphy;
1911 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1912 PlayField16[*si - 1] = fiYellowDisk;
1913 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1914 PlayField16[*si - 2] = 0;
1916 subCopyFieldToScreen(*si, fiMurphy);
1917 return subAnimateMurphy;
1919 // ==========================================================================
1920 // Push yellow disk from up to down
1921 // ==========================================================================
1924 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1925 return subAnimateMurphy;
1927 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1928 PlayField16[*si + FieldWidth] = fiYellowDisk;
1929 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1930 PlayField16[*si + 2 * FieldWidth] = 0;
1932 subCopyFieldToScreen(*si, fiMurphy);
1933 return subAnimateMurphy;
1935 // ==========================================================================
1936 // Push yellow disk from left to right
1937 // ==========================================================================
1940 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1941 return subAnimateMurphy;
1943 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1944 PlayField16[*si + 1] = fiYellowDisk;
1945 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1946 PlayField16[*si + 2] = 0;
1948 subCopyFieldToScreen(*si, fiMurphy);
1949 return subAnimateMurphy;
1951 // ==========================================================================
1952 // time red disk release (space)
1953 // ==========================================================================
1956 if (DemoKeyCode != keySpace)
1958 PlayField16[*si] = fiMurphy;
1959 subCopyFieldToScreen(*si, fiMurphy);
1960 RedDiskReleasePhase = 0;
1962 else if (MovingPictureSequencePhase == 0x20)
1964 subCopyFieldToScreen(*si, 43); // anxious murphy
1965 RedDiskReleasePhase = 1;
1968 return subAnimateMurphy;
1970 // ==========================================================================
1971 // Special port down to up
1972 // ==========================================================================
1975 if (LowByte(PlayField16[*si]) != fiExplosion)
1976 PlayField16[*si] = 0;
1978 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1980 *si = *si - FieldWidth;
1981 if (HighByte(PlayField16[*si]) == 1)
1984 *si = *si - FieldWidth;
1985 return subAnimateMurphy;
1987 // ==========================================================================
1988 // Special port right to left
1989 // ==========================================================================
1992 if (LowByte(PlayField16[*si]) != fiExplosion)
1993 PlayField16[*si] = 0;
1995 PlayField16[*si - 2] = fiMurphy;
1998 if (HighByte(PlayField16[*si]) == 1)
2002 return subAnimateMurphy;
2004 // ==========================================================================
2005 // Special port up to down
2006 // ==========================================================================
2009 if (LowByte(PlayField16[*si]) != fiExplosion)
2010 PlayField16[*si] = 0;
2012 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2014 *si = *si + FieldWidth;
2015 if (HighByte(PlayField16[*si]) == 1)
2018 *si = *si + FieldWidth;
2019 return subAnimateMurphy;
2021 // ==========================================================================
2022 // Special port left to right
2023 // ==========================================================================
2026 if (LowByte(PlayField16[*si]) != fiExplosion)
2027 PlayField16[*si] = 0;
2029 PlayField16[*si + 2] = fiMurphy;
2032 if (HighByte(PlayField16[*si]) == 1)
2036 return subAnimateMurphy;
2038 // ==========================================================================
2040 // ==========================================================================
2043 if (LowByte(PlayField16[*si]) != fiExplosion)
2044 PlayField16[*si] = 0;
2046 *si = *si - FieldWidth;
2047 PlayField16[*si] = fiMurphy;
2048 subEatRedDisk(*si); // inc+show Murphy's red disks
2049 return subAnimateMurphy;
2051 // ==========================================================================
2052 // Move Red Disk left
2053 // ==========================================================================
2056 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2057 PlayField16[*si + 1] = 0;
2059 PlayField16[*si] = fiMurphy;
2060 subEatRedDisk(*si); // inc+show Murphy's red disks
2061 return subAnimateMurphy;
2063 // ==========================================================================
2064 // Move Red Disk down
2065 // ==========================================================================
2068 if (LowByte(PlayField16[*si]) != fiExplosion)
2069 PlayField16[*si] = 0;
2071 *si = *si + FieldWidth;
2072 PlayField16[*si] = fiMurphy;
2073 subEatRedDisk(*si); // inc+show Murphy's red disks
2074 return subAnimateMurphy;
2076 // ==========================================================================
2077 // Move Red Disk right
2078 // ==========================================================================
2081 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2082 PlayField16[*si - 1] = 0;
2084 PlayField16[*si] = fiMurphy;
2085 subEatRedDisk(*si); // inc+show Murphy's red disks
2086 return subAnimateMurphy;
2088 // ==========================================================================
2090 // ==========================================================================
2093 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2094 PlayField16[*si - FieldWidth] = 0;
2096 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2097 return subAnimateMurphy;
2099 // ==========================================================================
2100 // Eat Red Disk left
2101 // ==========================================================================
2104 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2105 PlayField16[*si - 1] = 0;
2107 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2108 return subAnimateMurphy;
2110 // ==========================================================================
2111 // Eat Red Disk down
2112 // ==========================================================================
2115 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2116 PlayField16[*si + FieldWidth] = 0;
2118 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2119 return subAnimateMurphy;
2121 // ==========================================================================
2122 // Eat Red Disk right
2123 // ==========================================================================
2126 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2127 PlayField16[*si + 1] = 0;
2129 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2130 return subAnimateMurphy;
2132 // ==========================================================================
2133 // yellow disk, pushing up
2134 // ==========================================================================
2137 if (LowByte(PlayField16[*si]) != fiExplosion)
2138 PlayField16[*si] = 0;
2140 *si = *si - FieldWidth;
2141 PlayField16[*si] = fiMurphy;
2142 PlayField16[*si - FieldWidth] = fiYellowDisk;
2143 return subAnimateMurphy;
2145 // ==========================================================================
2146 // yellow disk, pushing left
2147 // ==========================================================================
2150 if (LowByte(PlayField16[*si]) != fiExplosion)
2151 PlayField16[*si] = 0;
2154 PlayField16[*si] = fiMurphy;
2155 PlayField16[*si - 1] = fiYellowDisk;
2156 return subAnimateMurphy;
2158 // ==========================================================================
2159 // yellow disk, pushing down
2160 // ==========================================================================
2163 if (LowByte(PlayField16[*si]) != fiExplosion)
2164 PlayField16[*si] = 0;
2166 *si = *si + FieldWidth;
2167 PlayField16[*si] = fiMurphy;
2168 PlayField16[*si + FieldWidth] = fiYellowDisk;
2169 return subAnimateMurphy;
2171 // ==========================================================================
2172 // yellow disk pushing right
2173 // ==========================================================================
2176 if (LowByte(PlayField16[*si]) != fiExplosion)
2177 PlayField16[*si] = 0;
2180 PlayField16[*si] = fiMurphy;
2181 PlayField16[*si + 1] = fiYellowDisk;
2182 return subAnimateMurphy;
2184 // ==========================================================================
2185 // orange disk, pushing left
2186 // ==========================================================================
2189 if (LowByte(PlayField16[*si]) != fiExplosion)
2190 PlayField16[*si] = 0;
2193 PlayField16[*si] = fiMurphy;
2194 PlayField16[*si - 1] = fiOrangeDisk;
2195 return subAnimateMurphy;
2197 // ==========================================================================
2198 // orange disk, pushing right
2199 // ==========================================================================
2202 if (LowByte(PlayField16[*si]) != fiExplosion)
2203 PlayField16[*si] = 0;
2206 PlayField16[*si] = fiMurphy;
2207 PlayField16[*si + 1] = fiOrangeDisk;
2208 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2210 MovHighByte(&PlayField16[*si + 1], 0x20);
2211 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2214 return subAnimateMurphy;
2216 // ==========================================================================
2217 // Release a red disk
2218 // ==========================================================================
2221 PlayField16[*si] = fiMurphy;
2222 RedDiskReleasePhase = 2;
2223 RedDiskCount = RedDiskCount - 1;
2224 subDisplayRedDiskCount();
2225 subSoundFXPush(); // Sound effects
2227 return subAnimateMurphy;
2228 } // subAnimateMurphy
2230 // ==========================================================================
2232 // ==========================================================================
2233 int subExplodeSnikSnaksBelow(int si)
2235 int subExplodeSnikSnaksBelow;
2239 ax = LowByte(PlayField16[si + FieldWidth]);
2240 if (ax == 0x11 || ax == 0xBB)
2241 ExplodeFieldSP(si + FieldWidth);
2243 return subExplodeSnikSnaksBelow;
2244 } // subExplodeSnikSnaksBelow
2246 // ==========================================================================
2248 // Does pushing against an object kill Murphy?
2249 // ==========================================================================
2250 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2252 static boolean subMoveKillsMurphy;
2258 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2264 if (al == fiExplosion)
2267 if (fiOrangeDisk <= al && al <= fiPortUp)
2270 ExplodeFieldSP(si); // Explode
2271 subMoveKillsMurphy = True;
2272 return subMoveKillsMurphy;
2281 ExplodeFieldSP(si); // Explode
2282 subMoveKillsMurphy = True;
2283 return subMoveKillsMurphy;
2285 loc_g_74F6: // zonk left
2287 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2290 subMoveKillsMurphy = True; // Set carry flag
2291 return subMoveKillsMurphy;
2293 loc_g_7512: // zonk right
2295 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2298 loc_g_752E: // Marked fields and Ports
2299 subMoveKillsMurphy = True; // Set carry flag
2300 return subMoveKillsMurphy;
2302 loc_g_7530: // explosion
2303 if ((ah & 0x80) != 0)
2310 ExplodeFieldSP(si); // Explode
2311 subMoveKillsMurphy = True; // Set carry flag
2312 return subMoveKillsMurphy;
2315 PlayField16[si] = 0;
2316 subMoveKillsMurphy = False;
2318 return subMoveKillsMurphy;
2319 } // subMoveKillsMurphy
2321 // ==========================================================================
2323 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2324 // change conditions to port specs
2325 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2326 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2327 // ==========================================================================
2328 int subSpPortTest(int si)
2335 cx = LInfo.SpecialPortCount; // number of special ports
2337 for (i = 0; i < cx; i++)
2340 /* this assumes that PortLocation is stored as big endian */
2341 bx = LInfo.SpecialPort[i].PortLocation;
2343 /* this assumes that PortLocation is stored as little endian */
2344 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2345 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2350 GravityFlag = LInfo.SpecialPort[i].Gravity;
2351 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2352 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2354 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2362 cx = LInfo.SpecialPortCount; // number of special ports
2363 for (i = 1; i <= cx; i++)
2366 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2367 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2370 GravityFlag = LInfo.SpecialPort[i].Gravity;
2371 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2372 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2373 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2380 return subSpPortTest;
2383 void subCopyFieldToScreen(int si, int fi)
2387 // +++++++++++++++++++++++++++++++++++++++++
2388 X = GetStretchX(si);
2389 Y = GetStretchY(si);
2390 StretchedSprites.BltEx(X, Y, fi);
2391 // +++++++++++++++++++++++++++++++++++++++++
2394 static void subEatRedDisk(int si)
2396 if (AllowRedDiskCheat == 0)
2398 if (RedDiskReleasePhase != 0)
2400 if (RedDiskReleaseMurphyPos == si)
2405 RedDiskCount = (RedDiskCount + 1) % 256;
2406 subDisplayRedDiskCount();
2409 int subAdjustZonksInfotronsAboveMurphy(int si)
2411 int subAdjustZonksInfotronsAboveMurphy;
2415 if (LowByte(PlayField16[si]) != fiExplosion)
2416 PlayField16[si] = 0;
2418 ax = PlayField16[si - FieldWidth];
2419 if (ax == 0 || ax == 0x9999)
2422 if (ax == fiZonk || ax == fiInfotron)
2424 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2427 return subAdjustZonksInfotronsAboveMurphy;
2429 loc_g_15A8: // empty above
2430 ax = PlayField16[si - FieldWidth - 1];
2431 if (ax == fiZonk || ax == fiInfotron)
2435 ax = PlayField16[si - FieldWidth + 1];
2436 if (ax == fiZonk || ax == fiInfotron)
2439 return subAdjustZonksInfotronsAboveMurphy;
2441 loc_g_15C5: // zonk/infotron above left
2442 ax = PlayField16[si - 1];
2443 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2446 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2447 PlayField16[si - FieldWidth] = 0x8888;
2448 return subAdjustZonksInfotronsAboveMurphy;
2450 loc_g_15E8: // zonk/infotron above right
2451 ax = PlayField16[si + 1];
2452 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2454 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2455 PlayField16[si - FieldWidth] = 0x8888;
2458 return subAdjustZonksInfotronsAboveMurphy;
2459 } // subAdjustZonksInfotronsAboveMurphy