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