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