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