diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index af4d18288..fd1a3fd30 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -729,6 +729,33 @@ void SetUserPath(const std::string& path) { g_paths.emplace(UserPath::StatesDir, user_path + STATES_DIR DIR_SEP); } +std::string g_currentRomPath{}; + +void SetCurrentRomPath(const std::string& path) { + g_currentRomPath = path; +} + +bool StringReplace(std::string& haystack, const std::string& a, const std::string& b, bool swap) { + const auto& needle = swap ? b : a; + const auto& replacement = swap ? a : b; + if (needle.empty()) { + return false; + } + auto index = haystack.find(needle, 0); + if (index == std::string::npos) { + return false; + } + haystack.replace(index, needle.size(), replacement); + return true; +} + +std::string SerializePath(const std::string& input, bool is_saving) { + auto result = input; + StringReplace(result, "%CITRA_ROM_FILE%", g_currentRomPath, is_saving); + StringReplace(result, "%CITRA_USER_DIR%", GetUserPath(UserPath::UserDir), is_saving); + return result; +} + const std::string& GetUserPath(UserPath path) { // Set up all paths and files on the first run if (g_paths.empty()) diff --git a/src/common/file_util.h b/src/common/file_util.h index 1b1e65609..9eafa2416 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -140,10 +140,15 @@ bool SetCurrentDir(const std::string& directory); void SetUserPath(const std::string& path = ""); +void SetCurrentRomPath(const std::string& path); + // Returns a pointer to a string with a Citra data dir in the user's home // directory. To be used in "multi-user" mode (that is, installed). const std::string& GetUserPath(UserPath path); +// Replaces install-specific paths with standard placeholders, and back again +std::string SerializePath(const std::string& input, bool is_saving); + // Returns the path to where the sys file are std::string GetSysDirectory(); @@ -318,7 +323,8 @@ private: template void save(Archive& ar, const unsigned int) const { - ar << filename; + auto s_filename = SerializePath(filename, true); + ar << s_filename; ar << openmode; ar << flags; ar << Tell(); @@ -327,6 +333,7 @@ private: template void load(Archive& ar, const unsigned int) { ar >> filename; + filename = SerializePath(filename, false); ar >> openmode; ar >> flags; u64 pos; diff --git a/src/core/core.cpp b/src/core/core.cpp index 2a99d3ccc..41fcb6855 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -214,6 +214,7 @@ System::ResultStatus System::SingleStep() { } System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath) { + FileUtil::SetCurrentRomPath(filepath); app_loader = Loader::GetLoader(filepath); if (!app_loader) { LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);