From 8a16f7745868e0969ead17fc6281e0788e37d1df Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Mon, 18 Aug 2014 21:01:35 +0200 Subject: [PATCH] Added --datadir/--userdir command line arguments and SUPERTUX2_DATA_DIR environment variable (probably redundant) --- src/supertux/command_line_arguments.cpp | 51 ++++++++++++++--- src/supertux/command_line_arguments.hpp | 3 + src/supertux/main.cpp | 99 ++++++++++++++++++++------------- 3 files changed, 108 insertions(+), 45 deletions(-) diff --git a/src/supertux/command_line_arguments.cpp b/src/supertux/command_line_arguments.cpp index 20073762d..37a38107c 100644 --- a/src/supertux/command_line_arguments.cpp +++ b/src/supertux/command_line_arguments.cpp @@ -29,6 +29,8 @@ CommandLineArguments::CommandLineArguments() : m_action(NO_ACTION), m_log_level(LOG_WARNING), + datadir(), + userdir(), fullscreen_size(), fullscreen_refresh_rate(), window_size(), @@ -68,32 +70,45 @@ void CommandLineArguments::print_help(const char* arg0) { std::cerr << boost::format(_( + "Usage: %s [OPTIONS] [LEVELFILE]\n" "\n" - "Usage: %s [OPTIONS] [LEVELFILE]\n\n" - "CommandLineArguments:\n" + "General Options:\n" + " -h, --help Show this help message and quit\n" + " -v, --version Show SuperTux version and quit\n" " --verbose Print verbose messages\n" " --debug Print extra verbose messages\n" + " --print-datadir Print supertux's primary data directory.\n" + "\n" + "Video 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" " -a, --aspect WIDTH:HEIGHT Run SuperTux with given aspect ratio\n" " -d, --default Reset video settings to default values\n" " --renderer RENDERER Use sdl, opengl, or auto to render\n" + "\n" + "Audio Options:\n" " --disable-sound Disable sound effects\n" " --disable-music Disable music\n" - " -h, --help Show this help message and quit\n" - " -v, --version Show SuperTux version and quit\n" + "\n" + "Game Options:\n" " --console Enable ingame scripting console\n" " --noconsole Disable ingame scripting console\n" " --show-fps Display framerate in levels\n" " --no-show-fps Do not display framerate in levels\n" + " -s, --debug-scripts Enable script debugger.\n" + "\n" + "Demo Recording Options:\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" - " --print-datadir Print supertux's primary data directory.\n" + "\n" + "Directory Options:\n" + " --datadir DIR Set the directory for the games datafiles\n" + " --userdir DIR Set the directory for user data (savegames, etc.)\n" "\n" "Environment variables:\n" - " SUPERTUX2_USER_DIR Directory for user data (savegames, etc.);\n" + " SUPERTUX2_USER_DIR Directory for user data (savegames, etc.)\n" + " SUPERTUX2_DATA_DIR Directory for the games datafiles\n" "\n" )) % arg0 @@ -137,6 +152,28 @@ CommandLineArguments::parse_args(int argc, char** argv) m_log_level = LOG_INFO; } } + else if (arg == "--datadir") + { + if (i+1 >= argc) + { + throw std::runtime_error("Need to specify a directory for --datadir"); + } + else + { + datadir = argv[++i]; + } + } + else if (arg == "--userdir") + { + if (i+1 >= argc) + { + throw std::runtime_error("Need to specify a directory for --userdir"); + } + else + { + userdir = argv[++i]; + } + } else if (arg == "--fullscreen" || arg == "-f") { use_fullscreen = true; diff --git a/src/supertux/command_line_arguments.hpp b/src/supertux/command_line_arguments.hpp index d47215c56..e76ebb76c 100644 --- a/src/supertux/command_line_arguments.hpp +++ b/src/supertux/command_line_arguments.hpp @@ -42,6 +42,9 @@ private: LogLevel m_log_level; public: + boost::optional datadir; + boost::optional userdir; + boost::optional fullscreen_size; boost::optional fullscreen_refresh_rate; boost::optional window_size; diff --git a/src/supertux/main.cpp b/src/supertux/main.cpp index 3e5402069..c7efd5531 100644 --- a/src/supertux/main.cpp +++ b/src/supertux/main.cpp @@ -20,11 +20,12 @@ #include #include -#include -#include -#include #include +#include +#include +#include #include +#include extern "C" { #include } @@ -113,8 +114,16 @@ Main::init_tinygettext() class PhysfsSubsystem { +private: + boost::optional m_forced_datadir; + boost::optional m_forced_userdir; + public: - PhysfsSubsystem(const char* argv0) + PhysfsSubsystem(const char* argv0, + boost::optional forced_datadir, + boost::optional forced_userdir) : + m_forced_datadir(forced_datadir), + m_forced_userdir(forced_userdir) { if (!PHYSFS_init(argv0)) { @@ -134,19 +143,31 @@ public: void find_datadir() { - // check if we run from source dir - char* basepath_c = SDL_GetBasePath(); - std::string basepath = basepath_c; - SDL_free(basepath_c); - - std::string datadir = FileSystem::join(basepath, "data"); - std::string testfname = FileSystem::join(datadir, "credits.txt"); - if (!FileSystem::exists(testfname)) + std::string datadir; + if (m_forced_datadir) + { + datadir = *m_forced_datadir; + } + else if (const char* env_datadir = getenv("SUPERTUX2_DATA_DIR")) + { + datadir = env_datadir; + } + else { - // if the game is not run from the source directory, try to find - // the global install location - datadir = datadir.substr(0, datadir.rfind(INSTALL_SUBDIR_BIN)); - datadir = FileSystem::join(datadir, INSTALL_SUBDIR_SHARE); + // check if we run from source dir + char* basepath_c = SDL_GetBasePath(); + std::string basepath = basepath_c; + SDL_free(basepath_c); + + datadir = FileSystem::join(basepath, "data"); + std::string testfname = FileSystem::join(datadir, "credits.txt"); + if (!FileSystem::exists(testfname)) + { + // if the game is not run from the source directory, try to find + // the global install location + datadir = datadir.substr(0, datadir.rfind(INSTALL_SUBDIR_BIN)); + datadir = FileSystem::join(datadir, INSTALL_SUBDIR_SHARE); + } } if (!PHYSFS_addToSearchPath(datadir.c_str(), 1)) @@ -157,48 +178,50 @@ public: void find_userdir() { -#ifdef _WIN32 -# define WRITEDIR_NAME PACKAGE_NAME -#else -# define WRITEDIR_NAME "." PACKAGE_NAME -#endif - - std::string writedir; - - const char* env_writedir = getenv("SUPERTUX2_USER_DIR"); - if (env_writedir) + std::string userdir; + if (m_forced_userdir) { - writedir = env_writedir; + userdir = *m_forced_userdir; + } + else if (const char* env_userdir = getenv("SUPERTUX2_USER_DIR")) + { + userdir = env_userdir; } else { - std::string userdir = PHYSFS_getUserDir(); - writedir = FileSystem::join(userdir, WRITEDIR_NAME); + std::string physfs_userdir = PHYSFS_getUserDir(); +#ifdef _WIN32 + userdir = FileSystem::join(physfs_userdir, "." PACKAGE_NAME); +#else + userdir = FileSystem::join(physfs_userdir, PACKAGE_NAME); +#endif } - if (!FileSystem::is_directory(writedir)) + if (!FileSystem::is_directory(userdir)) { - FileSystem::mkdir(writedir); - log_info << "Created SuperTux userdir: " << writedir << std::endl; + FileSystem::mkdir(userdir); + log_info << "Created SuperTux userdir: " << userdir << std::endl; } - if (!PHYSFS_setWriteDir(writedir.c_str())) + if (!PHYSFS_setWriteDir(userdir.c_str())) { std::ostringstream msg; - msg << "Failed to use configuration directory '" - << writedir << "': " << PHYSFS_getLastError(); + msg << "Failed to use userdir directory '" + << userdir << "': " << PHYSFS_getLastError(); throw std::runtime_error(msg.str()); } - PHYSFS_addToSearchPath(writedir.c_str(), 0); + PHYSFS_addToSearchPath(userdir.c_str(), 0); } void print_search_path() { + const char* writedir = PHYSFS_getWriteDir(); + log_info << "PhysfsWritedDir: " << (writedir || "") << std::endl; char** searchpath = PHYSFS_getSearchPath(); for(char** i = searchpath; *i != NULL; ++i) { - log_info << "[" << *i << "] is in the search path" << std::endl; + log_info << "PhysfsSearchPath: " << *i << std::endl; } PHYSFS_freeList(searchpath); } @@ -372,7 +395,7 @@ Main::run(int argc, char** argv) return EXIT_FAILURE; } - PhysfsSubsystem physfs_subsystem(argv[0]); + PhysfsSubsystem physfs_subsystem(argv[0], args.datadir, args.userdir); physfs_subsystem.print_search_path(); timelog("config"); -- 2.11.0