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