diff options
| author | 2019-04-10 12:30:49 -0400 | |
|---|---|---|
| committer | 2019-09-21 16:43:10 -0400 | |
| commit | 49c44e3faebe5912b71532a118f3bcd71bf73b4d (patch) | |
| tree | 756cb5b8cfbc715a87b74e266ba7e75b2b072270 /src/core | |
| parent | patch_manager: Add short-circuit edge-case to GetPatchVersionNames (diff) | |
| download | yuzu-49c44e3faebe5912b71532a118f3bcd71bf73b4d.tar.gz yuzu-49c44e3faebe5912b71532a118f3bcd71bf73b4d.tar.xz yuzu-49c44e3faebe5912b71532a118f3bcd71bf73b4d.zip | |
savedata_factory: Implement savedata creation and don't create dir on open
Matches hardware behavior and eliminates some nasty behavior we were doing that wasn't hw-accurate at all.
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/file_sys/savedata_factory.cpp | 65 | ||||
| -rw-r--r-- | src/core/file_sys/savedata_factory.h | 1 |
2 files changed, 40 insertions, 26 deletions
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index 7974b031d..c63815332 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp | |||
| @@ -15,22 +15,8 @@ namespace FileSys { | |||
| 15 | 15 | ||
| 16 | constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; | 16 | constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; |
| 17 | 17 | ||
| 18 | std::string SaveDataDescriptor::DebugInfo() const { | 18 | namespace { |
| 19 | return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}, " | 19 | void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) { |
| 20 | "rank={}, index={}]", | ||
| 21 | static_cast<u8>(type), title_id, user_id[1], user_id[0], save_id, | ||
| 22 | static_cast<u8>(rank), index); | ||
| 23 | } | ||
| 24 | |||
| 25 | SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) { | ||
| 26 | // Delete all temporary storages | ||
| 27 | // On hardware, it is expected that temporary storage be empty at first use. | ||
| 28 | dir->DeleteSubdirectoryRecursive("temp"); | ||
| 29 | } | ||
| 30 | |||
| 31 | SaveDataFactory::~SaveDataFactory() = default; | ||
| 32 | |||
| 33 | ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataDescriptor& meta) { | ||
| 34 | if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { | 20 | if (meta.type == SaveDataType::SystemSaveData || meta.type == SaveDataType::SaveData) { |
| 35 | if (meta.zero_1 != 0) { | 21 | if (meta.zero_1 != 0) { |
| 36 | LOG_WARNING(Service_FS, | 22 | LOG_WARNING(Service_FS, |
| @@ -65,23 +51,50 @@ ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, const SaveDat | |||
| 65 | "non-zero ({:016X}{:016X})", | 51 | "non-zero ({:016X}{:016X})", |
| 66 | meta.user_id[1], meta.user_id[0]); | 52 | meta.user_id[1], meta.user_id[0]); |
| 67 | } | 53 | } |
| 54 | } | ||
| 55 | } // Anonymous namespace | ||
| 68 | 56 | ||
| 69 | std::string save_directory = | 57 | std::string SaveDataDescriptor::DebugInfo() const { |
| 70 | GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); | 58 | return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, " |
| 59 | "save_id={:016X}, " | ||
| 60 | "rank={}, index={}]", | ||
| 61 | static_cast<u8>(type), title_id, user_id[1], user_id[0], save_id, | ||
| 62 | static_cast<u8>(rank), index); | ||
| 63 | } | ||
| 71 | 64 | ||
| 72 | // TODO(DarkLordZach): Try to not create when opening, there are dedicated create save methods. | 65 | SaveDataFactory::SaveDataFactory(VirtualDir save_directory) : dir(std::move(save_directory)) { |
| 73 | // But, user_ids don't match so this works for now. | 66 | // Delete all temporary storages |
| 67 | // On hardware, it is expected that temporary storage be empty at first use. | ||
| 68 | dir->DeleteSubdirectoryRecursive("temp"); | ||
| 69 | } | ||
| 74 | 70 | ||
| 75 | auto out = dir->GetDirectoryRelative(save_directory); | 71 | SaveDataFactory::~SaveDataFactory() = default; |
| 72 | |||
| 73 | ResultVal<VirtualDir> SaveDataFactory::Create(SaveDataSpaceId space, | ||
| 74 | const SaveDataDescriptor& meta) { | ||
| 75 | PrintSaveDataDescriptorWarnings(meta); | ||
| 76 | |||
| 77 | const auto save_directory = | ||
| 78 | GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); | ||
| 79 | |||
| 80 | auto out = dir->CreateDirectoryRelative(save_directory); | ||
| 76 | 81 | ||
| 82 | // Return an error if the save data doesn't actually exist. | ||
| 77 | if (out == nullptr) { | 83 | if (out == nullptr) { |
| 78 | // TODO(bunnei): This is a work-around to always create a save data directory if it does not | 84 | // TODO(DarkLordZach): Find out correct error code. |
| 79 | // already exist. This is a hack, as we do not understand yet how this works on hardware. | 85 | return ResultCode(-1); |
| 80 | // Without a save data directory, many games will assert on boot. This should not have any | ||
| 81 | // bad side-effects. | ||
| 82 | out = dir->CreateDirectoryRelative(save_directory); | ||
| 83 | } | 86 | } |
| 84 | 87 | ||
| 88 | return MakeResult<VirtualDir>(std::move(out)); | ||
| 89 | } | ||
| 90 | |||
| 91 | ResultVal<VirtualDir> SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataDescriptor& meta) { | ||
| 92 | |||
| 93 | const auto save_directory = | ||
| 94 | GetFullPath(space, meta.type, meta.title_id, meta.user_id, meta.save_id); | ||
| 95 | |||
| 96 | auto out = dir->GetDirectoryRelative(save_directory); | ||
| 97 | |||
| 85 | // Return an error if the save data doesn't actually exist. | 98 | // Return an error if the save data doesn't actually exist. |
| 86 | if (out == nullptr) { | 99 | if (out == nullptr) { |
| 87 | // TODO(Subv): Find out correct error code. | 100 | // TODO(Subv): Find out correct error code. |
diff --git a/src/core/file_sys/savedata_factory.h b/src/core/file_sys/savedata_factory.h index b73654571..738038ee0 100644 --- a/src/core/file_sys/savedata_factory.h +++ b/src/core/file_sys/savedata_factory.h | |||
| @@ -64,6 +64,7 @@ public: | |||
| 64 | explicit SaveDataFactory(VirtualDir dir); | 64 | explicit SaveDataFactory(VirtualDir dir); |
| 65 | ~SaveDataFactory(); | 65 | ~SaveDataFactory(); |
| 66 | 66 | ||
| 67 | ResultVal<VirtualDir> Create(SaveDataSpaceId space, const SaveDataDescriptor& meta); | ||
| 67 | ResultVal<VirtualDir> Open(SaveDataSpaceId space, const SaveDataDescriptor& meta); | 68 | ResultVal<VirtualDir> Open(SaveDataSpaceId space, const SaveDataDescriptor& meta); |
| 68 | 69 | ||
| 69 | VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; | 70 | VirtualDir GetSaveDataSpaceDirectory(SaveDataSpaceId space) const; |