1 /**
2  * @file tecnoballz.cc
3  * @brief Base of all classes, and main static methods of the game
4  * @created 2002-08-18
5  * @date 2014-08-16
6  * @copyright 1991-2014 TLK Games
7  * @author Bruno Ethvignot
8  * @version $Revision: 23 $
9  */
10 /*
11  * copyright (c) 1991-2014 TLK Games all rights reserved
12  * $Id: tecnoballz.cc 23 2014-08-16 20:13:07Z 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/tecnoballz.h"
30 #include "../include/handler_display.h"
31 #include "../include/handler_keyboard.h"
32 #include "../include/list_sprites.h"
33 #include "../include/handler_players.h"
34 #include "../include/supervisor_bricks_level.h"
35 #include "../include/supervisor_shop.h"
36 #include "../include/supervisor_guards_level.h"
37 #include "../include/supervisor_main_menu.h"
38 #include "../include/bitmap_data.h"
39 #include "../include/handler_audio.h"
40 #include "../include/handler_levels.h"
41 #include "../include/handler_resources.h"
42 #include "../include/handler_high_score.h"
43 #include "../include/supervisor_map_editor.h"
44 
45 
46 /**
47  * Once initialization, create persistent objects
48  */
49 void
first_init(configfile * pConf)50 tecnoballz::first_init (configfile * pConf)
51 {
52   config_file = pConf;
53   if (is_verbose)
54     {
55       std::cout << ">tecnoballz::first_init() start!" << std::endl;
56       std::cout << " has_background:" << has_background << std::endl;
57     }
58 #if __WORDSIZE == 64
59   random_counter = (long) first_init;
60 #else
61   random_counter = (intptr_t) first_init;
62 #endif
63   resources = handler_resources::get_instance ();
64   high_score = handler_high_score::get_instance ();
65   resources->load_sinus ();
66   display = new handler_display ();
67   display->initialize ();
68 #ifndef SOUNDISOFF
69   audio = handler_audio::get_instance ();
70 #endif
71   keyboard = handler_keyboard::get_instance ();
72   sprites = new list_sprites ();
73   sprites->init (400);
74   ptLev_data = new handler_levels ();
75   current_player =
76     handler_players::create_all_players (handler_players::MAX_OF_PLAYERS);
77   sprite_ball::init_collisions_points ();
78 
79   /* retrieve player names */
80   for (Uint32 i = 0; i < handler_players::MAX_OF_PLAYERS; i++)
81     {
82       handler_players::players_list[i]->set_name (pConf->get_player_name (i));
83     }
84   current_phase = MAIN_MENU;
85 
86   if (arg_jumper > 0)
87     {
88 #ifdef UNDER_DEVELOPMENT
89       is_enabled_cheat_mode = true;
90 #endif
91       current_phase = arg_jumper;
92     }
93   if (is_verbose)
94     {
95       std::cout << ">tecnoballz::first_init() end!" << std::endl;
96     }
97 }
98 
99 /**
100  * main loop of the game
101  */
102 void
game_begin()103 tecnoballz::game_begin ()
104 {
105   supervisor *stage = NULL;
106   do
107     {
108       if (is_verbose)
109         {
110           std::cout << ">tecnoballz::game_begin() phase:" << current_phase
111                     << std::endl;
112         }
113       switch (current_phase)
114         {
115         case LEAVE_TECNOBALLZ:
116           is_exit_game = true;
117           break;
118         case BRICKS_LEVEL:
119           stage = new supervisor_bricks_level ();
120           break;
121         case SHOP:
122           stage = new supervisor_shop ();
123           break;
124         case GUARDS_LEVEL:
125           stage = new supervisor_guards_level ();
126           break;
127         case MAIN_MENU:
128           stage = new supervisor_main_menu ();
129           break;
130         case MAP_EDITOR:
131           stage = new supervisor_map_editor ();
132           break;
133         default:
134           std::cerr << "(!)tecnoballz::game_begin() phase number " <<
135                     current_phase << "is invalid!" << std::endl;
136           throw std::runtime_error ("(!)tecnoballz::game_begin() "
137                                     "invalid phase number!");
138         }
139       if (NULL != stage)
140         {
141           stage->first_init ();
142           Uint32 next = 0;
143           do
144             {
145               next = stage->main_loop ();
146             }
147           while (!next);
148           current_phase = next;
149           delete stage;
150           stage = NULL;
151         }
152     }
153   while (!is_exit_game);
154 }
155 
156 /**
157  * Game exit, relase all objects
158  */
159 void
release_all_objects(configfile * pConf)160 tecnoballz::release_all_objects (configfile * pConf)
161 {
162   /* save player names into config file */
163   for (Uint32 i = 0; i < handler_players::MAX_OF_PLAYERS; i++)
164     {
165       pConf->set_player_name (i,
166                               handler_players::players_list[i]->get_name ());
167     }
168   if (is_verbose)
169     {
170       std::cout << "(X) 1. release all player objects " << std::endl;
171     }
172   handler_players::release_all_players ();
173   if (is_verbose)
174     {
175       std::cout << "(x) 2. delete 'handler_levels' singleton" << std::endl;
176     }
177   delete ptLev_data;
178   if (is_verbose)
179     {
180       std::cout << "(x) 3. delete 'list_sprites' singleton" << std::endl;
181     }
182   delete sprites;
183 
184   if (is_verbose)
185     {
186       std::cout << "(x) 4. delete 'hanbdler_keyboard' singleton" << std::endl;
187     }
188   delete keyboard;
189 
190   if (is_verbose)
191     {
192       std::
193       cout << "(x) 5. delete 'handler_high_score' singleton" << std::endl;
194     }
195   delete high_score;
196 
197 #ifndef SOUNDISOFF
198   if (is_verbose)
199     {
200       std::cout << "(x) 7. delete 'handler_audio' singleton" << std::endl;
201     }
202   delete audio;
203 #endif
204 
205   if (is_verbose)
206     {
207       std::cout << "(x) 6. delete 'handler_display' singleton" << std::endl;
208     }
209   delete display;
210 
211   if (is_verbose)
212     {
213       std::cout << "(x) 8. delete 'handler_resources'" << std::endl;
214     }
215   delete resources;
216 }
217 
218 /**
219  * Create the object
220  */
tecnoballz()221 tecnoballz::tecnoballz ()
222 {
223 }
224 
225 /**
226  * Release object
227  */
~tecnoballz()228 tecnoballz::~tecnoballz ()
229 {
230 }
231 
232 /**
233  * Initialize some members
234  */
235 void
object_init()236 tecnoballz::object_init ()
237 {
238   object_num = objects_counter;
239   objects_counter++;
240 }
241 
242 /**
243  * Object destroyed
244  */
245 void
object_free()246 tecnoballz::object_free ()
247 {
248   objects_counter--;
249 }
250 
251 /**
252  * Creates a string representing an integer number
253  * @param value the integer value to be converted
254  * @param padding length of the string
255  * @param str the string representation of the number
256  */
257 void
integer_to_ascii(Sint32 value,Uint32 padding,char * str)258 tecnoballz::integer_to_ascii (Sint32 value, Uint32 padding, char *str)
259 {
260   char *ptr = str + padding - 1;
261   bool neg = (value < 0);
262   if (neg)
263     {
264       value = -value;
265       --padding;
266     }
267   do
268     {
269       *ptr-- = (value % 10) + '0';
270       value /= 10;
271       --padding;
272     }
273   while (value && padding > 0);
274   for (; padding > 0; --padding)
275     {
276       *ptr-- = '0';
277     }
278   if (neg)
279     {
280       *ptr-- = '-';
281     }
282 }
283 
284 //------------------------------------------------------------------------------
285 // convert integer into ASCII string
286 // input => value:      number to convert
287 //       => strng:      pointer to ASCII string (finished by  zero)
288 //       => reste:      maximum length (1 = 2 chars, 2 = 3 chars, ...)
289 //------------------------------------------------------------------------------
290 /*
291 void
292 tecnoballz::intToASCII (Sint32 value, char *strng, Uint32 reste)
293 {
294   Uint32 index = 0;
295   Uint32 zsize = 1;
296   if (value < 0)
297     {
298       value = -value;
299       *(strng++) = '-';
300       if (reste > 0)
301         reste--;
302     }
303   for (index = 0; index < reste; index++)
304     zsize = zsize * 10;
305   index = 0;
306   while (zsize > 0)
307     {
308       Uint32 reste = value / zsize;
309       char zchar = (char) ('0' + reste);
310       if (zchar > '9' || zchar < '0')
311         zchar = '?';
312       strng[index++] = zchar;
313       value = value - (zsize * reste);
314       zsize = zsize / 10;
315     }
316 }
317 */
318 
319 void
int_to_big_endian(Uint32 * ptsrc,Uint32 * ptdes)320 tecnoballz::int_to_big_endian (Uint32 * ptsrc, Uint32 * ptdes)
321 {
322 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
323   *ptdes = *ptsrc;
324 #else
325   char *s = (char *) ptsrc;
326   char *d = (char *) ptdes;
327   d[0] = s[3];
328   d[1] = s[2];
329   d[2] = s[1];
330   d[3] = s[0];
331 #endif
332 }
333 
334 void
big_endian_to_int(Uint32 * ptsrc,Uint32 * ptdes)335 tecnoballz::big_endian_to_int (Uint32 * ptsrc, Uint32 * ptdes)
336 {
337 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
338   *ptdes = *ptsrc;
339 #else
340   char *s = (char *) ptsrc;
341   char *d = (char *) ptdes;
342   d[3] = s[0];
343   d[2] = s[1];
344   d[1] = s[2];
345   d[0] = s[3];
346 #endif
347 }
348 
349 
350 Sint32 tecnoballz::arg_jumper = -1;
351 bool tecnoballz::force_4_colors_tiles = false;
352 bool tecnoballz::is_verbose = false;
353 Uint32 tecnoballz::objects_counter = 0;
354 Sint32 tecnoballz::random_counter = 0;
355 Uint32 tecnoballz::frame_counter = 0;
356 handler_high_score *
357 tecnoballz::high_score = NULL;
358 handler_resources *
359 tecnoballz::resources = NULL;
360 handler_levels *
361 tecnoballz::ptLev_data = NULL;
362 #ifndef SOUNDISOFF
363 handler_audio *
364 tecnoballz::audio = NULL;
365 #endif
366 handler_display *
367 tecnoballz::display = NULL;
368 handler_keyboard *
369 tecnoballz::keyboard = NULL;
370 list_sprites *
371 tecnoballz::sprites = NULL;
372 handler_players *
373 tecnoballz::current_player = NULL;
374 Sint16 *
375 tecnoballz::table_cosL = NULL;
376 Sint16 *
377 tecnoballz::table_sinL = NULL;
378 
379 Uint32 tecnoballz::current_phase = BRICKS_LEVEL;
380 bool tecnoballz::is_exit_game = false;
381 bitmap_data *
382 tecnoballz::sprites_bitmap = NULL;
383 bool tecnoballz::is_enabled_cheat_mode = false;
384 bool tecnoballz::birth_flag = 0;
385 Sint32 tecnoballz::difficulty_level = DIFFICULTY_EASY;
386 Sint32 tecnoballz::initial_num_of_lifes = 8;
387 Sint32 tecnoballz::number_of_players = 1;
388 const char
389 tecnoballz::nomprefix[] = PREFIX;
390 Uint32 tecnoballz::resolution = 2;
391 bool tecnoballz::has_background = false;
392 bool tecnoballz::absolute_mouse_positioning = false;
393 offscreen_surface *
394 tecnoballz::game_screen = NULL;
395 offscreen_surface *
396 tecnoballz::background_screen = NULL;
397 configfile *
398 tecnoballz::config_file;
399