88434a90dbc64112c2f4b04002fbd5df2572d9b7
[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()
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       KillMurphyFlag = 0;                       // no more "kill Murphy"
74       ExplodeFieldSP(MurphyExplodePos);         // Explode
75       LeadOutCounter = 0x40;                    // quit: start lead-out
76
77       /* give Murphy some more time (LeadOutCounter) to reach the exit */
78     }
79   } //  loc_g_22FB:
80 }
81
82 static boolean IsToBeAnimated(int bl)
83 {
84   static boolean IsToBeAnimated;
85
86   switch (bl)
87   {
88     case fiZonk:
89     case fiInfotron:
90     case fiOrangeDisk:
91     case fiSnikSnak:
92     case fiTerminal:
93     case fiElectron:
94     case fiBug:
95     case fiExplosion:
96       IsToBeAnimated = True;
97       break;
98
99     default:
100       IsToBeAnimated = False;
101       break;
102   }
103
104   return IsToBeAnimated;
105 }
106
107 static void CallAnimation(int si, byte bl)
108 {
109   switch (bl)
110   {
111     case fiZonk:
112       subAnimateZonks(si);
113       break;
114
115     case fiInfotron:
116       subAnimateInfotrons(si);
117       break;
118
119     case fiOrangeDisk:
120       subAnimateOrangeDisks(si);
121       break;
122
123     case fiSnikSnak:
124       subAnimateSnikSnaks(si);
125       break;
126
127     case fiTerminal:
128       subAnimateTerminals(si);
129       break;
130
131     case fiElectron:
132       subAnimateElectrons(si);
133       break;
134
135     case fiBug:
136       subAnimateBugs(si);
137       break;
138
139     case fiExplosion:
140       subAnimateExplosion(si);
141       break;
142
143     default:
144       // Debug.Assert(False);
145       break;
146   }
147 }
148