5 * Copyright (C) 2003, 2007, 2008, 2009 Thomas Perl <thp@thpinfo.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
38 #include "animation.h"
40 #include "locations.h"
44 int main( int argc
, char** argv
) {
45 int i
, slide
, slide_direction
;
49 unsigned int worldmap_xpos
, worldmap_ypos
;
53 int sdl_flags
= SDL_SWSURFACE
;
54 int btn_hovering
= 0, btn_hovering_old
= 0;
56 bool mouse_pressed
= false;
58 bool benchmark
= false;
59 unsigned int night_start
, night_end
;
60 GameState
*current_game
= NULL
, *prepared_game
= NULL
;
61 InputDevice
* input_devices
;
62 unsigned int input_device_count
, input_device_id
;
64 AnimationState
*intro_playback
;
66 TennixNet
* connection
= NULL
;
68 char* net_host
= NULL
;
69 bool net_master
= false;
70 #endif /* HAVE_SDL_NET */
71 TennixArchive
* tnxar
= NULL
;
73 MenuButton btn_back
= {
74 NULL
, /* not needed for image-based button */
76 HEIGHT
-MENU_OPTIONS_BORDER
,
77 0, -1, /* width and height will be set by menu_button_init */
81 MenuButton btn_start
= {
82 NULL
, /* not needed for image-based button */
83 WIDTH
-MENU_OPTIONS_BORDER
,
84 HEIGHT
-MENU_OPTIONS_BORDER
,
85 -1, -1, /* width and height will be set by menu_button_init */
89 MenuButton btn_player1
= {
91 CONTROLLER_SETUP_BORDER
,
92 HEIGHT
/2 + CONTROLLER_SETUP_SIZE
/2 + 10,
93 CONTROLLER_SETUP_SIZE
, MENU_OPTIONS_BUTTON_HEIGHT
,
97 MenuButton btn_player2
= {
99 WIDTH
-CONTROLLER_SETUP_SIZE
-CONTROLLER_SETUP_BORDER
,
100 HEIGHT
/2 + CONTROLLER_SETUP_SIZE
/2 + 10,
101 CONTROLLER_SETUP_SIZE
, MENU_OPTIONS_BUTTON_HEIGHT
,
106 int highlight_location
= -1;
107 float highlight_location_distance
= 0.0;
108 float new_location_distance
= 0.0;
109 bool location_info_visible
= false;
110 unsigned int location_info_xpos
= 0, location_info_ypos
= 0;
112 const SDL_VideoInfo
* vi
= NULL
;
114 bool do_help
= false;
116 int state
= MENU_STATE_STARTED
;
118 #ifdef ENABLE_FPS_LIMIT
119 Uint32 ft
, frames
; /* frame timer and frames */
122 fprintf(stderr
, "Tennix Classic Championship Tour 2011 (v" VERSION
")\n" COPYRIGHT
"\n" URL
"\n\n");
126 /* A poor/lazy man's getopt */
127 #define OPTION_SET(longopt,shortopt) \
128 (strcmp(argv[i], longopt)==0 || strcmp(argv[i], shortopt)==0)
129 #define OPTION_VALUE \
130 ((i+1 < argc)?(argv[i+1]):(NULL))
131 #define OPTION_VALUE_PROCESSED \
133 if (OPTION_SET("--fullscreen", "-f")) {
134 sdl_flags
|= SDL_FULLSCREEN
;
136 else if (OPTION_SET("--help", "-h")) {
139 else if (OPTION_SET("--benchmark", "-b")) {
143 else if (OPTION_SET("--slave", "-s")) {
144 net_host
= OPTION_VALUE
;
145 if (OPTION_VALUE
!= NULL
) {
146 OPTION_VALUE_PROCESSED
;
149 fprintf(stderr
, "Missing option parameter.\n");
154 else if (OPTION_SET("--master", "-m")) {
155 net_host
= OPTION_VALUE
;
156 if (OPTION_VALUE
!= NULL
) {
157 OPTION_VALUE_PROCESSED
;
160 fprintf(stderr
, "Missing option parameter.\n");
165 #endif /* HAVE_SDL_NET */
167 fprintf(stderr
, "Unknown option: %s\n", argv
[i
]);
173 if (do_help
== true) {
174 fprintf(stderr
, "Usage: %s [OPTIONS]\n\n"
175 " Where [OPTIONS] are zero or more of the following:\n\n"
176 " [--fullscreen|-f] Fullscreen mode\n"
177 " [--benchmark|-b] Run in benchmark/attract mode\n"
179 " [--master|-m <IP-of-slave>] Network play as master\n"
180 " [--slave|-s <IP-of-master>] Network play as slave\n"
181 #endif /* HAVE_SDL_NET */
182 " [--help|-h] Show help information\n\n"
183 " See tennix(6) for details.\n", argv
[0]);
190 srand((unsigned)time(NULL
));
193 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_JOYSTICK
) == -1) {
194 fprintf( stderr
, "Can't init SDL: %s\n", SDL_GetError());
198 vi
= SDL_GetVideoInfo();
199 if( (screen
= SDL_SetVideoMode( WIDTH
, HEIGHT
, vi
->vfmt
->BitsPerPixel
, sdl_flags
)) == NULL
) {
200 fprintf( stderr
, "Can't set video mode: %s\n", SDL_GetError());
204 SDL_WM_SetCaption( "Tennix Classic Championship Tour 2011", "Tennix 2011");
205 SDL_ShowCursor( SDL_DISABLE
);
206 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY
, 1);
208 tnxar
= new TennixArchive(ARCHIVE_FILE
, ARCHIVE_FILE_INSTALLED
);
209 init_graphics(*tnxar
);
214 #endif /* HAVE_SDL_NET */
218 if (net_host
!= NULL
) {
219 connection
= network_connect(net_host
, net_master
);
221 #endif /* HAVE_SDL_NET */
223 menu_button_init(&btn_back
);
224 menu_button_init(&btn_start
);
225 menu_button_init(&btn_player1
);
226 menu_button_init(&btn_player2
);
228 input_devices
= find_input_devices(&input_device_count
);
230 current_game
= gamestate_load(GAMESTATE_FILE
);
231 if (current_game
!= NULL
) {
232 /* restore pointer to location */
233 current_game
->location
= &(locations
[current_game
->current_location
]);
235 for (i
=1; i
<=MAXPLAYERS
; i
++) {
236 if (PLAYER(current_game
, i
).type
== PLAYER_TYPE_HUMAN
) {
237 input_device_id
= PLAYER(current_game
, i
).input_device_index
;
238 if (input_device_id
< input_device_count
) {
239 /* ok, we still have that device around */
240 PLAYER(current_game
, i
).input
= &(input_devices
[input_device_id
]);
242 /* the device vanished - set to AI (FIXME: select new device) */
243 PLAYER(current_game
, i
).type
= PLAYER_TYPE_AI
;
244 PLAYER(current_game
, i
).input
= NULL
;
250 #ifdef ENABLE_FPS_LIMIT
256 GameState
* g
= gamestate_new();
257 PLAYER(g
, 1).type
= PLAYER_TYPE_AI
;
258 PLAYER(g
, 2).type
= PLAYER_TYPE_AI
;
259 g
->location
= &(locations
[0]);
260 gameloop(g
, connection
);
265 /*intro = create_intro();
266 intro_playback = animation_state_new(intro);
267 animation_state_run(intro_playback, 1);
268 animation_state_free(intro_playback);
269 animation_free(intro);
272 worldmap_xpos
= (WIDTH
-get_image_width(GR_WORLDMAP
))/2;
273 worldmap_ypos
= (HEIGHT
-get_image_height(GR_WORLDMAP
))/2;
276 /* Sliding initialization */
277 ticks
= SDL_GetTicks();
278 slide
= slide_start
= get_image_width(GR_SIDEBAR
);
281 /* State transitions */
283 case MENU_STATE_STARTED
:
284 state
= MENU_STATE_SLIDE_TO_MAINMENU
;
286 case MENU_STATE_SLIDE_TO_MAINMENU
:
288 //rectangle(0, 0, WIDTH, HEIGHT, 80, 80, 80);
291 slide_direction
= -1;
292 state
= MENU_STATE_SLIDE_TO_MAINMENU_IN_PROGRESS
;
294 case MENU_STATE_SLIDE_TO_MAINMENU_IN_PROGRESS
:
297 state
= MENU_STATE_MAINMENU
;
300 case MENU_STATE_MAINMENU
:
302 prepared_game
= NULL
;
304 case MENU_STATE_SLIDE_TO_LOCATION
:
307 state
= MENU_STATE_SLIDE_TO_LOCATION_IN_PROGRESS
;
309 case MENU_STATE_SLIDE_TO_LOCATION_IN_PROGRESS
:
310 if (slide
== slide_start
) {
311 state
= MENU_STATE_FADE_TO_LOCATION
;
314 case MENU_STATE_FADE_TO_LOCATION
:
316 state
= MENU_STATE_LOCATION
;
319 //rectangle(0, 0, WIDTH, HEIGHT, 80, 80, 80);
320 /* Draw and store the worldmap with day/night times */
321 show_image(GR_WORLDMAP
, WIDTH
/2-get_image_width(GR_WORLDMAP
)/2, HEIGHT
/2-get_image_height(GR_WORLDMAP
)/2, 255);
322 day_night(get_image_width(GR_WORLDMAP
), &night_start
, &night_end
);
323 if (night_start
> night_end
) {
324 rectangle_alpha(worldmap_xpos
, worldmap_ypos
, night_end
, get_image_height(GR_WORLDMAP
), 0, 0, 0, 150);
325 rectangle_alpha(worldmap_xpos
+night_start
, worldmap_ypos
, get_image_width(GR_WORLDMAP
)-night_start
, get_image_height(GR_WORLDMAP
), 0, 0, 0, 150);
327 rectangle_alpha(worldmap_xpos
+night_start
, worldmap_ypos
, night_end
-night_start
, get_image_height(GR_WORLDMAP
), 0, 0, 0, 150);
330 /* add misc items to screen */
331 font_draw_string(FONT_XLARGE
, "Pick a location", (WIDTH
-font_get_string_width(FONT_XLARGE
, "Pick a location"))/2, 20);
335 case MENU_STATE_FADE_TO_OPTIONS
:
338 //rectangle(0, 0, WIDTH, HEIGHT, 80, 80, 80);
339 rectangle(CONTROLLER_SETUP_BORDER
, HEIGHT
/2-CONTROLLER_SETUP_SIZE
/2, CONTROLLER_SETUP_SIZE
, CONTROLLER_SETUP_SIZE
, 150, 150, 150);
340 rectangle(WIDTH
-CONTROLLER_SETUP_BORDER
-CONTROLLER_SETUP_SIZE
, (HEIGHT
-CONTROLLER_SETUP_SIZE
)/2, CONTROLLER_SETUP_SIZE
, CONTROLLER_SETUP_SIZE
, 150, 150, 150);
341 font_draw_string(FONT_XLARGE
, "Controller setup", (WIDTH
-font_get_string_width(FONT_XLARGE
, "Controller setup"))/2, 20);
342 font_draw_string(FONT_MEDIUM
, "Player 1", 130 - font_get_string_width(FONT_MEDIUM
, "Player 1")/2, (HEIGHT
-CONTROLLER_SETUP_SIZE
)/2 - 10 - font_get_height(FONT_MEDIUM
));
343 font_draw_string(FONT_MEDIUM
, "Player 1", 130 - font_get_string_width(FONT_MEDIUM
, "Player 1")/2, (HEIGHT
-CONTROLLER_SETUP_SIZE
)/2 - 10 - font_get_height(FONT_MEDIUM
));
344 font_draw_string(FONT_MEDIUM
, "Player 2", WIDTH
- CONTROLLER_SETUP_SIZE
/2 - CONTROLLER_SETUP_BORDER
- font_get_string_width(FONT_MEDIUM
, "Player 2")/2, (HEIGHT
-CONTROLLER_SETUP_SIZE
)/2 - 10 - font_get_height(FONT_MEDIUM
));
347 state
= MENU_STATE_OPTIONS
;
349 case MENU_STATE_LOCATION
:
350 case MENU_STATE_OPTIONS
:
351 /* Prepare a new game */
352 if (prepared_game
== NULL
) {
353 prepared_game
= gamestate_new();
354 prepared_game
->location
= NULL
;
355 /* FIXME - this should not be written here, but taken from the input devices */
356 btn_player1
.text
= "Keyboard (arrows)";
357 btn_player2
.text
= "Carl Van Court";
358 PLAYER(prepared_game
, 1).input_device_index
= 2;
359 PLAYER(prepared_game
, 1).type
= PLAYER_TYPE_HUMAN
;
360 PLAYER(prepared_game
, 1).input
= &(input_devices
[PLAYER(prepared_game
, 1).input_device_index
]);
361 location_info_visible
= false;
362 prepared_game
->current_location
= -1;
363 highlight_location
= -1;
366 case MENU_STATE_SLIDE_TO_GAME
:
369 state = MENU_STATE_SLIDE_TO_GAME_IN_PROGRESS;
371 case MENU_STATE_SLIDE_TO_GAME_IN_PROGRESS:
372 if (slide == slide_start) {
373 state = MENU_STATE_GAME;
375 state
= MENU_STATE_GAME
;
377 case MENU_STATE_SLIDE_TO_RESUME
:
380 state
= MENU_STATE_SLIDE_TO_RESUME_IN_PROGRESS
;
382 case MENU_STATE_SLIDE_TO_RESUME_IN_PROGRESS
:
383 if (slide
== slide_start
) {
384 state
= MENU_STATE_RESUME
;
387 case MENU_STATE_GAME
:
388 if (prepared_game
== NULL
) {
389 fprintf(stderr
, "Game not yet prepared!\n");
393 /* Cancel a possibly started game */
395 current_game
= prepared_game
;
396 prepared_game
= NULL
;
397 /* no break - we are continuing with "resume" */
398 case MENU_STATE_RESUME
:
399 if (current_game
== NULL
) {
400 fprintf(stderr
, "Cannot resume game!\n");
404 gameloop(current_game
, connection
);
406 while (SDL_PollEvent(&e
)) {};
407 #ifdef ENABLE_FPS_LIMIT
412 state
= MENU_STATE_SLIDE_TO_MAINMENU
;
414 case MENU_STATE_SLIDE_TO_QUIT
:
417 state
= MENU_STATE_SLIDE_TO_QUIT_IN_PROGRESS
;
419 case MENU_STATE_SLIDE_TO_QUIT_IN_PROGRESS
:
420 if (slide
== slide_start
) {
421 state
= MENU_STATE_QUIT
;
424 case MENU_STATE_QUIT
:
428 fprintf(stderr
, "State error: %d\n", state
);
433 if (SDL_GetTicks() > ticks
+ 20) {
434 if (slide
>= 1 && slide
<= slide_start
) {
435 slide
+= slide_direction
+(slide_direction
*slide
/(sqrt(2*slide
)));
436 slide
= MAX(0, MIN(slide_start
, slide
));
437 } else if (slide_direction
!= 0) {
440 ticks
= SDL_GetTicks();
445 if (state
!= MENU_STATE_OPTIONS
) {
446 fill_image_offset(GR_FOG
, 0, 0, WIDTH
, HEIGHT
, -i
, 0);
449 show_image(GR_SIDEBAR
, WIDTH
-get_image_width(GR_SIDEBAR
)+slide
, 0, 255);
450 show_image(GR_TENNIXLOGO
, WIDTH
-get_image_width(GR_SIDEBAR
)-10, 20-slide
, 255);
451 if (state
!= MENU_STATE_OPTIONS
&& state
!= MENU_STATE_LOCATION
) {
453 show_image(GR_BTN_PLAY
, WIDTH
-get_image_width(GR_BTN_PLAY
)+slide
+(slide
/7)+3-(3*(btn_hovering
==MENU_START
)), 150, 255);
454 if (current_game
!= NULL
) {
455 show_image(GR_BTN_RESUME
, WIDTH
-get_image_width(GR_BTN_RESUME
)+slide
+(slide
/7)+3-(3*(btn_hovering
==MENU_RESUME
)), 230, 255);
456 font_draw_string(FONT_SMALL
, "match paused", 10, 10);
458 font_draw_string(FONT_MEDIUM
, "Tennix Classic Championship Tour 2011", 10, 10);
460 //font_draw_string_color(FONT_MEDIUM, URL, 10-1, HEIGHT-10-1-font_get_height(FONT_MEDIUM), 130, 130, 130);
461 font_draw_string_color(FONT_MEDIUM
, URL
, 10, HEIGHT
-10-font_get_height(FONT_MEDIUM
), 100, 100, 100);
462 show_image(GR_BTN_QUIT
, WIDTH
-get_image_width(GR_BTN_QUIT
)+slide
+(slide
/7)+3-(3*(btn_hovering
==MENU_QUIT
)), 350, 255);
463 } else if (state
== MENU_STATE_OPTIONS
) {
465 draw_button_object(&btn_back
, mx
, my
);
466 draw_button_object(&btn_start
, mx
, my
);
467 draw_button_object(&btn_player1
, mx
, my
);
468 draw_button_object(&btn_player2
, mx
, my
);
469 wiggle
= 15*sinf((float)ticks
/300.);
470 if (PLAYER(prepared_game
, 1).input_device_index
> -1) {
471 show_image_rotozoom(input_devices
[PLAYER(prepared_game
, 1).input_device_index
].icon
, CONTROLLER_SETUP_BORDER
+ CONTROLLER_SETUP_SIZE
/2, HEIGHT
/2, wiggle
, 1.0);
473 show_image_rotozoom(GR_INPUT_AI
, CONTROLLER_SETUP_BORDER
+ CONTROLLER_SETUP_SIZE
/2, HEIGHT
/2, wiggle
, 1.0);
475 if (PLAYER(prepared_game
, 2).input_device_index
> -1) {
476 show_image_rotozoom(input_devices
[PLAYER(prepared_game
, 2).input_device_index
].icon
, WIDTH
-CONTROLLER_SETUP_BORDER
-CONTROLLER_SETUP_SIZE
/2, HEIGHT
/2, -wiggle
, 1.0);
478 show_image_rotozoom(GR_INPUT_AI
, WIDTH
-CONTROLLER_SETUP_BORDER
-CONTROLLER_SETUP_SIZE
/2, HEIGHT
/2, -wiggle
, 1.0);
480 } else if (state
== MENU_STATE_LOCATION
) {
481 /* Location selection screen */
482 for (x
=0; x
<location_count(); x
++) {
483 new_location_distance
= SQUARE_DISTANCE(mx
-worldmap_xpos
-locations
[x
].worldmap_x
,
484 my
-worldmap_ypos
-locations
[x
].worldmap_y
);
485 if (highlight_location
== -1) {
486 if (new_location_distance
< 20*20) {
487 highlight_location
= x
;
490 highlight_location_distance
= SQUARE_DISTANCE(mx
-worldmap_xpos
-locations
[highlight_location
].worldmap_x
,
491 my
-worldmap_ypos
-locations
[highlight_location
].worldmap_y
);
492 if (highlight_location_distance
> 20*20) {
493 highlight_location
= -1;
495 if (highlight_location_distance
> new_location_distance
&& new_location_distance
< 20*20) {
496 highlight_location
= x
;
500 if (prepared_game
!= NULL
) {
501 if (!location_info_visible
) {
502 for (x
=0; x
<location_count(); x
++) {
503 /* draw rectangle for location at "x"*/
504 if (highlight_location
!= -1 && (unsigned int)highlight_location
== x
) {
505 rectangle(worldmap_xpos
+ locations
[x
].worldmap_x
-3, worldmap_ypos
+ locations
[x
].worldmap_y
-3, 7, 7, 255*((i
/10)%2), 0, 255*((i
/10)%2));
508 rectangle(worldmap_xpos
+ locations
[x
].worldmap_x
-2, worldmap_ypos
+ locations
[x
].worldmap_y
-2, 5, 5, 255, 255*(prepared_game
->current_location
!= -1 && x
==(unsigned int)(prepared_game
->current_location
)), 0);
511 rectangle_alpha(location_info_xpos
-5, location_info_ypos
-5, 10+get_image_width(prepared_game
->location
->photo
), get_image_height(prepared_game
->location
->photo
)+100, 30, 30, 30, 200);
512 show_sprite(prepared_game
->location
->photo
, (i
/1000)%(prepared_game
->location
->photo_frames
), prepared_game
->location
->photo_frames
, location_info_xpos
, location_info_ypos
, 255);
513 font_draw_string(FONT_SMALL
, prepared_game
->location
->name
, location_info_xpos
+MENU_OPTIONS_BORDER
, location_info_ypos
+MENU_OPTIONS_BORDER
+200);
514 font_draw_string(FONT_SMALL
, prepared_game
->location
->area
, location_info_xpos
+MENU_OPTIONS_BORDER
, location_info_ypos
+MENU_OPTIONS_BORDER
+200+font_get_height(FONT_SMALL
));
515 font_draw_string(FONT_SMALL
, prepared_game
->location
->city
, location_info_xpos
+MENU_OPTIONS_BORDER
, location_info_ypos
+MENU_OPTIONS_BORDER
+200+2*font_get_height(FONT_SMALL
));
516 font_draw_string(FONT_SMALL
, prepared_game
->location
->court_type_name
, location_info_xpos
+MENU_OPTIONS_BORDER
, location_info_ypos
+MENU_OPTIONS_BORDER
+200+3*font_get_height(FONT_SMALL
));
518 if (prepared_game
->location
!= NULL
) {
519 draw_button_object(&btn_start
, mx
, my
);
522 draw_button_object(&btn_back
, mx
, my
);
526 if( e
.type
== SDL_QUIT
) {
527 state
= MENU_STATE_SLIDE_TO_QUIT
;
531 keys
= SDL_GetKeyState( NULL
);
532 mb
= SDL_GetMouseState( &mx
, &my
);
534 btn_hovering_old
= btn_hovering
;
535 if (state
== MENU_STATE_MAINMENU
) {
536 btn_hovering
= M_POS_DECODE(mx
, my
);
537 if (current_game
== NULL
) {
538 btn_hovering
&= ~MENU_RESUME
;
540 } else if (state
== MENU_STATE_LOCATION
) {
541 if (M_POS_BUTTON(btn_back
, mx
, my
)) {
542 btn_hovering
= MENU_QUIT
;
543 } else if (M_POS_BUTTON(btn_start
, mx
, my
)) {
544 btn_hovering
= MENU_START
;
548 } else if (state
== MENU_STATE_OPTIONS
) {
549 if (M_POS_BUTTON(btn_back
, mx
, my
)) {
550 btn_hovering
= MENU_QUIT
;
551 } else if (M_POS_BUTTON(btn_start
, mx
, my
)) {
552 btn_hovering
= MENU_START
;
553 } else if (M_POS_BUTTON(btn_player1
, mx
, my
)) {
554 btn_hovering
= MENU_PLAYER1
;
555 } else if (M_POS_BUTTON(btn_player2
, mx
, my
)) {
556 btn_hovering
= MENU_PLAYER2
;
561 /* No menu screen - no hovering. */
564 if (btn_hovering_old
!= btn_hovering
&& btn_hovering
!= 0) {
565 #ifdef HAVE_VOICE_FILES
566 if (btn_hovering
== MENU_QUIT
) {
567 play_sample(VOICE_QUIT_IT
);
568 } else if (btn_hovering
== MENU_START
) {
569 play_sample(VOICE_NEW_GAME
);
571 play_sample(SOUND_MOUSEOVER
);
574 play_sample(SOUND_MOUSEOVER
);
578 if( keys
[SDLK_ESCAPE
] || keys
['q']) {
579 /* FIXME: do the state thingie! */
584 SDL_WM_ToggleFullScreen( screen
);
587 if (state
== MENU_STATE_MAINMENU
|| state
== MENU_STATE_OPTIONS
|| state
== MENU_STATE_LOCATION
) {
588 show_image(GR_CURSOR
, mx
-2, my
-1, 255);
591 /* Draw the "real" mouse coordinates */
592 /*rectangle(mx-1, my-1, 2, 2, 255, 255, 255);*/
594 /* Store the screen, because we are fading after this screen update */
595 /*if (!(mb & SDL_BUTTON(SDL_BUTTON_LEFT)) && btn_hovering != MENU_NONE && mouse_pressed == true) store_screen();*/
599 if( mb
& SDL_BUTTON(SDL_BUTTON_LEFT
)) {
600 if (!mouse_pressed
) {
601 play_sample(SOUND_MOUSEOVER
);
603 mouse_pressed
= true;
604 } else if (mouse_pressed
== true) {
605 /* Mouse button released */
606 if (state
== MENU_STATE_MAINMENU
|| state
== MENU_STATE_OPTIONS
|| state
== MENU_STATE_LOCATION
) {
607 #ifdef HAVE_VOICE_FILES
608 if (btn_hovering
== MENU_START
) {
609 play_sample(VOICE_LETS_GO
);
611 play_sample(SOUND_MOUSECLICK
);
614 /*play_sample(SOUND_MOUSEOVER);*/
617 if (state
== MENU_STATE_MAINMENU
) {
618 switch (btn_hovering
) {
620 state
= MENU_STATE_SLIDE_TO_LOCATION
;
623 state
= MENU_STATE_SLIDE_TO_RESUME
;
626 state
= MENU_STATE_SLIDE_TO_QUIT
;
629 } else if (state
== MENU_STATE_LOCATION
) {
630 switch (btn_hovering
) {
632 if (prepared_game
->location
!= NULL
) {
633 state
= MENU_STATE_FADE_TO_OPTIONS
;
637 state
= MENU_STATE_SLIDE_TO_MAINMENU
;
640 if (!location_info_visible
&& highlight_location
!= -1) {
641 prepared_game
->current_location
= highlight_location
;
642 /* Set the day/night status */
643 if (night_start
< night_end
) {
644 locations
[prepared_game
->current_location
].night
= (locations
[prepared_game
->current_location
].worldmap_x
> night_start
&& locations
[prepared_game
->current_location
].worldmap_x
< night_end
);
646 locations
[prepared_game
->current_location
].night
= (locations
[prepared_game
->current_location
].worldmap_x
< night_end
|| locations
[prepared_game
->current_location
].worldmap_x
> night_start
);
648 prepared_game
->location
= &(locations
[prepared_game
->current_location
]);
649 location_info_xpos
= MAX(0, MIN(WIDTH
-320-50, mx
-320/2));
650 location_info_ypos
= MAX(0, MIN(HEIGHT
-200-160, my
-200/2));
651 location_info_visible
= true;
653 location_info_visible
= false;
654 highlight_location
= -1;
655 prepared_game
->current_location
= -1;
656 prepared_game
->location
= NULL
;
660 } else if (state
== MENU_STATE_OPTIONS
) {
661 switch (btn_hovering
) {
663 state
= MENU_STATE_SLIDE_TO_GAME
;
666 state
= MENU_STATE_FADE_TO_LOCATION
;
669 /* advance the input device index */
670 PLAYER(prepared_game
, 1).input_device_index
++;
671 if (PLAYER(prepared_game
, 1).input_device_index
== (signed int)input_device_count
) {
672 PLAYER(prepared_game
, 1).input_device_index
= -1;
675 if (input_devices
[PLAYER(prepared_game
, 1).input_device_index
].exclusive_to_player
== 2) {
676 PLAYER(prepared_game
, 1).input_device_index
++;
679 /* determine the selected input device */
680 if (PLAYER(prepared_game
, 1).input_device_index
== -1) {
681 PLAYER(prepared_game
, 1).type
= PLAYER_TYPE_AI
;
682 PLAYER(prepared_game
, 1).input
= NULL
;
683 btn_player1
.text
= "Carl Van Court";
685 PLAYER(prepared_game
, 1).type
= PLAYER_TYPE_HUMAN
;
686 PLAYER(prepared_game
, 1).input
= &(input_devices
[PLAYER(prepared_game
, 1).input_device_index
]);
687 btn_player1
.text
= input_device_get_name(PLAYER(prepared_game
, 1).input
);
691 /* advance the input device index */
692 PLAYER(prepared_game
, 2).input_device_index
++;
694 if (input_devices
[PLAYER(prepared_game
, 2).input_device_index
].exclusive_to_player
== 1) {
695 PLAYER(prepared_game
, 2).input_device_index
++;
698 if (PLAYER(prepared_game
, 2).input_device_index
== (signed int)input_device_count
) {
699 PLAYER(prepared_game
, 2).input_device_index
= -1;
702 /* determine the selected input device */
703 if (PLAYER(prepared_game
, 2).input_device_index
== -1) {
704 PLAYER(prepared_game
, 2).type
= PLAYER_TYPE_AI
;
705 PLAYER(prepared_game
, 2).input
= NULL
;
706 btn_player2
.text
= "Carl Van Court";
708 PLAYER(prepared_game
, 2).type
= PLAYER_TYPE_HUMAN
;
709 PLAYER(prepared_game
, 2).input
= &(input_devices
[PLAYER(prepared_game
, 2).input_device_index
]);
710 btn_player2
.text
= input_device_get_name(PLAYER(prepared_game
, 2).input
);
715 mouse_pressed
= false;
718 #ifdef ENABLE_FPS_LIMIT
719 while (frames
*1000.0/((float)(SDL_GetTicks()-ft
+1))>(float)(DEFAULT_FPS
)) {
726 if (current_game
!= NULL
) {
727 if (gamestate_save(current_game
, GAMESTATE_FILE
) != 0) {
728 fprintf(stderr
, "Warning: cannot save gamestate to %s\n", GAMESTATE_FILE
);
732 /* Play the credits */
733 intro
= create_credits();
734 intro_playback
= animation_state_new(intro
);
735 animation_state_run(intro_playback
, 1);
736 animation_state_free(intro_playback
);
737 animation_free(intro
);
743 #endif /* HAVE_SDL_NET */
750 void menu_button_init(MenuButton
* b
)
754 if (b
->image_id
!= GR_COUNT
) {
756 * If the button is an image, the "w" and "h" attributes of the
757 * MenuButton struct are simply factors with which the real width
758 * and height of the image (=button) should be multiplied and added
759 * to the "x" and "y" position and the "w" and "h" are replaced with
760 * the real size of the image for the collision detection
765 b
->w
= get_image_width(b
->image_id
);
766 b
->h
= get_image_height(b
->image_id
);