X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fgameloop.cpp;h=4c2bfd2ccbea99a759cbfd8d1349317ad5168939;hb=6e85c29076267d353d426427bdb64c0684297d01;hp=68d986924f60d41941c6f3c3212e0f7e5c6c4519;hpb=7adc9ba6b26922c1d41443d6a5f2da324c83db2d;p=supertux.git diff --git a/src/gameloop.cpp b/src/gameloop.cpp index 68d986924..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,80 +47,48 @@ GameSession* GameSession::current_ = 0; -void -GameSession::init() -{ - game_pause = false; -} - -GameSession::GameSession() +GameSession::GameSession(const std::string& subset_, int levelnb_, int mode) + : world(0), st_gl_mode(mode), levelnb(levelnb_), subset(subset_) { current_ = this; - assert(0); + restart_level(); } -GameSession::GameSession(const std::string& filename) -{ - init(); - - //assert(!"Don't call me"); - current_ = this; - - world = new World; - - fps_timer.init(true); - frame_timer.init(true); - - world->load(filename); -} - -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(); - - if(st_gl_mode == ST_GL_LOAD_GAME) - loadgame(levelnb); + start_timers(); } GameSession::~GameSession() @@ -130,23 +99,19 @@ GameSession::~GameSession() void GameSession::levelintro(void) { - Player& tux = *world->get_tux(); - char str[60]; /* 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, 224, A_HMIDDLE, A_TOP, 1); + sprintf(str, "by %s", world->get_level()->author.c_str()); - red_text->drawf(str, 0, 256, A_HMIDDLE, A_TOP, 1); + white_small_text->drawf(str, 0, 400, A_HMIDDLE, A_TOP, 1); - sprintf(str, "TUX x %d", tux.lives); - white_text->drawf(str, 0, 288, A_HMIDDLE, A_TOP, 1); flipscreen(); @@ -164,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(); @@ -172,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; @@ -190,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; @@ -223,7 +195,7 @@ GameSession::process_events() switch(key) { case SDLK_p: - if(!show_menu) + if(!Menu::current()) { if(game_pause) { @@ -253,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; @@ -267,7 +235,7 @@ GameSession::process_events() break; case SDLK_l: if(debug_mode) - --tux.lives; + --player_status.lives; break; case SDLK_s: if(debug_mode) @@ -322,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: @@ -339,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!? */ - - if (tux.lives < 0) - { + 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 @@ -452,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(); } @@ -462,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; @@ -493,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()) { @@ -509,62 +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: - update_load_save_game_menu(save_game_menu, false); - break; - case 4: - update_load_save_game_menu(load_game_menu, true); - 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 == save_game_menu ) - { - process_save_game_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 { @@ -586,7 +497,7 @@ GameSession::run() draw(); /* Time stops in pause mode */ - if(game_pause || show_menu ) + if(game_pause || Menu::current()) { continue; } @@ -610,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) @@ -640,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: */ @@ -658,7 +566,6 @@ void bumpbrick(float x, float y) void GameSession::drawstatus() { - Player& tux = *world->get_tux(); char str[60]; sprintf(str, "%d", player_status.score); @@ -696,7 +603,7 @@ GameSession::drawstatus() gold_text->draw(str, screen->h + 60, 40, 1); } - for(int i= 0; i < tux.lives; ++i) + for(int i= 0; i < player_status.lives; ++i) { tux_life->draw(565+(18*i),20); } @@ -714,7 +621,7 @@ GameSession::drawendscreen() sprintf(str, "SCORE: %d", player_status.score); gold_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1); - sprintf(str, "DISTROS: %d", player_status.distros); + sprintf(str, "COINS: %d", player_status.distros); gold_text->drawf(str, 0, 256, A_HMIDDLE, A_TOP, 1); flipscreen(); @@ -744,129 +651,18 @@ GameSession::drawresultscreen(void) wait_for_event(event,2000,5000,true); } -void -GameSession::savegame(int) -{ -#if 0 - char savefile[1024]; - FILE* fi; - unsigned int ui; - - sprintf(savefile,"%s/slot%d.save",st_save_dir,slot); - - fi = fopen(savefile, "wb"); - - if (fi == NULL) - { - fprintf(stderr, "Warning: I could not open the slot file "); - } - else - { - fputs(level_subset, fi); - fputs("\n", fi); - fwrite(&level,sizeof(int),1,fi); - fwrite(&score,sizeof(int),1,fi); - fwrite(&distros,sizeof(int),1,fi); - fwrite(&scroll_x,sizeof(float),1,fi); - //FIXME:fwrite(&tux,sizeof(Player),1,fi); - //FIXME:timer_fwrite(&tux.invincible_timer,fi); - //FIXME:timer_fwrite(&tux.skidding_timer,fi); - //FIXME:timer_fwrite(&tux.safe_timer,fi); - //FIXME:timer_fwrite(&tux.frame_timer,fi); - timer_fwrite(&time_left,fi); - ui = st_get_ticks(); - fwrite(&ui,sizeof(int),1,fi); - } - fclose(fi); -#endif -} - -void -GameSession::loadgame(int) -{ -#if 0 - char savefile[1024]; - char str[100]; - FILE* fi; - unsigned int ui; - - sprintf(savefile,"%s/slot%d.save",st_save_dir,slot); - - fi = fopen(savefile, "rb"); - - if (fi == NULL) - { - fprintf(stderr, "Warning: I could not open the slot file "); - - } - else - { - fgets(str, 100, fi); - strcpy(level_subset, str); - level_subset[strlen(level_subset)-1] = '\0'; - fread(&level,sizeof(int),1,fi); - - world->set_defaults(); - world->get_level()->cleanup(); - world->arrays_free(); - world->get_level()->free_gfx(); - world->get_level()->free_song(); - - if(world->get_level()->load(level_subset,level) != 0) - exit(1); - - world->activate_bad_guys(); - world->activate_particle_systems(); - world->get_level()->load_gfx(); - world->get_level()->load_song(); - - levelintro(); - update_time = st_get_ticks(); - - fread(&score, sizeof(int),1,fi); - fread(&distros, sizeof(int),1,fi); - fread(&scroll_x,sizeof(float),1,fi); - //FIXME:fread(&tux, sizeof(Player), 1, fi); - //FIXME:timer_fread(&tux.invincible_timer,fi); - //FIXME:timer_fread(&tux.skidding_timer,fi); - //FIXME:timer_fread(&tux.safe_timer,fi); - //FIXME:timer_fread(&tux.frame_timer,fi); - timer_fread(&time_left,fi); - fread(&ui,sizeof(int),1,fi); - fclose(fi); - } -#endif -} - std::string slotinfo(int slot) { - FILE* fi; + char tmp[1024]; char slotfile[1024]; - char tmp[200]; - char str[5]; - int slot_level; - sprintf(slotfile,"%s/slot%d.save",st_save_dir,slot); - - fi = fopen(slotfile, "rb"); - - sprintf(tmp,"Slot %d - ",slot); + sprintf(slotfile,"%s/slot%d.stsg",st_save_dir,slot); - if (fi == NULL) - { - strcat(tmp,"Free"); - } + if (access(slotfile, F_OK) == 0) + sprintf(tmp,"Slot %d - Savegame",slot); else - { - fgets(str, 100, fi); - str[strlen(str)-1] = '\0'; - strcat(tmp, str); - strcat(tmp, " / Level:"); - fread(&slot_level,sizeof(int),1,fi); - sprintf(str,"%d",slot_level); - strcat(tmp,str); - fclose(fi); - } + sprintf(tmp,"Slot %d - Free",slot); return tmp; } +