1 /**
2  * @file supervisor_main_menu.cc
3  * @brief TecnoballZ's main menu 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_main_menu.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_main_menu.h"
29 #include "../include/handler_resources.h"
30 #include "../include/handler_players.h"
31 #include "../include/controller_guardians.h"
32 
33 /**
34  * Create the main menu supervisor
35  */
supervisor_main_menu()36 supervisor_main_menu::supervisor_main_menu ()
37 {
38   initialize ();
39   /* vertical background scrolling */
40   tiles_map = new tilesmap_scrolling ();
41   /* big TecnoballZ logo */
42   tecnoballz_logo = new sprite_object ();
43   font_scrolling = new controller_font_menu ();
44   text_menu = new sprite_display_menu ();
45   mouse_pointer = new sprite_mouse_pointer ();
46   tecnoballz_logo_angle = 0;
47 }
48 
49 /**
50  * Release the main menu supervisor
51  */
~supervisor_main_menu()52 supervisor_main_menu::~supervisor_main_menu ()
53 {
54   delete mouse_pointer;
55   delete text_menu;
56   delete font_scrolling;
57   delete tecnoballz_logo;
58   delete tiles_map;
59   release ();
60 }
61 
62 /**
63  * Perform some initializations
64  */
65 void
first_init()66 supervisor_main_menu::first_init ()
67 {
68   if (is_verbose)
69     {
70       std::cout << "supervisor_main_menu::first_init() Begin!" << std::endl;
71     }
72   sprites->reset ();
73 #ifndef SOUNDISOFF
74   audio->play_music (handler_audio::MUSICINTRO);
75 #endif
76 
77   /*
78    * create sprites data
79    */
80   resources->load_sprites_bitmap ();
81   tecnoballz_logo->create_sprite (sprite_object::TECNOBALLZ_LOGO,
82                                   sprites_bitmap, 1);
83   sprites->add (tecnoballz_logo);
84   tecnoballz_logo->enable ();
85   tecnoballz_logo->set_coordinates (64 * resolution, 13 * resolution);
86   font_scrolling->create_fontes_list ();
87   mouse_pointer->create_pointer_sprite (sprites_bitmap);
88   resources->release_sprites_bitmap ();
89   tiles_map->initialize (tilesmap_scrolling::TILES_COLOR_MENU,
90                          tilesmap_scrolling::MAP_MENU);
91 
92   text_menu->first_init ();
93   keyboard->set_grab_input (false);
94   if (is_verbose)
95     {
96       std::cout << "supervisor_main_menu::first_init() End!" << std::endl;
97     }
98 }
99 
100 /**
101  * Main loop of the main menu
102  */
103 Uint32
main_loop()104 supervisor_main_menu::main_loop ()
105 {
106 
107   display->wait_frame ();
108   /* vertical scrolling of the screen background */
109   tiles_map->scroll (-1);
110   display->lock_surfaces ();
111   move_tecnoballz_logo ();
112   /* scroll text of the menu */
113   font_scrolling->move_chars ();
114   mouse_pointer->move ();
115   sprites->draw ();
116 
117   /* check and draw the menu text */
118   switch (text_menu->check_and_display ())
119     {
120     case sprite_display_menu::PROGRAM_EXIT:
121       next_phase = LEAVE_TECNOBALLZ;
122       break;
123     case sprite_display_menu::START_GAME:
124       next_phase = start_new_game ();
125       break;
126     }
127 
128   text_menu->draw_copy_from_bitmap ();
129   if (keyboard->command_is_pressed (handler_keyboard::QUIT_TECNOBALLZ))
130     {
131       next_phase = LEAVE_TECNOBALLZ;
132     }
133   display->unlock_surfaces ();
134 
135   /* copy whole game surface into screen surface */
136   display->window_update ();
137 
138   /* [F5] key jump to map editor */
139 #ifdef UNDER_DEVELOPMENT
140   if (keyboard->key_is_pressed (SDLK_F5))
141     {
142       next_phase = MAP_EDITOR;
143     }
144 #endif
145   return next_phase;
146 }
147 
148 /**
149  * Move the logo of TecnoballZ sprite
150  */
151 void
move_tecnoballz_logo()152 supervisor_main_menu::move_tecnoballz_logo ()
153 {
154   tecnoballz_logo_angle = (tecnoballz_logo_angle + 6) & SINUS_MASK;
155   /* convert unsigned to signed */
156   Sint32 res = (Sint32) resolution;
157   Uint32 a = tecnoballz_logo_angle;
158   tecnoballz_logo->set_x_coord (((table_sinL[a] * 20 * res) >> SINUS_DECA) +
159                                 32 * res);
160   if (!birth_flag)
161     {
162       return;
163     }
164   a = (a * 4) & SINUS_MASK;
165   tecnoballz_logo->set_y_coord (((table_sinL[a] * 5 * res) >> SINUS_DECA) +
166                                 7 * res);
167 }
168 
169 /**
170  * Start new TecnoballZ game
171  */
start_new_game()172 Sint32 supervisor_main_menu::start_new_game ()
173 {
174   is_enabled_cheat_mode = false;
175 #ifdef UNDER_DEVELOPMENT
176   is_enabled_cheat_mode = true;
177 #endif
178 
179   /*
180    * check area password validity
181    */
182   Uint32
183   area_num;
184   Uint32
185   level_num;
186   Uint32
187   grdPt;
188   Uint32
189   area_count = check_area_code ();
190   if (area_count == 0)
191     {
192       area_num = 1;
193       level_num = 1;
194       grdPt = 0;
195     }
196   else
197     {
198       if (area_count == 6)
199         {
200           area_num = 5;
201           level_num = 13;
202         }
203       else
204         {
205           area_num = area_count;
206           level_num = 12;
207         }
208       if (is_verbose)
209         {
210           std::cout << "*supervisor_main_menu::start_new_game() " <<
211                     "password is valid! Password: " << &current_area_code[0] <<
212                     "; area number:" << area_num << "; level number:" << level_num <<
213                     "; difficulty level_num: " << difficulty_level << std::endl;
214 
215         }
216       grdPt = controller_guardians::level2gdpt (area_num, level_num);
217     }
218 
219   /* initialize and enable the player(s) */
220   Sint32
221   iplay;
222   for (iplay = 0; iplay < number_of_players; iplay++)
223     {
224       Uint32
225       nlife = initial_num_of_lifes;
226       handler_players *
227       player = handler_players::players_list[iplay];
228       if (birth_flag)
229         {
230           nlife = nlife + 10;
231         }
232       if (strcmp (player->get_name (), "ETB   ") == 0)
233         {
234           nlife += 5;
235         }
236       if (strcmp (player->get_name (), "DJI   ") == 0)
237         {
238           nlife += 4;
239         }
240       if (strcmp (player->get_name (), "JMM   ") == 0)
241         {
242           nlife += 3;
243         }
244       if (strcmp (player->get_name (), "ZBB   ") == 0)
245         {
246           nlife += 2;
247         }
248       if (strcmp (player->get_name (), "REG   ") == 0)
249         {
250           nlife += 1;
251         }
252       player->initialize (nlife, area_num, level_num, 600, grdPt);
253     }
254 
255 
256   /* disable other player(s) */
257   for (Uint32 i = iplay; i < handler_players::MAX_OF_PLAYERS; i++)
258     {
259       handler_players::players_list[i]->initialize (0, 1, 1, 0, 0);
260     }
261   current_player = handler_players::players_list[0];
262 
263   Uint32
264   next = current_player->get_next_phase ();
265   if (next == SHOP)
266     {
267       next = BRICKS_LEVEL;
268     }
269   return next;
270 }
271 
272 /**
273  * Check area area code validity
274  * @return if the code is valid return the area number from 1 to 5
275  *         or 6 for the very last guardian of the area 5.
276  *         Return 0 if the code is not valid
277  */
check_area_code()278 Uint32 supervisor_main_menu::check_area_code ()
279 {
280   Uint32 area_max = 4;
281   Uint32 index = 0;
282 #ifdef UNDER_DEVELOPMENT
283   /* The number of zones really goes from 1 to 5.
284    * The value 6 makes it possible to jump directly to the
285    * very last guardian of the area 5 */
286   area_max = 6;
287 #else
288   if (birth_flag)
289     {
290       area_max = 6;
291     }
292 #endif
293   for (Uint32 area_count = 1; area_count <= area_max; area_count++)
294     {
295       for (Uint32 difficulty_count = 1; difficulty_count <= 4;
296            difficulty_count++)
297         {
298           bool
299           is_valid = true;
300           for (Uint32 i = 0; i < 10; i++)
301             {
302               if (current_area_code[i] != area_codes[index + i])
303                 {
304                   is_valid = false;
305                   break;
306                 }
307             }
308           index += 10;
309           if (is_valid)
310             {
311               difficulty_level = difficulty_count;
312               return area_count;
313             }
314         }
315     }
316   return 0;
317 }
318 
319 /**
320  * Static method which return a area code
321  * @param area_num area number from 2 to 5
322  * @param difficulty 0 to 3
323  * @return the area code
324  */
325 const char *
get_area_code(Uint32 area_num,Uint32 difficulty)326 supervisor_main_menu::get_area_code (Uint32 area_num, Uint32 difficulty)
327 {
328   if (area_num < 2)
329     {
330       return NULL;
331     }
332   return &area_codes[(area_num - 2) * 40 + (difficulty - 1) * 10];
333 }
334 
335 /**
336 * Static method which return the current area code
337 * @return the current area code
338 */
339 char *
get_current_area_code()340 supervisor_main_menu::get_current_area_code ()
341 {
342   return current_area_code;
343 }
344 
345 /**
346  * Static method which copy current area code
347  * @param destination destination string
348  */
349 void
copy_current_area_code(char * destination)350 supervisor_main_menu::copy_current_area_code (char *destination)
351 {
352   for (Uint32 i = 0; i < AREA_CODE_LENGTH; i++)
353     {
354       destination[i] = current_area_code[i];
355     }
356 }
357 
358 /** All areas code for every areas and every difficulty levels */
359 const char
360 supervisor_main_menu::area_codes[241] =
361 {
362   /* level 12 area 1 */
363   "LARRYHEARD" "SAUNDERSON" "JUANATKINS" "STEPHENSON"
364   /* level 12 area 2 */
365   "DANCEFLOOR" "REVOLUTION" "LOOKTOSEXY" "REACHINGUP"
366   /* level 12 area 3 */
367   "ZULUNATION" "HOUSEPIMPS" "ANDRONICUS" "DEFINITIVE"
368   /* level 12 area 4 */
369   "DANCEMANIA" "PEPPERMINT" "SOLARTRIBE" "PROJECTXYZ"
370   /* level 12 area 5 (with cheat code enabled) */
371   "RINGOFFIRE" "POINTBLANK" "TEMPTATION" "BLUEMONDAY"
372   /* level 13 area 5 (with cheat code enabled) */
373   "SHELLSHOCK" "HOUSEMUSIC" "DAVECLARKE" "CYBERACTIF"
374 };
375 
376 /** Current input area code used to jump directly to the
377  * end of a area */
378 char
379 supervisor_main_menu::current_area_code[AREA_CODE_LENGTH + 1] =
380   "          ";
381