3bef36841c1bf6941f2757c8575fd624e7fa6b74
[rocksndiamonds.git] / src / game_sp / DoGameStuff.c
1 // ----------------------------------------------------------------------------
2 // DoGameStuff.c
3 // ----------------------------------------------------------------------------
4
5 #include "DoGameStuff.h"
6
7
8 static void CallAnimation(int si, byte bl);
9 static boolean IsToBeAnimated(int bl);
10
11 int *AnimationPosTable;
12 byte *AnimationSubTable;
13
14
15 // ==========================================================================
16 //                              SUBROUTINE
17 // Do game stuff
18 // ==========================================================================
19
20 void subDoGameStuff()
21 {
22   int si, cx, dx, bl;
23
24   subAnimateMurphy(&MurphyPosIndex);       // move Murphy in any direction
25
26   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
27   // Build a database of locations and subs-to-call of animatable fields only:
28   // Make a snapshot from the field before the animation cycle starts.
29   // first and last line are not animated.
30   si = FieldWidth + 1;
31   cx = LevelMax - 2 * FieldWidth - 1;
32   dx = 0;
33   do // locloop_g_2282:
34   {
35     bl = LowByte(PlayField16[si]);
36     if (((bl & 0xD) != 0) && (bl < 0x20)) // all animatables have 1's in &H0D' above &H1F? (&H1F=explosion!)
37     {
38       if (IsToBeAnimated(bl))
39       {
40         AnimationPosTable[dx] = si;
41         AnimationSubTable[dx] = bl;
42         dx = dx + 1; // count database entries
43       }
44     }
45
46     si = si + 1; // next field
47     cx = cx - 1;
48   }
49   while (0 < cx); // locloop_g_2282' until all lines scanned(not top- and bottom edge)
50
51   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
52   // Now use the database to animate all animatables the fastest way.
53   // All the other fields are not checked anymore: those have no database entry.
54   // The field from before animation is frozen in the database in order not to
55   // do follow-up animations in the same loop.
56   if (dx != 0) // any database entries?
57   {
58     dx = dx - 1;
59     for (cx = 0; cx <= dx; cx++)
60     {
61       CallAnimation(AnimationPosTable[cx], AnimationSubTable[cx]);
62     } // loop    locloop_g_22B8          ' until all animatables done
63   }
64
65   // All animations are done now
66   // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
67   if (KillMurphyFlag == 1 || MurphyMoveCounter == 0)
68   {
69     if (LeadOutCounter == 0 &&
70         !game_sp.LevelSolved &&
71         !game_sp.GameOver)
72     {
73 #if 1
74       printf("::: DoGameStuff.c: killing murphy [%d] ...\n", KillMurphyFlag);
75 #endif
76
77       KillMurphyFlag = 0;                       // no more "kill Murphy"
78       ExplodeFieldSP(MurphyExplodePos);         // Explode
79       LeadOutCounter = 0x40;                    // quit: start lead-out
80
81 #if 1
82       printf("::: DoGameStuff.c: !!!!!!!!!! GAME OVER !!!!!!!!!!\n");
83       printf("::: [KillMurphyFlag == %d]\n", KillMurphyFlag);
84 #endif
85
86       /* give Murphy some more time (LeadOutCounter) to reach the exit */
87     }
88   } //  loc_g_22FB:
89 }
90
91 static boolean IsToBeAnimated(int bl)
92 {
93   static boolean IsToBeAnimated;
94
95   switch (bl)
96   {
97     case fiZonk:
98     case fiInfotron:
99     case fiOrangeDisk:
100     case fiSnikSnak:
101     case fiTerminal:
102     case fiElectron:
103     case fiBug:
104     case fiExplosion:
105       IsToBeAnimated = True;
106       break;
107
108     default:
109       IsToBeAnimated = False;
110       break;
111   }
112
113   return IsToBeAnimated;
114 }
115
116 static void CallAnimation(int si, byte bl)
117 {
118   switch (bl)
119   {
120     case fiZonk:
121       subAnimateZonks(si);
122       break;
123
124     case fiInfotron:
125       subAnimateInfotrons(si);
126       break;
127
128     case fiOrangeDisk:
129       subAnimateOrangeDisks(si);
130       break;
131
132     case fiSnikSnak:
133       subAnimateSnikSnaks(si);
134       break;
135
136     case fiTerminal:
137       subAnimateTerminals(si);
138       break;
139
140     case fiElectron:
141       subAnimateElectrons(si);
142       break;
143
144     case fiBug:
145       subAnimateBugs(si);
146       break;
147
148     case fiExplosion:
149       subAnimateExplosion(si);
150       break;
151
152     default:
153       // Debug.Assert(False);
154       break;
155   }
156 }
157