1 /**
2 * @file curve_phase.c
3 * @brief Handle the curve phase
4 * @date 2010-01-01
5 * @author Jean-Michel Martin de Santero
6 * @author Bruno Ethvignot
7 */
8 /*
9 * copyright (c) 1998-2015 TLK Games all rights reserved
10 * $Id: curve_phase.c,v 1.22 2012/06/03 17:06:14 gurumeditation Exp $
11 *
12 * Powermanga is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * Powermanga is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 * MA 02110-1301, USA.
26 */
27 #include "config.h"
28 #include "powermanga.h"
29 #include "tools.h"
30 #include "images.h"
31 #include "curve_phase.h"
32 #include "display.h"
33 #include "electrical_shock.h"
34 #include "enemies.h"
35 #include "shots.h"
36 #include "log_recorder.h"
37 #include "meteors_phase.h"
38 #include "gfx_wrapper.h"
39 #include "grid_phase.h"
40 #include "guardians.h"
41 #include "spaceship.h"
42
43 /** Maximum number of bezier curves loaded at startup */
44 const Sint32 CURVES_BEZIER_NUMOF = 122;
45 /** All bezier curves loaded at startup */
46 curve *initial_curve = NULL;
47 /** Current curve phase level data structure */
48 curve_level courbe;
49 #ifdef DEVELOPPEMENT
50 /* curve editor: current curve number */
51 static Sint16 curv_number = 0;
52 /* curve editor: [l] key pressed */
53 static bool curve_l_key_down;
54 /* curve editor: [s] key pressed */
55 static bool curve_s_key_down;
56 short ge_act_pos_x = 0, ge_act_pos_y = 0;
57 short ce_vais_act = 0;
58 #endif
59 static bool curves_load_all (void);
60 static void curve_find_numof_enemies (void);
61
62 /**
63 * Allocate buffers and initialize structure of the curve phase
64 * @return TRUE if it completed successfully or FALSE otherwise
65 */
66 bool
curve_once_init(void)67 curve_once_init (void)
68 {
69 curve_free ();
70
71 /* allocate curve data structure */
72 if (initial_curve == NULL)
73 {
74 initial_curve =
75 (curve *) memory_allocation (CURVES_BEZIER_NUMOF * sizeof (curve));
76 if (initial_curve == NULL)
77 {
78 LOG_ERR ("'initial_curve' out of memory");
79 return FALSE;
80 }
81 }
82
83 if (!curves_load_all ())
84 {
85 return FALSE;
86 }
87 return TRUE;
88 }
89
90 /**
91 * Release memory used for the curve
92 */
93 void
curve_free(void)94 curve_free (void)
95 {
96 if (initial_curve != NULL)
97 {
98 free_memory ((char *) initial_curve);
99 initial_curve = NULL;
100 }
101 }
102
103 /**
104 * Phase 1: handle curves (little skirmish)
105 */
106 void
curve_phase(void)107 curve_phase (void)
108 {
109 Sint32 i, k;
110 enemy *foe;
111 spaceship_struct *ship = spaceship_get ();
112 if (!courbe.activity)
113 {
114 return;
115 }
116
117 /* we process each curve one by one */
118 for (i = 0; i < courbe.total_numof_curves; i++)
119 {
120 /* new enemy vessel appear on the curve? */
121 courbe.count_before_next[i]++;
122 if (courbe.current_numof_enemies[i] >= courbe.total_numof_enemies[i]
123 || courbe.count_before_next[i] <= courbe.delay_before_next[i])
124 {
125 continue;
126 }
127
128 /* add new a enemy sprite to the list */
129 foe = enemy_get ();
130 if (foe == NULL)
131 {
132 return;
133 }
134
135 /* set power of destruction */
136 foe->spr.pow_of_dest =
137 (Sint16) (1 +
138 courbe.num_vaisseau[i][courbe.current_numof_enemies[i]]);
139 /* set energy level */
140 foe->spr.energy_level =
141 (Sint16) ((ship->type << 1) + foe->spr.pow_of_dest);
142 /* set number of images for animation */
143 foe->spr.numof_images = (Sint16) 32;
144 /* set current image */
145 foe->spr.current_image = initial_curve[courbe.num_courbe[i]].angle[0];
146 /* set addresses of the images buffer */
147 for (k = 0; k < foe->spr.numof_images; k++)
148 {
149 foe->spr.img[k] =
150 (image *) &
151 enemi[courbe.num_vaisseau[i][courbe.current_numof_enemies[i]]][k];
152 }
153 /* set shot time-frequency */
154 foe->fire_rate = courbe.freq_tir[i][courbe.current_numof_enemies[i]];
155 /* set counter of delay between two shots */
156 foe->fire_rate_count = foe->fire_rate;
157
158 /* set type of displacement */
159 foe->displacement = DISPLACEMENT_CURVE;
160
161 /* set x and y coordinates */
162 foe->spr.xcoord =
163 (float) (initial_curve[courbe.num_courbe[i]].pos_x + 128 - 32);
164 foe->spr.ycoord =
165 (float) (initial_curve[courbe.num_courbe[i]].pos_y + 128 - 32);
166
167 /* clear index on the precalculated bezier curve */
168 foe->pos_vaiss[POS_CURVE] = 0;
169 /* set curve number used */
170 foe->num_courbe = courbe.num_courbe[i];
171
172 /* set size of the sprite as 16x16 pixels */
173 foe->type = 0;
174
175 /* increase number of the enemies on the curve */
176 courbe.current_numof_enemies[i]++;
177 /* clear counter delay before appearance of the next enemy */
178 courbe.count_before_next[i] = 0;
179 }
180 }
181
182 /**
183 * Test if curve phase is finished
184 */
185 void
curve_finished(void)186 curve_finished (void)
187 {
188 Sint32 i;
189 /* TRUE = all enemies are dead */
190 bool alldead;
191
192 /* curve phase enable? */
193 if (courbe.activity)
194 {
195 alldead = TRUE;
196 for (i = 0; i < courbe.total_numof_curves; i++)
197 {
198 if (courbe.current_numof_enemies[i] < courbe.total_numof_enemies[i])
199 {
200 /* there is still at least enemy */
201 alldead = FALSE;
202 }
203 }
204
205 /* move to next phase of the game */
206 if (alldead) /* no enemy is present? */
207 {
208 /* initialize the grid phase */
209 grid_start ();
210 courbe.activity = FALSE;
211 meteor_activity = FALSE;
212 guardian->number = 0;
213 /* grid phase enable */
214 grid.is_enable = TRUE;
215 }
216 }
217 }
218
219 /*
220 * curve editor
221 */
222 #ifdef DEVELOPPEMENT
223 void
courbe_editeur()224 courbe_editeur ()
225 {
226 Sint32 i, j, tmp_tsts_x, tmp_tsts_y, handle;
227 if (!courbe.total_numof_curves)
228 {
229 courbe.total_numof_curves = 1;
230 for (i = 0; i < CURVES_MAX_OF; i++)
231 {
232 courbe.delay_before_next[i] = 10;
233 }
234 }
235
236 /* draw grid lines */
237 for (i = 128; i <= (128 + LARG_GRILLE * 15); i += 16)
238 {
239 if (courbe.total_numof_curves)
240 line_v (game_offscreen + ((128 * offscreen_width) + i), 512,
241 (Sint16) (16 * courbe.total_numof_curves), coulor[GRIS]);
242 }
243 for (i = 128; i <= (128 + courbe.total_numof_curves * 16); i += 16)
244 {
245 line_h (game_offscreen + ((i * offscreen_width) + 128), 256,
246 coulor[GRIS]);
247 }
248
249 /* set mouse cursor x and y coordinates */
250 mouse_x -= 128;
251 mouse_y -= 128;
252
253 if (!keys_down[K_F] && !keys_down[K_T] && !keys_down[K_N] && !keys_down[K_B]
254 && !keys_down[K_V] && !keys_down[K_A])
255 {
256 /* set grid cursor x and y coordinates */
257 ge_act_pos_x = (Sint16) (mouse_x >> 4);
258 ge_act_pos_y = (Sint16) (mouse_y >> 4);
259 }
260
261 /* set mouse cursor x and y coordinates */
262 mouse_x += 128;
263 mouse_y += 128;
264
265 /* check minimum and maximum coordinates of the grid's cell selected */
266 if (ge_act_pos_x < 0)
267 {
268 ge_act_pos_x = 0;
269 }
270 if (ge_act_pos_x > (LARG_GRILLE - 1))
271 {
272 ge_act_pos_x = LARG_GRILLE - 1;
273 }
274 if (ge_act_pos_y < 0)
275 {
276 ge_act_pos_y = 0;
277 }
278 if (ge_act_pos_y > (courbe.total_numof_curves - 1))
279 {
280 ge_act_pos_y = (Sint16) (courbe.total_numof_curves - 1);
281 }
282 /* display current curve number */
283 ltoa ((Sint32) curv_number, chaine, 10);
284 textxy ("curv_number :", 128, 194 + 128 - 32, coulor[LIGHT_GRAY], 0,
285 game_offscreen, offscreen_width);
286 textxy ("c n ", 128, 194 + 128 - 32, coulor[RED], -1,
287 game_offscreen, offscreen_width);
288 textxy (chaine, 86 + 128 - 32, 194 + 128 - 32, coulor[WHITE], 0,
289 game_offscreen, offscreen_width);
290 /* display current enemy vessel number */
291 textxy ("ce_vais_act :", 128, 201 + 128 - 32, coulor[LIGHT_GRAY], 0,
292 game_offscreen, offscreen_width);
293 textxy (" e v ", 128, 201 + 128 - 32, coulor[RED], -1,
294 game_offscreen, offscreen_width);
295 itoa ((Sint32) ce_vais_act, chaine, 10);
296 textxy (chaine, 86 + 128 - 32, 201 + 128 - 32, coulor[WHITE], 0,
297 game_offscreen, offscreen_width);
298 /* display rate of fire of the enemy */
299 ltoa ((Sint32) courbe.freq_tir[ge_act_pos_y][ge_act_pos_x], chaine, 10);
300 textxy ("ce_freq_tir :", 128, 208 + 128 - 32, coulor[LIGHT_GRAY], 0,
301 game_offscreen, offscreen_width);
302 textxy (" f t ", 128, 208 + 128 - 32, coulor[RED], -1,
303 game_offscreen, offscreen_width);
304 textxy (chaine, 86 + 128 - 32, 208 + 128 - 32, coulor[WHITE], 0,
305 game_offscreen, offscreen_width);
306 /* display current coordinates of grid cursor selected */
307 textxy ("ge_act_pos :", 100 + 128 - 32, 194 + 128 - 32, coulor[LIGHT_GRAY],
308 0, game_offscreen, offscreen_width);
309 ltoa ((Sint32) ge_act_pos_x, chaine, 10);
310 textxy (chaine, 154 + 128 - 32, 194 + 128 - 32, coulor[WHITE], 0,
311 game_offscreen, offscreen_width);
312 ltoa ((Sint32) ge_act_pos_y, chaine, 10);
313 textxy (chaine, 162 + 128 - 32, 194 + 128 - 32, coulor[WHITE], 0,
314 game_offscreen, offscreen_width);
315 /* display number of curves used for this level */
316 textxy ("total_numof_curves :", 100 + 128 - 32, 201 + 128 - 32,
317 coulor[LIGHT_GRAY], 0, game_offscreen, offscreen_width);
318 textxy (" t c ", 100 + 128 - 32, 201 + 128 - 32, coulor[RED],
319 -1, game_offscreen, offscreen_width);
320 ltoa ((Sint32) (courbe.total_numof_curves), chaine, 10);
321 textxy (chaine, 170 + 128 - 32, 201 + 128 - 32, coulor[WHITE], 0,
322 game_offscreen, offscreen_width);
323 /* display curve number used for this level */
324 textxy ("num_courbe :", 100 + 128 - 32, 208 + 128 - 32, coulor[LIGHT_GRAY],
325 0, game_offscreen, offscreen_width);
326 textxy ("n b ", 100 + 128 - 32, 208 + 128 - 32, coulor[RED], -1,
327 game_offscreen, offscreen_width);
328 ltoa ((Sint32) (courbe.num_courbe[ge_act_pos_y]), chaine, 10);
329 textxy (chaine, 154 + 128 - 32, 208 + 128 - 32, coulor[WHITE], 0,
330 game_offscreen, offscreen_width);
331 /* display current coordinates of grid cursor selected */
332 textxy ("total_numof_enemies :", 178 + 128 - 32, 194 + 128 - 32,
333 coulor[LIGHT_GRAY], 0, game_offscreen, offscreen_width);
334 ltoa ((Sint32) courbe.total_numof_enemies[ge_act_pos_y], chaine, 10);
335 textxy (chaine, 258 + 128 - 32, 194 + 128 - 32, coulor[WHITE], 0,
336 game_offscreen, offscreen_width);
337 /* display time delay before next enemy */
338 textxy ("delay_before_next :", 178 + 128 - 32, 201 + 128 - 32,
339 coulor[LIGHT_GRAY], 0, game_offscreen, offscreen_width);
340 textxy (" v a ", 178 + 128 - 32, 201 + 128 - 32,
341 coulor[RED], -1, game_offscreen, offscreen_width);
342 ltoa ((Sint32) (courbe.delay_before_next[ge_act_pos_y]), chaine, 10);
343 textxy (chaine, 262 + 128 - 32, 201 + 128 - 32, coulor[WHITE], 0,
344 game_offscreen, offscreen_width);
345 /* display current coordinates of grid cursor selected */
346 line_v (game_offscreen +
347 ((((ge_act_pos_y << 4) + 128) * offscreen_width) +
348 ((ge_act_pos_x << 4) + 128)), offscreen_width, 16, coulor[RED]);
349 line_v (game_offscreen +
350 ((((ge_act_pos_y << 4) + 128) * offscreen_width) +
351 ((ge_act_pos_x << 4) + 128 + 16)), offscreen_width, 16,
352 coulor[RED]);
353 line_h (game_offscreen +
354 ((((ge_act_pos_y << 4) + 128) * offscreen_width) +
355 ((ge_act_pos_x << 4) + 128)), 16, coulor[RED]);
356 line_h (game_offscreen +
357 ((((ge_act_pos_y << 4) + 128 + 16) * offscreen_width) +
358 ((ge_act_pos_x << 4) + 128)), 16, coulor[RED]);
359 /* find total number of enemies on the current curve */
360 curve_find_numof_enemies ();
361 /* draw all enemies on the curve */
362 for (i = 0; i < courbe.total_numof_curves; i++)
363 {
364 for (j = 0; j < courbe.total_numof_enemies[i]; j++)
365 {
366 draw_sprite (enemi[courbe.num_vaisseau[i][j]][15].img,
367 game_offscreen + ((128 + i * 16) * offscreen_width) +
368 (128 + 16 * j),
369 enemi[courbe.num_vaisseau[i][j]][15].compress,
370 (Sint16) (enemi[courbe.num_vaisseau[i][j]]
371 [15].nbr_data_comp >> 2),
372 "enemi[courbe.num_vaisseau[i][j]][15].img");
373 }
374 }
375
376 /* draw the cureen curve */
377 tmp_tsts_x =
378 initial_curve[courbe.num_courbe[ge_act_pos_y]].pos_x + 128 - 32;
379 tmp_tsts_y =
380 initial_curve[courbe.num_courbe[ge_act_pos_y]].pos_y + 128 - 32;
381 for (i = 0;
382 i < initial_curve[courbe.num_courbe[ge_act_pos_y]].nbr_pnt_curve; i++)
383 {
384 if (tmp_tsts_x >= 0 && tmp_tsts_x < offscreen_width && tmp_tsts_y >= 0
385 && tmp_tsts_y < offscreen_height)
386 put_pixel (game_offscreen, tmp_tsts_x, tmp_tsts_y, coulor[GREEN]);
387 tmp_tsts_x += initial_curve[courbe.num_courbe[ge_act_pos_y]].delta_x[i];
388 tmp_tsts_y += initial_curve[courbe.num_courbe[ge_act_pos_y]].delta_y[i];
389 }
390 /* save a level curve */
391 if (keys_down[K_S] && keys_down[K_A] && !curve_s_key_down)
392 {
393 strcpy (str_file, "data/levels/curves_phase/curves_");
394 itoa ((Sint32) curv_number, str_tmp, 10);
395 strcat (str_file, str_tmp);
396 _fmode = O_BINARY;
397 if ((handle = _lcreat (str_file, NULL)) != -1)
398 {
399 _lwrite (handle, (const char *) &courbe.total_numof_curves,
400 sizeof (Sint16));
401 _lwrite (handle, (const char *) courbe.num_courbe,
402 sizeof (Sint16) * CURVES_MAX_OF);
403 _lwrite (handle, (const char *) courbe.total_numof_enemies,
404 sizeof (Sint16) * CURVES_MAX_OF);
405 _lwrite (handle, (const char *) courbe.delay_before_next,
406 sizeof (Sint16) * CURVES_MAX_OF);
407 _lwrite (handle, (const char *) courbe.num_vaisseau,
408 sizeof (Sint16) * CURVES_MAX_OF * NUM_VAI_BY_CURVE);
409 _lwrite (handle, (const char *) courbe.freq_tir,
410 sizeof (Sint16) * CURVES_MAX_OF * NUM_VAI_BY_CURVE);
411 _lclose (handle);
412 }
413 else
414 {
415 LOG_ERR ("Cannot create curve file!");
416 }
417 }
418 curve_s_key_down = keys_down[K_S];
419
420 /* load and enable a curve level */
421 if (keys_down[K_L] && keys_down[K_O] && !curve_l_key_down)
422 {
423 curve_load_level (curv_number);
424 curve_enable_level ();
425 }
426 curve_l_key_down = keys_down[K_L];
427
428 if (mouse_b)
429 {
430 /* change the curve number used for this level */
431 if (keys_down[K_C] && keys_down[K_N])
432 {
433 curv_number = (Sint16) (mouse_y - 128 + mouse_x - 128);
434 /* check range limits */
435 if (curv_number < 0)
436 {
437 curv_number = 0;
438 }
439 goto fin_curv_editor;
440 }
441
442 /* select a new enemy */
443 if (keys_down[K_V] && keys_down[K_E])
444 {
445 ce_vais_act = (Sint16) (mouse_x - 128);
446 /* check range limits */
447 if (ce_vais_act > (ENEMIES_MAX_SMALL_TYPES - 1))
448 {
449 ce_vais_act = (ENEMIES_MAX_SMALL_TYPES - 1);
450 }
451 if (ce_vais_act < 0)
452 {
453 ce_vais_act = 0;
454 }
455 goto fin_curv_editor;
456 }
457 /* modify the delay between two shots */
458 if (keys_down[K_F] && keys_down[K_T])
459 {
460 courbe.freq_tir[ge_act_pos_y][ge_act_pos_x] =
461 (Sint16) ((mouse_y - 128) * 4 + mouse_x - 128);
462 /* check range limits */
463 if (courbe.freq_tir[ge_act_pos_y][ge_act_pos_x] < 0)
464 {
465 courbe.freq_tir[ge_act_pos_y][ge_act_pos_x] = 0;
466 }
467 goto fin_curv_editor;
468 }
469 /* modify the number of curves for this level */
470 if (keys_down[K_C] && keys_down[K_T])
471 {
472 courbe.total_numof_curves =
473 (Sint16) (mouse_y - 128 + mouse_x - 128);
474 /* check range limits */
475 if (courbe.total_numof_curves < 1)
476 {
477 courbe.total_numof_curves = 1;
478 }
479 if (courbe.total_numof_curves > CURVES_MAX_OF)
480 {
481 courbe.total_numof_curves = CURVES_MAX_OF;
482 }
483 goto fin_curv_editor;
484 }
485
486 /* modify the curve number used for this level */
487 if (keys_down[K_N] && keys_down[K_B])
488 {
489 courbe.num_courbe[ge_act_pos_y] =
490 (Sint16) (mouse_y - 128 + mouse_x - 128);
491 /* check range limits */
492 if (courbe.num_courbe[ge_act_pos_y] < 0)
493 {
494 courbe.num_courbe[ge_act_pos_y] = 0;
495 }
496 if (courbe.num_courbe[ge_act_pos_y] > (CURVES_BEZIER_NUMOF - 1))
497 {
498 courbe.num_courbe[ge_act_pos_y] = CURVES_BEZIER_NUMOF - 1;
499 }
500 goto fin_curv_editor;
501 }
502
503 /* modify time delay before appearance of the next enemy */
504 if (keys_down[K_V] && keys_down[K_A])
505 {
506 courbe.delay_before_next[ge_act_pos_y] =
507 (Sint16) ((mouse_y - 128) * 4 + mouse_x - 128);
508 /* check range limits */
509 if (courbe.delay_before_next[ge_act_pos_y] < 10)
510 {
511 courbe.delay_before_next[ge_act_pos_y] = 10;
512 }
513 return;
514 }
515
516 /* right mouse down? */
517 if (mouse_b == 2)
518 {
519 /* clear grid's cells */
520 courbe.num_vaisseau[ge_act_pos_y][ge_act_pos_x] = -1;
521 courbe.freq_tir[ge_act_pos_y][ge_act_pos_x] = 0;
522 }
523 else
524 {
525 courbe.num_vaisseau[ge_act_pos_y][ge_act_pos_x] = ce_vais_act;
526 courbe.freq_tir[ge_act_pos_y][ge_act_pos_x] = 210;
527 }
528 }
529 fin_curv_editor:;
530 }
531 #endif
532
533 /**
534 * Load all curves files
535 * @return TRUE if it completed successfully or FALSE otherwise
536 */
537 bool
curves_load_all(void)538 curves_load_all (void)
539 {
540 Sint32 i, j;
541 char *fcurve;
542 signed char *ptr8;
543 Sint16 *ptr16;
544 for (i = 0; i < CURVES_BEZIER_NUMOF; i++)
545 {
546 fcurve = loadfile_num ("data/curves/bezier_curve_%03d.bin", i);
547 if (fcurve == NULL)
548 {
549 return FALSE;
550 }
551 /* 16-bit access */
552 ptr16 = (Sint16 *) fcurve;
553 /* number of points of the curve */
554 initial_curve[i].nbr_pnt_curve = little_endian_to_short (ptr16++);
555 /* start x coordinate */
556 initial_curve[i].pos_x = little_endian_to_short (ptr16++);
557 /* start y coordinate */
558 initial_curve[i].pos_y = little_endian_to_short (ptr16++);
559 /* 8-bit access */
560 ptr8 = (signed char *) ptr16;
561 for (j = 0; j < initial_curve[i].nbr_pnt_curve; j++)
562 {
563 initial_curve[i].delta_x[j] = *(ptr8++);
564 initial_curve[i].delta_y[j] = *(ptr8++);
565 initial_curve[i].angle[j] = *(ptr8++);
566 }
567 free_memory (fcurve);
568 }
569 return TRUE;
570 }
571
572 /**
573 * load a level curve file and copy data into curve structure
574 * @param level_num level number from 0 to 41
575 * @return TRUE if it completed successfully or FALSE otherwise
576 */
577 bool
curve_load_level(Sint32 level_num)578 curve_load_level (Sint32 level_num)
579 {
580 char *level_data;
581 Sint16 *source;
582 Sint16 *dest;
583 Sint32 i;
584
585 /* load the file of the level curve */
586 if (level_num > MAX_NUM_OF_LEVELS || level_num < 0)
587 {
588 level_num = 0;
589 }
590 level_data =
591 loadfile_num ("data/levels/curves_phase/curves_%02d.bin", level_num);
592 if (level_data == NULL)
593 {
594 return FALSE;
595 }
596 source = (Sint16 *) level_data;
597
598 /* read the number of curves for this level */
599 courbe.total_numof_curves = little_endian_to_short (source++);
600
601 /* read the curves numbers used for this level */
602 for (i = 0; i < CURVES_MAX_OF; i++)
603 {
604 courbe.num_courbe[i] = little_endian_to_short (source++);
605 }
606
607 /* read the number of enemies on each curve */
608 for (i = 0; i < CURVES_MAX_OF; i++)
609 {
610 courbe.total_numof_enemies[i] = little_endian_to_short (source++);
611 }
612 /* read time delay before appearance of the next enemy */
613 for (i = 0; i < CURVES_MAX_OF; i++)
614 {
615 courbe.delay_before_next[i] = little_endian_to_short (source++);
616 }
617
618 /* read the numbers of enemies used on each curve */
619 dest = &courbe.num_vaisseau[0][0];
620 for (i = 0; i < CURVES_MAX_OF * NUM_VAI_BY_CURVE; i++)
621 {
622 *(dest++) = little_endian_to_short (source++);
623 }
624
625 /* read the delay between two shots */
626 dest = &courbe.freq_tir[0][0];
627 for (i = 0; i < CURVES_MAX_OF * NUM_VAI_BY_CURVE; i++)
628 {
629 *(dest++) = little_endian_to_short (source++);
630 }
631 free_memory (level_data);
632 return TRUE;
633 }
634
635 /**
636 * Initialize and enable a curve phase
637 */
638 void
curve_enable_level(void)639 curve_enable_level (void)
640 {
641 Sint32 i;
642 #ifdef DEVELOPPEMENT
643 enemy *foe;
644 Sint32 j;
645 spaceship_struct *ship = spaceship_get ();
646 #endif
647
648 /* search the total number of enemies */
649 curve_find_numof_enemies ();
650 for (i = 0; i < courbe.total_numof_curves; i++)
651 {
652 /* set the number of enemies */
653 courbe.current_numof_enemies[i] = 0;
654 /* clear counter delay before appearance of the next enemy */
655 courbe.count_before_next[i] = 0;
656
657 #ifdef DEVELOPPEMENT
658 if (!curve_editor_enable)
659 {
660 continue;
661 }
662 /* add new a enemy sprite to the list */
663 foe = enemy_get ();
664 if (foe == NULL)
665 {
666 return;
667 }
668 /* set power of destruction */
669 foe->spr.pow_of_dest =
670 (Sint16) (5 + 1 +
671 courbe.num_vaisseau[i][courbe.current_numof_enemies[i]]);
672 /* set energy level */
673 foe->spr.energy_level =
674 (Sint16) ((ship->type << 1) + foe->spr.pow_of_dest - 5);
675 /* set size of the sprite as 16x16 pixels */
676 foe->type = 0;
677 /* set number of images for animation */
678 foe->spr.numof_images = 32;
679 /* set current image */
680 foe->spr.current_image = initial_curve[courbe.num_courbe[i]].angle[0];
681 /* set addresses of the images buffer */
682 for (j = 0; j < foe->spr.numof_images; j++)
683 {
684 foe->spr.img[j] =
685 (image *) &
686 enemi[courbe.num_vaisseau[i][courbe.nbr_vaisseaux_act[i]]][j];
687 }
688 /* set shot time-frequency */
689 foe->fire_rate = courbe.freq_tir[i][courbe.current_numof_enemies[i]];
690 /* set counter of delay between two shots */
691 foe->fire_rate_count = foe->fire_rate;
692 /* set type of displacement */
693 foe->displacement = DISPLACEMENT_CURVE;
694 /* set x and y coordinates */
695 foe->spr.xcoord =
696 (float) (initial_curve[courbe.num_courbe[i]].pos_x + 128 - 32);
697 foe->spr.ycoord =
698 (float) (initial_curve[courbe.num_courbe[i]].pos_y + 128 - 32);
699 /* clear index on the precalculated bezier curve */
700 foe->pos_vaiss[POS_CURVE] = 0;
701 /* set curve number used */
702 foe->num_courbe = courbe.num_courbe[i];
703 /* increase number of the enemies on the curve */
704 courbe.current_numof_enemies[i]++;
705 #endif
706 }
707 }
708
709 /**
710 * Fin the total number of enemies on a curve
711 */
712 void
curve_find_numof_enemies(void)713 curve_find_numof_enemies (void)
714 {
715 Sint32 i, j;
716
717 find_num_of_enemies:;
718 for (i = 0; i < courbe.total_numof_curves; i++)
719 {
720 courbe.total_numof_enemies[i] = 0;
721 for (j = 0; j < NUM_VAI_BY_CURVE; j++)
722 {
723 /* enemy exist. */
724 if (courbe.num_vaisseau[i][j] != -1)
725 {
726 /* increase the number of enemies */
727 courbe.total_numof_enemies[i]++;
728 /* previous curve is empty? */
729 if (j && courbe.num_vaisseau[i][j - 1] == -1)
730 {
731 courbe.num_vaisseau[i][j - 1] = courbe.num_vaisseau[i][j];
732 courbe.freq_tir[i][j - 1] = courbe.freq_tir[i][j];
733 courbe.num_vaisseau[i][j] = -1;
734 courbe.freq_tir[i][j] = 0;
735 goto find_num_of_enemies;
736 }
737 }
738 }
739 }
740 }
741