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
43 MurphyMoveCounter = 0; // We have no Murphy! Exit!
44 return subAnimateMurphy;
47 MurphyMoveCounter = 1; // We have a Murphy!
48 MurphyExplodePos = si;
49 if (ax != 3) // yes--go proceed moving murphy?
50 goto locProceedMovingMurphy;
52 // FS: reset moving sequence variables
60 ScratchGravity = 0; // scratch gravity off
61 if (GravityFlag != 0) // Gravity? (1=gravity on)
63 bl = LowByte(PlayField16[si - FieldWidth]); // check above
64 if (! (bl == fiPortUp || bl == fiPortUpAndDown || bl == fiPortAllDirections))
66 if (PlayField16[si + FieldWidth] == 0) // gravity on and space below!
72 if (bl != 0) // a key was pressed!
73 goto locKeyPressed5FCF;
75 RedDiskReleaseFlag = 1;
76 if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
84 return subAnimateMurphy;
86 // ------------------------------------------------------------------
87 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
88 YawnSleepCounter = YawnSleepCounter + 1;
89 if (YawnSleepCounter == 4)
91 subCopyFieldToScreen(si, fiMurphy); // normal grin
92 return subAnimateMurphy;
95 if (YawnSleepCounter <= 500) // loc_g_5ED7:
96 return subAnimateMurphy;
98 if (YawnSleepCounter <= 522)
100 bx = (YawnSleepCounter - 500) / 2;
101 subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
102 return subAnimateMurphy;
105 if (YawnSleepCounter <= 1000)
106 return subAnimateMurphy;
108 if (YawnSleepCounter <= 1022)
110 bx = (YawnSleepCounter - 1000) / 2;
111 subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn again!
112 return subAnimateMurphy;
115 if (YawnSleepCounter <= 1600) // loc_g_5F3B:
116 return subAnimateMurphy;
118 if (YawnSleepCounter <= 1622)
120 bx = (YawnSleepCounter - 1600) / 2;
121 subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn again! - third time
122 return subAnimateMurphy;
125 if (YawnSleepCounter > 1654)
126 return subAnimateMurphy;
128 if (PlayField16[si - 1] == 0)
130 if (PlayField16[si + 1] == 0)
132 YawnSleepCounter = 36;
133 return subAnimateMurphy;
138 bx = (YawnSleepCounter - 1622) / 16;
139 subCopyFieldToScreen(si, aniMurphySleepRight + bx); // go to sleep
140 return subAnimateMurphy;
144 bx = (YawnSleepCounter - 1622) / 16;
145 subCopyFieldToScreen(si, aniMurphySleepLeft + bx); // go to sleep
146 return subAnimateMurphy;
148 // end of YAWN-SLEEP-Sequence
149 // ------------------------------------------------------------------
150 // ==========================================================================
151 // (Direct Jump) a key was pressed
152 // ==========================================================================
155 if (ScratchGravity == 0)
158 if (PlayField16[si + FieldWidth] != 0)
163 if (PlayField16[si - FieldWidth] == fiBase)
167 else if (bl == keyLeft)
169 if (PlayField16[si - 1] == fiBase)
173 else if (bl == keyRight)
175 if (PlayField16[si + 1] == fiBase)
179 bl = keyDown; // force moving down!
184 RedDiskReleaseFlag = 0; // moving down to up ...
190 RedDiskReleaseFlag = 0; // moving right to left ...
196 RedDiskReleaseFlag = 0; // moving up to down ...
202 RedDiskReleaseFlag = 0; // moving left to right ...
207 case keySpaceUp: // 5
208 RedDiskReleaseFlag = 0; // touching down to up ...
213 case keySpaceLeft: // 6
214 RedDiskReleaseFlag = 0; // touching right to left ...
219 case keySpaceDown: // 7
220 RedDiskReleaseFlag = 0; // touching up to down ...
225 case keySpaceRight: // 8
226 RedDiskReleaseFlag = 0; // touching left to right ...
232 goto loc_g_62E2; // no move ...
237 RedDiskReleaseFlag = 0;
238 return subAnimateMurphy;
242 // ==========================================================================
243 // moving down to up ...
244 // ==========================================================================
250 ax = PlayField16[si - FieldWidth];
261 if (ax == fiInfotron)
267 if (al == fiTerminal)
270 if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
276 if (al == fiYellowDisk)
279 if (! subMoveKillsMurphy(si - FieldWidth, ax, bl))
282 return subAnimateMurphy;
284 // ==========================================================================
285 // moving right to left ...
286 // ==========================================================================
292 MurphyVarFaceLeft = 1;
293 ax = PlayField16[si - 1];
304 if (ax == fiInfotron)
313 if (al == fiTerminal)
316 if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
322 if (ax == fiYellowDisk)
325 if (ax == fiOrangeDisk)
328 if (! subMoveKillsMurphy(si - 1, ax, bl))
331 return subAnimateMurphy;
333 // ==========================================================================
334 // moving up to down ...
335 // ==========================================================================
341 ax = PlayField16[si + FieldWidth];
352 if (ax == fiInfotron)
358 if (al == fiTerminal)
361 if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
367 if (al == fiYellowDisk)
370 if (! subMoveKillsMurphy(si + FieldWidth, ax, bl))
373 return subAnimateMurphy;
375 // ==========================================================================
376 // moving left to right ...
377 // ==========================================================================
383 MurphyVarFaceLeft = 0;
384 ax = PlayField16[si + 1];
395 if (ax == fiInfotron)
404 if (al == fiTerminal)
407 if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
413 if (al == fiYellowDisk)
416 if (ax == fiOrangeDisk)
419 if (! subMoveKillsMurphy(si + 1, ax, bl))
422 return subAnimateMurphy;
424 // ==========================================================================
425 // touching down to up ...
426 // ==========================================================================
431 dxPos = si - FieldWidth;
433 ax = PlayField16[si - FieldWidth];
442 if (ax == fiInfotron)
445 if (al == fiTerminal)
451 return subAnimateMurphy;
453 // ==========================================================================
454 // touching right to left ...
455 // ==========================================================================
462 MurphyVarFaceLeft = 1;
463 ax = PlayField16[si - 1];
471 if (ax == fiInfotron)
474 if (al == fiTerminal)
480 return subAnimateMurphy;
482 // ==========================================================================
483 // touching up to down ...
484 // ==========================================================================
489 dxPos = si + FieldWidth;
491 ax = PlayField16[si + FieldWidth];
499 if (ax == fiInfotron)
502 if (al == fiTerminal)
508 return subAnimateMurphy;
510 // ==========================================================================
511 // touching left to right ...
512 // ==========================================================================
519 MurphyVarFaceLeft = 0;
520 ax = PlayField16[si + 1];
528 if (ax == fiInfotron)
531 if (al == fiTerminal)
537 return subAnimateMurphy;
539 // ==========================================================================
540 // Release Red disk: no move ...
541 // ==========================================================================
547 if (LowByte(RedDiskCount) == 0)
548 return subAnimateMurphy;
550 if (LowByte(RedDiskReleasePhase) != 0)
551 return subAnimateMurphy;
553 if (LowByte(RedDiskReleaseFlag) != 1)
554 return subAnimateMurphy;
556 MovHighByte(&PlayField16[si], 0x2A);
557 MovingPictureSequencePhase = 0x40; // init picture move sequence
559 MovLowByte(&RedDiskReleasePhase, 1);
560 Mov(&RedDiskReleaseMurphyPos, si); // remember Murphy's location
563 // ==========================================================================
564 // SPACE moving down to up
565 // ==========================================================================
568 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
569 PlayField16[si - FieldWidth] = 0x103;
570 PlayField16[si] = 0x300;
571 si = si - FieldWidth;
572 goto loc_StopNoSplit;
574 // ==========================================================================
575 // SPACE moving right to left
576 // ==========================================================================
579 dx = aniMurphyEatLeft;
580 PlayField16[si - 1] = 0x203;
581 PlayField16[si] = 0x300;
583 goto loc_StopNoSplit;
585 // ==========================================================================
586 // SPACE moving up to down, and when gravity is pulling!
587 // ==========================================================================
590 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
591 PlayField16[si + FieldWidth] = 0x303;
592 PlayField16[si] = 0x300;
593 si = si + FieldWidth;
594 goto loc_StopNoSplit;
596 // ==========================================================================
597 // SPACE moving left to right
598 // ==========================================================================
601 dx = aniMurphyEatRight;
602 PlayField16[si + 1] = 0x403;
603 PlayField16[si] = 0x300;
605 goto loc_StopNoSplit;
607 // ==========================================================================
608 // BUG moving down to up
609 // ==========================================================================
612 if (SgnHighByte(PlayField16[si - FieldWidth]) >= 0)
614 ExplodeFieldSP(si); // Explode
615 return subAnimateMurphy;
618 PlayField16[si - FieldWidth] = fiBase;
619 // ==========================================================================
620 // BASE moving down to up
621 // ==========================================================================
625 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
626 PlayField16[si - FieldWidth] = 0x503;
627 PlayField16[si] = 0x300;
628 si = si - FieldWidth;
629 goto loc_StopNoSplit;
631 // ==========================================================================
632 // BUG moving right to left
633 // ==========================================================================
636 if (SgnHighByte(PlayField16[si - 1]) >= 0)
638 ExplodeFieldSP(si); // Explode
639 return subAnimateMurphy;
642 PlayField16[si - 1] = fiBase;
643 // ==========================================================================
644 // BASE moving right to left
645 // ==========================================================================
649 dx = aniMurphyEatLeft;
650 PlayField16[si - 1] = 0x203;
651 PlayField16[si] = 0x300;
653 goto loc_StopNoSplit;
655 // ==========================================================================
656 // BUG moving up to down
657 // ==========================================================================
660 if (SgnHighByte(PlayField16[si + FieldWidth]) >= 0)
662 ExplodeFieldSP(si); // Explode
663 return subAnimateMurphy;
666 PlayField16[si + FieldWidth] = fiBase;
667 // ==========================================================================
668 // BASE moving up to down
669 // ==========================================================================
673 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
674 PlayField16[si + FieldWidth] = 0x703;
675 PlayField16[si] = 0x300;
676 si = si + FieldWidth;
677 goto loc_StopNoSplit;
679 // ==========================================================================
680 // BUG moving left to right
681 // ==========================================================================
684 if (SgnHighByte(PlayField16[si + 1]) >= 0)
686 ExplodeFieldSP(si); // Explode
687 return subAnimateMurphy;
690 PlayField16[si + 1] = fiBase;
691 // ==========================================================================
692 // BASE moving left to right
693 // ==========================================================================
697 dx = aniMurphyEatRight;
698 PlayField16[si + 1] = 0x803;
699 PlayField16[si] = 0x300;
701 goto loc_StopNoSplit;
703 // ==========================================================================
704 // BUG touching down to up
705 // ==========================================================================
708 if (SgnHighByte(PlayField16[si - FieldWidth]) >= 0)
710 ExplodeFieldSP(si); // Explode
711 return subAnimateMurphy;
714 PlayField16[si - FieldWidth] = fiBase;
715 // ==========================================================================
716 // BASE touching down to up
717 // ==========================================================================
720 subCopyFieldToScreen(si, aniMurphyTouchUp);
723 dxPos = si - FieldWidth;
724 MovHighByte(&PlayField16[si], 0x10);
725 goto loc_StopNoSplit;
727 // ==========================================================================
728 // BUG touching right to left
729 // ==========================================================================
732 if (SgnHighByte(PlayField16[si - 1]) >= 0)
734 ExplodeFieldSP(si); // Explode
735 return subAnimateMurphy;
738 PlayField16[si - 1] = fiBase;
739 // ==========================================================================
740 // BASE touching right to left
741 // ==========================================================================
744 subCopyFieldToScreen(si, aniMurphyTouchLeft);
748 MovHighByte(&PlayField16[si], 0x11);
749 goto loc_StopNoSplit;
751 // ==========================================================================
752 // BUG touching up to down
753 // ==========================================================================
756 if (SgnHighByte(PlayField16[si + FieldWidth]) >= 0)
758 ExplodeFieldSP(si); // Explode
759 return subAnimateMurphy;
762 PlayField16[si + FieldWidth] = fiBase;
763 // ==========================================================================
764 // BASE touching up to down
765 // ==========================================================================
768 subCopyFieldToScreen(si, aniMurphyTouchDown);
771 dxPos = si + FieldWidth;
772 MovHighByte(&PlayField16[si], 0x12);
773 goto loc_StopNoSplit;
775 // ==========================================================================
776 // BUG touching left to right
777 // ==========================================================================
780 if (SgnHighByte(PlayField16[si + 1]) >= 0)
782 ExplodeFieldSP(si); // Explode
783 return subAnimateMurphy;
786 PlayField16[si + 1] = fiBase;
787 // ==========================================================================
788 // BASE touching left to right
789 // ==========================================================================
792 subCopyFieldToScreen(si, aniMurphyTouchRight);
796 MovHighByte(&PlayField16[si], 0x13);
797 goto loc_StopNoSplit;
799 // ==========================================================================
800 // INFOTRON moving down to up
801 // ==========================================================================
804 subSoundFXInfotron();
805 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
806 PlayField16[si - FieldWidth] = 0x903;
807 PlayField16[si] = 0x300;
808 si = si - FieldWidth;
809 goto loc_StopNoSplit;
811 // ==========================================================================
812 // INFOTRON moving right to left
813 // ==========================================================================
816 subSoundFXInfotron();
817 dx = aniEatInfotronLeft;
821 PlayField16[si - 1] = 0xA03;
822 PlayField16[si] = 0x300;
824 goto loc_StopNoSplit;
826 // ==========================================================================
827 // INFOTRON moving up to down
828 // ==========================================================================
831 subSoundFXInfotron();
832 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
833 PlayField16[si + FieldWidth] = 0xB03;
834 PlayField16[si] = 0x300;
835 si = si + FieldWidth;
836 goto loc_StopNoSplit;
838 // ==========================================================================
839 // INFOTRON moving left to right
840 // ==========================================================================
843 subSoundFXInfotron();
844 dx = aniEatInfotronRight;
848 PlayField16[si + 1] = 0xC03;
849 PlayField16[si] = 0x300;
851 goto loc_StopNoSplit;
853 // ==========================================================================
854 // INFOTRON touching down to up
855 // ==========================================================================
858 subCopyFieldToScreen(si, aniMurphyTouchUp);
859 subSoundFXInfotron();
860 dx = aniTouchInfotron;
861 MovHighByte(&PlayField16[si], 0x14);
862 MovHighByte(&PlayField16[si - FieldWidth], 0xFF);
863 goto loc_StopNoSplit;
865 // ==========================================================================
866 // INFOTRON touching right to left
867 // ==========================================================================
870 subCopyFieldToScreen(si, aniMurphyTouchLeft);
871 subSoundFXInfotron();
872 dx = aniTouchInfotron;
873 MovHighByte(&PlayField16[si], 0x15);
874 MovHighByte(&PlayField16[si - 1], 0xFF);
875 goto loc_StopNoSplit;
877 // ==========================================================================
878 // INFOTRON touching up to down
879 // ==========================================================================
882 subCopyFieldToScreen(si, aniMurphyTouchDown);
883 subSoundFXInfotron();
884 dx = aniTouchInfotron;
885 MovHighByte(&PlayField16[si], 0x16);
886 MovHighByte(&PlayField16[si + FieldWidth], 0xFF);
887 goto loc_StopNoSplit;
889 // ==========================================================================
890 // INFOTRON touching left to right
891 // ==========================================================================
894 subCopyFieldToScreen(si, aniMurphyTouchRight);
895 subSoundFXInfotron();
896 dx = aniTouchInfotron;
897 MovHighByte(&PlayField16[si], 0x17);
898 MovHighByte(&PlayField16[si + 1], 0xFF);
899 goto loc_StopNoSplit;
901 // ==========================================================================
902 // EXIT pressed from any direction
903 // ==========================================================================
911 if (LowByte(InfotronsNeeded) != 0)
912 return subAnimateMurphy;
915 data_h_DemoDone = 1; // EP set level success bytes
916 LevelStatus = 1; // set Level Status DONE
917 EP_GameDemoVar0DAA = 0; // force demo for lead-out
918 if (SavedGameFlag == 0) // saved game running?
920 if (UpdateTimeFlag != 0) // update time?
922 UpdatedFlag = 1; // prevent double update
923 subUpdatePlayingTime(); // update playing time
928 subUpdateHallOfFame(); // update time + Hall-Of-Fame
931 LeadOutCounter = 0x40; // quit: start lead-out
933 MovHighByte(&PlayField16[si], 0xD);
934 goto loc_StopNoSplit;
936 // ==========================================================================
937 // ZONK moving right to left
938 // ==========================================================================
941 ax = PlayField16[si - 2];
943 return subAnimateMurphy;
945 MovHighByte(&PlayField16[si - 2], 1);
946 subCopyFieldToScreen(si, aniPushLeft); // draw pushing murphy
947 dx = aniZonkRollLeft;
951 MovHighByte(&PlayField16[si], 0xE);
952 goto loc_MoveNoSplit;
954 // ==========================================================================
955 // ZONK moving left to right
956 // ==========================================================================
959 ax = PlayField16[si + 2];
961 return subAnimateMurphy;
963 ax = PlayField16[si + FieldWidth + 1];
964 if (ax == 0) // zonk falls
965 return subAnimateMurphy;
967 MovHighByte(&PlayField16[si + 2], 1);
968 subCopyFieldToScreen(si, aniPushRight); // draw pushing murphy
969 dx = aniZonkRollRight;
973 MovHighByte(&PlayField16[si], 0xF);
974 goto loc_MoveNoSplit;
976 // ==========================================================================
977 // TERMINAL moving/touching down to up
978 // ==========================================================================
981 subCopyFieldToScreen(si, aniMurphyTouchUp);
982 if (YellowDisksExploded != 0)
984 YawnSleepCounter = 10; // stay hypnotized
985 return subAnimateMurphy;
988 subCopyFieldToScreen(si - FieldWidth, 0x88); // draw new terminal type
989 TerminalState[si - FieldWidth] = 8;
992 // ==========================================================================
993 // TERMINAL moving/touching right to left
994 // ==========================================================================
997 subCopyFieldToScreen(si, aniMurphyTouchLeft);
998 if (YellowDisksExploded != 0)
1000 YawnSleepCounter = 10; // stay hypnotized
1001 return subAnimateMurphy;
1004 subCopyFieldToScreen(si - 1, 0x88); // draw new terminal type
1005 TerminalState[si - 1] = 8;
1008 // ==========================================================================
1009 // TERMINAL moving/touching up to down
1010 // ==========================================================================
1013 subCopyFieldToScreen(si, aniMurphyTouchDown);
1014 if (YellowDisksExploded != 0)
1016 YawnSleepCounter = 10; // stay hypnotized
1017 return subAnimateMurphy;
1020 subCopyFieldToScreen(si + FieldWidth, 0x88); // draw new terminal type
1021 TerminalState[si + FieldWidth] = 8;
1024 // ==========================================================================
1025 // TERMINAL moving/touching left to right
1026 // ==========================================================================
1029 subCopyFieldToScreen(si, aniMurphyTouchRight);
1030 if (YellowDisksExploded != 0)
1032 YawnSleepCounter = 10; // stay hypnotized
1033 return subAnimateMurphy;
1036 subCopyFieldToScreen(si + 1, 0x88); // draw new terminal type
1037 TerminalState[si + 1] = 8;
1038 // ==========================================================================
1039 // common TERMINAL stuff moving/touching from all directions
1040 // ==========================================================================
1043 TerminalMaxCycles = 7;
1044 YellowDisksExploded = 1;
1045 for (i = 0; i <= LevelMax; i++)
1047 if (PlayField16[i] == fiYellowDisk)
1051 return subAnimateMurphy;
1053 // ==========================================================================
1054 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1055 // ==========================================================================
1058 if (PlayField16[si - 2 * FieldWidth] != 0)
1059 return subAnimateMurphy;
1061 dx = aniSplitUpDown;
1062 dx2Step = -FieldWidth;
1063 PlayField16[si] = 0x1803;
1064 PlayField16[si - 2 * FieldWidth] = 0x300;
1067 // ==========================================================================
1068 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1069 // ==========================================================================
1072 if (PlayField16[si - 2] != 0)
1073 return subAnimateMurphy;
1075 dx = aniMurphyEatLeft;
1077 PlayField16[si] = 0x1903;
1078 PlayField16[si - 2] = 0x300;
1081 // ==========================================================================
1082 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1083 // ==========================================================================
1086 if (PlayField16[si + 2 * FieldWidth] != 0)
1087 return subAnimateMurphy;
1089 dx = aniSplitUpDown;
1090 dx2Step = FieldWidth;
1091 PlayField16[si] = 0x1A03;
1092 PlayField16[si + 2 * FieldWidth] = 0x300;
1095 // ==========================================================================
1096 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1097 // ==========================================================================
1100 if (PlayField16[si + 2] != 0)
1101 return subAnimateMurphy;
1103 dx = aniMurphyEatRight;
1105 PlayField16[si] = 0x1B03;
1106 PlayField16[si + 2] = 0x300;
1109 MovingPictureSequencePhase = 0; // stop picture move sequence
1110 SplitMoveFlag = 1; // port: split movement
1113 // ==========================================================================
1114 // RED DISK moving down to up
1115 // ==========================================================================
1118 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1119 PlayField16[si] = 0x1C03;
1120 PlayField16[si - FieldWidth] = 0x300;
1121 goto loc_StopNoSplit;
1123 // ==========================================================================
1124 // RED DISK moving right to left
1125 // ==========================================================================
1128 dx = aniMurphyEatLeft;
1129 PlayField16[si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1130 PlayField16[si - 1] = 0x1D03;
1132 goto loc_StopNoSplit;
1134 // ==========================================================================
1135 // RED DISK moving up to down
1136 // ==========================================================================
1139 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1140 PlayField16[si] = 0x1E03;
1141 PlayField16[si + FieldWidth] = 0x300;
1142 goto loc_StopNoSplit;
1144 // ==========================================================================
1145 // RED DISK moving left to right
1146 // ==========================================================================
1149 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1150 dx = aniMurphyEatRight;
1151 // --------------------------------------------------------------------------
1153 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1154 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1155 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1156 // We may not fix the table, because then the timing of the game changes
1157 // and several existing demo's do not run properly anymore.
1158 // We only correct Murphies x-location here, when the sequence starts.
1159 // Remember that this is not the real bug-fix, but we must live with
1160 // this existing bug and correct for the consequences of it.
1161 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1162 MurphyScreenXPos = MurphyScreenXPos - 2;
1165 // FS: for me this means to blit the first animation frame twice
1167 // --------------------------------------------------------------------------
1168 PlayField16[si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1169 PlayField16[si + 1] = 0x1F03;
1171 goto loc_StopNoSplit;
1173 // ==========================================================================
1174 // RED DISK touching down to up
1175 // ==========================================================================
1178 dx = aniTouchRedDisk;
1179 MovHighByte(&PlayField16[si], 0x20);
1180 MovHighByte(&PlayField16[si - FieldWidth], 3);
1181 goto loc_StopNoSplit;
1183 // ==========================================================================
1184 // RED DISK touching right to left
1185 // ==========================================================================
1188 dx = aniTouchRedDisk;
1189 MovHighByte(&PlayField16[si], 0x21);
1190 MovHighByte(&PlayField16[si - 1], 3);
1191 goto loc_StopNoSplit;
1193 // ==========================================================================
1194 // RED DISK touching up to down
1195 // ==========================================================================
1198 dx = aniTouchRedDisk;
1199 MovHighByte(&PlayField16[si], 0x22);
1200 MovHighByte(&PlayField16[si + FieldWidth], 3);
1201 goto loc_StopNoSplit;
1203 // ==========================================================================
1204 // RED DISK touching left to right
1205 // ==========================================================================
1208 dx = aniTouchRedDisk;
1209 MovHighByte(&PlayField16[si], 0x23);
1210 MovHighByte(&PlayField16[si + 1], 3);
1213 MovingPictureSequencePhase = 0; // stop picture move sequence
1216 // ==========================================================================
1217 // YELLOW DISK moving down to up
1218 // ==========================================================================
1221 if (PlayField16[si - 2 * FieldWidth] != 0)
1222 return subAnimateMurphy;
1224 PlayField16[si - 2 * FieldWidth] = 0x1200;
1225 subCopyFieldToScreen(si, aniPushRight);
1227 dxPos = si - FieldWidth;
1228 dx2 = aniPushUpDown;
1229 dx2Step = FieldWidth;
1230 PlayField16[si] = 0x2403;
1231 goto loc_MoveNoSplit;
1233 // ==========================================================================
1234 // YELLOW DISK moving right to left
1235 // ==========================================================================
1238 if (PlayField16[si - 2] != 0)
1239 return subAnimateMurphy;
1241 PlayField16[si - 2] = 0x1200;
1242 subCopyFieldToScreen(si, aniPushLeft);
1247 PlayField16[si] = 0x2503;
1248 goto loc_MoveNoSplit;
1250 // ==========================================================================
1251 // YELLOW DISK moving up to down
1252 // ==========================================================================
1255 if (PlayField16[si + 2 * FieldWidth] != 0)
1256 return subAnimateMurphy;
1258 PlayField16[si + 2 * FieldWidth] = 0x1200;
1259 subCopyFieldToScreen(si, aniPushRight);
1261 dxPos = si + FieldWidth;
1262 dx2 = aniPushUpDown;
1263 dx2Step = -FieldWidth;
1264 PlayField16[si] = 0x2703;
1265 goto loc_MoveNoSplit;
1267 // ==========================================================================
1268 // YELLOW DISK moving left to right
1269 // ==========================================================================
1272 if (PlayField16[si + 2] != 0)
1273 return subAnimateMurphy;
1275 PlayField16[si + 2] = 0x1200;
1276 subCopyFieldToScreen(si, aniPushRight);
1281 PlayField16[si] = 0x2603;
1282 goto loc_MoveNoSplit;
1284 // ==========================================================================
1285 // ORANGE DISK moving right to left
1286 // ==========================================================================
1289 if (PlayField16[si - 2] != 0)
1290 return subAnimateMurphy;
1292 PlayField16[si - 2] = 0x800;
1293 subCopyFieldToScreen(si, aniPushLeft);
1298 PlayField16[si] = 0x2803;
1299 goto loc_MoveNoSplit;
1301 // ==========================================================================
1302 // ORANGE DISK moving left to right
1303 // ==========================================================================
1306 if (PlayField16[si + 2] != 0)
1307 return subAnimateMurphy;
1309 if (PlayField16[si + FieldWidth + 1] == 0) // falling goes before pushing
1310 return subAnimateMurphy;
1312 PlayField16[si + 2] = 0x100;
1313 subCopyFieldToScreen(si, aniPushRight);
1318 PlayField16[si] = 0x2903;
1319 // ==========================================================================
1320 // Copy screen animation action table to action work space
1321 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1322 // ==========================================================================
1325 MovingPictureSequencePhase = 8; // init picture move sequence
1328 SplitMoveFlag = 0; // no port: no split movement
1331 // copy/store global move sequence info????????????????????????????????????
1332 // ... dont think so ...(FS)
1333 // ==========================================================================
1334 // Proceed with all movements
1335 // ==========================================================================
1337 locProceedMovingMurphy: // proceed moving murphy
1338 YawnSleepCounter = 0; // Wake up sleeping Murphy
1339 ax = MovingPictureSequencePhase; // sequence busy?
1340 if (ax == 0) // no -- start sequence!
1343 ax = ax - 1; // next picture of sequence
1344 MovingPictureSequencePhase = ax; // store for later
1345 if (ax == 0) // Sound effects
1348 bl = HighByte(PlayField16[si]);
1349 if (bl == 0xE) // Push Zonk to left
1352 if (bl == 0xF) // Push Zonk to right
1355 if (bl == 0x28) // Push orange disk to left
1358 if (bl == 0x29) // Push orange disk to right
1361 if (bl == 0x24) // Push yellow disk up
1364 if (bl == 0x25) // Push yellow disk to left
1367 if (bl == 0x27) // Push yellow disk down
1370 if (bl == 0x26) // Push yellow disk to right
1373 if (bl == 0x2A) // Red disk release timer
1376 return subAnimateMurphy;
1378 // ==========================================================================
1379 // Paint frame of MOVING.DAT sequence
1380 // ==========================================================================
1383 if (SplitMoveFlag == 0)
1385 // ++++++++++++++++++++++++++
1386 // Begin of normal movement
1387 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1388 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1389 if (! ClearPos < 0) // clear field that murphy is leaving
1390 subCopyFieldToScreen(ClearPos, 0);
1392 if (dx2 == fiInfotron) // special case of infotron moving left or right
1399 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1400 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1403 X = GetStretchX(dxPos) + tDeltaX;
1404 Y = GetStretchY(dxPos) + tDeltaY;
1405 Tmp = (SeqPos < 0 ? 0 : 0); // 9StepBugFix!(red disk move right)
1406 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1409 tPos = dxPos + dx2Step;
1410 X = GetStretchX(tPos);
1411 Y = GetStretchY(tPos);
1412 if (dx2 == fiInfotron) // special case of infotron moving left or right
1414 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1416 else // pushing something
1418 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1422 // End of normal movement
1423 // ------------------------
1427 // ++++++++++++++++++++++++++++++++
1428 // Begin of split movement (port)
1429 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1430 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1431 subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1432 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1433 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1434 X = GetStretchX(dxPos) + tDeltaX;
1435 Y = GetStretchY(dxPos) + tDeltaY;
1436 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1437 tPos = dxPos + dx2Step;
1438 X = GetStretchX(tPos);
1439 Y = GetStretchY(tPos);
1440 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1441 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1442 // End of split movement (port)
1443 // ------------------------------
1444 } // loc_g_6D1E:'loc_g_6D28:
1446 SeqPos = SeqPos + 1;
1447 if (dx[SeqPos] > -1)
1448 return subAnimateMurphy;
1450 // Follow-up after movement completed 'loc_g_6D35:
1451 MurphyXPos = MurphyXPos + MurphyDX;
1452 MurphyYPos = MurphyYPos + MurphyDY;
1453 bl = HighByte(PlayField16[si]); // animation phase
1454 MovHighByte(&PlayField16[si], 0);
1456 if (bl == 0x1) // space, moving up
1459 if (bl == 0x2) // space, moving left
1462 if (bl == 0x3) // space, moving down
1465 if (bl == 0x4) // space, moving right
1468 if (bl == 0x5) // base , moving up
1471 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1474 if (bl == 0x7) // base , moving down
1477 if (bl == 0x8) // base , moving right
1480 if (bl == 0x9) // infotron, moving up
1483 if (bl == 0xA) // infotron, moving left
1486 if (bl == 0xB) // infotron, moving down
1489 if (bl == 0xC) // infotron, moving right
1492 if (bl == 0xD) // exit
1495 if (bl == 0xE) // zonk, pushing left
1498 if (bl == 0xF) // zonk, pushing right
1501 if (bl == 0x10) // base , touching up
1504 if (bl == 0x11) // base , touching left
1507 if (bl == 0x12) // base , touching down
1510 if (bl == 0x13) // base , touching right
1513 if (bl == 0x14) // infotron touching up
1516 if (bl == 0x15) // infotron touching left
1519 if (bl == 0x16) // infotron touching down
1522 if (bl == 0x17) // infotron touching right
1525 if (bl == 0x18) // port up
1528 if (bl == 0x19) // port left
1531 if (bl == 0x1A) // port down
1534 if (bl == 0x1B) // port right
1537 if (bl == 0x1C) // red disk, moving up
1540 if (bl == 0x1D) // red disk, moving left
1543 if (bl == 0x1E) // red disk, moving down
1546 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1549 if (bl == 0x20) // red disk, touching up
1552 if (bl == 0x21) // red disk, touching left
1555 if (bl == 0x22) // red disk, touching down
1558 if (bl == 0x23) // red disk, touching right
1561 if (bl == 0x24) // yellow disk, pushing up
1564 if (bl == 0x25) // yellow disk, pushing left
1567 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1570 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1573 if (bl == 0x28) // orange disk, pushing left
1576 if (bl == 0x29) // orange disk, pushing right
1579 if (bl == 0x2A) // red disk, release
1583 return subAnimateMurphy;
1585 // ==========================================================================
1586 // infotron, moving up
1587 // ==========================================================================
1590 if (0 < LowByte(InfotronsNeeded))
1591 InfotronsNeeded = InfotronsNeeded - 1;
1593 subDisplayInfotronsNeeded();
1594 loc_g_6EC8: // space, base
1595 PlayField16[si] = fiMurphy;
1596 subAdjustZonksInfotronsAboveMurphy(si + FieldWidth);
1597 return subAnimateMurphy;
1599 // ==========================================================================
1600 // infotron, moving left
1601 // ==========================================================================
1604 if (0 < LowByte(InfotronsNeeded))
1605 InfotronsNeeded = InfotronsNeeded - 1;
1607 subDisplayInfotronsNeeded();
1608 loc_g_6EE6: // space, base
1609 PlayField16[si] = fiMurphy;
1610 subAdjustZonksInfotronsAboveMurphy(si + 1);
1611 return subAnimateMurphy;
1613 // ==========================================================================
1614 // infotron, moving down
1615 // ==========================================================================
1618 if (0 < LowByte(InfotronsNeeded))
1619 InfotronsNeeded = InfotronsNeeded - 1;
1621 subDisplayInfotronsNeeded();
1622 loc_g_6F04: // space, base
1623 if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
1624 PlayField16[si - FieldWidth] = 0;
1626 PlayField16[si] = fiMurphy;
1627 return subAnimateMurphy;
1629 // ==========================================================================
1630 // infotron, moving right
1631 // ==========================================================================
1634 if (0 < LowByte(InfotronsNeeded))
1635 InfotronsNeeded = InfotronsNeeded - 1;
1637 subDisplayInfotronsNeeded();
1638 loc_g_71C4: // space, base
1639 subAdjustZonksInfotronsAboveMurphy(si - 1);
1640 PlayField16[si] = fiMurphy;
1641 return subAnimateMurphy;
1643 // ==========================================================================
1644 // infotron, touching up
1645 // ==========================================================================
1648 if (0 < LowByte(InfotronsNeeded))
1649 InfotronsNeeded = InfotronsNeeded - 1;
1651 subDisplayInfotronsNeeded();
1653 if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
1654 PlayField16[si - FieldWidth] = 0;
1656 return subAnimateMurphy;
1658 // ==========================================================================
1659 // infotron, touching left
1660 // ==========================================================================
1663 if (0 < LowByte(InfotronsNeeded))
1664 InfotronsNeeded = InfotronsNeeded - 1;
1666 subDisplayInfotronsNeeded();
1668 if (LowByte(PlayField16[si - 1]) != fiExplosion)
1669 PlayField16[si - 1] = 0;
1671 return subAnimateMurphy;
1673 // ==========================================================================
1674 // infotron, touching down
1675 // ==========================================================================
1678 if (0 < LowByte(InfotronsNeeded))
1679 InfotronsNeeded = InfotronsNeeded - 1;
1681 subDisplayInfotronsNeeded();
1683 if (LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
1684 PlayField16[si + FieldWidth] = 0;
1686 return subAnimateMurphy;
1688 // ==========================================================================
1689 // infotron, touching right
1690 // ==========================================================================
1693 if (0 < LowByte(InfotronsNeeded))
1694 InfotronsNeeded = InfotronsNeeded - 1;
1696 subDisplayInfotronsNeeded();
1698 if (LowByte(PlayField16[si + 1]) != fiExplosion)
1699 PlayField16[si + 1] = 0;
1701 return subAnimateMurphy;
1703 // ==========================================================================
1704 // zonk, pushing left
1705 // ==========================================================================
1708 if (LowByte(PlayField16[si]) != fiExplosion)
1709 PlayField16[si] = 0;
1711 PlayField16[si - 1] = fiMurphy;
1712 PlayField16[si - 2] = fiZonk;
1713 subExplodeSnikSnaksBelow(si - 2);
1715 return subAnimateMurphy;
1717 // ==========================================================================
1718 // zonk, pushing right
1719 // ==========================================================================
1722 if (LowByte(PlayField16[si]) != fiExplosion)
1723 PlayField16[si] = 0;
1725 PlayField16[si + 1] = fiMurphy;
1726 PlayField16[si + 2] = fiZonk;
1727 subExplodeSnikSnaksBelow(si + 2);
1729 return subAnimateMurphy;
1731 // ==========================================================================
1733 // ==========================================================================
1737 return subAnimateMurphy;
1739 // ==========================================================================
1740 // Push Zonk from right to left
1741 // ==========================================================================
1744 if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiZonk)
1745 return subAnimateMurphy;
1747 PlayField16[si] = fiMurphy; // else restore - no more zonk pushing!
1748 PlayField16[si - 1] = fiZonk;
1749 if (LowByte(PlayField16[si - 2]) != fiExplosion)
1750 PlayField16[si - 2] = 0;
1752 subCopyFieldToScreen(si, fiMurphy);
1753 return subAnimateMurphy;
1755 // ==========================================================================
1756 // Push Zonk from left to right
1757 // ==========================================================================
1760 if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiZonk)
1761 return subAnimateMurphy;
1763 PlayField16[si] = fiMurphy; // else restore - no more zonk pushing!
1764 PlayField16[si + 1] = fiZonk;
1765 if (LowByte(PlayField16[si + 2]) != fiExplosion)
1766 PlayField16[si + 2] = 0;
1768 subCopyFieldToScreen(si, fiMurphy);
1769 return subAnimateMurphy;
1771 // ==========================================================================
1772 // Push orange disk from right to left
1773 // ==========================================================================
1776 if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiOrangeDisk)
1777 return subAnimateMurphy;
1779 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1780 PlayField16[si - 1] = fiOrangeDisk;
1781 if (LowByte(PlayField16[si - 2]) != fiExplosion)
1782 PlayField16[si - 2] = 0;
1784 subCopyFieldToScreen(si, fiMurphy);
1785 return subAnimateMurphy;
1787 // ==========================================================================
1788 // Push orange disk from left to right
1789 // ==========================================================================
1792 if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiOrangeDisk)
1793 return subAnimateMurphy;
1795 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1796 PlayField16[si + 1] = fiOrangeDisk;
1797 if (LowByte(PlayField16[si + 2]) != fiExplosion)
1798 PlayField16[si + 2] = 0;
1800 subCopyFieldToScreen(si, fiMurphy);
1801 return subAnimateMurphy;
1803 // ==========================================================================
1804 // Push yellow disk from down to up
1805 // ==========================================================================
1808 if (DemoKeyCode == keyUp && PlayField16[si - FieldWidth] == fiYellowDisk)
1809 return subAnimateMurphy;
1811 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1812 PlayField16[si - FieldWidth] = fiYellowDisk;
1813 if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiExplosion)
1814 PlayField16[si - 2 * FieldWidth] = 0;
1816 subCopyFieldToScreen(si, fiMurphy);
1817 return subAnimateMurphy;
1819 // ==========================================================================
1820 // Push yellow disk from right to left
1821 // ==========================================================================
1824 if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiYellowDisk)
1825 return subAnimateMurphy;
1827 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1828 PlayField16[si - 1] = fiYellowDisk;
1829 if (LowByte(PlayField16[si - 2]) != fiExplosion)
1830 PlayField16[si - 2] = 0;
1832 subCopyFieldToScreen(si, fiMurphy);
1833 return subAnimateMurphy;
1835 // ==========================================================================
1836 // Push yellow disk from up to down
1837 // ==========================================================================
1840 if (DemoKeyCode == keyDown && PlayField16[si + FieldWidth] == fiYellowDisk)
1841 return subAnimateMurphy;
1843 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1844 PlayField16[si + FieldWidth] = fiYellowDisk;
1845 if (LowByte(PlayField16[si + 2 * FieldWidth]) != fiExplosion)
1846 PlayField16[si + 2 * FieldWidth] = 0;
1848 subCopyFieldToScreen(si, fiMurphy);
1849 return subAnimateMurphy;
1851 // ==========================================================================
1852 // Push yellow disk from left to right
1853 // ==========================================================================
1856 if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiYellowDisk)
1857 return subAnimateMurphy;
1859 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1860 PlayField16[si + 1] = fiYellowDisk;
1861 if (LowByte(PlayField16[si + 2]) != fiExplosion)
1862 PlayField16[si + 2] = 0;
1864 subCopyFieldToScreen(si, fiMurphy);
1865 return subAnimateMurphy;
1867 // ==========================================================================
1868 // time red disk release (space)
1869 // ==========================================================================
1872 if (DemoKeyCode != keySpace)
1874 PlayField16[si] = fiMurphy;
1875 subCopyFieldToScreen(si, fiMurphy);
1876 RedDiskReleasePhase = 0;
1878 else if (MovingPictureSequencePhase == 0x20)
1880 subCopyFieldToScreen(si, 43); // anxious murphy
1881 RedDiskReleasePhase = 1;
1884 return subAnimateMurphy;
1886 // ==========================================================================
1887 // Special port down to up
1888 // ==========================================================================
1891 if (LowByte(PlayField16[si]) != fiExplosion)
1892 PlayField16[si] = 0;
1894 PlayField16[si - 2 * FieldWidth] = fiMurphy;
1896 si = si - FieldWidth;
1897 if (HighByte(PlayField16[si]) == 1)
1900 si = si - FieldWidth;
1901 return subAnimateMurphy;
1903 // ==========================================================================
1904 // Special port right to left
1905 // ==========================================================================
1908 if (LowByte(PlayField16[si]) != fiExplosion)
1909 PlayField16[si] = 0;
1911 PlayField16[si - 2] = fiMurphy;
1914 if (HighByte(PlayField16[si]) == 1)
1918 return subAnimateMurphy;
1920 // ==========================================================================
1921 // Special port up to down
1922 // ==========================================================================
1925 if (LowByte(PlayField16[si]) != fiExplosion)
1926 PlayField16[si] = 0;
1928 PlayField16[si + 2 * FieldWidth] = fiMurphy;
1930 si = si + FieldWidth;
1931 if (HighByte(PlayField16[si]) == 1)
1934 si = si + FieldWidth;
1935 return subAnimateMurphy;
1937 // ==========================================================================
1938 // Special port left to right
1939 // ==========================================================================
1942 if (LowByte(PlayField16[si]) != fiExplosion)
1943 PlayField16[si] = 0;
1945 PlayField16[si + 2] = fiMurphy;
1948 if (HighByte(PlayField16[si]) == 1)
1952 return subAnimateMurphy;
1954 // ==========================================================================
1956 // ==========================================================================
1959 if (LowByte(PlayField16[si]) != fiExplosion)
1960 PlayField16[si] = 0;
1962 si = si - FieldWidth;
1963 PlayField16[si] = fiMurphy;
1964 subEatRedDisk(si); // inc+show Murphy's red disks
1965 return subAnimateMurphy;
1967 // ==========================================================================
1968 // Move Red Disk left
1969 // ==========================================================================
1972 if (LowByte(PlayField16[si + 1]) != fiExplosion)
1973 PlayField16[si + 1] = 0;
1975 PlayField16[si] = fiMurphy;
1976 subEatRedDisk(si); // inc+show Murphy's red disks
1977 return subAnimateMurphy;
1979 // ==========================================================================
1980 // Move Red Disk down
1981 // ==========================================================================
1984 if (LowByte(PlayField16[si]) != fiExplosion)
1985 PlayField16[si] = 0;
1987 si = si + FieldWidth;
1988 PlayField16[si] = fiMurphy;
1989 subEatRedDisk(si); // inc+show Murphy's red disks
1990 return subAnimateMurphy;
1992 // ==========================================================================
1993 // Move Red Disk right
1994 // ==========================================================================
1997 if (LowByte(PlayField16[si - 1]) != fiExplosion)
1998 PlayField16[si - 1] = 0;
2000 PlayField16[si] = fiMurphy;
2001 subEatRedDisk(si); // inc+show Murphy's red disks
2002 return subAnimateMurphy;
2004 // ==========================================================================
2006 // ==========================================================================
2009 if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
2010 PlayField16[si - FieldWidth] = 0;
2012 subEatRedDisk(si - FieldWidth); // inc+show Murphy's red disks
2013 return subAnimateMurphy;
2015 // ==========================================================================
2016 // Eat Red Disk left
2017 // ==========================================================================
2020 if (LowByte(PlayField16[si - 1]) != fiExplosion)
2021 PlayField16[si - 1] = 0;
2023 subEatRedDisk(si - 1); // inc+show Murphy's red disks
2024 return subAnimateMurphy;
2026 // ==========================================================================
2027 // Eat Red Disk down
2028 // ==========================================================================
2031 if (LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
2032 PlayField16[si + FieldWidth] = 0;
2034 subEatRedDisk(si + FieldWidth); // inc+show Murphy's red disks
2035 return subAnimateMurphy;
2037 // ==========================================================================
2038 // Eat Red Disk right
2039 // ==========================================================================
2042 if (LowByte(PlayField16[si + 1]) != fiExplosion)
2043 PlayField16[si + 1] = 0;
2045 subEatRedDisk(si + 1); // inc+show Murphy's red disks
2046 return subAnimateMurphy;
2048 // ==========================================================================
2049 // yellow disk, pushing up
2050 // ==========================================================================
2053 if (LowByte(PlayField16[si]) != fiExplosion)
2054 PlayField16[si] = 0;
2056 si = si - FieldWidth;
2057 PlayField16[si] = fiMurphy;
2058 PlayField16[si - FieldWidth] = fiYellowDisk;
2059 return subAnimateMurphy;
2061 // ==========================================================================
2062 // yellow disk, pushing left
2063 // ==========================================================================
2066 if (LowByte(PlayField16[si]) != fiExplosion)
2067 PlayField16[si] = 0;
2070 PlayField16[si] = fiMurphy;
2071 PlayField16[si - 1] = fiYellowDisk;
2072 return subAnimateMurphy;
2074 // ==========================================================================
2075 // yellow disk, pushing down
2076 // ==========================================================================
2079 if (LowByte(PlayField16[si]) != fiExplosion)
2080 PlayField16[si] = 0;
2082 si = si + FieldWidth;
2083 PlayField16[si] = fiMurphy;
2084 PlayField16[si + FieldWidth] = fiYellowDisk;
2085 return subAnimateMurphy;
2087 // ==========================================================================
2088 // yellow disk pushing right
2089 // ==========================================================================
2092 if (LowByte(PlayField16[si]) != fiExplosion)
2093 PlayField16[si] = 0;
2096 PlayField16[si] = fiMurphy;
2097 PlayField16[si + 1] = fiYellowDisk;
2098 return subAnimateMurphy;
2100 // ==========================================================================
2101 // orange disk, pushing left
2102 // ==========================================================================
2105 if (LowByte(PlayField16[si]) != fiExplosion)
2106 PlayField16[si] = 0;
2109 PlayField16[si] = fiMurphy;
2110 PlayField16[si - 1] = fiOrangeDisk;
2111 return subAnimateMurphy;
2113 // ==========================================================================
2114 // orange disk, pushing right
2115 // ==========================================================================
2118 if (LowByte(PlayField16[si]) != fiExplosion)
2119 PlayField16[si] = 0;
2122 PlayField16[si] = fiMurphy;
2123 PlayField16[si + 1] = fiOrangeDisk;
2124 if (PlayField16[si + FieldWidth + 1] == 0) // make it fall down if below is empty
2126 MovHighByte(&PlayField16[si + 1], 0x20);
2127 MovHighByte(&PlayField16[si + FieldWidth + 1], fiOrangeDisk);
2130 return subAnimateMurphy;
2132 // ==========================================================================
2133 // Release a red disk
2134 // ==========================================================================
2137 PlayField16[si] = fiMurphy;
2138 RedDiskReleasePhase = 2;
2139 RedDiskCount = RedDiskCount - 1;
2140 subDisplayRedDiskCount();
2141 subSoundFXPush(); // Sound effects
2143 return subAnimateMurphy;
2144 } // subAnimateMurphy
2146 // ==========================================================================
2148 // ==========================================================================
2149 int subExplodeSnikSnaksBelow(int si)
2151 int subExplodeSnikSnaksBelow;
2155 ax = LowByte(PlayField16[si + FieldWidth]);
2156 if (ax == 0x11 || ax == 0xBB)
2157 ExplodeFieldSP(si + FieldWidth);
2159 return subExplodeSnikSnaksBelow;
2160 } // subExplodeSnikSnaksBelow
2162 // ==========================================================================
2164 // Does pushing against an object kill Murphy?
2165 // ==========================================================================
2166 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2168 static boolean subMoveKillsMurphy;
2174 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2180 if (al == fiExplosion)
2183 if (fiOrangeDisk <= al && al <= fiPortUp)
2186 ExplodeFieldSP(si); // Explode
2187 subMoveKillsMurphy = True;
2188 return subMoveKillsMurphy;
2197 ExplodeFieldSP(si); // Explode
2198 subMoveKillsMurphy = True;
2199 return subMoveKillsMurphy;
2201 loc_g_74F6: // zonk left
2203 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2206 subMoveKillsMurphy = True; // Set carry flag
2207 return subMoveKillsMurphy;
2209 loc_g_7512: // zonk right
2211 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2214 loc_g_752E: // Marked fields and Ports
2215 subMoveKillsMurphy = True; // Set carry flag
2216 return subMoveKillsMurphy;
2218 loc_g_7530: // explosion
2219 if ((ah & 0x80) != 0)
2226 ExplodeFieldSP(si); // Explode
2227 subMoveKillsMurphy = True; // Set carry flag
2228 return subMoveKillsMurphy;
2231 PlayField16[si] = 0;
2232 subMoveKillsMurphy = False;
2234 return subMoveKillsMurphy;
2235 } // subMoveKillsMurphy
2237 // ==========================================================================
2239 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2240 // change conditions to port specs
2241 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2242 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2243 // ==========================================================================
2244 int subSpPortTest(int si)
2250 cx = LInfo.SpecialPortCount; // number of special ports
2251 for (i = 1; i <= cx; i++)
2254 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2255 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2258 GravityFlag = LInfo.SpecialPort[i].Gravity;
2259 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2260 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2261 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2268 return subSpPortTest;
2271 void subCopyFieldToScreen(int si, int fi)
2275 // +++++++++++++++++++++++++++++++++++++++++
2276 X = GetStretchX(si);
2277 Y = GetStretchY(si);
2278 StretchedSprites.BltEx(X, Y, fi);
2279 // +++++++++++++++++++++++++++++++++++++++++
2282 static void subEatRedDisk(int si)
2284 if (AllowRedDiskCheat == 0)
2286 if (RedDiskReleasePhase != 0)
2288 if (RedDiskReleaseMurphyPos == si)
2293 RedDiskCount = (RedDiskCount + 1) % 256;
2294 subDisplayRedDiskCount();
2297 int subAdjustZonksInfotronsAboveMurphy(int si)
2299 int subAdjustZonksInfotronsAboveMurphy;
2303 if (LowByte(PlayField16[si]) != fiExplosion)
2304 PlayField16[si] = 0;
2306 ax = PlayField16[si - FieldWidth];
2307 if (ax == 0 || ax == 0x9999)
2310 if (ax == fiZonk || ax == fiInfotron)
2312 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2315 return subAdjustZonksInfotronsAboveMurphy;
2317 loc_g_15A8: // empty above
2318 ax = PlayField16[si - FieldWidth - 1];
2319 if (ax == fiZonk || ax == fiInfotron)
2323 ax = PlayField16[si - FieldWidth + 1];
2324 if (ax == fiZonk || ax == fiInfotron)
2327 return subAdjustZonksInfotronsAboveMurphy;
2329 loc_g_15C5: // zonk/infotron above left
2330 ax = PlayField16[si - 1];
2331 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2334 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2335 PlayField16[si - FieldWidth] = 0x8888;
2336 return subAdjustZonksInfotronsAboveMurphy;
2338 loc_g_15E8: // zonk/infotron above right
2339 ax = PlayField16[si + 1];
2340 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2342 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2343 PlayField16[si - FieldWidth] = 0x8888;
2346 return subAdjustZonksInfotronsAboveMurphy;
2347 } // subAdjustZonksInfotronsAboveMurphy