1 /**
2  * @file supervisor_bricks_level.cc
3  * @brief Bricks levels supervisor
4  * @date 2012-09-15
5  * @copyright 1991-2014 TLK Games
6  * @author Bruno Ethvignot
7  * @version $Revision: 24 $
8  */
9 /*
10  * copyright (c) 1991-2014 TLK Games all rights reserved
11  * $Id: supervisor_bricks_level.cc 24 2014-09-28 15:30:04Z bruno.ethvignot@gmail.com $
12  *
13  * TecnoballZ is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * TecnoballZ is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26  * MA  02110-1301, USA.
27  */
28 #include "../include/supervisor_bricks_level.h"
29 #include "../include/handler_resources.h"
30 
31 /**
32  * Create the bricks level supervisor
33  */
supervisor_bricks_level()34 supervisor_bricks_level::supervisor_bricks_level ()
35 {
36   initialize ();
37   sides_bricks = controller_sides_bricks::get_instance ();
38   tiles_ground = tiles_background::get_instance ();
39   panel_score = right_panel_score::get_instance ();
40   ejectors_corners = controller_ejectors::get_instance ();
41   money_capsules = controller_moneys::get_instance ();
42   power_up_capsules = controller_capsules::get_instance ();
43   gem_stones = controller_gems::get_instance ();
44   bricks = controller_bricks::get_instance ();
45   head_anim = head_animation::get_instance ();
46   ships = controller_ships::get_instance ();
47   magnetic_eyes = controller_magnetic_eyes::get_instance ();
48   bottom_wall = sprite_wall::get_instance ();
49   info_messages = short_info_messages::get_instance ();
50   balls = controller_balls::get_instance ();
51   viewfinders_paddles = controller_viewfinders::get_instance ();
52   paddles = controller_paddles::get_instance ();
53   font_game = controller_font_game::get_instance ();
54   gigablitz = controller_gigablitz::get_instance ();
55   player_indicators = controller_indicators::get_instance ();
56   game_over = controller_game_over::get_instance ();
57 
58   popup_menu = new handler_popup_menu ();
59 
60   sprite_projectile::start_list ();
61   level_number = 1;
62   area_number = 1;
63   gameover_counter = 0;
64 #ifdef UNDER_DEVELOPMENT
65   backgound_index = 0;
66   devel_keyw = false;
67   devel_keyx = false;
68 #endif
69 }
70 
71 /**
72  * Release the bricks level supervisor
73  */
~supervisor_bricks_level()74 supervisor_bricks_level::~supervisor_bricks_level ()
75 {
76   delete popup_menu;
77   delete game_over;
78   delete player_indicators;
79   delete gigablitz;
80   delete font_game;
81   delete paddles;
82   delete viewfinders_paddles;
83   delete balls;
84   delete info_messages;
85   delete bottom_wall;
86   delete magnetic_eyes;
87   delete ships;
88   delete head_anim;
89   delete bricks;
90   delete gem_stones;
91   delete power_up_capsules;
92   delete money_capsules;
93   delete ejectors_corners;
94   delete panel_score;
95   delete tiles_ground;
96   delete sides_bricks;
97   release ();
98 }
99 
100 /**
101  * Initialization of a bricks level
102  */
103 void
first_init()104 supervisor_bricks_level::first_init ()
105 {
106   game_screen->clear ();
107   sprites->reset ();
108   area_number = current_player->get_area_number ();
109   level_number = current_player->get_level_number ();
110 #ifndef SOUNDISOFF
111   audio->play_level_music (area_number, level_number);
112   audio->enable_sound ();
113 #endif
114 
115   count_next = 0;
116   next_phase = 0;
117   gameover_counter = 0;
118   if (is_verbose)
119     {
120       std::cout << "supervisor_bricks_level::first_init() area_number:"
121                 << area_number << "level_number:" << level_number
122                 << " difficulty_level:" << difficulty_level << std::endl;
123     }
124 
125   /* generation of paddles graphics shapes tables */
126   paddles->create_paddles_sprites ();
127 
128   /* generation of gigablitz graphics shapes tables */
129   gigablitz->create_gigablitz_sprites ();
130 
131   /* load bitmap of sprites in memory (all other sprites) */
132   resources->load_sprites_bitmap ();
133 
134   /*
135    * generate the data of the spites
136    */
137   bottom_wall->create_sprite (sprite_object::BOTTOM_WALL, sprites_bitmap, 0);
138   sprites->add (bottom_wall);
139   bottom_wall->set_coordinates (32 * resolution, 232 * resolution);
140   paddles->initialize_robot ();
141   sides_bricks->initialize ();
142   ejectors_corners->create_ejectors_sprites ();
143 
144   initialize_background ();
145   bricks->add_to_sprites_list ();
146 
147   game_over->create_sprites_list ();
148   balls->create_sprites_list ();
149   ships->create_sprites_list ();
150   magnetic_eyes->create_eyes_list ();
151   money_capsules->create_sprites_list ();
152   power_up_capsules->create_sprites_list (6);
153   gem_stones->create_sprites_list ();
154   font_game->create_sprites_list ();
155   paddles->create_projectiles_list ();
156   player_indicators->create_indicators_sprites ();
157   viewfinders_paddles->create_sprites_list ();
158   popup_menu->first_init (sprites_bitmap);
159   resources->release_sprites_bitmap ();
160   panel_score->first_init ();
161 
162   display->lock_surfaces ();
163 
164   /* initialize controller of the big letters animated composing the word
165    * "game over"  */
166   game_over->first_init ();
167   head_anim->load_bitmap ();
168   init_level ();
169   /* draw ejectors and side walls */
170   paddles->init_paddles (gigablitz, balls);
171 
172   /* balls initialization */
173   balls->init (
174     /* time before the ball leaves paddle, at the level beginning */
175     level_desc->ball_release_time,
176     /* time before the ball leaves (glue option) */
177     level_desc->glue_time / difficulty_level,
178     /* time before the ball accelerates */
179     level_desc->acceleration_delay / difficulty_level,
180     /* time before "tilt" is available */
181     level_desc->tilt_delay, level_desc->starting_speed);
182 
183   ships->initialise (level_desc->reappearance / difficulty_level,
184                      level_desc->ship_appearance_delay1 / difficulty_level,
185                      level_desc->ship_appearance_delay2 / difficulty_level,
186                      level_desc->ship_appearance_delay3 / difficulty_level,
187                      level_desc->ship_appearance_delay4 / difficulty_level,
188                      level_desc->ships_strength * difficulty_level);
189 
190   money_capsules->initialize (level_desc->moneys_frequency * difficulty_level,
191                               panel_score, player_indicators);
192 
193   /* initialize the object which handles bonus and penalty capsules */
194   power_up_capsules->initialize (level_desc->penalties_frequency *
195                                  difficulty_level, level_desc->malusListe);
196   gem_stones->initialize ();
197   /* initialize sprite fonts "LEVEL x COMPLETED" */
198   font_game->initialize (level_number);
199   viewfinders_paddles->initialize ();
200   display->unlock_surfaces ();
201   /* copy the background offscreen to the game offscreen */
202   if (has_background)
203     {
204       background_screen->blit_to_surface (game_screen);
205     }
206   keyboard->clear_command_keys ();
207   keyboard->set_grab_input (true);
208   info_messages->send_message_request (short_info_messages::ARE_YOU_READY);
209 }
210 
211 /**
212  * Reads the parameters of the current level
213  */
214 void
init_level()215 supervisor_bricks_level::init_level ()
216 {
217   level_desc =
218     ptLev_data->get_bricks_levels_params (area_number, level_number);
219 }
220 
221 /**
222  * Main loop in the bricks level
223  * @return
224  */
main_loop()225 Uint32 supervisor_bricks_level::main_loop ()
226 {
227   Sint32
228   Ecode = -1;
229 
230   /*
231    * the player has no more lives: Game Over
232    */
233   if (current_player->get_num_of_lifes () <= 0)
234     {
235       if (gameover_counter == 0)
236         {
237 #ifndef SOUNDISOFF
238           audio->disable_sound ();
239           audio->stop_music ();
240 #endif
241           paddles->disable_all_paddles ();
242           bricks->clr_bricks ();
243           font_game->disable_sprites ();
244           gem_stones->disable_sprites ();
245           power_up_capsules->disable_sprites ();
246           money_capsules->disable_sprites ();
247           balls->disable_sprites ();
248           sprite_projectile::disable_sprites ();
249           info_messages->clear_messages_request ();
250           tiles_ground->
251           set_scroll_type (tiles_background::TILES_SCROLL_GAMEOVER);
252           gameover_counter++;
253         }
254       if (has_background)
255         {
256           info_messages->run ();
257         }
258       display->wait_frame ();
259       head_anim->play ();
260       display->lock_surfaces ();
261       gigablitz->run_in_bricks_levels ();
262       if (has_background)
263         {
264           sprites->clear ();
265         }
266       if (!(random_counter & 0x00f))
267         {
268           head_anim->start_interference ();
269         }
270 
271       sides_bricks->run ();
272       viewfinders_paddles->run ();
273       ships->move ();
274       draw_tilesmap ();
275       sprites->draw ();
276 
277       if (gameover_counter >= 2)
278         {
279           gameover_counter++;
280           game_over->run ();
281         }
282       if (!bricks->update () && gameover_counter < 2)
283         {
284           gameover_counter = 2;
285         }
286 
287 
288       panel_score->draw_gigablizt_gauge ();
289       player_indicators->display_money_and_reverse ();
290       display->unlock_surfaces ();
291       panel_score->text_refresh ();
292       display->window_update ();
293       if (keyboard->wait_key () && gameover_counter > 60)
294         {
295           current_player =
296             handler_players::get_next_player (current_player, &next_phase, 1);
297         }
298     }
299 
300   /*
301    * game is running!
302    */
303   else
304     {
305       display->wait_frame ();
306       if (!keyboard->command_is_pressed (handler_keyboard::COMMAND_KEY_PAUSE))
307         {
308           head_anim->play ();
309         }
310       sides_bricks->run ();
311       display->lock_surfaces ();
312       if (has_background)
313         {
314           sprites->clear ();
315         }
316       bricks->color_cycling ();
317       /* draw or clear bricks
318        * send a money and/or a capsule */
319       bricks->update ();
320       switch_background ();
321 
322       if (!keyboard->command_is_pressed (handler_keyboard::COMMAND_KEY_PAUSE))
323         {
324           if (has_background)
325             {
326               info_messages->run ();
327             }
328           gigablitz->run_in_bricks_levels ();
329           /* handle the "less bricks" option */
330           bricks->less_bricks ();
331           paddles->move_paddles ();
332           if (panel_score->get_bricks_counter () > 0)
333             {
334               paddles->check_if_release_balls ();
335               paddles->fire_projectiles ();
336             }
337           paddles->move_robot ();
338           balls->run_in_bricks_levels ();
339           viewfinders_paddles->run ();
340           sprite_projectile::gestionTir ();
341           ships->move ();
342           magnetic_eyes->move ();
343           money_capsules->move ();
344           power_up_capsules->move_in_bricks_level ();
345           power_up_capsules->check_cheat_keys ();
346           gem_stones->move ();
347           font_game->move ();
348           if (bottom_wall->thecounter < 1)
349             {
350               bottom_wall->disable ();
351             }
352           else
353             {
354               bottom_wall->thecounter--;
355             }
356 
357           panel_score->draw_gigablizt_gauge ();
358           player_indicators->display_money_and_reverse ();
359         }
360 
361       draw_tilesmap ();
362       sprites->draw ();
363       Ecode = popup_menu->run ();
364       display->unlock_surfaces ();
365       panel_score->text_refresh ();
366       display->window_update ();
367 
368       /*
369        * jump to next level or next player
370        */
371       if (panel_score->get_bricks_counter () == 0)
372         {
373           if (count_next > 0)
374             {
375               count_next++;
376               bool
377               music_finished = false;
378               if (count_next > 350)
379                 {
380                   music_finished = true;
381 #ifndef SOUNDISOFF
382                   music_finished = audio->is_win_music_finished ();
383 #endif
384                 }
385               if (count_next > 20000000 ||
386                   keyboard->wait_key () || music_finished)
387                 {
388                   sides_bricks->save_state_of_walls ();
389                   current_player =
390                     handler_players::get_next_player (current_player,
391                                                       &next_phase);
392 #ifndef SOUNDISOFF
393                   audio->stop_music ();
394 #endif
395                 }
396               balls->disable_sprites ();
397               sprite_projectile::disable_sprites ();
398             }
399           else
400             {
401               font_game->enable ();
402               sprite_projectile::disable_sprites ();
403               balls->disable_sprites ();
404 #ifndef SOUNDISOFF
405               audio->play_win_music ();
406 #endif
407               info_messages->
408               send_message_request (short_info_messages::NEXT_LEVEL);
409 #ifndef SOUNDISOFF
410               audio->disable_sound ();
411 #endif
412               tiles_ground->
413               set_scroll_type (tiles_background::TILES_SCROLL_WIN);
414               count_next = 1;
415             }
416         }
417     }
418 
419   /* escape key to quit the game! */
420   if (keyboard->command_is_pressed (handler_keyboard::QUIT_TECNOBALLZ) ||
421       Ecode == handler_popup_menu::QUIT_TECNOBALLZ)
422     {
423       next_phase = LEAVE_TECNOBALLZ;
424     }
425   if (keyboard->command_is_pressed (handler_keyboard::CAUSE_GAME_OVER) ||
426       Ecode == handler_popup_menu::CAUSE_GAME_OVER)
427     {
428       current_player->remove_all_lifes ();
429     }
430   if (keyboard->command_is_pressed (handler_keyboard::QUIT_TO_MAIN_MENU) ||
431       Ecode == handler_popup_menu::QUIT_TO_MAIN_MENU)
432     {
433       next_phase = MAIN_MENU;
434     }
435 
436   /* control position music's module */
437 #ifndef SOUNDISOFF
438   Uint32
439   phase = audio->get_portion_music_played ();
440   if (phase == handler_audio::LOST_PORTION &&
441       phase != audio->get_portion_music_played ())
442     {
443       info_messages->
444       send_message_request (short_info_messages::YEAH_YOU_WHERE);
445       paddles->release_all_balls ();
446     }
447 #endif
448   return next_phase;
449 }
450 
451 /**
452  * Change the tiles background
453  */
454 void
switch_background()455 supervisor_bricks_level::switch_background ()
456 {
457 #ifdef UNDER_DEVELOPMENT
458   if (keyboard->key_is_pressed (SDLK_RSHIFT) ||
459       keyboard->key_is_pressed (SDLK_LSHIFT) ||
460       keyboard->key_is_pressed (SDLK_RCTRL) ||
461       keyboard->key_is_pressed (SDLK_LCTRL) ||
462       keyboard->key_is_pressed (SDLK_RALT) ||
463       !keyboard->key_is_pressed (SDLK_LALT))
464     {
465       return;
466     }
467 
468   if (keyboard->key_is_pressed (SDLK_w))
469     {
470       devel_keyw = true;
471     }
472   if (keyboard->key_is_pressed (SDLK_x))
473     {
474       devel_keyx = true;
475     }
476 
477   if ((keyboard->key_is_released (SDLK_w) && devel_keyw) ||
478       (keyboard->key_is_released (SDLK_x) && devel_keyx))
479     {
480       game_screen->clear ();
481 
482       if (devel_keyw)
483         {
484           devel_keyw = false;
485           if (--backgound_index < 0)
486             {
487               backgound_index = 49;
488             }
489         }
490       if (devel_keyx)
491         {
492           devel_keyx = false;
493           if (++backgound_index > 49)
494             {
495               backgound_index = 0;
496             }
497         }
498       if (is_verbose)
499         {
500           std::cout << ">supervisor_bricks_level::switch_background: " <<
501                     "backgound_index: " << backgound_index << std::endl;
502         }
503       initialize_background (backgound_index);
504       background_screen->blit_to_surface (game_screen);
505     }
506 
507   if (keyboard->key_is_pressed (SDLK_v))
508     {
509       head_anim->start_yawn ();
510     }
511   if (keyboard->key_is_pressed (SDLK_b))
512     {
513       head_anim->start_yawn ();
514     }
515   if (keyboard->key_is_pressed (SDLK_n))
516     {
517       head_anim->start_interference ();
518     }
519   if (keyboard->key_is_pressed (SDLK_g))
520     {
521       gigablitz->shoot_paddle ();
522     }
523   /*
524 
525      if(keyboard->key_is_pressed(SDLK_w))
526      {
527      }
528 
529      if(keyboard->key_is_pressed(SDLK_w))
530      { keyw = 1;
531      }
532 
533 
534      if(keyboard->key_is_released(SDLK_w) && keyw == 1)
535      { tiles_ground->prev_color();
536      keyw = 0;
537      }
538      if(keyboard->key_is_released(SDLK_x) && keyx == 1)
539      { tiles_ground->next_color();
540      keyx = 0;
541      }
542    */
543 
544 
545 #endif
546 }
547 
548 /**
549  * Initialize the background, draw tiles side bricks and bicks
550  * @param bkg_num tileset number, if negative then the
551  *                tilesset number depends on the current level number
552  */
553 void
initialize_background(Sint32 bkg_num)554 supervisor_bricks_level::initialize_background (Sint32 bkg_num)
555 {
556   if (is_verbose)
557     {
558       std::cout << ">supervisor_bricks_level::initialize_background() start! "
559                 << std::endl;
560     }
561   if (bkg_num < 0)
562     {
563       bkg_num = ((area_number - 1) * 10) + level_number;
564       if (level_number > 5)
565         {
566           bkg_num--;
567         }
568       if (is_verbose)
569         {
570           std::cout << "supervisor_bricks_level::initialize_background() " <<
571                     "background number: " << bkg_num << std::endl;
572         }
573     }
574   /* initialize and draw the tiles background */
575   tiles_ground->setup (bkg_num);
576   /* short info messages displayed */
577   info_messages->initialize ();
578   /* draw shadows of ejectors */
579   ejectors_corners->draw_shadow ();
580   /* save background under small bricks */
581   sides_bricks->save_background ();
582   /* draw shadows of small bricks */
583   sides_bricks->draw_shadows_to_brackground ();
584   /* draw small bricks of the three walls */
585   sides_bricks->draw_to_brackground ();
586   ejectors_corners->draw ();
587   /* initialize the bricks level */
588   bricks->first_init ();
589   bricks->initialize ();
590   if (is_verbose)
591     {
592       std::cout << "/supervisor_bricks_level::initialize_background() start! "
593                 << std::endl;
594     }
595 }
596 
597 /**
598  * Draw the tiles background
599  */
600 void
draw_tilesmap()601 supervisor_bricks_level::draw_tilesmap ()
602 {
603   if (has_background)
604     {
605       return;
606     }
607   display->unlock_surfaces ();
608   tiles_ground->draw ();
609   info_messages->run ();
610   display->lock_surfaces ();
611 }
612