Implement night for world map + automatic night mode
[tennix.git] / tennix.c
blob65609fdd849ce43a388281c0a9e932d4f97e6046
2 /**
4 * Tennix! SDL Port
5 * Copyright (C) 2003, 2007, 2008, 2009 Thomas Perl <thp@thpinfo.com>
6 *
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,
20 * MA 02110-1301, USA.
22 **/
24 #include <stdio.h>
25 #include <time.h>
26 #include <libgen.h>
27 #include <string.h>
28 #include <stdlib.h>
30 #ifdef WIN32
31 #include <windows.h>
32 #endif
34 #include "tennix.h"
35 #include "game.h"
36 #include "graphics.h"
37 #include "sound.h"
38 #include "input.h"
39 #include "util.h"
41 #include "locations.h"
43 SDL_Surface *screen;
45 #ifdef WIN32
47 /* IDs from the resource file */
48 #define START_BUTTON 1
49 #define CHECKBOX_FULLSCREEN 2
50 #define QUIT_BUTTON 3
52 BOOL CALLBACK ConfigDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
54 static int checkbox_is_checked;
56 switch (uMsg) {
57 case WM_CLOSE:
58 EndDialog(hwndDlg, IDCANCEL);
59 break;
60 case WM_COMMAND:
61 switch (wParam) {
62 case START_BUTTON:
63 EndDialog(hwndDlg, (checkbox_is_checked)?(IDYES):(IDNO));
64 break;
65 case QUIT_BUTTON:
66 EndDialog(hwndDlg, IDCANCEL);
67 break;
68 case CHECKBOX_FULLSCREEN:
69 checkbox_is_checked ^= 1;
70 break;
72 break;
73 default:
74 return FALSE;
76 return TRUE;
78 #endif
80 #ifdef WIN32
81 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
82 LPSTR lpCmdLine, int nCmdShow) {
83 #else
84 int main( int argc, char** argv) {
85 #endif
86 int i, slide, slide_direction;
87 unsigned int x;
88 Uint32 ticks;
89 int mx, my;
90 unsigned int worldmap_xpos, worldmap_ypos;
91 Uint8 *keys;
92 Uint8 mb;
93 SDL_Event e;
94 int sdl_flags = SDL_SWSURFACE;
95 int btn_hovering = 0, btn_hovering_old = 0;
96 int slide_start;
97 bool mouse_pressed = false;
98 bool quit = false;
99 bool benchmark = false;
100 unsigned int night_start, night_end;
101 GameState *current_game = NULL, *prepared_game = NULL;
103 MenuButton btn_back = {
104 "Back to main menu",
105 MENU_OPTIONS_BORDER,
106 HEIGHT-(MENU_OPTIONS_BORDER+MENU_OPTIONS_BUTTON_HEIGHT),
107 MENU_OPTIONS_BUTTON_WIDTH, MENU_OPTIONS_BUTTON_HEIGHT,
108 255, 0, 0
110 MenuButton btn_start = {
111 "Start new game",
112 WIDTH-(MENU_OPTIONS_BORDER+MENU_OPTIONS_BUTTON_WIDTH),
113 HEIGHT-(MENU_OPTIONS_BORDER+MENU_OPTIONS_BUTTON_HEIGHT),
114 MENU_OPTIONS_BUTTON_WIDTH, MENU_OPTIONS_BUTTON_HEIGHT,
115 0, 255, 0
117 MenuButton btn_player1 = {
118 NULL,
119 380,
120 180,
121 MENU_OPTIONS_BUTTON_WIDTH, MENU_OPTIONS_BUTTON_HEIGHT,
122 50, 50, 255
124 MenuButton btn_player2 = {
125 NULL,
126 380,
127 180+MENU_OPTIONS_BORDER*2+MENU_OPTIONS_BUTTON_HEIGHT,
128 MENU_OPTIONS_BUTTON_WIDTH, MENU_OPTIONS_BUTTON_HEIGHT,
129 255, 50, 50
132 int current_location = -1;
133 int highlight_location = -1;
134 float highlight_location_distance = 0.0;
135 float new_location_distance = 0.0;
136 bool location_info_visible = false;
137 unsigned int location_info_xpos = 0, location_info_ypos = 0;
139 const SDL_VideoInfo* vi = NULL;
141 bool do_help = false;
143 int state = MENU_STATE_STARTED;
145 #ifdef ENABLE_FPS_LIMIT
146 Uint32 ft, frames; /* frame timer and frames */
147 #endif
149 #ifdef MAEMO
150 sdl_flags |= SDL_FULLSCREEN;
151 #endif
153 #ifdef WIN32
154 int mb_result;
155 mb_result = DialogBox(hInstance, "CONFIG", 0, (DLGPROC)ConfigDialogProc);
157 switch (mb_result) {
158 case IDYES:
159 sdl_flags |= SDL_FULLSCREEN;
160 break;
161 case IDCANCEL:
162 return 0;
163 break;
164 default:
165 break;
167 #else
168 fprintf(stderr, "Tennix " VERSION "\n" COPYRIGHT "\n" URL "\n\n");
170 i = 1;
171 while (i < argc) {
172 /* A poor/lazy man's getopt */
173 #define OPTION_SET(longopt,shortopt) \
174 (strcmp(argv[i], longopt)==0 || strcmp(argv[i], shortopt)==0)
175 #define OPTION_VALUE \
176 ((i+1 < argc)?(argv[i+1]):(NULL))
177 #define OPTION_VALUE_PROCESSED \
178 (i++)
179 if (OPTION_SET("--fullscreen", "-f")) {
180 sdl_flags |= SDL_FULLSCREEN;
182 else if (OPTION_SET("--help", "-h")) {
183 do_help = true;
185 else if (OPTION_SET("--list-joysticks", "-J")) {
186 SDL_Init(SDL_INIT_JOYSTICK);
187 joystick_list();
188 return 0;
190 else if (OPTION_SET("--benchmark", "-b")) {
191 benchmark = true;
193 else if (OPTION_SET("--joystick", "-j")) {
194 SDL_Init(SDL_INIT_JOYSTICK);
195 if (OPTION_VALUE == NULL) {
196 fprintf(stderr, "Error: You need to specify the name of the joystick as parameter.\n");
197 do_help = true;
198 break;
200 if (joystick_open(OPTION_VALUE)==0) {
201 fprintf(stderr, "Warning: Cannot find joystick \"%s\" - Ignored.\n", OPTION_VALUE);
202 break;
204 OPTION_VALUE_PROCESSED;
206 else {
207 fprintf(stderr, "Ignoring unknown option: %s\n", argv[i]);
209 i++;
212 if (do_help == true) {
213 fprintf(stderr, "Usage: %s [--fullscreen|-f] [--help|-h] [--list-joysticks|-J] [--joystick|-j] [joystick name]\n", argv[0]);
214 return 0;
216 #endif
218 if (benchmark) {
219 srand(100);
220 } else {
221 srand((unsigned)time(NULL));
224 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) == -1) {
225 fprintf( stderr, "Can't init SDL: %s\n", SDL_GetError());
226 exit( 1);
229 vi = SDL_GetVideoInfo();
230 if( (screen = SDL_SetVideoMode( WIDTH, HEIGHT, vi->vfmt->BitsPerPixel, sdl_flags)) == NULL) {
231 fprintf( stderr, "Can't set video mode: %s\n", SDL_GetError());
232 exit( 1);
235 SDL_WM_SetCaption( "Tennix " VERSION, "Tennix");
236 SDL_ShowCursor( SDL_DISABLE);
237 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, 1);
239 init_graphics();
240 init_sound();
241 init_joystick();
243 #ifdef ENABLE_FPS_LIMIT
244 frames = 0;
245 ft = SDL_GetTicks();
246 #endif
248 if (benchmark) {
249 GameState* g = gamestate_new();
250 PLAYER(g, 1).type = PLAYER_TYPE_AI;
251 PLAYER(g, 2).type = PLAYER_TYPE_AI;
252 g->timelimit = BENCHMARK_TIMELIMIT*1000;
253 g->location = &(locations[0]);
254 gameloop(g);
255 free(g);
256 exit(0);
259 worldmap_xpos = (WIDTH-get_image_width(GR_WORLDMAP))/2;
260 worldmap_ypos = (HEIGHT-get_image_height(GR_WORLDMAP))/2;
262 i = 0;
263 /* Sliding initialization */
264 ticks = SDL_GetTicks();
265 slide = slide_start = get_image_width(GR_SIDEBAR);
266 slide_direction = 0;
267 while(!quit) {
268 /* State transitions */
269 switch (state) {
270 case MENU_STATE_STARTED:
271 state = MENU_STATE_SLIDE_TO_MAINMENU;
272 break;
273 case MENU_STATE_SLIDE_TO_MAINMENU:
274 clear_screen();
275 store_screen();
276 slide = slide_start;
277 slide_direction = -1;
278 state = MENU_STATE_SLIDE_TO_MAINMENU_IN_PROGRESS;
279 break;
280 case MENU_STATE_SLIDE_TO_MAINMENU_IN_PROGRESS:
281 if (slide == 0) {
282 slide_direction = 0;
283 state = MENU_STATE_MAINMENU;
285 break;
286 case MENU_STATE_MAINMENU:
287 free(prepared_game);
288 prepared_game = NULL;
289 break;
290 case MENU_STATE_SLIDE_TO_LOCATION:
291 slide = 1;
292 slide_direction = 3;
293 state = MENU_STATE_SLIDE_TO_LOCATION_IN_PROGRESS;
294 break;
295 case MENU_STATE_SLIDE_TO_LOCATION_IN_PROGRESS:
296 if (slide == slide_start) {
297 start_fade();
298 state = MENU_STATE_LOCATION;
300 break;
301 case MENU_STATE_FADE_TO_LOCATION:
302 start_fade();
303 state = MENU_STATE_LOCATION;
304 break;
305 case MENU_STATE_FADE_TO_OPTIONS:
306 clear_screen();
307 store_screen();
308 start_fade();
309 state = MENU_STATE_OPTIONS;
310 break;
311 case MENU_STATE_LOCATION:
312 clear_screen();
314 /* Draw and store the worldmap with day/night times */
315 show_image(GR_WORLDMAP, WIDTH/2-get_image_width(GR_WORLDMAP)/2, HEIGHT/2-get_image_height(GR_WORLDMAP)/2, 255);
316 day_night(get_image_width(GR_WORLDMAP), &night_start, &night_end);
317 if (night_start > night_end) {
318 rectangle_alpha(worldmap_xpos, worldmap_ypos, night_end, get_image_height(GR_WORLDMAP), 0, 0, 0, 150);
319 rectangle_alpha(worldmap_xpos+night_start, worldmap_ypos, get_image_width(GR_WORLDMAP)-night_start, 10, 0, 0, 0, 150);
320 } else {
321 rectangle_alpha(worldmap_xpos+night_start, worldmap_ypos, night_end-night_start, get_image_height(GR_WORLDMAP), 0, 0, 0, 150);
324 store_screen();
325 case MENU_STATE_OPTIONS:
326 /* Prepare a new game */
327 if (prepared_game == NULL) {
328 prepared_game = gamestate_new();
329 prepared_game->location = NULL;
330 btn_player1.text = "Keyboard (W-S-D)";
331 btn_player2.text = "Computer (AI)";
332 location_info_visible = false;
333 current_location = -1;
334 highlight_location = -1;
336 break;
337 case MENU_STATE_SLIDE_TO_GAME:
338 /*slide = 1;
339 slide_direction = 2;
340 state = MENU_STATE_SLIDE_TO_GAME_IN_PROGRESS;
341 break;
342 case MENU_STATE_SLIDE_TO_GAME_IN_PROGRESS:
343 if (slide == slide_start) {
344 state = MENU_STATE_GAME;
346 state = MENU_STATE_GAME;
347 break;
348 case MENU_STATE_SLIDE_TO_RESUME:
349 slide = 1;
350 slide_direction = 2;
351 state = MENU_STATE_SLIDE_TO_RESUME_IN_PROGRESS;
352 break;
353 case MENU_STATE_SLIDE_TO_RESUME_IN_PROGRESS:
354 if (slide == slide_start) {
355 state = MENU_STATE_RESUME;
357 break;
358 case MENU_STATE_GAME:
359 if (prepared_game == NULL) {
360 fprintf(stderr, "Game not yet prepared!\n");
361 exit(EXIT_FAILURE);
363 /* Set the day/night status */
364 if (night_start < night_end) {
365 prepared_game->night = (prepared_game->location->worldmap_x > night_start && prepared_game->location->worldmap_x < night_end);
366 } else {
367 prepared_game->night = (prepared_game->location->worldmap_x < night_end || prepared_game->location->worldmap_x > night_start);
370 /* Cancel a possibly started game */
371 free(current_game);
372 current_game = prepared_game;
373 prepared_game = NULL;
374 /* no break - we are continuing with "resume" */
375 case MENU_STATE_RESUME:
376 if (current_game == NULL) {
377 fprintf(stderr, "Cannot resume game!\n");
378 exit(EXIT_FAILURE);
380 start_fade();
381 gameloop(current_game);
382 SDL_Delay(150);
383 while(SDL_PollEvent(&e));
384 #ifdef ENABLE_FPS_LIMIT
385 frames = 0;
386 ft = SDL_GetTicks();
387 #endif
388 start_fade();
389 state = MENU_STATE_SLIDE_TO_MAINMENU;
390 break;
391 case MENU_STATE_SLIDE_TO_QUIT:
392 slide = 1;
393 slide_direction = 3;
394 state = MENU_STATE_SLIDE_TO_QUIT_IN_PROGRESS;
395 break;
396 case MENU_STATE_SLIDE_TO_QUIT_IN_PROGRESS:
397 if (slide == slide_start) {
398 state = MENU_STATE_QUIT;
400 break;
401 case MENU_STATE_QUIT:
402 quit = true;
403 break;
404 default:
405 fprintf(stderr, "State error: %d\n", state);
406 exit(EXIT_FAILURE);
409 /* Sliding */
410 if (SDL_GetTicks() > ticks + 20) {
411 if (slide >= 1 && slide <= slide_start) {
412 slide += slide_direction+(slide_direction*slide/(sqrt(2*slide)));
413 slide = MAX(0, MIN(slide_start, slide));
414 } else if (slide_direction != 0) {
415 slide_direction = 0;
417 ticks = SDL_GetTicks();
420 /* Graphics */
421 #ifdef DEBUG
422 if (state != MENU_STATE_OPTIONS) {
423 fill_image_offset(GR_FOG, 0, 0, WIDTH, HEIGHT, -i, 0);
425 #endif
426 show_image(GR_SIDEBAR, WIDTH-get_image_width(GR_SIDEBAR)+slide, 0, 255);
427 show_image(GR_TENNIXLOGO, WIDTH-get_image_width(GR_SIDEBAR)-10, 20-slide, 255);
428 if (state != MENU_STATE_OPTIONS && state != MENU_STATE_LOCATION) {
429 /* Main Menu */
430 show_image(GR_BTN_PLAY, WIDTH-get_image_width(GR_BTN_PLAY)+slide+(slide/7)+3-(3*(btn_hovering==MENU_START)), 150, 255);
431 if (current_game != NULL) {
432 show_image(GR_BTN_RESUME, WIDTH-get_image_width(GR_BTN_RESUME)+slide+(slide/7)+3-(3*(btn_hovering==MENU_RESUME)), 230, 255);
433 font_draw_string(GR_DKC2_FONT, "current match:", 10, 10, 0, 0);
434 font_draw_string(GR_DKC2_FONT, current_game->sets_score_str, 10, 40, 0, 0);
435 } else {
436 font_draw_string(GR_DKC2_FONT, "Tennix " VERSION, 10, 10, 0, 0);
438 font_draw_string(GR_DKC2_FONT, URL, 10, HEIGHT-10-get_image_height(GR_DKC2_FONT), 0, 0);
439 show_image(GR_BTN_QUIT, WIDTH-get_image_width(GR_BTN_QUIT)+slide+(slide/7)+3-(3*(btn_hovering==MENU_QUIT)), 350, 255);
440 } else if (state == MENU_STATE_OPTIONS) {
441 /* Options screen */
442 show_image(GR_TENNIXLOGO, WIDTH-get_image_width(GR_SIDEBAR)-10, 20, 255);
443 draw_button_object(btn_back, mx, my);
444 draw_button_object(btn_start, mx, my);
445 draw_button_object(btn_player1, mx, my);
446 draw_button_object(btn_player2, mx, my);
447 font_draw_string(GR_DKC2_FONT, "Player 1", btn_player1.x, btn_player1.y-MENU_OPTIONS_BORDER, 0, 0);
448 font_draw_string(GR_DKC2_FONT, "Player 2", btn_player2.x, btn_player2.y-MENU_OPTIONS_BORDER, 0, 0);
449 } else if (state == MENU_STATE_LOCATION) {
450 /* Location selection screen */
451 show_image(GR_TENNIXLOGO, WIDTH-get_image_width(GR_SIDEBAR)-10, 20, 255);
453 for (x=0; x<location_count(); x++) {
454 new_location_distance = SQUARE_DISTANCE(mx-worldmap_xpos-locations[x].worldmap_x,
455 my-worldmap_ypos-locations[x].worldmap_y);
456 if (highlight_location == -1) {
457 if (new_location_distance < 20*20) {
458 highlight_location = x;
460 } else {
461 highlight_location_distance = SQUARE_DISTANCE(mx-worldmap_xpos-locations[highlight_location].worldmap_x,
462 my-worldmap_ypos-locations[highlight_location].worldmap_y);
463 if (highlight_location_distance > 20*20) {
464 highlight_location = -1;
466 if (highlight_location_distance > new_location_distance && new_location_distance < 20*20) {
467 highlight_location = x;
471 if (!location_info_visible) {
472 for (x=0; x<location_count(); x++) {
473 /* draw rectangle for location at "x"*/
474 if (highlight_location != -1 && (unsigned int)highlight_location == x) {
475 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));
478 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);
481 font_draw_string(GR_DKC2_FONT, "Where do you want to play?", MENU_OPTIONS_BORDER, MENU_OPTIONS_BORDER, 0, 0);
482 if (prepared_game != NULL) {
483 if (location_info_visible) {
484 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);
485 font_draw_string(GR_DKC2_FONT, prepared_game->location->name, location_info_xpos+MENU_OPTIONS_BORDER, location_info_ypos+MENU_OPTIONS_BORDER+200, 0, 0);
486 font_draw_string(GR_DKC2_FONT, prepared_game->location->area, location_info_xpos+MENU_OPTIONS_BORDER, location_info_ypos+MENU_OPTIONS_BORDER+200+get_image_height(GR_DKC2_FONT), 0, 0);
487 font_draw_string(GR_DKC2_FONT, prepared_game->location->city, location_info_xpos+MENU_OPTIONS_BORDER, location_info_ypos+MENU_OPTIONS_BORDER+200+2*get_image_height(GR_DKC2_FONT), 0, 0);
488 font_draw_string(GR_DKC2_FONT, prepared_game->location->court_type_name, location_info_xpos+MENU_OPTIONS_BORDER, location_info_ypos+MENU_OPTIONS_BORDER+200+4*get_image_height(GR_DKC2_FONT), 0, 0);
490 if (prepared_game->location != NULL) {
491 draw_button_object(btn_start, mx, my);
494 draw_button_object(btn_back, mx, my);
497 SDL_PollEvent( &e);
498 if( e.type == SDL_QUIT) {
499 state = MENU_STATE_SLIDE_TO_QUIT;
500 /*break;*/
503 keys = SDL_GetKeyState( NULL);
504 mb = SDL_GetMouseState( &mx, &my);
506 btn_hovering_old = btn_hovering;
507 if (state == MENU_STATE_MAINMENU) {
508 btn_hovering = M_POS_DECODE(mx, my);
509 if (current_game == NULL) {
510 btn_hovering &= ~MENU_RESUME;
512 } else if (state == MENU_STATE_LOCATION) {
513 if (M_POS_BUTTON(btn_back, mx, my)) {
514 btn_hovering = MENU_QUIT;
515 } else if (M_POS_BUTTON(btn_start, mx, my)) {
516 btn_hovering = MENU_START;
517 } else {
518 btn_hovering = 0;
520 } else if (state == MENU_STATE_OPTIONS) {
521 if (M_POS_BUTTON(btn_back, mx, my)) {
522 btn_hovering = MENU_QUIT;
523 } else if (M_POS_BUTTON(btn_start, mx, my)) {
524 btn_hovering = MENU_START;
525 } else if (M_POS_BUTTON(btn_player1, mx, my)) {
526 btn_hovering = MENU_PLAYER1;
527 } else if (M_POS_BUTTON(btn_player2, mx, my)) {
528 btn_hovering = MENU_PLAYER2;
529 } else {
530 btn_hovering = 0;
532 } else {
533 /* No menu screen - no hovering. */
534 btn_hovering = 0;
536 #ifndef MAEMO /* On Maemo, we cannot really "hover" (touchscreen!) */
537 if (btn_hovering_old != btn_hovering && btn_hovering != 0) {
538 #ifdef HAVE_VOICE_FILES
539 if (btn_hovering == MENU_QUIT) {
540 play_sample(VOICE_QUIT_IT);
541 } else if (btn_hovering == MENU_START) {
542 play_sample(VOICE_NEW_GAME);
543 } else {
544 play_sample(SOUND_MOUSEOVER);
546 #else
547 play_sample(SOUND_MOUSEOVER);
548 #endif
550 #endif
552 if( keys[SDLK_ESCAPE] || keys['q']) {
553 /* FIXME: do the state thingie! */
554 break;
557 if( keys['f']) {
558 SDL_WM_ToggleFullScreen( screen);
561 #ifndef MAEMO /* No mouse cursor on Maemo (we have a touchscreen) */
562 if (state == MENU_STATE_MAINMENU || state == MENU_STATE_OPTIONS || state == MENU_STATE_LOCATION) {
563 show_image(GR_CURSOR, mx-2, my-1, 255);
565 #endif
567 /* Draw the "real" mouse coordinates */
568 /*rectangle(mx-1, my-1, 2, 2, 255, 255, 255);*/
570 /* Store the screen, because we are fading after this screen update */
571 /*if (!(mb & SDL_BUTTON(SDL_BUTTON_LEFT)) && btn_hovering != MENU_NONE && mouse_pressed == true) store_screen();*/
573 updatescr();
575 if( mb & SDL_BUTTON(SDL_BUTTON_LEFT)) {
576 mouse_pressed = true;
577 } else if (mouse_pressed == true) {
578 /* Mouse button released */
579 if (state == MENU_STATE_MAINMENU || state == MENU_STATE_OPTIONS || state == MENU_STATE_LOCATION) {
580 #ifdef HAVE_VOICE_FILES
581 if (btn_hovering == MENU_START) {
582 play_sample(VOICE_LETS_GO);
583 } else {
584 play_sample(SOUND_MOUSECLICK);
586 #else
587 play_sample(SOUND_MOUSECLICK);
588 #endif
590 if (state == MENU_STATE_MAINMENU) {
591 switch (btn_hovering) {
592 case MENU_START:
593 state = MENU_STATE_SLIDE_TO_LOCATION;
594 break;
595 case MENU_RESUME:
596 state = MENU_STATE_SLIDE_TO_RESUME;
597 break;
598 case MENU_QUIT:
599 state = MENU_STATE_SLIDE_TO_QUIT;
600 break;
602 } else if (state == MENU_STATE_LOCATION) {
603 switch (btn_hovering) {
604 case MENU_START:
605 if (prepared_game->location != NULL) {
606 state = MENU_STATE_FADE_TO_OPTIONS;
608 break;
609 case MENU_QUIT:
610 state = MENU_STATE_SLIDE_TO_MAINMENU;
611 break;
612 default:
613 if (!location_info_visible && highlight_location != -1) {
614 current_location = highlight_location;
615 prepared_game->location = &(locations[current_location]);
616 location_info_xpos = MAX(0, MIN(WIDTH-320-50, mx-320/2));
617 location_info_ypos = MAX(0, MIN(HEIGHT-200-160, my-200/2));
618 location_info_visible = true;
619 } else {
620 location_info_visible = false;
621 current_location = -1;
622 highlight_location = -1;
623 prepared_game->location = NULL;
625 break;
627 } else if (state == MENU_STATE_OPTIONS) {
628 switch (btn_hovering) {
629 case MENU_START:
630 state = MENU_STATE_SLIDE_TO_GAME;
631 break;
632 case MENU_QUIT:
633 state = MENU_STATE_FADE_TO_LOCATION;
634 break;
635 case MENU_PLAYER1:
636 switch (PLAYER(prepared_game, 1).type) {
637 case PLAYER_TYPE_HUMAN:
638 PLAYER(prepared_game, 1).type = PLAYER_TYPE_AI;
639 btn_player1.text = "Computer (AI)";
640 break;
641 case PLAYER_TYPE_AI:
642 PLAYER(prepared_game, 1).type = PLAYER_TYPE_HUMAN;
643 btn_player1.text = "Keyboard (W-S-D)";
644 break;
646 break;
647 case MENU_PLAYER2:
648 switch (PLAYER(prepared_game, 2).type) {
649 case PLAYER_TYPE_HUMAN:
650 PLAYER(prepared_game, 2).type = PLAYER_TYPE_AI;
651 btn_player2.text = "Computer (AI)";
652 break;
653 case PLAYER_TYPE_AI:
654 PLAYER(prepared_game, 2).type = PLAYER_TYPE_HUMAN;
655 btn_player2.text = "Keyboard (O-L-K)";
656 break;
658 break;
661 mouse_pressed = false;
663 i++;
664 #ifdef ENABLE_FPS_LIMIT
665 while (frames*1000.0/((float)(SDL_GetTicks()-ft+1))>(float)(DEFAULT_FPS)) {
666 SDL_Delay(10);
668 frames++;
669 #endif
672 uninit_graphics();
673 uninit_joystick();
675 SDL_Quit();
676 return 0;