rnd-20100210-1-src
[rocksndiamonds.git] / src / game_sp / Murphy.c
1 // ----------------------------------------------------------------------------
2 // Murphy.c
3 // ----------------------------------------------------------------------------
4
5 #include "Murphy.h"
6
7 static void subEatRedDisk(int si);
8 static boolean subMoveKillsMurphy(int si, int ax, int bl);
9
10 // static char *VB_Name = "modMurphy";
11
12 // --- Option Explicit
13
14 #if 1
15
16 #define LocalStretch                    (2)
17 #define MurphyZoomFactor                (ZoomFactor)
18
19 #else
20
21 #define LocalStretch                    (1)
22 #define MurphyZoomFactor                (1)
23
24 #endif
25
26 // ==========================================================================
27 //                              SUBROUTINE
28 // Move Murphy in any direction
29 // ==========================================================================
30
31 int subAnimateMurphy(int *si)
32 {
33   int subAnimateMurphy;
34
35   // int ax, al, ah, bx, bl, i, X, Y;
36   // int tX, tY, tDeltaX, tDeltaY, tPos, Tmp;
37 #if 1
38   int ax, al, bl, i, X, Y;
39   int time1, time2;
40 #else
41   int ax, al, bx, bl, i, X, Y;
42 #endif
43   int tDeltaX, tDeltaY, tPos, Tmp;
44
45   // Variables that hold information about the animation sequence
46   static int *dx = 0; // an array of image positions in moving.mpx, finalized with -1
47   static int dx2 = 0; // an additional image position of a second sprite, for instance: yellow disk if pushed
48   static int MurphyDX = 0, MurphyDY = 0; // murphys move steps
49   static int SeqPos = 0; // index into dx()
50   static int ClearPos = 0; // Position to clear before blitting sprites, none=-1
51   static int dxPos = 0; // field-position  to draw dx(SeqPos)
52   static int dx2Step = 0; // position of dx2 relative to dx-position
53
54   ax = PlayField16[*si];
55   al = LowByte(ax);
56
57 #if 0
58   printf("::: Murphy.c: subAnimateMurphy(): %d [%d, %d] %d, %d [%d]\n",
59          *si, *si % 60, *si / 60, ax, al, (al == fiMurphy));
60 #endif
61
62 #if 0
63   printf("::: Murphy.c: subAnimateMurphy(): %d [%d] [%d]\n",
64          YawnSleepCounter, FrameCounter, TimerVar);
65 #endif
66
67   if (al != fiMurphy)
68   {
69     MurphyMoveCounter = 0;             // We have no Murphy! Exit!
70     return subAnimateMurphy;
71   }
72
73   MurphyMoveCounter = 1;             // We have a Murphy!
74   MurphyExplodePos = *si;
75   if (ax != 3) // yes--go proceed moving murphy?
76     goto locProceedMovingMurphy;
77
78   // FS: reset moving sequence variables
79   MurphyDX = 0;
80   MurphyDY = 0;
81   ClearPos = *si;
82   dxPos = *si;
83   dx2 = -1;
84   SeqPos = 0;
85   // end of FS
86   ScratchGravity = 0; // scratch gravity off
87   if (GravityFlag != 0) // Gravity? (1=gravity on)
88   {
89     bl = LowByte(PlayField16[*si - FieldWidth]); // check above
90     if (! (bl == fiPortUp || bl == fiPortUpAndDown || bl == fiPortAllDirections))
91     {
92       if (PlayField16[*si + FieldWidth] == 0) // gravity on and space below!
93         ScratchGravity = 1;
94     }
95   } // loc_g_5E8B:
96
97   bl = DemoKeyCode;
98   if (bl != 0) // a key was pressed!
99     goto locKeyPressed5FCF;
100
101 #if 0
102   printf("::: Murphy.c: !!! %d [%d]\n", DemoKeyCode, GravityFlag);
103 #endif
104
105   RedDiskReleaseFlag = 1;
106   if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
107   {
108     MurphyDY = 2;
109     goto loc_g_6364;
110   }
111
112 #if 1
113
114 #if 0
115   ax = (TimerVar & 3);
116   if (ax != 0)
117     return subAnimateMurphy;
118 #endif
119
120   // ------------------------------------------------------------------
121   // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
122
123   YawnSleepCounter = YawnSleepCounter + 1;
124
125   if (YawnSleepCounter < 16)
126     return subAnimateMurphy;
127
128   if (YawnSleepCounter < 2000)
129   {
130     // normal grin
131     // (default: single graphic, no animation)
132     subCopyImageToScreen(*si, aniMurphy, YawnSleepCounter - 16);
133
134     return subAnimateMurphy;
135   }
136
137   if (YawnSleepCounter < 4000)
138   {
139     // yawn! and look depressed afterwards...
140     // (default: 12 animation frames with delay of 8)
141     subCopyImageToScreen(*si, aniMurphyYawn, YawnSleepCounter - 2000);
142
143     return subAnimateMurphy;
144   }
145
146   if (YawnSleepCounter < 6400)
147   {
148     // yawn again!
149     // (default: 12 animation frames with delay of 8)
150     subCopyImageToScreen(*si, aniMurphyYawn, YawnSleepCounter - 4000);
151
152     return subAnimateMurphy;
153   }
154
155   // time1 = 6400 + 12 * 8;     // (default: 6496 == 6400 + 12 * 8)
156   time1 = 6400 + 12 * 10;
157
158   if (YawnSleepCounter < time1)
159   {
160     // yawn again! - third time
161     // (default: 12 animation frames with delay of 8)
162     subCopyImageToScreen(*si, aniMurphyYawn, YawnSleepCounter - 6400);
163
164     return subAnimateMurphy;
165   }
166
167   // time2 = 6496 + 3 * 64;     // (default: 6688 == 6496 + 3 * 64)
168   time2 = 6496 + 3 * 100;
169
170   if (YawnSleepCounter > time2)         // Murphy already went to sleep
171     return subAnimateMurphy;
172
173   if (PlayField16[*si - 1] == 0)
174   {
175     if (PlayField16[*si + 1] == 0)
176     {
177       // no sleep -- go back to "wait and start yawning" phase
178       YawnSleepCounter = 144;
179
180       return subAnimateMurphy;
181     }
182     else
183     {
184       // go to sleep (right side)
185       // (default: 3 animation frames with delay of 64)
186       subCopyImageToScreen(*si, aniMurphySleepRight, YawnSleepCounter - time1);
187
188       return subAnimateMurphy;
189     }
190   }
191
192   // go to sleep (left side)
193   // (default: 3 animation frames with delay of 64)
194   subCopyImageToScreen(*si, aniMurphySleepLeft, YawnSleepCounter - time1);
195
196   return subAnimateMurphy;
197
198   // end of YAWN-SLEEP-Sequence
199
200 #else
201
202   ax = (TimerVar & 3);
203   if (ax != 0)
204     return subAnimateMurphy;
205
206   // ------------------------------------------------------------------
207   // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
208   YawnSleepCounter = YawnSleepCounter + 1;
209   if (YawnSleepCounter == 4)
210   {
211     subCopyFieldToScreen(*si, fiMurphy); // normal grin
212     return subAnimateMurphy;
213   } // loc_g_5ECE:
214
215   if (YawnSleepCounter <= 500) // loc_g_5ED7:
216     return subAnimateMurphy;
217
218   if (YawnSleepCounter <= 522)
219   {
220     bx = (YawnSleepCounter - 500) / 2;
221     subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
222     return subAnimateMurphy;
223   } // loc_g_5F00:
224
225   if (YawnSleepCounter <= 1000)
226     return subAnimateMurphy;
227
228   if (YawnSleepCounter <= 1022)
229   {
230     bx = (YawnSleepCounter - 1000) / 2;
231     subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again!
232     return subAnimateMurphy;
233   } // loc_g_5F32:
234
235   if (YawnSleepCounter <= 1600) // loc_g_5F3B:
236     return subAnimateMurphy;
237
238   if (YawnSleepCounter <= 1622)
239   {
240     bx = (YawnSleepCounter - 1600) / 2;
241     subCopyFieldToScreen(*si, aniMurphyYawn + bx); // yawn again! - third time
242     return subAnimateMurphy;
243   } // loc_g_5F64:
244
245   if (YawnSleepCounter > 1654)
246     return subAnimateMurphy;
247
248   if (PlayField16[*si - 1] == 0)
249   {
250     if (PlayField16[*si + 1] == 0)
251     {
252       YawnSleepCounter = 36;
253       return subAnimateMurphy;
254
255     }
256     else
257     {
258       bx = (YawnSleepCounter - 1622) / 16;
259       subCopyFieldToScreen(*si, aniMurphySleepRight + bx); // go to sleep
260       return subAnimateMurphy;
261     }
262   } // loc_g_5F81:
263
264   bx = (YawnSleepCounter - 1622) / 16;
265   subCopyFieldToScreen(*si, aniMurphySleepLeft + bx); // go to sleep
266
267   return subAnimateMurphy;
268
269   // end of YAWN-SLEEP-Sequence
270
271 #endif
272
273   // ------------------------------------------------------------------
274   // ==========================================================================
275   //                       (Direct Jump) a key was pressed
276   // ==========================================================================
277
278 locKeyPressed5FCF:
279   if (ScratchGravity == 0)
280     goto loc_g_6003;
281
282   if (PlayField16[*si + FieldWidth] != 0)
283     goto loc_g_6003;
284
285   if (bl == keyUp)
286   {
287     if (PlayField16[*si - FieldWidth] == fiBase)
288       goto loc_g_6003;
289
290   }
291   else if (bl == keyLeft)
292   {
293     if (PlayField16[*si - 1] == fiBase)
294       goto loc_g_6003;
295
296   }
297   else if (bl == keyRight)
298   {
299     if (PlayField16[*si + 1] == fiBase)
300       goto loc_g_6003;
301   } // loc_g_6001:
302
303   bl = keyDown;                      // force moving down!
304 loc_g_6003:
305   switch (bl)
306   {
307     case keyUp: // 1
308       RedDiskReleaseFlag = 0; // moving down to up ...
309       goto loc_g_6078;
310
311       break;
312
313     case keyLeft: // 2
314       RedDiskReleaseFlag = 0; // moving right to left ...
315       goto loc_g_60DA;
316
317       break;
318
319     case keyDown: // 3
320       RedDiskReleaseFlag = 0; // moving up to down ...
321       goto loc_g_6154;
322
323       break;
324
325     case keyRight: // 4
326       RedDiskReleaseFlag = 0; // moving left to right ...
327       goto loc_g_61B6;
328
329       break;
330
331     case keySpaceUp: // 5
332       RedDiskReleaseFlag = 0; // touching down to up ...
333       goto loc_g_622E;
334
335       break;
336
337     case keySpaceLeft: // 6
338       RedDiskReleaseFlag = 0; // touching right to left ...
339       goto loc_g_6258;
340
341       break;
342
343     case keySpaceDown: // 7
344       RedDiskReleaseFlag = 0; // touching up to down ...
345       goto loc_g_6288;
346
347       break;
348
349     case keySpaceRight: // 8
350       RedDiskReleaseFlag = 0; // touching left to right ...
351       goto loc_g_62B2;
352
353       break;
354
355     case keySpace: // 9
356       goto loc_g_62E2;                         // no move ...
357
358       break;
359
360     default:
361       RedDiskReleaseFlag = 0;
362       return subAnimateMurphy;
363       break;
364   }
365
366   // ==========================================================================
367   // moving down to up ...
368   // ==========================================================================
369
370 loc_g_6078:
371   // FS:
372   MurphyDY = -2;
373   // end of FS
374   ax = PlayField16[*si - FieldWidth];
375   al = LowByte(ax);
376   if (ax == fiSpace)
377     goto loc_g_6312;
378
379   if (ax == fiBase)
380     goto loc_g_63D3;
381
382   if (al == fiBug)
383     goto loc_g_63C2;
384
385   if (ax == fiInfotron)
386     goto loc_g_65C6;
387
388   if (ax == fiExit)
389     goto loc_g_6756;
390
391   if (al == fiTerminal)
392     goto loc_g_6817;
393
394   if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
395     goto loc_g_6916;
396
397   if (al == fiRedDisk)
398     goto loc_g_69A6;
399
400   if (al == fiYellowDisk)
401     goto loc_g_6AB8;
402
403   if (! subMoveKillsMurphy(*si - FieldWidth, ax, bl))
404     goto loc_g_6078;
405
406   return subAnimateMurphy;
407
408   // ==========================================================================
409   // moving right to left ...
410   // ==========================================================================
411
412 loc_g_60DA:
413   // FS:
414   MurphyDX = -2;
415   // end of FS
416   MurphyVarFaceLeft = 1;
417   ax = PlayField16[*si - 1];
418   al = LowByte(ax);
419   if (ax == fiSpace)
420     goto loc_g_6341;
421
422   if (ax == fiBase)
423     goto loc_g_641C;
424
425   if (al == fiBug)
426     goto loc_g_640B;
427
428   if (ax == fiInfotron)
429     goto loc_g_65FE;
430
431   if (ax == fiExit)
432     goto loc_g_6756;
433
434   if (ax == fiZonk)
435     goto loc_g_679B;
436
437   if (al == fiTerminal)
438     goto loc_g_684E;
439
440   if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
441     goto loc_g_693A;
442
443   if (ax == fiRedDisk)
444     goto loc_g_69CE;
445
446   if (ax == fiYellowDisk)
447     goto loc_g_6AF1;
448
449   if (ax == fiOrangeDisk)
450     goto loc_g_6B9B;
451
452   if (! subMoveKillsMurphy(*si - 1, ax, bl))
453     goto loc_g_60DA;
454
455   return subAnimateMurphy;
456
457   // ==========================================================================
458   // moving up to down ...
459   // ==========================================================================
460
461 loc_g_6154:
462   // FS:
463   MurphyDY = 2;
464   // end of FS
465   ax = PlayField16[*si + FieldWidth];
466   al = LowByte(ax);
467   if (ax == fiSpace)
468     goto loc_g_6364;
469
470   if (ax == fiBase)
471     goto loc_g_6459;
472
473   if (al == fiBug)
474     goto loc_g_6448;
475
476   if (ax == fiInfotron)
477     goto loc_g_662A;
478
479   if (ax == fiExit)
480     goto loc_g_6756;
481
482   if (al == fiTerminal)
483     goto loc_g_6884;
484
485   if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
486     goto loc_g_695E;
487
488   if (al == fiRedDisk)
489     goto loc_g_69F7;
490
491   if (al == fiYellowDisk)
492     goto loc_g_6B2A;
493
494   if (! subMoveKillsMurphy(*si + FieldWidth, ax, bl))
495     goto loc_g_6154;
496
497   return subAnimateMurphy;
498
499   // ==========================================================================
500   // moving left to right ...
501   // ==========================================================================
502
503 loc_g_61B6:
504   // FS:
505   MurphyDX = 2;
506   // end of FS
507   MurphyVarFaceLeft = 0;
508   ax = PlayField16[*si + 1];
509   al = LowByte(ax);
510   if (ax == fiSpace)
511     goto loc_g_6399;
512
513   if (ax == fiBase)
514     goto loc_g_64A2;
515
516   if (al == fiBug)
517     goto loc_g_6491;
518
519   if (ax == fiInfotron)
520     goto loc_g_6662;
521
522   if (ax == fiExit)
523     goto loc_g_6756;
524
525   if (ax == fiZonk)
526     goto loc_g_67D4;
527
528   if (al == fiTerminal)
529     goto loc_g_68BA;
530
531   if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
532     goto loc_g_6982;
533
534   if (al == fiRedDisk)
535     goto loc_g_6A1F;
536
537   if (al == fiYellowDisk)
538     goto loc_g_6B63;
539
540   if (ax == fiOrangeDisk)
541     goto loc_g_6BD3;
542
543   if (! subMoveKillsMurphy(*si + 1, ax, bl))
544     goto loc_g_61B6;
545
546   return subAnimateMurphy;
547
548   // ==========================================================================
549   // touching down to up ...
550   // ==========================================================================
551
552 loc_g_622E:
553   // FS:
554   ClearPos = -1;
555   dxPos = *si - FieldWidth;
556   // end of FS
557   ax = PlayField16[*si - FieldWidth];
558   al = LowByte(ax);
559   al = LowByte(ax);
560   if (ax == fiBase)
561     goto loc_g_64DF;
562
563   if (al == fiBug)
564     goto loc_g_64CE;
565
566   if (ax == fiInfotron)
567     goto loc_g_668E;
568
569   if (al == fiTerminal)
570     goto loc_g_6817;
571
572   if (al == fiRedDisk)
573     goto loc_g_6A48;
574
575   return subAnimateMurphy;
576
577   // ==========================================================================
578   // touching right to left ...
579   // ==========================================================================
580
581 loc_g_6258:
582   // FS:
583   ClearPos = -1;
584   dxPos = *si - 1;
585   // end of FS
586   MurphyVarFaceLeft = 1;
587   ax = PlayField16[*si - 1];
588   al = LowByte(ax);
589   if (ax == fiBase)
590     goto loc_g_651D;
591
592   if (al == fiBug)
593     goto loc_g_650C;
594
595   if (ax == fiInfotron)
596     goto loc_g_66C0;
597
598   if (al == fiTerminal)
599     goto loc_g_684E;
600
601   if (al == fiRedDisk)
602     goto loc_g_6A64;
603
604   return subAnimateMurphy;
605
606   // ==========================================================================
607   // touching up to down ...
608   // ==========================================================================
609
610 loc_g_6288:
611   // FS:
612   ClearPos = -1;
613   dxPos = *si + FieldWidth;
614   // end of FS
615   ax = PlayField16[*si + FieldWidth];
616   al = LowByte(ax);
617   if (ax == fiBase)
618     goto loc_g_655B;
619
620   if (al == fiBug)
621     goto loc_g_654A;
622
623   if (ax == fiInfotron)
624     goto loc_g_66F2;
625
626   if (al == fiTerminal)
627     goto loc_g_6884;
628
629   if (al == fiRedDisk)
630     goto loc_g_6A80;
631
632   return subAnimateMurphy;
633
634   // ==========================================================================
635   // touching left to right ...
636   // ==========================================================================
637
638 loc_g_62B2:
639   // FS:
640   ClearPos = -1;
641   dxPos = *si + 1;
642   // end of FS
643   MurphyVarFaceLeft = 0;
644   ax = PlayField16[*si + 1];
645   al = LowByte(ax);
646   if (ax == fiBase)
647     goto loc_g_6599;
648
649   if (al == fiBug)
650     goto loc_g_6588;
651
652   if (ax == fiInfotron)
653     goto loc_g_6724;
654
655   if (al == fiTerminal)
656     goto loc_g_68BA;
657
658   if (al == fiRedDisk)
659     goto loc_g_6A9C;
660
661   return subAnimateMurphy;
662
663   // ==========================================================================
664   // Release Red disk: no move ...
665   // ==========================================================================
666
667 loc_g_62E2:
668   // FS:
669   ClearPos = -1;
670   // end of FS
671   if (LowByte(RedDiskCount) == 0)
672     return subAnimateMurphy;
673
674   if (LowByte(RedDiskReleasePhase) != 0)
675     return subAnimateMurphy;
676
677   if (LowByte(RedDiskReleaseFlag) != 1)
678     return subAnimateMurphy;
679
680   MovHighByte(&PlayField16[*si], 0x2A);
681   MovingPictureSequencePhase = 0x40; // init picture move sequence
682   dx = aniRedDisk;
683   MovLowByte(&RedDiskReleasePhase, 1);
684   Mov(&RedDiskReleaseMurphyPos, *si);             // remember Murphy's location
685   goto loc_Split;
686
687   // ==========================================================================
688   // SPACE moving down to up
689   // ==========================================================================
690
691 loc_g_6312:
692   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
693   PlayField16[*si - FieldWidth] = 0x103;
694   PlayField16[*si] = 0x300;
695   *si = *si - FieldWidth;
696   goto loc_StopNoSplit;
697
698   // ==========================================================================
699   // SPACE moving right to left
700   // ==========================================================================
701
702 loc_g_6341:
703   dx = aniMurphyEatLeft;
704   PlayField16[*si - 1] = 0x203;
705   PlayField16[*si] = 0x300;
706   *si = *si - 1;
707   goto loc_StopNoSplit;
708
709   // ==========================================================================
710   // SPACE moving up to down, and when gravity is pulling!
711   // ==========================================================================
712
713 loc_g_6364:
714   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
715   PlayField16[*si + FieldWidth] = 0x303;
716   PlayField16[*si] = 0x300;
717   *si = *si + FieldWidth;
718   goto loc_StopNoSplit;
719
720   // ==========================================================================
721   // SPACE moving left to right
722   // ==========================================================================
723
724 loc_g_6399:
725   dx = aniMurphyEatRight;
726   PlayField16[*si + 1] = 0x403;
727   PlayField16[*si] = 0x300;
728   *si = *si + 1;
729   goto loc_StopNoSplit;
730
731   // ==========================================================================
732   // BUG moving down to up
733   // ==========================================================================
734
735 loc_g_63C2:
736   if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
737   {
738     ExplodeFieldSP(*si);                 // Explode
739     return subAnimateMurphy;
740   }
741
742   PlayField16[*si - FieldWidth] = fiBase;
743   // ==========================================================================
744   // BASE moving down to up
745   // ==========================================================================
746
747 loc_g_63D3:
748   subSoundFXBase();
749   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
750   PlayField16[*si - FieldWidth] = 0x503;
751   PlayField16[*si] = 0x300;
752   *si = *si - FieldWidth;
753   goto loc_StopNoSplit;
754
755   // ==========================================================================
756   // BUG moving right to left
757   // ==========================================================================
758
759 loc_g_640B:
760   if (SgnHighByte(PlayField16[*si - 1]) >= 0)
761   {
762     ExplodeFieldSP(*si);                 // Explode
763     return subAnimateMurphy;
764   }
765
766   PlayField16[*si - 1] = fiBase;
767   // ==========================================================================
768   // BASE moving right to left
769   // ==========================================================================
770
771 loc_g_641C:
772   subSoundFXBase();
773   dx = aniMurphyEatLeft;
774   PlayField16[*si - 1] = 0x203;
775   PlayField16[*si] = 0x300;
776   *si = *si - 1;
777   goto loc_StopNoSplit;
778
779   // ==========================================================================
780   // BUG moving up to down
781   // ==========================================================================
782
783 loc_g_6448:
784   if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
785   {
786     ExplodeFieldSP(*si);                 // Explode
787     return subAnimateMurphy;
788   }
789
790   PlayField16[*si + FieldWidth] = fiBase;
791   // ==========================================================================
792   // BASE moving up to down
793   // ==========================================================================
794
795 loc_g_6459:
796   subSoundFXBase();
797   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
798   PlayField16[*si + FieldWidth] = 0x703;
799   PlayField16[*si] = 0x300;
800   *si = *si + FieldWidth;
801   goto loc_StopNoSplit;
802
803   // ==========================================================================
804   // BUG moving left to right
805   // ==========================================================================
806
807 loc_g_6491:
808   if (SgnHighByte(PlayField16[*si + 1]) >= 0)
809   {
810     ExplodeFieldSP(*si);                 // Explode
811     return subAnimateMurphy;
812   }
813
814   PlayField16[*si + 1] = fiBase;
815   // ==========================================================================
816   // BASE moving left to right
817   // ==========================================================================
818
819 loc_g_64A2:
820   subSoundFXBase();
821   dx = aniMurphyEatRight;
822   PlayField16[*si + 1] = 0x803;
823   PlayField16[*si] = 0x300;
824   *si = *si + 1;
825   goto loc_StopNoSplit;
826
827   // ==========================================================================
828   // BUG touching down to up
829   // ==========================================================================
830
831 loc_g_64CE:
832   if (SgnHighByte(PlayField16[*si - FieldWidth]) >= 0)
833   {
834     ExplodeFieldSP(*si);                 // Explode
835     return subAnimateMurphy;
836   }
837
838   PlayField16[*si - FieldWidth] = fiBase;
839   // ==========================================================================
840   // BASE touching down to up
841   // ==========================================================================
842
843 loc_g_64DF:
844   subCopyFieldToScreen(*si, aniMurphyTouchUp);
845   subSoundFXBase();
846   dx = aniTouchBase;
847   dxPos = *si - FieldWidth;
848   MovHighByte(&PlayField16[*si], 0x10);
849   goto loc_StopNoSplit;
850
851   // ==========================================================================
852   // BUG touching right to left
853   // ==========================================================================
854
855 loc_g_650C:
856   if (SgnHighByte(PlayField16[*si - 1]) >= 0)
857   {
858     ExplodeFieldSP(*si);                 // Explode
859     return subAnimateMurphy;
860   }
861
862   PlayField16[*si - 1] = fiBase;
863   // ==========================================================================
864   // BASE touching right to left
865   // ==========================================================================
866
867 loc_g_651D:
868   subCopyFieldToScreen(*si, aniMurphyTouchLeft);
869   subSoundFXBase();
870   dx = aniTouchBase;
871   dxPos = *si - 1;
872   MovHighByte(&PlayField16[*si], 0x11);
873   goto loc_StopNoSplit;
874
875   // ==========================================================================
876   // BUG touching up to down
877   // ==========================================================================
878
879 loc_g_654A:
880   if (SgnHighByte(PlayField16[*si + FieldWidth]) >= 0)
881   {
882     ExplodeFieldSP(*si);                 // Explode
883     return subAnimateMurphy;
884   }
885
886   PlayField16[*si + FieldWidth] = fiBase;
887   // ==========================================================================
888   // BASE touching up to down
889   // ==========================================================================
890
891 loc_g_655B:
892   subCopyFieldToScreen(*si, aniMurphyTouchDown);
893   subSoundFXBase();
894   dx = aniTouchBase;
895   dxPos = *si + FieldWidth;
896   MovHighByte(&PlayField16[*si], 0x12);
897   goto loc_StopNoSplit;
898
899   // ==========================================================================
900   // BUG touching left to right
901   // ==========================================================================
902
903 loc_g_6588:
904   if (SgnHighByte(PlayField16[*si + 1]) >= 0)
905   {
906     ExplodeFieldSP(*si);                 // Explode
907     return subAnimateMurphy;
908   }
909
910   PlayField16[*si + 1] = fiBase;
911   // ==========================================================================
912   // BASE touching left to right
913   // ==========================================================================
914
915 loc_g_6599:
916   subCopyFieldToScreen(*si, aniMurphyTouchRight);
917   subSoundFXBase();
918   dx = aniTouchBase;
919   dxPos = *si + 1;
920   MovHighByte(&PlayField16[*si], 0x13);
921   goto loc_StopNoSplit;
922
923   // ==========================================================================
924   // INFOTRON moving down to up
925   // ==========================================================================
926
927 loc_g_65C6:
928   subSoundFXInfotron();
929   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
930   PlayField16[*si - FieldWidth] = 0x903;
931   PlayField16[*si] = 0x300;
932   *si = *si - FieldWidth;
933   goto loc_StopNoSplit;
934
935   // ==========================================================================
936   // INFOTRON moving right to left
937   // ==========================================================================
938
939 loc_g_65FE:
940   subSoundFXInfotron();
941   dx = aniEatInfotronLeft;
942   dx2 = fiInfotron;
943   dx2Step = -1;
944   ClearPos = -1;
945   PlayField16[*si - 1] = 0xA03;
946   PlayField16[*si] = 0x300;
947   *si = *si - 1;
948   goto loc_StopNoSplit;
949
950   // ==========================================================================
951   // INFOTRON moving up to down
952   // ==========================================================================
953
954 loc_g_662A:
955   subSoundFXInfotron();
956   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
957   PlayField16[*si + FieldWidth] = 0xB03;
958   PlayField16[*si] = 0x300;
959   *si = *si + FieldWidth;
960   goto loc_StopNoSplit;
961
962   // ==========================================================================
963   // INFOTRON moving left to right
964   // ==========================================================================
965
966 loc_g_6662:
967   subSoundFXInfotron();
968   dx = aniEatInfotronRight;
969   dx2 = fiInfotron;
970   dx2Step = 1;
971   ClearPos = -1;
972   PlayField16[*si + 1] = 0xC03;
973   PlayField16[*si] = 0x300;
974   *si = *si + 1;
975   goto loc_StopNoSplit;
976
977   // ==========================================================================
978   // INFOTRON touching down to up
979   // ==========================================================================
980
981 loc_g_668E:
982   subCopyFieldToScreen(*si, aniMurphyTouchUp);
983   subSoundFXInfotron();
984   dx = aniTouchInfotron;
985   MovHighByte(&PlayField16[*si], 0x14);
986   MovHighByte(&PlayField16[*si - FieldWidth], 0xFF);
987   goto loc_StopNoSplit;
988
989   // ==========================================================================
990   // INFOTRON touching right to left
991   // ==========================================================================
992
993 loc_g_66C0:
994   subCopyFieldToScreen(*si, aniMurphyTouchLeft);
995   subSoundFXInfotron();
996   dx = aniTouchInfotron;
997   MovHighByte(&PlayField16[*si], 0x15);
998   MovHighByte(&PlayField16[*si - 1], 0xFF);
999   goto loc_StopNoSplit;
1000
1001   // ==========================================================================
1002   // INFOTRON touching up to down
1003   // ==========================================================================
1004
1005 loc_g_66F2:
1006   subCopyFieldToScreen(*si, aniMurphyTouchDown);
1007   subSoundFXInfotron();
1008   dx = aniTouchInfotron;
1009   MovHighByte(&PlayField16[*si], 0x16);
1010   MovHighByte(&PlayField16[*si + FieldWidth], 0xFF);
1011   goto loc_StopNoSplit;
1012
1013   // ==========================================================================
1014   // INFOTRON touching left to right
1015   // ==========================================================================
1016
1017 loc_g_6724:
1018   subCopyFieldToScreen(*si, aniMurphyTouchRight);
1019   subSoundFXInfotron();
1020   dx = aniTouchInfotron;
1021   MovHighByte(&PlayField16[*si], 0x17);
1022   MovHighByte(&PlayField16[*si + 1], 0xFF);
1023   goto loc_StopNoSplit;
1024
1025   // ==========================================================================
1026   // EXIT pressed from any direction
1027   // ==========================================================================
1028
1029 loc_g_6756:
1030   // FS
1031   ClearPos = -1;
1032   MurphyDX = 0;
1033   MurphyDY = 0;
1034   // end of FS
1035   if (LowByte(InfotronsNeeded) != 0)
1036     return subAnimateMurphy;
1037
1038 #if 1
1039   if (!game_sp_info.LevelSolved)
1040     printf("::: Murphy.c: !!!!!!!!!! LEVEL %d SOLVED !!!!!!!!!!\n",LevelNumber);
1041 #endif
1042
1043 #if 1
1044   game_sp_info.LevelSolved = TRUE;
1045 #endif
1046
1047   subSoundFXExit();
1048   data_h_DemoDone = 1; // EP set level success bytes
1049   LevelStatus = 1; // set Level Status DONE
1050   EP_GameDemoVar0DAA = 0; // force demo for lead-out
1051   if (SavedGameFlag == 0) // saved game running?
1052   {
1053     if (UpdateTimeFlag != 0)    // update time?
1054     {
1055       UpdatedFlag = 1; // prevent double update
1056       subUpdatePlayingTime();    // update playing time
1057     }
1058   }
1059
1060 #if 0
1061   subUpdateHallOfFame(); // update time + Hall-Of-Fame
1062 #endif
1063
1064   LeadOutCounter = 0x40;          // quit: start lead-out
1065   dx = aniMurphyExit;
1066   MovHighByte(&PlayField16[*si], 0xD);
1067   goto loc_StopNoSplit;
1068
1069   // ==========================================================================
1070   // ZONK moving right to left
1071   // ==========================================================================
1072
1073 loc_g_679B:
1074   ax = PlayField16[*si - 2];
1075   if (ax != 0)
1076     return subAnimateMurphy;
1077
1078   MovHighByte(&PlayField16[*si - 2], 1);
1079   subCopyFieldToScreen(*si, aniPushLeft); // draw pushing murphy
1080   dx = aniZonkRollLeft;
1081   dxPos = *si - 1;
1082   dx2 = aniPushLeft;
1083   dx2Step = 1;
1084   MovHighByte(&PlayField16[*si], 0xE);
1085   goto loc_MoveNoSplit;
1086
1087   // ==========================================================================
1088   // ZONK moving left to right
1089   // ==========================================================================
1090
1091 loc_g_67D4:
1092   ax = PlayField16[*si + 2];
1093   if (ax != 0)
1094     return subAnimateMurphy;
1095
1096   ax = PlayField16[*si + FieldWidth + 1];
1097   if (ax == 0) // zonk falls
1098     return subAnimateMurphy;
1099
1100   MovHighByte(&PlayField16[*si + 2], 1);
1101   subCopyFieldToScreen(*si, aniPushRight); // draw pushing murphy
1102   dx = aniZonkRollRight;
1103   dxPos = *si + 1;
1104   dx2 = aniPushRight;
1105   dx2Step = -1;
1106   MovHighByte(&PlayField16[*si], 0xF);
1107   goto loc_MoveNoSplit;
1108
1109   // ==========================================================================
1110   // TERMINAL moving/touching down to up
1111   // ==========================================================================
1112
1113 loc_g_6817:
1114   subCopyFieldToScreen(*si, aniMurphyTouchUp);
1115   if (YellowDisksExploded != 0)
1116   {
1117     YawnSleepCounter = 40; // stay hypnotized
1118     return subAnimateMurphy;
1119   } // loc_g_6838:
1120
1121   subCopyFieldToScreen(*si - FieldWidth, 0x88); // draw new terminal type
1122   TerminalState[*si - FieldWidth] = 8;
1123   goto loc_g_68F0;
1124
1125   // ==========================================================================
1126   // TERMINAL moving/touching right to left
1127   // ==========================================================================
1128
1129 loc_g_684E:
1130   subCopyFieldToScreen(*si, aniMurphyTouchLeft);
1131   if (YellowDisksExploded != 0)
1132   {
1133     YawnSleepCounter = 40; // stay hypnotized
1134     return subAnimateMurphy;
1135   } // loc_g_6838:
1136
1137   subCopyFieldToScreen(*si - 1, 0x88); // draw new terminal type
1138   TerminalState[*si - 1] = 8;
1139   goto loc_g_68F0;
1140
1141   // ==========================================================================
1142   // TERMINAL moving/touching up to down
1143   // ==========================================================================
1144
1145 loc_g_6884:
1146   subCopyFieldToScreen(*si, aniMurphyTouchDown);
1147   if (YellowDisksExploded != 0)
1148   {
1149     YawnSleepCounter = 40; // stay hypnotized
1150     return subAnimateMurphy;
1151   } // loc_g_6838:
1152
1153   subCopyFieldToScreen(*si + FieldWidth, 0x88); // draw new terminal type
1154   TerminalState[*si + FieldWidth] = 8;
1155   goto loc_g_68F0;
1156
1157   // ==========================================================================
1158   // TERMINAL moving/touching left to right
1159   // ==========================================================================
1160
1161 loc_g_68BA:
1162   subCopyFieldToScreen(*si, aniMurphyTouchRight);
1163   if (YellowDisksExploded != 0)
1164   {
1165     YawnSleepCounter = 40; // stay hypnotized
1166     return subAnimateMurphy;
1167   } // loc_g_6838:
1168
1169   subCopyFieldToScreen(*si + 1, 0x88); // draw new terminal type
1170   TerminalState[*si + 1] = 8;
1171   // ==========================================================================
1172   // common TERMINAL stuff moving/touching from all directions
1173   // ==========================================================================
1174
1175 loc_g_68F0:
1176   TerminalMaxCycles = 7;
1177   YellowDisksExploded = 1;
1178   for (i = 0; i <= LevelMax; i++)
1179   {
1180     if (PlayField16[i] == fiYellowDisk)
1181       ExplodeFieldSP (i);
1182   }
1183
1184   return subAnimateMurphy;
1185
1186   // ==========================================================================
1187   // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
1188   // ==========================================================================
1189
1190 loc_g_6916:
1191   if (PlayField16[*si - 2 * FieldWidth] != 0)
1192     return subAnimateMurphy;
1193
1194   dx = aniSplitUpDown;
1195   dx2Step = -FieldWidth;
1196   PlayField16[*si] = 0x1803;
1197   PlayField16[*si - 2 * FieldWidth] = 0x300;
1198   goto loc_StopSplit;
1199
1200   // ==========================================================================
1201   // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
1202   // ==========================================================================
1203
1204 loc_g_693A:
1205   if (PlayField16[*si - 2] != 0)
1206     return subAnimateMurphy;
1207
1208   dx = aniMurphyEatLeft;
1209   dx2Step = -1;
1210   PlayField16[*si] = 0x1903;
1211   PlayField16[*si - 2] = 0x300;
1212   goto loc_StopSplit;
1213
1214   // ==========================================================================
1215   // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
1216   // ==========================================================================
1217
1218 loc_g_695E:
1219   if (PlayField16[*si + 2 * FieldWidth] != 0)
1220     return subAnimateMurphy;
1221
1222   dx = aniSplitUpDown;
1223   dx2Step = FieldWidth;
1224   PlayField16[*si] = 0x1A03;
1225   PlayField16[*si + 2 * FieldWidth] = 0x300;
1226   goto loc_StopSplit;
1227
1228   // ==========================================================================
1229   // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
1230   // ==========================================================================
1231
1232 loc_g_6982:
1233   if (PlayField16[*si + 2] != 0)
1234     return subAnimateMurphy;
1235
1236   dx = aniMurphyEatRight;
1237   dx2Step = 1;
1238   PlayField16[*si] = 0x1B03;
1239   PlayField16[*si + 2] = 0x300;
1240
1241 loc_StopSplit:
1242   MovingPictureSequencePhase = 0; // stop picture move sequence
1243   SplitMoveFlag = 1; // port: split movement
1244   goto loc_Split;
1245
1246   // ==========================================================================
1247   // RED DISK moving down to up
1248   // ==========================================================================
1249
1250 loc_g_69A6:
1251   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1252   PlayField16[*si] = 0x1C03;
1253   PlayField16[*si - FieldWidth] = 0x300;
1254   goto loc_StopNoSplit;
1255
1256   // ==========================================================================
1257   // RED DISK moving right to left
1258   // ==========================================================================
1259
1260 loc_g_69CE:
1261   dx = aniMurphyEatLeft;
1262   PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1263   PlayField16[*si - 1] = 0x1D03;
1264   *si = *si - 1;
1265   goto loc_StopNoSplit;
1266
1267   // ==========================================================================
1268   // RED DISK moving up to down
1269   // ==========================================================================
1270
1271 loc_g_69F7:
1272   dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpLeft);
1273   PlayField16[*si] = 0x1E03;
1274   PlayField16[*si + FieldWidth] = 0x300;
1275   goto loc_StopNoSplit;
1276
1277   // ==========================================================================
1278   // RED DISK moving left to right
1279   // ==========================================================================
1280
1281 loc_g_6A1F:
1282   //  dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
1283   dx = aniMurphyEatRight;
1284   // --------------------------------------------------------------------------
1285   // BugFix
1286   // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
1287   // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
1288   // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
1289   // We may not fix the table, because then the timing of the game changes
1290   // and several existing demo's do not run properly anymore.
1291   // We only correct Murphies x-location here, when the sequence starts.
1292   // Remember that this is not the real bug-fix, but we must live with
1293   // this existing bug and correct for the consequences of it.
1294
1295 #if 1
1296   if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1297     MurphyScreenXPos = MurphyScreenXPos - 2 * MurphyZoomFactor;
1298 #else
1299   if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
1300     MurphyScreenXPos = MurphyScreenXPos - 2;
1301 #endif
1302
1303   SeqPos = -1;
1304   // FS: for me this means to blit the first animation frame twice
1305   // end of BugFix
1306   // --------------------------------------------------------------------------
1307   PlayField16[*si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
1308   PlayField16[*si + 1] = 0x1F03;
1309   *si = *si + 1;
1310   goto loc_StopNoSplit;
1311
1312   // ==========================================================================
1313   // RED DISK touching down to up
1314   // ==========================================================================
1315
1316 loc_g_6A48:
1317   dx = aniTouchRedDisk;
1318   MovHighByte(&PlayField16[*si], 0x20);
1319   MovHighByte(&PlayField16[*si - FieldWidth], 3);
1320   goto loc_StopNoSplit;
1321
1322   // ==========================================================================
1323   // RED DISK touching right to left
1324   // ==========================================================================
1325
1326 loc_g_6A64:
1327   dx = aniTouchRedDisk;
1328   MovHighByte(&PlayField16[*si], 0x21);
1329   MovHighByte(&PlayField16[*si - 1], 3);
1330   goto loc_StopNoSplit;
1331
1332   // ==========================================================================
1333   // RED DISK touching up to down
1334   // ==========================================================================
1335
1336 loc_g_6A80:
1337   dx = aniTouchRedDisk;
1338   MovHighByte(&PlayField16[*si], 0x22);
1339   MovHighByte(&PlayField16[*si + FieldWidth], 3);
1340   goto loc_StopNoSplit;
1341
1342   // ==========================================================================
1343   // RED DISK touching left to right
1344   // ==========================================================================
1345
1346 loc_g_6A9C:
1347   dx = aniTouchRedDisk;
1348   MovHighByte(&PlayField16[*si], 0x23);
1349   MovHighByte(&PlayField16[*si + 1], 3);
1350
1351 loc_StopNoSplit:
1352   MovingPictureSequencePhase = 0; // stop picture move sequence
1353   goto loc_NoSplit;
1354
1355   // ==========================================================================
1356   // YELLOW DISK moving down to up
1357   // ==========================================================================
1358
1359 loc_g_6AB8:
1360   if (PlayField16[*si - 2 * FieldWidth] != 0)
1361     return subAnimateMurphy;
1362
1363   PlayField16[*si - 2 * FieldWidth] = 0x1200;
1364   subCopyFieldToScreen(*si, aniPushRight);
1365   dx = aniYellowDisk;
1366   dxPos = *si - FieldWidth;
1367   dx2 = aniPushUpDown;
1368   dx2Step = FieldWidth;
1369   PlayField16[*si] = 0x2403;
1370   goto loc_MoveNoSplit;
1371
1372   // ==========================================================================
1373   // YELLOW DISK moving right to left
1374   // ==========================================================================
1375
1376 loc_g_6AF1:
1377   if (PlayField16[*si - 2] != 0)
1378     return subAnimateMurphy;
1379
1380   PlayField16[*si - 2] = 0x1200;
1381   subCopyFieldToScreen(*si, aniPushLeft);
1382   dx = aniYellowDisk;
1383   dxPos = *si - 1;
1384   dx2 = aniPushLeft;
1385   dx2Step = 1;
1386   PlayField16[*si] = 0x2503;
1387   goto loc_MoveNoSplit;
1388
1389   // ==========================================================================
1390   // YELLOW DISK moving up to down
1391   // ==========================================================================
1392
1393 loc_g_6B2A:
1394   if (PlayField16[*si + 2 * FieldWidth] != 0)
1395     return subAnimateMurphy;
1396
1397   PlayField16[*si + 2 * FieldWidth] = 0x1200;
1398   subCopyFieldToScreen(*si, aniPushRight);
1399   dx = aniYellowDisk;
1400   dxPos = *si + FieldWidth;
1401   dx2 = aniPushUpDown;
1402   dx2Step = -FieldWidth;
1403   PlayField16[*si] = 0x2703;
1404   goto loc_MoveNoSplit;
1405
1406   // ==========================================================================
1407   // YELLOW DISK moving left to right
1408   // ==========================================================================
1409
1410 loc_g_6B63:
1411   if (PlayField16[*si + 2] != 0)
1412     return subAnimateMurphy;
1413
1414   PlayField16[*si + 2] = 0x1200;
1415   subCopyFieldToScreen(*si, aniPushRight);
1416   dx = aniYellowDisk;
1417   dxPos = *si + 1;
1418   dx2 = aniPushRight;
1419   dx2Step = -1;
1420   PlayField16[*si] = 0x2603;
1421   goto loc_MoveNoSplit;
1422
1423   // ==========================================================================
1424   // ORANGE DISK moving right to left
1425   // ==========================================================================
1426
1427 loc_g_6B9B:
1428   if (PlayField16[*si - 2] != 0)
1429     return subAnimateMurphy;
1430
1431   PlayField16[*si - 2] = 0x800;
1432   subCopyFieldToScreen(*si, aniPushLeft);
1433   dx = aniOrangeDisk;
1434   dxPos = *si - 1;
1435   dx2 = aniPushLeft;
1436   dx2Step = 1;
1437   PlayField16[*si] = 0x2803;
1438   goto loc_MoveNoSplit;
1439
1440   // ==========================================================================
1441   // ORANGE DISK moving left to right
1442   // ==========================================================================
1443
1444 loc_g_6BD3:
1445   if (PlayField16[*si + 2] != 0)
1446     return subAnimateMurphy;
1447
1448   if (PlayField16[*si + FieldWidth + 1] == 0) // falling goes before pushing
1449     return subAnimateMurphy;
1450
1451   PlayField16[*si + 2] = 0x100;
1452   subCopyFieldToScreen(*si, aniPushRight);
1453   dx = aniOrangeDisk;
1454   dxPos = *si + 1;
1455   dx2 = aniPushRight;
1456   dx2Step = -1;
1457   PlayField16[*si] = 0x2903;
1458   // ==========================================================================
1459   // Copy screen animation action table to action work space
1460   // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
1461   // ==========================================================================
1462
1463 loc_MoveNoSplit:
1464   MovingPictureSequencePhase = 8; // init picture move sequence
1465
1466 loc_NoSplit:
1467   SplitMoveFlag = 0; // no port: no split movement
1468
1469 loc_Split:
1470   //  copy/store global move sequence info????????????????????????????????????
1471   //  ... dont think so ...(FS)
1472   // ==========================================================================
1473   // Proceed with all movements
1474   // ==========================================================================
1475
1476 locProceedMovingMurphy: // proceed moving murphy
1477   YawnSleepCounter = 0; // Wake up sleeping Murphy
1478   ax = MovingPictureSequencePhase;            // sequence busy?
1479   if (ax == 0)             // no -- start sequence!
1480     goto loc_g_6C8F;
1481
1482   ax = ax - 1;   // next picture of sequence
1483   MovingPictureSequencePhase = ax;            // store for later
1484   if (ax == 0) // Sound effects
1485     subSoundFXPush();
1486
1487   bl = HighByte(PlayField16[*si]);
1488   if (bl == 0xE)        // Push Zonk to left
1489     goto loc_g_6F7E;
1490
1491   if (bl == 0xF)        // Push Zonk to right
1492     goto loc_g_6FBC;
1493
1494   if (bl == 0x28)       // Push orange disk to left
1495     goto loc_g_6FFA;
1496
1497   if (bl == 0x29)       // Push orange disk to right
1498     goto loc_g_7038;
1499
1500   if (bl == 0x24)       // Push yellow disk up
1501     goto loc_g_7076;
1502
1503   if (bl == 0x25)       // Push yellow disk to left
1504     goto loc_g_70B4;
1505
1506   if (bl == 0x27)       // Push yellow disk down
1507     goto loc_g_70F2;
1508
1509   if (bl == 0x26)       // Push yellow disk to right
1510     goto loc_g_7130;
1511
1512   if (bl == 0x2A)       // Red disk release timer
1513     goto loc_g_716E;
1514
1515   return subAnimateMurphy;
1516
1517   // ==========================================================================
1518   // Paint frame of MOVING.DAT sequence
1519   // ==========================================================================
1520
1521 loc_g_6C8F:
1522   if (SplitMoveFlag == 0)
1523   {
1524     // ++++++++++++++++++++++++++
1525     // Begin of normal movement
1526 #if 1
1527     MurphyScreenXPos = MurphyScreenXPos + MurphyDX * MurphyZoomFactor;
1528     MurphyScreenYPos = MurphyScreenYPos + MurphyDY * MurphyZoomFactor;
1529 #else
1530     MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
1531     MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
1532 #endif
1533
1534
1535 #if 0
1536   printf("::: %04d [%03ld, %02d] ----------> %s [%d] [%d, %d] [%d, %d] [%d]\n",
1537          TimerVar,
1538          DemoOffset - DemoPointer, DemoKeyRepeatCounter,
1539          (DemoKeyCode == keyNone        ? "(none)"              :
1540           DemoKeyCode == keyLeft        ? "left"                :
1541           DemoKeyCode == keyRight       ? "right"               :
1542           DemoKeyCode == keyUp          ? "up"                  :
1543           DemoKeyCode == keyDown        ? "down"                :
1544           DemoKeyCode == keySpace       ? "space"               :
1545           DemoKeyCode == keySpaceLeft   ? "space + left"        :
1546           DemoKeyCode == keySpaceRight  ? "space + right"       :
1547           DemoKeyCode == keySpaceUp     ? "space + up"          :
1548           DemoKeyCode == keySpaceDown   ? "space + down"        : "(unknown)"),
1549          DemoKeyCode,
1550          MurphyScreenXPos, MurphyScreenYPos,
1551          MurphyPosIndex % 60, MurphyPosIndex / 60,
1552          ClearPos);
1553 #endif
1554
1555 #if 0
1556   Delay(500);
1557 #endif
1558
1559 #if 1
1560     if (!(ClearPos < 0)) // clear field that murphy is leaving
1561       subCopyFieldToScreen(ClearPos, 0);
1562 #else
1563     if (! ClearPos < 0) // clear field that murphy is leaving
1564       subCopyFieldToScreen(ClearPos, 0);
1565 #endif
1566
1567 #if 0
1568     printf("::: ---------------> %d, %d [%d, %d]\n",
1569            MurphyScreenXPos, MurphyScreenYPos, MurphyDX, MurphyDY);
1570 #endif
1571
1572     if (dx2 == fiInfotron) // special case of infotron moving left or right
1573     {
1574       tDeltaX = 0;
1575       tDeltaY = 0;
1576     }
1577     else
1578     {
1579       tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1580       tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1581     }
1582
1583     X = GetStretchX(dxPos) + tDeltaX;
1584     Y = GetStretchY(dxPos) + tDeltaY;
1585     Tmp = (SeqPos < 0 ? 0 : SeqPos); // 9StepBugFix!(red disk move right)
1586     StretchedSprites.BltEx(X, Y, dx[Tmp]);
1587
1588 #if 1
1589     if (!(dx2 < 0))
1590 #else
1591     if (! dx2 < 0)
1592 #endif
1593     {
1594       tPos = dxPos + dx2Step;
1595       X = GetStretchX(tPos);
1596       Y = GetStretchY(tPos);
1597       if (dx2 == fiInfotron) // special case of infotron moving left or right
1598       {
1599         StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
1600       }
1601       else // pushing something
1602       {
1603         StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
1604       }
1605     }
1606
1607     // End of normal movement
1608     // ------------------------
1609   }
1610   else
1611   {
1612     // ++++++++++++++++++++++++++++++++
1613     // Begin of split movement (port)
1614 #if 1
1615     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX * MurphyZoomFactor;
1616     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY * MurphyZoomFactor;
1617 #else
1618     MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
1619     MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
1620 #endif
1621     subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
1622     tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
1623     tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
1624     X = GetStretchX(dxPos) + tDeltaX;
1625     Y = GetStretchY(dxPos) + tDeltaY;
1626     StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
1627     tPos = dxPos + dx2Step;
1628     X = GetStretchX(tPos);
1629     Y = GetStretchY(tPos);
1630     StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
1631     StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
1632     // End of split movement (port)
1633     // ------------------------------
1634   } // loc_g_6D1E:'loc_g_6D28:
1635
1636   SeqPos = SeqPos + 1;
1637   if (dx[SeqPos] > -1)
1638     return subAnimateMurphy;
1639
1640   // Follow-up after movement completed     'loc_g_6D35:
1641   MurphyXPos = MurphyXPos + MurphyDX;
1642   MurphyYPos = MurphyYPos + MurphyDY;
1643   bl = HighByte(PlayField16[*si]);  // animation phase
1644   MovHighByte(&PlayField16[*si], 0);
1645
1646   if (bl == 0x1)    // space, moving up
1647     goto loc_g_6EC8;
1648
1649   if (bl == 0x2)    // space, moving left
1650     goto loc_g_6EE6;
1651
1652   if (bl == 0x3)    // space, moving down
1653     goto loc_g_6F04;
1654
1655   if (bl == 0x4)    // space, moving right
1656     goto loc_g_71C4;
1657
1658   if (bl == 0x5)    // base , moving up
1659     goto loc_g_6EC8;
1660
1661   if (bl == 0x6)    // base , moving left -> 6 is not used, value is set to 2 instead of 6!
1662     goto loc_g_6EE6;
1663
1664   if (bl == 0x7)    // base , moving down
1665     goto loc_g_6F04;
1666
1667   if (bl == 0x8)    // base , moving right
1668     goto loc_g_71C4;
1669
1670   if (bl == 0x9)    // infotron, moving up
1671     goto loc_g_6EBA;
1672
1673   if (bl == 0xA)      // infotron, moving left
1674     goto loc_g_6ED8;
1675
1676   if (bl == 0xB)    // infotron, moving down
1677     goto loc_g_6EF6;
1678
1679   if (bl == 0xC)      // infotron, moving right
1680     goto loc_g_71B6;
1681
1682   if (bl == 0xD)      // exit
1683     goto loc_g_6F77;
1684
1685   if (bl == 0xE)      // zonk, pushing left
1686     goto loc_g_6F18;
1687
1688   if (bl == 0xF)      // zonk, pushing right
1689     goto loc_g_6F3B;
1690
1691   if (bl == 0x10)   // base , touching up
1692     goto loc_g_71E2;
1693
1694   if (bl == 0x11)   // base , touching left
1695     goto loc_g_71FE;
1696
1697   if (bl == 0x12)   // base , touching down
1698     goto loc_g_721A;
1699
1700   if (bl == 0x13)   // base , touching right
1701     goto loc_g_7236;
1702
1703   if (bl == 0x14)   // infotron touching up
1704     goto loc_g_71D4;
1705
1706   if (bl == 0x15)   // infotron touching left
1707     goto loc_g_71F0;
1708
1709   if (bl == 0x16)   // infotron touching down
1710     goto loc_g_720C;
1711
1712   if (bl == 0x17)   // infotron touching right
1713     goto loc_g_7228;
1714
1715   if (bl == 0x18)     // port up
1716     goto loc_g_7244;
1717
1718   if (bl == 0x19)     // port left
1719     goto loc_g_7272;
1720
1721   if (bl == 0x1A)     // port down
1722     goto loc_g_729F;
1723
1724   if (bl == 0x1B)     // port right
1725     goto loc_g_72CD;
1726
1727   if (bl == 0x1C)   // red disk, moving up
1728     goto loc_g_72FA;
1729
1730   if (bl == 0x1D)   // red disk, moving left
1731     goto loc_g_7318;
1732
1733   if (bl == 0x1E)   // red disk, moving down
1734     goto loc_g_7333;
1735
1736   if (bl == 0x1F)   // red disk, moving right -> 9-Step-Bug!
1737     goto loc_g_7351;
1738
1739   if (bl == 0x20)   // red disk, touching up
1740     goto loc_g_736C;
1741
1742   if (bl == 0x21)   // red disk, touching left
1743     goto loc_g_7381;
1744
1745   if (bl == 0x22)   // red disk, touching down
1746     goto loc_g_7396;
1747
1748   if (bl == 0x23)   // red disk, touching right
1749     goto loc_g_73AB;
1750
1751   if (bl == 0x24)     // yellow disk, pushing up
1752     goto loc_g_73C0;
1753
1754   if (bl == 0x25)     // yellow disk, pushing left
1755     goto loc_g_73DD;
1756
1757   if (bl == 0x26)     // yellow disk, pushing right -> order of "down" exchanged with "right"!
1758     goto loc_g_7417;
1759
1760   if (bl == 0x27)     // yellow disk, pushing down  -> order of "down" exchanged with "right"!
1761     goto loc_g_73FA;
1762
1763   if (bl == 0x28)     // orange disk, pushing left
1764     goto loc_g_7434;
1765
1766   if (bl == 0x29)     // orange disk, pushing right
1767     goto loc_g_7451;
1768
1769   if (bl == 0x2A)   // red disk, release
1770     goto loc_g_747F;
1771
1772   ExitToMenuFlag = 1;
1773   return subAnimateMurphy;
1774
1775   // ==========================================================================
1776   //                       infotron, moving up
1777   // ==========================================================================
1778
1779 loc_g_6EBA:
1780   if (0 < LowByte(InfotronsNeeded))
1781     InfotronsNeeded = InfotronsNeeded - 1;
1782
1783   subDisplayInfotronsNeeded();
1784 loc_g_6EC8: // space, base
1785   PlayField16[*si] = fiMurphy;
1786   subAdjustZonksInfotronsAboveMurphy(*si + FieldWidth);
1787   return subAnimateMurphy;
1788
1789   // ==========================================================================
1790   //                       infotron, moving left
1791   // ==========================================================================
1792
1793 loc_g_6ED8:
1794   if (0 < LowByte(InfotronsNeeded))
1795     InfotronsNeeded = InfotronsNeeded - 1;
1796
1797   subDisplayInfotronsNeeded();
1798 loc_g_6EE6: // space, base
1799   PlayField16[*si] = fiMurphy;
1800   subAdjustZonksInfotronsAboveMurphy(*si + 1);
1801   return subAnimateMurphy;
1802
1803   // ==========================================================================
1804   //                       infotron, moving down
1805   // ==========================================================================
1806
1807 loc_g_6EF6:
1808   if (0 < LowByte(InfotronsNeeded))
1809     InfotronsNeeded = InfotronsNeeded - 1;
1810
1811   subDisplayInfotronsNeeded();
1812 loc_g_6F04: // space, base
1813   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1814     PlayField16[*si - FieldWidth] = 0;
1815
1816   PlayField16[*si] = fiMurphy;
1817   return subAnimateMurphy;
1818
1819   // ==========================================================================
1820   //                       infotron, moving right
1821   // ==========================================================================
1822
1823 loc_g_71B6:
1824   if (0 < LowByte(InfotronsNeeded))
1825     InfotronsNeeded = InfotronsNeeded - 1;
1826
1827   subDisplayInfotronsNeeded();
1828 loc_g_71C4: // space, base
1829   subAdjustZonksInfotronsAboveMurphy(*si - 1);
1830   PlayField16[*si] = fiMurphy;
1831   return subAnimateMurphy;
1832
1833   // ==========================================================================
1834   //                       infotron, touching up
1835   // ==========================================================================
1836
1837 loc_g_71D4:
1838   if (0 < LowByte(InfotronsNeeded))
1839     InfotronsNeeded = InfotronsNeeded - 1;
1840
1841   subDisplayInfotronsNeeded();
1842 loc_g_71E2: // base
1843   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
1844     PlayField16[*si - FieldWidth] = 0;
1845
1846   return subAnimateMurphy;
1847
1848   // ==========================================================================
1849   //                       infotron, touching left
1850   // ==========================================================================
1851
1852 loc_g_71F0:
1853   if (0 < LowByte(InfotronsNeeded))
1854     InfotronsNeeded = InfotronsNeeded - 1;
1855
1856   subDisplayInfotronsNeeded();
1857 loc_g_71FE: // base
1858   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
1859     PlayField16[*si - 1] = 0;
1860
1861   return subAnimateMurphy;
1862
1863   // ==========================================================================
1864   //                       infotron, touching down
1865   // ==========================================================================
1866
1867 loc_g_720C:
1868   if (0 < LowByte(InfotronsNeeded))
1869     InfotronsNeeded = InfotronsNeeded - 1;
1870
1871   subDisplayInfotronsNeeded();
1872 loc_g_721A: // base
1873   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
1874     PlayField16[*si + FieldWidth] = 0;
1875
1876   return subAnimateMurphy;
1877
1878   // ==========================================================================
1879   //                       infotron, touching right
1880   // ==========================================================================
1881
1882 loc_g_7228:
1883   if (0 < LowByte(InfotronsNeeded))
1884     InfotronsNeeded = InfotronsNeeded - 1;
1885
1886   subDisplayInfotronsNeeded();
1887 loc_g_7236: // base
1888   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
1889     PlayField16[*si + 1] = 0;
1890
1891   return subAnimateMurphy;
1892
1893   // ==========================================================================
1894   //                       zonk, pushing left
1895   // ==========================================================================
1896
1897 loc_g_6F18:
1898   if (LowByte(PlayField16[*si]) != fiExplosion)
1899     PlayField16[*si] = 0;
1900
1901   PlayField16[*si - 1] = fiMurphy;
1902   PlayField16[*si - 2] = fiZonk;
1903   subExplodeSnikSnaksBelow(*si - 2);
1904   *si = *si - 1;
1905   return subAnimateMurphy;
1906
1907   // ==========================================================================
1908   //                       zonk, pushing right
1909   // ==========================================================================
1910
1911 loc_g_6F3B:
1912   if (LowByte(PlayField16[*si]) != fiExplosion)
1913     PlayField16[*si] = 0;
1914
1915   PlayField16[*si + 1] = fiMurphy;
1916   PlayField16[*si + 2] = fiZonk;
1917   subExplodeSnikSnaksBelow(*si + 2);
1918   *si = *si + 1;
1919   return subAnimateMurphy;
1920
1921   // ==========================================================================
1922   //                       exit
1923   // ==========================================================================
1924
1925 loc_g_6F77:
1926   ExitToMenuFlag = 1;
1927
1928 #if 1
1929   PlayField16[*si] = fiSpace;   // remove Murphy from playfield after exiting
1930 #endif
1931
1932   return subAnimateMurphy;
1933
1934   // ==========================================================================
1935   //               Push Zonk from right to left
1936   // ==========================================================================
1937
1938 loc_g_6F7E:
1939   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiZonk)
1940     return subAnimateMurphy;
1941
1942   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1943   PlayField16[*si - 1] = fiZonk;
1944   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1945     PlayField16[*si - 2] = 0;
1946
1947   subCopyFieldToScreen(*si, fiMurphy);
1948   return subAnimateMurphy;
1949
1950   // ==========================================================================
1951   //                       Push Zonk from left to right
1952   // ==========================================================================
1953
1954 loc_g_6FBC:
1955   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiZonk)
1956     return subAnimateMurphy;
1957
1958   PlayField16[*si] = fiMurphy; // else restore - no more zonk pushing!
1959   PlayField16[*si + 1] = fiZonk;
1960   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1961     PlayField16[*si + 2] = 0;
1962
1963   subCopyFieldToScreen(*si, fiMurphy);
1964   return subAnimateMurphy;
1965
1966   // ==========================================================================
1967   //               Push orange disk from right to left
1968   // ==========================================================================
1969
1970 loc_g_6FFA:
1971   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiOrangeDisk)
1972     return subAnimateMurphy;
1973
1974   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1975   PlayField16[*si - 1] = fiOrangeDisk;
1976   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
1977     PlayField16[*si - 2] = 0;
1978
1979   subCopyFieldToScreen(*si, fiMurphy);
1980   return subAnimateMurphy;
1981
1982   // ==========================================================================
1983   //               Push orange disk from left to right
1984   // ==========================================================================
1985
1986 loc_g_7038:
1987   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiOrangeDisk)
1988     return subAnimateMurphy;
1989
1990   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
1991   PlayField16[*si + 1] = fiOrangeDisk;
1992   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
1993     PlayField16[*si + 2] = 0;
1994
1995   subCopyFieldToScreen(*si, fiMurphy);
1996   return subAnimateMurphy;
1997
1998   // ==========================================================================
1999   //               Push yellow disk from down to up
2000   // ==========================================================================
2001
2002 loc_g_7076:
2003   if (DemoKeyCode == keyUp && PlayField16[*si - FieldWidth] == fiYellowDisk)
2004     return subAnimateMurphy;
2005
2006   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2007   PlayField16[*si - FieldWidth] = fiYellowDisk;
2008   if (LowByte(PlayField16[*si - 2 * FieldWidth]) != fiExplosion)
2009     PlayField16[*si - 2 * FieldWidth] = 0;
2010
2011   subCopyFieldToScreen(*si, fiMurphy);
2012   return subAnimateMurphy;
2013
2014   // ==========================================================================
2015   //               Push yellow disk from right to left
2016   // ==========================================================================
2017
2018 loc_g_70B4:
2019   if (DemoKeyCode == keyLeft && PlayField16[*si - 1] == fiYellowDisk)
2020     return subAnimateMurphy;
2021
2022   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2023   PlayField16[*si - 1] = fiYellowDisk;
2024   if (LowByte(PlayField16[*si - 2]) != fiExplosion)
2025     PlayField16[*si - 2] = 0;
2026
2027   subCopyFieldToScreen(*si, fiMurphy);
2028   return subAnimateMurphy;
2029
2030   // ==========================================================================
2031   //               Push yellow disk from up to down
2032   // ==========================================================================
2033
2034 loc_g_70F2:
2035   if (DemoKeyCode == keyDown && PlayField16[*si + FieldWidth] == fiYellowDisk)
2036     return subAnimateMurphy;
2037
2038   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2039   PlayField16[*si + FieldWidth] = fiYellowDisk;
2040   if (LowByte(PlayField16[*si + 2 * FieldWidth]) != fiExplosion)
2041     PlayField16[*si + 2 * FieldWidth] = 0;
2042
2043   subCopyFieldToScreen(*si, fiMurphy);
2044   return subAnimateMurphy;
2045
2046   // ==========================================================================
2047   //               Push yellow disk from left to right
2048   // ==========================================================================
2049
2050 loc_g_7130:
2051   if (DemoKeyCode == keyRight && PlayField16[*si + 1] == fiYellowDisk)
2052     return subAnimateMurphy;
2053
2054   PlayField16[*si] = fiMurphy; // else restore - no more pushing!
2055   PlayField16[*si + 1] = fiYellowDisk;
2056   if (LowByte(PlayField16[*si + 2]) != fiExplosion)
2057     PlayField16[*si + 2] = 0;
2058
2059   subCopyFieldToScreen(*si, fiMurphy);
2060   return subAnimateMurphy;
2061
2062   // ==========================================================================
2063   //               time red disk release (space)
2064   // ==========================================================================
2065
2066 loc_g_716E:
2067   if (DemoKeyCode != keySpace)
2068   {
2069     PlayField16[*si] = fiMurphy;
2070     subCopyFieldToScreen(*si, fiMurphy);
2071     RedDiskReleasePhase = 0;
2072   }
2073   else if (MovingPictureSequencePhase == 0x20)
2074   {
2075     subCopyFieldToScreen(*si, 43);  // anxious murphy
2076     RedDiskReleasePhase = 1;
2077   }
2078
2079   return subAnimateMurphy;
2080
2081   // ==========================================================================
2082   // Special port down to up
2083   // ==========================================================================
2084
2085 loc_g_7244:
2086   if (LowByte(PlayField16[*si]) != fiExplosion)
2087     PlayField16[*si] = 0;
2088
2089   PlayField16[*si - 2 * FieldWidth] = fiMurphy;
2090   SplitMoveFlag = 0;
2091   *si = *si - FieldWidth;
2092   if (HighByte(PlayField16[*si]) == 1)
2093     subSpPortTest(*si);
2094
2095   *si = *si - FieldWidth;
2096   return subAnimateMurphy;
2097
2098   // ==========================================================================
2099   // Special port right to left
2100   // ==========================================================================
2101
2102 loc_g_7272:
2103   if (LowByte(PlayField16[*si]) != fiExplosion)
2104     PlayField16[*si] = 0;
2105
2106   PlayField16[*si - 2] = fiMurphy;
2107   SplitMoveFlag = 0;
2108   *si = *si - 1;
2109   if (HighByte(PlayField16[*si]) == 1)
2110     subSpPortTest(*si);
2111
2112   *si = *si - 1;
2113   return subAnimateMurphy;
2114
2115   // ==========================================================================
2116   // Special port up to down
2117   // ==========================================================================
2118
2119 loc_g_729F:
2120   if (LowByte(PlayField16[*si]) != fiExplosion)
2121     PlayField16[*si] = 0;
2122
2123   PlayField16[*si + 2 * FieldWidth] = fiMurphy;
2124   SplitMoveFlag = 0;
2125   *si = *si + FieldWidth;
2126   if (HighByte(PlayField16[*si]) == 1)
2127     subSpPortTest(*si);
2128
2129   *si = *si + FieldWidth;
2130   return subAnimateMurphy;
2131
2132   // ==========================================================================
2133   // Special port left to right
2134   // ==========================================================================
2135
2136 loc_g_72CD:
2137   if (LowByte(PlayField16[*si]) != fiExplosion)
2138     PlayField16[*si] = 0;
2139
2140   PlayField16[*si + 2] = fiMurphy;
2141   SplitMoveFlag = 0;
2142   *si = *si + 1;
2143   if (HighByte(PlayField16[*si]) == 1)
2144     subSpPortTest(*si);
2145
2146   *si = *si + 1;
2147   return subAnimateMurphy;
2148
2149   // ==========================================================================
2150   // Move Red Disk up
2151   // ==========================================================================
2152
2153 loc_g_72FA:
2154   if (LowByte(PlayField16[*si]) != fiExplosion)
2155     PlayField16[*si] = 0;
2156
2157   *si = *si - FieldWidth;
2158   PlayField16[*si] = fiMurphy;
2159   subEatRedDisk(*si); // inc+show Murphy's red disks
2160   return subAnimateMurphy;
2161
2162   // ==========================================================================
2163   // Move Red Disk left
2164   // ==========================================================================
2165
2166 loc_g_7318:
2167   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2168     PlayField16[*si + 1] = 0;
2169
2170   PlayField16[*si] = fiMurphy;
2171   subEatRedDisk(*si); // inc+show Murphy's red disks
2172   return subAnimateMurphy;
2173
2174   // ==========================================================================
2175   // Move Red Disk down
2176   // ==========================================================================
2177
2178 loc_g_7333:
2179   if (LowByte(PlayField16[*si]) != fiExplosion)
2180     PlayField16[*si] = 0;
2181
2182   *si = *si + FieldWidth;
2183   PlayField16[*si] = fiMurphy;
2184   subEatRedDisk(*si); // inc+show Murphy's red disks
2185   return subAnimateMurphy;
2186
2187   // ==========================================================================
2188   // Move Red Disk right
2189   // ==========================================================================
2190
2191 loc_g_7351:
2192   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2193     PlayField16[*si - 1] = 0;
2194
2195   PlayField16[*si] = fiMurphy;
2196   subEatRedDisk(*si); // inc+show Murphy's red disks
2197   return subAnimateMurphy;
2198
2199   // ==========================================================================
2200   // Eat Red Disk up
2201   // ==========================================================================
2202
2203 loc_g_736C:
2204   if (LowByte(PlayField16[*si - FieldWidth]) != fiExplosion)
2205     PlayField16[*si - FieldWidth] = 0;
2206
2207   subEatRedDisk(*si - FieldWidth); // inc+show Murphy's red disks
2208   return subAnimateMurphy;
2209
2210   // ==========================================================================
2211   // Eat Red Disk left
2212   // ==========================================================================
2213
2214 loc_g_7381:
2215   if (LowByte(PlayField16[*si - 1]) != fiExplosion)
2216     PlayField16[*si - 1] = 0;
2217
2218   subEatRedDisk(*si - 1); // inc+show Murphy's red disks
2219   return subAnimateMurphy;
2220
2221   // ==========================================================================
2222   // Eat Red Disk down
2223   // ==========================================================================
2224
2225 loc_g_7396:
2226   if (LowByte(PlayField16[*si + FieldWidth]) != fiExplosion)
2227     PlayField16[*si + FieldWidth] = 0;
2228
2229   subEatRedDisk(*si + FieldWidth); // inc+show Murphy's red disks
2230   return subAnimateMurphy;
2231
2232   // ==========================================================================
2233   // Eat Red Disk right
2234   // ==========================================================================
2235
2236 loc_g_73AB:
2237   if (LowByte(PlayField16[*si + 1]) != fiExplosion)
2238     PlayField16[*si + 1] = 0;
2239
2240   subEatRedDisk(*si + 1); // inc+show Murphy's red disks
2241   return subAnimateMurphy;
2242
2243   // ==========================================================================
2244   //                       yellow disk, pushing up
2245   // ==========================================================================
2246
2247 loc_g_73C0:
2248   if (LowByte(PlayField16[*si]) != fiExplosion)
2249     PlayField16[*si] = 0;
2250
2251   *si = *si - FieldWidth;
2252   PlayField16[*si] = fiMurphy;
2253   PlayField16[*si - FieldWidth] = fiYellowDisk;
2254   return subAnimateMurphy;
2255
2256   // ==========================================================================
2257   //                       yellow disk, pushing left
2258   // ==========================================================================
2259
2260 loc_g_73DD:
2261   if (LowByte(PlayField16[*si]) != fiExplosion)
2262     PlayField16[*si] = 0;
2263
2264   *si = *si - 1;
2265   PlayField16[*si] = fiMurphy;
2266   PlayField16[*si - 1] = fiYellowDisk;
2267   return subAnimateMurphy;
2268
2269   // ==========================================================================
2270   //                       yellow disk, pushing down
2271   // ==========================================================================
2272
2273 loc_g_73FA:
2274   if (LowByte(PlayField16[*si]) != fiExplosion)
2275     PlayField16[*si] = 0;
2276
2277   *si = *si + FieldWidth;
2278   PlayField16[*si] = fiMurphy;
2279   PlayField16[*si + FieldWidth] = fiYellowDisk;
2280   return subAnimateMurphy;
2281
2282   // ==========================================================================
2283   //                       yellow disk pushing right
2284   // ==========================================================================
2285
2286 loc_g_7417:
2287   if (LowByte(PlayField16[*si]) != fiExplosion)
2288     PlayField16[*si] = 0;
2289
2290   *si = *si + 1;
2291   PlayField16[*si] = fiMurphy;
2292   PlayField16[*si + 1] = fiYellowDisk;
2293   return subAnimateMurphy;
2294
2295   // ==========================================================================
2296   //                       orange disk, pushing left
2297   // ==========================================================================
2298
2299 loc_g_7434:
2300   if (LowByte(PlayField16[*si]) != fiExplosion)
2301     PlayField16[*si] = 0;
2302
2303   *si = *si - 1;
2304   PlayField16[*si] = fiMurphy;
2305   PlayField16[*si - 1] = fiOrangeDisk;
2306   return subAnimateMurphy;
2307
2308   // ==========================================================================
2309   //                       orange disk, pushing right
2310   // ==========================================================================
2311
2312 loc_g_7451:
2313   if (LowByte(PlayField16[*si]) != fiExplosion)
2314     PlayField16[*si] = 0;
2315
2316   *si = *si + 1;
2317   PlayField16[*si] = fiMurphy;
2318   PlayField16[*si + 1] = fiOrangeDisk;
2319   if (PlayField16[*si + FieldWidth + 1] == 0) // make it fall down if below is empty
2320   {
2321     MovHighByte(&PlayField16[*si + 1], 0x20);
2322     MovHighByte(&PlayField16[*si + FieldWidth + 1], fiOrangeDisk);
2323   }
2324
2325   return subAnimateMurphy;
2326
2327   // ==========================================================================
2328   //                     Release a red disk
2329   // ==========================================================================
2330
2331 loc_g_747F:
2332   PlayField16[*si] = fiMurphy;
2333   RedDiskReleasePhase = 2;
2334   RedDiskCount = RedDiskCount - 1;
2335   subDisplayRedDiskCount();
2336   subSoundFXPush();                 // Sound effects
2337
2338   return subAnimateMurphy;
2339 } // subAnimateMurphy
2340
2341 // ==========================================================================
2342 //                              SUBROUTINE
2343 // ==========================================================================
2344 int subExplodeSnikSnaksBelow(int si)
2345 {
2346   int subExplodeSnikSnaksBelow;
2347
2348   int ax;
2349
2350   ax = LowByte(PlayField16[si + FieldWidth]);
2351   if (ax == 0x11 || ax == 0xBB)
2352     ExplodeFieldSP(si + FieldWidth);
2353
2354   return subExplodeSnikSnaksBelow;
2355 } // subExplodeSnikSnaksBelow
2356
2357 // ==========================================================================
2358 //                              SUBROUTINE
2359 // Does pushing against an object kill Murphy?
2360 // ==========================================================================
2361 static boolean subMoveKillsMurphy(int si, int ax, int bl)
2362 {
2363   static boolean subMoveKillsMurphy;
2364
2365   int al, ah;
2366
2367   al = LowByte(ax);
2368   ah = HighByte(ax);
2369   if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
2370     goto loc_g_752E;
2371
2372   if (al == fiZonk)
2373     goto loc_g_74E7;
2374
2375   if (al == fiExplosion)
2376     goto loc_g_7530;
2377
2378   if (fiOrangeDisk <= al && al <= fiPortUp)
2379     goto loc_g_752E;
2380
2381   ExplodeFieldSP(si);                 // Explode
2382   subMoveKillsMurphy = True;
2383   return subMoveKillsMurphy;
2384
2385 loc_g_74E7: // zonk
2386   if (bl == keyLeft)
2387     goto loc_g_74F6;
2388
2389   if (bl == keyRight)
2390     goto loc_g_7512;
2391
2392   ExplodeFieldSP(si);                 // Explode
2393   subMoveKillsMurphy = True;
2394   return subMoveKillsMurphy;
2395
2396 loc_g_74F6: // zonk left
2397   ah = ah & 0xF0;
2398   if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
2399     ExplodeFieldSP(si);
2400
2401   subMoveKillsMurphy = True;                           // Set carry flag
2402   return subMoveKillsMurphy;
2403
2404 loc_g_7512: // zonk right
2405   ah = ah & 0xF0;
2406   if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
2407     ExplodeFieldSP(si);
2408
2409 loc_g_752E: // Marked fields and Ports
2410   subMoveKillsMurphy = True;                           // Set carry flag
2411   return subMoveKillsMurphy;
2412
2413 loc_g_7530: // explosion
2414   if ((ah & 0x80) != 0)
2415     goto loc_g_753A;
2416
2417   if (ah >= 4)
2418     goto loc_g_753F;
2419
2420 loc_g_753A:
2421   ExplodeFieldSP(si);                 // Explode
2422   subMoveKillsMurphy = True;                           // Set carry flag
2423   return subMoveKillsMurphy;
2424
2425 loc_g_753F:
2426   PlayField16[si] = 0;
2427   subMoveKillsMurphy = False;
2428
2429   return subMoveKillsMurphy;
2430 } // subMoveKillsMurphy
2431
2432 // ==========================================================================
2433 //                              SUBROUTINE
2434 // Test If si 's a special (grav) port and If so Then fetch new values (see below)
2435 // change conditions to port specs
2436 // The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
2437 // (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
2438 // ==========================================================================
2439 int subSpPortTest(int si)
2440 {
2441   int subSpPortTest;
2442
2443   int i, cx, bx;
2444
2445 #if 1
2446   cx = LInfo.SpecialPortCount; // number of special ports
2447
2448   for (i = 0; i < cx; i++)
2449   {
2450 #if 1
2451     /* this assumes that PortLocation is stored as big endian */
2452     bx = LInfo.SpecialPort[i].PortLocation;
2453 #else
2454     /* this assumes that PortLocation is stored as little endian */
2455     bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2456     MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2457 #endif
2458
2459     if (bx / 2 == si)
2460     {
2461       GravityFlag = LInfo.SpecialPort[i].Gravity;
2462       FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2463       SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2464
2465       // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2466
2467       break;
2468     }
2469   }
2470
2471 #else
2472
2473   cx = LInfo.SpecialPortCount; // number of special ports
2474   for (i = 1; i <= cx; i++)
2475   {
2476     {
2477       bx = HighByte(LInfo.SpecialPort[i].PortLocation);
2478       MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
2479       if (bx / 2 == si)
2480       {
2481         GravityFlag = LInfo.SpecialPort[i].Gravity;
2482         FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
2483         SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
2484         //        RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
2485         i = cx + 1;
2486       }
2487     }
2488   }
2489 #endif
2490
2491   return subSpPortTest;
2492 } // subSpPortTest
2493
2494 void subCopyFieldToScreen(int si, int fi)
2495 {
2496   int X, Y;
2497
2498   // +++++++++++++++++++++++++++++++++++++++++
2499   X = GetStretchX(si);
2500   Y = GetStretchY(si);
2501   StretchedSprites.BltEx(X, Y, fi);
2502   // +++++++++++++++++++++++++++++++++++++++++
2503 }
2504
2505 void subCopyImageToScreen(int si, int graphic, int sync_frame)
2506 {
2507   int X, Y;
2508
2509   // +++++++++++++++++++++++++++++++++++++++++
2510   X = GetStretchX(si);
2511   Y = GetStretchY(si);
2512   StretchedSprites.BltImg(X, Y, graphic, sync_frame);
2513   // +++++++++++++++++++++++++++++++++++++++++
2514 }
2515
2516 static void subEatRedDisk(int si)
2517 {
2518   if (AllowRedDiskCheat == 0)
2519   {
2520     if (RedDiskReleasePhase != 0)
2521     {
2522       if (RedDiskReleaseMurphyPos == si)
2523         return;
2524     }
2525   }
2526
2527   RedDiskCount = (RedDiskCount + 1) % 256;
2528   subDisplayRedDiskCount();
2529 }
2530
2531 int subAdjustZonksInfotronsAboveMurphy(int si)
2532 {
2533   int subAdjustZonksInfotronsAboveMurphy;
2534
2535   int ax;
2536
2537   if (LowByte(PlayField16[si]) != fiExplosion)
2538     PlayField16[si] = 0;
2539
2540   ax = PlayField16[si - FieldWidth];
2541   if (ax == 0 || ax == 0x9999)
2542     goto loc_g_15A8;
2543
2544   if (ax == fiZonk || ax == fiInfotron)
2545   {
2546     MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
2547   }
2548
2549   return subAdjustZonksInfotronsAboveMurphy;
2550
2551 loc_g_15A8: // empty above
2552   ax = PlayField16[si - FieldWidth - 1];
2553   if (ax == fiZonk || ax == fiInfotron)
2554     goto loc_g_15C5;
2555
2556 loc_g_15B6:
2557   ax = PlayField16[si - FieldWidth + 1];
2558   if (ax == fiZonk || ax == fiInfotron)
2559     goto loc_g_15E8;
2560
2561   return subAdjustZonksInfotronsAboveMurphy;
2562
2563 loc_g_15C5: // zonk/infotron above left
2564   ax = PlayField16[si - 1];
2565   if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
2566     goto loc_g_15B6;
2567
2568   MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
2569   PlayField16[si - FieldWidth] = 0x8888;
2570   return subAdjustZonksInfotronsAboveMurphy;
2571
2572 loc_g_15E8: // zonk/infotron above right
2573   ax = PlayField16[si + 1];
2574   if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
2575   {
2576     MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
2577     PlayField16[si - FieldWidth] = 0x8888;
2578   }
2579
2580   return subAdjustZonksInfotronsAboveMurphy;
2581 } // subAdjustZonksInfotronsAboveMurphy