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);
940 game_sp_info.LevelSolved = TRUE;
944 data_h_DemoDone = 1; // EP set level success bytes
945 LevelStatus = 1; // set Level Status DONE
946 EP_GameDemoVar0DAA = 0; // force demo for lead-out
947 if (SavedGameFlag == 0) // saved game running?
949 if (UpdateTimeFlag != 0) // update time?
951 UpdatedFlag = 1; // prevent double update
952 subUpdatePlayingTime(); // update playing time
957 subUpdateHallOfFame(); // update time + Hall-Of-Fame
960 LeadOutCounter = 0x40; // quit: start lead-out
962 MovHighByte(&PlayField16[*si], 0xD);
963 goto loc_StopNoSplit;
965 // ==========================================================================
966 // ZONK moving right to left
967 // ==========================================================================
970 ax = PlayField16[*si - 2];
972 return subAnimateMurphy;
974 MovHighByte(&PlayField16[*si - 2], 1);
975 subCopyFieldToScreen(*si, aniPushLeft); // draw pushing murphy
976 dx = aniZonkRollLeft;
980 MovHighByte(&PlayField16[*si], 0xE);
981 goto loc_MoveNoSplit;
983 // ==========================================================================
984 // ZONK moving left to right
985 // ==========================================================================
988 ax = PlayField16[*si + 2];
990 return subAnimateMurphy;
992 ax = PlayField16[*si + FieldWidth + 1];
993 if (ax == 0) // zonk falls
994 return subAnimateMurphy;
996 MovHighByte(&PlayField16[*si + 2], 1);
997 subCopyFieldToScreen(*si, aniPushRight); // draw pushing murphy
998 dx = aniZonkRollRight;
1002 MovHighByte(&PlayField16[*si], 0xF);
1003 goto loc_MoveNoSplit;
1005 // ==========================================================================
1006 // TERMINAL moving/touching down to up
1007 // ==========================================================================
1010 subCopyFieldToScreen(*si, aniMurphyTouchUp);
1011 if (YellowDisksExploded != 0)
1013 YawnSleepCounter = 10; // stay hypnotized
1014 return subAnimateMurphy;
1017 subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1018 TerminalState[*si - FieldWidth] = 8;
1021 // ==========================================================================
1022 // TERMINAL moving/touching right to left
1023 // ==========================================================================
1026 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
1027 if (YellowDisksExploded != 0)
1029 YawnSleepCounter = 10; // stay hypnotized
1030 return subAnimateMurphy;
1033 subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1034 TerminalState[*si - 1] = 8;
1037 // ==========================================================================
1038 // TERMINAL moving/touching up to down
1039 // ==========================================================================
1042 subCopyFieldToScreen(*si, aniMurphyTouchDown);
1043 if (YellowDisksExploded != 0)
1045 YawnSleepCounter = 10; // stay hypnotized
1046 return subAnimateMurphy;
1049 subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1050 TerminalState[*si + FieldWidth] = 8;
1053 // ==========================================================================
1054 // TERMINAL moving/touching left to right
1055 // ==========================================================================
1058 subCopyFieldToScreen(*si, aniMurphyTouchRight);
1059 if (YellowDisksExploded != 0)
1061 YawnSleepCounter = 10; // stay hypnotized
1062 return subAnimateMurphy;
1065 subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1066 TerminalState[*si + 1] = 8;
1067 // ==========================================================================
1068 // common TERMINAL stuff moving/touching from all directions
1069 // ==========================================================================
1072 TerminalMaxCycles = 7;
1073 YellowDisksExploded = 1;
1074 for (i = 0; i <= LevelMax; i++)
1076 if (PlayField16[i] == fiYellowDisk)
1080 return subAnimateMurphy;
1082 // ==========================================================================
1083 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1084 // ==========================================================================
1087 if (PlayField16[*si - 2 * FieldWidth] != 0)
1088 return subAnimateMurphy;
1090 dx = aniSplitUpDown;
1091 dx2Step = -FieldWidth;
1092 PlayField16[*si] = 0x1803;
1093 PlayField16[*si - 2 * FieldWidth] = 0x300;
1096 // ==========================================================================
1097 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1098 // ==========================================================================
1101 if (PlayField16[*si - 2] != 0)
1102 return subAnimateMurphy;
1104 dx = aniMurphyEatLeft;
1106 PlayField16[*si] = 0x1903;
1107 PlayField16[*si - 2] = 0x300;
1110 // ==========================================================================
1111 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1112 // ==========================================================================
1115 if (PlayField16[*si + 2 * FieldWidth] != 0)
1116 return subAnimateMurphy;
1118 dx = aniSplitUpDown;
1119 dx2Step = FieldWidth;
1120 PlayField16[*si] = 0x1A03;
1121 PlayField16[*si + 2 * FieldWidth] = 0x300;
1124 // ==========================================================================
1125 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1126 // ==========================================================================
1129 if (PlayField16[*si + 2] != 0)
1130 return subAnimateMurphy;
1132 dx = aniMurphyEatRight;
1134 PlayField16[*si] = 0x1B03;
1135 PlayField16[*si + 2] = 0x300;
1138 MovingPictureSequencePhase = 0; // stop picture move sequence
1139 SplitMoveFlag = 1; // port: split movement
1142 // ==========================================================================
1143 // RED DISK moving down to up
1144 // ==========================================================================
1147 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1148 PlayField16[*si] = 0x1C03;
1149 PlayField16[*si - FieldWidth] = 0x300;
1150 goto loc_StopNoSplit;
1152 // ==========================================================================
1153 // RED DISK moving right to left
1154 // ==========================================================================
1157 dx = aniMurphyEatLeft;
1158 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1159 PlayField16[*si - 1] = 0x1D03;
1161 goto loc_StopNoSplit;
1163 // ==========================================================================
1164 // RED DISK moving up to down
1165 // ==========================================================================
1168 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1169 PlayField16[*si] = 0x1E03;
1170 PlayField16[*si + FieldWidth] = 0x300;
1171 goto loc_StopNoSplit;
1173 // ==========================================================================
1174 // RED DISK moving left to right
1175 // ==========================================================================
1178 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1179 dx = aniMurphyEatRight;
1180 // --------------------------------------------------------------------------
1182 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1183 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1184 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1185 // We may not fix the table, because then the timing of the game changes
1186 // and several existing demo's do not run properly anymore.
1187 // We only correct Murphies x-location here, when the sequence starts.
1188 // Remember that this is not the real bug-fix, but we must live with
1189 // this existing bug and correct for the consequences of it.
1192 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1193 MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1195 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1196 MurphyScreenXPos = MurphyScreenXPos - 2;
1200 // FS: for me this means to blit the first animation frame twice
1202 // --------------------------------------------------------------------------
1203 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1204 PlayField16[*si + 1] = 0x1F03;
1206 goto loc_StopNoSplit;
1208 // ==========================================================================
1209 // RED DISK touching down to up
1210 // ==========================================================================
1213 dx = aniTouchRedDisk;
1214 MovHighByte(&PlayField16[*si], 0x20);
1215 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1216 goto loc_StopNoSplit;
1218 // ==========================================================================
1219 // RED DISK touching right to left
1220 // ==========================================================================
1223 dx = aniTouchRedDisk;
1224 MovHighByte(&PlayField16[*si], 0x21);
1225 MovHighByte(&PlayField16[*si - 1], 3);
1226 goto loc_StopNoSplit;
1228 // ==========================================================================
1229 // RED DISK touching up to down
1230 // ==========================================================================
1233 dx = aniTouchRedDisk;
1234 MovHighByte(&PlayField16[*si], 0x22);
1235 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1236 goto loc_StopNoSplit;
1238 // ==========================================================================
1239 // RED DISK touching left to right
1240 // ==========================================================================
1243 dx = aniTouchRedDisk;
1244 MovHighByte(&PlayField16[*si], 0x23);
1245 MovHighByte(&PlayField16[*si + 1], 3);
1248 MovingPictureSequencePhase = 0; // stop picture move sequence
1251 // ==========================================================================
1252 // YELLOW DISK moving down to up
1253 // ==========================================================================
1256 if (PlayField16[*si - 2 * FieldWidth] != 0)
1257 return subAnimateMurphy;
1259 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1260 subCopyFieldToScreen(*si, aniPushRight);
1262 dxPos = *si - FieldWidth;
1263 dx2 = aniPushUpDown;
1264 dx2Step = FieldWidth;
1265 PlayField16[*si] = 0x2403;
1266 goto loc_MoveNoSplit;
1268 // ==========================================================================
1269 // YELLOW DISK moving right to left
1270 // ==========================================================================
1273 if (PlayField16[*si - 2] != 0)
1274 return subAnimateMurphy;
1276 PlayField16[*si - 2] = 0x1200;
1277 subCopyFieldToScreen(*si, aniPushLeft);
1282 PlayField16[*si] = 0x2503;
1283 goto loc_MoveNoSplit;
1285 // ==========================================================================
1286 // YELLOW DISK moving up to down
1287 // ==========================================================================
1290 if (PlayField16[*si + 2 * FieldWidth] != 0)
1291 return subAnimateMurphy;
1293 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1294 subCopyFieldToScreen(*si, aniPushRight);
1296 dxPos = *si + FieldWidth;
1297 dx2 = aniPushUpDown;
1298 dx2Step = -FieldWidth;
1299 PlayField16[*si] = 0x2703;
1300 goto loc_MoveNoSplit;
1302 // ==========================================================================
1303 // YELLOW DISK moving left to right
1304 // ==========================================================================
1307 if (PlayField16[*si + 2] != 0)
1308 return subAnimateMurphy;
1310 PlayField16[*si + 2] = 0x1200;
1311 subCopyFieldToScreen(*si, aniPushRight);
1316 PlayField16[*si] = 0x2603;
1317 goto loc_MoveNoSplit;
1319 // ==========================================================================
1320 // ORANGE DISK moving right to left
1321 // ==========================================================================
1324 if (PlayField16[*si - 2] != 0)
1325 return subAnimateMurphy;
1327 PlayField16[*si - 2] = 0x800;
1328 subCopyFieldToScreen(*si, aniPushLeft);
1333 PlayField16[*si] = 0x2803;
1334 goto loc_MoveNoSplit;
1336 // ==========================================================================
1337 // ORANGE DISK moving left to right
1338 // ==========================================================================
1341 if (PlayField16[*si + 2] != 0)
1342 return subAnimateMurphy;
1344 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1345 return subAnimateMurphy;
1347 PlayField16[*si + 2] = 0x100;
1348 subCopyFieldToScreen(*si, aniPushRight);
1353 PlayField16[*si] = 0x2903;
1354 // ==========================================================================
1355 // Copy screen animation action table to action work space
1356 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1357 // ==========================================================================
1360 MovingPictureSequencePhase = 8; // init picture move sequence
1363 SplitMoveFlag = 0; // no port: no split movement
1366 // copy/store global move sequence info????????????????????????????????????
1367 // ... dont think so ...(FS)
1368 // ==========================================================================
1369 // Proceed with all movements
1370 // ==========================================================================
1372 locProceedMovingMurphy: // proceed moving murphy
1373 YawnSleepCounter = 0; // Wake up sleeping Murphy
1374 ax = MovingPictureSequencePhase; // sequence busy?
1375 if (ax == 0) // no -- start sequence!
1378 ax = ax - 1; // next picture of sequence
1379 MovingPictureSequencePhase = ax; // store for later
1380 if (ax == 0) // Sound effects
1383 bl = HighByte(PlayField16[*si]);
1384 if (bl == 0xE) // Push Zonk to left
1387 if (bl == 0xF) // Push Zonk to right
1390 if (bl == 0x28) // Push orange disk to left
1393 if (bl == 0x29) // Push orange disk to right
1396 if (bl == 0x24) // Push yellow disk up
1399 if (bl == 0x25) // Push yellow disk to left
1402 if (bl == 0x27) // Push yellow disk down
1405 if (bl == 0x26) // Push yellow disk to right
1408 if (bl == 0x2A) // Red disk release timer
1411 return subAnimateMurphy;
1413 // ==========================================================================
1414 // Paint frame of MOVING.DAT sequence
1415 // ==========================================================================
1418 if (SplitMoveFlag == 0)
1420 // ++++++++++++++++++++++++++
1421 // Begin of normal movement
1423 MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1424 MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1426 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1427 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1432 printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1434 DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1435 (DemoKeyCode == keyNone ? "(none)" :
1436 DemoKeyCode == keyLeft ? "left" :
1437 DemoKeyCode == keyRight ? "right" :
1438 DemoKeyCode == keyUp ? "up" :
1439 DemoKeyCode == keyDown ? "down" :
1440 DemoKeyCode == keySpace ? "space" :
1441 DemoKeyCode == keySpaceLeft ? "space + left" :
1442 DemoKeyCode == keySpaceRight ? "space + right" :
1443 DemoKeyCode == keySpaceUp ? "space + up" :
1444 DemoKeyCode == keySpaceDown ? "space + down" : "(unknown)"),
1446 MurphyScreenXPos, MurphyScreenYPos,
1447 MurphyPosIndex % 60, MurphyPosIndex / 60,
1456 if (!(ClearPos < 0)) // clear field that murphy is leaving
1457 subCopyFieldToScreen(ClearPos, 0);
1459 if (! ClearPos < 0) // clear field that murphy is leaving
1460 subCopyFieldToScreen(ClearPos, 0);
1464 printf("::: ---------------> %d, %d [%d, %d]\n",
1465 MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1468 if (dx2 == fiInfotron) // special case of infotron moving left or right
1475 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1476 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1479 X = GetStretchX(dxPos) + tDeltaX;
1480 Y = GetStretchY(dxPos) + tDeltaY;
1481 Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1482 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1490 tPos = dxPos + dx2Step;
1491 X = GetStretchX(tPos);
1492 Y = GetStretchY(tPos);
1493 if (dx2 == fiInfotron) // special case of infotron moving left or right
1495 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1497 else // pushing something
1499 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1503 // End of normal movement
1504 // ------------------------
1508 // ++++++++++++++++++++++++++++++++
1509 // Begin of split movement (port)
1511 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1512 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1514 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1515 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1517 subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1518 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1519 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1520 X = GetStretchX(dxPos) + tDeltaX;
1521 Y = GetStretchY(dxPos) + tDeltaY;
1522 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1523 tPos = dxPos + dx2Step;
1524 X = GetStretchX(tPos);
1525 Y = GetStretchY(tPos);
1526 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1527 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1528 // End of split movement (port)
1529 // ------------------------------
1530 } // loc_g_6D1E:'loc_g_6D28:
1532 SeqPos = SeqPos + 1;
1533 if (dx[SeqPos] > -1)
1534 return subAnimateMurphy;
1536 // Follow-up after movement completed 'loc_g_6D35:
1537 MurphyXPos = MurphyXPos + MurphyDX;
1538 MurphyYPos = MurphyYPos + MurphyDY;
1539 bl = HighByte(PlayField16[*si]); // animation phase
1540 MovHighByte(&PlayField16[*si], 0);
1542 if (bl == 0x1) // space, moving up
1545 if (bl == 0x2) // space, moving left
1548 if (bl == 0x3) // space, moving down
1551 if (bl == 0x4) // space, moving right
1554 if (bl == 0x5) // base , moving up
1557 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1560 if (bl == 0x7) // base , moving down
1563 if (bl == 0x8) // base , moving right
1566 if (bl == 0x9) // infotron, moving up
1569 if (bl == 0xA) // infotron, moving left
1572 if (bl == 0xB) // infotron, moving down
1575 if (bl == 0xC) // infotron, moving right
1578 if (bl == 0xD) // exit
1581 if (bl == 0xE) // zonk, pushing left
1584 if (bl == 0xF) // zonk, pushing right
1587 if (bl == 0x10) // base , touching up
1590 if (bl == 0x11) // base , touching left
1593 if (bl == 0x12) // base , touching down
1596 if (bl == 0x13) // base , touching right
1599 if (bl == 0x14) // infotron touching up
1602 if (bl == 0x15) // infotron touching left
1605 if (bl == 0x16) // infotron touching down
1608 if (bl == 0x17) // infotron touching right
1611 if (bl == 0x18) // port up
1614 if (bl == 0x19) // port left
1617 if (bl == 0x1A) // port down
1620 if (bl == 0x1B) // port right
1623 if (bl == 0x1C) // red disk, moving up
1626 if (bl == 0x1D) // red disk, moving left
1629 if (bl == 0x1E) // red disk, moving down
1632 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1635 if (bl == 0x20) // red disk, touching up
1638 if (bl == 0x21) // red disk, touching left
1641 if (bl == 0x22) // red disk, touching down
1644 if (bl == 0x23) // red disk, touching right
1647 if (bl == 0x24) // yellow disk, pushing up
1650 if (bl == 0x25) // yellow disk, pushing left
1653 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1656 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1659 if (bl == 0x28) // orange disk, pushing left
1662 if (bl == 0x29) // orange disk, pushing right
1665 if (bl == 0x2A) // red disk, release
1669 return subAnimateMurphy;
1671 // ==========================================================================
1672 // infotron, moving up
1673 // ==========================================================================
1676 if (0 < LowByte(InfotronsNeeded))
1677 InfotronsNeeded = InfotronsNeeded - 1;
1679 subDisplayInfotronsNeeded();
1680 loc_g_6EC8: // space, base
1681 PlayField16[*si] = fiMurphy;
1682 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1683 return subAnimateMurphy;
1685 // ==========================================================================
1686 // infotron, moving left
1687 // ==========================================================================
1690 if (0 < LowByte(InfotronsNeeded))
1691 InfotronsNeeded = InfotronsNeeded - 1;
1693 subDisplayInfotronsNeeded();
1694 loc_g_6EE6: // space, base
1695 PlayField16[*si] = fiMurphy;
1696 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1697 return subAnimateMurphy;
1699 // ==========================================================================
1700 // infotron, moving down
1701 // ==========================================================================
1704 if (0 < LowByte(InfotronsNeeded))
1705 InfotronsNeeded = InfotronsNeeded - 1;
1707 subDisplayInfotronsNeeded();
1708 loc_g_6F04: // space, base
1709 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1710 PlayField16[*si - FieldWidth] = 0;
1712 PlayField16[*si] = fiMurphy;
1713 return subAnimateMurphy;
1715 // ==========================================================================
1716 // infotron, moving right
1717 // ==========================================================================
1720 if (0 < LowByte(InfotronsNeeded))
1721 InfotronsNeeded = InfotronsNeeded - 1;
1723 subDisplayInfotronsNeeded();
1724 loc_g_71C4: // space, base
1725 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1726 PlayField16[*si] = fiMurphy;
1727 return subAnimateMurphy;
1729 // ==========================================================================
1730 // infotron, touching up
1731 // ==========================================================================
1734 if (0 < LowByte(InfotronsNeeded))
1735 InfotronsNeeded = InfotronsNeeded - 1;
1737 subDisplayInfotronsNeeded();
1739 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1740 PlayField16[*si - FieldWidth] = 0;
1742 return subAnimateMurphy;
1744 // ==========================================================================
1745 // infotron, touching left
1746 // ==========================================================================
1749 if (0 < LowByte(InfotronsNeeded))
1750 InfotronsNeeded = InfotronsNeeded - 1;
1752 subDisplayInfotronsNeeded();
1754 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1755 PlayField16[*si - 1] = 0;
1757 return subAnimateMurphy;
1759 // ==========================================================================
1760 // infotron, touching down
1761 // ==========================================================================
1764 if (0 < LowByte(InfotronsNeeded))
1765 InfotronsNeeded = InfotronsNeeded - 1;
1767 subDisplayInfotronsNeeded();
1769 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1770 PlayField16[*si + FieldWidth] = 0;
1772 return subAnimateMurphy;
1774 // ==========================================================================
1775 // infotron, touching right
1776 // ==========================================================================
1779 if (0 < LowByte(InfotronsNeeded))
1780 InfotronsNeeded = InfotronsNeeded - 1;
1782 subDisplayInfotronsNeeded();
1784 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1785 PlayField16[*si + 1] = 0;
1787 return subAnimateMurphy;
1789 // ==========================================================================
1790 // zonk, pushing left
1791 // ==========================================================================
1794 if (LowByte(PlayField16[*si]) != fiExplosion)
1795 PlayField16[*si] = 0;
1797 PlayField16[*si - 1] = fiMurphy;
1798 PlayField16[*si - 2] = fiZonk;
1799 subExplodeSnikSnaksBelow(*si - 2);
1801 return subAnimateMurphy;
1803 // ==========================================================================
1804 // zonk, pushing right
1805 // ==========================================================================
1808 if (LowByte(PlayField16[*si]) != fiExplosion)
1809 PlayField16[*si] = 0;
1811 PlayField16[*si + 1] = fiMurphy;
1812 PlayField16[*si + 2] = fiZonk;
1813 subExplodeSnikSnaksBelow(*si + 2);
1815 return subAnimateMurphy;
1817 // ==========================================================================
1819 // ==========================================================================
1825 PlayField16[*si] = fiSpace; // remove Murphy from playfield after exiting
1828 return subAnimateMurphy;
1830 // ==========================================================================
1831 // Push Zonk from right to left
1832 // ==========================================================================
1835 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1836 return subAnimateMurphy;
1838 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1839 PlayField16[*si - 1] = fiZonk;
1840 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1841 PlayField16[*si - 2] = 0;
1843 subCopyFieldToScreen(*si, fiMurphy);
1844 return subAnimateMurphy;
1846 // ==========================================================================
1847 // Push Zonk from left to right
1848 // ==========================================================================
1851 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1852 return subAnimateMurphy;
1854 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1855 PlayField16[*si + 1] = fiZonk;
1856 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1857 PlayField16[*si + 2] = 0;
1859 subCopyFieldToScreen(*si, fiMurphy);
1860 return subAnimateMurphy;
1862 // ==========================================================================
1863 // Push orange disk from right to left
1864 // ==========================================================================
1867 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1868 return subAnimateMurphy;
1870 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1871 PlayField16[*si - 1] = fiOrangeDisk;
1872 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1873 PlayField16[*si - 2] = 0;
1875 subCopyFieldToScreen(*si, fiMurphy);
1876 return subAnimateMurphy;
1878 // ==========================================================================
1879 // Push orange disk from left to right
1880 // ==========================================================================
1883 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1884 return subAnimateMurphy;
1886 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1887 PlayField16[*si + 1] = fiOrangeDisk;
1888 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1889 PlayField16[*si + 2] = 0;
1891 subCopyFieldToScreen(*si, fiMurphy);
1892 return subAnimateMurphy;
1894 // ==========================================================================
1895 // Push yellow disk from down to up
1896 // ==========================================================================
1899 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1900 return subAnimateMurphy;
1902 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1903 PlayField16[*si - FieldWidth] = fiYellowDisk;
1904 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1905 PlayField16[*si - 2 * FieldWidth] = 0;
1907 subCopyFieldToScreen(*si, fiMurphy);
1908 return subAnimateMurphy;
1910 // ==========================================================================
1911 // Push yellow disk from right to left
1912 // ==========================================================================
1915 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1916 return subAnimateMurphy;
1918 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1919 PlayField16[*si - 1] = fiYellowDisk;
1920 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1921 PlayField16[*si - 2] = 0;
1923 subCopyFieldToScreen(*si, fiMurphy);
1924 return subAnimateMurphy;
1926 // ==========================================================================
1927 // Push yellow disk from up to down
1928 // ==========================================================================
1931 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1932 return subAnimateMurphy;
1934 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1935 PlayField16[*si + FieldWidth] = fiYellowDisk;
1936 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1937 PlayField16[*si + 2 * FieldWidth] = 0;
1939 subCopyFieldToScreen(*si, fiMurphy);
1940 return subAnimateMurphy;
1942 // ==========================================================================
1943 // Push yellow disk from left to right
1944 // ==========================================================================
1947 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1948 return subAnimateMurphy;
1950 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1951 PlayField16[*si + 1] = fiYellowDisk;
1952 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1953 PlayField16[*si + 2] = 0;
1955 subCopyFieldToScreen(*si, fiMurphy);
1956 return subAnimateMurphy;
1958 // ==========================================================================
1959 // time red disk release (space)
1960 // ==========================================================================
1963 if (DemoKeyCode != keySpace)
1965 PlayField16[*si] = fiMurphy;
1966 subCopyFieldToScreen(*si, fiMurphy);
1967 RedDiskReleasePhase = 0;
1969 else if (MovingPictureSequencePhase == 0x20)
1971 subCopyFieldToScreen(*si, 43); // anxious murphy
1972 RedDiskReleasePhase = 1;
1975 return subAnimateMurphy;
1977 // ==========================================================================
1978 // Special port down to up
1979 // ==========================================================================
1982 if (LowByte(PlayField16[*si]) != fiExplosion)
1983 PlayField16[*si] = 0;
1985 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1987 *si = *si - FieldWidth;
1988 if (HighByte(PlayField16[*si]) == 1)
1991 *si = *si - FieldWidth;
1992 return subAnimateMurphy;
1994 // ==========================================================================
1995 // Special port right to left
1996 // ==========================================================================
1999 if (LowByte(PlayField16[*si]) != fiExplosion)
2000 PlayField16[*si] = 0;
2002 PlayField16[*si - 2] = fiMurphy;
2005 if (HighByte(PlayField16[*si]) == 1)
2009 return subAnimateMurphy;
2011 // ==========================================================================
2012 // Special port up to down
2013 // ==========================================================================
2016 if (LowByte(PlayField16[*si]) != fiExplosion)
2017 PlayField16[*si] = 0;
2019 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2021 *si = *si + FieldWidth;
2022 if (HighByte(PlayField16[*si]) == 1)
2025 *si = *si + FieldWidth;
2026 return subAnimateMurphy;
2028 // ==========================================================================
2029 // Special port left to right
2030 // ==========================================================================
2033 if (LowByte(PlayField16[*si]) != fiExplosion)
2034 PlayField16[*si] = 0;
2036 PlayField16[*si + 2] = fiMurphy;
2039 if (HighByte(PlayField16[*si]) == 1)
2043 return subAnimateMurphy;
2045 // ==========================================================================
2047 // ==========================================================================
2050 if (LowByte(PlayField16[*si]) != fiExplosion)
2051 PlayField16[*si] = 0;
2053 *si = *si - FieldWidth;
2054 PlayField16[*si] = fiMurphy;
2055 subEatRedDisk(*si); // inc+show Murphy's red disks
2056 return subAnimateMurphy;
2058 // ==========================================================================
2059 // Move Red Disk left
2060 // ==========================================================================
2063 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2064 PlayField16[*si + 1] = 0;
2066 PlayField16[*si] = fiMurphy;
2067 subEatRedDisk(*si); // inc+show Murphy's red disks
2068 return subAnimateMurphy;
2070 // ==========================================================================
2071 // Move Red Disk down
2072 // ==========================================================================
2075 if (LowByte(PlayField16[*si]) != fiExplosion)
2076 PlayField16[*si] = 0;
2078 *si = *si + FieldWidth;
2079 PlayField16[*si] = fiMurphy;
2080 subEatRedDisk(*si); // inc+show Murphy's red disks
2081 return subAnimateMurphy;
2083 // ==========================================================================
2084 // Move Red Disk right
2085 // ==========================================================================
2088 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2089 PlayField16[*si - 1] = 0;
2091 PlayField16[*si] = fiMurphy;
2092 subEatRedDisk(*si); // inc+show Murphy's red disks
2093 return subAnimateMurphy;
2095 // ==========================================================================
2097 // ==========================================================================
2100 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2101 PlayField16[*si - FieldWidth] = 0;
2103 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2104 return subAnimateMurphy;
2106 // ==========================================================================
2107 // Eat Red Disk left
2108 // ==========================================================================
2111 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2112 PlayField16[*si - 1] = 0;
2114 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2115 return subAnimateMurphy;
2117 // ==========================================================================
2118 // Eat Red Disk down
2119 // ==========================================================================
2122 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2123 PlayField16[*si + FieldWidth] = 0;
2125 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2126 return subAnimateMurphy;
2128 // ==========================================================================
2129 // Eat Red Disk right
2130 // ==========================================================================
2133 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2134 PlayField16[*si + 1] = 0;
2136 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2137 return subAnimateMurphy;
2139 // ==========================================================================
2140 // yellow disk, pushing up
2141 // ==========================================================================
2144 if (LowByte(PlayField16[*si]) != fiExplosion)
2145 PlayField16[*si] = 0;
2147 *si = *si - FieldWidth;
2148 PlayField16[*si] = fiMurphy;
2149 PlayField16[*si - FieldWidth] = fiYellowDisk;
2150 return subAnimateMurphy;
2152 // ==========================================================================
2153 // yellow disk, pushing left
2154 // ==========================================================================
2157 if (LowByte(PlayField16[*si]) != fiExplosion)
2158 PlayField16[*si] = 0;
2161 PlayField16[*si] = fiMurphy;
2162 PlayField16[*si - 1] = fiYellowDisk;
2163 return subAnimateMurphy;
2165 // ==========================================================================
2166 // yellow disk, pushing down
2167 // ==========================================================================
2170 if (LowByte(PlayField16[*si]) != fiExplosion)
2171 PlayField16[*si] = 0;
2173 *si = *si + FieldWidth;
2174 PlayField16[*si] = fiMurphy;
2175 PlayField16[*si + FieldWidth] = fiYellowDisk;
2176 return subAnimateMurphy;
2178 // ==========================================================================
2179 // yellow disk pushing right
2180 // ==========================================================================
2183 if (LowByte(PlayField16[*si]) != fiExplosion)
2184 PlayField16[*si] = 0;
2187 PlayField16[*si] = fiMurphy;
2188 PlayField16[*si + 1] = fiYellowDisk;
2189 return subAnimateMurphy;
2191 // ==========================================================================
2192 // orange disk, pushing left
2193 // ==========================================================================
2196 if (LowByte(PlayField16[*si]) != fiExplosion)
2197 PlayField16[*si] = 0;
2200 PlayField16[*si] = fiMurphy;
2201 PlayField16[*si - 1] = fiOrangeDisk;
2202 return subAnimateMurphy;
2204 // ==========================================================================
2205 // orange disk, pushing right
2206 // ==========================================================================
2209 if (LowByte(PlayField16[*si]) != fiExplosion)
2210 PlayField16[*si] = 0;
2213 PlayField16[*si] = fiMurphy;
2214 PlayField16[*si + 1] = fiOrangeDisk;
2215 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2217 MovHighByte(&PlayField16[*si + 1], 0x20);
2218 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2221 return subAnimateMurphy;
2223 // ==========================================================================
2224 // Release a red disk
2225 // ==========================================================================
2228 PlayField16[*si] = fiMurphy;
2229 RedDiskReleasePhase = 2;
2230 RedDiskCount = RedDiskCount - 1;
2231 subDisplayRedDiskCount();
2232 subSoundFXPush(); // Sound effects
2234 return subAnimateMurphy;
2235 } // subAnimateMurphy
2237 // ==========================================================================
2239 // ==========================================================================
2240 int subExplodeSnikSnaksBelow(int si)
2242 int subExplodeSnikSnaksBelow;
2246 ax = LowByte(PlayField16[si + FieldWidth]);
2247 if (ax == 0x11 || ax == 0xBB)
2248 ExplodeFieldSP(si + FieldWidth);
2250 return subExplodeSnikSnaksBelow;
2251 } // subExplodeSnikSnaksBelow
2253 // ==========================================================================
2255 // Does pushing against an object kill Murphy?
2256 // ==========================================================================
2257 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2259 static boolean subMoveKillsMurphy;
2265 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2271 if (al == fiExplosion)
2274 if (fiOrangeDisk <= al && al <= fiPortUp)
2277 ExplodeFieldSP(si); // Explode
2278 subMoveKillsMurphy = True;
2279 return subMoveKillsMurphy;
2288 ExplodeFieldSP(si); // Explode
2289 subMoveKillsMurphy = True;
2290 return subMoveKillsMurphy;
2292 loc_g_74F6: // zonk left
2294 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2297 subMoveKillsMurphy = True; // Set carry flag
2298 return subMoveKillsMurphy;
2300 loc_g_7512: // zonk right
2302 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2305 loc_g_752E: // Marked fields and Ports
2306 subMoveKillsMurphy = True; // Set carry flag
2307 return subMoveKillsMurphy;
2309 loc_g_7530: // explosion
2310 if ((ah & 0x80) != 0)
2317 ExplodeFieldSP(si); // Explode
2318 subMoveKillsMurphy = True; // Set carry flag
2319 return subMoveKillsMurphy;
2322 PlayField16[si] = 0;
2323 subMoveKillsMurphy = False;
2325 return subMoveKillsMurphy;
2326 } // subMoveKillsMurphy
2328 // ==========================================================================
2330 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2331 // change conditions to port specs
2332 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2333 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2334 // ==========================================================================
2335 int subSpPortTest(int si)
2342 cx = LInfo.SpecialPortCount; // number of special ports
2344 for (i = 0; i < cx; i++)
2347 /* this assumes that PortLocation is stored as big endian */
2348 bx = LInfo.SpecialPort[i].PortLocation;
2350 /* this assumes that PortLocation is stored as little endian */
2351 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2352 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2357 GravityFlag = LInfo.SpecialPort[i].Gravity;
2358 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2359 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2361 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2369 cx = LInfo.SpecialPortCount; // number of special ports
2370 for (i = 1; i <= cx; i++)
2373 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2374 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2377 GravityFlag = LInfo.SpecialPort[i].Gravity;
2378 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2379 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2380 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2387 return subSpPortTest;
2390 void subCopyFieldToScreen(int si, int fi)
2394 // +++++++++++++++++++++++++++++++++++++++++
2395 X = GetStretchX(si);
2396 Y = GetStretchY(si);
2397 StretchedSprites.BltEx(X, Y, fi);
2398 // +++++++++++++++++++++++++++++++++++++++++
2401 static void subEatRedDisk(int si)
2403 if (AllowRedDiskCheat == 0)
2405 if (RedDiskReleasePhase != 0)
2407 if (RedDiskReleaseMurphyPos == si)
2412 RedDiskCount = (RedDiskCount + 1) % 256;
2413 subDisplayRedDiskCount();
2416 int subAdjustZonksInfotronsAboveMurphy(int si)
2418 int subAdjustZonksInfotronsAboveMurphy;
2422 if (LowByte(PlayField16[si]) != fiExplosion)
2423 PlayField16[si] = 0;
2425 ax = PlayField16[si - FieldWidth];
2426 if (ax == 0 || ax == 0x9999)
2429 if (ax == fiZonk || ax == fiInfotron)
2431 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2434 return subAdjustZonksInfotronsAboveMurphy;
2436 loc_g_15A8: // empty above
2437 ax = PlayField16[si - FieldWidth - 1];
2438 if (ax == fiZonk || ax == fiInfotron)
2442 ax = PlayField16[si - FieldWidth + 1];
2443 if (ax == fiZonk || ax == fiInfotron)
2446 return subAdjustZonksInfotronsAboveMurphy;
2448 loc_g_15C5: // zonk/infotron above left
2449 ax = PlayField16[si - 1];
2450 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2453 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2454 PlayField16[si - FieldWidth] = 0x8888;
2455 return subAdjustZonksInfotronsAboveMurphy;
2457 loc_g_15E8: // zonk/infotron above right
2458 ax = PlayField16[si + 1];
2459 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2461 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2462 PlayField16[si - FieldWidth] = 0x8888;
2465 return subAdjustZonksInfotronsAboveMurphy;
2466 } // subAdjustZonksInfotronsAboveMurphy