// $Id: gamemanager.cc,v 1.9 2006/08/28 15:23:14 matthew Exp $ // Fish Supper // Copyright (C) 2006 Matthew Clarke // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. #include "gamemanager.h" #include #include // ******************* // *** CONSTRUCTOR *** // ******************* FS::GameManager::GameManager(SDL_Surface * s) : ts_display(s), gr_display(s), p_display(s), s_display(s, &my_settings) { screen = s; current_state = INTRO; p_model.init_sprite_manager(&p_display, &snd_engine); snd_engine.turn_on( my_settings.is_sound() ); } // FS::GameManager::GameManager() // ****************** // *** DESTRUCTOR *** // ****************** FS::GameManager::~GameManager() { // ... } // FS::GameManager::~GameManager() // ************************ // *** MEMBER FUNCTIONS *** // ************************ // ************************************************** void FS::GameManager::start_loop() { SDL_Event event; my_key_event = NONE; loop_running = true; int i; // used in some of 'while' loops below key_down = false; // Stores return val from GetReadyDisplay::redraw_level_select. int start_level; pause_menu_needs_erasing = false; // Before we enter the loop, display the title screen ts_display.redraw(); while (loop_running) { num_key_events = num_key_downs = 0; while ( SDL_PollEvent(&event) ) { switch (event.type) { case SDL_KEYDOWN: if ( current_state == ENTERING_NAME ) { my_key_downs[num_key_downs++] = event.key.keysym; break; } // if // allow 'fall-through' case SDL_KEYUP: case SDL_JOYAXISMOTION: case SDL_JOYBUTTONDOWN: analyse_event(&event); break; case SDL_QUIT: loop_running = false; break; } // switch } // while switch (current_state) { case INTRO: if ( num_key_events ) { handle_selection( ts_display.update(my_key_events, num_key_events) ); } // if break; case SELECTING_START_LEVEL: start_level = gr_display.redraw_level_select(my_key_events, num_key_events, my_settings.get_furthest_level()); if (start_level) { current_state = GET_READY; p_model.new_game(start_level); gr_display.start_draw( timer.get_time(), p_model.get_level() ); } // if break; case GET_READY: if ( gr_display.redraw(timer.get_time(), my_key_events, num_key_events) ) { // start play display current_state = PLAY; p_model.new_level(timer.get_time()); p_display.reset(); } // if break; case PLAY: i = 0; while ( i < num_key_events ) { if ( my_key_events[i] == ESCAPE_PRESSED && timer.is_running() ) { timer.pause(); snd_engine.pause_all_sounds(); my_pause_menu.reset(); } else if (!timer.is_running()) { switch ( my_pause_menu.update(my_key_events, num_key_events) ) { case PauseMenu::PMS_NONE: break; case PauseMenu::PMS_CONTINUE: timer.pause(); snd_engine.resume_all_sounds(); // ensure we break out of loop num_key_events = 0; // menu needs erasing from display pause_menu_needs_erasing = true; break; case PauseMenu::PMS_QUIT: current_state = INTRO; ts_display.redraw(); // make sure timer is running timer.resume(); num_key_events = 0; break; } // switch } // if ... else ++i; } // while if ( current_state == PLAY ) { switch ( p_model.update(timer.get_time(), my_key_events, num_key_events, timer.is_running()) ) { case PR_OK: if (!timer.is_running()) { p_display.request_draw_pause_menu( my_pause_menu.get_image_id() ); } else if (pause_menu_needs_erasing) { p_display.request_erase_pause_menu(); pause_menu_needs_erasing = false; } // if ... else p_display.redraw(); break; case PR_LEVEL_COMPLETED: current_state = GET_READY; gr_display.start_draw( timer.get_time(), p_model.get_level() ); break; case PR_GAME_OVER: my_settings.set_furthest_level(p_model.get_level()); if ( hs_display.check_candidate(p_model.get_score()) ) { current_state = ENTERING_NAME; hs_display.init_input(p_model.get_score(), screen); } else { current_state = INTRO; ts_display.redraw(); } // if ... else break; } // switch } // if break; case SETTINGS: // No point calling redraw() if there was no key event... if ( num_key_events && s_display.redraw(my_key_events, num_key_events) ) { snd_engine.turn_on( my_settings.is_sound() ); current_state = INTRO; ts_display.redraw(); } // if break; case HI_SCORES: i = 0; while (i < num_key_events) { if ( my_key_events[i] == ESCAPE_PRESSED || my_key_events[i] == JUMP_KEY_PRESSED ) { current_state = INTRO; ts_display.redraw(); } // if ++i; } // while break; case ENTERING_NAME: if ( num_key_downs && hs_display.input(my_key_downs, num_key_downs, screen) ) { current_state = HI_SCORES; hs_display.show_high_scores(screen); } // if /* if (key_down) { if ( hs_display.input(event.key.keysym, screen) ) { current_state = HI_SCORES; hs_display.show_high_scores(screen); } // if } // if */ break; } // switch SDL_Delay(10); // 100 fps // IMPORTANT!!! Clear my_key_event! my_key_event = NONE; key_down = false; } // while my_settings.write_config_file(); hs_display.write_high_scores(); } // FS::GameManager::start_loop() // ************************************************** void FS::GameManager::analyse_event(const SDL_Event * event) { bool joystick_selected = my_settings.is_joystick_selected(); if (event->type == SDL_KEYDOWN) { if (event->key.keysym.sym == SDLK_ESCAPE) { my_key_event = ESCAPE_PRESSED; } else if (event->key.keysym.sym == SDLK_p) { my_key_event = PAUSE_KEY_PRESSED; } else if ( !joystick_selected ) { if (event->key.keysym.sym == SDLK_UP) { my_key_event = UP_KEY_PRESSED; } else if (event->key.keysym.sym == SDLK_RIGHT) { my_key_event = RIGHT_KEY_PRESSED; } else if (event->key.keysym.sym == SDLK_DOWN) { my_key_event = DOWN_KEY_PRESSED; } else if (event->key.keysym.sym == SDLK_LEFT) { my_key_event = LEFT_KEY_PRESSED; } else if (event->key.keysym.sym == SDLK_SPACE) { my_key_event = JUMP_KEY_PRESSED; } // if ... else } // if ... else } else if ( (!joystick_selected) && (event->type == SDL_KEYUP) ) { if (event->key.keysym.sym == SDLK_UP) { my_key_event = UP_KEY_RELEASED; } else if (event->key.keysym.sym == SDLK_RIGHT) { my_key_event = RIGHT_KEY_RELEASED; } else if (event->key.keysym.sym == SDLK_DOWN) { my_key_event = DOWN_KEY_RELEASED; } else if (event->key.keysym.sym == SDLK_LEFT) { my_key_event = LEFT_KEY_RELEASED; } // if ... else } else if ( joystick_selected && (event->type == SDL_JOYAXISMOTION) ) { if ( event->jaxis.axis == 0 ) // left/right { if ( event->jaxis.value < -3200 ) { my_key_event = last_horizontal = LEFT_KEY_PRESSED; } else if ( !event->jaxis.value ) { my_key_event = (last_horizontal == LEFT_KEY_PRESSED) ? LEFT_KEY_RELEASED : RIGHT_KEY_RELEASED; } else if ( event->jaxis.value > 3200 ) { my_key_event = last_horizontal = RIGHT_KEY_PRESSED; } // if ... else } else if ( event->jaxis.axis == 1 ) { if ( event->jaxis.value < -3200 ) { my_key_event = last_vertical = UP_KEY_PRESSED; } else if ( !event->jaxis.value ) { my_key_event = (last_vertical == UP_KEY_PRESSED) ? UP_KEY_RELEASED : DOWN_KEY_RELEASED; } else if ( event->jaxis.value > 3200 ) { my_key_event = last_vertical = DOWN_KEY_PRESSED; } // if ... else } // if ... else } else if (joystick_selected && event->type == SDL_JOYBUTTONDOWN) { my_key_event = JUMP_KEY_PRESSED; } // if ... else my_key_events[num_key_events++] = my_key_event; } // FS::GameManager::analyse_event() // ************************************************** void FS::GameManager::handle_selection(TitleScreenDisplay::Selection sel) { switch (sel) { case TitleScreenDisplay::NONE: break; case TitleScreenDisplay::PLAY: if (my_settings.get_furthest_level() > 1) { current_state = SELECTING_START_LEVEL; gr_display.start_draw_level_select(my_settings.get_furthest_level()); } else { current_state = GET_READY; p_model.new_game(); gr_display.start_draw( timer.get_time(), p_model.get_level() ); } // if ... else break; case TitleScreenDisplay::SETTINGS: current_state = SETTINGS; s_display.start_draw(); break; case TitleScreenDisplay::HI_SCORES: current_state = HI_SCORES; hs_display.show_high_scores(screen); break; case TitleScreenDisplay::QUIT: loop_running = false; break; } // switch } // FS::GameManager::handle_selection() // ************************************************** // ************************************************** // ************************************************** // ************************************************** // **************************************************