X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fgameloop.cpp;h=275c42fa62190be20265986908a69430a560d051;hb=58bf708dc9f036b2c7d8d3edfdbfa62f0da3481a;hp=298b8dd440ae3ef0a6d7644214916f329f12e972;hpb=76d092bebada7aca0db7435a2810ce749816a056;p=supertux.git diff --git a/src/gameloop.cpp b/src/gameloop.cpp index 298b8dd44..275c42fa6 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -18,6 +18,7 @@ // 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 #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include "SDL.h" @@ -42,60 +44,57 @@ #include "gameloop.h" #include "video/screen.h" #include "app/setup.h" -#include "high_scores.h" #include "gui/menu.h" -#include "badguy.h" #include "sector.h" -#include "special.h" -#include "player.h" #include "level.h" #include "scene.h" -#include "collision.h" #include "tile.h" -#include "particlesystem.h" +#include "object/particlesystem.h" +#include "object/background.h" +#include "object/tilemap.h" +#include "object/camera.h" +#include "object/player.h" +#include "lisp/lisp.h" +#include "lisp/parser.h" #include "resources.h" -#include "background.h" -#include "tilemap.h" #include "app/gettext.h" #include "worldmap.h" #include "intro.h" #include "misc.h" -#include "camera.h" +#include "statistics.h" +#include "timer.h" +#include "object/fireworks.h" GameSession* GameSession::current_ = 0; bool compare_last(std::string& haystack, std::string needle) { -int haystack_size = haystack.size(); -int needle_size = needle.size(); + int haystack_size = haystack.size(); + int needle_size = needle.size(); -if(haystack_size < needle_size) - return false; + if(haystack_size < needle_size) + return false; -if(haystack.compare(haystack_size-needle_size, needle_size, needle) == 0) - return true; -return false; + if(haystack.compare(haystack_size-needle_size, needle_size, needle) == 0) + return true; + return false; } -GameSession::GameSession(const std::string& levelname_, int mode, bool flip_level_) +GameSession::GameSession(const std::string& levelfile_, int mode, + Statistics* statistics) : level(0), currentsector(0), st_gl_mode(mode), - end_sequence(NO_ENDSEQUENCE), levelname(levelname_), flip_level(flip_level_) + end_sequence(NO_ENDSEQUENCE), levelfile(levelfile_), + best_level_statistics(statistics) { current_ = this; - global_frame_counter = 0; game_pause = false; fps_fps = 0; - fps_timer.init(true); - frame_timer.init(true); - random_timer.init(true); - frame_rate.set_fps(100); - context = new DrawingContext(); - if(flip_levels_mode) - flip_level = true; + last_swap_point = Vector(-1, -1); + last_swap_stats.reset(); restart_level(); } @@ -107,42 +106,56 @@ GameSession::restart_level() exit_status = ES_NONE; end_sequence = NO_ENDSEQUENCE; - fps_timer.init(true); - frame_timer.init(true); - random_timer.init(true); - last_keys.clear(); +#if 0 Vector tux_pos = Vector(-1,-1); if (currentsector) - { // Tux has lost a life, so we try to respawn him at the nearest reset point + { + // Tux has lost a life, so we try to respawn him at the nearest reset point tux_pos = currentsector->player->base; } +#endif delete level; currentsector = 0; level = new Level; - level->load(levelname); - if(flip_level) - level->do_vertical_flip(); + level->load(levelfile); + + global_stats.reset(); + global_stats.set_total_points(COINS_COLLECTED_STAT, level->get_total_coins()); + global_stats.set_total_points(BADGUYS_KILLED_STAT, level->get_total_badguys()); + global_stats.set_total_points(TIME_NEEDED_STAT, level->timelimit); currentsector = level->get_sector("main"); if(!currentsector) Termination::abort("Level has no main sector.", ""); currentsector->activate("main"); +#if 0 // Set Tux to the nearest reset point if(tux_pos.x != -1) { tux_pos = currentsector->get_best_spawn_point(tux_pos); + + if(last_swap_point.x > tux_pos.x) + tux_pos = last_swap_point; + else // new swap point + { + last_swap_point = tux_pos; + + last_swap_stats += global_stats; + } + currentsector->player->base.x = tux_pos.x; currentsector->player->base.y = tux_pos.y; - + // has to reset camera on swapping currentsector->camera->reset(Vector(currentsector->player->base.x, currentsector->player->base.y)); } +#endif if (st_gl_mode != ST_GL_DEMO_GAME) { @@ -150,7 +163,6 @@ GameSession::restart_level() levelintro(); } - time_left.init(true); start_timers(); currentsector->play_music(LEVEL_MUSIC); } @@ -169,25 +181,32 @@ GameSession::levelintro(void) char str[60]; DrawingContext context; - currentsector->background->draw(context); + for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin(); + i != currentsector->gameobjects.end(); ++i) { + Background* background = dynamic_cast (*i); + if(background) { + background->draw(context); + } + } - context.draw_text_center(gold_text, level->get_name(), Vector(0, 220), +// context.draw_text(gold_text, level->get_name(), Vector(screen->w/2, 160), +// CENTER_ALLIGN, LAYER_FOREGROUND1); + context.draw_center_text(gold_text, level->get_name(), Vector(0, 160), LAYER_FOREGROUND1); sprintf(str, "TUX x %d", player_status.lives); - context.draw_text_center(white_text, str, Vector(0, 240), - LAYER_FOREGROUND1); + context.draw_text(white_text, str, Vector(screen->w/2, 210), + CENTER_ALLIGN, LAYER_FOREGROUND1); - if(level->get_author().size()) - context.draw_text_center(white_small_text, - std::string(_("by ")) + level->get_author(), - Vector(0, 400), LAYER_FOREGROUND1); + if((level->get_author().size()) && (level->get_author() != "SuperTux Team")) + //TODO make author check case/blank-insensitive + context.draw_text(white_small_text, + std::string(_("contributed by ")) + level->get_author(), + Vector(screen->w/2, 350), CENTER_ALLIGN, LAYER_FOREGROUND1); - if(flip_level) - context.draw_text_center(white_text, - _("Level Vertically Flipped!"), - Vector(0, 310), LAYER_FOREGROUND1); + if(best_level_statistics != NULL) + best_level_statistics->draw_message_info(context, _("Best Level Statistics")); context.do_drawing(); @@ -199,9 +218,8 @@ GameSession::levelintro(void) void GameSession::start_timers() { - time_left.start(level->time_left*1000); + time_left.start(level->timelimit); Ticks::pause_init(); - frame_rate.start(); } void @@ -223,11 +241,12 @@ GameSession::on_escape_press() it could have nasty bugs, like going allways to the right or whatever that key does */ Player& tux = *(currentsector->player); - tux.key_event((SDLKey)keymap.jump, UP); - tux.key_event((SDLKey)keymap.duck, UP); + tux.key_event((SDLKey)keymap.up, UP); + tux.key_event((SDLKey)keymap.down, UP); tux.key_event((SDLKey)keymap.left, UP); tux.key_event((SDLKey)keymap.right, UP); - tux.key_event((SDLKey)keymap.fire, UP); + tux.key_event((SDLKey)keymap.jump, UP); + tux.key_event((SDLKey)keymap.power, UP); Menu::set_current(game_menu); Ticks::pause_start(); @@ -246,12 +265,12 @@ GameSession::process_events() tux.input.right = DOWN; tux.input.down = UP; - if (int(last_x_pos) == int(tux.base.x)) + if (int(last_x_pos) == int(tux.get_pos().x)) tux.input.up = DOWN; else tux.input.up = UP; - last_x_pos = tux.base.x; + last_x_pos = tux.get_pos().x; SDL_Event event; while (SDL_PollEvent(&event)) @@ -347,10 +366,10 @@ GameSession::process_events() { char buf[160]; snprintf(buf, sizeof(buf), "P: %4.1f,%4.1f", - tux.base.x, tux.base.y); + tux.get_pos().x, tux.get_pos().y); context->draw_text(white_text, buf, Vector(0, screen->h - white_text->get_height()), - LAYER_FOREGROUND1); + LEFT_ALLIGN, LAYER_FOREGROUND1); context->do_drawing(); SDL_Delay(1000); } @@ -358,6 +377,11 @@ GameSession::process_events() case SDLK_p: if(!Menu::current()) { + // "lifeup" cheat activates pause cause of the 'p' + // so work around to ignore it + if(compare_last(last_keys, "lifeu")) + break; + if(game_pause) { game_pause = false; @@ -413,12 +437,63 @@ GameSession::process_events() player_status.lives--; last_keys.clear(); } + if(compare_last(last_keys, "grease")) + { + tux.physic.set_velocity_x(tux.physic.get_velocity_x()*3); + last_keys.clear(); + } if(compare_last(last_keys, "invincible")) { // be invincle for the rest of the level - tux.invincible_timer.start(time_left.get_left()); + tux.invincible_timer.start(10000); + last_keys.clear(); + } + if(compare_last(last_keys, "shrink")) + { // remove powerups + tux.kill(tux.SHRINK); + last_keys.clear(); + } + if(compare_last(last_keys, "kill")) + { // kill Tux, but without losing a life + player_status.lives++; + tux.kill(tux.KILL); + last_keys.clear(); + } + if(compare_last(last_keys, "grid")) + { // toggle debug grid + debug_grid = !debug_grid; + last_keys.clear(); + } + if(compare_last(last_keys, "hover")) + { // toggle hover ability on/off + tux.enable_hover = !tux.enable_hover; + last_keys.clear(); + } + if(compare_last(last_keys, "gotoend")) + { // goes to the end of the level + tux.move(Vector( + (currentsector->solids->get_width()*32) + - (screen->w*2), + 0)); + currentsector->camera->reset( + Vector(tux.get_pos().x, tux.get_pos().y)); + last_keys.clear(); + } + // temporary to help player's choosing a flapping + if(compare_last(last_keys, "marek")) + { + tux.flapping_mode = Player::MAREK_FLAP; + last_keys.clear(); + } + if(compare_last(last_keys, "ricardo")) + { + tux.flapping_mode = Player::RICARDO_FLAP; + last_keys.clear(); + } + if(compare_last(last_keys, "ryan")) + { + tux.flapping_mode = Player::RYAN_FLAP; last_keys.clear(); } - break; case SDL_JOYAXISMOTION: @@ -443,11 +518,20 @@ GameSession::process_events() else if (event.jaxis.axis == joystick_keymap.y_axis) { if (event.jaxis.value > joystick_keymap.dead_zone) - tux.input.down = DOWN; - else if (event.jaxis.value < -joystick_keymap.dead_zone) + { + tux.input.up = DOWN; tux.input.down = UP; + } + else if (event.jaxis.value < -joystick_keymap.dead_zone) + { + tux.input.up = UP; + tux.input.down = DOWN; + } else - tux.input.down = UP; + { + tux.input.up = DOWN; + tux.input.down = DOWN; + } } break; @@ -474,7 +558,7 @@ GameSession::process_events() case SDL_JOYBUTTONDOWN: if (event.jbutton.button == joystick_keymap.a_button) - tux.input.up = DOWN; + tux.input.jump = DOWN; else if (event.jbutton.button == joystick_keymap.b_button) tux.input.fire = DOWN; else if (event.jbutton.button == joystick_keymap.start_button) @@ -482,7 +566,7 @@ GameSession::process_events() break; case SDL_JOYBUTTONUP: if (event.jbutton.button == joystick_keymap.a_button) - tux.input.up = UP; + tux.input.jump = UP; else if (event.jbutton.button == joystick_keymap.b_button) tux.input.fire = UP; break; @@ -501,50 +585,31 @@ GameSession::check_end_conditions() Player* tux = currentsector->player; /* End of level? */ - Tile* endtile = collision_goal(tux->base); - - if(end_sequence && !endsequence_timer.check()) - { + if(end_sequence && endsequence_timer.check()) { exit_status = ES_LEVEL_FINISHED; + global_stats += last_swap_stats; // add swap points stats return; - } - else if(end_sequence == ENDSEQUENCE_RUNNING && endtile && endtile->data >= 1) - { - end_sequence = ENDSEQUENCE_WAITING; - } - else if(!end_sequence && endtile && endtile->data == 0) - { - end_sequence = ENDSEQUENCE_RUNNING; - random_timer.start(200); // start 1st firework - last_x_pos = -1; - SoundManager::get()->play_music(level_end_song, 0); - endsequence_timer.start(7000); // 5 seconds until we finish the map - tux->invincible_timer.start(7000); //FIXME: Implement a winning timer for the end sequence (with special winning animation etc.) - } - else if (!end_sequence && tux->is_dead()) - { - player_status.bonus = PlayerStatus::NO_BONUS; - - if (player_status.lives < 0) - { // No more lives!? - exit_status = ES_GAME_OVER; - } - else - { // Still has lives, so reset Tux to the levelstart - restart_level(); - } + } else if (!end_sequence && tux->is_dead()) { + player_status.bonus = PlayerStatus::NO_BONUS; - return; + if (player_status.lives < 0) { // No more lives!? + exit_status = ES_GAME_OVER; + } else { // Still has lives, so reset Tux to the levelstart + restart_level(); } + + return; + } } void -GameSession::action(double frame_ratio) +GameSession::action(float elapsed_time) { + // advance timers if (exit_status == ES_NONE && !currentsector->player->growing_timer.check()) { // Update Tux and the World - currentsector->action(frame_ratio); + currentsector->action(elapsed_time); } // respawning in new sector? @@ -555,22 +620,6 @@ GameSession::action(double frame_ratio) currentsector->play_music(LEVEL_MUSIC); newsector = newspawnpoint = ""; } - - // on end sequence make a few fireworks - if(end_sequence == ENDSEQUENCE_RUNNING && !random_timer.check()) - { - Vector epicenter = currentsector->camera->get_translation(); - epicenter.x += screen->w * ((float)rand() / RAND_MAX); - epicenter.y += (screen->h/2) * ((float)rand() / RAND_MAX); - - int red = rand() % 255; // calculate firework color - int green = rand() % red; - currentsector->add_particles(epicenter, Vector(1.4,1.4), Vector(0,0), - 45, Color(red,green,0), 3, 1300); - - SoundManager::get()->play_sound(IDToSound(SND_FIREWORKS)); - random_timer.start(rand() % 400 + 600); // next firework - } } void @@ -594,8 +643,8 @@ GameSession::draw() context->draw_filled_rect( Vector(0,0), Vector(screen->w, screen->h), Color(rand() % 50, rand() % 50, rand() % 50, 128), LAYER_FOREGROUND1); - context->draw_text_center(blue_text, _("PAUSE - Press 'P' To Play"), - Vector(0, 230), LAYER_FOREGROUND1+2); + context->draw_text(blue_text, _("PAUSE - Press 'P' To Play"), + Vector(screen->w/2, 230), CENTER_ALLIGN, LAYER_FOREGROUND1+2); char str1[60]; char str2[124]; @@ -604,10 +653,10 @@ GameSession::draw() context->draw_text(blue_text, str1, Vector((screen->w - (blue_text->get_text_width(str1) + white_text->get_text_width(str2)))/2, 340), - LAYER_FOREGROUND1+2); + LEFT_ALLIGN, LAYER_FOREGROUND1+2); context->draw_text(white_text, str2, Vector(((screen->w - (blue_text->get_text_width(str1) + white_text->get_text_width(str2)))/2)+blue_text->get_text_width(str1), 340), - LAYER_FOREGROUND1+2); + LEFT_ALLIGN, LAYER_FOREGROUND1+2); } if(Menu::current()) @@ -659,94 +708,95 @@ GameSession::run() int fps_cnt = 0; - frame_rate.start(); - // Eat unneeded events SDL_Event event; - while (SDL_PollEvent(&event)) {} + while(SDL_PollEvent(&event)) + {} draw(); - while (exit_status == ES_NONE) - { - /* Calculate the movement-factor */ - double frame_ratio = frame_rate.get(); - - if(!frame_timer.check()) - { - frame_timer.start(25); - ++global_frame_counter; - } - - /* Handle events: */ - currentsector->player->input.old_fire - = currentsector->player->input.fire; + Uint32 lastticks = SDL_GetTicks(); + fps_ticks = SDL_GetTicks(); - process_events(); - process_menu(); - - // Update the world state and all objects in the world - // Do that with a constante time-delta so that the game will run - // determistic and not different on different machines - if(!game_pause && !Menu::current()) - { - // Update the world - check_end_conditions(); - if (end_sequence == ENDSEQUENCE_RUNNING) - action(frame_ratio/2); - else if(end_sequence == NO_ENDSEQUENCE) - action(frame_ratio); - } - else - { - ++pause_menu_frame; - SDL_Delay(50); - } + while (exit_status == ES_NONE) { + Uint32 ticks = SDL_GetTicks(); + float elapsed_time = float(ticks - lastticks) / 1000.; + if(!game_pause) + global_time += elapsed_time; + lastticks = ticks; - draw(); + // 40fps is minimum + if(elapsed_time > .025) + elapsed_time = .025; + + /* Handle events: */ + currentsector->player->input.old_fire = currentsector->player->input.fire; + currentsector->player->input.old_up = currentsector->player->input.old_up; - /* Time stops in pause mode */ - if(game_pause || Menu::current()) - { - continue; - } + process_events(); + process_menu(); - frame_rate.update(); + // Update the world state and all objects in the world + // Do that with a constante time-delta so that the game will run + // determistic and not different on different machines + if(!game_pause && !Menu::current()) + { + // Update the world + check_end_conditions(); + if (end_sequence == ENDSEQUENCE_RUNNING) + action(elapsed_time/2); + else if(end_sequence == NO_ENDSEQUENCE) + action(elapsed_time); + } + else + { + ++pause_menu_frame; + SDL_Delay(50); + } - /* Handle time: */ - if (!time_left.check() && currentsector->player->dying == DYING_NOT - && !end_sequence) - currentsector->player->kill(Player::KILL); + draw(); - /* Handle music: */ - if(currentsector->player->invincible_timer.check() && !end_sequence) - { - currentsector->play_music(HERRING_MUSIC); - } - /* are we low on time ? */ - else if (time_left.get_left() < TIME_WARNING && !end_sequence) - { - currentsector->play_music(HURRYUP_MUSIC); - } - /* or just normal music? */ - else if(currentsector->get_music_type() != LEVEL_MUSIC && !end_sequence) - { - currentsector->play_music(LEVEL_MUSIC); - } + /* Time stops in pause mode */ + if(game_pause || Menu::current()) + { + continue; + } - /* Calculate frames per second */ - if(show_fps) - { - ++fps_cnt; - fps_fps = (1000.0 / (float)fps_timer.get_gone()) * (float)fps_cnt; + //frame_rate.update(); + + /* Handle time: */ + if (time_left.check() && !end_sequence) + currentsector->player->kill(Player::KILL); + + /* Handle music: */ + if (currentsector->player->invincible_timer.started() && !end_sequence) + { + currentsector->play_music(HERRING_MUSIC); + } + /* are we low on time ? */ + else if (time_left.get_timeleft() < TIME_WARNING && !end_sequence) + { + currentsector->play_music(HURRYUP_MUSIC); + } + /* or just normal music? */ + else if(currentsector->get_music_type() != LEVEL_MUSIC && !end_sequence) + { + currentsector->play_music(LEVEL_MUSIC); + } - if(!fps_timer.check()) - { - fps_timer.start(1000); - fps_cnt = 0; - } - } + /* Calculate frames per second */ + if(show_fps) + { + ++fps_cnt; + + if(SDL_GetTicks() - fps_ticks >= 500) + { + fps_fps = (float) fps_cnt / .5; + fps_cnt = 0; + fps_ticks = SDL_GetTicks(); + } } + } return exit_status; } @@ -758,13 +808,29 @@ GameSession::respawn(const std::string& sector, const std::string& spawnpoint) newspawnpoint = spawnpoint; } -/* Bounce a brick: */ -void bumpbrick(float x, float y) +void +GameSession::start_sequence(const std::string& sequencename) { - Sector::current()->add_bouncy_brick(Vector(((int)(x + 1) / 32) * 32, - (int)(y / 32) * 32)); - - SoundManager::get()->play_sound(IDToSound(SND_BRICK), Vector(x, y), Sector::current()->player->get_pos()); + if(sequencename == "endsequence") { + if(end_sequence) + return; + + end_sequence = ENDSEQUENCE_RUNNING; + endsequence_timer.start(7.0); // 7 seconds until we finish the map + last_x_pos = -1; + SoundManager::get()->play_music(level_end_song, 0); + currentsector->player->invincible_timer.start(7.0); + + // add left time to stats + global_stats.set_points(TIME_NEEDED_STAT, + int(time_left.get_period() - time_left.get_timeleft())); + + if(level->get_end_sequence_type() == Level::FIREWORKS_ENDSEQ_ANIM) { + currentsector->add_object(new Fireworks()); + } + } else { + std::cout << "Unknown sequence '" << sequencename << "'.\n"; + } } /* (Status): */ @@ -773,39 +839,40 @@ GameSession::drawstatus(DrawingContext& context) { char str[60]; - snprintf(str, 60, " %d", player_status.score); - context.draw_text(white_text, _("SCORE"), Vector(0, 0), LAYER_FOREGROUND1); - context.draw_text(gold_text, str, Vector(96, 0), LAYER_FOREGROUND1); + snprintf(str, 60, " %d", global_stats.get_points(SCORE_STAT)); + context.draw_text(white_text, _("SCORE"), Vector(0, 0), LEFT_ALLIGN, LAYER_FOREGROUND1); + context.draw_text(gold_text, str, Vector(96, 0), LEFT_ALLIGN, LAYER_FOREGROUND1); if(st_gl_mode == ST_GL_TEST) { context.draw_text(white_text, _("Press ESC To Return"), Vector(0,20), - LAYER_FOREGROUND1); + LEFT_ALLIGN, LAYER_FOREGROUND1); } - if(!time_left.check()) { - context.draw_text_center(white_text, _("TIME's UP"), Vector(0, 0), - LAYER_FOREGROUND1); - } else if (time_left.get_left() > TIME_WARNING || (global_frame_counter % 10) < 5) { - sprintf(str, " %d", time_left.get_left() / 1000 ); - context.draw_text_center(white_text, _("TIME"), - Vector(0, 0), LAYER_FOREGROUND1); - context.draw_text_center(gold_text, str, - Vector(4*16, 0), LAYER_FOREGROUND1); + if(time_left.get_timeleft() < 0) { + context.draw_text(white_text, _("TIME's UP"), Vector(screen->w/2, 0), + CENTER_ALLIGN, LAYER_FOREGROUND1); + } else if (time_left.get_timeleft() > TIME_WARNING + || int(global_time * 2.5) % 2) { + sprintf(str, " %d", int(time_left.get_timeleft())); + context.draw_text(white_text, _("TIME"), + Vector(screen->w/2, 0), CENTER_ALLIGN, LAYER_FOREGROUND1); + context.draw_text(gold_text, str, + Vector(screen->w/2 + 4*16, 0), CENTER_ALLIGN, LAYER_FOREGROUND1); } sprintf(str, " %d", player_status.distros); context.draw_text(white_text, _("COINS"), Vector(screen->w - white_text->get_text_width(_("COINS"))-white_text->get_text_width(" 99"), 0), - LAYER_FOREGROUND1); + LEFT_ALLIGN, LAYER_FOREGROUND1); context.draw_text(gold_text, str, - Vector(screen->w - gold_text->get_text_width(" 99"), 0),LAYER_FOREGROUND1); + Vector(screen->w - gold_text->get_text_width(" 99"), 0),LEFT_ALLIGN, LAYER_FOREGROUND1); if (player_status.lives >= 5) { sprintf(str, "%dx", player_status.lives); float x = screen->w - gold_text->get_text_width(str) - tux_life->w; - context.draw_text(gold_text, str, Vector(x, 20), LAYER_FOREGROUND1); + context.draw_text(gold_text, str, Vector(x, 20), LEFT_ALLIGN, LAYER_FOREGROUND1); context.draw_surface(tux_life, Vector(screen->w - 16, 20), LAYER_FOREGROUND1); } @@ -819,35 +886,41 @@ GameSession::drawstatus(DrawingContext& context) context.draw_text(white_text, _("LIVES"), Vector(screen->w - white_text->get_text_width(_("LIVES")) - white_text->get_text_width(" 99"), 20), - LAYER_FOREGROUND1); + LEFT_ALLIGN, LAYER_FOREGROUND1); if(show_fps) { sprintf(str, "%2.1f", fps_fps); context.draw_text(white_text, "FPS", Vector(screen->w - white_text->get_text_width("FPS "), 40), - LAYER_FOREGROUND1); + LEFT_ALLIGN, LAYER_FOREGROUND1); context.draw_text(gold_text, str, - Vector(screen->w-4*16, 40), LAYER_FOREGROUND1); + Vector(screen->w-4*16, 40), LEFT_ALLIGN, LAYER_FOREGROUND1); } } void -GameSession::drawresultscreen(void) +GameSession::drawresultscreen() { char str[80]; DrawingContext context; - currentsector->background->draw(context); + for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin(); + i != currentsector->gameobjects.end(); ++i) { + Background* background = dynamic_cast (*i); + if(background) { + background->draw(context); + } + } - context.draw_text_center(blue_text, _("Result:"), Vector(0, 200), - LAYER_FOREGROUND1); + context.draw_text(blue_text, _("Result:"), Vector(screen->w/2, 200), + CENTER_ALLIGN, LAYER_FOREGROUND1); - sprintf(str, _("SCORE: %d"), player_status.score); - context.draw_text_center(gold_text, str, Vector(0, 224), LAYER_FOREGROUND1); + sprintf(str, _("SCORE: %d"), global_stats.get_points(SCORE_STAT)); + context.draw_text(gold_text, str, Vector(screen->w/2, 224), CENTER_ALLIGN, LAYER_FOREGROUND1); sprintf(str, _("COINS: %d"), player_status.distros); - context.draw_text_center(gold_text, str, Vector(0, 256), LAYER_FOREGROUND1); + context.draw_text(gold_text, str, Vector(screen->w/2, 256), CENTER_ALLIGN, LAYER_FOREGROUND1); context.do_drawing(); @@ -864,25 +937,21 @@ std::string slotinfo(int slot) stream << slot; slotfile = st_save_dir + "/slot" + stream.str() + ".stsg"; - lisp_object_t* savegame = lisp_read_from_file(slotfile.c_str()); - if (savegame) - { - LispReader reader(lisp_cdr(savegame)); - reader.read_string("title", title); - lisp_free(savegame); - } + try { + lisp::Parser parser; + std::auto_ptr root (parser.parse(slotfile)); - if (access(slotfile.c_str(), F_OK) == 0) - { - if (!title.empty()) - tmp = "Slot " + stream.str() + " - " + title; - else - tmp = "Slot " + stream.str() + " - Savegame"; - } - else - tmp = std::string(_("Slot")) + " " + stream.str() + " - " + std::string(_("Free")); + const lisp::Lisp* savegame = root->get_lisp("supertux-savegame"); + if(!savegame) + throw std::runtime_error("file is not a supertux-savegame."); + + savegame->get("title", title); + } catch(std::exception& e) { + return std::string(_("Slot")) + " " + stream.str() + " - " + + std::string(_("Free")); + } - return tmp; + return std::string("Slot ") + stream.str() + " - " + title; } bool process_load_game_menu() @@ -895,21 +964,15 @@ bool process_load_game_menu() stream << slot; std::string slotfile = st_save_dir + "/slot" + stream.str() + ".stsg"; - if (access(slotfile.c_str(), F_OK) != 0) - { - draw_intro(); - } - - // shrink_fade(Point((screen->w/2),(screen->h/2)), 1000); fadeout(256); - DrawingContext context; - context.draw_text_center(white_text, "Loading...", - Vector(0, screen->h/2), LAYER_FOREGROUND1); + context.draw_text(white_text, "Loading...", + Vector(screen->w/2, screen->h/2), CENTER_ALLIGN, LAYER_FOREGROUND1); context.do_drawing(); WorldMapNS::WorldMap worldmap; + worldmap.set_map_filename("/levels/world1/worldmap.stwm"); // Load the game or at least set the savegame_file variable worldmap.loadgame(slotfile);