summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-04-10 12:30:49 -0400
committerGravatar Zach Hilman2019-09-21 16:43:10 -0400
commit49c44e3faebe5912b71532a118f3bcd71bf73b4d (patch)
tree756cb5b8cfbc715a87b74e266ba7e75b2b072270 /src/core
parentpatch_manager: Add short-circuit edge-case to GetPatchVersionNames (diff)
downloadyuzu-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.cpp65
-rw-r--r--src/core/file_sys/savedata_factory.h1
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
16constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size"; 16constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size";
17 17
18std::string SaveDataDescriptor::DebugInfo() const { 18namespace {
19 return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}, " 19void 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
25SaveDataFactory::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
31SaveDataFactory::~SaveDataFactory() = default;
32
33ResultVal<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 = 57std::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. 65SaveDataFactory::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); 71SaveDataFactory::~SaveDataFactory() = default;
72
73ResultVal<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
91ResultVal<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;