From fc73efa7ff699fe3c9c237845b6f4fda0d999862 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 17 Apr 2006 12:48:19 +0000 Subject: [PATCH] the boat works now SVN-Revision: 3354 --- data/images/worldmap.strf | 4 +- src/badguy/badguy.cpp | 5 +- src/game_session.cpp | 155 ++++++----------------------------------- src/game_session.hpp | 33 +++------ src/{misc.hpp => log.cpp} | 32 ++++----- src/log.hpp | 3 + src/main.cpp | 13 ++-- src/mainloop.cpp | 16 ++++- src/mainloop.hpp | 3 + src/misc.cpp | 65 ----------------- src/resources.hpp | 8 --- src/scripting/functions.cpp | 14 ++-- src/scripting/functions.hpp | 7 +- src/scripting/wrapper.cpp | 41 +++++++++-- src/timer.hpp | 2 +- src/title.cpp | 38 ++++++---- src/title.hpp | 1 + src/world.cpp | 6 +- src/worldmap/sprite_change.cpp | 11 ++- src/worldmap/sprite_change.hpp | 2 +- src/worldmap/tux.cpp | 98 +++++++++++++++----------- src/worldmap/worldmap.cpp | 63 +++++++---------- src/worldmap/worldmap.hpp | 50 +++++-------- 23 files changed, 258 insertions(+), 412 deletions(-) rename src/{misc.hpp => log.cpp} (57%) delete mode 100644 src/misc.cpp diff --git a/data/images/worldmap.strf b/data/images/worldmap.strf index 529b731da..f7844ffc6 100644 --- a/data/images/worldmap.strf +++ b/data/images/worldmap.strf @@ -3993,10 +3993,10 @@ (tile (id 916) (images (region "worldmap/antarctica/pier.png" 64 0 32 32)) - (stop #t) + (stop #f) (north #f) (south #f) (west #t) - (east #f)) + (east #t)) ) diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp index 3798ab903..d993c0fc4 100644 --- a/src/badguy/badguy.cpp +++ b/src/badguy/badguy.cpp @@ -165,18 +165,21 @@ BadGuy::collision_solid(GameObject& , const CollisionHit& ) } HitResponse -BadGuy::collision_player(Player& player, const CollisionHit& hit) +BadGuy::collision_player(Player& player, const CollisionHit& ) { if(player.is_invincible()) { kill_fall(); return ABORT_MOVE; } + /* printf("PlayerHit: GT %3.1f PM: %3.1f %3.1f BM: %3.1f %3.1f Hit: %3.1f %3.1f\n", game_time, player.get_movement().x, player.get_movement().y, get_movement().x, get_movement().y, hit.normal.x, hit.normal.y); + */ + // hit from above? if(player.get_movement().y /*- get_movement().y*/ > 0 && player.get_bbox().p2.y < diff --git a/src/game_session.cpp b/src/game_session.cpp index 1532e3942..30e115edc 100644 --- a/src/game_session.cpp +++ b/src/game_session.cpp @@ -53,9 +53,9 @@ #include "lisp/lisp.hpp" #include "lisp/parser.hpp" #include "resources.hpp" -#include "misc.hpp" #include "statistics.hpp" #include "timer.hpp" +#include "options_menu.hpp" #include "object/fireworks.hpp" #include "textscroller.hpp" #include "control/codecontroller.hpp" @@ -72,11 +72,15 @@ // binary fraction... static const float LOGICAL_FPS = 64.0; +enum GameMenuIDs { + MNID_CONTINUE, + MNID_ABORTLEVEL +}; + GameSession* GameSession::current_ = NULL; -GameSession::GameSession(const std::string& levelfile_, GameSessionMode mode, - Statistics* statistics) - : level(0), currentsector(0), mode(mode), +GameSession::GameSession(const std::string& levelfile_, Statistics* statistics) + : level(0), currentsector(0), end_sequence(NO_ENDSEQUENCE), end_sequence_controller(0), levelfile(levelfile_), best_level_statistics(statistics), capture_demo_stream(0), playback_demo_stream(0), demo_controller(0) @@ -85,11 +89,18 @@ GameSession::GameSession(const std::string& levelfile_, GameSessionMode mode, currentsector = NULL; game_pause = false; - fps_fps = 0; statistics_backdrop.reset(new Surface("images/engine/menu/score-backdrop.png")); restart_level(true); + + game_menu.reset(new Menu()); + game_menu->add_label(_("Pause")); + game_menu->add_hl(); + game_menu->add_entry(MNID_CONTINUE, _("Continue")); + game_menu->add_submenu(_("Options"), get_options_menu()); + game_menu->add_hl(); + game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level")); } void @@ -143,8 +154,7 @@ GameSession::restart_level(bool fromBeginning) currentsector->activate("main"); } - if(mode == ST_GL_PLAY || mode == ST_GL_LOAD_LEVEL_FILE) - levelintro(); + levelintro(); currentsector->play_music(LEVEL_MUSIC); @@ -243,10 +253,8 @@ GameSession::on_escape_press() if(currentsector->player->is_dying() || end_sequence != NO_ENDSEQUENCE) return; // don't let the player open the menu, when he is dying - if(mode == ST_GL_TEST) { - main_loop->exit_screen(); - } else if (!Menu::current()) { - Menu::set_current(game_menu); + if (!Menu::current()) { + Menu::set_current(game_menu.get()); game_menu->set_active_item(MNID_CONTINUE); game_pause = true; } else { @@ -360,7 +368,7 @@ GameSession::process_menu() if(menu) { menu->update(); - if(menu == game_menu) { + if(menu == game_menu.get()) { switch (game_menu->check()) { case MNID_CONTINUE: Menu::set_current(0); @@ -441,121 +449,6 @@ GameSession::update(float elapsed_time) } } -#if 0 -GameSession::ExitStatus -GameSession::run() -{ - Menu::set_current(0); - current_ = this; - - int fps_cnt = 0; - - // Eat unneeded events - SDL_Event event; - while(SDL_PollEvent(&event)) - {} - - draw(); - - Uint32 fps_ticks = SDL_GetTicks(); - Uint32 fps_nextframe_ticks = SDL_GetTicks(); - Uint32 ticks; - bool skipdraw = false; - - while (exit_status == ES_NONE) { - // we run in a logical framerate so elapsed time is a constant - // This will make the game run determistic and not different on different - // machines - static const float elapsed_time = 1.0 / LOGICAL_FPS; - // old code... float elapsed_time = float(ticks - lastticks) / 1000.; - if(!game_pause) - game_time += elapsed_time; - - // regulate fps - ticks = SDL_GetTicks(); - if(ticks > fps_nextframe_ticks) { - if(skipdraw == true) { - // already skipped last frame? we have to slow down the game then... - skipdraw = false; - fps_nextframe_ticks -= (Uint32) (1000.0 / LOGICAL_FPS); - } else { - // don't draw all frames when we're getting too slow - skipdraw = true; - } - } else { - skipdraw = false; - while(fps_nextframe_ticks > ticks) { - /* just wait */ - // If we really have to wait long, then do an imprecise SDL_Delay() - Uint32 diff = fps_nextframe_ticks - ticks; - if(diff > 15) { - SDL_Delay(diff - 10); - } - ticks = SDL_GetTicks(); - } - } - fps_nextframe_ticks = ticks + (Uint32) (1000.0 / LOGICAL_FPS); - - process_events(); - process_menu(); - - // Update the world state and all objects in the world - if(!game_pause) - { - // Update the world - check_end_conditions(); - if (end_sequence == ENDSEQUENCE_RUNNING) - update(elapsed_time/2); - else if(end_sequence == NO_ENDSEQUENCE) - update(elapsed_time); - } - - if(!skipdraw) - draw(); - - // update sounds - sound_manager->update(); - - /* Time stops in pause mode */ - if(game_pause || Menu::current()) - { - continue; - } - - /* Handle music: */ - if (currentsector->player->invincible_timer.started() && - currentsector->player->invincible_timer.get_timeleft() - > TUX_INVINCIBLE_TIME_WARNING && !end_sequence) - { - currentsector->play_music(HERRING_MUSIC); - } - /* or just normal music? */ - else if(currentsector->get_music_type() != LEVEL_MUSIC && !end_sequence) - { - currentsector->play_music(LEVEL_MUSIC); - } - - /* Calculate frames per second */ - if(config->show_fps) - { - ++fps_cnt; - - if(SDL_GetTicks() - fps_ticks >= 500) - { - fps_fps = (float) fps_cnt / .5; - fps_cnt = 0; - fps_ticks = SDL_GetTicks(); - } - } - } - - // just in case - currentsector = 0; - main_controller->reset(); - return exit_status; -} -#endif - void GameSession::finish(bool win) { @@ -691,14 +584,6 @@ GameSession::drawstatus(DrawingContext& context) { player_status->draw(context); - if(config->show_fps) { - char str[60]; - snprintf(str, sizeof(str), "%3.1f", fps_fps); - const char* fpstext = "FPS"; - context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1); - context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_FOREGROUND1); - } - // draw level stats while end_sequence is running if (end_sequence) { global_stats.draw_endseq_panel(context, best_level_statistics, statistics_backdrop.get()); diff --git a/src/game_session.hpp b/src/game_session.hpp index e41eb1e66..3a216fd50 100644 --- a/src/game_session.hpp +++ b/src/game_session.hpp @@ -28,27 +28,12 @@ #include "console.hpp" #include "video/surface.hpp" -/* GameLoop modes */ -enum GameSessionMode { - ST_GL_PLAY, - ST_GL_TEST, - ST_GL_LOAD_GAME, - ST_GL_LOAD_LEVEL_FILE, - ST_GL_DEMO_GAME -}; - -enum GameMenuIDs { - MNID_CONTINUE, - MNID_ABORTLEVEL -}; - -extern int game_started; - class Level; class Sector; class Statistics; class DrawingContext; class CodeController; +class Menu; /** * The GameSession class controlls the controll flow of the Game (the part @@ -57,8 +42,7 @@ class CodeController; class GameSession : public Screen { public: - GameSession(const std::string& levelfile, GameSessionMode mode, - Statistics* statistics = NULL); + GameSession(const std::string& levelfile, Statistics* statistics = NULL); ~GameSession(); void record_demo(const std::string& filename); @@ -75,10 +59,8 @@ public: /// ends the current level void finish(bool win = true); - void respawn(const std::string& sectorname, - const std::string& spawnpointname); - void set_reset_point(const std::string& sectorname, - const Vector& pos); + void respawn(const std::string& sectorname, const std::string& spawnpointname); + void set_reset_point(const std::string& sectorname, const Vector& pos); void display_info_box(const std::string& text); Sector* get_current_sector() @@ -89,7 +71,8 @@ public: void start_sequence(const std::string& sequencename); - /** returns the "working directory" usually this is the directory where the + /** + * returns the "working directory" usually this is the directory where the * currently played level resides. This is used when locating additional * resources for the current level/world */ @@ -114,9 +97,7 @@ private: Sector* currentsector; - GameSessionMode mode; int levelnb; - float fps_fps; int pause_menu_frame; /** If true the end_sequence will be played, user input will be @@ -150,6 +131,8 @@ private: std::string capture_file; std::istream* playback_demo_stream; CodeController* demo_controller; + + std::auto_ptr game_menu; }; #endif /*SUPERTUX_GAMELOOP_H*/ diff --git a/src/misc.hpp b/src/log.cpp similarity index 57% rename from src/misc.hpp rename to src/log.cpp index 9122104c1..b65524759 100644 --- a/src/misc.hpp +++ b/src/log.cpp @@ -1,8 +1,7 @@ -// $Id$ +// $Id: log.hpp 3327 2006-04-13 15:02:40Z ravu_al_hemio $ // -// SuperTux -// Copyright (C) 2004 Tobas Glaesser -// Copyright (C) 2006 Matthias Braun +// SuperTux Debug Helper Functions +// Copyright (C) 2006 Christoph Sommer // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -16,21 +15,16 @@ // // 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. -#ifndef SUPERTUX_MISC_H -#define SUPERTUX_MISC_H +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +#include -enum MainMenuIDs { - MNID_STARTGAME, - MNID_LEVELS_CONTRIB, - MNID_OPTIONMENU, - MNID_LEVELEDITOR, - MNID_CREDITS, - MNID_QUITMAINMENU -}; +#include "log.hpp" +#include "math/vector.hpp" -/* Create and setup menus. */ -void setup_menu(); -void free_menu(); +std::ostream& operator<<(std::ostream& out, const Vector& vector) +{ + out << '[' << vector.x << ',' << vector.y << ']'; + return out; +} -#endif diff --git a/src/log.hpp b/src/log.hpp index 716c1299a..eb1406922 100644 --- a/src/log.hpp +++ b/src/log.hpp @@ -79,5 +79,8 @@ inline std::ostream& log_fatal_f() { #endif +class Vector; +std::ostream& operator<< (std::ostream& str, const Vector& vector); + #endif diff --git a/src/main.cpp b/src/main.cpp index 0520a3119..1ab47a716 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,7 +44,7 @@ #include "video/surface.hpp" #include "video/texture_manager.hpp" #include "control/joystickkeyboardcontroller.hpp" -#include "misc.hpp" +#include "options_menu.hpp" #include "mainloop.hpp" #include "title.hpp" #include "game_session.hpp" @@ -503,8 +503,6 @@ int main(int argc, char** argv) timelog("scripting"); init_scripting(); - timelog("menu"); - setup_menu(); timelog("resources"); load_shared(); timelog(0); @@ -515,14 +513,13 @@ int main(int argc, char** argv) // So we simply mount that path here... std::string dir = FileSystem::dirname(config->start_level); PHYSFS_addToSearchPath(dir.c_str(), true); - GameSession* session - = new GameSession( - FileSystem::basename(config->start_level), ST_GL_LOAD_LEVEL_FILE); + std::auto_ptr session + (new GameSession(FileSystem::basename(config->start_level))); if(config->start_demo != "") session->play_demo(config->start_demo); if(config->record_demo != "") session->record_demo(config->record_demo); - main_loop->push_screen(session); + main_loop->push_screen(session.release()); } else { main_loop->push_screen(new TitleScreen()); } @@ -539,7 +536,7 @@ int main(int argc, char** argv) delete main_loop; main_loop = NULL; - free_menu(); + free_options_menu(); unload_shared(); quit_audio(); diff --git a/src/mainloop.cpp b/src/mainloop.cpp index 1be011437..7e5a01bc5 100644 --- a/src/mainloop.cpp +++ b/src/mainloop.cpp @@ -32,6 +32,7 @@ #include "script_manager.hpp" #include "screen.hpp" #include "timer.hpp" +#include "player_status.hpp" // the engine will be run with a logical framerate of 64fps. // We chose 64fps here because it is a power of 2, so 1/64 gives an "even" @@ -87,12 +88,22 @@ MainLoop::set_speed(float speed) } void +MainLoop::draw_fps(DrawingContext& context, float fps_fps) +{ + char str[60]; + snprintf(str, sizeof(str), "%3.1f", fps_fps); + const char* fpstext = "FPS"; + context.draw_text(white_text, fpstext, Vector(SCREEN_WIDTH - white_text->get_text_width(fpstext) - gold_text->get_text_width(" 99999") - BORDER_X, BORDER_Y + 20), LEFT_ALLIGN, LAYER_FOREGROUND1); + context.draw_text(gold_text, str, Vector(SCREEN_WIDTH - BORDER_X, BORDER_Y + 20), RIGHT_ALLIGN, LAYER_FOREGROUND1); +} + +void MainLoop::run() { DrawingContext context; unsigned int frame_count; - float fps_fps; + float fps_fps = 0; Uint32 fps_ticks = SDL_GetTicks(); Uint32 fps_nextframe_ticks = SDL_GetTicks(); Uint32 ticks; @@ -147,6 +158,9 @@ MainLoop::run() Menu::current()->draw(context); Console::instance->draw(context); + if(config->show_fps) + draw_fps(context, fps_fps); + context.do_drawing(); /* Calculate frames per second */ diff --git a/src/mainloop.hpp b/src/mainloop.hpp index 8be8b11d9..dfb2f9ed4 100644 --- a/src/mainloop.hpp +++ b/src/mainloop.hpp @@ -24,6 +24,7 @@ class Screen; class Console; +class DrawingContext; class MainLoop { @@ -40,6 +41,8 @@ public: void push_screen(Screen* screen); private: + void draw_fps(DrawingContext& context, float fps); + bool running; float speed; bool nextpush; diff --git a/src/misc.cpp b/src/misc.cpp deleted file mode 100644 index 2dba5aa03..000000000 --- a/src/misc.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// $Id$ -// -// SuperTux -// Copyright (C) 2004 Tobas Glaesser -// Copyright (C) 2006 Matthias Braun -// -// 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 - -#include "misc.hpp" -#include "main.hpp" -#include "gameconfig.hpp" -#include "game_session.hpp" -#include "gui/menu.hpp" -#include "gui/button.hpp" -#include "audio/sound_manager.hpp" -#include "title.hpp" -#include "resources.hpp" -#include "worldmap/worldmap.hpp" -#include "gettext.hpp" -#include "options_menu.hpp" -#include "control/joystickkeyboardcontroller.hpp" - -Menu* main_menu = NULL; -Menu* game_menu = NULL; - -void setup_menu() -{ - main_menu = new Menu(); - game_menu = new Menu(); - - main_menu->set_pos(SCREEN_WIDTH/2, 335); - main_menu->add_entry(MNID_STARTGAME, _("Start Game")); - main_menu->add_entry(MNID_LEVELS_CONTRIB, _("Contrib Levels")); - main_menu->add_submenu(_("Options"), get_options_menu()); - main_menu->add_entry(MNID_CREDITS, _("Credits")); - main_menu->add_entry(MNID_QUITMAINMENU, _("Quit")); - - game_menu->add_label(_("Pause")); - game_menu->add_hl(); - game_menu->add_entry(MNID_CONTINUE, _("Continue")); - game_menu->add_submenu(_("Options"), get_options_menu()); - game_menu->add_hl(); - game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level")); -} - -void free_menu() -{ - delete main_menu; - delete game_menu; - free_options_menu(); -} - diff --git a/src/resources.hpp b/src/resources.hpp index feaca220b..2ee485b2f 100644 --- a/src/resources.hpp +++ b/src/resources.hpp @@ -20,17 +20,9 @@ #ifndef SUPERTUX_RESOURCES_H #define SUPERTUX_RESOURCES_H -class SpriteManager; -class Menu; class Font; -class Surface; -class SoundManager; -class TileManager; class MouseCursor; -extern Menu* main_menu; -extern Menu* game_menu; - extern MouseCursor* mouse_cursor; extern Font* gold_text; diff --git a/src/scripting/functions.cpp b/src/scripting/functions.cpp index b7a377903..9d4515427 100644 --- a/src/scripting/functions.cpp +++ b/src/scripting/functions.cpp @@ -37,6 +37,7 @@ #include "worldmap/worldmap.hpp" #include "world.hpp" #include "sector.hpp" +#include "gameconfig.hpp" #include "object/player.hpp" #include "object/tilemap.hpp" #include "main.hpp" @@ -88,14 +89,12 @@ void load_worldmap(const std::string& filename) { using namespace WorldMapNS; - std::auto_ptr worldmap(new WorldMap()); - worldmap->loadmap(filename); - main_loop->push_screen(worldmap.release()); + main_loop->push_screen(new WorldMap(filename)); } void load_level(const std::string& filename) { - main_loop->push_screen(new GameSession(filename, ST_GL_PLAY)); + main_loop->push_screen(new GameSession(filename)); } static SQInteger squirrel_read_char(SQUserPointer file) @@ -135,7 +134,12 @@ void debug_collrects(bool enable) Sector::show_collrects = enable; } -void draw_solids_only(bool enable) +void debug_draw_fps(bool enable) +{ + config->show_fps = enable; +} + +void debug_draw_solids_only(bool enable) { Sector::draw_solids_only = enable; } diff --git a/src/scripting/functions.hpp b/src/scripting/functions.hpp index 6a5908311..4793cdbfa 100644 --- a/src/scripting/functions.hpp +++ b/src/scripting/functions.hpp @@ -101,9 +101,14 @@ void add_key(int new_key); void debug_collrects(bool enable); /** + * enable/disable drawing of fps + */ +void debug_draw_fps(bool enable); + +/** * enable/disable drawing of non-solid layers */ -void draw_solids_only(bool enable); +void debug_draw_solids_only(bool enable); /** * speeds Tux up diff --git a/src/scripting/wrapper.cpp b/src/scripting/wrapper.cpp index fcef54839..1068071c4 100644 --- a/src/scripting/wrapper.cpp +++ b/src/scripting/wrapper.cpp @@ -1725,7 +1725,7 @@ static int debug_collrects_wrapper(HSQUIRRELVM vm) } -static int draw_solids_only_wrapper(HSQUIRRELVM vm) +static int debug_draw_fps_wrapper(HSQUIRRELVM vm) { SQBool arg0; if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) { @@ -1734,7 +1734,7 @@ static int draw_solids_only_wrapper(HSQUIRRELVM vm) } try { - Scripting::draw_solids_only(arg0); + Scripting::debug_draw_fps(arg0); return 0; @@ -1742,7 +1742,30 @@ static int draw_solids_only_wrapper(HSQUIRRELVM vm) sq_throwerror(vm, e.what()); return SQ_ERROR; } catch(...) { - sq_throwerror(vm, _SC("Unexpected exception while executing function 'draw_solids_only'")); + sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_draw_fps'")); + return SQ_ERROR; + } + +} + +static int debug_draw_solids_only_wrapper(HSQUIRRELVM vm) +{ + SQBool arg0; + if(SQ_FAILED(sq_getbool(vm, 2, &arg0))) { + sq_throwerror(vm, _SC("Argument 1 not a bool")); + return SQ_ERROR; + } + + try { + Scripting::debug_draw_solids_only(arg0); + + return 0; + + } catch(std::exception& e) { + sq_throwerror(vm, e.what()); + return SQ_ERROR; + } catch(...) { + sq_throwerror(vm, _SC("Unexpected exception while executing function 'debug_draw_solids_only'")); return SQ_ERROR; } @@ -2308,10 +2331,16 @@ void register_supertux_wrapper(HSQUIRRELVM v) throw SquirrelError(v, "Couldn't register function 'debug_collrects'"); } - sq_pushstring(v, "draw_solids_only", -1); - sq_newclosure(v, &draw_solids_only_wrapper, 0); + sq_pushstring(v, "debug_draw_fps", -1); + sq_newclosure(v, &debug_draw_fps_wrapper, 0); + if(SQ_FAILED(sq_createslot(v, -3))) { + throw SquirrelError(v, "Couldn't register function 'debug_draw_fps'"); + } + + sq_pushstring(v, "debug_draw_solids_only", -1); + sq_newclosure(v, &debug_draw_solids_only_wrapper, 0); if(SQ_FAILED(sq_createslot(v, -3))) { - throw SquirrelError(v, "Couldn't register function 'draw_solids_only'"); + throw SquirrelError(v, "Couldn't register function 'debug_draw_solids_only'"); } sq_pushstring(v, "grease", -1); diff --git a/src/timer.hpp b/src/timer.hpp index 8b5641c22..340e8cebb 100644 --- a/src/timer.hpp +++ b/src/timer.hpp @@ -23,7 +23,7 @@ extern float game_time; /** - * new simpler timer designed to be used in the update functions of objects + * Simple timer designed to be used in the update functions of objects */ class Timer { diff --git a/src/title.cpp b/src/title.cpp index a68866730..da22b4936 100644 --- a/src/title.cpp +++ b/src/title.cpp @@ -55,15 +55,24 @@ #include "object/player.hpp" #include "resources.hpp" #include "gettext.hpp" -#include "misc.hpp" #include "textscroller.hpp" #include "file_system.hpp" #include "control/joystickkeyboardcontroller.hpp" #include "control/codecontroller.hpp" #include "main.hpp" #include "log.hpp" +#include "options_menu.hpp" #include "console.hpp" +enum MainMenuIDs { + MNID_STARTGAME, + MNID_LEVELS_CONTRIB, + MNID_OPTIONMENU, + MNID_LEVELEDITOR, + MNID_CREDITS, + MNID_QUITMAINMENU +}; + void TitleScreen::update_load_game_menu() { @@ -190,8 +199,7 @@ TitleScreen::check_contrib_world_menu() if (contrib_world_menu->get_item_by_id(index).kind == MN_ACTION) { sound_manager->stop_music(); GameSession* session = - new GameSession( - current_world->get_level_filename(index), ST_GL_PLAY); + new GameSession(current_world->get_level_filename(index)); main_loop->push_screen(session); } } @@ -254,10 +262,18 @@ TitleScreen::make_tux_jump() TitleScreen::TitleScreen() { controller.reset(new CodeController()); - titlesession.reset(new GameSession("levels/misc/menu.stl", ST_GL_DEMO_GAME)); + titlesession.reset(new GameSession("levels/misc/menu.stl")); Player* player = titlesession->get_current_sector()->player; player->set_controller(controller.get()); + + main_menu.reset(new Menu()); + main_menu->set_pos(SCREEN_WIDTH/2, 335); + main_menu->add_entry(MNID_STARTGAME, _("Start Game")); + main_menu->add_entry(MNID_LEVELS_CONTRIB, _("Contrib Levels")); + main_menu->add_submenu(_("Options"), get_options_menu()); + main_menu->add_entry(MNID_CREDITS, _("Credits")); + main_menu->add_entry(MNID_QUITMAINMENU, _("Quit")); } TitleScreen::~TitleScreen() @@ -275,7 +291,7 @@ TitleScreen::setup() sector->activate(sector->player->get_pos()); } - Menu::set_current(main_menu); + Menu::set_current(main_menu.get()); } void @@ -291,12 +307,6 @@ TitleScreen::draw(DrawingContext& context) Sector* sector = titlesession->get_current_sector(); sector->draw(context); - /* - if (Menu::current() == main_menu) - context.draw_surface(logo, Vector(SCREEN_WIDTH/2 - logo->get_width()/2, 30), - LAYER_FOREGROUND1+1); - */ - context.draw_text(white_small_text, " SuperTux " PACKAGE_VERSION "\n", Vector(0, SCREEN_HEIGHT - 50), LEFT_ALLIGN, LAYER_FOREGROUND1); context.draw_text(white_small_text, @@ -322,7 +332,7 @@ TitleScreen::update(float elapsed_time) if(menu) { menu->update(); - if(menu == main_menu) { + if(menu == main_menu.get()) { switch (main_menu->check()) { case MNID_STARTGAME: // Start Game, ie. goto the slots menu @@ -362,7 +372,7 @@ TitleScreen::update(float elapsed_time) } update_load_save_game_menu(load_game_menu); - Menu::set_current(main_menu); + Menu::set_current(main_menu.get()); }*/ process_load_game_menu(); } else if(menu == contrib_menu.get()) { @@ -375,7 +385,7 @@ TitleScreen::update(float elapsed_time) // reopen menu of user closed it (so that the app doesn't close when user // accidently hit ESC) if(Menu::current() == 0) { - Menu::set_current(main_menu); + Menu::set_current(main_menu.get()); } } diff --git a/src/title.hpp b/src/title.hpp index 4ef55fe0a..746bce7ae 100644 --- a/src/title.hpp +++ b/src/title.hpp @@ -54,6 +54,7 @@ private: void check_contrib_world_menu(); void free_contrib_menu(); + std::auto_ptr main_menu; std::auto_ptr load_game_menu; std::auto_ptr contrib_menu; std::auto_ptr contrib_world_menu; diff --git a/src/world.cpp b/src/world.cpp index 6c3a5fbd6..53fcdb716 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -144,11 +144,9 @@ World::run() HSQUIRRELVM new_vm = ScriptManager::instance->create_thread(); Scripting::compile_and_run(new_vm, in, filename); } catch(std::exception& e) { + // fallback: try to load worldmap worldmap.stwm using namespace WorldMapNS; - // fallback try to load worldmap - std::auto_ptr worldmap (new WorldMap); - worldmap->loadmap(basedir + "worldmap.stwm"); - main_loop->push_screen(worldmap.release()); + main_loop->push_screen(new WorldMap(basedir + "worldmap.stwm")); } } diff --git a/src/worldmap/sprite_change.cpp b/src/worldmap/sprite_change.cpp index 7eb044f09..ee959fe63 100644 --- a/src/worldmap/sprite_change.cpp +++ b/src/worldmap/sprite_change.cpp @@ -22,16 +22,17 @@ #include "sprite_change.hpp" #include "sprite/sprite_manager.hpp" #include "sprite/sprite.hpp" +#include "video/drawing_context.hpp" namespace WorldMapNS { SpriteChange::SpriteChange(const lisp::Lisp* lisp) - : enter(false), in_stay_action(false) + : change_on_touch(false), in_stay_action(false) { lisp->get("x", pos.x); lisp->get("y", pos.y); - lisp->get("enter", enter); + lisp->get("change-on-touch", change_on_touch); std::string spritefile = ""; lisp->get("sprite", spritefile); @@ -46,8 +47,12 @@ SpriteChange::~SpriteChange() } void -SpriteChange::draw(DrawingContext& ) +SpriteChange::draw(DrawingContext& context) { + if(in_stay_action && stay_action != "") { + sprite->set_action(stay_action); + sprite->draw(context, pos * 32 + Vector(16, 16), LAYER_OBJECTS-1); + } } void diff --git a/src/worldmap/sprite_change.hpp b/src/worldmap/sprite_change.hpp index c572309d4..a597f7a0e 100644 --- a/src/worldmap/sprite_change.hpp +++ b/src/worldmap/sprite_change.hpp @@ -42,7 +42,7 @@ public: * should tuxs sprite change when the tile has been completely entered, * or already when the tile was just touched */ - bool enter; + bool change_on_touch; /// sprite to change tux image to std::auto_ptr sprite; /** diff --git a/src/worldmap/tux.cpp b/src/worldmap/tux.cpp index f1086af52..b660149df 100644 --- a/src/worldmap/tux.cpp +++ b/src/worldmap/tux.cpp @@ -26,6 +26,7 @@ #include "worldmap.hpp" #include "level.hpp" #include "special_tile.hpp" +#include "sprite_change.hpp" #include "control/joystickkeyboardcontroller.hpp" #include "main.hpp" @@ -127,21 +128,18 @@ Tux::tryStartWalking() // We got a new direction, so lets start walking when possible Vector next_tile; - if ((!level || level->solved) && worldmap->path_ok(input_direction, tile_pos, &next_tile)) - { + if ((!level || level->solved) + && worldmap->path_ok(input_direction, tile_pos, &next_tile)) { tile_pos = next_tile; moving = true; direction = input_direction; back_direction = reverse_dir(direction); - } - else if (input_direction == back_direction) - { + } else if (input_direction == back_direction) { moving = true; direction = input_direction; tile_pos = worldmap->get_next_tile(tile_pos, direction); back_direction = reverse_dir(direction); } - } bool @@ -156,16 +154,24 @@ Tux::canWalk(const Tile* tile, Direction dir) void Tux::tryContinueWalking(float elapsed_time) { - if (!moving) return; + if (!moving) + return; // Let tux walk offset += TUXSPEED * elapsed_time; // Do nothing if we have not yet reached the next tile - if (offset <= 32) return; + if (offset <= 32) + return; offset -= 32; + SpriteChange* sprite_change = worldmap->at_sprite_change(tile_pos); + if(sprite_change != NULL) { + sprite.reset(new Sprite( *(sprite_change->sprite.get()) )); + sprite_change->in_stay_action = false; + } + // if this is a special_tile with passive_message, display it SpecialTile* special_tile = worldmap->at_special_tile(); if(special_tile && special_tile->passive_message) @@ -182,36 +188,36 @@ Tux::tryContinueWalking(float elapsed_time) } } - - // stop if we reached a level, a WORLDMAP_STOP tile or a special tile without a passive_message - if ((worldmap->at_level()) || (worldmap->at(tile_pos)->getData() & Tile::WORLDMAP_STOP) || (special_tile && !special_tile->passive_message)) - { - if(special_tile && !special_tile->map_message.empty() && !special_tile->passive_message) worldmap->passive_message_timer.start(0); + if ((worldmap->at_level()) + || (worldmap->at(tile_pos)->getData() & Tile::WORLDMAP_STOP) + || (special_tile && !special_tile->passive_message)) { + if(special_tile && !special_tile->map_message.empty() + && !special_tile->passive_message) + worldmap->passive_message_timer.start(0); stop(); return; } // if user wants to change direction, try changing, else guess the direction in which to walk next const Tile* tile = worldmap->at(tile_pos); - if (direction != input_direction) - { - if(canWalk(tile, input_direction)) - { + if (direction != input_direction) { + if(canWalk(tile, input_direction)) { direction = input_direction; back_direction = reverse_dir(direction); } - } - else - { + } else { Direction dir = D_NONE; - if (tile->getData() & Tile::WORLDMAP_NORTH && back_direction != D_NORTH) dir = D_NORTH; - else if (tile->getData() & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH) dir = D_SOUTH; - else if (tile->getData() & Tile::WORLDMAP_EAST && back_direction != D_EAST) dir = D_EAST; - else if (tile->getData() & Tile::WORLDMAP_WEST && back_direction != D_WEST) dir = D_WEST; - - if (dir == D_NONE) - { + if (tile->getData() & Tile::WORLDMAP_NORTH && back_direction != D_NORTH) + dir = D_NORTH; + else if (tile->getData() & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH) + dir = D_SOUTH; + else if (tile->getData() & Tile::WORLDMAP_EAST && back_direction != D_EAST) + dir = D_EAST; + else if (tile->getData() & Tile::WORLDMAP_WEST && back_direction != D_WEST) + dir = D_WEST; + + if (dir == D_NONE) { // Should never be reached if tiledata is good log_warning << "Could not determine where to walk next" << std::endl; stop(); @@ -224,19 +230,28 @@ Tux::tryContinueWalking(float elapsed_time) } // Walk automatically to the next tile - if(direction != D_NONE) - { - Vector next_tile; - if (worldmap->path_ok(direction, tile_pos, &next_tile)) - { - tile_pos = next_tile; - } - else - { - log_warning << "Tilemap data is buggy" << std::endl; - stop(); - } + if(direction == D_NONE) + return; + + Vector next_tile; + if (!worldmap->path_ok(direction, tile_pos, &next_tile)) { + log_warning << "Tilemap data is buggy" << std::endl; + stop(); + return; + } + + SpriteChange* next_sprite = worldmap->at_sprite_change(next_tile); + if(next_sprite != NULL && next_sprite->change_on_touch) { + sprite.reset(new Sprite( *(next_sprite->sprite.get()) )); + next_sprite->in_stay_action = false; + } + SpriteChange* last_sprite = worldmap->at_sprite_change(tile_pos); + if(last_sprite != NULL && next_sprite != NULL) { + log_debug << "Old: " << tile_pos << " New: " << next_tile << std::endl; + last_sprite->in_stay_action = true; } + + tile_pos = next_tile; } void @@ -256,7 +271,10 @@ void Tux::update(float elapsed_time) { updateInputDirection(); - if (moving) tryContinueWalking(elapsed_time); else tryStartWalking(); + if (moving) + tryContinueWalking(elapsed_time); + else + tryStartWalking(); } } diff --git a/src/worldmap/worldmap.cpp b/src/worldmap/worldmap.cpp index 84423f391..39c2526f3 100644 --- a/src/worldmap/worldmap.cpp +++ b/src/worldmap/worldmap.cpp @@ -46,7 +46,6 @@ #include "sector.hpp" #include "worldmap.hpp" #include "resources.hpp" -#include "misc.hpp" #include "log.hpp" #include "world.hpp" #include "player_status.hpp" @@ -130,7 +129,7 @@ string_to_direction(const std::string& directory) //--------------------------------------------------------------------------- -WorldMap::WorldMap() +WorldMap::WorldMap(const std::string& filename) : tux(0), solids(0) { tile_manager.reset(new TileManager("images/worldmap.strf")); @@ -140,7 +139,6 @@ WorldMap::WorldMap() name = ""; music = "music/salcon.ogg"; - intro_displayed = false; total_stats.reset(); @@ -151,6 +149,8 @@ WorldMap::WorldMap() worldmap_menu->add_submenu(_("Options"), get_options_menu()); worldmap_menu->add_hl(); worldmap_menu->add_entry(MNID_QUITWORLDMAP, _("Quit World")); + + load(filename); } WorldMap::~WorldMap() @@ -158,7 +158,10 @@ WorldMap::~WorldMap() if(current_ == this) current_ = NULL; - clear_objects(); + for(GameObjects::iterator i = game_objects.begin(); + i != game_objects.end(); ++i) + delete *i; + for(SpawnPoints::iterator i = spawn_points.begin(); i != spawn_points.end(); ++i) { delete *i; @@ -177,21 +180,9 @@ WorldMap::add_object(GameObject* object) } void -WorldMap::clear_objects() -{ - for(GameObjects::iterator i = game_objects.begin(); - i != game_objects.end(); ++i) - delete *i; - game_objects.clear(); - solids = 0; - tux = new Tux(this); - add_object(tux); -} - -// Don't forget to set map_filename before calling this -void -WorldMap::load_map() +WorldMap::load(const std::string& filename) { + map_filename = filename; levels_path = FileSystem::dirname(map_filename); try { @@ -208,7 +199,6 @@ WorldMap::load_map() if(!sector) throw std::runtime_error("No sector sepcified in worldmap file."); - clear_objects(); lisp::ListIterator iter(sector); while(iter.next()) { if(iter.item() == "tilemap") { @@ -217,8 +207,6 @@ WorldMap::load_map() add_object(new Background(*(iter.lisp()))); } else if(iter.item() == "music") { iter.value()->get(music); - } else if(iter.item() == "intro-script") { - iter.value()->get(intro_script); } else if(iter.item() == "worldmap-spawnpoint") { SpawnPoint* sp = new SpawnPoint(iter.lisp()); spawn_points.push_back(sp); @@ -230,7 +218,7 @@ WorldMap::load_map() SpecialTile* special_tile = new SpecialTile(iter.lisp()); special_tiles.push_back(special_tile); game_objects.push_back(special_tile); - } else if(iter.item() == "spritechange") { + } else if(iter.item() == "sprite-change") { SpriteChange* sprite_change = new SpriteChange(iter.lisp()); sprite_changes.push_back(sprite_change); game_objects.push_back(sprite_change); @@ -329,7 +317,7 @@ WorldMap::get_next_tile(Vector pos, Direction direction) } bool -WorldMap::path_ok(Direction direction, Vector old_pos, Vector* new_pos) +WorldMap::path_ok(Direction direction, const Vector& old_pos, Vector* new_pos) { *new_pos = get_next_tile(old_pos, direction); @@ -359,7 +347,7 @@ WorldMap::path_ok(Direction direction, Vector old_pos, Vector* new_pos) && at(*new_pos)->getData() & Tile::WORLDMAP_NORTH); case D_NONE: - assert(!"path_ok() can't work if direction is NONE"); + assert(!"path_ok() can't walk if direction is NONE"); } return false; } @@ -516,14 +504,12 @@ WorldMap::update(float delta) if (level->pos == tux->get_tile_pos()) { // do a shriking fade to the level - shrink_fade(Vector((level->pos.x*32 + 16 + offset.x), - (level->pos.y*32 + 16 + offset.y)), 500); + shrink_fade(Vector((level->pos.x*32 + 16 + camera_offset.x), + (level->pos.y*32 + 16 + camera_offset.y)), 500); try { - GameSession *session = - new GameSession(levels_path + level->name, - ST_GL_LOAD_LEVEL_FILE, &level->statistics); - main_loop->push_screen(session); + main_loop->push_screen(new GameSession( + levels_path + level->name, &level->statistics)); } catch(std::exception& e) { log_fatal << "Couldn't load level: " << e.what() << std::endl; } @@ -567,8 +553,15 @@ WorldMap::at_special_tile() } SpriteChange* -WorldMap::at_sprite_change() +WorldMap::at_sprite_change(const Vector& pos) { + for(SpriteChanges::iterator i = sprite_changes.begin(); + i != sprite_changes.end(); ++i) { + SpriteChange* sprite_change = *i; + if(sprite_change->pos == pos) + return sprite_change; + } + return NULL; } @@ -897,12 +890,4 @@ WorldMap::solved_level_count() return count; } -void -WorldMap::loadmap(const std::string& filename) -{ - savegame_file = ""; - map_filename = filename; - load_map(); -} - } // namespace WorldMapNS diff --git a/src/worldmap/worldmap.hpp b/src/worldmap/worldmap.hpp index 69e1ca76c..9a089cb0d 100644 --- a/src/worldmap/worldmap.hpp +++ b/src/worldmap/worldmap.hpp @@ -62,7 +62,9 @@ std::string direction_to_string(Direction d); Direction string_to_direction(const std::string& d); Direction reverse_dir(Direction d); -/** */ +/** + * Screen that displays a worldmap + */ class WorldMap : public Screen { private: @@ -101,40 +103,23 @@ private: typedef std::vector SpawnPoints; SpawnPoints spawn_points; - Vector offset; - std::string savegame_file; - - std::string intro_script; - bool intro_displayed; - - void get_level_title(Level& level); - - void draw_status(DrawingContext& context); - - // to avoid calculating total stats all the time. This way only - // when need, it is calculated. Statistics total_stats; - void calculate_total_stats(); public: - WorldMap(); + WorldMap(const std::string& filename); ~WorldMap(); - void load_map(); - void add_object(GameObject* object); - void clear_objects(); static WorldMap* current() { return current_; } - void setup(); - - /** Update Tux position */ - void update(float delta); + virtual void setup(); - /** Draw one frame */ - void draw(DrawingContext& context); + /** Update worldmap state */ + virtual void update(float delta); + /** Draw worldmap */ + virtual void draw(DrawingContext& context); Vector get_next_tile(Vector pos, Direction direction); const Tile* at(Vector pos); @@ -150,11 +135,11 @@ public: Level* at_level(); SpecialTile* at_special_tile(); - SpriteChange* at_sprite_change(); + SpriteChange* at_sprite_change(const Vector& pos); /** Check if it is possible to walk from \a pos into \a direction, if possible, write the new position to \a new_pos */ - bool path_ok(Direction direction, Vector pos, Vector* new_pos); + bool path_ok(Direction direction, const Vector& pos, Vector* new_pos); /** * Save worldmap state to squirrel state table @@ -166,18 +151,15 @@ public: */ void load_state(); - /** - * Load a worldmap - */ - void loadmap(const std::string& filename); - const std::string& get_title() const { return name; } - void set_map_filename(std::string filename) - { map_filename = filename; } - private: + void get_level_title(Level& level); + void draw_status(DrawingContext& context); + void calculate_total_stats(); + + void load(const std::string& filename); void on_escape_press(); void parse_special_tile(const lisp::Lisp* lisp); void parse_sprite_change(const lisp::Lisp* lisp); -- 2.11.0