|
|
@ -3,6 +3,7 @@ |
|
|
// Refer to the license.txt file included.
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
#include <sstream>
|
|
|
|
|
|
#include <unordered_map>
|
|
|
#include "common/assert.h"
|
|
|
#include "common/assert.h"
|
|
|
#include "common/common_funcs.h"
|
|
|
#include "common/common_funcs.h"
|
|
|
#include "common/common_paths.h"
|
|
|
#include "common/common_paths.h"
|
|
|
@ -681,67 +682,68 @@ std::string GetSysDirectory() { |
|
|
|
|
|
|
|
|
// Returns a string with a yuzu data dir or file in the user's home
|
|
|
// Returns a string with a yuzu data dir or file in the user's home
|
|
|
// directory. To be used in "multi-user" mode (that is, installed).
|
|
|
// directory. To be used in "multi-user" mode (that is, installed).
|
|
|
const std::string& GetUserPath(const unsigned int DirIDX, const std::string& newPath) { |
|
|
|
|
|
static std::string paths[NUM_PATH_INDICES]; |
|
|
|
|
|
|
|
|
const std::string& GetUserPath(UserPath path, const std::string& new_path) { |
|
|
|
|
|
static std::unordered_map<UserPath, std::string> paths; |
|
|
|
|
|
auto& user_path = paths[UserPath::UserDir]; |
|
|
|
|
|
|
|
|
// Set up all paths and files on the first run
|
|
|
// Set up all paths and files on the first run
|
|
|
if (paths[D_USER_IDX].empty()) { |
|
|
|
|
|
|
|
|
if (user_path.empty()) { |
|
|
#ifdef _WIN32
|
|
|
#ifdef _WIN32
|
|
|
paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; |
|
|
|
|
|
if (!FileUtil::IsDirectory(paths[D_USER_IDX])) { |
|
|
|
|
|
paths[D_USER_IDX] = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP; |
|
|
|
|
|
|
|
|
user_path = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP; |
|
|
|
|
|
if (!FileUtil::IsDirectory(user_path)) { |
|
|
|
|
|
user_path = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP; |
|
|
} else { |
|
|
} else { |
|
|
LOG_INFO(Common_Filesystem, "Using the local user directory"); |
|
|
LOG_INFO(Common_Filesystem, "Using the local user directory"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
|
|
|
|
|
paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
|
|
|
|
|
|
|
|
paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); |
|
|
|
|
|
paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); |
|
|
#else
|
|
|
#else
|
|
|
if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { |
|
|
if (FileUtil::Exists(ROOT_DIR DIR_SEP USERDATA_DIR)) { |
|
|
paths[D_USER_IDX] = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; |
|
|
|
|
|
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
|
|
|
|
|
paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
|
|
|
|
|
|
|
|
user_path = ROOT_DIR DIR_SEP USERDATA_DIR DIR_SEP; |
|
|
|
|
|
paths.emplace(UserPath::ConfigDir, user_path + CONFIG_DIR DIR_SEP); |
|
|
|
|
|
paths.emplace(UserPath::CacheDir, user_path + CACHE_DIR DIR_SEP); |
|
|
} else { |
|
|
} else { |
|
|
std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); |
|
|
std::string data_dir = GetUserDirectory("XDG_DATA_HOME"); |
|
|
std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME"); |
|
|
std::string config_dir = GetUserDirectory("XDG_CONFIG_HOME"); |
|
|
std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); |
|
|
std::string cache_dir = GetUserDirectory("XDG_CACHE_HOME"); |
|
|
|
|
|
|
|
|
paths[D_USER_IDX] = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; |
|
|
|
|
|
paths[D_CONFIG_IDX] = config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; |
|
|
|
|
|
paths[D_CACHE_IDX] = cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; |
|
|
|
|
|
|
|
|
user_path = data_dir + DIR_SEP EMU_DATA_DIR DIR_SEP; |
|
|
|
|
|
paths.emplace(UserPath::ConfigDir, config_dir + DIR_SEP EMU_DATA_DIR DIR_SEP); |
|
|
|
|
|
paths.emplace(UserPath::CacheDir, cache_dir + DIR_SEP EMU_DATA_DIR DIR_SEP); |
|
|
} |
|
|
} |
|
|
#endif
|
|
|
#endif
|
|
|
paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; |
|
|
|
|
|
paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; |
|
|
|
|
|
paths[D_SYSDATA_IDX] = paths[D_USER_IDX] + SYSDATA_DIR DIR_SEP; |
|
|
|
|
|
|
|
|
paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP); |
|
|
|
|
|
paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP); |
|
|
|
|
|
paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP); |
|
|
// TODO: Put the logs in a better location for each OS
|
|
|
// TODO: Put the logs in a better location for each OS
|
|
|
paths[D_LOGS_IDX] = paths[D_USER_IDX] + LOG_DIR DIR_SEP; |
|
|
|
|
|
|
|
|
paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (!newPath.empty()) { |
|
|
|
|
|
if (!FileUtil::IsDirectory(newPath)) { |
|
|
|
|
|
LOG_ERROR(Common_Filesystem, "Invalid path specified {}", newPath); |
|
|
|
|
|
return paths[DirIDX]; |
|
|
|
|
|
|
|
|
if (!new_path.empty()) { |
|
|
|
|
|
if (!FileUtil::IsDirectory(new_path)) { |
|
|
|
|
|
LOG_ERROR(Common_Filesystem, "Invalid path specified {}", new_path); |
|
|
|
|
|
return paths[path]; |
|
|
} else { |
|
|
} else { |
|
|
paths[DirIDX] = newPath; |
|
|
|
|
|
|
|
|
paths[path] = new_path; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
switch (DirIDX) { |
|
|
|
|
|
case D_ROOT_IDX: |
|
|
|
|
|
paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; |
|
|
|
|
|
|
|
|
switch (path) { |
|
|
|
|
|
case UserPath::RootDir: |
|
|
|
|
|
user_path = paths[UserPath::RootDir] + DIR_SEP; |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case D_USER_IDX: |
|
|
|
|
|
paths[D_USER_IDX] = paths[D_ROOT_IDX] + DIR_SEP; |
|
|
|
|
|
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP; |
|
|
|
|
|
paths[D_CACHE_IDX] = paths[D_USER_IDX] + CACHE_DIR DIR_SEP; |
|
|
|
|
|
paths[D_SDMC_IDX] = paths[D_USER_IDX] + SDMC_DIR DIR_SEP; |
|
|
|
|
|
paths[D_NAND_IDX] = paths[D_USER_IDX] + NAND_DIR DIR_SEP; |
|
|
|
|
|
|
|
|
case UserPath::UserDir: |
|
|
|
|
|
user_path = paths[UserPath::RootDir] + DIR_SEP; |
|
|
|
|
|
paths[UserPath::ConfigDir] = user_path + CONFIG_DIR DIR_SEP; |
|
|
|
|
|
paths[UserPath::CacheDir] = user_path + CACHE_DIR DIR_SEP; |
|
|
|
|
|
paths[UserPath::SDMCDir] = user_path + SDMC_DIR DIR_SEP; |
|
|
|
|
|
paths[UserPath::NANDDir] = user_path + NAND_DIR DIR_SEP; |
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return paths[DirIDX]; |
|
|
|
|
|
|
|
|
return paths[path]; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { |
|
|
size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { |
|
|
|