arrays are dynamic now, fixed bugs, more code cleanups
[supertux.git] / src / scene.c
1 //
2 // C Implementation: scene
3 //
4 // Description: 
5 //
6 //
7 // Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2004
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12
13 #include <stdlib.h>
14 #include "scene.h"
15
16 /* Initialize all 'dynamic' arrays */
17 void arrays_init(void)
18 {
19 num_bad_guys = 0;
20 num_bouncy_distros = 0;
21 num_broken_bricks = 0;
22 num_bouncy_bricks = 0;
23 num_floating_scores = 0;
24 num_upgrades = 0;
25 num_bullets = 0;
26 bad_guys = NULL;
27 bouncy_distros = NULL;
28 broken_bricks = NULL;
29 bouncy_bricks = NULL;
30 floating_scores = NULL;
31 upgrades = NULL;
32 bullets = NULL;
33 }
34
35 /* Free memory of 'dynamic' arrays */
36 void arrays_free(void)
37 {
38 free(bad_guys);
39 free(bouncy_distros);
40 free(broken_bricks);
41 free(bouncy_bricks);
42 free(floating_scores);
43 free(upgrades);
44 free(bullets);
45 }
46
47 void set_defaults(void)
48 {
49   int i;
50
51   /* Reset arrays: */
52
53   for (i = 0; i < num_bouncy_distros; i++)
54     bouncy_distros[i].base.alive = NO;
55
56   for (i = 0; i < num_broken_bricks; i++)
57     broken_bricks[i].base.alive = NO;
58
59   for (i = 0; i < num_bouncy_bricks; i++)
60     bouncy_bricks[i].base.alive = NO;
61         
62   for (i = 0; i < num_bad_guys; i++)
63   {
64     /*bad_guys[i].alive = NO;*/
65     badguy_init(&bad_guys[i]);
66     }
67  
68   for (i = 0; i < num_floating_scores; i++)
69     floating_scores[i].base.alive = NO;
70
71   for (i = 0; i < num_upgrades; i++)
72   {
73     /*upgrades[i].alive = NO;*/
74     upgrade_init(&upgrades[i]);
75     }
76
77   for (i = 0; i < num_bullets; i++)
78   {
79     /*bullets[i].alive = NO;*/
80     bullet_init(&bullets[i]);
81     }
82
83
84   /* Set defaults: */
85   
86   scroll_x = 0;
87
88   score_multiplier = 1;
89   super_bkgd_time = 0;
90
91   counting_distros = NO;
92   distro_counter = 0;
93
94   endpos = 0;
95
96   /* set current song/music */
97   current_music = LEVEL_MUSIC;
98 }
99
100 /* Add score: */
101
102 void add_score(int x, int y, int s)
103 {
104   int i, found;
105
106
107   /* Add the score: */
108
109   score = score + s;
110
111
112   /* Add a floating score thing to the game: */
113
114   found = -1;
115
116   for (i = 0; i < num_floating_scores && found == -1; i++)
117     {
118       if (!floating_scores[i].base.alive)
119         found = i;
120     }
121     
122   if (found == -1)
123   {
124   ++num_floating_scores;
125   floating_scores = realloc(floating_scores,num_floating_scores*sizeof(floating_score_type));
126   floating_score_init(&floating_scores[num_floating_scores-1],x,y,s);
127   found = -1;
128   }
129
130   if (found != -1)
131     {
132         floating_score_init(&floating_scores[found],x,y,s);
133     }
134 }
135
136 /* Add a bouncy distro: */
137
138 void add_bouncy_distro(float x, float y)
139 {
140   int i, found;
141
142   found = -1;
143
144   for (i = 0; i < num_bouncy_distros && found == -1; i++)
145     {
146       if (!bouncy_distros[i].base.alive)
147         found = i;
148     }
149     
150   if (found == -1)
151   {
152   ++num_bouncy_distros;
153   bouncy_distros = realloc(bouncy_distros,num_bouncy_distros*sizeof(bouncy_distro_type));
154   found = num_bouncy_distros - 1;
155   }
156     
157   if (found != -1)
158     {
159       bouncy_distros[found].base.alive = YES;
160       bouncy_distros[found].base.x = x;
161       bouncy_distros[found].base.y = y;
162       bouncy_distros[found].base.ym = -6;
163     }
164 }
165
166
167 /* Add broken brick pieces: */
168
169 void add_broken_brick(float x, float y)
170 {
171   add_broken_brick_piece(x, y, -4, -16);
172   add_broken_brick_piece(x, y + 16, -6, -12);
173
174   add_broken_brick_piece(x + 16, y, 4, -16);
175   add_broken_brick_piece(x + 16, y + 16, 6, -12);
176 }
177
178
179 /* Add a broken brick piece: */
180
181 void add_broken_brick_piece(float x, float y, float xm, float ym)
182 {
183   int i, found;
184
185   found = -1;
186
187   for (i = 0; i < num_broken_bricks && found == -1; i++)
188     {
189       if (!broken_bricks[i].base.alive)
190         found = i;
191     }
192
193   if (found == -1)
194   {
195   ++num_broken_bricks;
196   broken_bricks = realloc(broken_bricks,num_broken_bricks*sizeof(broken_brick_type));
197   found = num_broken_bricks - 1;
198   }
199
200   if (found != -1)
201     {
202       broken_bricks[found].base.alive = YES;
203       broken_bricks[found].base.x = x;
204       broken_bricks[found].base.y = y;
205       broken_bricks[found].base.xm = xm;
206       broken_bricks[found].base.ym = ym;
207     }
208 }
209
210
211 /* Add a bouncy brick piece: */
212
213 void add_bouncy_brick(float x, float y)
214 {
215   int i, found;
216
217   found = -1;
218
219   for (i = 0; i < num_bouncy_bricks && found == -1; i++)
220     {
221       if (!bouncy_bricks[i].base.alive)
222         found = i;
223     }
224     
225   if (found == -1)
226   {
227   ++num_bouncy_bricks;
228   bouncy_bricks = realloc(bouncy_bricks,num_bouncy_bricks*sizeof(bouncy_brick_type));
229   found = num_bouncy_bricks - 1;
230   }
231
232   if (found != -1)
233     {
234       bouncy_bricks[found].base.alive = YES;
235       bouncy_bricks[found].base.x = x;
236       bouncy_bricks[found].base.y = y;
237       bouncy_bricks[found].offset = 0;
238       bouncy_bricks[found].offset_m = -BOUNCY_BRICK_SPEED;
239       bouncy_bricks[found].shape = shape(x, y);
240     }
241 }
242
243
244 /* Add a bad guy: */
245
246 void add_bad_guy(float x, float y, int kind)
247 {
248   int i, found;
249
250   found = -1;
251
252   for (i = 0; i < num_bad_guys && found == -1; i++)
253     {
254       if (!bad_guys[i].base.alive)
255         found = i;
256     }
257  
258   if (found == -1)
259   {
260   ++num_bad_guys;
261   bad_guys = realloc(bad_guys,num_bad_guys*sizeof(bad_guy_type));
262   badguy_init(&bad_guys[num_bad_guys-1]);
263   found = num_bad_guys - 1;
264   }
265
266   if (found != -1)
267     {
268       bad_guys[found].base.alive = YES;
269       bad_guys[found].mode = NORMAL;
270       bad_guys[found].dying = NO;
271       bad_guys[found].kind = kind;
272       bad_guys[found].base.x = x;
273       bad_guys[found].base.y = y;
274       bad_guys[found].base.xm = 1.3;
275       bad_guys[found].base.ym = 1.5;
276       bad_guys[found].dir = LEFT;
277       bad_guys[found].seen = NO;
278       timer_init(&bad_guys[found].timer);
279     }
280 }
281
282 /* Add an upgrade: */
283
284 void add_upgrade(float x, float y, int kind)
285 {
286   int i, r, found;
287   /* we use this pointer to check, if realloc() returned a new memory address */
288   upgrade_type * pointee = upgrades;
289
290   found = -1;
291   r = 0;
292
293   for (i = 0; i < num_upgrades && found == -1; i++)
294     {
295       if (!upgrades[i].base.alive)
296         found = i;
297     }
298
299   if (found == -1)
300   {
301   ++num_upgrades;
302   upgrades = realloc(upgrades,num_upgrades*sizeof(upgrade_type));
303   if(upgrades != pointee)
304   r = 1;
305   upgrade_init(&upgrades[num_upgrades-1]);
306   found = num_upgrades - 1;
307   }
308
309   if (found != -1)
310     {
311       if(r == 1)
312       {
313         for (i = 0; i < num_upgrades && found == -1; i++)
314     {
315        upgrade_init(&upgrades[i]);
316     }
317       }
318       upgrade_init(&upgrades[found]);
319       upgrades[found].base.alive = YES;
320       upgrades[found].kind = kind;
321       upgrades[found].base.x = x;
322       upgrades[found].base.y = y;
323       upgrades[found].base.xm = 2;
324       upgrades[found].base.ym = -2;
325       upgrades[found].base.height = 0;
326     }
327 }
328
329 /* Add a bullet: */
330
331 void add_bullet(float x, float y, float xm, int dir)
332 {
333   int i, found;
334   
335   found = -1;
336
337   for (i = 0; i < num_bullets && found == -1; i++)
338     {
339       if (!bullets[i].base.alive)
340         found = i;
341     }
342
343   if (found == -1)
344   {
345   ++num_bullets;
346   bullets = realloc(bullets,num_bullets*sizeof(bullet_type));
347   bullet_init(&bullets[num_bullets-1]);
348   found = num_bullets - 1;
349   }
350
351   if (found != -1)
352     {
353       bullet_init(&bullets[found]);
354       bullets[found].base.alive = YES;
355
356       if (dir == RIGHT)
357         {
358           bullets[found].base.x = x + 32;
359           bullets[found].base.xm = BULLET_XM + xm;
360         }
361       else
362         {
363           bullets[found].base.x = x;
364           bullets[found].base.xm = -BULLET_XM + xm;
365         }
366
367       bullets[found].base.y = y;
368       bullets[found].base.ym = BULLET_STARTING_YM;
369
370       play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER);
371     }
372 }
373