diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index 0adeb8a4..38097443 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -180,6 +180,7 @@ set(UNLEASHED_RECOMP_USER_CXX_SOURCES "user/achievement_manager.cpp" "user/config.cpp" "user/registry.cpp" + "user/paths.cpp" ) set(UNLEASHED_RECOMP_MOD_CXX_SOURCES diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index a88882ba..656a9382 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -152,6 +152,14 @@ int main(int argc, char *argv[]) os::logger::Init(); + Registry::Load(); + + if (!Registry::RootDirectoryPath.empty()) + { + if (!os::process::SetWorkingDirectory(std::filesystem::path(Registry::RootDirectoryPath))) + LOGFN_ERROR("Failed to set working directory: \"{}\"", Registry::RootDirectoryPath.string()); + } + bool forceInstaller = false; bool forceDLCInstaller = false; const char *sdlVideoDriver = nullptr; @@ -171,13 +179,6 @@ int main(int argc, char *argv[]) } Config::Load(); - Registry::Load(); - - if (!Registry::RootDirectoryPath.empty()) - { - if (!os::process::SetWorkingDirectory(std::filesystem::path(Registry::RootDirectoryPath))) - LOGFN_ERROR("Failed to set working directory: \"{}\"", Registry::RootDirectoryPath.string()); - } HostStartup(); diff --git a/UnleashedRecomp/user/paths.cpp b/UnleashedRecomp/user/paths.cpp new file mode 100644 index 00000000..398fb152 --- /dev/null +++ b/UnleashedRecomp/user/paths.cpp @@ -0,0 +1,52 @@ +#include "paths.h" +#include + +std::filesystem::path g_executableRoot = os::process::GetExecutablePath().remove_filename(); +std::filesystem::path g_userPath = BuildUserPath(); + +bool CheckPortable() +{ + return std::filesystem::exists(g_executableRoot / "/portable.txt"); +} + +std::filesystem::path BuildUserPath() +{ + if (CheckPortable()) + return g_executableRoot; + + std::filesystem::path userPath; + +#if defined(_WIN32) + PWSTR knownPath = NULL; + if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &knownPath) == S_OK) + userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY; + + CoTaskMemFree(knownPath); +#elif defined(__linux__) + const char* homeDir = getenv("HOME"); + if (homeDir == nullptr) + { + homeDir = getpwuid(getuid())->pw_dir; + } + + if (homeDir != nullptr) + { + // Prefer to store in the .config directory if it exists. Use the home directory otherwise. + std::filesystem::path homePath = homeDir; + std::filesystem::path configPath = homePath / ".config"; + if (std::filesystem::exists(configPath)) + userPath = configPath / USER_DIRECTORY; + else + userPath = homePath / ("." USER_DIRECTORY); + } +#else + static_assert(false, "GetUserPath() not implemented for this platform."); +#endif + + return userPath; +} + +const std::filesystem::path& GetUserPath() +{ + return g_userPath; +} diff --git a/UnleashedRecomp/user/paths.h b/UnleashedRecomp/user/paths.h index 003f4eb7..951a637a 100644 --- a/UnleashedRecomp/user/paths.h +++ b/UnleashedRecomp/user/paths.h @@ -13,49 +13,16 @@ inline std::filesystem::path GetGamePath() return GAME_INSTALL_DIRECTORY; } -inline std::filesystem::path GetUserPath() -{ - if (std::filesystem::exists(GAME_INSTALL_DIRECTORY "/portable.txt")) - return GAME_INSTALL_DIRECTORY; - - std::filesystem::path userPath; - -#if defined(_WIN32) - PWSTR knownPath = NULL; - if (SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &knownPath) == S_OK) - userPath = std::filesystem::path{ knownPath } / USER_DIRECTORY; - - CoTaskMemFree(knownPath); -#elif defined(__linux__) - const char *homeDir = getenv("HOME"); - if (homeDir == nullptr) - { - homeDir = getpwuid(getuid())->pw_dir; - } - - if (homeDir != nullptr) - { - // Prefer to store in the .config directory if it exists. Use the home directory otherwise. - std::filesystem::path homePath = homeDir; - std::filesystem::path configPath = homePath / ".config"; - if (std::filesystem::exists(configPath)) - userPath = configPath / USER_DIRECTORY; - else - userPath = homePath / ("." USER_DIRECTORY); - } -#else - static_assert(false, "GetUserPath() not implemented for this platform."); -#endif - - return userPath; -} +bool CheckPortable(); +std::filesystem::path BuildUserPath(); +const std::filesystem::path& GetUserPath(); inline std::filesystem::path GetSavePath(bool checkForMods) { if (checkForMods && !ModLoader::s_saveFilePath.empty()) return ModLoader::s_saveFilePath.parent_path(); else - return GetUserPath() / "save"; + return BuildUserPath() / "save"; } // Returned file name may not necessarily be