1 // ----------------------------------------------------------------------------
3 // ----------------------------------------------------------------------------
7 static void subEatRedDisk(int si);
8 static boolean subMoveKillsMurphy(int si, int ax, int bl);
10 static char *VB_Name = "modMurphy";
11 // --- Option Explicit
13 #define LocalStretch (1)
15 // ==========================================================================
17 // Move Murphy in any direction
18 // ==========================================================================
20 int subAnimateMurphy(int si)
24 int ax, al, ah, bx, bl, i, X, Y;
25 int tX, tY, tDeltaX, tDeltaY, tPos, Tmp;
27 // Variables that hold information about the animation sequence
28 int *dx; // an array of image positions in moving.mpx, finalized with -1
29 int dx2; // an additional image position of a second sprite, for instance: yellow disk if pushed
30 int MurphyDX, MurphyDY; // murphys move steps
31 int SeqPos; // index into dx()
32 int ClearPos; // Position to clear before blitting sprites, none=-1
33 int dxPos; // field-position to draw dx(SeqPos)
34 int dx2Step; // position of dx2 relative to dx-position
40 MurphyMoveCounter = 0; // We have no Murphy! Exit!
41 return subAnimateMurphy;
44 MurphyMoveCounter = 1; // We have a Murphy!
45 MurphyExplodePos = si;
46 if (ax != 3) // yes--go proceed moving murphy?
47 goto locProceedMovingMurphy;
49 // FS: reset moving sequence variables
57 ScratchGravity = 0; // scratch gravity off
58 if (GravityFlag != 0) // Gravity? (1=gravity on)
60 bl = LowByte(PlayField16[si - FieldWidth]); // check above
61 if (! (bl == fiPortUp || bl == fiPortUpAndDown || bl == fiPortAllDirections))
63 if (PlayField16[si + FieldWidth] == 0) // gravity on and space below!
69 if (bl != 0) // a key was pressed!
70 goto locKeyPressed5FCF;
72 RedDiskReleaseFlag = 1;
73 if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
81 return subAnimateMurphy;
83 // ------------------------------------------------------------------
84 // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
85 YawnSleepCounter = YawnSleepCounter + 1;
86 if (YawnSleepCounter == 4)
88 subCopyFieldToScreen(si, fiMurphy); // normal grin
89 return subAnimateMurphy;
92 if (YawnSleepCounter <= 500) // loc_g_5ED7:
93 return subAnimateMurphy;
95 if (YawnSleepCounter <= 522)
97 bx = (YawnSleepCounter - 500) / 2;
98 subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
99 return subAnimateMurphy;
102 if (YawnSleepCounter <= 1000)
103 return subAnimateMurphy;
105 if (YawnSleepCounter <= 1022)
107 bx = (YawnSleepCounter - 1000) / 2;
108 subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn again!
109 return subAnimateMurphy;
112 if (YawnSleepCounter <= 1600) // loc_g_5F3B:
113 return subAnimateMurphy;
115 if (YawnSleepCounter <= 1622)
117 bx = (YawnSleepCounter - 1600) / 2;
118 subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn again! - third time
119 return subAnimateMurphy;
122 if (YawnSleepCounter > 1654)
123 return subAnimateMurphy;
125 if (PlayField16[si - 1] == 0)
127 if (PlayField16[si + 1] == 0)
129 YawnSleepCounter = 36;
130 return subAnimateMurphy;
135 bx = (YawnSleepCounter - 1622) / 16;
136 subCopyFieldToScreen(si, aniMurphySleepRight + bx); // go to sleep
137 return subAnimateMurphy;
141 bx = (YawnSleepCounter - 1622) / 16;
142 subCopyFieldToScreen(si, aniMurphySleepLeft + bx); // go to sleep
143 return subAnimateMurphy;
145 // end of YAWN-SLEEP-Sequence
146 // ------------------------------------------------------------------
147 // ==========================================================================
148 // (Direct Jump) a key was pressed
149 // ==========================================================================
152 if (ScratchGravity == 0)
155 if (PlayField16[si + FieldWidth] != 0)
160 if (PlayField16[si - FieldWidth] == fiBase)
164 else if (bl == keyLeft)
166 if (PlayField16[si - 1] == fiBase)
170 else if (bl == keyRight)
172 if (PlayField16[si + 1] == fiBase)
176 bl = keyDown; // force moving down!
181 RedDiskReleaseFlag = 0; // moving down to up ...
187 RedDiskReleaseFlag = 0; // moving right to left ...
193 RedDiskReleaseFlag = 0; // moving up to down ...
199 RedDiskReleaseFlag = 0; // moving left to right ...
204 case keySpaceUp: // 5
205 RedDiskReleaseFlag = 0; // touching down to up ...
210 case keySpaceLeft: // 6
211 RedDiskReleaseFlag = 0; // touching right to left ...
216 case keySpaceDown: // 7
217 RedDiskReleaseFlag = 0; // touching up to down ...
222 case keySpaceRight: // 8
223 RedDiskReleaseFlag = 0; // touching left to right ...
229 goto loc_g_62E2; // no move ...
234 RedDiskReleaseFlag = 0;
235 return subAnimateMurphy;
239 // ==========================================================================
240 // moving down to up ...
241 // ==========================================================================
247 ax = PlayField16[si - FieldWidth];
258 if (ax == fiInfotron)
264 if (al == fiTerminal)
267 if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
273 if (al == fiYellowDisk)
276 if (! subMoveKillsMurphy(si - FieldWidth, ax, bl))
279 return subAnimateMurphy;
281 // ==========================================================================
282 // moving right to left ...
283 // ==========================================================================
289 MurphyVarFaceLeft = 1;
290 ax = PlayField16[si - 1];
301 if (ax == fiInfotron)
310 if (al == fiTerminal)
313 if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
319 if (ax == fiYellowDisk)
322 if (ax == fiOrangeDisk)
325 if (! subMoveKillsMurphy(si - 1, ax, bl))
328 return subAnimateMurphy;
330 // ==========================================================================
331 // moving up to down ...
332 // ==========================================================================
338 ax = PlayField16[si + FieldWidth];
349 if (ax == fiInfotron)
355 if (al == fiTerminal)
358 if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
364 if (al == fiYellowDisk)
367 if (! subMoveKillsMurphy(si + FieldWidth, ax, bl))
370 return subAnimateMurphy;
372 // ==========================================================================
373 // moving left to right ...
374 // ==========================================================================
380 MurphyVarFaceLeft = 0;
381 ax = PlayField16[si + 1];
392 if (ax == fiInfotron)
401 if (al == fiTerminal)
404 if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
410 if (al == fiYellowDisk)
413 if (ax == fiOrangeDisk)
416 if (! subMoveKillsMurphy(si + 1, ax, bl))
419 return subAnimateMurphy;
421 // ==========================================================================
422 // touching down to up ...
423 // ==========================================================================
428 dxPos = si - FieldWidth;
430 ax = PlayField16[si - FieldWidth];
439 if (ax == fiInfotron)
442 if (al == fiTerminal)
448 return subAnimateMurphy;
450 // ==========================================================================
451 // touching right to left ...
452 // ==========================================================================
459 MurphyVarFaceLeft = 1;
460 ax = PlayField16[si - 1];
468 if (ax == fiInfotron)
471 if (al == fiTerminal)
477 return subAnimateMurphy;
479 // ==========================================================================
480 // touching up to down ...
481 // ==========================================================================
486 dxPos = si + FieldWidth;
488 ax = PlayField16[si + FieldWidth];
496 if (ax == fiInfotron)
499 if (al == fiTerminal)
505 return subAnimateMurphy;
507 // ==========================================================================
508 // touching left to right ...
509 // ==========================================================================
516 MurphyVarFaceLeft = 0;
517 ax = PlayField16[si + 1];
525 if (ax == fiInfotron)
528 if (al == fiTerminal)
534 return subAnimateMurphy;
536 // ==========================================================================
537 // Release Red disk: no move ...
538 // ==========================================================================
544 if (LowByte(RedDiskCount) == 0)
545 return subAnimateMurphy;
547 if (LowByte(RedDiskReleasePhase) != 0)
548 return subAnimateMurphy;
550 if (LowByte(RedDiskReleaseFlag) != 1)
551 return subAnimateMurphy;
553 MovHighByte(&PlayField16[si], 0x2A);
554 MovingPictureSequencePhase = 0x40; // init picture move sequence
556 MovLowByte(&RedDiskReleasePhase, 1);
557 Mov(&RedDiskReleaseMurphyPos, si); // remember Murphy's location
560 // ==========================================================================
561 // SPACE moving down to up
562 // ==========================================================================
565 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
566 PlayField16[si - FieldWidth] = 0x103;
567 PlayField16[si] = 0x300;
568 si = si - FieldWidth;
569 goto loc_StopNoSplit;
571 // ==========================================================================
572 // SPACE moving right to left
573 // ==========================================================================
576 dx = aniMurphyEatLeft;
577 PlayField16[si - 1] = 0x203;
578 PlayField16[si] = 0x300;
580 goto loc_StopNoSplit;
582 // ==========================================================================
583 // SPACE moving up to down, and when gravity is pulling!
584 // ==========================================================================
587 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
588 PlayField16[si + FieldWidth] = 0x303;
589 PlayField16[si] = 0x300;
590 si = si + FieldWidth;
591 goto loc_StopNoSplit;
593 // ==========================================================================
594 // SPACE moving left to right
595 // ==========================================================================
598 dx = aniMurphyEatRight;
599 PlayField16[si + 1] = 0x403;
600 PlayField16[si] = 0x300;
602 goto loc_StopNoSplit;
604 // ==========================================================================
605 // BUG moving down to up
606 // ==========================================================================
609 if (SgnHighByte(PlayField16[si - FieldWidth]) >= 0)
611 ExplodeFieldSP(si); // Explode
612 return subAnimateMurphy;
615 PlayField16[si - FieldWidth] = fiBase;
616 // ==========================================================================
617 // BASE moving down to up
618 // ==========================================================================
622 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
623 PlayField16[si - FieldWidth] = 0x503;
624 PlayField16[si] = 0x300;
625 si = si - FieldWidth;
626 goto loc_StopNoSplit;
628 // ==========================================================================
629 // BUG moving right to left
630 // ==========================================================================
633 if (SgnHighByte(PlayField16[si - 1]) >= 0)
635 ExplodeFieldSP(si); // Explode
636 return subAnimateMurphy;
639 PlayField16[si - 1] = fiBase;
640 // ==========================================================================
641 // BASE moving right to left
642 // ==========================================================================
646 dx = aniMurphyEatLeft;
647 PlayField16[si - 1] = 0x203;
648 PlayField16[si] = 0x300;
650 goto loc_StopNoSplit;
652 // ==========================================================================
653 // BUG moving up to down
654 // ==========================================================================
657 if (SgnHighByte(PlayField16[si + FieldWidth]) >= 0)
659 ExplodeFieldSP(si); // Explode
660 return subAnimateMurphy;
663 PlayField16[si + FieldWidth] = fiBase;
664 // ==========================================================================
665 // BASE moving up to down
666 // ==========================================================================
670 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
671 PlayField16[si + FieldWidth] = 0x703;
672 PlayField16[si] = 0x300;
673 si = si + FieldWidth;
674 goto loc_StopNoSplit;
676 // ==========================================================================
677 // BUG moving left to right
678 // ==========================================================================
681 if (SgnHighByte(PlayField16[si + 1]) >= 0)
683 ExplodeFieldSP(si); // Explode
684 return subAnimateMurphy;
687 PlayField16[si + 1] = fiBase;
688 // ==========================================================================
689 // BASE moving left to right
690 // ==========================================================================
694 dx = aniMurphyEatRight;
695 PlayField16[si + 1] = 0x803;
696 PlayField16[si] = 0x300;
698 goto loc_StopNoSplit;
700 // ==========================================================================
701 // BUG touching down to up
702 // ==========================================================================
705 if (SgnHighByte(PlayField16[si - FieldWidth]) >= 0)
707 ExplodeFieldSP(si); // Explode
708 return subAnimateMurphy;
711 PlayField16[si - FieldWidth] = fiBase;
712 // ==========================================================================
713 // BASE touching down to up
714 // ==========================================================================
717 subCopyFieldToScreen(si, aniMurphyTouchUp);
720 dxPos = si - FieldWidth;
721 MovHighByte(&PlayField16[si], 0x10);
722 goto loc_StopNoSplit;
724 // ==========================================================================
725 // BUG touching right to left
726 // ==========================================================================
729 if (SgnHighByte(PlayField16[si - 1]) >= 0)
731 ExplodeFieldSP(si); // Explode
732 return subAnimateMurphy;
735 PlayField16[si - 1] = fiBase;
736 // ==========================================================================
737 // BASE touching right to left
738 // ==========================================================================
741 subCopyFieldToScreen(si, aniMurphyTouchLeft);
745 MovHighByte(&PlayField16[si], 0x11);
746 goto loc_StopNoSplit;
748 // ==========================================================================
749 // BUG touching up to down
750 // ==========================================================================
753 if (SgnHighByte(PlayField16[si + FieldWidth]) >= 0)
755 ExplodeFieldSP(si); // Explode
756 return subAnimateMurphy;
759 PlayField16[si + FieldWidth] = fiBase;
760 // ==========================================================================
761 // BASE touching up to down
762 // ==========================================================================
765 subCopyFieldToScreen(si, aniMurphyTouchDown);
768 dxPos = si + FieldWidth;
769 MovHighByte(&PlayField16[si], 0x12);
770 goto loc_StopNoSplit;
772 // ==========================================================================
773 // BUG touching left to right
774 // ==========================================================================
777 if (SgnHighByte(PlayField16[si + 1]) >= 0)
779 ExplodeFieldSP(si); // Explode
780 return subAnimateMurphy;
783 PlayField16[si + 1] = fiBase;
784 // ==========================================================================
785 // BASE touching left to right
786 // ==========================================================================
789 subCopyFieldToScreen(si, aniMurphyTouchRight);
793 MovHighByte(&PlayField16[si], 0x13);
794 goto loc_StopNoSplit;
796 // ==========================================================================
797 // INFOTRON moving down to up
798 // ==========================================================================
801 subSoundFXInfotron();
802 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
803 PlayField16[si - FieldWidth] = 0x903;
804 PlayField16[si] = 0x300;
805 si = si - FieldWidth;
806 goto loc_StopNoSplit;
808 // ==========================================================================
809 // INFOTRON moving right to left
810 // ==========================================================================
813 subSoundFXInfotron();
814 dx = aniEatInfotronLeft;
818 PlayField16[si - 1] = 0xA03;
819 PlayField16[si] = 0x300;
821 goto loc_StopNoSplit;
823 // ==========================================================================
824 // INFOTRON moving up to down
825 // ==========================================================================
828 subSoundFXInfotron();
829 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
830 PlayField16[si + FieldWidth] = 0xB03;
831 PlayField16[si] = 0x300;
832 si = si + FieldWidth;
833 goto loc_StopNoSplit;
835 // ==========================================================================
836 // INFOTRON moving left to right
837 // ==========================================================================
840 subSoundFXInfotron();
841 dx = aniEatInfotronRight;
845 PlayField16[si + 1] = 0xC03;
846 PlayField16[si] = 0x300;
848 goto loc_StopNoSplit;
850 // ==========================================================================
851 // INFOTRON touching down to up
852 // ==========================================================================
855 subCopyFieldToScreen(si, aniMurphyTouchUp);
856 subSoundFXInfotron();
857 dx = aniTouchInfotron;
858 MovHighByte(&PlayField16[si], 0x14);
859 MovHighByte(&PlayField16[si - FieldWidth], 0xFF);
860 goto loc_StopNoSplit;
862 // ==========================================================================
863 // INFOTRON touching right to left
864 // ==========================================================================
867 subCopyFieldToScreen(si, aniMurphyTouchLeft);
868 subSoundFXInfotron();
869 dx = aniTouchInfotron;
870 MovHighByte(&PlayField16[si], 0x15);
871 MovHighByte(&PlayField16[si - 1], 0xFF);
872 goto loc_StopNoSplit;
874 // ==========================================================================
875 // INFOTRON touching up to down
876 // ==========================================================================
879 subCopyFieldToScreen(si, aniMurphyTouchDown);
880 subSoundFXInfotron();
881 dx = aniTouchInfotron;
882 MovHighByte(&PlayField16[si], 0x16);
883 MovHighByte(&PlayField16[si + FieldWidth], 0xFF);
884 goto loc_StopNoSplit;
886 // ==========================================================================
887 // INFOTRON touching left to right
888 // ==========================================================================
891 subCopyFieldToScreen(si, aniMurphyTouchRight);
892 subSoundFXInfotron();
893 dx = aniTouchInfotron;
894 MovHighByte(&PlayField16[si], 0x17);
895 MovHighByte(&PlayField16[si + 1], 0xFF);
896 goto loc_StopNoSplit;
898 // ==========================================================================
899 // EXIT pressed from any direction
900 // ==========================================================================
908 if (LowByte(InfotronsNeeded) != 0)
909 return subAnimateMurphy;
912 data_h_DemoDone = 1; // EP set level success bytes
913 LevelStatus = 1; // set Level Status DONE
914 EP_GameDemoVar0DAA = 0; // force demo for lead-out
915 if (SavedGameFlag == 0) // saved game running?
917 if (UpdateTimeFlag != 0) // update time?
919 UpdatedFlag = 1; // prevent double update
920 subUpdatePlayingTime(); // update playing time
925 subUpdateHallOfFame(); // update time + Hall-Of-Fame
928 LeadOutCounter = 0x40; // quit: start lead-out
930 MovHighByte(&PlayField16[si], 0xD);
931 goto loc_StopNoSplit;
933 // ==========================================================================
934 // ZONK moving right to left
935 // ==========================================================================
938 ax = PlayField16[si - 2];
940 return subAnimateMurphy;
942 MovHighByte(&PlayField16[si - 2], 1);
943 subCopyFieldToScreen(si, aniPushLeft); // draw pushing murphy
944 dx = aniZonkRollLeft;
948 MovHighByte(&PlayField16[si], 0xE);
949 goto loc_MoveNoSplit;
951 // ==========================================================================
952 // ZONK moving left to right
953 // ==========================================================================
956 ax = PlayField16[si + 2];
958 return subAnimateMurphy;
960 ax = PlayField16[si + FieldWidth + 1];
961 if (ax == 0) // zonk falls
962 return subAnimateMurphy;
964 MovHighByte(&PlayField16[si + 2], 1);
965 subCopyFieldToScreen(si, aniPushRight); // draw pushing murphy
966 dx = aniZonkRollRight;
970 MovHighByte(&PlayField16[si], 0xF);
971 goto loc_MoveNoSplit;
973 // ==========================================================================
974 // TERMINAL moving/touching down to up
975 // ==========================================================================
978 subCopyFieldToScreen(si, aniMurphyTouchUp);
979 if (YellowDisksExploded != 0)
981 YawnSleepCounter = 10; // stay hypnotized
982 return subAnimateMurphy;
985 subCopyFieldToScreen(si - FieldWidth, 0x88); // draw new terminal type
986 TerminalState[si - FieldWidth] = 8;
989 // ==========================================================================
990 // TERMINAL moving/touching right to left
991 // ==========================================================================
994 subCopyFieldToScreen(si, aniMurphyTouchLeft);
995 if (YellowDisksExploded != 0)
997 YawnSleepCounter = 10; // stay hypnotized
998 return subAnimateMurphy;
1001 subCopyFieldToScreen(si - 1, 0x88); // draw new terminal type
1002 TerminalState[si - 1] = 8;
1005 // ==========================================================================
1006 // TERMINAL moving/touching up to down
1007 // ==========================================================================
1010 subCopyFieldToScreen(si, aniMurphyTouchDown);
1011 if (YellowDisksExploded != 0)
1013 YawnSleepCounter = 10; // stay hypnotized
1014 return subAnimateMurphy;
1017 subCopyFieldToScreen(si + FieldWidth, 0x88); // draw new terminal type
1018 TerminalState[si + FieldWidth] = 8;
1021 // ==========================================================================
1022 // TERMINAL moving/touching left to right
1023 // ==========================================================================
1026 subCopyFieldToScreen(si, aniMurphyTouchRight);
1027 if (YellowDisksExploded != 0)
1029 YawnSleepCounter = 10; // stay hypnotized
1030 return subAnimateMurphy;
1033 subCopyFieldToScreen(si + 1, 0x88); // draw new terminal type
1034 TerminalState[si + 1] = 8;
1035 // ==========================================================================
1036 // common TERMINAL stuff moving/touching from all directions
1037 // ==========================================================================
1040 TerminalMaxCycles = 7;
1041 YellowDisksExploded = 1;
1042 for (i = 0; i <= LevelMax; i++)
1044 if (PlayField16[i] == fiYellowDisk)
1048 return subAnimateMurphy;
1050 // ==========================================================================
1051 // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1052 // ==========================================================================
1055 if (PlayField16[si - 2 * FieldWidth] != 0)
1056 return subAnimateMurphy;
1058 dx = aniSplitUpDown;
1059 dx2Step = -FieldWidth;
1060 PlayField16[si] = 0x1803;
1061 PlayField16[si - 2 * FieldWidth] = 0x300;
1064 // ==========================================================================
1065 // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1066 // ==========================================================================
1069 if (PlayField16[si - 2] != 0)
1070 return subAnimateMurphy;
1072 dx = aniMurphyEatLeft;
1074 PlayField16[si] = 0x1903;
1075 PlayField16[si - 2] = 0x300;
1078 // ==========================================================================
1079 // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1080 // ==========================================================================
1083 if (PlayField16[si + 2 * FieldWidth] != 0)
1084 return subAnimateMurphy;
1086 dx = aniSplitUpDown;
1087 dx2Step = FieldWidth;
1088 PlayField16[si] = 0x1A03;
1089 PlayField16[si + 2 * FieldWidth] = 0x300;
1092 // ==========================================================================
1093 // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1094 // ==========================================================================
1097 if (PlayField16[si + 2] != 0)
1098 return subAnimateMurphy;
1100 dx = aniMurphyEatRight;
1102 PlayField16[si] = 0x1B03;
1103 PlayField16[si + 2] = 0x300;
1106 MovingPictureSequencePhase = 0; // stop picture move sequence
1107 SplitMoveFlag = 1; // port: split movement
1110 // ==========================================================================
1111 // RED DISK moving down to up
1112 // ==========================================================================
1115 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1116 PlayField16[si] = 0x1C03;
1117 PlayField16[si - FieldWidth] = 0x300;
1118 goto loc_StopNoSplit;
1120 // ==========================================================================
1121 // RED DISK moving right to left
1122 // ==========================================================================
1125 dx = aniMurphyEatLeft;
1126 PlayField16[si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1127 PlayField16[si - 1] = 0x1D03;
1129 goto loc_StopNoSplit;
1131 // ==========================================================================
1132 // RED DISK moving up to down
1133 // ==========================================================================
1136 dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
1137 PlayField16[si] = 0x1E03;
1138 PlayField16[si + FieldWidth] = 0x300;
1139 goto loc_StopNoSplit;
1141 // ==========================================================================
1142 // RED DISK moving left to right
1143 // ==========================================================================
1146 // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1147 dx = aniMurphyEatRight;
1148 // --------------------------------------------------------------------------
1150 // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1151 // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1152 // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1153 // We may not fix the table, because then the timing of the game changes
1154 // and several existing demo's do not run properly anymore.
1155 // We only correct Murphies x-location here, when the sequence starts.
1156 // Remember that this is not the real bug-fix, but we must live with
1157 // this existing bug and correct for the consequences of it.
1158 if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1159 MurphyScreenXPos = MurphyScreenXPos - 2;
1162 // FS: for me this means to blit the first animation frame twice
1164 // --------------------------------------------------------------------------
1165 PlayField16[si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1166 PlayField16[si + 1] = 0x1F03;
1168 goto loc_StopNoSplit;
1170 // ==========================================================================
1171 // RED DISK touching down to up
1172 // ==========================================================================
1175 dx = aniTouchRedDisk;
1176 MovHighByte(&PlayField16[si], 0x20);
1177 MovHighByte(&PlayField16[si - FieldWidth], 3);
1178 goto loc_StopNoSplit;
1180 // ==========================================================================
1181 // RED DISK touching right to left
1182 // ==========================================================================
1185 dx = aniTouchRedDisk;
1186 MovHighByte(&PlayField16[si], 0x21);
1187 MovHighByte(&PlayField16[si - 1], 3);
1188 goto loc_StopNoSplit;
1190 // ==========================================================================
1191 // RED DISK touching up to down
1192 // ==========================================================================
1195 dx = aniTouchRedDisk;
1196 MovHighByte(&PlayField16[si], 0x22);
1197 MovHighByte(&PlayField16[si + FieldWidth], 3);
1198 goto loc_StopNoSplit;
1200 // ==========================================================================
1201 // RED DISK touching left to right
1202 // ==========================================================================
1205 dx = aniTouchRedDisk;
1206 MovHighByte(&PlayField16[si], 0x23);
1207 MovHighByte(&PlayField16[si + 1], 3);
1210 MovingPictureSequencePhase = 0; // stop picture move sequence
1213 // ==========================================================================
1214 // YELLOW DISK moving down to up
1215 // ==========================================================================
1218 if (PlayField16[si - 2 * FieldWidth] != 0)
1219 return subAnimateMurphy;
1221 PlayField16[si - 2 * FieldWidth] = 0x1200;
1222 subCopyFieldToScreen(si, aniPushRight);
1224 dxPos = si - FieldWidth;
1225 dx2 = aniPushUpDown;
1226 dx2Step = FieldWidth;
1227 PlayField16[si] = 0x2403;
1228 goto loc_MoveNoSplit;
1230 // ==========================================================================
1231 // YELLOW DISK moving right to left
1232 // ==========================================================================
1235 if (PlayField16[si - 2] != 0)
1236 return subAnimateMurphy;
1238 PlayField16[si - 2] = 0x1200;
1239 subCopyFieldToScreen(si, aniPushLeft);
1244 PlayField16[si] = 0x2503;
1245 goto loc_MoveNoSplit;
1247 // ==========================================================================
1248 // YELLOW DISK moving up to down
1249 // ==========================================================================
1252 if (PlayField16[si + 2 * FieldWidth] != 0)
1253 return subAnimateMurphy;
1255 PlayField16[si + 2 * FieldWidth] = 0x1200;
1256 subCopyFieldToScreen(si, aniPushRight);
1258 dxPos = si + FieldWidth;
1259 dx2 = aniPushUpDown;
1260 dx2Step = -FieldWidth;
1261 PlayField16[si] = 0x2703;
1262 goto loc_MoveNoSplit;
1264 // ==========================================================================
1265 // YELLOW DISK moving left to right
1266 // ==========================================================================
1269 if (PlayField16[si + 2] != 0)
1270 return subAnimateMurphy;
1272 PlayField16[si + 2] = 0x1200;
1273 subCopyFieldToScreen(si, aniPushRight);
1278 PlayField16[si] = 0x2603;
1279 goto loc_MoveNoSplit;
1281 // ==========================================================================
1282 // ORANGE DISK moving right to left
1283 // ==========================================================================
1286 if (PlayField16[si - 2] != 0)
1287 return subAnimateMurphy;
1289 PlayField16[si - 2] = 0x800;
1290 subCopyFieldToScreen(si, aniPushLeft);
1295 PlayField16[si] = 0x2803;
1296 goto loc_MoveNoSplit;
1298 // ==========================================================================
1299 // ORANGE DISK moving left to right
1300 // ==========================================================================
1303 if (PlayField16[si + 2] != 0)
1304 return subAnimateMurphy;
1306 if (PlayField16[si + FieldWidth + 1] == 0) // falling goes before pushing
1307 return subAnimateMurphy;
1309 PlayField16[si + 2] = 0x100;
1310 subCopyFieldToScreen(si, aniPushRight);
1315 PlayField16[si] = 0x2903;
1316 // ==========================================================================
1317 // Copy screen animation action table to action work space
1318 // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1319 // ==========================================================================
1322 MovingPictureSequencePhase = 8; // init picture move sequence
1325 SplitMoveFlag = 0; // no port: no split movement
1328 // copy/store global move sequence info????????????????????????????????????
1329 // ... dont think so ...(FS)
1330 // ==========================================================================
1331 // Proceed with all movements
1332 // ==========================================================================
1334 locProceedMovingMurphy: // proceed moving murphy
1335 YawnSleepCounter = 0; // Wake up sleeping Murphy
1336 ax = MovingPictureSequencePhase; // sequence busy?
1337 if (ax == 0) // no -- start sequence!
1340 ax = ax - 1; // next picture of sequence
1341 MovingPictureSequencePhase = ax; // store for later
1342 if (ax == 0) // Sound effects
1345 bl = HighByte(PlayField16[si]);
1346 if (bl == 0xE) // Push Zonk to left
1349 if (bl == 0xF) // Push Zonk to right
1352 if (bl == 0x28) // Push orange disk to left
1355 if (bl == 0x29) // Push orange disk to right
1358 if (bl == 0x24) // Push yellow disk up
1361 if (bl == 0x25) // Push yellow disk to left
1364 if (bl == 0x27) // Push yellow disk down
1367 if (bl == 0x26) // Push yellow disk to right
1370 if (bl == 0x2A) // Red disk release timer
1373 return subAnimateMurphy;
1375 // ==========================================================================
1376 // Paint frame of MOVING.DAT sequence
1377 // ==========================================================================
1380 if (SplitMoveFlag == 0)
1382 // ++++++++++++++++++++++++++
1383 // Begin of normal movement
1384 MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1385 MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1386 if (! ClearPos < 0) // clear field that murphy is leaving
1387 subCopyFieldToScreen(ClearPos, 0);
1389 if (dx2 == fiInfotron) // special case of infotron moving left or right
1396 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1397 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1400 X = GetStretchX(dxPos) + tDeltaX;
1401 Y = GetStretchY(dxPos) + tDeltaY;
1402 Tmp = (SeqPos < 0 ? 0 : 0); // 9StepBugFix!(red disk move right)
1403 StretchedSprites.BltEx(X, Y, dx[Tmp]);
1406 tPos = dxPos + dx2Step;
1407 X = GetStretchX(tPos);
1408 Y = GetStretchY(tPos);
1409 if (dx2 == fiInfotron) // special case of infotron moving left or right
1411 StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1413 else // pushing something
1415 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1419 // End of normal movement
1420 // ------------------------
1424 // ++++++++++++++++++++++++++++++++
1425 // Begin of split movement (port)
1426 MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1427 MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1428 subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1429 tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1430 tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1431 X = GetStretchX(dxPos) + tDeltaX;
1432 Y = GetStretchY(dxPos) + tDeltaY;
1433 StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1434 tPos = dxPos + dx2Step;
1435 X = GetStretchX(tPos);
1436 Y = GetStretchY(tPos);
1437 StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1438 StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1439 // End of split movement (port)
1440 // ------------------------------
1441 } // loc_g_6D1E:'loc_g_6D28:
1443 SeqPos = SeqPos + 1;
1444 if (dx[SeqPos] > -1)
1445 return subAnimateMurphy;
1447 // Follow-up after movement completed 'loc_g_6D35:
1448 MurphyXPos = MurphyXPos + MurphyDX;
1449 MurphyYPos = MurphyYPos + MurphyDY;
1450 bl = HighByte(PlayField16[si]); // animation phase
1451 MovHighByte(&PlayField16[si], 0);
1453 if (bl == 0x1) // space, moving up
1456 if (bl == 0x2) // space, moving left
1459 if (bl == 0x3) // space, moving down
1462 if (bl == 0x4) // space, moving right
1465 if (bl == 0x5) // base , moving up
1468 if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1471 if (bl == 0x7) // base , moving down
1474 if (bl == 0x8) // base , moving right
1477 if (bl == 0x9) // infotron, moving up
1480 if (bl == 0xA) // infotron, moving left
1483 if (bl == 0xB) // infotron, moving down
1486 if (bl == 0xC) // infotron, moving right
1489 if (bl == 0xD) // exit
1492 if (bl == 0xE) // zonk, pushing left
1495 if (bl == 0xF) // zonk, pushing right
1498 if (bl == 0x10) // base , touching up
1501 if (bl == 0x11) // base , touching left
1504 if (bl == 0x12) // base , touching down
1507 if (bl == 0x13) // base , touching right
1510 if (bl == 0x14) // infotron touching up
1513 if (bl == 0x15) // infotron touching left
1516 if (bl == 0x16) // infotron touching down
1519 if (bl == 0x17) // infotron touching right
1522 if (bl == 0x18) // port up
1525 if (bl == 0x19) // port left
1528 if (bl == 0x1A) // port down
1531 if (bl == 0x1B) // port right
1534 if (bl == 0x1C) // red disk, moving up
1537 if (bl == 0x1D) // red disk, moving left
1540 if (bl == 0x1E) // red disk, moving down
1543 if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
1546 if (bl == 0x20) // red disk, touching up
1549 if (bl == 0x21) // red disk, touching left
1552 if (bl == 0x22) // red disk, touching down
1555 if (bl == 0x23) // red disk, touching right
1558 if (bl == 0x24) // yellow disk, pushing up
1561 if (bl == 0x25) // yellow disk, pushing left
1564 if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
1567 if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
1570 if (bl == 0x28) // orange disk, pushing left
1573 if (bl == 0x29) // orange disk, pushing right
1576 if (bl == 0x2A) // red disk, release
1580 return subAnimateMurphy;
1582 // ==========================================================================
1583 // infotron, moving up
1584 // ==========================================================================
1587 if (0 < LowByte(InfotronsNeeded))
1588 InfotronsNeeded = InfotronsNeeded - 1;
1590 subDisplayInfotronsNeeded();
1591 loc_g_6EC8: // space, base
1592 PlayField16[si] = fiMurphy;
1593 subAdjustZonksInfotronsAboveMurphy(si + FieldWidth);
1594 return subAnimateMurphy;
1596 // ==========================================================================
1597 // infotron, moving left
1598 // ==========================================================================
1601 if (0 < LowByte(InfotronsNeeded))
1602 InfotronsNeeded = InfotronsNeeded - 1;
1604 subDisplayInfotronsNeeded();
1605 loc_g_6EE6: // space, base
1606 PlayField16[si] = fiMurphy;
1607 subAdjustZonksInfotronsAboveMurphy(si + 1);
1608 return subAnimateMurphy;
1610 // ==========================================================================
1611 // infotron, moving down
1612 // ==========================================================================
1615 if (0 < LowByte(InfotronsNeeded))
1616 InfotronsNeeded = InfotronsNeeded - 1;
1618 subDisplayInfotronsNeeded();
1619 loc_g_6F04: // space, base
1620 if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
1621 PlayField16[si - FieldWidth] = 0;
1623 PlayField16[si] = fiMurphy;
1624 return subAnimateMurphy;
1626 // ==========================================================================
1627 // infotron, moving right
1628 // ==========================================================================
1631 if (0 < LowByte(InfotronsNeeded))
1632 InfotronsNeeded = InfotronsNeeded - 1;
1634 subDisplayInfotronsNeeded();
1635 loc_g_71C4: // space, base
1636 subAdjustZonksInfotronsAboveMurphy(si - 1);
1637 PlayField16[si] = fiMurphy;
1638 return subAnimateMurphy;
1640 // ==========================================================================
1641 // infotron, touching up
1642 // ==========================================================================
1645 if (0 < LowByte(InfotronsNeeded))
1646 InfotronsNeeded = InfotronsNeeded - 1;
1648 subDisplayInfotronsNeeded();
1650 if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
1651 PlayField16[si - FieldWidth] = 0;
1653 return subAnimateMurphy;
1655 // ==========================================================================
1656 // infotron, touching left
1657 // ==========================================================================
1660 if (0 < LowByte(InfotronsNeeded))
1661 InfotronsNeeded = InfotronsNeeded - 1;
1663 subDisplayInfotronsNeeded();
1665 if (LowByte(PlayField16[si - 1]) != fiExplosion)
1666 PlayField16[si - 1] = 0;
1668 return subAnimateMurphy;
1670 // ==========================================================================
1671 // infotron, touching down
1672 // ==========================================================================
1675 if (0 < LowByte(InfotronsNeeded))
1676 InfotronsNeeded = InfotronsNeeded - 1;
1678 subDisplayInfotronsNeeded();
1680 if (LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
1681 PlayField16[si + FieldWidth] = 0;
1683 return subAnimateMurphy;
1685 // ==========================================================================
1686 // infotron, touching right
1687 // ==========================================================================
1690 if (0 < LowByte(InfotronsNeeded))
1691 InfotronsNeeded = InfotronsNeeded - 1;
1693 subDisplayInfotronsNeeded();
1695 if (LowByte(PlayField16[si + 1]) != fiExplosion)
1696 PlayField16[si + 1] = 0;
1698 return subAnimateMurphy;
1700 // ==========================================================================
1701 // zonk, pushing left
1702 // ==========================================================================
1705 if (LowByte(PlayField16[si]) != fiExplosion)
1706 PlayField16[si] = 0;
1708 PlayField16[si - 1] = fiMurphy;
1709 PlayField16[si - 2] = fiZonk;
1710 subExplodeSnikSnaksBelow(si - 2);
1712 return subAnimateMurphy;
1714 // ==========================================================================
1715 // zonk, pushing right
1716 // ==========================================================================
1719 if (LowByte(PlayField16[si]) != fiExplosion)
1720 PlayField16[si] = 0;
1722 PlayField16[si + 1] = fiMurphy;
1723 PlayField16[si + 2] = fiZonk;
1724 subExplodeSnikSnaksBelow(si + 2);
1726 return subAnimateMurphy;
1728 // ==========================================================================
1730 // ==========================================================================
1734 return subAnimateMurphy;
1736 // ==========================================================================
1737 // Push Zonk from right to left
1738 // ==========================================================================
1741 if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiZonk)
1742 return subAnimateMurphy;
1744 PlayField16[si] = fiMurphy; // else restore - no more zonk pushing!
1745 PlayField16[si - 1] = fiZonk;
1746 if (LowByte(PlayField16[si - 2]) != fiExplosion)
1747 PlayField16[si - 2] = 0;
1749 subCopyFieldToScreen(si, fiMurphy);
1750 return subAnimateMurphy;
1752 // ==========================================================================
1753 // Push Zonk from left to right
1754 // ==========================================================================
1757 if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiZonk)
1758 return subAnimateMurphy;
1760 PlayField16[si] = fiMurphy; // else restore - no more zonk pushing!
1761 PlayField16[si + 1] = fiZonk;
1762 if (LowByte(PlayField16[si + 2]) != fiExplosion)
1763 PlayField16[si + 2] = 0;
1765 subCopyFieldToScreen(si, fiMurphy);
1766 return subAnimateMurphy;
1768 // ==========================================================================
1769 // Push orange disk from right to left
1770 // ==========================================================================
1773 if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiOrangeDisk)
1774 return subAnimateMurphy;
1776 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1777 PlayField16[si - 1] = fiOrangeDisk;
1778 if (LowByte(PlayField16[si - 2]) != fiExplosion)
1779 PlayField16[si - 2] = 0;
1781 subCopyFieldToScreen(si, fiMurphy);
1782 return subAnimateMurphy;
1784 // ==========================================================================
1785 // Push orange disk from left to right
1786 // ==========================================================================
1789 if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiOrangeDisk)
1790 return subAnimateMurphy;
1792 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1793 PlayField16[si + 1] = fiOrangeDisk;
1794 if (LowByte(PlayField16[si + 2]) != fiExplosion)
1795 PlayField16[si + 2] = 0;
1797 subCopyFieldToScreen(si, fiMurphy);
1798 return subAnimateMurphy;
1800 // ==========================================================================
1801 // Push yellow disk from down to up
1802 // ==========================================================================
1805 if (DemoKeyCode == keyUp && PlayField16[si - FieldWidth] == fiYellowDisk)
1806 return subAnimateMurphy;
1808 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1809 PlayField16[si - FieldWidth] = fiYellowDisk;
1810 if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiExplosion)
1811 PlayField16[si - 2 * FieldWidth] = 0;
1813 subCopyFieldToScreen(si, fiMurphy);
1814 return subAnimateMurphy;
1816 // ==========================================================================
1817 // Push yellow disk from right to left
1818 // ==========================================================================
1821 if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiYellowDisk)
1822 return subAnimateMurphy;
1824 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1825 PlayField16[si - 1] = fiYellowDisk;
1826 if (LowByte(PlayField16[si - 2]) != fiExplosion)
1827 PlayField16[si - 2] = 0;
1829 subCopyFieldToScreen(si, fiMurphy);
1830 return subAnimateMurphy;
1832 // ==========================================================================
1833 // Push yellow disk from up to down
1834 // ==========================================================================
1837 if (DemoKeyCode == keyDown && PlayField16[si + FieldWidth] == fiYellowDisk)
1838 return subAnimateMurphy;
1840 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1841 PlayField16[si + FieldWidth] = fiYellowDisk;
1842 if (LowByte(PlayField16[si + 2 * FieldWidth]) != fiExplosion)
1843 PlayField16[si + 2 * FieldWidth] = 0;
1845 subCopyFieldToScreen(si, fiMurphy);
1846 return subAnimateMurphy;
1848 // ==========================================================================
1849 // Push yellow disk from left to right
1850 // ==========================================================================
1853 if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiYellowDisk)
1854 return subAnimateMurphy;
1856 PlayField16[si] = fiMurphy; // else restore - no more pushing!
1857 PlayField16[si + 1] = fiYellowDisk;
1858 if (LowByte(PlayField16[si + 2]) != fiExplosion)
1859 PlayField16[si + 2] = 0;
1861 subCopyFieldToScreen(si, fiMurphy);
1862 return subAnimateMurphy;
1864 // ==========================================================================
1865 // time red disk release (space)
1866 // ==========================================================================
1869 if (DemoKeyCode != keySpace)
1871 PlayField16[si] = fiMurphy;
1872 subCopyFieldToScreen(si, fiMurphy);
1873 RedDiskReleasePhase = 0;
1875 else if (MovingPictureSequencePhase == 0x20)
1877 subCopyFieldToScreen(si, 43); // anxious murphy
1878 RedDiskReleasePhase = 1;
1881 return subAnimateMurphy;
1883 // ==========================================================================
1884 // Special port down to up
1885 // ==========================================================================
1888 if (LowByte(PlayField16[si]) != fiExplosion)
1889 PlayField16[si] = 0;
1891 PlayField16[si - 2 * FieldWidth] = fiMurphy;
1893 si = si - FieldWidth;
1894 if (HighByte(PlayField16[si]) == 1)
1897 si = si - FieldWidth;
1898 return subAnimateMurphy;
1900 // ==========================================================================
1901 // Special port right to left
1902 // ==========================================================================
1905 if (LowByte(PlayField16[si]) != fiExplosion)
1906 PlayField16[si] = 0;
1908 PlayField16[si - 2] = fiMurphy;
1911 if (HighByte(PlayField16[si]) == 1)
1915 return subAnimateMurphy;
1917 // ==========================================================================
1918 // Special port up to down
1919 // ==========================================================================
1922 if (LowByte(PlayField16[si]) != fiExplosion)
1923 PlayField16[si] = 0;
1925 PlayField16[si + 2 * FieldWidth] = fiMurphy;
1927 si = si + FieldWidth;
1928 if (HighByte(PlayField16[si]) == 1)
1931 si = si + FieldWidth;
1932 return subAnimateMurphy;
1934 // ==========================================================================
1935 // Special port left to right
1936 // ==========================================================================
1939 if (LowByte(PlayField16[si]) != fiExplosion)
1940 PlayField16[si] = 0;
1942 PlayField16[si + 2] = fiMurphy;
1945 if (HighByte(PlayField16[si]) == 1)
1949 return subAnimateMurphy;
1951 // ==========================================================================
1953 // ==========================================================================
1956 if (LowByte(PlayField16[si]) != fiExplosion)
1957 PlayField16[si] = 0;
1959 si = si - FieldWidth;
1960 PlayField16[si] = fiMurphy;
1961 subEatRedDisk(si); // inc+show Murphy's red disks
1962 return subAnimateMurphy;
1964 // ==========================================================================
1965 // Move Red Disk left
1966 // ==========================================================================
1969 if (LowByte(PlayField16[si + 1]) != fiExplosion)
1970 PlayField16[si + 1] = 0;
1972 PlayField16[si] = fiMurphy;
1973 subEatRedDisk(si); // inc+show Murphy's red disks
1974 return subAnimateMurphy;
1976 // ==========================================================================
1977 // Move Red Disk down
1978 // ==========================================================================
1981 if (LowByte(PlayField16[si]) != fiExplosion)
1982 PlayField16[si] = 0;
1984 si = si + FieldWidth;
1985 PlayField16[si] = fiMurphy;
1986 subEatRedDisk(si); // inc+show Murphy's red disks
1987 return subAnimateMurphy;
1989 // ==========================================================================
1990 // Move Red Disk right
1991 // ==========================================================================
1994 if (LowByte(PlayField16[si - 1]) != fiExplosion)
1995 PlayField16[si - 1] = 0;
1997 PlayField16[si] = fiMurphy;
1998 subEatRedDisk(si); // inc+show Murphy's red disks
1999 return subAnimateMurphy;
2001 // ==========================================================================
2003 // ==========================================================================
2006 if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
2007 PlayField16[si - FieldWidth] = 0;
2009 subEatRedDisk(si - FieldWidth); // inc+show Murphy's red disks
2010 return subAnimateMurphy;
2012 // ==========================================================================
2013 // Eat Red Disk left
2014 // ==========================================================================
2017 if (LowByte(PlayField16[si - 1]) != fiExplosion)
2018 PlayField16[si - 1] = 0;
2020 subEatRedDisk(si - 1); // inc+show Murphy's red disks
2021 return subAnimateMurphy;
2023 // ==========================================================================
2024 // Eat Red Disk down
2025 // ==========================================================================
2028 if (LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
2029 PlayField16[si + FieldWidth] = 0;
2031 subEatRedDisk(si + FieldWidth); // inc+show Murphy's red disks
2032 return subAnimateMurphy;
2034 // ==========================================================================
2035 // Eat Red Disk right
2036 // ==========================================================================
2039 if (LowByte(PlayField16[si + 1]) != fiExplosion)
2040 PlayField16[si + 1] = 0;
2042 subEatRedDisk(si + 1); // inc+show Murphy's red disks
2043 return subAnimateMurphy;
2045 // ==========================================================================
2046 // yellow disk, pushing up
2047 // ==========================================================================
2050 if (LowByte(PlayField16[si]) != fiExplosion)
2051 PlayField16[si] = 0;
2053 si = si - FieldWidth;
2054 PlayField16[si] = fiMurphy;
2055 PlayField16[si - FieldWidth] = fiYellowDisk;
2056 return subAnimateMurphy;
2058 // ==========================================================================
2059 // yellow disk, pushing left
2060 // ==========================================================================
2063 if (LowByte(PlayField16[si]) != fiExplosion)
2064 PlayField16[si] = 0;
2067 PlayField16[si] = fiMurphy;
2068 PlayField16[si - 1] = fiYellowDisk;
2069 return subAnimateMurphy;
2071 // ==========================================================================
2072 // yellow disk, pushing down
2073 // ==========================================================================
2076 if (LowByte(PlayField16[si]) != fiExplosion)
2077 PlayField16[si] = 0;
2079 si = si + FieldWidth;
2080 PlayField16[si] = fiMurphy;
2081 PlayField16[si + FieldWidth] = fiYellowDisk;
2082 return subAnimateMurphy;
2084 // ==========================================================================
2085 // yellow disk pushing right
2086 // ==========================================================================
2089 if (LowByte(PlayField16[si]) != fiExplosion)
2090 PlayField16[si] = 0;
2093 PlayField16[si] = fiMurphy;
2094 PlayField16[si + 1] = fiYellowDisk;
2095 return subAnimateMurphy;
2097 // ==========================================================================
2098 // orange disk, pushing left
2099 // ==========================================================================
2102 if (LowByte(PlayField16[si]) != fiExplosion)
2103 PlayField16[si] = 0;
2106 PlayField16[si] = fiMurphy;
2107 PlayField16[si - 1] = fiOrangeDisk;
2108 return subAnimateMurphy;
2110 // ==========================================================================
2111 // orange disk, pushing right
2112 // ==========================================================================
2115 if (LowByte(PlayField16[si]) != fiExplosion)
2116 PlayField16[si] = 0;
2119 PlayField16[si] = fiMurphy;
2120 PlayField16[si + 1] = fiOrangeDisk;
2121 if (PlayField16[si + FieldWidth + 1] == 0) // make it fall down if below is empty
2123 MovHighByte(&PlayField16[si + 1], 0x20);
2124 MovHighByte(&PlayField16[si + FieldWidth + 1], fiOrangeDisk);
2127 return subAnimateMurphy;
2129 // ==========================================================================
2130 // Release a red disk
2131 // ==========================================================================
2134 PlayField16[si] = fiMurphy;
2135 RedDiskReleasePhase = 2;
2136 RedDiskCount = RedDiskCount - 1;
2137 subDisplayRedDiskCount();
2138 subSoundFXPush(); // Sound effects
2140 return subAnimateMurphy;
2141 } // subAnimateMurphy
2143 // ==========================================================================
2145 // ==========================================================================
2146 int subExplodeSnikSnaksBelow(int si)
2148 int subExplodeSnikSnaksBelow;
2152 ax = LowByte(PlayField16[si + FieldWidth]);
2153 if (ax == 0x11 || ax == 0xBB)
2154 ExplodeFieldSP(si + FieldWidth);
2156 return subExplodeSnikSnaksBelow;
2157 } // subExplodeSnikSnaksBelow
2159 // ==========================================================================
2161 // Does pushing against an object kill Murphy?
2162 // ==========================================================================
2163 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2165 static boolean subMoveKillsMurphy;
2171 if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2177 if (al == fiExplosion)
2180 if (fiOrangeDisk <= al && al <= fiPortUp)
2183 ExplodeFieldSP(si); // Explode
2184 subMoveKillsMurphy = True;
2185 return subMoveKillsMurphy;
2194 ExplodeFieldSP(si); // Explode
2195 subMoveKillsMurphy = True;
2196 return subMoveKillsMurphy;
2198 loc_g_74F6: // zonk left
2200 if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2203 subMoveKillsMurphy = True; // Set carry flag
2204 return subMoveKillsMurphy;
2206 loc_g_7512: // zonk right
2208 if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2211 loc_g_752E: // Marked fields and Ports
2212 subMoveKillsMurphy = True; // Set carry flag
2213 return subMoveKillsMurphy;
2215 loc_g_7530: // explosion
2216 if ((ah & 0x80) != 0)
2223 ExplodeFieldSP(si); // Explode
2224 subMoveKillsMurphy = True; // Set carry flag
2225 return subMoveKillsMurphy;
2228 PlayField16[si] = 0;
2229 subMoveKillsMurphy = False;
2231 return subMoveKillsMurphy;
2232 } // subMoveKillsMurphy
2234 // ==========================================================================
2236 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2237 // change conditions to port specs
2238 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2239 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2240 // ==========================================================================
2241 int subSpPortTest(int si)
2247 cx = LInfo.SpecialPortCount; // number of special ports
2248 for (i = 1; i <= cx; i++)
2251 bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2252 MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2255 GravityFlag = LInfo.SpecialPort[i].Gravity;
2256 FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2257 SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2258 // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2265 return subSpPortTest;
2268 void subCopyFieldToScreen(int si, int fi)
2272 // +++++++++++++++++++++++++++++++++++++++++
2273 X = GetStretchX(si);
2274 Y = GetStretchY(si);
2275 StretchedSprites.BltEx(X, Y, fi);
2276 // +++++++++++++++++++++++++++++++++++++++++
2279 static void subEatRedDisk(int si)
2281 if (AllowRedDiskCheat == 0)
2283 if (RedDiskReleasePhase != 0)
2285 if (RedDiskReleaseMurphyPos == si)
2290 RedDiskCount = (RedDiskCount + 1) % 256;
2291 subDisplayRedDiskCount();
2294 int subAdjustZonksInfotronsAboveMurphy(int si)
2296 int subAdjustZonksInfotronsAboveMurphy;
2300 if (LowByte(PlayField16[si]) != fiExplosion)
2301 PlayField16[si] = 0;
2303 ax = PlayField16[si - FieldWidth];
2304 if (ax == 0 || ax == 0x9999)
2307 if (ax == fiZonk || ax == fiInfotron)
2309 MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2312 return subAdjustZonksInfotronsAboveMurphy;
2314 loc_g_15A8: // empty above
2315 ax = PlayField16[si - FieldWidth - 1];
2316 if (ax == fiZonk || ax == fiInfotron)
2320 ax = PlayField16[si - FieldWidth + 1];
2321 if (ax == fiZonk || ax == fiInfotron)
2324 return subAdjustZonksInfotronsAboveMurphy;
2326 loc_g_15C5: // zonk/infotron above left
2327 ax = PlayField16[si - 1];
2328 if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2331 MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2332 PlayField16[si - FieldWidth] = 0x8888;
2333 return subAdjustZonksInfotronsAboveMurphy;
2335 loc_g_15E8: // zonk/infotron above right
2336 ax = PlayField16[si + 1];
2337 if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2339 MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2340 PlayField16[si - FieldWidth] = 0x8888;
2343 return subAdjustZonksInfotronsAboveMurphy;
2344 } // subAdjustZonksInfotronsAboveMurphy