1 /**
2  * @file controller_game_over.cc
3  * @brief Game Over controller
4  * @created 2002-12-14
5  * @date 2007-10-21
6  * @copyright 1991-2014 TLK Games
7  * @author Bruno Ethvignot
8  * @version $Revision: 24 $
9  */
10 /*
11  * copyright (c) 1991-2014 TLK Games all rights reserved
12  * $Id: controller_game_over.cc 24 2014-09-28 15:30:04Z bruno.ethvignot@gmail.com $
13  *
14  * TecnoballZ is free software; you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation; either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * TecnoballZ is distributed in the hope that it will be useful, but
20  * WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
27  * MA  02110-1301, USA.
28  */
29 #include "../include/controller_game_over.h"
30 #include "../include/handler_audio.h"
31 #include "../include/handler_resources.h"
32 #include "../include/handler_high_score.h"
33 
34 /**
35  * Create the Game Over controller
36  */
controller_game_over()37 controller_game_over::controller_game_over ()
38 {
39   littleInit ();
40   /* there are 8 letters */
41   max_of_sprites = 8;
42   sprites_have_shades = true;
43   max_of_sprites = 8;
44   sprite_type_id = sprite_object::GAME_OVER_LETTERS;
45   move_phase = 0;
46   sprite_high_score = (sprite_display_scores *) NULL;
47 }
48 
49 /**
50  * Release the Game Over controller
51  */
~controller_game_over()52 controller_game_over::~controller_game_over ()
53 {
54   if (NULL != sprite_high_score)
55     {
56       delete sprite_high_score;
57       sprite_high_score = NULL;
58     }
59   release_sprites_list ();
60 }
61 
62 /**
63  * Return pointer to the high score object
64  * @return A sprite_display_scores object
65  */
66 sprite_display_scores *
get_sprite_high_score()67 controller_game_over::get_sprite_high_score ()
68 {
69   return sprite_high_score;
70 }
71 
72 /**
73  * Perform some initializations
74  */
75 void
first_init(Uint32 x_offset)76 controller_game_over::first_init (Uint32 x_offset)
77 {
78   char_x_offset = x_offset;
79 
80   /* enable_game_over score table */
81   sprite_high_score = new sprite_display_scores ();
82   sprite_high_score->first_init (char_x_offset);
83 }
84 
85 /**
86  * Enable the Game Over
87  * @param is_victory If true game is finished, play game over with
88  *                   congratulations
89  */
90 void
enable_game_over(bool is_victory)91 controller_game_over::enable_game_over (bool is_victory)
92 {
93   Sint32 x = 100 * resolution;
94   Sint32 y = 200 * resolution;
95   const Sint32 *p = initial_coordinates;
96   for (Uint32 i = 0; i < max_of_sprites; i++)
97     {
98       sprite_object *sprite = sprites_list[i];
99       sprite->enable ();
100       sprite->set_coordinates (x, y);
101       sprite->set_image (i);
102       Sint32 x2 = *(p++);
103       Sint32 y2 = *(p++);
104       sprite->x_maximum = x2;
105       sprite->y_maximum = y2;
106     }
107   move_phase = 1;
108   next_phase_counter = 50 * 10;
109 #ifndef SOUNDISOFF
110   bool is_ranked = high_score->is_player_ranked ();
111   if (is_victory)
112     {
113       audio->play_music (handler_audio::MUSICCONGR);
114     }
115   else
116     {
117       if (is_ranked)
118         {
119           audio->play_music (handler_audio::MUSICSCORE);
120         }
121       else
122         {
123           audio->play_music (handler_audio::MUSICGOVER);
124         }
125     }
126 #else
127   high_score->is_player_ranked ();
128 #endif
129   sprite_high_score->copyToText ();
130 }
131 
132 /**
133  * Move the "GAME OVER" chars and draw high score
134  * @param is_victory If true game is finished, play game over with
135  *                   congratulations
136  */
137 void
run(bool is_victory)138 controller_game_over::run (bool is_victory)
139 {
140   switch (move_phase)
141     {
142     case 0:
143       enable_game_over (is_victory);
144       break;
145 
146     case 1:
147       displacement_01 ();
148       break;
149 
150     case 2:
151       displacement_02 ();
152       break;
153 
154     case 3:
155       displacement_03 ();
156       break;
157 
158     case 4:
159       displacement_04 ();
160       break;
161     }
162   sprite_high_score->displayTxt ();
163   sprite_high_score->draw_copy_from_bitmap ();
164 }
165 
166 /**
167  * Movement 1
168  */
169 void
displacement_01()170 controller_game_over::displacement_01 ()
171 {
172   Sint32 maxi = SIZETSINUS;
173   Sint32 decal = 32 * resolution;
174   const Sint32 *sinus = sinus_over;
175   for (Uint32 i = 0; i < max_of_sprites; i++)
176     {
177       sprite_object *sprite = sprites_list[i];
178       if (++sprite->x_maximum >= maxi)
179         {
180           sprite->x_maximum = 0;
181         }
182       if (++sprite->y_maximum >= maxi)
183         {
184           sprite->y_maximum = 0;
185         }
186       Sint32 x = char_x_offset + decal
187         + sinus[sprite->x_maximum] * resolution;
188       Sint32 y = decal + sinus[sprite->y_maximum] * resolution;
189       sprite->set_coordinates (x, y);
190       random_counter += y;
191     }
192   if (--next_phase_counter <= 0)
193     {
194       move_phase = 2;
195     }
196 }
197 
198 /**
199  * Movement 2
200  */
201 void
displacement_02()202 controller_game_over::displacement_02 ()
203 {
204   Sint32 maxi = SIZETSINUS;
205   Sint32 decal = 32 * resolution;
206   const Sint32 *sinus = sinus_over;
207   for (Uint32 i = 0; i < max_of_sprites; i++)
208     {
209       sprite_object *sprite = sprites_list[i];
210       if (++sprite->y_maximum >= maxi)
211         {
212           sprite->y_maximum = 0;
213         }
214       Sint32 y = decal + sinus[sprite->y_maximum] * resolution;
215       sprite->set_y_coord (y);
216       random_counter += y;
217     }
218 
219   /* move the letters "G", "A", "M", and "E" */
220   Sint32 f = 0;
221   Sint32 v = 32 * resolution + char_x_offset;
222   for (Sint32 i = 0; i < 4; i++)
223     {
224       sprite_object *sprite = sprites_list[i];
225       if (sprite->x_coord > v)
226         {
227           sprite->x_coord -= resolution;
228           f = 1;
229         }
230     }
231 
232   /* move the letters "O", "V", "E", and "R" */
233   v = 192 * resolution + char_x_offset;
234   for (Uint32 i = 4; i < max_of_sprites; i++)
235     {
236       sprite_object *sprite = sprites_list[i];
237       if (sprite->x_coord < v)
238         {
239           sprite->x_coord += resolution;
240           f = 1;
241         }
242     }
243 
244   if (f <= 0)
245     {
246       move_phase = 3;
247     }
248 }
249 
250 /**
251  * Movement 2
252  */
253 void
displacement_03()254 controller_game_over::displacement_03 ()
255 {
256   /* move the letters "G", "A", "M" and "E" */
257   Sint32 f = 0;
258   Sint32 maxi = SIZETSINUS;
259   Sint32 decal = 32 * resolution;
260   const Sint32 *sinus = sinus_over;
261   for (Sint32 i = 0; i < 4; i++)
262     {
263       sprite_object *sprite = sprites_list[i];
264       if (++sprite->y_maximum >= maxi)
265         {
266           sprite->y_maximum = 0;
267         }
268       if (sprite->y_coord <= decal)
269         {
270           sprite->y_coord = decal;
271           f++;
272         }
273       else
274         {
275           Sint32 y = decal + sinus[sprite->y_maximum] * resolution;
276           sprite->set_y_coord (y);
277         }
278       random_counter += sprite->y_maximum;
279     }
280 
281   /* move the letters "O", "V", "E" and "R" */
282   Sint32 v = 191 * resolution;
283   for (Uint32 i = 4; i < max_of_sprites; i++)
284     {
285       sprite_object *sprite = sprites_list[i];
286       if (++sprite->y_maximum >= maxi)
287         sprite->y_maximum = 0;
288       if (sprite->y_coord >= v)
289         {
290           sprite->y_coord = v;
291           f++;
292         }
293       else
294         {
295           Sint32 y = decal + sinus[sprite->y_maximum] * resolution;
296           sprite->set_y_coord (y);
297         }
298       random_counter += sprite->y_maximum;
299     }
300   if (f == 8)
301     {
302       move_phase = 4;
303     }
304 }
305 
306 /**
307  * movement 4 : the letters are moving towards their final abscissas
308  */
309 void
displacement_04()310 controller_game_over::displacement_04 ()
311 {
312   /* move the letters "G", "A", "M", and "E" */
313   Sint32 offst = 2 * resolution;
314   Sint32 final = 35 * resolution + char_x_offset;
315   for (Sint32 i = 0; i < 4; i++)
316     {
317       sprite_object *sprite = sprites_list[i];
318       Sint32 o = final - sprite->x_coord;
319       if (o > offst)
320         {
321           o = offst;
322         }
323       else
324         {
325           if (o < (-offst))
326             {
327               o = -offst;
328             }
329         }
330       sprite->x_coord += o;
331       final = final + 54 * resolution;
332       random_counter += sprite->x_coord;
333     }
334 
335   /* move the letters "O", "V", "E" and "R" */
336   final = 32 * resolution + char_x_offset;
337   for (Uint32 i = 4; i < max_of_sprites; i++)
338     {
339       sprite_object *sprite = sprites_list[i];
340       Sint32 o = final - sprite->x_coord;
341       if (o > offst)
342         {
343           o = offst;
344         }
345       else
346         {
347           if (o < (-offst))
348             {
349               o = -offst;
350             }
351         }
352       sprite->x_coord += o;
353       final = final + 54 * resolution;
354       random_counter += sprite->x_coord;
355     }
356 }
357 
358 const Sint32 controller_game_over::sinus_over[SIZETSINUS] =
359   {
360     159, 159, 159, 159, 158, 158, 158, 157, 156, 156,
361     155, 154, 153, 152, 151, 150, 149, 148, 147, 145,
362     144, 142, 141, 139, 137, 135, 134, 132, 130, 128,
363     126, 124, 122, 120, 117, 115, 113, 111, 108, 106,
364     104, 101, 99, 96, 94, 91, 89, 86, 84, 81,
365     79, 76, 74, 71, 69, 66, 64, 61, 59, 57,
366     54, 52, 50, 47, 45, 43, 40, 38, 36, 34,
367     32, 30, 28, 26, 24, 23, 21, 19, 18, 16,
368     15, 13, 12, 11, 9, 8, 7, 6, 5, 4,
369     4, 3, 2, 2, 1, 1, 0, 0, 0, 0,
370     0, 0, 0, 0, 1, 1, 2, 2, 3, 4,
371     4, 5, 6, 7, 8, 9, 11, 12, 13, 15,
372     16, 18, 19, 21, 23, 24, 26, 28, 30, 32,
373     34, 36, 38, 40, 43, 45, 47, 50, 52, 54,
374     57, 59, 61, 64, 66, 69, 71, 74, 76, 79,
375     81, 84, 86, 89, 91, 94, 96, 99, 101, 104,
376     106, 108, 111, 113, 115, 117, 120, 122, 124, 126,
377     128, 130, 132, 134, 135, 137, 139, 141, 142, 144,
378     145, 147, 148, 149, 150, 151, 152, 153, 154, 155,
379     156, 156, 157, 158, 158, 158, 159, 159, 159, 159,
380   };
381 
382 const Sint32 controller_game_over::initial_coordinates[] =
383   {
384     0, 175,
385     25, 150,
386     50, 125,
387     75, 100,
388     100, 75,
389     125, 50,
390     150, 25,
391     175, 0
392   };
393