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