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
14 #define LocalStretch (1)
16 // ==========================================================================
18 // Move Murphy in any direction
19 // ==========================================================================
21 int subAnimateMurphy(int *si)
25 // int ax, al, ah, bx, bl, i, X, Y;
26 // int tX, tY, tDeltaX, tDeltaY, tPos, Tmp;
27 int ax, al, bx, bl, i, X, Y;
28 int tDeltaX, tDeltaY, tPos, Tmp;
30 // Variables that hold information about the animation sequence
31 static int *dx = 0; // an array of image positions in moving.mpx, finalized with -1
32 static int dx2 = 0; // an additional image position of a second sprite, for instance: yellow disk if pushed
33 static int MurphyDX = 0, MurphyDY = 0; // murphys move steps
34 static int SeqPos = 0; // index into dx()
35 static int ClearPos = 0; // Position to clear before blitting sprites, none=-1
36 static int dxPos = 0; // field-position to draw dx(SeqPos)
37 static int dx2Step = 0; // position of dx2 relative to dx-position
39 ax = PlayField16[*si];
43 printf("::: Murphy.c: subAnimateMurphy(): %d [%d, %d] %d, %d [%d]\n",
44 *si, *si % 60, *si / 60, ax, al, (al == fiMurphy));
49 MurphyMoveCounter = 0; // We have no Murphy! Exit!
50 return subAnimateMurphy;
53 MurphyMoveCounter = 1; // We have a Murphy!
54 MurphyExplodePos = *si;
55 if (ax != 3) // yes--go proceed moving murphy?
56 goto locProceedMovingMurphy;
58 // FS: reset moving sequence variables
66 ScratchGravity = 0; // scratch gravity off
67 if (GravityFlag != 0) // Gravity? (1=gravity on)
69 bl = LowByte(PlayField16[*si - FieldWidth]); // check above
70 if (! (bl == fiPortUp || bl == fiPortUpAndDown || bl == fiPortAllDirections))
72 if (PlayField16[*si + FieldWidth] == 0) // gravity on and space below!
78 if (bl != 0) // a key was pressed!
79 goto locKeyPressed5FCF;
81 RedDiskReleaseFlag = 1;
82 if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
90 return subAnimateMurphy;
92 // ------------------------------------------------------------------
93 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
94 YawnSleepCounter = YawnSleepCounter + 1;
95 if (YawnSleepCounter == 4)
97 subCopyFieldToScreen(*si, fiMurphy); // normal grin
98 return subAnimateMurphy;
101 if (YawnSleepCounter <= 500) // loc_g_5ED7:
102 return subAnimateMurphy;
104 if (YawnSleepCounter <= 522)
106 bx = (YawnSleepCounter - 500) / 2;
107 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
108 return subAnimateMurphy;
111 if (YawnSleepCounter <= 1000)
112 return subAnimateMurphy;
114 if (YawnSleepCounter <= 1022)
116 bx = (YawnSleepCounter - 1000) / 2;
117 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again!
118 return subAnimateMurphy;
121 if (YawnSleepCounter <= 1600) // loc_g_5F3B:
122 return subAnimateMurphy;
124 if (YawnSleepCounter <= 1622)
126 bx = (YawnSleepCounter - 1600) / 2;
127 subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again! - third time
128 return subAnimateMurphy;
131 if (YawnSleepCounter > 1654)
132 return subAnimateMurphy;
134 if (PlayField16[*si - 1] == 0)
136 if (PlayField16[*si + 1] == 0)
138 YawnSleepCounter = 36;
139 return subAnimateMurphy;
144 bx = (YawnSleepCounter - 1622) / 16;
145 subCopyFieldToScreen(*si, aniMurphySleepRight + bx); // go to sleep
146 return subAnimateMurphy;
150 bx = (YawnSleepCounter - 1622) / 16;
151 subCopyFieldToScreen(*si, aniMurphySleepLeft + bx); // go to sleep
152 return subAnimateMurphy;
154 // end of YAWN-SLEEP-Sequence
155 // ------------------------------------------------------------------
156 // ==========================================================================
157 // (Direct Jump) a key was pressed
158 // ==========================================================================
161 if (ScratchGravity == 0)
164 if (PlayField16[*si + FieldWidth] != 0)
169 if (PlayField16[*si - FieldWidth] == fiBase)
173 else if (bl == keyLeft)
175 if (PlayField16[*si - 1] == fiBase)
179 else if (bl == keyRight)
181 if (PlayField16[*si + 1] == fiBase)
185 bl = keyDown; // force moving down!
190 RedDiskReleaseFlag = 0; // moving down to up ...
196 RedDiskReleaseFlag = 0; // moving right to left ...
202 RedDiskReleaseFlag = 0; // moving up to down ...
208 RedDiskReleaseFlag = 0; // moving left to right ...
213 case keySpaceUp: // 5
214 RedDiskReleaseFlag = 0; // touching down to up ...
219 case keySpaceLeft: // 6
220 RedDiskReleaseFlag = 0; // touching right to left ...
225 case keySpaceDown: // 7
226 RedDiskReleaseFlag = 0; // touching up to down ...
231 case keySpaceRight: // 8
232 RedDiskReleaseFlag = 0; // touching left to right ...
238 goto loc_g_62E2; // no move ...
243 RedDiskReleaseFlag = 0;
244 return subAnimateMurphy;
248 // ==========================================================================
249 // moving down to up ...
250 // ==========================================================================
256 ax = PlayField16[*si - FieldWidth];
267 if (ax == fiInfotron)
273 if (al == fiTerminal)
276 if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
282 if (al == fiYellowDisk)
285 if (! subMoveKillsMurphy(*si - FieldWidth, ax, bl))
288 return subAnimateMurphy;
290 // ==========================================================================
291 // moving right to left ...
292 // ==========================================================================
298 MurphyVarFaceLeft = 1;
299 ax = PlayField16[*si - 1];
310 if (ax == fiInfotron)
319 if (al == fiTerminal)
322 if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
328 if (ax == fiYellowDisk)
331 if (ax == fiOrangeDisk)
334 if (! subMoveKillsMurphy(*si - 1, ax, bl))
337 return subAnimateMurphy;
339 // ==========================================================================
340 // moving up to down ...
341 // ==========================================================================
347 ax = PlayField16[*si + FieldWidth];
358 if (ax == fiInfotron)
364 if (al == fiTerminal)
367 if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
373 if (al == fiYellowDisk)
376 if (! subMoveKillsMurphy(*si + FieldWidth, ax, bl))
379 return subAnimateMurphy;
381 // ==========================================================================
382 // moving left to right ...
383 // ==========================================================================
389 MurphyVarFaceLeft = 0;
390 ax = PlayField16[*si + 1];
401 if (ax == fiInfotron)
410 if (al == fiTerminal)
413 if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
419 if (al == fiYellowDisk)
422 if (ax == fiOrangeDisk)
425 if (! subMoveKillsMurphy(*si + 1, ax, bl))
428 return subAnimateMurphy;
430 // ==========================================================================
431 // touching down to up ...
432 // ==========================================================================
437 dxPos = *si - FieldWidth;
439 ax = PlayField16[*si - FieldWidth];
448 if (ax == fiInfotron)
451 if (al == fiTerminal)
457 return subAnimateMurphy;
459 // ==========================================================================
460 // touching right to left ...
461 // ==========================================================================
468 MurphyVarFaceLeft = 1;
469 ax = PlayField16[*si - 1];
477 if (ax == fiInfotron)
480 if (al == fiTerminal)
486 return subAnimateMurphy;
488 // ==========================================================================
489 // touching up to down ...
490 // ==========================================================================
495 dxPos = *si + FieldWidth;
497 ax = PlayField16[*si + FieldWidth];
505 if (ax == fiInfotron)
508 if (al == fiTerminal)
514 return subAnimateMurphy;
516 // ==========================================================================
517 // touching left to right ...
518 // ==========================================================================
525 MurphyVarFaceLeft = 0;
526 ax = PlayField16[*si + 1];
534 if (ax == fiInfotron)
537 if (al == fiTerminal)
543 return subAnimateMurphy;
545 // ==========================================================================
546 // Release Red disk: no move ...
547 // ==========================================================================
553 if (LowByte(RedDiskCount) == 0)
554 return subAnimateMurphy;
556 if (LowByte(RedDiskReleasePhase) != 0)
557 return subAnimateMurphy;
559 if (LowByte(RedDiskReleaseFlag) != 1)
560 return subAnimateMurphy;
562 MovHighByte(&PlayField16[*si], 0x2A);
563 MovingPictureSequencePhase = 0x40; // init picture move sequence
565 MovLowByte(&RedDiskReleasePhase, 1);
566 Mov(&RedDiskReleaseMurphyPos, *si); // remember Murphy's location
569 // ==========================================================================
570 // SPACE moving down to up
571 // ==========================================================================
574 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
575 PlayField16[*si - FieldWidth] = 0x103;
576 PlayField16[*si] = 0x300;
577 *si = *si - FieldWidth;
578 goto loc_StopNoSplit;
580 // ==========================================================================
581 // SPACE moving right to left
582 // ==========================================================================
585 dx = aniMurphyEatLeft;
586 PlayField16[*si - 1] = 0x203;
587 PlayField16[*si] = 0x300;
589 goto loc_StopNoSplit;
591 // ==========================================================================
592 // SPACE moving up to down, and when gravity is pulling!
593 // ==========================================================================
596 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
597 PlayField16[*si + FieldWidth] = 0x303;
598 PlayField16[*si] = 0x300;
599 *si = *si + FieldWidth;
600 goto loc_StopNoSplit;
602 // ==========================================================================
603 // SPACE moving left to right
604 // ==========================================================================
607 dx = aniMurphyEatRight;
608 PlayField16[*si + 1] = 0x403;
609 PlayField16[*si] = 0x300;
611 goto loc_StopNoSplit;
613 // ==========================================================================
614 // BUG moving down to up
615 // ==========================================================================
618 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
620 ExplodeFieldSP(*si); // Explode
621 return subAnimateMurphy;
624 PlayField16[*si - FieldWidth] = fiBase;
625 // ==========================================================================
626 // BASE moving down to up
627 // ==========================================================================
631 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
632 PlayField16[*si - FieldWidth] = 0x503;
633 PlayField16[*si] = 0x300;
634 *si = *si - FieldWidth;
635 goto loc_StopNoSplit;
637 // ==========================================================================
638 // BUG moving right to left
639 // ==========================================================================
642 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
644 ExplodeFieldSP(*si); // Explode
645 return subAnimateMurphy;
648 PlayField16[*si - 1] = fiBase;
649 // ==========================================================================
650 // BASE moving right to left
651 // ==========================================================================
655 dx = aniMurphyEatLeft;
656 PlayField16[*si - 1] = 0x203;
657 PlayField16[*si] = 0x300;
659 goto loc_StopNoSplit;
661 // ==========================================================================
662 // BUG moving up to down
663 // ==========================================================================
666 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
668 ExplodeFieldSP(*si); // Explode
669 return subAnimateMurphy;
672 PlayField16[*si + FieldWidth] = fiBase;
673 // ==========================================================================
674 // BASE moving up to down
675 // ==========================================================================
679 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
680 PlayField16[*si + FieldWidth] = 0x703;
681 PlayField16[*si] = 0x300;
682 *si = *si + FieldWidth;
683 goto loc_StopNoSplit;
685 // ==========================================================================
686 // BUG moving left to right
687 // ==========================================================================
690 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
692 ExplodeFieldSP(*si); // Explode
693 return subAnimateMurphy;
696 PlayField16[*si + 1] = fiBase;
697 // ==========================================================================
698 // BASE moving left to right
699 // ==========================================================================
703 dx = aniMurphyEatRight;
704 PlayField16[*si + 1] = 0x803;
705 PlayField16[*si] = 0x300;
707 goto loc_StopNoSplit;
709 // ==========================================================================
710 // BUG touching down to up
711 // ==========================================================================
714 if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
716 ExplodeFieldSP(*si); // Explode
717 return subAnimateMurphy;
720 PlayField16[*si - FieldWidth] = fiBase;
721 // ==========================================================================
722 // BASE touching down to up
723 // ==========================================================================
726 subCopyFieldToScreen(*si, aniMurphyTouchUp);
729 dxPos = *si - FieldWidth;
730 MovHighByte(&PlayField16[*si], 0x10);
731 goto loc_StopNoSplit;
733 // ==========================================================================
734 // BUG touching right to left
735 // ==========================================================================
738 if (SgnHighByte(PlayField16[*si - 1]) >= 0)
740 ExplodeFieldSP(*si); // Explode
741 return subAnimateMurphy;
744 PlayField16[*si - 1] = fiBase;
745 // ==========================================================================
746 // BASE touching right to left
747 // ==========================================================================
750 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
754 MovHighByte(&PlayField16[*si], 0x11);
755 goto loc_StopNoSplit;
757 // ==========================================================================
758 // BUG touching up to down
759 // ==========================================================================
762 if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
764 ExplodeFieldSP(*si); // Explode
765 return subAnimateMurphy;
768 PlayField16[*si + FieldWidth] = fiBase;
769 // ==========================================================================
770 // BASE touching up to down
771 // ==========================================================================
774 subCopyFieldToScreen(*si, aniMurphyTouchDown);
777 dxPos = *si + FieldWidth;
778 MovHighByte(&PlayField16[*si], 0x12);
779 goto loc_StopNoSplit;
781 // ==========================================================================
782 // BUG touching left to right
783 // ==========================================================================
786 if (SgnHighByte(PlayField16[*si + 1]) >= 0)
788 ExplodeFieldSP(*si); // Explode
789 return subAnimateMurphy;
792 PlayField16[*si + 1] = fiBase;
793 // ==========================================================================
794 // BASE touching left to right
795 // ==========================================================================
798 subCopyFieldToScreen(*si, aniMurphyTouchRight);
802 MovHighByte(&PlayField16[*si], 0x13);
803 goto loc_StopNoSplit;
805 // ==========================================================================
806 // INFOTRON moving down to up
807 // ==========================================================================
810 subSoundFXInfotron();
811 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
812 PlayField16[*si - FieldWidth] = 0x903;
813 PlayField16[*si] = 0x300;
814 *si = *si - FieldWidth;
815 goto loc_StopNoSplit;
817 // ==========================================================================
818 // INFOTRON moving right to left
819 // ==========================================================================
822 subSoundFXInfotron();
823 dx = aniEatInfotronLeft;
827 PlayField16[*si - 1] = 0xA03;
828 PlayField16[*si] = 0x300;
830 goto loc_StopNoSplit;
832 // ==========================================================================
833 // INFOTRON moving up to down
834 // ==========================================================================
837 subSoundFXInfotron();
838 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
839 PlayField16[*si + FieldWidth] = 0xB03;
840 PlayField16[*si] = 0x300;
841 *si = *si + FieldWidth;
842 goto loc_StopNoSplit;
844 // ==========================================================================
845 // INFOTRON moving left to right
846 // ==========================================================================
849 subSoundFXInfotron();
850 dx = aniEatInfotronRight;
854 PlayField16[*si + 1] = 0xC03;
855 PlayField16[*si] = 0x300;
857 goto loc_StopNoSplit;
859 // ==========================================================================
860 // INFOTRON touching down to up
861 // ==========================================================================
864 subCopyFieldToScreen(*si, aniMurphyTouchUp);
865 subSoundFXInfotron();
866 dx = aniTouchInfotron;
867 MovHighByte(&PlayField16[*si], 0x14);
868 MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
869 goto loc_StopNoSplit;
871 // ==========================================================================
872 // INFOTRON touching right to left
873 // ==========================================================================
876 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
877 subSoundFXInfotron();
878 dx = aniTouchInfotron;
879 MovHighByte(&PlayField16[*si], 0x15);
880 MovHighByte(&PlayField16[*si - 1], 0xFF);
881 goto loc_StopNoSplit;
883 // ==========================================================================
884 // INFOTRON touching up to down
885 // ==========================================================================
888 subCopyFieldToScreen(*si, aniMurphyTouchDown);
889 subSoundFXInfotron();
890 dx = aniTouchInfotron;
891 MovHighByte(&PlayField16[*si], 0x16);
892 MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
893 goto loc_StopNoSplit;
895 // ==========================================================================
896 // INFOTRON touching left to right
897 // ==========================================================================
900 subCopyFieldToScreen(*si, aniMurphyTouchRight);
901 subSoundFXInfotron();
902 dx = aniTouchInfotron;
903 MovHighByte(&PlayField16[*si], 0x17);
904 MovHighByte(&PlayField16[*si + 1], 0xFF);
905 goto loc_StopNoSplit;
907 // ==========================================================================
908 // EXIT pressed from any direction
909 // ==========================================================================
917 if (LowByte(InfotronsNeeded) != 0)
918 return subAnimateMurphy;
921 data_h_DemoDone = 1; // EP set level success bytes
922 LevelStatus = 1; // set Level Status DONE
923 EP_GameDemoVar0DAA = 0; // force demo for lead-out
924 if (SavedGameFlag == 0) // saved game running?
926 if (UpdateTimeFlag != 0) // update time?
928 UpdatedFlag = 1; // prevent double update
929 subUpdatePlayingTime(); // update playing time
934 subUpdateHallOfFame(); // update time + Hall-Of-Fame
937 LeadOutCounter = 0x40; // quit: start lead-out
939 MovHighByte(&PlayField16[*si], 0xD);
940 goto loc_StopNoSplit;
942 // ==========================================================================
943 // ZONK moving right to left
944 // ==========================================================================
947 ax = PlayField16[*si - 2];
949 return subAnimateMurphy;
951 MovHighByte(&PlayField16[*si - 2], 1);
952 subCopyFieldToScreen(*si, aniPushLeft); // draw pushing murphy
953 dx = aniZonkRollLeft;
957 MovHighByte(&PlayField16[*si], 0xE);
958 goto loc_MoveNoSplit;
960 // ==========================================================================
961 // ZONK moving left to right
962 // ==========================================================================
965 ax = PlayField16[*si + 2];
967 return subAnimateMurphy;
969 ax = PlayField16[*si + FieldWidth + 1];
970 if (ax == 0) // zonk falls
971 return subAnimateMurphy;
973 MovHighByte(&PlayField16[*si + 2], 1);
974 subCopyFieldToScreen(*si, aniPushRight); // draw pushing murphy
975 dx = aniZonkRollRight;
979 MovHighByte(&PlayField16[*si], 0xF);
980 goto loc_MoveNoSplit;
982 // ==========================================================================
983 // TERMINAL moving/touching down to up
984 // ==========================================================================
987 subCopyFieldToScreen(*si, aniMurphyTouchUp);
988 if (YellowDisksExploded != 0)
990 YawnSleepCounter = 10; // stay hypnotized
991 return subAnimateMurphy;
994 subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
995 TerminalState[*si - FieldWidth] = 8;
998 // ==========================================================================
999 // TERMINAL moving/touching right to left
1000 // ==========================================================================
1003 subCopyFieldToScreen(*si, aniMurphyTouchLeft);
1004 if (YellowDisksExploded != 0)
1006 YawnSleepCounter = 10; // stay hypnotized
1007 return subAnimateMurphy;
1010 subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1011 TerminalState[*si - 1] = 8;
1014 // ==========================================================================
1015 // TERMINAL moving/touching up to down
1016 // ==========================================================================
1019 subCopyFieldToScreen(*si, aniMurphyTouchDown);
1020 if (YellowDisksExploded != 0)
1022 YawnSleepCounter = 10; // stay hypnotized
1023 return subAnimateMurphy;
1026 subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1027 TerminalState[*si + FieldWidth] = 8;
1030 // ==========================================================================
1031 // TERMINAL moving/touching left to right
1032 // ==========================================================================
1035 subCopyFieldToScreen(*si, aniMurphyTouchRight);
1036 if (YellowDisksExploded != 0)
1038 YawnSleepCounter = 10; // stay hypnotized
1039 return subAnimateMurphy;
1042 subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1043 TerminalState[*si + 1] = 8;
1044 // ==========================================================================
1045 // common TERMINAL stuff moving/touching from all directions
1046 // ==========================================================================
1049 TerminalMaxCycles = 7;
1050 YellowDisksExploded = 1;
1051 for (i = 0; i <= LevelMax; i++)
1053 if (PlayField16[i] == fiYellowDisk)
1057 return subAnimateMurphy;
1059 // ==========================================================================
1060 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1061 // ==========================================================================
1064 if (PlayField16[*si - 2 * FieldWidth] != 0)
1065 return subAnimateMurphy;
1067 dx = aniSplitUpDown;
1068 dx2Step = -FieldWidth;
1069 PlayField16[*si] = 0x1803;
1070 PlayField16[*si - 2 * FieldWidth] = 0x300;
1073 // ==========================================================================
1074 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1075 // ==========================================================================
1078 if (PlayField16[*si - 2] != 0)
1079 return subAnimateMurphy;
1081 dx = aniMurphyEatLeft;
1083 PlayField16[*si] = 0x1903;
1084 PlayField16[*si - 2] = 0x300;
1087 // ==========================================================================
1088 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1089 // ==========================================================================
1092 if (PlayField16[*si + 2 * FieldWidth] != 0)
1093 return subAnimateMurphy;
1095 dx = aniSplitUpDown;
1096 dx2Step = FieldWidth;
1097 PlayField16[*si] = 0x1A03;
1098 PlayField16[*si + 2 * FieldWidth] = 0x300;
1101 // ==========================================================================
1102 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1103 // ==========================================================================
1106 if (PlayField16[*si + 2] != 0)
1107 return subAnimateMurphy;
1109 dx = aniMurphyEatRight;
1111 PlayField16[*si] = 0x1B03;
1112 PlayField16[*si + 2] = 0x300;
1115 MovingPictureSequencePhase = 0; // stop picture move sequence
1116 SplitMoveFlag = 1; // port: split movement
1119 // ==========================================================================
1120 // RED DISK moving down to up
1121 // ==========================================================================
1124 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1125 PlayField16[*si] = 0x1C03;
1126 PlayField16[*si - FieldWidth] = 0x300;
1127 goto loc_StopNoSplit;
1129 // ==========================================================================
1130 // RED DISK moving right to left
1131 // ==========================================================================
1134 dx = aniMurphyEatLeft;
1135 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1136 PlayField16[*si - 1] = 0x1D03;
1138 goto loc_StopNoSplit;
1140 // ==========================================================================
1141 // RED DISK moving up to down
1142 // ==========================================================================
1145 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1146 PlayField16[*si] = 0x1E03;
1147 PlayField16[*si + FieldWidth] = 0x300;
1148 goto loc_StopNoSplit;
1150 // ==========================================================================
1151 // RED DISK moving left to right
1152 // ==========================================================================
1155 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1156 dx = aniMurphyEatRight;
1157 // --------------------------------------------------------------------------
1159 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1160 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1161 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1162 // We may not fix the table, because then the timing of the game changes
1163 // and several existing demo's do not run properly anymore.
1164 // We only correct Murphies x-location here, when the sequence starts.
1165 // Remember that this is not the real bug-fix, but we must live with
1166 // this existing bug and correct for the consequences of it.
1167 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1168 MurphyScreenXPos = MurphyScreenXPos - 2;
1171 // FS: for me this means to blit the first animation frame twice
1173 // --------------------------------------------------------------------------
1174 PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1175 PlayField16[*si + 1] = 0x1F03;
1177 goto loc_StopNoSplit;
1179 // ==========================================================================
1180 // RED DISK touching down to up
1181 // ==========================================================================
1184 dx = aniTouchRedDisk;
1185 MovHighByte(&PlayField16[*si], 0x20);
1186 MovHighByte(&PlayField16[*si - FieldWidth], 3);
1187 goto loc_StopNoSplit;
1189 // ==========================================================================
1190 // RED DISK touching right to left
1191 // ==========================================================================
1194 dx = aniTouchRedDisk;
1195 MovHighByte(&PlayField16[*si], 0x21);
1196 MovHighByte(&PlayField16[*si - 1], 3);
1197 goto loc_StopNoSplit;
1199 // ==========================================================================
1200 // RED DISK touching up to down
1201 // ==========================================================================
1204 dx = aniTouchRedDisk;
1205 MovHighByte(&PlayField16[*si], 0x22);
1206 MovHighByte(&PlayField16[*si + FieldWidth], 3);
1207 goto loc_StopNoSplit;
1209 // ==========================================================================
1210 // RED DISK touching left to right
1211 // ==========================================================================
1214 dx = aniTouchRedDisk;
1215 MovHighByte(&PlayField16[*si], 0x23);
1216 MovHighByte(&PlayField16[*si + 1], 3);
1219 MovingPictureSequencePhase = 0; // stop picture move sequence
1222 // ==========================================================================
1223 // YELLOW DISK moving down to up
1224 // ==========================================================================
1227 if (PlayField16[*si - 2 * FieldWidth] != 0)
1228 return subAnimateMurphy;
1230 PlayField16[*si - 2 * FieldWidth] = 0x1200;
1231 subCopyFieldToScreen(*si, aniPushRight);
1233 dxPos = *si - FieldWidth;
1234 dx2 = aniPushUpDown;
1235 dx2Step = FieldWidth;
1236 PlayField16[*si] = 0x2403;
1237 goto loc_MoveNoSplit;
1239 // ==========================================================================
1240 // YELLOW DISK moving right to left
1241 // ==========================================================================
1244 if (PlayField16[*si - 2] != 0)
1245 return subAnimateMurphy;
1247 PlayField16[*si - 2] = 0x1200;
1248 subCopyFieldToScreen(*si, aniPushLeft);
1253 PlayField16[*si] = 0x2503;
1254 goto loc_MoveNoSplit;
1256 // ==========================================================================
1257 // YELLOW DISK moving up to down
1258 // ==========================================================================
1261 if (PlayField16[*si + 2 * FieldWidth] != 0)
1262 return subAnimateMurphy;
1264 PlayField16[*si + 2 * FieldWidth] = 0x1200;
1265 subCopyFieldToScreen(*si, aniPushRight);
1267 dxPos = *si + FieldWidth;
1268 dx2 = aniPushUpDown;
1269 dx2Step = -FieldWidth;
1270 PlayField16[*si] = 0x2703;
1271 goto loc_MoveNoSplit;
1273 // ==========================================================================
1274 // YELLOW DISK moving left to right
1275 // ==========================================================================
1278 if (PlayField16[*si + 2] != 0)
1279 return subAnimateMurphy;
1281 PlayField16[*si + 2] = 0x1200;
1282 subCopyFieldToScreen(*si, aniPushRight);
1287 PlayField16[*si] = 0x2603;
1288 goto loc_MoveNoSplit;
1290 // ==========================================================================
1291 // ORANGE DISK moving right to left
1292 // ==========================================================================
1295 if (PlayField16[*si - 2] != 0)
1296 return subAnimateMurphy;
1298 PlayField16[*si - 2] = 0x800;
1299 subCopyFieldToScreen(*si, aniPushLeft);
1304 PlayField16[*si] = 0x2803;
1305 goto loc_MoveNoSplit;
1307 // ==========================================================================
1308 // ORANGE DISK moving left to right
1309 // ==========================================================================
1312 if (PlayField16[*si + 2] != 0)
1313 return subAnimateMurphy;
1315 if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1316 return subAnimateMurphy;
1318 PlayField16[*si + 2] = 0x100;
1319 subCopyFieldToScreen(*si, aniPushRight);
1324 PlayField16[*si] = 0x2903;
1325 // ==========================================================================
1326 // Copy screen animation action table to action work space
1327 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1328 // ==========================================================================
1331 MovingPictureSequencePhase = 8; // init picture move sequence
1334 SplitMoveFlag = 0; // no port: no split movement
1337 // copy/store global move sequence info????????????????????????????????????
1338 // ... dont think so ...(FS)
1339 // ==========================================================================
1340 // Proceed with all movements
1341 // ==========================================================================
1343 locProceedMovingMurphy: // proceed moving murphy
1344 YawnSleepCounter = 0; // Wake up sleeping Murphy
1345 ax = MovingPictureSequencePhase; // sequence busy?
1346 if (ax == 0) // no -- start sequence!
1349 ax = ax - 1; // next picture of sequence
1350 MovingPictureSequencePhase = ax; // store for later
1351 if (ax == 0) // Sound effects
1354 bl = HighByte(PlayField16[*si]);
1355 if (bl == 0xE) // Push Zonk to left
1358 if (bl == 0xF) // Push Zonk to right
1361 if (bl == 0x28) // Push orange disk to left
1364 if (bl == 0x29) // Push orange disk to right
1367 if (bl == 0x24) // Push yellow disk up
1370 if (bl == 0x25) // Push yellow disk to left
1373 if (bl == 0x27) // Push yellow disk down
1376 if (bl == 0x26) // Push yellow disk to right
1379 if (bl == 0x2A) // Red disk release timer
1382 return subAnimateMurphy;
1384 // ==========================================================================
1385 // Paint frame of MOVING.DAT sequence
1386 // ==========================================================================
1389 if (SplitMoveFlag == 0)
1391 // ++++++++++++++++++++++++++
1392 // Begin of normal movement
1393 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1394 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1395 if (! ClearPos < 0) // clear field that murphy is leaving
1396 subCopyFieldToScreen(ClearPos, 0);
1398 if (dx2 == fiInfotron) // special case of infotron moving left or right
1405 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1406 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1409 X = GetStretchX(dxPos) + tDeltaX;
1410 Y = GetStretchY(dxPos) + tDeltaY;
1411 Tmp = (SeqPos < 0 ? 0 : 0); // 9StepBugFix!(red disk move right)
1412 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1415 tPos = dxPos + dx2Step;
1416 X = GetStretchX(tPos);
1417 Y = GetStretchY(tPos);
1418 if (dx2 == fiInfotron) // special case of infotron moving left or right
1420 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1422 else // pushing something
1424 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1428 // End of normal movement
1429 // ------------------------
1433 // ++++++++++++++++++++++++++++++++
1434 // Begin of split movement (port)
1435 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1436 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1437 subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1438 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1439 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1440 X = GetStretchX(dxPos) + tDeltaX;
1441 Y = GetStretchY(dxPos) + tDeltaY;
1442 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1443 tPos = dxPos + dx2Step;
1444 X = GetStretchX(tPos);
1445 Y = GetStretchY(tPos);
1446 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1447 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1448 // End of split movement (port)
1449 // ------------------------------
1450 } // loc_g_6D1E:'loc_g_6D28:
1452 SeqPos = SeqPos + 1;
1453 if (dx[SeqPos] > -1)
1454 return subAnimateMurphy;
1456 // Follow-up after movement completed 'loc_g_6D35:
1457 MurphyXPos = MurphyXPos + MurphyDX;
1458 MurphyYPos = MurphyYPos + MurphyDY;
1459 bl = HighByte(PlayField16[*si]); // animation phase
1460 MovHighByte(&PlayField16[*si], 0);
1462 if (bl == 0x1) // space, moving up
1465 if (bl == 0x2) // space, moving left
1468 if (bl == 0x3) // space, moving down
1471 if (bl == 0x4) // space, moving right
1474 if (bl == 0x5) // base , moving up
1477 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1480 if (bl == 0x7) // base , moving down
1483 if (bl == 0x8) // base , moving right
1486 if (bl == 0x9) // infotron, moving up
1489 if (bl == 0xA) // infotron, moving left
1492 if (bl == 0xB) // infotron, moving down
1495 if (bl == 0xC) // infotron, moving right
1498 if (bl == 0xD) // exit
1501 if (bl == 0xE) // zonk, pushing left
1504 if (bl == 0xF) // zonk, pushing right
1507 if (bl == 0x10) // base , touching up
1510 if (bl == 0x11) // base , touching left
1513 if (bl == 0x12) // base , touching down
1516 if (bl == 0x13) // base , touching right
1519 if (bl == 0x14) // infotron touching up
1522 if (bl == 0x15) // infotron touching left
1525 if (bl == 0x16) // infotron touching down
1528 if (bl == 0x17) // infotron touching right
1531 if (bl == 0x18) // port up
1534 if (bl == 0x19) // port left
1537 if (bl == 0x1A) // port down
1540 if (bl == 0x1B) // port right
1543 if (bl == 0x1C) // red disk, moving up
1546 if (bl == 0x1D) // red disk, moving left
1549 if (bl == 0x1E) // red disk, moving down
1552 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1555 if (bl == 0x20) // red disk, touching up
1558 if (bl == 0x21) // red disk, touching left
1561 if (bl == 0x22) // red disk, touching down
1564 if (bl == 0x23) // red disk, touching right
1567 if (bl == 0x24) // yellow disk, pushing up
1570 if (bl == 0x25) // yellow disk, pushing left
1573 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1576 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1579 if (bl == 0x28) // orange disk, pushing left
1582 if (bl == 0x29) // orange disk, pushing right
1585 if (bl == 0x2A) // red disk, release
1589 return subAnimateMurphy;
1591 // ==========================================================================
1592 // infotron, moving up
1593 // ==========================================================================
1596 if (0 < LowByte(InfotronsNeeded))
1597 InfotronsNeeded = InfotronsNeeded - 1;
1599 subDisplayInfotronsNeeded();
1600 loc_g_6EC8: // space, base
1601 PlayField16[*si] = fiMurphy;
1602 subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1603 return subAnimateMurphy;
1605 // ==========================================================================
1606 // infotron, moving left
1607 // ==========================================================================
1610 if (0 < LowByte(InfotronsNeeded))
1611 InfotronsNeeded = InfotronsNeeded - 1;
1613 subDisplayInfotronsNeeded();
1614 loc_g_6EE6: // space, base
1615 PlayField16[*si] = fiMurphy;
1616 subAdjustZonksInfotronsAboveMurphy(*si + 1);
1617 return subAnimateMurphy;
1619 // ==========================================================================
1620 // infotron, moving down
1621 // ==========================================================================
1624 if (0 < LowByte(InfotronsNeeded))
1625 InfotronsNeeded = InfotronsNeeded - 1;
1627 subDisplayInfotronsNeeded();
1628 loc_g_6F04: // space, base
1629 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1630 PlayField16[*si - FieldWidth] = 0;
1632 PlayField16[*si] = fiMurphy;
1633 return subAnimateMurphy;
1635 // ==========================================================================
1636 // infotron, moving right
1637 // ==========================================================================
1640 if (0 < LowByte(InfotronsNeeded))
1641 InfotronsNeeded = InfotronsNeeded - 1;
1643 subDisplayInfotronsNeeded();
1644 loc_g_71C4: // space, base
1645 subAdjustZonksInfotronsAboveMurphy(*si - 1);
1646 PlayField16[*si] = fiMurphy;
1647 return subAnimateMurphy;
1649 // ==========================================================================
1650 // infotron, touching up
1651 // ==========================================================================
1654 if (0 < LowByte(InfotronsNeeded))
1655 InfotronsNeeded = InfotronsNeeded - 1;
1657 subDisplayInfotronsNeeded();
1659 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1660 PlayField16[*si - FieldWidth] = 0;
1662 return subAnimateMurphy;
1664 // ==========================================================================
1665 // infotron, touching left
1666 // ==========================================================================
1669 if (0 < LowByte(InfotronsNeeded))
1670 InfotronsNeeded = InfotronsNeeded - 1;
1672 subDisplayInfotronsNeeded();
1674 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1675 PlayField16[*si - 1] = 0;
1677 return subAnimateMurphy;
1679 // ==========================================================================
1680 // infotron, touching down
1681 // ==========================================================================
1684 if (0 < LowByte(InfotronsNeeded))
1685 InfotronsNeeded = InfotronsNeeded - 1;
1687 subDisplayInfotronsNeeded();
1689 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1690 PlayField16[*si + FieldWidth] = 0;
1692 return subAnimateMurphy;
1694 // ==========================================================================
1695 // infotron, touching right
1696 // ==========================================================================
1699 if (0 < LowByte(InfotronsNeeded))
1700 InfotronsNeeded = InfotronsNeeded - 1;
1702 subDisplayInfotronsNeeded();
1704 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1705 PlayField16[*si + 1] = 0;
1707 return subAnimateMurphy;
1709 // ==========================================================================
1710 // zonk, pushing left
1711 // ==========================================================================
1714 if (LowByte(PlayField16[*si]) != fiExplosion)
1715 PlayField16[*si] = 0;
1717 PlayField16[*si - 1] = fiMurphy;
1718 PlayField16[*si - 2] = fiZonk;
1719 subExplodeSnikSnaksBelow(*si - 2);
1721 return subAnimateMurphy;
1723 // ==========================================================================
1724 // zonk, pushing right
1725 // ==========================================================================
1728 if (LowByte(PlayField16[*si]) != fiExplosion)
1729 PlayField16[*si] = 0;
1731 PlayField16[*si + 1] = fiMurphy;
1732 PlayField16[*si + 2] = fiZonk;
1733 subExplodeSnikSnaksBelow(*si + 2);
1735 return subAnimateMurphy;
1737 // ==========================================================================
1739 // ==========================================================================
1743 return subAnimateMurphy;
1745 // ==========================================================================
1746 // Push Zonk from right to left
1747 // ==========================================================================
1750 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1751 return subAnimateMurphy;
1753 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1754 PlayField16[*si - 1] = fiZonk;
1755 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1756 PlayField16[*si - 2] = 0;
1758 subCopyFieldToScreen(*si, fiMurphy);
1759 return subAnimateMurphy;
1761 // ==========================================================================
1762 // Push Zonk from left to right
1763 // ==========================================================================
1766 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1767 return subAnimateMurphy;
1769 PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1770 PlayField16[*si + 1] = fiZonk;
1771 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1772 PlayField16[*si + 2] = 0;
1774 subCopyFieldToScreen(*si, fiMurphy);
1775 return subAnimateMurphy;
1777 // ==========================================================================
1778 // Push orange disk from right to left
1779 // ==========================================================================
1782 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1783 return subAnimateMurphy;
1785 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1786 PlayField16[*si - 1] = fiOrangeDisk;
1787 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1788 PlayField16[*si - 2] = 0;
1790 subCopyFieldToScreen(*si, fiMurphy);
1791 return subAnimateMurphy;
1793 // ==========================================================================
1794 // Push orange disk from left to right
1795 // ==========================================================================
1798 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1799 return subAnimateMurphy;
1801 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1802 PlayField16[*si + 1] = fiOrangeDisk;
1803 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1804 PlayField16[*si + 2] = 0;
1806 subCopyFieldToScreen(*si, fiMurphy);
1807 return subAnimateMurphy;
1809 // ==========================================================================
1810 // Push yellow disk from down to up
1811 // ==========================================================================
1814 if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
1815 return subAnimateMurphy;
1817 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1818 PlayField16[*si - FieldWidth] = fiYellowDisk;
1819 if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
1820 PlayField16[*si - 2 * FieldWidth] = 0;
1822 subCopyFieldToScreen(*si, fiMurphy);
1823 return subAnimateMurphy;
1825 // ==========================================================================
1826 // Push yellow disk from right to left
1827 // ==========================================================================
1830 if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
1831 return subAnimateMurphy;
1833 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1834 PlayField16[*si - 1] = fiYellowDisk;
1835 if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1836 PlayField16[*si - 2] = 0;
1838 subCopyFieldToScreen(*si, fiMurphy);
1839 return subAnimateMurphy;
1841 // ==========================================================================
1842 // Push yellow disk from up to down
1843 // ==========================================================================
1846 if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
1847 return subAnimateMurphy;
1849 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1850 PlayField16[*si + FieldWidth] = fiYellowDisk;
1851 if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
1852 PlayField16[*si + 2 * FieldWidth] = 0;
1854 subCopyFieldToScreen(*si, fiMurphy);
1855 return subAnimateMurphy;
1857 // ==========================================================================
1858 // Push yellow disk from left to right
1859 // ==========================================================================
1862 if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
1863 return subAnimateMurphy;
1865 PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1866 PlayField16[*si + 1] = fiYellowDisk;
1867 if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1868 PlayField16[*si + 2] = 0;
1870 subCopyFieldToScreen(*si, fiMurphy);
1871 return subAnimateMurphy;
1873 // ==========================================================================
1874 // time red disk release (space)
1875 // ==========================================================================
1878 if (DemoKeyCode != keySpace)
1880 PlayField16[*si] = fiMurphy;
1881 subCopyFieldToScreen(*si, fiMurphy);
1882 RedDiskReleasePhase = 0;
1884 else if (MovingPictureSequencePhase == 0x20)
1886 subCopyFieldToScreen(*si, 43); // anxious murphy
1887 RedDiskReleasePhase = 1;
1890 return subAnimateMurphy;
1892 // ==========================================================================
1893 // Special port down to up
1894 // ==========================================================================
1897 if (LowByte(PlayField16[*si]) != fiExplosion)
1898 PlayField16[*si] = 0;
1900 PlayField16[*si - 2 * FieldWidth] = fiMurphy;
1902 *si = *si - FieldWidth;
1903 if (HighByte(PlayField16[*si]) == 1)
1906 *si = *si - FieldWidth;
1907 return subAnimateMurphy;
1909 // ==========================================================================
1910 // Special port right to left
1911 // ==========================================================================
1914 if (LowByte(PlayField16[*si]) != fiExplosion)
1915 PlayField16[*si] = 0;
1917 PlayField16[*si - 2] = fiMurphy;
1920 if (HighByte(PlayField16[*si]) == 1)
1924 return subAnimateMurphy;
1926 // ==========================================================================
1927 // Special port up to down
1928 // ==========================================================================
1931 if (LowByte(PlayField16[*si]) != fiExplosion)
1932 PlayField16[*si] = 0;
1934 PlayField16[*si + 2 * FieldWidth] = fiMurphy;
1936 *si = *si + FieldWidth;
1937 if (HighByte(PlayField16[*si]) == 1)
1940 *si = *si + FieldWidth;
1941 return subAnimateMurphy;
1943 // ==========================================================================
1944 // Special port left to right
1945 // ==========================================================================
1948 if (LowByte(PlayField16[*si]) != fiExplosion)
1949 PlayField16[*si] = 0;
1951 PlayField16[*si + 2] = fiMurphy;
1954 if (HighByte(PlayField16[*si]) == 1)
1958 return subAnimateMurphy;
1960 // ==========================================================================
1962 // ==========================================================================
1965 if (LowByte(PlayField16[*si]) != fiExplosion)
1966 PlayField16[*si] = 0;
1968 *si = *si - FieldWidth;
1969 PlayField16[*si] = fiMurphy;
1970 subEatRedDisk(*si); // inc+show Murphy's red disks
1971 return subAnimateMurphy;
1973 // ==========================================================================
1974 // Move Red Disk left
1975 // ==========================================================================
1978 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1979 PlayField16[*si + 1] = 0;
1981 PlayField16[*si] = fiMurphy;
1982 subEatRedDisk(*si); // inc+show Murphy's red disks
1983 return subAnimateMurphy;
1985 // ==========================================================================
1986 // Move Red Disk down
1987 // ==========================================================================
1990 if (LowByte(PlayField16[*si]) != fiExplosion)
1991 PlayField16[*si] = 0;
1993 *si = *si + FieldWidth;
1994 PlayField16[*si] = fiMurphy;
1995 subEatRedDisk(*si); // inc+show Murphy's red disks
1996 return subAnimateMurphy;
1998 // ==========================================================================
1999 // Move Red Disk right
2000 // ==========================================================================
2003 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2004 PlayField16[*si - 1] = 0;
2006 PlayField16[*si] = fiMurphy;
2007 subEatRedDisk(*si); // inc+show Murphy's red disks
2008 return subAnimateMurphy;
2010 // ==========================================================================
2012 // ==========================================================================
2015 if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2016 PlayField16[*si - FieldWidth] = 0;
2018 subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2019 return subAnimateMurphy;
2021 // ==========================================================================
2022 // Eat Red Disk left
2023 // ==========================================================================
2026 if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2027 PlayField16[*si - 1] = 0;
2029 subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2030 return subAnimateMurphy;
2032 // ==========================================================================
2033 // Eat Red Disk down
2034 // ==========================================================================
2037 if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2038 PlayField16[*si + FieldWidth] = 0;
2040 subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2041 return subAnimateMurphy;
2043 // ==========================================================================
2044 // Eat Red Disk right
2045 // ==========================================================================
2048 if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2049 PlayField16[*si + 1] = 0;
2051 subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2052 return subAnimateMurphy;
2054 // ==========================================================================
2055 // yellow disk, pushing up
2056 // ==========================================================================
2059 if (LowByte(PlayField16[*si]) != fiExplosion)
2060 PlayField16[*si] = 0;
2062 *si = *si - FieldWidth;
2063 PlayField16[*si] = fiMurphy;
2064 PlayField16[*si - FieldWidth] = fiYellowDisk;
2065 return subAnimateMurphy;
2067 // ==========================================================================
2068 // yellow disk, pushing left
2069 // ==========================================================================
2072 if (LowByte(PlayField16[*si]) != fiExplosion)
2073 PlayField16[*si] = 0;
2076 PlayField16[*si] = fiMurphy;
2077 PlayField16[*si - 1] = fiYellowDisk;
2078 return subAnimateMurphy;
2080 // ==========================================================================
2081 // yellow disk, pushing down
2082 // ==========================================================================
2085 if (LowByte(PlayField16[*si]) != fiExplosion)
2086 PlayField16[*si] = 0;
2088 *si = *si + FieldWidth;
2089 PlayField16[*si] = fiMurphy;
2090 PlayField16[*si + FieldWidth] = fiYellowDisk;
2091 return subAnimateMurphy;
2093 // ==========================================================================
2094 // yellow disk pushing right
2095 // ==========================================================================
2098 if (LowByte(PlayField16[*si]) != fiExplosion)
2099 PlayField16[*si] = 0;
2102 PlayField16[*si] = fiMurphy;
2103 PlayField16[*si + 1] = fiYellowDisk;
2104 return subAnimateMurphy;
2106 // ==========================================================================
2107 // orange disk, pushing left
2108 // ==========================================================================
2111 if (LowByte(PlayField16[*si]) != fiExplosion)
2112 PlayField16[*si] = 0;
2115 PlayField16[*si] = fiMurphy;
2116 PlayField16[*si - 1] = fiOrangeDisk;
2117 return subAnimateMurphy;
2119 // ==========================================================================
2120 // orange disk, pushing right
2121 // ==========================================================================
2124 if (LowByte(PlayField16[*si]) != fiExplosion)
2125 PlayField16[*si] = 0;
2128 PlayField16[*si] = fiMurphy;
2129 PlayField16[*si + 1] = fiOrangeDisk;
2130 if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2132 MovHighByte(&PlayField16[*si + 1], 0x20);
2133 MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2136 return subAnimateMurphy;
2138 // ==========================================================================
2139 // Release a red disk
2140 // ==========================================================================
2143 PlayField16[*si] = fiMurphy;
2144 RedDiskReleasePhase = 2;
2145 RedDiskCount = RedDiskCount - 1;
2146 subDisplayRedDiskCount();
2147 subSoundFXPush(); // Sound effects
2149 return subAnimateMurphy;
2150 } // subAnimateMurphy
2152 // ==========================================================================
2154 // ==========================================================================
2155 int subExplodeSnikSnaksBelow(int si)
2157 int subExplodeSnikSnaksBelow;
2161 ax = LowByte(PlayField16[si + FieldWidth]);
2162 if (ax == 0x11 || ax == 0xBB)
2163 ExplodeFieldSP(si + FieldWidth);
2165 return subExplodeSnikSnaksBelow;
2166 } // subExplodeSnikSnaksBelow
2168 // ==========================================================================
2170 // Does pushing against an object kill Murphy?
2171 // ==========================================================================
2172 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2174 static boolean subMoveKillsMurphy;
2180 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2186 if (al == fiExplosion)
2189 if (fiOrangeDisk <= al && al <= fiPortUp)
2192 ExplodeFieldSP(si); // Explode
2193 subMoveKillsMurphy = True;
2194 return subMoveKillsMurphy;
2203 ExplodeFieldSP(si); // Explode
2204 subMoveKillsMurphy = True;
2205 return subMoveKillsMurphy;
2207 loc_g_74F6: // zonk left
2209 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2212 subMoveKillsMurphy = True; // Set carry flag
2213 return subMoveKillsMurphy;
2215 loc_g_7512: // zonk right
2217 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2220 loc_g_752E: // Marked fields and Ports
2221 subMoveKillsMurphy = True; // Set carry flag
2222 return subMoveKillsMurphy;
2224 loc_g_7530: // explosion
2225 if ((ah & 0x80) != 0)
2232 ExplodeFieldSP(si); // Explode
2233 subMoveKillsMurphy = True; // Set carry flag
2234 return subMoveKillsMurphy;
2237 PlayField16[si] = 0;
2238 subMoveKillsMurphy = False;
2240 return subMoveKillsMurphy;
2241 } // subMoveKillsMurphy
2243 // ==========================================================================
2245 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2246 // change conditions to port specs
2247 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2248 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2249 // ==========================================================================
2250 int subSpPortTest(int si)
2256 cx = LInfo.SpecialPortCount; // number of special ports
2257 for (i = 1; i <= cx; i++)
2260 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2261 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2264 GravityFlag = LInfo.SpecialPort[i].Gravity;
2265 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2266 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2267 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2274 return subSpPortTest;
2277 void subCopyFieldToScreen(int si, int fi)
2281 // +++++++++++++++++++++++++++++++++++++++++
2282 X = GetStretchX(si);
2283 Y = GetStretchY(si);
2284 StretchedSprites.BltEx(X, Y, fi);
2285 // +++++++++++++++++++++++++++++++++++++++++
2288 static void subEatRedDisk(int si)
2290 if (AllowRedDiskCheat == 0)
2292 if (RedDiskReleasePhase != 0)
2294 if (RedDiskReleaseMurphyPos == si)
2299 RedDiskCount = (RedDiskCount + 1) % 256;
2300 subDisplayRedDiskCount();
2303 int subAdjustZonksInfotronsAboveMurphy(int si)
2305 int subAdjustZonksInfotronsAboveMurphy;
2309 if (LowByte(PlayField16[si]) != fiExplosion)
2310 PlayField16[si] = 0;
2312 ax = PlayField16[si - FieldWidth];
2313 if (ax == 0 || ax == 0x9999)
2316 if (ax == fiZonk || ax == fiInfotron)
2318 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2321 return subAdjustZonksInfotronsAboveMurphy;
2323 loc_g_15A8: // empty above
2324 ax = PlayField16[si - FieldWidth - 1];
2325 if (ax == fiZonk || ax == fiInfotron)
2329 ax = PlayField16[si - FieldWidth + 1];
2330 if (ax == fiZonk || ax == fiInfotron)
2333 return subAdjustZonksInfotronsAboveMurphy;
2335 loc_g_15C5: // zonk/infotron above left
2336 ax = PlayField16[si - 1];
2337 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2340 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2341 PlayField16[si - FieldWidth] = 0x8888;
2342 return subAdjustZonksInfotronsAboveMurphy;
2344 loc_g_15E8: // zonk/infotron above right
2345 ax = PlayField16[si + 1];
2346 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2348 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2349 PlayField16[si - FieldWidth] = 0x8888;
2352 return subAdjustZonksInfotronsAboveMurphy;
2353 } // subAdjustZonksInfotronsAboveMurphy