X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fgameloop.cpp;h=5e860225f50e6ff5bea266ae5d3bfc55209d9e8f;hb=820473dd8331f9c8949f0d492162fa9d1860ca90;hp=e111f68f6f82fc24974d0b324ee5b6e4329c7566;hpb=9049bc39abe1375659584ed8cf950faf8b6a5145;p=supertux.git diff --git a/src/gameloop.cpp b/src/gameloop.cpp index e111f68f6..5e860225f 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() -{ - 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(); - - if(st_gl_mode == ST_GL_LOAD_GAME) - loadgame(levelnb); + start_timers(); } GameSession::~GameSession() @@ -130,20 +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); - text_drawf(&blue_text, str, 0, 200, A_HMIDDLE, A_TOP, 1); - sprintf(str, "%s", world->get_level()->name.c_str()); - text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1); + gold_text->drawf(str, 0, 200, A_HMIDDLE, A_TOP, 1); - sprintf(str, "TUX x %d", tux.lives); - text_drawf(&white_text, str, 0, 256, 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()); + white_small_text->drawf(str, 0, 400, A_HMIDDLE, A_TOP, 1); + flipscreen(); @@ -169,14 +137,14 @@ GameSession::process_events() while (SDL_PollEvent(&event)) { /* Check for menu-events, if the menu is shown */ - if(show_menu) - current_menu->event(event); + current_menu->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,8 +158,10 @@ GameSession::process_events() if(!game_pause) { if(st_gl_mode == ST_GL_TEST) - quit = true; - else if(show_menu) + { + exit_status = LEVEL_ABORT; + } + else if(!show_menu) { Menu::set_current(game_menu); show_menu = 0; @@ -250,10 +220,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; @@ -264,7 +230,7 @@ GameSession::process_events() break; case SDLK_l: if(debug_mode) - --tux.lives; + --player_status.lives; break; case SDLK_s: if(debug_mode) @@ -336,100 +302,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 @@ -446,7 +370,7 @@ GameSession::draw() fillrect(i % 2 ? (pause_menu_frame * i)%screen->w : -((pause_menu_frame * i)%screen->w) ,(i*20+pause_menu_frame)%screen->h,screen->w,10,20,20,20, rand() % 20 + 1); } fillrect(0,0,screen->w,screen->h,rand() % 50, rand() % 50, rand() % 50, 128); - text_drawf(&blue_text, "PAUSE - Press 'P' To Play", 0, 230, A_HMIDDLE, A_TOP, 1); + blue_text->drawf("PAUSE - Press 'P' To Play", 0, 230, A_HMIDDLE, A_TOP, 1); } if(show_menu) @@ -459,14 +383,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; @@ -490,14 +413,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()) { @@ -506,7 +426,7 @@ GameSession::run() } /* Handle events: */ - tux.input.old_fire = tux.input.fire; + tux->input.old_fire = tux->input.fire; process_events(); @@ -519,15 +439,9 @@ GameSession::run() 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; } } @@ -535,33 +449,26 @@ GameSession::run() { process_options_menu(); } - else if(current_menu == save_game_menu ) - { - process_save_game_menu(); - } else if(current_menu == load_game_menu ) { process_load_game_menu(); } } - - - /* Handle actions: */ - + + // Handle actions: if(!game_pause && !show_menu) { - /*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 { @@ -607,15 +514,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) @@ -637,9 +543,7 @@ GameSession::run() world->get_level()->cleanup(); world->get_level()->free_song(); - world->arrays_free(); - - return quit; + return exit_status; } /* Bounce a brick: */ @@ -655,47 +559,46 @@ void bumpbrick(float x, float y) void GameSession::drawstatus() { - Player& tux = *world->get_tux(); char str[60]; sprintf(str, "%d", player_status.score); - text_draw(&white_text, "SCORE", 0, 0, 1); - text_draw(&gold_text, str, 96, 0, 1); + white_text->draw("SCORE", 0, 0, 1); + gold_text->draw(str, 96, 0, 1); if(st_gl_mode != ST_GL_TEST) { sprintf(str, "%d", hs_score); - text_draw(&white_text, "HIGH", 0, 20, 1); - text_draw(&gold_text, str, 96, 20, 1); + white_text->draw("HIGH", 0, 20, 1); + gold_text->draw(str, 96, 20, 1); } else { - text_draw(&white_text,"Press ESC To Return",0,20,1); + white_text->draw("Press ESC To Return",0,20,1); } if (time_left.get_left() > TIME_WARNING || (global_frame_counter % 10) < 5) { sprintf(str, "%d", time_left.get_left() / 1000 ); - text_draw(&white_text, "TIME", 224, 0, 1); - text_draw(&gold_text, str, 304, 0, 1); + white_text->draw("TIME", 224, 0, 1); + gold_text->draw(str, 304, 0, 1); } sprintf(str, "%d", player_status.distros); - text_draw(&white_text, "DISTROS", screen->h, 0, 1); - text_draw(&gold_text, str, 608, 0, 1); + white_text->draw("DISTROS", screen->h, 0, 1); + gold_text->draw(str, 608, 0, 1); - text_draw(&white_text, "LIVES", screen->h, 20, 1); + white_text->draw("LIVES", screen->h, 20, 1); if(show_fps) { sprintf(str, "%2.1f", fps_fps); - text_draw(&white_text, "FPS", screen->h, 40, 1); - text_draw(&gold_text, str, screen->h + 60, 40, 1); + white_text->draw("FPS", screen->h, 40, 1); + 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) { - texture_draw(&tux_life,565+(18*i),20); + tux_life->draw(565+(18*i),20); } } @@ -706,13 +609,13 @@ GameSession::drawendscreen() clearscreen(0, 0, 0); - text_drawf(&blue_text, "GAMEOVER", 0, 200, A_HMIDDLE, A_TOP, 1); + blue_text->drawf("GAMEOVER", 0, 200, A_HMIDDLE, A_TOP, 1); sprintf(str, "SCORE: %d", player_status.score); - text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1); + gold_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1); - sprintf(str, "DISTROS: %d", player_status.distros); - text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1); + sprintf(str, "COINS: %d", player_status.distros); + gold_text->drawf(str, 0, 256, A_HMIDDLE, A_TOP, 1); flipscreen(); @@ -727,13 +630,13 @@ GameSession::drawresultscreen(void) clearscreen(0, 0, 0); - text_drawf(&blue_text, "Result:", 0, 200, A_HMIDDLE, A_TOP, 1); + blue_text->drawf("Result:", 0, 200, A_HMIDDLE, A_TOP, 1); sprintf(str, "SCORE: %d", player_status.score); - text_drawf(&gold_text, str, 0, 224, A_HMIDDLE, A_TOP, 1); + gold_text->drawf(str, 0, 224, A_HMIDDLE, A_TOP, 1); sprintf(str, "DISTROS: %d", player_status.distros); - text_drawf(&gold_text, str, 0, 256, A_HMIDDLE, A_TOP, 1); + gold_text->drawf(str, 0, 256, A_HMIDDLE, A_TOP, 1); flipscreen(); @@ -741,129 +644,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(slotfile,"%s/slot%d.stsg",st_save_dir,slot); - sprintf(tmp,"Slot %d - ",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; } +