diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 6c1fe80ef..c395a95ae 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -31,8 +31,24 @@ bool scrape_cmdline = false; bool parseArgs(int argc, char* argv[]) { - Settings::getInstance()->setString("ExePath", argv[0]); + Utils::FileSystem::setExePath(argv[0]); + // We need to process --home before any call to Settings::getInstance(), because settings are loaded from homepath + for(int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "--home") == 0) + { + if (i >= argc - 1) + { + std::cerr << "Invalid home path supplied."; + return false; + } + + Utils::FileSystem::setHomePath(argv[i + 1]); + break; + } + } + for(int i = 1; i < argc; i++) { if(strcmp(argv[i], "--resolution") == 0) @@ -168,6 +184,7 @@ bool parseArgs(int argc, char* argv[]) "--force-kid Force the UI mode to be Kid\n" "--force-kiosk Force the UI mode to be Kiosk\n" "--force-disable-filters Force the UI to ignore applied filters in gamelist\n" + "--home [path] Directory to use as home path\n" "--help, -h summon a sentient, angry tuba\n\n" "More information available in README.md.\n"; return false; //exit after printing help diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 455bea453..e2c128645 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -33,8 +33,7 @@ std::vector settings_dont_save { { "ScreenHeight" }, { "ScreenOffsetX" }, { "ScreenOffsetY" }, - { "ScreenRotate" }, - { "ExePath" } + { "ScreenRotate" } }; Settings::Settings() @@ -161,8 +160,6 @@ void Settings::setDefaults() mIntMap["ScreenOffsetX"] = 0; mIntMap["ScreenOffsetY"] = 0; mIntMap["ScreenRotate"] = 0; - - mStringMap["ExePath"] = ""; } template diff --git a/es-core/src/utils/FileSystemUtil.cpp b/es-core/src/utils/FileSystemUtil.cpp index 5a0a351c9..bd2c84ba6 100644 --- a/es-core/src/utils/FileSystemUtil.cpp +++ b/es-core/src/utils/FileSystemUtil.cpp @@ -2,7 +2,6 @@ #include "utils/FileSystemUtil.h" -#include "Settings.h" #include #include @@ -26,6 +25,8 @@ namespace Utils { namespace FileSystem { + static std::string homePath; + static std::string exePath; #if defined(_WIN32) static std::string convertFromWideString(const std::wstring wstring) @@ -138,36 +139,46 @@ namespace Utils } // getPathList + void setHomePath(const std::string& _path) + { + homePath = getGenericPath(_path); + } + std::string getHomePath() { - static std::string path; + if(homePath.length()) + return homePath; - // only construct the homepath once - if(!path.length()) + // Is it a portable installation ? Check if ".emulationstation/es_systems.cfg" exists in the exe's path + if(Utils::FileSystem::exists(getExePath() + "/.emulationstation/es_systems.cfg")) + homePath = getExePath(); + + // Check for HOME environment variable + if(!homePath.length()) { - // this should give us something like "/home/YOUR_USERNAME" on Linux and "C:/Users/YOUR_USERNAME/" on Windows char* envHome = getenv("HOME"); if(envHome) - path = getGenericPath(envHome); - -#if defined(_WIN32) - // but does not seem to work for Windows XP or Vista, so try something else - if(!path.length()) - { - char* envHomeDrive = getenv("HOMEDRIVE"); - char* envHomePath = getenv("HOMEPATH"); - if(envHomeDrive && envHomePath) - path = getGenericPath(std::string(envHomeDrive) + "/" + envHomePath); - } -#endif // _WIN32 - - // no homepath found, fall back to current working directory - if(!path.length()) - path = getCWDPath(); + homePath = getGenericPath(envHome); } +#if defined(_WIN32) + // On Windows, HOME is not the system's user path but a user environment variable. + // Instead we get the home user's path using %HOMEDRIVE%/%HOMEPATH% which are system variables. + if(!homePath.length()) + { + char* envHomeDrive = getenv("HOMEDRIVE"); + char* envHomePath = getenv("HOMEPATH"); + if(envHomeDrive && envHomePath) + homePath = getGenericPath(std::string(envHomeDrive) + "/" + envHomePath); + } +#endif // _WIN32 + + // no homepath found, fall back to current working directory + if(!homePath.length()) + homePath = getCWDPath(); + // return constructed homepath - return path; + return homePath; } // getHomePath @@ -180,23 +191,18 @@ namespace Utils } // getCWDPath - std::string getExePath() + void setExePath(const std::string& _path) { - static std::string path; + std::string path = getCanonicalPath(_path); + if(isRegularFile(path)) + path = getParent(path); - // only construct the exepath once - if(!path.length()) - { - path = getCanonicalPath(Settings::getInstance()->getString("ExePath")); + exePath = path; + } // setExePath - if(isRegularFile(path)) - { - path = getParent(path); - } - } - - // return constructed exepath - return path; + std::string getExePath() + { + return exePath; } // getExePath diff --git a/es-core/src/utils/FileSystemUtil.h b/es-core/src/utils/FileSystemUtil.h index 48c7f4f5a..bb6ea6764 100644 --- a/es-core/src/utils/FileSystemUtil.h +++ b/es-core/src/utils/FileSystemUtil.h @@ -13,8 +13,10 @@ namespace Utils stringList getDirContent (const std::string& _path, const bool _recursive = false); stringList getPathList (const std::string& _path); + void setHomePath (const std::string& _path); std::string getHomePath (); std::string getCWDPath (); + void setExePath (const std::string& _path); std::string getExePath (); std::string getPreferredPath (const std::string& _path); std::string getGenericPath (const std::string& _path); @@ -37,7 +39,6 @@ namespace Utils bool isDirectory (const std::string& _path); bool isSymlink (const std::string& _path); bool isHidden (const std::string& _path); - } // FileSystem:: } // Utils::