1 /**
2  * @file supervisor_shop.cc
3  * @brief Shop supervisor
4  * @date 2012-08-19
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_shop.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_shop.h"
29 #include "../include/handler_resources.h"
30 #include "../include/supervisor_main_menu.h"
31 #include "../include/sprite_display_menu.h"
32 
33 /**
34  * Create the shop supervisor
35  */
supervisor_shop()36 supervisor_shop::supervisor_shop ()
37 {
38   initialize ();
39   menu_events = new handler_menu_events();
40   tiles_ground = tiles_background::get_instance ();
41   mouse_pointer = new sprite_mouse_pointer ();
42   led_indicator = new sprite_object ();
43   power_up_capsules = controller_capsules::get_instance ();
44   display_text = new display_text_bitmap ();
45   popup_menu = new handler_popup_menu ();
46   current_selected_option = 0;
47   some_infos_index = INFO_PADDLES;
48   is_already_view_info = false;
49   current_price = 0;
50   num_of_bought_capsules = 0;
51   led_indicator_xcoord = 0;
52   led_indicator_ycoord = 0;
53   is_caspule_drag = false;
54   blink_capsule = (sprite_capsule *) NULL;
55 
56   options_frame_xmin = 6 * resolution;
57   options_frame_xmax1 = 283 * resolution;
58   options_frame_xmax2 = 51 * resolution;
59   options_frame_ymax1 = 173 * resolution;
60   options_frame_ymax2 = 218 * resolution;
61 
62   selected_capsule_index = -1;
63   is_drawn_select_cursor = false;
64   capsules_frame_ymin = 3 * resolution;
65   capsules_frame_ymax = 171 * resolution + capsules_frame_ymin;
66   select_cursor_xcoord = 292 * resolution;
67   select_cursor_ycoord = 0;
68   select_cursor_width = 21 * resolution;
69   select_cursor_height = 9 * resolution;
70   select_cursor_color = 0;
71   select_cursor_sin_index = 0;
72   /* last key pressed */
73   previous_key_code_down = 0;
74   /* if cheat_code_input == cheat_code then is_enabled_cheat_mode = 1 */
75   cheat_code_input = 0;
76   cheat_code = SDLK_e << 24 | SDLK_t << 16 | SDLK_b << 8 | SDLK_RETURN;
77   box_texts = NULL;
78 }
79 
80 /**
81  * Release the shop supervisor
82  */
~supervisor_shop()83 supervisor_shop::~supervisor_shop ()
84 {
85   delete popup_menu;
86   delete display_text;
87   delete power_up_capsules;
88   if (NULL != led_indicator)
89     {
90       delete led_indicator;
91       led_indicator = (sprite_object *) NULL;
92     }
93   if (NULL != box_texts)
94     {
95       delete[](char *) box_texts;
96       box_texts = NULL;
97     }
98   delete mouse_pointer;
99   delete tiles_ground;
100   delete menu_events;
101   release ();
102 }
103 
104 /**
105  * Initialize the shop supervisor
106  */
107 void
first_init()108 supervisor_shop::first_init ()
109 {
110 
111   box_texts =
112     resources->load_texts (handler_resources::TEXTS_SHOP, 0,
113                            BOX_LENGTH_STRING, 3);
114   //for (Uint32 i = 0; i < 36; i++)
115   //  {
116   //    printf ("%02d): %s \n", i, box_texts[i]);
117   //  }
118 
119 
120   Uint32 area_num = current_player->get_area_number ();
121   Uint32 level_num = current_player->get_level_number ();
122 #ifndef SOUNDISOFF
123   audio->play_level_music (area_num, level_num);
124   audio->play_shop_music (area_num);
125 #endif
126   sprites->reset ();
127 
128   /* copy name player into menu text */
129   display_text->print_to_string (current_player->get_name (),
130                                  box_texts[TEXT_WELCOME]);
131   //char * dest;
132   //dest = current_player->get_name ();
133   display_text->print_int_to_string (current_player->get_num_of_lifes (),
134                                      2, box_texts[TEXT_LIVES_LEFT]);
135   display_text->print_int_to_string (MAX_OF_CAPSULES_BOUGHT, 2,
136                                      box_texts[TEXT_CANNOT_BUY_MORE]);
137 
138   /* copy area code */
139   if (area_num > 1)
140     {
141       char * code = (char *)
142                     supervisor_main_menu::get_area_code (area_num, difficulty_level);
143       display_text->print_to_string (code,
144                                      box_texts[TEXT_AREA_CODE],
145                                      supervisor_main_menu::AREA_CODE_LENGTH);
146     }
147 
148 
149   /*
150    dest = &info_text1[6 * BOX_LENGTH_STRING];
151    for (Uint32 i = 0; i < (BOX_LENGTH_STRING * 2); i++)
152      {
153        dest[i] = source[i];
154      }
155 
156 
157    source = &sprite_display_menu::difficulte[(difficulty_level - 1) * 4];
158    dest = &info_text1[8 * BOX_LENGTH_STRING + 16];
159    for (Sint32 i = 0; i < 4; i++)
160      {
161        dest[i] = source[i];
162      }
163      */
164 
165   resources->load_sprites_bitmap ();
166 
167   /* initialize the led indicator */
168   if (resolution == 1)
169     {
170       led_indicator->create_sprite (sprite_object::SHOP_LED_INDICATOR_320,
171                                     sprites_bitmap, false);
172     }
173   else
174     {
175       led_indicator->create_sprite (sprite_object::SHOP_LED_INDICATOR_640,
176                                     sprites_bitmap, false);
177     }
178   sprites->add (led_indicator);
179   led_indicator->enable ();
180 
181   /* initialize the power-up capsules  */
182   power_up_capsules->create_shop_sprites_list ();
183   current_player->clear_shopping_cart ();
184   Sint32 * tp = temporary_shopping_cart;
185   for (Uint32 i = 0; i < MAX_OF_CAPSULES_BOUGHT; i++)
186     {
187       *(tp++) = 0;
188     }
189   sprite_capsule **capsules = power_up_capsules->get_sprites_list ();
190   drag_sprite = capsules[(MAX_OF_CAPSULES_BOUGHT + 2) - 1 - 1];
191 
192   /* initialize the mouse pointer */
193   mouse_pointer->create_pointer_sprite (sprites_bitmap);
194 
195   /* intialize the "escape menu" */
196   popup_menu->first_init (sprites_bitmap);
197   resources->release_sprites_bitmap ();
198   display_text->initialize ();
199 
200   /* load bitmap background of the shop */
201   bitmap_data *
202   bmp = new bitmap_data ();
203   bmp->load (handler_resources::BITMAP_SHOP);
204   background_screen->blit_surface (bmp, 0, 0, 0, 0, bmp->get_width (),
205                                    bmp->get_height ());
206   delete bmp;
207   background_screen->blit_to_surface (game_screen);
208 
209 
210   put_current_text (box_texts[TEXT_WELCOME]);
211   if (!current_player->is_budget_prices ())
212     {
213       char *str = box_texts[TEXT_WELCOME] + BOX_LENGTH_STRING * 2;
214       for (Uint32 i = 0; i < BOX_LENGTH_STRING; i++)
215         {
216           str[i] = ' ';
217         }
218     }
219 
220   keyboard->set_grab_input (false);
221   tiles_ground->set_4_color_palette ();
222 
223 
224   menu_events->begin(
225     48 * resolution,
226     44 * resolution,
227     0,
228     0,
229     5,
230     3,
231     options_frame_xmin,
232     0
233   );
234 
235 }
236 
237 /**
238  * The main loop of the shop
239  */
240 Uint32
main_loop()241 supervisor_shop::main_loop ()
242 {
243   display->wait_frame ();
244 
245   /* copy the background offscreen to the game offscreen */
246   background_screen->blit_to_surface (game_screen, 290 * resolution,
247                                       3 * resolution, 26 * resolution,
248                                       180 * resolution);
249 
250 
251   /* display the 3 lines of text  */
252   display_box_text ();
253   /* display current price and credit */
254   display_text->draw (game_screen, 263 * resolution, 227 * resolution,
255                       current_price, 6);
256   display_text->draw (game_screen, 263 * resolution, 183 * resolution,
257                       current_player->get_money_amount (), 6);
258 
259   display->lock_surfaces ();
260   next_phase = 0;
261   sprites->clear ();
262 
263   if (!popup_menu->is_enable ())
264     {
265       set_select_cursor_coordinates ();
266       Sint32 x = mouse_pointer->get_x_coord ();
267       Sint32 y = mouse_pointer->get_y_coord ();
268       if (!is_caspule_drag)
269         {
270           Sint32 x2, y2;
271           bool is_left_up = keyboard->is_left_button_up (&x2, &y2);
272           is_left_up |= menu_events->check();
273           if (is_left_up)
274             {
275               Sint32 option = get_option_over_mouse_cursor (x, y);
276               if (option == current_selected_option)
277                 {
278                   Sint32 option_id = available_options_id[option];
279                   purchase_option_or_capsule (option_id);
280                 }
281             }
282           else
283             {
284               if (!keyboard->is_left_button ())
285                 {
286                   current_selected_option =
287                     get_option_over_mouse_cursor (x, y);
288                   current_price =
289                     get_price_and_update_led (current_selected_option);
290                 }
291             }
292 
293         }
294       else
295         {
296           current_price = get_price_and_update_led (-1);
297         }
298       capsule_drag_and_drop ();
299     }
300 
301   mouse_pointer->move ();
302   if (is_enabled_cheat_mode)
303     {
304       power_up_capsules->play_animation_in_shop (2);
305     }
306   else
307     {
308       power_up_capsules->play_animation_in_shop (1);
309     }
310 
311   /* display the cursor of the bonus selected in the list on the right */
312   draw_select_cursor ();
313   sprites->draw ();
314   display_capsules_bought ();
315   Sint32 popup_event = popup_menu->run ();
316 
317   /* copy whole game surface into screen surface */
318   display->unlock_surfaces ();
319   display->window_update ();
320 
321   /* escape key to quit the game! */
322   if (keyboard->command_is_pressed (handler_keyboard::QUIT_TECNOBALLZ) ||
323       popup_event == handler_popup_menu::QUIT_TECNOBALLZ)
324     {
325       next_phase = LEAVE_TECNOBALLZ;
326     }
327   if (keyboard->command_is_pressed (handler_keyboard::QUIT_TO_MAIN_MENU) ||
328       popup_event == handler_popup_menu::QUIT_TO_MAIN_MENU)
329     {
330       next_phase = MAIN_MENU;
331     }
332 
333   check_if_enable_cheat ();
334   return next_phase;
335 }
336 
337 /**
338  * Display list bonus capsule(s) bought in the shop,
339  * on the right of the screen
340  */
341 void
display_capsules_bought()342 supervisor_shop::display_capsules_bought ()
343 {
344   Sint32 *cart = current_player->get_shopping_cart ();
345   sprite_capsule **capsules = power_up_capsules->get_sprites_list ();
346   Sint32 pos_y = 4 * resolution;
347   for (Uint32 i = 0; i < MAX_OF_CAPSULES_BOUGHT; i++)
348     {
349       sprite_capsule *capsule = *(capsules++);
350       capsule->set_coordinates (294 * resolution, pos_y);
351       pos_y = pos_y + 9 * resolution;
352       Sint32 id = *(cart++);
353       capsule->set_in_shop (id);
354     }
355 }
356 
357 /**
358  * Return selected bonus, and calculate position of LED indicator
359  * @input x X-coordinate of the mouse pointer
360  * @input y Y-coordinate of the mouse pointer
361  * @return index of the selected bonus from 0 to 24
362  *         or otherwise -1 if no bonus is selected
363  * */
364 Sint32
get_option_over_mouse_cursor(Sint32 x,Sint32 y)365 supervisor_shop::get_option_over_mouse_cursor (Sint32 x, Sint32 y)
366 {
367   if (x < options_frame_xmin || x > options_frame_xmax1 || y > options_frame_ymax2 ||
368       (x > options_frame_xmax2 && y > options_frame_ymax1))
369     {
370       return -1;
371     }
372   else
373     {
374       x = (x - (6 * resolution)) / (48 * resolution);
375       y = (y / (44 * resolution));
376       if (y > 4)
377         {
378           x = 0;
379         }
380       Sint32 i = x + 6 * y;
381       led_indicator_xcoord = (x * (48 * resolution)) + (17 * resolution);
382       if (resolution == 1)
383         {
384           led_indicator_ycoord = (y * (44 * resolution)) + (36 * resolution);
385         }
386       else
387         {
388           led_indicator_ycoord = (y * (44 * resolution)) + (35 * resolution);
389         }
390       return i;
391     }
392 }
393 
394 /**
395  * Update LED indicator state, and return the price of
396  * the current option
397  * @param index Index on the selected option from 0 to 24,
398  *              otherwise -1 if not option selected
399  * @return The price of the selected option
400 */
401 Uint32
get_price_and_update_led(Sint32 index)402 supervisor_shop::get_price_and_update_led (Sint32 index)
403 {
404   if (index < 0)
405     {
406       led_indicator->disable ();
407       power_up_capsules->set_overview_capsule (0);
408       return 0;
409     }
410 
411   /* set capsule overview */
412   power_up_capsules->set_overview_capsule (available_options_id[index]);
413 
414   /* set LED indicator */
415   led_indicator->enable ();
416   led_indicator->set_coordinates (led_indicator_xcoord, led_indicator_ycoord);
417 
418   Sint32 price;
419   /* info already seen at least once? */
420   if (index == 10 && is_already_view_info)
421     {
422       price = 0;
423     }
424   else if (current_player->is_budget_prices ())
425     {
426       price = 1;
427     }
428   else
429     {
430       price = options_prices[index];
431     }
432   return price;
433 }
434 
435 /**
436  * Bought a bonus capsule or an option
437  * @param option_id Option identifier
438  */
439 void
purchase_option_or_capsule(Uint32 option_id)440 supervisor_shop::purchase_option_or_capsule (Uint32 option_id)
441 {
442   if (option_id != sprite_capsule::SOME_INFOS)
443     {
444       some_infos_index = INFO_PADDLES;
445     }
446 
447   switch (option_id)
448     {
449     case sprite_capsule::EXPAND_PADDLE:
450       purchase_bonus_capsule (option_id);
451       break;
452 
453     case sprite_capsule::FIRE_POWER_1:
454       purchase_bonus_capsule (option_id);
455       break;
456 
457     case sprite_capsule::FIRE_POWER_2:
458       purchase_bonus_capsule (option_id);
459       break;
460 
461     case sprite_capsule::EXTRA_BALLS:
462       purchase_bonus_capsule (option_id);
463       break;
464 
465     case sprite_capsule::MULTI_BALLS:
466       purchase_bonus_capsule (option_id);
467       break;
468 
469     case sprite_capsule::POWER_BALL_1:
470       purchase_bonus_capsule (option_id);
471       break;
472 
473     case sprite_capsule::POWER_BALL_2:
474       purchase_bonus_capsule (option_id);
475       break;
476 
477     case sprite_capsule::EXTRA_LIFE:
478       purchase_bonus_capsule (option_id);
479       break;
480 
481     case sprite_capsule::BOTTOM_WALL:
482       purchase_bonus_capsule (option_id);
483       break;
484 
485     case sprite_capsule::BALL_SIZE_2:
486       purchase_bonus_capsule (option_id);
487       break;
488 
489     case sprite_capsule::BALL_SIZE_3:
490       purchase_bonus_capsule (option_id);
491       break;
492 
493     case sprite_capsule::ROBOT_PADDLE:
494       purchase_bonus_capsule (option_id);
495       break;
496 
497     case sprite_capsule::BALLS_CONTROL:
498       purchase_bonus_capsule (option_id);
499       break;
500 
501     case sprite_capsule::GLUE:
502       purchase_bonus_capsule (option_id);
503       break;
504 
505     case sprite_capsule::SOME_INFOS:
506       display_info ();
507       break;
508 
509       /* rebuild the wall */
510     case sprite_capsule::REBUILD_THE_WALL:
511       if (current_player->get_area_number () < 5)
512         {
513           put_current_text (box_texts[TEXT_ONLY_FOR_AREA_5]);
514         }
515       else
516         {
517           if (!current_player->is_rebuild_walls ()
518               && decrease_money_amount ())
519             {
520               current_player->set_rebuild_walls (true);
521               display_sales_confirmation (current_selected_option);
522             }
523         }
524       break;
525 
526       /* less bricks option */
527     case sprite_capsule::LESS_BRICKS:
528       if (current_player->get_less_bricks () <= 0
529           && decrease_money_amount ())
530         {
531           current_player->set_less_bricks (10);
532           display_sales_confirmation (current_selected_option);
533         }
534       break;
535 
536       /* exit from the shop */
537     case sprite_capsule::LEAVE_SHOP:
538       current_player->set_budget_prices (false);
539       current_player =
540         handler_players::get_next_player (current_player, &next_phase);
541       break;
542 
543       /* buy a right, up or left paddle */
544     default:
545     {
546       if (option_id >= sprite_capsule::ENABLE_RIGHT_PADDLE
547           && option_id <= sprite_capsule::ENABLE_LEFT_PADDLE)
548         {
549           Sint32 i = (option_id - sprite_capsule::ENABLE_RIGHT_PADDLE) / 2 + 2;
550           if (current_player->get_paddle_alive_counter (i) <= 0
551               && decrease_money_amount ())
552             {
553               current_player->set_paddle_alive_counter (i, 3);
554               display_sales_confirmation (current_selected_option);
555             }
556         }
557     }
558     break;
559     }
560 }
561 
562 /**
563  * Display info message
564  */
565 void
display_info()566 supervisor_shop::display_info ()
567 {
568   if (!is_already_view_info)
569     {
570       if (!decrease_money_amount ())
571         {
572           return;
573         }
574     }
575   is_already_view_info = true;
576 
577   switch (some_infos_index)
578     {
579     case INFO_PADDLES:
580     {
581       Uint32 area_num = current_player->get_area_number ();
582       Uint32 index = TEXT_PADDLE_RIGHT;
583       Uint32 line = 0;
584       char *dest = box_texts[TEXT_PADDLES];
585       char *src;
586       for (Uint32 i = controller_paddles::RIGHT_PADDLE;
587            i <= controller_paddles::LEFT_PADDLE; i++)
588         {
589           src = box_texts[index];
590           if (current_player->get_paddle_alive_counter (i) == 0)
591             {
592               src += BOX_LENGTH_STRING;
593               if ((area_num >= 2 && i == controller_paddles::TOP_PADDLE) ||
594                   (area_num >= 3 && i == controller_paddles::RIGHT_PADDLE)
595                   || (area_num >= 4
596                       && i == controller_paddles::LEFT_PADDLE))
597                 {
598                   src += BOX_LENGTH_STRING;
599                 }
600             }
601           index++;
602           line++;
603           strncpy (dest, src, BOX_LENGTH_STRING);
604           dest += BOX_LENGTH_STRING;
605         }
606     }
607     put_current_text (box_texts[TEXT_PADDLES]);
608     break;
609 
610     case INFO_LIVES:
611       put_current_text (box_texts[TEXT_LIVES_LEFT]);
612       break;
613 
614     case INFO_AREA_CODE:
615       if (current_player->get_area_number () > 1)
616         {
617           put_current_text (box_texts[TEXT_AREA_CODE]);
618         }
619       else
620         {
621           put_current_text (box_texts[TEXT_NO_AREA_CODE]);
622         }
623       break;
624 
625     case INFO_END:
626     default:
627       if (is_enabled_cheat_mode)
628         {
629           put_current_text (box_texts[TEXT_ENABLED_CHEAT_MODE]);
630         }
631       else if (birth_flag)
632         {
633           put_current_text (box_texts[TEXT_WAITING_CHEAT_MODE]);
634         }
635       else
636         {
637           put_current_text (box_texts[TEXT_HOPING_HELP]);
638         }
639       put_current_text (box_texts[TEXT_HOPING_HELP]);
640       break;
641     }
642   if (++some_infos_index > INFO_END)
643     {
644       some_infos_index = INFO_PADDLES;
645     }
646 
647 }
648 
649 /**
650  * Check if a purchase is possible, so decrement the money amount
651  * @return true if the money amount could be descreased
652  */
decrease_money_amount()653 bool supervisor_shop::decrease_money_amount ()
654 {
655   if (current_player->decrease_money_amount (current_price))
656     {
657       return true;
658     }
659   else
660     {
661       put_current_text (box_texts[TEXT_NOT_ENOUGH_MONEY]);
662       return false;
663     }
664 }
665 
666 /**
667  * Purchase a bonus capsule if possible
668  * @param capsule_id Capsule identifier
669  */
670 void
purchase_bonus_capsule(Sint32 capsule_id)671 supervisor_shop::purchase_bonus_capsule (Sint32 capsule_id)
672 {
673   /* maximum number of capsules reached */
674   if (num_of_bought_capsules >= MAX_OF_CAPSULES_BOUGHT)
675     {
676       put_current_text (box_texts[TEXT_CANNOT_BUY_MORE]);
677       return;
678     }
679 
680   /* purchase is possible? */
681   if (!decrease_money_amount ())
682     {
683       return;
684     }
685 
686   Sint32 *cart = current_player->get_shopping_cart ();
687   cart[num_of_bought_capsules] = capsule_id;
688   sprite_capsule **caspules = power_up_capsules->get_sprites_list ();
689   sprite_capsule *capsule = caspules[num_of_bought_capsules++];
690   capsule->set_in_shop (capsule_id);
691   display_sales_confirmation (current_selected_option);
692   current_player->set_numof_items_in_shopping_cart (num_of_bought_capsules);
693 }
694 
695 /**
696  * Display the sales confirmation message
697  * @param option_index Option index
698  */
699 void
display_sales_confirmation(Sint32 option_index)700 supervisor_shop::display_sales_confirmation (Sint32 option_index)
701 {
702   char *text = box_texts[(int)led_index_to_text_index[option_index]];
703   put_current_text (text);
704 }
705 
706 /**
707  * Update the pointers of three lines currently displayed
708  * @param str Pointer to a string containing three lines
709  */
710 void
put_current_text(char * str)711 supervisor_shop::put_current_text (char *str)
712 {
713   current_text_displayed[0] = str;
714   str += BOX_LENGTH_STRING;
715   current_text_displayed[1] = str;
716   str += BOX_LENGTH_STRING;
717   current_text_displayed[2] = str;
718 }
719 
720 /**
721  * Display the three lines of text in the box in bottom
722  */
723 void
display_box_text()724 supervisor_shop::display_box_text ()
725 {
726   Uint32 height = display_text->get_char_height ();
727   Uint32 x_pos = 60 * resolution;
728   Uint32 y_pos = 180 * resolution;
729   Uint32 yspac = height + resolution;
730   game_screen->clear (0, x_pos, y_pos, 22 * 8 * resolution, 3 * yspac);
731   display_text->draw (game_screen, x_pos, y_pos, current_text_displayed[0],
732                       BOX_LENGTH_STRING);
733   display_text->draw (game_screen, x_pos, y_pos + yspac, current_text_displayed[1],
734                       BOX_LENGTH_STRING);
735   display_text->draw (game_screen, x_pos, y_pos + yspac * 2, current_text_displayed[2],
736                       BOX_LENGTH_STRING);
737 }
738 
739 /**
740  * Drag and drop the bonus capsule
741  */
742 void
capsule_drag_and_drop()743 supervisor_shop::capsule_drag_and_drop ()
744 {
745   /* index on 'options_prices' list, if -1 no drag objet  */
746   if (!is_caspule_drag)
747     /* grab an object with the mouse */
748     {
749       drag_sprite->disable ();
750       if (keyboard->is_left_button ()
751           && selected_capsule_index >= 0)
752         {
753           dragged_capsule_pt = current_player->get_shopping_cart ()
754                                + selected_capsule_index;
755           sprite_capsule **capsules =
756             power_up_capsules->get_sprites_list ();
757           blink_capsule = *(capsules + selected_capsule_index);
758           is_caspule_drag = true;
759           drag_sprite->clone_from_capsule (blink_capsule);
760           blink_capsule->is_enabled = true;
761         }
762       return;
763     }
764 
765   /* drag the bonus capsule */
766   if (keyboard->is_left_button ())
767     {
768       drag_sprite->enable ();
769       drag_sprite->set_coordinates (mouse_pointer->get_x_coord (),
770                                     mouse_pointer->get_y_coord ());
771       if (blink_capsule->is_enabled)
772         {
773           blink_capsule->is_enabled = false;
774         }
775       else
776         {
777           blink_capsule->is_enabled = true;
778         }
779       return;
780     }
781 
782 
783   /*
784    * drop a bonus capsule
785    */
786   drag_sprite->disable ();
787   blink_capsule->is_enabled = true;
788   Sint32 i = selected_capsule_index;
789 
790   /* change position of a bonus capsule in the capsules list */
791   if (i >= 0)
792     {
793       if (i >= (Sint32)num_of_bought_capsules)
794         {
795           i = num_of_bought_capsules - 1;
796         }
797       Sint32 *player_cart = current_player->get_shopping_cart ();
798       Sint32 *source = dragged_capsule_pt;
799       Sint32 *dest = player_cart + i;
800       Sint32 *cart = temporary_shopping_cart;
801       Sint32 drop_id = *source;
802       if (source != dest)
803         {
804           Uint32 i = 0;
805           do
806             {
807               if (player_cart == source)
808                 {
809                   player_cart++;
810                   i++;
811                 }
812               else
813                 {
814                   if (player_cart == dest)
815                     {
816                       if (source <= dest)
817                         {
818                           if (i++ < MAX_OF_CAPSULES_BOUGHT)
819                             {
820                               *(cart++) = *(player_cart++);
821                             }
822                         }
823                       if (i++ < MAX_OF_CAPSULES_BOUGHT)
824                         {
825                           *(cart++) = drop_id;
826                         }
827                     }
828                   if (i++ < MAX_OF_CAPSULES_BOUGHT)
829                     {
830                       *(cart++) = *(player_cart++);
831                     }
832                 }
833             }
834           while (i < MAX_OF_CAPSULES_BOUGHT);
835           cart = temporary_shopping_cart;
836           player_cart = current_player->get_shopping_cart ();
837           for (Uint32 i = 0; i < MAX_OF_CAPSULES_BOUGHT; i++)
838             {
839               *(player_cart++) = *(cart++);
840             }
841         }
842     }
843 
844   /* resell a bonus capsule to the shop */
845   else
846     {
847       Sint32 *source = dragged_capsule_pt;
848       Sint32 *dest = source;
849       Sint32 drop_id = *source;
850       *(source++) = 0;
851       while (*source >= 0)
852         {
853           *(dest++) = *source;
854           *(source++) = 0;
855         }
856       num_of_bought_capsules--;
857       current_player->set_numof_items_in_shopping_cart (num_of_bought_capsules);
858       Sint32 price = 0;
859       if (current_player->is_budget_prices ())
860         {
861           /* the player collected a chance capsule containing
862            * a budget prices bonus in the previous bricks level.
863            * All the options are thus for the price of 1 in
864            * the current shop */
865           price = 1;
866         }
867       else
868         {
869           i = 0;
870           while (available_options_id[i] != sprite_capsule::LEAVE_SHOP)
871             {
872               if (available_options_id[i] == drop_id)
873                 {
874                   price = options_prices[i];
875                   break;
876                 }
877               i++;
878             }
879         }
880       current_player->increase_money_amount (price);
881     }
882   is_caspule_drag = false;
883 }
884 
885 /**
886  * Calculate coordinates the
887  * Calculate the coordinates of the cursor which selects a capsule in the list
888  * of the bought capsules
889  *
890  */
891 void
set_select_cursor_coordinates()892 supervisor_shop::set_select_cursor_coordinates ()
893 {
894   Sint32 y = mouse_pointer->get_y_coord () - capsules_frame_ymin;
895   Sint32 offset = (y / select_cursor_height);
896   y = offset * select_cursor_height + capsules_frame_ymin;
897   if (y < capsules_frame_ymin)
898     {
899       y = capsules_frame_ymin;
900     }
901   if (y > capsules_frame_ymax)
902     {
903       y = capsules_frame_ymax;
904     }
905   /* cursor y coordinate */
906   select_cursor_ycoord = y;
907 
908   /* don't display cursor by default */
909   is_drawn_select_cursor = false;
910   selected_capsule_index = -1;
911   /* at least one bonus capsule? */
912   if (num_of_bought_capsules < 1)
913     {
914       return;
915     }
916 
917   /*
918    * calculate maximum y coordinate
919    */
920   Sint32 ymax = num_of_bought_capsules * select_cursor_height
921                 + capsules_frame_ymin;
922   /* if an object is drag, then adds a supplementary place */
923   if (is_caspule_drag)
924     {
925       ymax = ymax + select_cursor_height;
926     }
927 
928   Sint32 x = mouse_pointer->get_x_coord ();
929   y = mouse_pointer->get_y_coord ();
930   if (x >= select_cursor_xcoord && y < ymax)
931     {
932       is_drawn_select_cursor = true;
933       selected_capsule_index = offset;
934     }
935 }
936 
937 /**
938  * Draw the cursor of the bonus selected in the list on the right
939  */
940 void
draw_select_cursor()941 supervisor_shop::draw_select_cursor ()
942 {
943   if (select_cursor_color++ > 32)
944     {
945       select_cursor_color = 0;
946     }
947 
948   /* calculation the height and the width of the cursor */
949   Sint32 a = select_cursor_sin_index + 5;
950   a &= 511;
951   select_cursor_sin_index = a;
952   if (!is_drawn_select_cursor > 0)
953     {
954       return;
955     }
956   Sint16 *s = table_cosL + a;
957   a = *s;
958   a *= (select_cursor_width / 5);
959   a >>= 7;
960   a = a + select_cursor_width / 5;
961   Sint32 b = select_cursor_sin_index;
962   s = table_cosL + b;
963   b = *s;
964   b *= (select_cursor_height / 5);
965   b >>= 7;
966   b = b + select_cursor_height / 5;
967   Sint32 w = select_cursor_width - a;
968   Sint32 h = select_cursor_height - b;
969 
970   /* calculation of the coordinates of the cursor */
971   Sint32 x = select_cursor_xcoord + (select_cursor_width - w) / 2;
972   Sint32 y = select_cursor_ycoord + (select_cursor_height - h) / 2;
973 
974   /* draw the cursor */
975   Uint32 delay = 0;
976   Uint32 color = select_cursor_color;
977   char *dest = game_screen->get_pixel_data (x, y);
978   Uint32 next_line = game_screen->get_row_size ();
979   for (Sint32 i = 0; i < h; i++)
980     {
981       for (Sint32 j = 0; j < w; j++)
982         {
983           unsigned char pixel = color_cycling[color];
984           dest[j] = pixel;
985         }
986       if (++delay == 5)
987         {
988           delay = 0;
989           if (color++ > 32)
990             {
991               color = 0;
992             }
993         }
994       dest += next_line;
995     }
996 }
997 
998 /**
999  * Check if the player enables the cheating mode
1000  */
1001 void
check_if_enable_cheat()1002 supervisor_shop::check_if_enable_cheat ()
1003 {
1004   mouse_pointer->set_frame_period (3);
1005   if (is_enabled_cheat_mode)
1006     {
1007       /* the cheating mode is already enabled */
1008       return;
1009     }
1010   if (!birth_flag)
1011     {
1012       return;
1013     }
1014   if (!mouse_pointer->get_x_coord () && !mouse_pointer->get_y_coord ())
1015     {
1016       mouse_pointer->set_frame_period (20);
1017       Uint32 code = keyboard->get_key_down_code ();
1018       if (previous_key_code_down != code && code > 0)
1019         {
1020           previous_key_code_down = code;
1021           cheat_code_input = cheat_code_input << 8 | code;
1022         }
1023     }
1024   if (cheat_code_input == cheat_code)
1025     {
1026       is_enabled_cheat_mode = true;
1027     }
1028   else
1029     {
1030       is_enabled_cheat_mode = false;
1031     }
1032 }
1033 
1034 /**
1035  * Identifiers of the available options and bonus capsules
1036  */
1037 Sint32
1038 supervisor_shop::available_options_id[] =
1039 {
1040   sprite_capsule::EXPAND_PADDLE,
1041   sprite_capsule::FIRE_POWER_1,
1042   sprite_capsule::FIRE_POWER_2,
1043   sprite_capsule::REBUILD_THE_WALL,
1044   sprite_capsule::EXTRA_BALLS,
1045   sprite_capsule::MULTI_BALLS,
1046   sprite_capsule::POWER_BALL_1, sprite_capsule::POWER_BALL_2,
1047   sprite_capsule::LESS_BRICKS, sprite_capsule::EXTRA_LIFE,
1048   sprite_capsule::SOME_INFOS, sprite_capsule::BOTTOM_WALL,
1049   sprite_capsule::ENABLE_LEFT_PADDLE,
1050   sprite_capsule::ENABLE_TOP_PADDLE,
1051   sprite_capsule::ENABLE_RIGHT_PADDLE,
1052   sprite_capsule::BALL_SIZE_2,
1053   sprite_capsule::BALL_SIZE_3,
1054   sprite_capsule::ROBOT_PADDLE,
1055   sprite_capsule::BALLS_CONTROL,
1056   sprite_capsule::GLUE,
1057   sprite_capsule::LEAVE_SHOP,
1058   sprite_capsule::LEAVE_SHOP,
1059   sprite_capsule::LEAVE_SHOP,
1060   sprite_capsule::LEAVE_SHOP,
1061   sprite_capsule::LEAVE_SHOP,
1062   sprite_capsule::LEAVE_SHOP,
1063   sprite_capsule::LEAVE_SHOP,
1064   sprite_capsule::LEAVE_SHOP,
1065   sprite_capsule::LEAVE_SHOP,
1066   sprite_capsule::LEAVE_SHOP
1067 };
1068 
1069 /**
1070  * Prices of all the available options in the shop
1071  */
1072 Uint32
1073 supervisor_shop::options_prices[] =
1074 {
1075   60, 75, 150, 350, 25, 50,
1076   250, 500, 400, 450, 10, 75,
1077   100, 100, 100, 60, 75, 100,
1078   60, 150, 0, 0, 0, 0,
1079   0, 0, 0, 0, 0, 0
1080 };
1081 
1082 /**
1083  * Indexes of the texts used for sales confirmation messages
1084  */
1085 unsigned char
1086 supervisor_shop::led_index_to_text_index[] =
1087 {
1088   /* S+/F1/F2/RW/B2/B3 */
1089   0, 1, 2, 3, 4, 5,
1090   /* P1/P2/LB/L+/??/WA */
1091   6, 7, 8, 9, 10, 11,
1092   /* BL/BU/BR/S2/S3/RB */
1093   12, 13, 14, 15, 16, 17,
1094   /* CT/GL/XX/XX/XX/XX */
1095   18, 19, 20, 20, 20, 20,
1096   /* XX/XX/XX/XX/XX/XX */
1097   20, 20, 20, 20, 20, 20,
1098 };
1099 
1100 const unsigned char
1101 supervisor_shop::color_cycling[] =
1102 {
1103   239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252,
1104   253, 254, 255, 254, 253, 252, 251, 250, 249, 248, 247, 246, 245, 244,
1105   243, 242, 241, 240, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248,
1106   249, 250, 251, 252, 253, 254, 255
1107 };
1108