diff --git a/UnleashedRecomp/kernel/xam.cpp b/UnleashedRecomp/kernel/xam.cpp index 21732034..66a3d67f 100644 --- a/UnleashedRecomp/kernel/xam.cpp +++ b/UnleashedRecomp/kernel/xam.cpp @@ -308,7 +308,7 @@ SWA_API uint32_t XamContentCreateEx(uint32_t dwUserIndex, const char* szRootName if (pContentData->dwContentType == XCONTENTTYPE_SAVEDATA) { - std::u8string savePathU8 = GetSavePath().u8string(); + std::u8string savePathU8 = GetSavePath(true).u8string(); root = (const char *)(savePathU8.c_str()); } else if (pContentData->dwContentType == XCONTENTTYPE_DLC) diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index c7a6a718..cf87aa5c 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -54,13 +54,26 @@ void KiSystemStartup() XamRegisterContent(gameContent, GAME_INSTALL_DIRECTORY "/game"); XamRegisterContent(updateContent, GAME_INSTALL_DIRECTORY "/update"); - const auto savePath = GetSavePath(); - const auto saveName = "SYS-DATA"; + const auto saveFilePath = GetSaveFilePath(true); + bool saveFileExists = std::filesystem::exists(saveFilePath); - if (std::filesystem::exists(savePath / saveName)) + if (!saveFileExists) { - std::u8string savePathU8 = savePath.u8string(); - XamRegisterContent(XamMakeContent(XCONTENTTYPE_SAVEDATA, saveName), (const char *)(savePathU8.c_str())); + // Copy base save data to modded save as fallback. + std::error_code ec; + std::filesystem::create_directories(saveFilePath.parent_path(), ec); + + if (!ec) + { + std::filesystem::copy_file(GetSaveFilePath(false), saveFilePath, ec); + saveFileExists = !ec; + } + } + + if (saveFileExists) + { + std::u8string savePathU8 = saveFilePath.parent_path().u8string(); + XamRegisterContent(XamMakeContent(XCONTENTTYPE_SAVEDATA, "SYS-DATA"), (const char*)(savePathU8.c_str())); } // Mount game diff --git a/UnleashedRecomp/user/achievement_data.cpp b/UnleashedRecomp/user/achievement_data.cpp index 00c12963..4b9e25bb 100644 --- a/UnleashedRecomp/user/achievement_data.cpp +++ b/UnleashedRecomp/user/achievement_data.cpp @@ -104,10 +104,15 @@ bool AchievementData::VerifyChecksum() void AchievementData::Load() { - auto dataPath = GetDataPath(); + auto dataPath = GetDataPath(true); if (!std::filesystem::exists(dataPath)) - return; + { + // Try loading base achievement data as fallback. + dataPath = GetDataPath(false); + if (!std::filesystem::exists(dataPath)) + return; + } std::ifstream file(dataPath, std::ios::binary); @@ -160,7 +165,7 @@ void AchievementData::Load() void AchievementData::Save() { - std::ofstream file(GetDataPath(), std::ios::binary); + std::ofstream file(GetDataPath(true), std::ios::binary); if (!file) { diff --git a/UnleashedRecomp/user/achievement_data.h b/UnleashedRecomp/user/achievement_data.h index 2a23c28e..ec995196 100644 --- a/UnleashedRecomp/user/achievement_data.h +++ b/UnleashedRecomp/user/achievement_data.h @@ -45,9 +45,9 @@ public: static inline Data Data{ ACH_SIGNATURE, ACH_VERSION }; - static std::filesystem::path GetDataPath() + static std::filesystem::path GetDataPath(bool checkForMods) { - return GetSavePath() / "ACH-DATA"; + return GetSavePath(checkForMods) / "ACH-DATA"; } static time_t GetTimestamp(uint16_t id); diff --git a/UnleashedRecomp/user/paths.h b/UnleashedRecomp/user/paths.h index d067ca9f..a081f857 100644 --- a/UnleashedRecomp/user/paths.h +++ b/UnleashedRecomp/user/paths.h @@ -50,10 +50,20 @@ inline std::filesystem::path GetUserPath() return userPath; } -inline std::filesystem::path GetSavePath() +inline std::filesystem::path GetSavePath(bool checkForMods) { - if (!ModLoader::s_saveFilePath.empty()) + if (checkForMods && !ModLoader::s_saveFilePath.empty()) return ModLoader::s_saveFilePath.parent_path(); else return GetUserPath() / "save"; } + +// Returned file name may not necessarily be +// equal to SYS-DATA as mods can assign anything. +inline std::filesystem::path GetSaveFilePath(bool checkForMods) +{ + if (checkForMods && !ModLoader::s_saveFilePath.empty()) + return ModLoader::s_saveFilePath; + else + return GetSavePath(false) / "SYS-DATA"; +}