X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fgameloop.cpp;h=4c2bfd2ccbea99a759cbfd8d1349317ad5168939;hb=6e85c29076267d353d426427bdb64c0684297d01;hp=cb91373990768e1949f1b62fd1bdb7f803b0e01b;hpb=e7978bb4f7e4ca74b29dcad75c72303e78fc323b;p=supertux.git diff --git a/src/gameloop.cpp b/src/gameloop.cpp index cb9137399..4c2bfd2cc 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -10,6 +10,7 @@ April 11, 2000 - March 15, 2004 */ +#include #include #include #include @@ -46,77 +47,48 @@ GameSession* GameSession::current_ = 0; -void -GameSession::init() -{ - game_pause = false; -} - -GameSession::GameSession() -{ - current_ = this; - assert(0); -} - -GameSession::GameSession(const std::string& filename) +GameSession::GameSession(const std::string& subset_, int levelnb_, int mode) + : world(0), st_gl_mode(mode), levelnb(levelnb_), subset(subset_) { - init(); - - //assert(!"Don't call me"); current_ = this; - - world = new World; - - fps_timer.init(true); - frame_timer.init(true); - - world->load(filename); + restart_level(); } -GameSession::GameSession(const std::string& subset_, int levelnb_, int mode) - : subset(subset_), - levelnb(levelnb_) +void +GameSession::restart_level() { - init(); - - current_ = this; - - world = new World; + game_pause = false; + exit_status = NONE; fps_timer.init(true); frame_timer.init(true); - st_gl_mode = mode; - - /* Init the game: */ - world->arrays_free(); - world->set_defaults(); + delete world; if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE) { - if (world->load(subset)) - exit(1); + world = new World(subset); + } + else if (st_gl_mode == ST_GL_DEMO_GAME) + { + world = new World(subset); } else { - if(world->load(subset, levelnb) != 0) - exit(1); + world = new World(subset, levelnb); } + + if (st_gl_mode != ST_GL_DEMO_GAME) + { + if(st_gl_mode != ST_GL_TEST) + load_hs(); - world->get_level()->load_gfx(); - - world->activate_bad_guys(); - world->activate_particle_systems(); - world->get_level()->load_song(); - - if(st_gl_mode != ST_GL_TEST) - load_hs(); - - if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE) - levelintro(); + if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE) + levelintro(); + } time_left.init(true); - start_timers(); + start_timers(); } GameSession::~GameSession() @@ -131,14 +103,11 @@ GameSession::levelintro(void) /* Level Intro: */ clearscreen(0, 0, 0); - sprintf(str, "LEVEL %d", levelnb); - blue_text->drawf(str, 0, 200, A_HMIDDLE, A_TOP, 1); - sprintf(str, "%s", world->get_level()->name.c_str()); - gold_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1); + gold_text->drawf(str, 0, 200, A_HMIDDLE, A_TOP, 1); sprintf(str, "TUX x %d", player_status.lives); - white_text->drawf(str, 0, 256, A_HMIDDLE, A_TOP, 1); + white_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1); sprintf(str, "by %s", world->get_level()->author.c_str()); white_small_text->drawf(str, 0, 400, A_HMIDDLE, A_TOP, 1); @@ -160,6 +129,28 @@ GameSession::start_timers() } void +GameSession::on_escape_press() +{ + if(!game_pause) + { + if(st_gl_mode == ST_GL_TEST) + { + exit_status = LEVEL_ABORT; + } + else if (!Menu::current()) + { + Menu::set_current(game_menu); + st_pause_ticks_stop(); + } + else + { + Menu::set_current(NULL); + st_pause_ticks_start(); + } + } +} + +void GameSession::process_events() { Player& tux = *world->get_tux(); @@ -168,14 +159,15 @@ GameSession::process_events() while (SDL_PollEvent(&event)) { /* Check for menu-events, if the menu is shown */ - if(show_menu) - current_menu->event(event); + if (Menu::current()) + Menu::current()->event(event); switch(event.type) { case SDL_QUIT: /* Quit event - quit: */ - quit = true; + st_abort("Received window close", ""); break; + case SDL_KEYDOWN: /* A keypress! */ { SDLKey key = event.key.keysym.sym; @@ -186,23 +178,7 @@ GameSession::process_events() switch(key) { case SDLK_ESCAPE: /* Escape: Open/Close the menu: */ - if(!game_pause) - { - if(st_gl_mode == ST_GL_TEST) - quit = true; - else if(show_menu) - { - Menu::set_current(game_menu); - show_menu = 0; - st_pause_ticks_stop(); - } - else - { - Menu::set_current(game_menu); - show_menu = 1; - st_pause_ticks_start(); - } - } + on_escape_press(); break; default: break; @@ -219,7 +195,7 @@ GameSession::process_events() switch(key) { case SDLK_p: - if(!show_menu) + if(!Menu::current()) { if(game_pause) { @@ -249,10 +225,6 @@ GameSession::process_events() if(debug_mode) player_status.distros += 50; break; - case SDLK_SPACE: - if(debug_mode) - player_status.next_level = 1; - break; case SDLK_DELETE: if(debug_mode) tux.got_coffee = 1; @@ -318,13 +290,14 @@ GameSession::process_events() tux.input.up = DOWN; else if (event.jbutton.button == JOY_B) tux.input.fire = DOWN; + else if (event.jbutton.button == JOY_START) + on_escape_press(); break; case SDL_JOYBUTTONUP: if (event.jbutton.button == JOY_A) tux.input.up = UP; else if (event.jbutton.button == JOY_B) tux.input.fire = UP; - break; default: @@ -335,100 +308,58 @@ GameSession::process_events() } /* while */ } -int -GameSession::action(double frame_ratio) + +void +GameSession::check_end_conditions() { - Player& tux = *world->get_tux(); + Player* tux = world->get_tux(); - if (tux.is_dead() || player_status.next_level) + /* End of level? */ + if (tux->base.x >= World::current()->get_level()->endpos + && World::current()->get_level()->endpos != 0) { - /* Tux either died, or reached the end of a level! */ - halt_music(); - - if (player_status.next_level) - { - /* End of a level! */ - levelnb++; - player_status.next_level = 0; - if(st_gl_mode != ST_GL_TEST) - { - drawresultscreen(); - } - else - { - world->get_level()->free_gfx(); - world->get_level()->cleanup(); - world->get_level()->free_song(); - world->arrays_free(); - - return(0); - } - tux.level_begin(); - } - else + exit_status = LEVEL_FINISHED; + } + else + { + // Check End conditions + if (tux->is_dead()) { - tux.is_dying(); - - /* No more lives!? */ - + player_status.lives -= 1; + if (player_status.lives < 0) - { + { // No more lives!? if(st_gl_mode != ST_GL_TEST) drawendscreen(); - + if(st_gl_mode != ST_GL_TEST) { - if (player_status.score > hs_score) - save_hs(player_status.score); + // FIXME: highscore soving doesn't make sense in its + // current form + //if (player_status.score > hs_score) + //save_hs(player_status.score); } - - world->get_level()->free_gfx(); - world->get_level()->cleanup(); - world->get_level()->free_song(); - world->arrays_free(); - - return(0); - } /* if (lives < 0) */ - } - - /* Either way, (re-)load the (next) level... */ - tux.level_begin(); - world->set_defaults(); - - world->get_level()->cleanup(); - - if (st_gl_mode == ST_GL_LOAD_LEVEL_FILE) - { - if(world->get_level()->load(subset) != 0) - return 0; - } - else - { - if(world->get_level()->load(subset, levelnb) != 0) - return 0; + + exit_status = GAME_OVER; + } + else + { // Still has lives, so reset Tux to the levelstart + restart_level(); + } } + } +} - world->arrays_free(); - world->activate_bad_guys(); - world->activate_particle_systems(); - - world->get_level()->free_gfx(); - world->get_level()->load_gfx(); - world->get_level()->free_song(); - world->get_level()->load_song(); - - if(st_gl_mode != ST_GL_TEST) - levelintro(); - start_timers(); - /* Play music: */ - play_current_music(); +void +GameSession::action(double frame_ratio) +{ + check_end_conditions(); + + if (exit_status == NONE) + { + // Update Tux and the World + world->action(frame_ratio); } - - tux.action(frame_ratio); - - world->action(frame_ratio); - - return -1; } void @@ -448,9 +379,10 @@ GameSession::draw() blue_text->drawf("PAUSE - Press 'P' To Play", 0, 230, A_HMIDDLE, A_TOP, 1); } - if(show_menu) + if(Menu::current()) { - menu_process_current(); + Menu::current()->action(); + Menu::current()->draw(); mouse_cursor->draw(); } @@ -458,14 +390,13 @@ GameSession::draw() } -int +GameSession::ExitStatus GameSession::run() { - Player& tux = *world->get_tux(); + Player* tux = world->get_tux(); current_ = this; int fps_cnt; - bool done; global_frame_counter = 0; game_pause = false; @@ -489,14 +420,11 @@ GameSession::run() draw(); - done = false; - quit = false; - while (!done && !quit) + float overlap = 0.0f; + while (exit_status == NONE) { /* Calculate the movement-factor */ double frame_ratio = ((double)(update_time-last_update_time))/((double)FRAME_RATE); - if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */ - frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85; if(!frame_timer.check()) { @@ -505,59 +433,49 @@ GameSession::run() } /* Handle events: */ - tux.input.old_fire = tux.input.fire; + tux->input.old_fire = tux->input.fire; process_events(); - if(show_menu) + if(Menu::current()) { - if(current_menu == game_menu) + if(Menu::current() == game_menu) { switch (game_menu->check()) { case 2: st_pause_ticks_stop(); break; - case 3: - // FIXME: - //update_load_save_game_menu(save_game_menu); - break; - case 4: - update_load_save_game_menu(load_game_menu); - break; - case 7: + case 5: st_pause_ticks_stop(); - done = true; + exit_status = LEVEL_ABORT; break; } } - else if(current_menu == options_menu) + else if(Menu::current() == options_menu) { process_options_menu(); } - else if(current_menu == load_game_menu ) + else if(Menu::current() == load_game_menu ) { process_load_game_menu(); } } - - - /* Handle actions: */ - - if(!game_pause && !show_menu) + + // Handle actions: + if(!game_pause && !Menu::current()) { - /*float z = frame_ratio; - frame_ratio = 1; - while(z >= 1) - {*/ - if (action(frame_ratio) == 0) + frame_ratio *= game_speed; + frame_ratio += overlap; + while (frame_ratio > 0) { - /* == 0: no more lives */ - /* == -1: continues */ - return 0; + action(1.0f); + frame_ratio -= 1.0f; } - /* --z; - }*/ + overlap = frame_ratio; + + if (exit_status != NONE) + return exit_status; } else { @@ -579,7 +497,7 @@ GameSession::run() draw(); /* Time stops in pause mode */ - if(game_pause || show_menu ) + if(game_pause || Menu::current()) { continue; } @@ -603,15 +521,14 @@ GameSession::run() { /* are we low on time ? */ if (time_left.get_left() < TIME_WARNING - && (get_current_music() != HURRYUP_MUSIC)) /* play the fast music */ + && (get_current_music() != HURRYUP_MUSIC)) /* play the fast music */ { set_current_music(HURRYUP_MUSIC); play_current_music(); } - } - else if(tux.dying == DYING_NOT) - tux.kill(KILL); + else if(tux->dying == DYING_NOT) + tux->kill(KILL); /* Calculate frames per second */ if(show_fps) @@ -633,9 +550,7 @@ GameSession::run() world->get_level()->cleanup(); world->get_level()->free_song(); - world->arrays_free(); - - return quit; + return exit_status; } /* Bounce a brick: */