rnd-20100317-1-src
[rocksndiamonds.git] / src / game_sp / InitGameConditions.c
1 // ----------------------------------------------------------------------------
2 // InitGameConditions.c
3 // ----------------------------------------------------------------------------
4
5 #include "InitGameConditions.h"
6
7
8 // ==========================================================================
9 //                              SUBROUTINE
10 // Init game conditions (variables)
11 // ==========================================================================
12
13 void subInitGameConditions()
14 {
15   MurphyVarFaceLeft = 0;
16   KillMurphyFlag = 0;                   // no "kill Murphy"
17   ExitToMenuFlag = 0;
18   LeadOutCounter = 0;                   // quit flag: lead-out counter
19   RedDiskCount = 0;                     // Red disk counter
20
21   YawnSleepCounter = 0;                 // Wake up sleeping Murphy
22
23   ExplosionShake = 0;                   // Force explosion flag off
24
25   TerminalMaxCycles = 0x7F;
26   YellowDisksExploded = 0;
27
28   TimerVar = 0;
29
30   SnikSnaksElectronsFrozen = 0;         // Snik-Snaks and Electrons move!
31
32   SplitMoveFlag = 0;                    // Reset Split-through-ports
33   RedDiskReleasePhase = 0;              // (re-)enable red disk release
34   RedDiskReleaseMurphyPos = 0;          // Red disk was released here
35 }
36
37
38 // ==========================================================================
39 //                              SUBROUTINE
40 // Locate Murphy and init location.
41 // ==========================================================================
42
43 void InitMurphyPos()
44 {
45   int si;
46
47   for (si = 0; si < LevelMax; si++)
48     if (PlayField16[si] == fiMurphy)
49       break;
50
51   InitMurphyPosB(si);
52
53   MurphyPosIndex = si;
54 }
55
56 void InitMurphyPosB(int si)
57 {
58   MurphyScreenXPos = MurphyXPos = GetStretchX(si); // Murphy's screen x-position
59   MurphyScreenYPos = MurphyYPos = GetStretchY(si); // Murphy's screen y-position
60
61   // To Do: draw Murphy in location ax
62   DDSpriteBuffer_BltImg(MurphyScreenXPos, MurphyScreenYPos, aniMurphy, 0);
63
64   subCalculateScreenScrollPos();           // calculate screen start addrs
65
66   if (AutoScrollFlag)
67   {
68     if (bPlaying)
69       SoftScrollTo(ScreenScrollXPos, ScreenScrollYPos, 1000, 25);
70     else
71       ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
72   }
73 }
74
75
76 // ==========================================================================
77 //                              SUBROUTINE
78 // Convert to easy symbols and reset Infotron count If not ThenVer62
79 // ==========================================================================
80
81 int subConvertToEasySymbols()
82 {
83   int ax, bx, cx, dx, i;
84   int al;
85
86   bx = 0;
87   dx = 0;
88   cx = LevelMax + 1;
89   i = 0;
90
91 loc_g_26C9:
92   ax = PlayField16[i];
93   al = LowByte(ax);
94   if (al == 0xF1) // converted explosion?
95   {
96     MovLowByte(&PlayField16[i], 0x1F);      // restore explosions
97     goto loc_g_2778;
98   }
99
100   if (LowByte(GameBusyFlag) != 1) // free screen write?
101   {
102     if (ax == fiInfotron) // Infotron? -> yes--count!
103       goto loc_g_2704;
104
105     if (ax == fiSnikSnak) // Snik Snak? -> yes--rearrange
106       goto loc_g_2713;
107
108     if (ax == fiElectron) // Electron? -> yes--rearrange
109       goto loc_g_2741;
110   }
111
112   // test for fancy RAM Chips:
113   if (ax == fiRAMLeft || ax == fiRAMRight)
114     goto loc_g_2707;
115
116   if (ax == fiRAMTop || ax == fiRAMBottom)
117     goto loc_g_2707;
118
119   if (ax < fiHWFirst) // All but deco hardware?
120     goto loc_g_26F8;
121
122   if (ax < fiRAMTop) // Decorative hardware?
123     goto loc_g_270D;
124
125 loc_g_26F8:
126   if (ax < fiSpPortRight) // Gravity change ports only?
127     goto loc_g_2778;
128
129   if (ax < fiSnikSnak) // Gravity change port! 'loc_g_2702:
130     goto loc_g_276F;
131
132   goto loc_g_2778;
133
134 loc_g_2704:                                     // INFOTRON
135   dx = dx + 1;                      // Count Infotrons
136   goto loc_g_2778;
137
138 loc_g_2707:                                     // DECO RAM CHIPS
139   PlayField16[i] = fiRAM; // Convert to standard RAM chip
140   goto loc_g_2778;
141
142 loc_g_270D:                                     // DECO HARDWARE
143   PlayField16[i] = fiHardWare; // Convert to standard hardware
144   goto loc_g_2778;
145
146 loc_g_2713:                                     // SNIK-SNAK
147   if (PlayField16[i - 1] != 0) // 1 field left empty? -> no--try up
148     goto loc_g_271F;
149
150   MovHighByte(&PlayField16[i], 1); // turn left, step = NorthWest
151   goto loc_g_2778;
152
153 loc_g_271F:
154   if (PlayField16[i - FieldWidth] != 0) // 1 field up empty? -> no--try right
155     goto loc_g_2730;
156
157   PlayField16[i - FieldWidth] = 0x1011; // SnikSnak accessing from below, step = 0
158   PlayField16[i] = 0xFFFF;
159   goto loc_g_2778;
160
161 loc_g_2730:
162   if (PlayField16[i + 1] != 0) // 1 field right empty? -> point up
163     goto loc_g_2778;
164
165   PlayField16[i + 1] = 0x2811; // SnikSnak accessing from left, step = 0
166   PlayField16[i] = 0xFFFF;
167   goto loc_g_2778;
168
169 loc_g_2741:                                     // ELECTRON
170   if (PlayField16[i - 1] != 0) // 1 field left empty? -> no--try up
171     goto loc_g_274D;
172
173   MovHighByte(&PlayField16[i], 1);
174   goto loc_g_2778;
175
176 loc_g_274D:
177   if (PlayField16[i - FieldWidth] != 0) // 1 field up empty? -> no--try right
178     goto loc_g_275E;
179
180   PlayField16[i - FieldWidth] = 0x1018; // 1 field up
181   PlayField16[i] = 0xFFFF;
182   goto loc_g_2778;
183
184 loc_g_275E:
185   if (PlayField16[i + 1] != 0) // 1 field right empty? -> no--point down
186     goto loc_g_2778;
187
188   PlayField16[i + 1] = 0x2818;
189   PlayField16[i] = 0xFFFF;
190   goto loc_g_2778;
191
192 loc_g_276F:                                     // GRAVITY CHANGING PORTS
193   PlayField16[i] = (ax - 4) | 0x100;    // Convert to standard ports
194   goto loc_g_2778;
195
196 loc_g_2778:
197   i = i + 1;                   // Next field
198   bx = bx + 1;
199   cx = cx - 1;
200   if (0 < cx) // Until all done 'loc_g_2782:
201     goto loc_g_26C9;
202
203   return dx;    // return InfotronCount
204 }
205
206
207 // ==========================================================================
208 //                              SUBROUTINE
209 // Reset Infotron count.  Call immediately after subConvertToEasySymbols
210 // ==========================================================================
211
212 void ResetInfotronsNeeded(int dx)
213 {
214   if (LInfo.InfotronsNeeded != 0)               // Jump If equal (autodetect)
215     dx = LInfo.InfotronsNeeded;
216
217   InfotronsNeeded = LowByte(dx);                // Remaining Infotrons needed
218   TotalInfotronsNeeded = InfotronsNeeded;       // Number of Infotrons needed
219 }
220
221
222 // ==========================================================================
223 //                              SUBROUTINE
224 // Fetch and initialize a level
225 // ==========================================================================
226
227 void subFetchAndInitLevelB()
228 {
229   subFetchAndInitLevelA();
230 }
231
232 void subFetchAndInitLevelA()
233 {
234   GameBusyFlag = 0;                             // restore scissors too
235   subFetchAndInitLevel();                       // fetch and initialize a level
236   GameBusyFlag = 1;                             // no free screen write
237
238   DemoKeyCode = 0;                              // delete last demo key!
239 }
240
241 void subFetchAndInitLevel()
242 {
243   int InfoCountInLevel;
244
245   PrepareLevel();                               // initialize level data
246
247   GameBusyFlag = -GameBusyFlag;                 // make != 1
248   InfoCountInLevel = subConvertToEasySymbols(); // convert to easy symbols
249   GameBusyFlag = -GameBusyFlag;                 // restore
250
251   subDisplayLevel();                            // paint (init) game field
252
253   ResetInfotronsNeeded(InfoCountInLevel);       // and reset Infotron count
254
255   subInitGameConditions();                      // init game conditions (vars)
256
257   InitMurphyPos();                              // locate Murphy + screen pos
258 }