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,
40 #include "animation.h"
42 #include "locations.h"
48 /* IDs from the resource file */
49 #define START_BUTTON 1
50 #define CHECKBOX_FULLSCREEN 2
53 BOOL CALLBACK
ConfigDialogProc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
55 static int checkbox_is_checked
;
59 EndDialog(hwndDlg
, IDCANCEL
);
64 EndDialog(hwndDlg
, (checkbox_is_checked
)?(IDYES
):(IDNO
));
67 EndDialog(hwndDlg
, IDCANCEL
);
69 case CHECKBOX_FULLSCREEN
:
70 checkbox_is_checked
^= 1;
82 int WINAPI
WinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
,
83 LPSTR lpCmdLine
, int nCmdShow
) {
85 int main( int argc
, char** argv
) {
87 int i
, slide
, slide_direction
;
91 unsigned int worldmap_xpos
, worldmap_ypos
;
95 int sdl_flags
= SDL_SWSURFACE
;
96 int btn_hovering
= 0, btn_hovering_old
= 0;
98 bool mouse_pressed
= false;
100 bool benchmark
= false;
101 unsigned int night_start
, night_end
;
102 GameState
*current_game
= NULL
, *prepared_game
= NULL
;
103 InputDevice
* input_devices
;
104 unsigned int input_device_count
;
106 AnimationState
*intro_playback
;
109 MenuButton btn_back
= {
112 HEIGHT
-(MENU_OPTIONS_BORDER
+MENU_OPTIONS_BUTTON_HEIGHT
),
113 MENU_OPTIONS_BUTTON_WIDTH
, MENU_OPTIONS_BUTTON_HEIGHT
,
116 MenuButton btn_start
= {
118 WIDTH
-(MENU_OPTIONS_BORDER
+MENU_OPTIONS_BUTTON_WIDTH
),
119 HEIGHT
-(MENU_OPTIONS_BORDER
+MENU_OPTIONS_BUTTON_HEIGHT
),
120 MENU_OPTIONS_BUTTON_WIDTH
, MENU_OPTIONS_BUTTON_HEIGHT
,
123 MenuButton btn_player1
= {
125 CONTROLLER_SETUP_BORDER
,
126 HEIGHT
/2 + CONTROLLER_SETUP_SIZE
/2 + 10,
127 CONTROLLER_SETUP_SIZE
, MENU_OPTIONS_BUTTON_HEIGHT
,
130 MenuButton btn_player2
= {
132 WIDTH
-CONTROLLER_SETUP_SIZE
-CONTROLLER_SETUP_BORDER
,
133 HEIGHT
/2 + CONTROLLER_SETUP_SIZE
/2 + 10,
134 CONTROLLER_SETUP_SIZE
, MENU_OPTIONS_BUTTON_HEIGHT
,
138 int current_location
= -1;
139 int highlight_location
= -1;
140 float highlight_location_distance
= 0.0;
141 float new_location_distance
= 0.0;
142 bool location_info_visible
= false;
143 unsigned int location_info_xpos
= 0, location_info_ypos
= 0;
145 const SDL_VideoInfo
* vi
= NULL
;
147 bool do_help
= false;
149 int state
= MENU_STATE_STARTED
;
151 #ifdef ENABLE_FPS_LIMIT
152 Uint32 ft
, frames
; /* frame timer and frames */
156 sdl_flags
|= SDL_FULLSCREEN
;
161 mb_result
= DialogBox(hInstance
, "CONFIG", 0, (DLGPROC
)ConfigDialogProc
);
165 sdl_flags
|= SDL_FULLSCREEN
;
174 fprintf(stderr
, "Tennix " VERSION
"\n" COPYRIGHT
"\n" URL
"\n\n");
178 /* A poor/lazy man's getopt */
179 #define OPTION_SET(longopt,shortopt) \
180 (strcmp(argv[i], longopt)==0 || strcmp(argv[i], shortopt)==0)
181 #define OPTION_VALUE \
182 ((i+1 < argc)?(argv[i+1]):(NULL))
183 #define OPTION_VALUE_PROCESSED \
185 if (OPTION_SET("--fullscreen", "-f")) {
186 sdl_flags
|= SDL_FULLSCREEN
;
188 else if (OPTION_SET("--help", "-h")) {
191 else if (OPTION_SET("--benchmark", "-b")) {
195 fprintf(stderr
, "Ignoring unknown option: %s\n", argv
[i
]);
200 if (do_help
== true) {
201 fprintf(stderr
, "Usage: %s [--fullscreen|-f] [--help|-h]\n", argv
[0]);
209 srand((unsigned)time(NULL
));
212 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_JOYSTICK
) == -1) {
213 fprintf( stderr
, "Can't init SDL: %s\n", SDL_GetError());
217 vi
= SDL_GetVideoInfo();
218 if( (screen
= SDL_SetVideoMode( WIDTH
, HEIGHT
, vi
->vfmt
->BitsPerPixel
, sdl_flags
)) == NULL
) {
219 fprintf( stderr
, "Can't set video mode: %s\n", SDL_GetError());
223 SDL_WM_SetCaption( "Tennix " VERSION
, "Tennix");
224 SDL_ShowCursor( SDL_DISABLE
);
225 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY
, 1);
231 input_devices
= find_input_devices(&input_device_count
);
233 #ifdef ENABLE_FPS_LIMIT
239 GameState
* g
= gamestate_new();
240 PLAYER(g
, 1).type
= PLAYER_TYPE_AI
;
241 PLAYER(g
, 2).type
= PLAYER_TYPE_AI
;
242 g
->timelimit
= BENCHMARK_TIMELIMIT
*1000;
243 g
->location
= &(locations
[0]);
249 intro
= create_intro();
250 intro_playback
= animation_state_new(intro
);
251 animation_state_run(intro_playback
, 1);
252 animation_state_free(intro_playback
);
253 animation_free(intro
);
255 worldmap_xpos
= (WIDTH
-get_image_width(GR_WORLDMAP
))/2;
256 worldmap_ypos
= (HEIGHT
-get_image_height(GR_WORLDMAP
))/2;
259 /* Sliding initialization */
260 ticks
= SDL_GetTicks();
261 slide
= slide_start
= get_image_width(GR_SIDEBAR
);
264 /* State transitions */
266 case MENU_STATE_STARTED
:
267 state
= MENU_STATE_SLIDE_TO_MAINMENU
;
269 case MENU_STATE_SLIDE_TO_MAINMENU
:
273 slide_direction
= -1;
274 state
= MENU_STATE_SLIDE_TO_MAINMENU_IN_PROGRESS
;
276 case MENU_STATE_SLIDE_TO_MAINMENU_IN_PROGRESS
:
279 state
= MENU_STATE_MAINMENU
;
282 case MENU_STATE_MAINMENU
:
284 prepared_game
= NULL
;
286 case MENU_STATE_SLIDE_TO_LOCATION
:
289 state
= MENU_STATE_SLIDE_TO_LOCATION_IN_PROGRESS
;
291 case MENU_STATE_SLIDE_TO_LOCATION_IN_PROGRESS
:
292 if (slide
== slide_start
) {
293 state
= MENU_STATE_FADE_TO_LOCATION
;
296 case MENU_STATE_FADE_TO_LOCATION
:
298 state
= MENU_STATE_LOCATION
;
301 rectangle(0, 0, WIDTH
, HEIGHT
, 80, 80, 80);
302 /* Draw and store the worldmap with day/night times */
303 show_image(GR_WORLDMAP
, WIDTH
/2-get_image_width(GR_WORLDMAP
)/2, HEIGHT
/2-get_image_height(GR_WORLDMAP
)/2, 255);
304 day_night(get_image_width(GR_WORLDMAP
), &night_start
, &night_end
);
305 if (night_start
> night_end
) {
306 rectangle_alpha(worldmap_xpos
, worldmap_ypos
, night_end
, get_image_height(GR_WORLDMAP
), 0, 0, 0, 150);
307 rectangle_alpha(worldmap_xpos
+night_start
, worldmap_ypos
, get_image_width(GR_WORLDMAP
)-night_start
, get_image_height(GR_WORLDMAP
), 0, 0, 0, 150);
309 rectangle_alpha(worldmap_xpos
+night_start
, worldmap_ypos
, night_end
-night_start
, get_image_height(GR_WORLDMAP
), 0, 0, 0, 150);
312 /* add misc items to screen */
313 font_draw_string(FONT_XLARGE
, "Pick a location", (WIDTH
-font_get_string_width(FONT_XLARGE
, "Pick a location"))/2, 20);
317 case MENU_STATE_FADE_TO_OPTIONS
:
320 rectangle(0, 0, WIDTH
, HEIGHT
, 80, 80, 80);
321 rectangle(CONTROLLER_SETUP_BORDER
, HEIGHT
/2-CONTROLLER_SETUP_SIZE
/2, CONTROLLER_SETUP_SIZE
, CONTROLLER_SETUP_SIZE
, 150, 150, 150);
322 rectangle(WIDTH
-CONTROLLER_SETUP_BORDER
-CONTROLLER_SETUP_SIZE
, (HEIGHT
-CONTROLLER_SETUP_SIZE
)/2, CONTROLLER_SETUP_SIZE
, CONTROLLER_SETUP_SIZE
, 150, 150, 150);
323 font_draw_string(FONT_XLARGE
, "Controller setup", (WIDTH
-font_get_string_width(FONT_XLARGE
, "Controller setup"))/2, 20);
324 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
));
325 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
));
326 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
));
329 state
= MENU_STATE_OPTIONS
;
331 case MENU_STATE_LOCATION
:
332 case MENU_STATE_OPTIONS
:
333 /* Prepare a new game */
334 if (prepared_game
== NULL
) {
335 prepared_game
= gamestate_new();
336 prepared_game
->location
= NULL
;
337 btn_player1
.text
= "default";
338 btn_player2
.text
= "computer (AI)";
340 PLAYER(prepared_game
, 1).input_device_index
= 0;
342 PLAYER(prepared_game
, 1).input_device_index
= 2;
344 location_info_visible
= false;
345 current_location
= -1;
346 highlight_location
= -1;
349 case MENU_STATE_SLIDE_TO_GAME
:
352 state = MENU_STATE_SLIDE_TO_GAME_IN_PROGRESS;
354 case MENU_STATE_SLIDE_TO_GAME_IN_PROGRESS:
355 if (slide == slide_start) {
356 state = MENU_STATE_GAME;
358 state
= MENU_STATE_GAME
;
360 case MENU_STATE_SLIDE_TO_RESUME
:
363 state
= MENU_STATE_SLIDE_TO_RESUME_IN_PROGRESS
;
365 case MENU_STATE_SLIDE_TO_RESUME_IN_PROGRESS
:
366 if (slide
== slide_start
) {
367 state
= MENU_STATE_RESUME
;
370 case MENU_STATE_GAME
:
371 if (prepared_game
== NULL
) {
372 fprintf(stderr
, "Game not yet prepared!\n");
375 /* Set the day/night status */
376 if (night_start
< night_end
) {
377 prepared_game
->night
= (prepared_game
->location
->worldmap_x
> night_start
&& prepared_game
->location
->worldmap_x
< night_end
);
379 prepared_game
->night
= (prepared_game
->location
->worldmap_x
< night_end
|| prepared_game
->location
->worldmap_x
> night_start
);
382 /* Cancel a possibly started game */
384 current_game
= prepared_game
;
385 prepared_game
= NULL
;
386 /* no break - we are continuing with "resume" */
387 case MENU_STATE_RESUME
:
388 if (current_game
== NULL
) {
389 fprintf(stderr
, "Cannot resume game!\n");
393 gameloop(current_game
);
395 while(SDL_PollEvent(&e
));
396 #ifdef ENABLE_FPS_LIMIT
401 state
= MENU_STATE_SLIDE_TO_MAINMENU
;
403 case MENU_STATE_SLIDE_TO_QUIT
:
406 state
= MENU_STATE_SLIDE_TO_QUIT_IN_PROGRESS
;
408 case MENU_STATE_SLIDE_TO_QUIT_IN_PROGRESS
:
409 if (slide
== slide_start
) {
410 state
= MENU_STATE_QUIT
;
413 case MENU_STATE_QUIT
:
417 fprintf(stderr
, "State error: %d\n", state
);
422 if (SDL_GetTicks() > ticks
+ 20) {
423 if (slide
>= 1 && slide
<= slide_start
) {
424 slide
+= slide_direction
+(slide_direction
*slide
/(sqrt(2*slide
)));
425 slide
= MAX(0, MIN(slide_start
, slide
));
426 } else if (slide_direction
!= 0) {
429 ticks
= SDL_GetTicks();
434 if (state
!= MENU_STATE_OPTIONS
) {
435 fill_image_offset(GR_FOG
, 0, 0, WIDTH
, HEIGHT
, -i
, 0);
438 show_image(GR_SIDEBAR
, WIDTH
-get_image_width(GR_SIDEBAR
)+slide
, 0, 255);
439 show_image(GR_TENNIXLOGO
, WIDTH
-get_image_width(GR_SIDEBAR
)-10, 20-slide
, 255);
440 if (state
!= MENU_STATE_OPTIONS
&& state
!= MENU_STATE_LOCATION
) {
442 show_image(GR_BTN_PLAY
, WIDTH
-get_image_width(GR_BTN_PLAY
)+slide
+(slide
/7)+3-(3*(btn_hovering
==MENU_START
)), 150, 255);
443 if (current_game
!= NULL
) {
444 show_image(GR_BTN_RESUME
, WIDTH
-get_image_width(GR_BTN_RESUME
)+slide
+(slide
/7)+3-(3*(btn_hovering
==MENU_RESUME
)), 230, 255);
445 font_draw_string(FONT_SMALL
, "current match:", 10, 10);
446 font_draw_string(FONT_SMALL
, current_game
->sets_score_str
, 10, 40);
448 font_draw_string(FONT_MEDIUM
, "Tennix " VERSION
, 10, 10);
450 font_draw_string_color(FONT_SMALL
, URL
, 10, HEIGHT
-10-font_get_height(FONT_SMALL
), 100, 100, 100);
451 show_image(GR_BTN_QUIT
, WIDTH
-get_image_width(GR_BTN_QUIT
)+slide
+(slide
/7)+3-(3*(btn_hovering
==MENU_QUIT
)), 350, 255);
452 } else if (state
== MENU_STATE_OPTIONS
) {
454 draw_button_object(btn_back
, mx
, my
);
455 draw_button_object(btn_start
, mx
, my
);
456 draw_button_object(btn_player1
, mx
, my
);
457 draw_button_object(btn_player2
, mx
, my
);
458 wiggle
= 15*sinf((float)ticks
/300.);
459 if (PLAYER(prepared_game
, 1).input_device_index
> -1) {
460 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);
462 show_image_rotozoom(GR_INPUT_AI
, CONTROLLER_SETUP_BORDER
+ CONTROLLER_SETUP_SIZE
/2, HEIGHT
/2, wiggle
, 1.0);
464 if (PLAYER(prepared_game
, 2).input_device_index
> -1) {
465 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);
467 show_image_rotozoom(GR_INPUT_AI
, WIDTH
-CONTROLLER_SETUP_BORDER
-CONTROLLER_SETUP_SIZE
/2, HEIGHT
/2, -wiggle
, 1.0);
469 } else if (state
== MENU_STATE_LOCATION
) {
470 /* Location selection screen */
471 for (x
=0; x
<location_count(); x
++) {
472 new_location_distance
= SQUARE_DISTANCE(mx
-worldmap_xpos
-locations
[x
].worldmap_x
,
473 my
-worldmap_ypos
-locations
[x
].worldmap_y
);
474 if (highlight_location
== -1) {
475 if (new_location_distance
< 20*20) {
476 highlight_location
= x
;
479 highlight_location_distance
= SQUARE_DISTANCE(mx
-worldmap_xpos
-locations
[highlight_location
].worldmap_x
,
480 my
-worldmap_ypos
-locations
[highlight_location
].worldmap_y
);
481 if (highlight_location_distance
> 20*20) {
482 highlight_location
= -1;
484 if (highlight_location_distance
> new_location_distance
&& new_location_distance
< 20*20) {
485 highlight_location
= x
;
489 if (!location_info_visible
) {
490 for (x
=0; x
<location_count(); x
++) {
491 /* draw rectangle for location at "x"*/
492 if (highlight_location
!= -1 && (unsigned int)highlight_location
== x
) {
493 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));
496 rectangle(worldmap_xpos
+ locations
[x
].worldmap_x
-2, worldmap_ypos
+ locations
[x
].worldmap_y
-2, 5, 5, 255, 255*(current_location
!= -1 && x
==(unsigned int)current_location
), 0);
499 if (prepared_game
!= NULL
) {
500 if (location_info_visible
) {
501 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, 100, 0, 0, 200);
502 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);
503 font_draw_string(FONT_SMALL
, prepared_game
->location
->name
, location_info_xpos
+MENU_OPTIONS_BORDER
, location_info_ypos
+MENU_OPTIONS_BORDER
+200);
504 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
));
505 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
));
506 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
));
508 if (prepared_game
->location
!= NULL
) {
509 draw_button_object(btn_start
, mx
, my
);
512 draw_button_object(btn_back
, mx
, my
);
516 if( e
.type
== SDL_QUIT
) {
517 state
= MENU_STATE_SLIDE_TO_QUIT
;
521 keys
= SDL_GetKeyState( NULL
);
522 mb
= SDL_GetMouseState( &mx
, &my
);
524 btn_hovering_old
= btn_hovering
;
525 if (state
== MENU_STATE_MAINMENU
) {
526 btn_hovering
= M_POS_DECODE(mx
, my
);
527 if (current_game
== NULL
) {
528 btn_hovering
&= ~MENU_RESUME
;
530 } else if (state
== MENU_STATE_LOCATION
) {
531 if (M_POS_BUTTON(btn_back
, mx
, my
)) {
532 btn_hovering
= MENU_QUIT
;
533 } else if (M_POS_BUTTON(btn_start
, mx
, my
)) {
534 btn_hovering
= MENU_START
;
538 } else if (state
== MENU_STATE_OPTIONS
) {
539 if (M_POS_BUTTON(btn_back
, mx
, my
)) {
540 btn_hovering
= MENU_QUIT
;
541 } else if (M_POS_BUTTON(btn_start
, mx
, my
)) {
542 btn_hovering
= MENU_START
;
543 } else if (M_POS_BUTTON(btn_player1
, mx
, my
)) {
544 btn_hovering
= MENU_PLAYER1
;
545 } else if (M_POS_BUTTON(btn_player2
, mx
, my
)) {
546 btn_hovering
= MENU_PLAYER2
;
551 /* No menu screen - no hovering. */
554 #ifndef MAEMO /* On Maemo, we cannot really "hover" (touchscreen!) */
555 if (btn_hovering_old
!= btn_hovering
&& btn_hovering
!= 0) {
556 #ifdef HAVE_VOICE_FILES
557 if (btn_hovering
== MENU_QUIT
) {
558 play_sample(VOICE_QUIT_IT
);
559 } else if (btn_hovering
== MENU_START
) {
560 play_sample(VOICE_NEW_GAME
);
562 play_sample(SOUND_MOUSEOVER
);
565 /*play_sample(SOUND_MOUSEOVER);*/
570 if( keys
[SDLK_ESCAPE
] || keys
['q']) {
571 /* FIXME: do the state thingie! */
576 SDL_WM_ToggleFullScreen( screen
);
579 #ifndef MAEMO /* No mouse cursor on Maemo (we have a touchscreen) */
580 if (state
== MENU_STATE_MAINMENU
|| state
== MENU_STATE_OPTIONS
|| state
== MENU_STATE_LOCATION
) {
581 show_image(GR_CURSOR
, mx
-2, my
-1, 255);
585 /* Draw the "real" mouse coordinates */
586 /*rectangle(mx-1, my-1, 2, 2, 255, 255, 255);*/
588 /* Store the screen, because we are fading after this screen update */
589 /*if (!(mb & SDL_BUTTON(SDL_BUTTON_LEFT)) && btn_hovering != MENU_NONE && mouse_pressed == true) store_screen();*/
593 if( mb
& SDL_BUTTON(SDL_BUTTON_LEFT
)) {
594 if (!mouse_pressed
) {
595 play_sample(SOUND_MOUSEOVER
);
597 mouse_pressed
= true;
598 } else if (mouse_pressed
== true) {
599 /* Mouse button released */
600 if (state
== MENU_STATE_MAINMENU
|| state
== MENU_STATE_OPTIONS
|| state
== MENU_STATE_LOCATION
) {
601 #ifdef HAVE_VOICE_FILES
602 if (btn_hovering
== MENU_START
) {
603 play_sample(VOICE_LETS_GO
);
605 play_sample(SOUND_MOUSECLICK
);
608 /*play_sample(SOUND_MOUSEOVER);*/
611 if (state
== MENU_STATE_MAINMENU
) {
612 switch (btn_hovering
) {
614 state
= MENU_STATE_SLIDE_TO_LOCATION
;
617 state
= MENU_STATE_SLIDE_TO_RESUME
;
620 state
= MENU_STATE_SLIDE_TO_QUIT
;
623 } else if (state
== MENU_STATE_LOCATION
) {
624 switch (btn_hovering
) {
626 if (prepared_game
->location
!= NULL
) {
627 state
= MENU_STATE_FADE_TO_OPTIONS
;
631 state
= MENU_STATE_SLIDE_TO_MAINMENU
;
634 if (!location_info_visible
&& highlight_location
!= -1) {
635 current_location
= highlight_location
;
636 prepared_game
->location
= &(locations
[current_location
]);
637 location_info_xpos
= MAX(0, MIN(WIDTH
-320-50, mx
-320/2));
638 location_info_ypos
= MAX(0, MIN(HEIGHT
-200-160, my
-200/2));
639 location_info_visible
= true;
641 location_info_visible
= false;
642 current_location
= -1;
643 highlight_location
= -1;
644 prepared_game
->location
= NULL
;
648 } else if (state
== MENU_STATE_OPTIONS
) {
649 switch (btn_hovering
) {
651 state
= MENU_STATE_SLIDE_TO_GAME
;
654 state
= MENU_STATE_FADE_TO_LOCATION
;
657 /* advance the input device index */
658 PLAYER(prepared_game
, 1).input_device_index
++;
659 if (PLAYER(prepared_game
, 1).input_device_index
== (signed int)input_device_count
) {
660 PLAYER(prepared_game
, 1).input_device_index
= -1;
663 if (input_devices
[PLAYER(prepared_game
, 1).input_device_index
].exclusive_to_player
== 2) {
664 PLAYER(prepared_game
, 1).input_device_index
++;
667 /* determine the selected input device */
668 if (PLAYER(prepared_game
, 1).input_device_index
== -1) {
669 PLAYER(prepared_game
, 1).type
= PLAYER_TYPE_AI
;
670 PLAYER(prepared_game
, 1).input
= NULL
;
671 btn_player1
.text
= "Computer (AI)";
673 PLAYER(prepared_game
, 1).type
= PLAYER_TYPE_HUMAN
;
674 PLAYER(prepared_game
, 1).input
= &(input_devices
[PLAYER(prepared_game
, 1).input_device_index
]);
675 btn_player1
.text
= input_device_get_name(PLAYER(prepared_game
, 1).input
);
679 /* advance the input device index */
680 PLAYER(prepared_game
, 2).input_device_index
++;
682 if (input_devices
[PLAYER(prepared_game
, 2).input_device_index
].exclusive_to_player
== 1) {
683 PLAYER(prepared_game
, 2).input_device_index
++;
686 if (PLAYER(prepared_game
, 2).input_device_index
== (signed int)input_device_count
) {
687 PLAYER(prepared_game
, 2).input_device_index
= -1;
690 /* determine the selected input device */
691 if (PLAYER(prepared_game
, 2).input_device_index
== -1) {
692 PLAYER(prepared_game
, 2).type
= PLAYER_TYPE_AI
;
693 PLAYER(prepared_game
, 2).input
= NULL
;
694 btn_player2
.text
= "Computer (AI)";
696 PLAYER(prepared_game
, 2).type
= PLAYER_TYPE_HUMAN
;
697 PLAYER(prepared_game
, 2).input
= &(input_devices
[PLAYER(prepared_game
, 2).input_device_index
]);
698 btn_player2
.text
= input_device_get_name(PLAYER(prepared_game
, 2).input
);
703 mouse_pressed
= false;
706 #ifdef ENABLE_FPS_LIMIT
707 while (frames
*1000.0/((float)(SDL_GetTicks()-ft
+1))>(float)(DEFAULT_FPS
)) {