X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fmain.cpp;h=8bf4657d6e2c664e527531e4a5b31ac7a26a3f62;hb=d963f8dc3d2c4e432d3eeecd15351169e10243da;hp=1b5653b9474e6f617ddc3767ba1120ec347be203;hpb=311e23e2671e47d5cbbb06a869282be3238573de;p=supertux.git diff --git a/src/main.cpp b/src/main.cpp index 1b5653b94..8bf4657d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ // $Id$ -// +// // SuperTux -// Copyright (C) 2005 Matthias Braun +// 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 @@ -12,7 +12,7 @@ // 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 @@ -20,10 +20,10 @@ #include #include +#include "log.hpp" #include "main.hpp" #include -#include #include #include #include @@ -34,9 +34,8 @@ #include #include #include -#include #include -#include +#include #include "gameconfig.hpp" #include "resources.hpp" @@ -44,13 +43,17 @@ #include "audio/sound_manager.hpp" #include "video/surface.hpp" #include "video/texture_manager.hpp" +#include "video/glutil.hpp" #include "control/joystickkeyboardcontroller.hpp" -#include "misc.hpp" +#include "options_menu.hpp" +#include "mainloop.hpp" #include "title.hpp" #include "game_session.hpp" +#include "scripting/level.hpp" +#include "scripting/squirrel_util.hpp" #include "file_system.hpp" #include "physfs/physfs_sdl.hpp" -#include "exceptions.hpp" +#include "random_generator.hpp" SDL_Surface* screen = 0; JoystickKeyboardController* main_controller = 0; @@ -62,8 +65,7 @@ static void init_config() try { config->load(); } catch(std::exception& e) { - std::cerr << "Couldn't load config file: " << e.what() << "\n"; - std::cerr << "Using default settings.\n"; + log_info << "Couldn't load config file: " << e.what() << ", using default settings" << std::endl; } } @@ -146,12 +148,28 @@ static void init_physfs(const char* argv0) if(f) { fclose(f); if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) { - std::cout << "Warning: Couldn't add '" << dir - << "' to physfs searchpath: " << PHYSFS_getLastError() << "\n"; + log_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl; + } else { + sourcedir = true; + } + } + +#ifdef MACOSX + // when started from Application file on Mac OS X... + dir = PHYSFS_getBaseDir(); + dir += "SuperTux.app/Contents/Resources/data"; + testfname = dir + "/credits.txt"; + sourcedir = false; + f = fopen(testfname.c_str(), "r"); + if(f) { + fclose(f); + if(!PHYSFS_addToSearchPath(dir.c_str(), 1)) { + msg_warning << "Couldn't add '" << dir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl; } else { sourcedir = true; } } +#endif if(!sourcedir) { #if defined(APPDATADIR) || defined(ENABLE_BINRELOC) @@ -164,8 +182,7 @@ static void init_physfs(const char* argv0) datadir = APPDATADIR; #endif if(!PHYSFS_addToSearchPath(datadir.c_str(), 1)) { - std::cout << "Couldn't add '" << datadir - << "' to physfs searchpath: " << PHYSFS_getLastError() << "\n"; + log_warning << "Couldn't add '" << datadir << "' to physfs searchpath: " << PHYSFS_getLastError() << std::endl; } #endif } @@ -175,7 +192,7 @@ static void init_physfs(const char* argv0) //show search Path for(char** i = PHYSFS_getSearchPath(); *i != NULL; i++) - printf("[%s] is in the search path.\n", *i); + log_info << "[" << *i << "] is in the search path" << std::endl; } static void print_usage(const char* argv0) @@ -196,7 +213,7 @@ static void print_usage(const char* argv0) "\n")); } -static void parse_commandline(int argc, char** argv) +static bool parse_commandline(int argc, char** argv) { for(int i = 1; i < argc; ++i) { std::string arg = argv[i]; @@ -233,30 +250,33 @@ static void parse_commandline(int argc, char** argv) throw std::runtime_error("Need to specify a demo filename"); } config->record_demo = argv[++i]; + } else if(arg == "-d") { + config->enable_script_debugger = true; } else if(arg == "--help") { print_usage(argv[0]); - throw graceful_shutdown(); + return true; } else if(arg == "--version") { - std::cerr << PACKAGE_NAME << " " << PACKAGE_VERSION << "\n"; - throw graceful_shutdown(); + log_info << PACKAGE_NAME << " " << PACKAGE_VERSION << std::endl; + return true; } else if(arg[0] != '-') { config->start_level = arg; } else { - std::cerr << "Unknown option '" << arg << "'.\n"; - std::cerr << "Use --help to see a list of options.\n"; + log_warning << "Unknown option '" << arg << "'. Use --help to see a list of options" << std::endl; } } - // TODO joystick switchyes... + return false; } static void init_sdl() { - if(SDL_Init(SDL_INIT_EVERYTHING) < 0) { + if(SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { std::stringstream msg; msg << "Couldn't initialize SDL: " << SDL_GetError(); throw std::runtime_error(msg.str()); } + // just to be sure + atexit(SDL_Quit); SDL_EnableUNICODE(1); @@ -268,42 +288,13 @@ static void init_sdl() ; } -static void check_gl_error() +static void init_rand() { - GLenum glerror = glGetError(); - std::string errormsg; - - if(glerror != GL_NO_ERROR) { - switch(glerror) { - case GL_INVALID_ENUM: - errormsg = "Invalid enumeration value"; - break; - case GL_INVALID_VALUE: - errormsg = "Numeric argzment out of range"; - break; - case GL_INVALID_OPERATION: - errormsg = "Invalid operation"; - break; - case GL_STACK_OVERFLOW: - errormsg = "stack overflow"; - break; - case GL_STACK_UNDERFLOW: - errormsg = "stack underflow"; - break; - case GL_OUT_OF_MEMORY: - errormsg = "out of memory"; - break; - case GL_TABLE_TOO_LARGE: - errormsg = "table too large"; - break; - default: - errormsg = "unknown error number"; - break; - } - std::stringstream msg; - msg << "OpenGL Error: " << errormsg; - throw std::runtime_error(msg.str()); - } + const char *how = config->random_seed? ", user fixed.": ", from time()."; + + config->random_seed = systemRandom.srand(config->random_seed); + + log_info << "Using random seed " << config->random_seed << how << std::endl; } void init_video() @@ -342,7 +333,7 @@ void init_video() } #ifdef DEBUG else { - std::cerr << "Warning: Couldn't find icon 'images/engine/icons/supertux.xpm'.\n"; + log_warning << "Couldn't find icon 'images/engine/icons/supertux.xpm'" << std::endl; } #endif @@ -362,7 +353,7 @@ void init_video() glLoadIdentity(); glTranslatef(0, 0, 0); - check_gl_error(); + check_gl_error("Setting up view matrices"); if(texture_manager != NULL) texture_manager->reload_textures(); @@ -380,9 +371,9 @@ static void init_audio() static void quit_audio() { - if(sound_manager) { + if(sound_manager != NULL) { delete sound_manager; - sound_manager = 0; + sound_manager = NULL; } } @@ -399,7 +390,7 @@ void wait_for_event(float min_delay, float max_delay) sound_manager->update(); } - // clear even queue + // clear event queue SDL_Event event; while (SDL_PollEvent(&event)) {} @@ -411,7 +402,8 @@ void wait_for_event(float min_delay, float max_delay) while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: - throw graceful_shutdown(); + main_loop->quit(); + break; case SDL_KEYDOWN: case SDL_JOYBUTTONDOWN: case SDL_MOUSEBUTTONDOWN: @@ -425,57 +417,109 @@ void wait_for_event(float min_delay, float max_delay) } } +#ifdef DEBUG +static Uint32 last_timelog_ticks = 0; +static const char* last_timelog_component = 0; + +static inline void timelog(const char* component) +{ + Uint32 current_ticks = SDL_GetTicks(); + + if(last_timelog_component != 0) { + log_info << "Component '" << last_timelog_component << "' finished after " << (current_ticks - last_timelog_ticks) / 1000.0 << " seconds" << std::endl; + } + + last_timelog_ticks = current_ticks; + last_timelog_component = component; +} +#else +static inline void timelog(const char* ) +{ +} +#endif + int main(int argc, char** argv) { + int result = 0; + try { - srand(time(0)); + Console::instance = new Console(); +// srand(time(0)); // this breaks repeatability in random numbers init_physfs(argv[0]); init_sdl(); + + timelog("controller"); main_controller = new JoystickKeyboardController(); + timelog("config"); init_config(); + timelog("tinygettext"); init_tinygettext(); - parse_commandline(argc, argv); + timelog("commandline"); + if(parse_commandline(argc, argv)) + return 0; + timelog("audio"); init_audio(); + timelog("video"); init_video(); - - setup_menu(); - load_shared(); + Console::instance->init_graphics(); + timelog("scripting"); + Scripting::init_squirrel(config->enable_script_debugger); + timelog("resources"); + load_shared(); + timelog(0); + + main_loop = new MainLoop(); if(config->start_level != "") { // we have a normal path specified at commandline not physfs paths. // So we simply mount that path here... std::string dir = FileSystem::dirname(config->start_level); PHYSFS_addToSearchPath(dir.c_str(), true); - GameSession session( - FileSystem::basename(config->start_level), ST_GL_LOAD_LEVEL_FILE); + + init_rand(); // play_demo sets seed, record_demo uses it + + std::auto_ptr session + (new GameSession(FileSystem::basename(config->start_level))); if(config->start_demo != "") - session.play_demo(config->start_demo); + session->play_demo(config->start_demo); + if(config->record_demo != "") - session.record_demo(config->record_demo); - session.run(); + session->record_demo(config->record_demo); + main_loop->push_screen(session.release()); } else { - // normal game - title(); + init_rand(); + main_loop->push_screen(new TitleScreen()); } - } catch(graceful_shutdown& e) { + + main_loop->run(); + } catch(std::exception& e) { - std::cerr << "Unexpected exception: " << e.what() << std::endl; - return 1; + log_fatal << "Unexpected exception: " << e.what() << std::endl; + result = 1; } catch(...) { - std::cerr << "Unexpected exception." << std::endl; - return 1; + log_fatal << "Unexpected exception" << std::endl; + result = 1; } - free_menu(); + delete main_loop; + main_loop = NULL; + + free_options_menu(); unload_shared(); quit_audio(); if(config) config->save(); delete config; + config = NULL; delete main_controller; + main_controller = NULL; + delete Console::instance; + Console::instance = NULL; + Scripting::exit_squirrel(); delete texture_manager; + texture_manager = NULL; SDL_Quit(); PHYSFS_deinit(); - return 0; + return result; }