#include <iostream>
#include <binreloc.h>
#include <tinygettext/log.hpp>
+#include <boost/format.hpp>
+extern "C" {
+#include <findlocale.h>
+}
#include "supertux/main.hpp"
#include "scripting/squirrel_util.hpp"
#include "supertux/gameconfig.hpp"
#include "supertux/globals.hpp"
+#include "supertux/player_status.hpp"
#include "supertux/screen_manager.hpp"
#include "supertux/resources.hpp"
#include "supertux/title_screen.hpp"
namespace { DrawingContext *context_pointer; }
+#ifdef _WIN32
+# define WRITEDIR_NAME PACKAGE_NAME
+#else
+# define WRITEDIR_NAME "." PACKAGE_NAME
+#endif
+
void
Main::init_config()
{
if (g_config->locale != "")
{
dictionary_manager->set_language(tinygettext::Language::from_name(g_config->locale));
+ } else {
+ FL_Locale *locale;
+ FL_FindLocale(&locale);
+ tinygettext::Language language = tinygettext::Language::from_spec( locale->lang?locale->lang:"", locale->country?locale->country:"", locale->variant?locale->variant:"");
+ FL_FreeLocale(&locale);
+ dictionary_manager->set_language(language);
}
}
PHYSFS_permitSymbolicLinks(1);
// Initialize physfs (this is a slightly modified version of
- // PHYSFS_setSaneConfig
- const char* application = PACKAGE_NAME;
- const char* userdir = PHYSFS_getUserDir();
- char* writedir = new char[strlen(userdir) + strlen(application) + 2];
-
- // Set configuration directory
- sprintf(writedir, "%s.%s", userdir, application);
- if(!PHYSFS_setWriteDir(writedir)) {
- // try to create the directory
- char* mkdir = new char[strlen(application) + 2];
- sprintf(mkdir, ".%s", application);
- if(!PHYSFS_setWriteDir(userdir) || !PHYSFS_mkdir(mkdir)) {
- std::ostringstream msg;
- msg << "Failed creating configuration directory '"
- << writedir << "': " << PHYSFS_getLastError();
- delete[] writedir;
- delete[] mkdir;
- throw std::runtime_error(msg.str());
- }
- delete[] mkdir;
+ // PHYSFS_setSaneConfig)
+ const char *env_writedir;
+ std::string writedir;
- if(!PHYSFS_setWriteDir(writedir)) {
+ if ((env_writedir = getenv("SUPERTUX2_USER_DIR")) != NULL) {
+ writedir = env_writedir;
+ if(!PHYSFS_setWriteDir(writedir.c_str())) {
std::ostringstream msg;
msg << "Failed to use configuration directory '"
<< writedir << "': " << PHYSFS_getLastError();
- delete[] writedir;
throw std::runtime_error(msg.str());
}
+
+ } else {
+ std::string userdir = PHYSFS_getUserDir();
+
+ // Set configuration directory
+ writedir = userdir + WRITEDIR_NAME;
+ if(!PHYSFS_setWriteDir(writedir.c_str())) {
+ // try to create the directory
+ if(!PHYSFS_setWriteDir(userdir.c_str()) || !PHYSFS_mkdir(WRITEDIR_NAME)) {
+ std::ostringstream msg;
+ msg << "Failed creating configuration directory '"
+ << writedir << "': " << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
+
+ if(!PHYSFS_setWriteDir(writedir.c_str())) {
+ std::ostringstream msg;
+ msg << "Failed to use configuration directory '"
+ << writedir << "': " << PHYSFS_getLastError();
+ throw std::runtime_error(msg.str());
+ }
+ }
}
- PHYSFS_addToSearchPath(writedir, 0);
- delete[] writedir;
+ PHYSFS_addToSearchPath(writedir.c_str(), 0);
// when started from source dir...
std::string dir = PHYSFS_getBaseDir();
- dir += "/data";
+ if (dir[dir.length() - 1] != '/')
+ dir += "/";
+ dir += "data";
std::string testfname = dir;
testfname += "/credits.txt";
bool sourcedir = false;
void
Main::print_usage(const char* argv0)
{
- std::cerr << _("Usage: ") << argv0 << _(" [OPTIONS] [LEVELFILE]\n\n")
- << _("Options:\n"
+ std::string default_user_data_dir =
+ std::string(PHYSFS_getUserDir()) + WRITEDIR_NAME;
+
+ std::cerr << boost::format(_(
+ "\n"
+ "Usage: %s [OPTIONS] [LEVELFILE]\n\n"
+ "Options:\n"
" -f, --fullscreen Run in fullscreen mode\n"
" -w, --window Run in window mode\n"
" -g, --geometry WIDTHxHEIGHT Run SuperTux in given resolution\n"
" --record-demo FILE LEVEL Record a demo to FILE\n"
" --play-demo FILE LEVEL Play a recorded demo\n"
" -s, --debug-scripts Enable script debugger.\n"
- "\n")
+ " --print-datadir Print supertux's primary data directory.\n"
+ "\n"
+ "Environment variables:\n"
+ " SUPERTUX2_USER_DIR Directory for user data (savegames, etc.);\n"
+ " default %s\n"
+ "\n"
+ ))
+ % argv0 % default_user_data_dir
<< std::flush;
}
print_usage(argv[0]);
return true;
}
+ if(arg == "--print-datadir") {
+ /*
+ * Print the datadir searchpath to stdout, one path per
+ * line. Then exit. Intended for use by the supertux-editor.
+ */
+ char **sp;
+ size_t sp_index;
+ sp = PHYSFS_getSearchPath();
+ if (sp)
+ for (sp_index = 0; sp[sp_index]; sp_index++)
+ std::cout << sp[sp_index] << std::endl;
+ PHYSFS_freeList(sp);
+ return true;
+ }
}
return false;
void
Main::init_rand()
{
- g_config->random_seed = systemRandom.srand(g_config->random_seed);
+ g_config->random_seed = gameRandom.srand(g_config->random_seed);
+
+ graphicsRandom.srand(0);
//const char *how = config->random_seed? ", user fixed.": ", from time().";
//log_info << "Using random seed " << config->random_seed << how << std::endl;
SDL_WM_SetIcon(icon, 0);
SDL_FreeSurface(icon);
}
-#ifndef NDEBUG
else {
log_warning << "Couldn't load icon '" << icon_fname << "'" << std::endl;
}
-#endif
SDL_ShowCursor(0);
}
}
-#ifndef NDEBUG
static Uint32 last_timelog_ticks = 0;
static const char* last_timelog_component = 0;
last_timelog_ticks = current_ticks;
last_timelog_component = component;
}
-#else
-static inline void timelog(const char* )
-{
-}
-#endif
int
Main::run(int argc, char** argv)
int result = 0;
try {
+ /* Do this before pre_parse_commandline, because --help now shows the
+ * default user data dir. */
+ init_physfs(argv[0]);
if(pre_parse_commandline(argc, argv))
return 0;
Console::instance = new Console();
- init_physfs(argv[0]);
init_sdl();
timelog("controller");
- g_main_controller = new JoystickKeyboardController();
+ g_jk_controller = new JoystickKeyboardController();
timelog("config");
init_config();
timelog(0);
+ const std::auto_ptr<PlayerStatus> default_playerstatus(new PlayerStatus());
+
g_screen_manager = new ScreenManager();
+
+ init_rand();
+
if(g_config->start_level != "") {
// we have a normal path specified at commandline, not a physfs path.
// So we simply mount that path here...
if(g_config->start_level.size() > 4 &&
g_config->start_level.compare(g_config->start_level.size() - 5, 5, ".stwm") == 0) {
- init_rand();
g_screen_manager->push_screen(new worldmap::WorldMap(
- FileSystem::basename(g_config->start_level)));
+ FileSystem::basename(g_config->start_level), default_playerstatus.get()));
} else {
- init_rand();//If level uses random eg. for
- // rain particles before we do this:
std::auto_ptr<GameSession> session (
- new GameSession(FileSystem::basename(g_config->start_level)));
+ new GameSession(FileSystem::basename(g_config->start_level), default_playerstatus.get()));
g_config->random_seed =session->get_demo_random_seed(g_config->start_demo);
init_rand();//initialise generator with seed from session
g_screen_manager->push_screen(session.release());
}
} else {
- init_rand();
- g_screen_manager->push_screen(new TitleScreen());
+ g_screen_manager->push_screen(new TitleScreen(default_playerstatus.get()));
}
- //init_rand(); PAK: this call might subsume the above 3, but I'm chicken!
g_screen_manager->run(context);
} catch(std::exception& e) {
log_fatal << "Unexpected exception: " << e.what() << std::endl;
g_config->save();
delete g_config;
g_config = NULL;
- delete g_main_controller;
- g_main_controller = NULL;
+ delete g_jk_controller;
+ g_jk_controller = NULL;
delete Console::instance;
Console::instance = NULL;
scripting::exit_squirrel();