summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Yuri Kunde Schlesner2015-02-25 22:35:55 -0300
committerGravatar Yuri Kunde Schlesner2015-02-25 22:35:55 -0300
commit1b5ee96797e7f3fb334ea60e0c37d356929638e8 (patch)
tree1fc581af35a290d40318d32b40737d23650afd52
parentMerge pull request #611 from yuriks/pixelated-textures (diff)
parentArchives: Properly implemented the SystemSaveData archive. (diff)
downloadyuzu-1b5ee96797e7f3fb334ea60e0c37d356929638e8.tar.gz
yuzu-1b5ee96797e7f3fb334ea60e0c37d356929638e8.tar.xz
yuzu-1b5ee96797e7f3fb334ea60e0c37d356929638e8.zip
Merge pull request #604 from Subv/arc_ssd
Archives: Properly implemented the SystemSaveData archive.
-rw-r--r--src/core/file_sys/archive_systemsavedata.cpp33
-rw-r--r--src/core/file_sys/archive_systemsavedata.h14
-rw-r--r--src/core/hle/service/cfg/cfg.cpp64
-rw-r--r--src/core/hle/service/fs/archive.cpp4
4 files changed, 70 insertions, 45 deletions
diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp
index c2a5d641a..25c94cd26 100644
--- a/src/core/file_sys/archive_systemsavedata.cpp
+++ b/src/core/file_sys/archive_systemsavedata.cpp
@@ -6,9 +6,9 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/file_util.h" 8#include "common/file_util.h"
9#include "common/make_unique.h"
9 10
10#include "core/file_sys/archive_systemsavedata.h" 11#include "core/file_sys/archive_systemsavedata.h"
11#include "core/file_sys/disk_archive.h"
12#include "core/hle/service/fs/archive.h" 12#include "core/hle/service/fs/archive.h"
13#include "core/settings.h" 13#include "core/settings.h"
14 14
@@ -17,9 +17,11 @@
17 17
18namespace FileSys { 18namespace FileSys {
19 19
20static std::string GetSystemSaveDataPath(const std::string& mount_point, u64 save_id) { 20static std::string GetSystemSaveDataPath(const std::string& mount_point, const Path& path) {
21 u32 save_high = static_cast<u32>((save_id >> 32) & 0xFFFFFFFF); 21 std::vector<u8> vec_data = path.AsBinary();
22 u32 save_low = static_cast<u32>(save_id & 0xFFFFFFFF); 22 const u32* data = reinterpret_cast<const u32*>(vec_data.data());
23 u32 save_low = data[1];
24 u32 save_high = data[0];
23 return Common::StringFromFormat("%s%08X/%08X/", mount_point.c_str(), save_low, save_high); 25 return Common::StringFromFormat("%s%08X/%08X/", mount_point.c_str(), save_low, save_high);
24} 26}
25 27
@@ -27,18 +29,25 @@ static std::string GetSystemSaveDataContainerPath(const std::string& mount_point
27 return Common::StringFromFormat("%sdata/%s/sysdata/", mount_point.c_str(), SYSTEM_ID.c_str()); 29 return Common::StringFromFormat("%sdata/%s/sysdata/", mount_point.c_str(), SYSTEM_ID.c_str());
28} 30}
29 31
30Archive_SystemSaveData::Archive_SystemSaveData(const std::string& mount_point, u64 save_id) 32ArchiveFactory_SystemSaveData::ArchiveFactory_SystemSaveData(const std::string& nand_path)
31 : DiskArchive(GetSystemSaveDataPath(GetSystemSaveDataContainerPath(mount_point), save_id)) { 33 : base_path(GetSystemSaveDataContainerPath(nand_path)) {
32 LOG_INFO(Service_FS, "Directory %s set as SystemSaveData.", this->mount_point.c_str());
33} 34}
34 35
35bool Archive_SystemSaveData::Initialize() { 36ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveFactory_SystemSaveData::Open(const Path& path) {
36 if (!FileUtil::CreateFullPath(mount_point)) { 37 std::string fullpath = GetSystemSaveDataPath(base_path, path);
37 LOG_ERROR(Service_FS, "Unable to create SystemSaveData path."); 38 if (!FileUtil::Exists(fullpath)) {
38 return false; 39 // TODO(Subv): Check error code, this one is probably wrong
40 return ResultCode(ErrorDescription::FS_NotFormatted, ErrorModule::FS,
41 ErrorSummary::InvalidState, ErrorLevel::Status);
39 } 42 }
43 auto archive = Common::make_unique<DiskArchive>(fullpath);
44 return MakeResult<std::unique_ptr<ArchiveBackend>>(std::move(archive));
45}
40 46
41 return true; 47ResultCode ArchiveFactory_SystemSaveData::Format(const Path& path) {
48 std::string fullpath = GetSystemSaveDataPath(base_path, path);
49 FileUtil::CreateFullPath(fullpath);
50 return RESULT_SUCCESS;
42} 51}
43 52
44} // namespace FileSys 53} // namespace FileSys
diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h
index c8f5845ca..556a2a488 100644
--- a/src/core/file_sys/archive_systemsavedata.h
+++ b/src/core/file_sys/archive_systemsavedata.h
@@ -15,17 +15,17 @@
15namespace FileSys { 15namespace FileSys {
16 16
17/// File system interface to the SystemSaveData archive 17/// File system interface to the SystemSaveData archive
18class Archive_SystemSaveData final : public DiskArchive { 18class ArchiveFactory_SystemSaveData final : public ArchiveFactory {
19public: 19public:
20 Archive_SystemSaveData(const std::string& mount_point, u64 save_id); 20 ArchiveFactory_SystemSaveData(const std::string& mount_point);
21 21
22 /** 22 ResultVal<std::unique_ptr<ArchiveBackend>> Open(const Path& path) override;
23 * Initialize the archive. 23 ResultCode Format(const Path& path) override;
24 * @return true if it initialized successfully
25 */
26 bool Initialize();
27 24
28 std::string GetName() const override { return "SystemSaveData"; } 25 std::string GetName() const override { return "SystemSaveData"; }
26
27private:
28 std::string base_path;
29}; 29};
30 30
31} // namespace FileSys 31} // namespace FileSys
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index 1a2104b48..b7cdccb86 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -4,8 +4,8 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include "common/make_unique.h" 6#include "common/make_unique.h"
7#include "core/file_sys/archive_systemsavedata.h"
8#include "core/hle/service/cfg/cfg.h" 7#include "core/hle/service/cfg/cfg.h"
8#include "core/hle/service/fs/archive.h"
9 9
10namespace Service { 10namespace Service {
11namespace CFG { 11namespace CFG {
@@ -36,7 +36,8 @@ const std::array<float, 8> STEREO_CAMERA_SETTINGS = {
36static const u32 CONFIG_SAVEFILE_SIZE = 0x8000; 36static const u32 CONFIG_SAVEFILE_SIZE = 0x8000;
37static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer; 37static std::array<u8, CONFIG_SAVEFILE_SIZE> cfg_config_file_buffer;
38 38
39static std::unique_ptr<FileSys::Archive_SystemSaveData> cfg_system_save_data; 39static Service::FS::ArchiveHandle cfg_system_save_data_archive;
40static const std::vector<u8> cfg_system_savedata_id = { 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x01, 0x00 };
40 41
41ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) { 42ResultCode GetConfigInfoBlock(u32 block_id, u32 size, u32 flag, u8* output) {
42 // Read the header 43 // Read the header
@@ -97,19 +98,22 @@ ResultCode CreateConfigInfoBlk(u32 block_id, u16 size, u16 flags, const u8* data
97 98
98ResultCode DeleteConfigNANDSaveFile() { 99ResultCode DeleteConfigNANDSaveFile() {
99 FileSys::Path path("config"); 100 FileSys::Path path("config");
100 if (cfg_system_save_data->DeleteFile(path)) 101 return Service::FS::DeleteFileFromArchive(cfg_system_save_data_archive, path);
101 return RESULT_SUCCESS;
102 return ResultCode(-1); // TODO(Subv): Find the right error code
103} 102}
104 103
105ResultCode UpdateConfigNANDSavegame() { 104ResultCode UpdateConfigNANDSavegame() {
106 FileSys::Mode mode = {}; 105 FileSys::Mode mode = {};
107 mode.write_flag = 1; 106 mode.write_flag = 1;
108 mode.create_flag = 1; 107 mode.create_flag = 1;
108
109 FileSys::Path path("config"); 109 FileSys::Path path("config");
110 auto file = cfg_system_save_data->OpenFile(path, mode); 110
111 ASSERT_MSG(file != nullptr, "could not open file"); 111 auto config_result = Service::FS::OpenFileFromArchive(cfg_system_save_data_archive, path, mode);
112 file->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data()); 112 ASSERT_MSG(config_result.Succeeded(), "could not open file");
113
114 auto config = config_result.MoveFrom();
115 config->backend->Write(0, CONFIG_SAVEFILE_SIZE, 1, cfg_config_file_buffer.data());
116
113 return RESULT_SUCCESS; 117 return RESULT_SUCCESS;
114} 118}
115 119
@@ -158,27 +162,33 @@ ResultCode FormatConfig() {
158} 162}
159 163
160void CFGInit() { 164void CFGInit() {
161 // TODO(Subv): In the future we should use the FS service to query this archive, 165 // Open the SystemSaveData archive 0x00010017
162 // currently it is not possible because you can only have one open archive of the same type at any time 166 FileSys::Path archive_path(cfg_system_savedata_id);
163 std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); 167 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
164 cfg_system_save_data = Common::make_unique<FileSys::Archive_SystemSaveData>( 168
165 nand_directory, CFG_SAVE_ID); 169 // If the archive didn't exist, create the files inside
166 if (!cfg_system_save_data->Initialize()) { 170 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
167 LOG_CRITICAL(Service_CFG, "Could not initialize SystemSaveData archive for the CFG:U service"); 171 // Format the archive to create the directories
168 return; 172 Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
173
174 // Open it again to get a valid archive now that the folder exists
175 archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
169 } 176 }
170 177
171 // TODO(Subv): All this code should be moved to cfg:i, 178 ASSERT_MSG(archive_result.Succeeded(), "Could not open the CFG SystemSaveData archive!");
172 // it's only here because we do not currently emulate the lower level code that uses that service 179
173 // Try to open the file in read-only mode to check its existence 180 cfg_system_save_data_archive = *archive_result;
174 FileSys::Mode mode = {}; 181
175 mode.read_flag = 1; 182 FileSys::Path config_path("config");
176 FileSys::Path path("config"); 183 FileSys::Mode open_mode = {};
177 auto file = cfg_system_save_data->OpenFile(path, mode); 184 open_mode.read_flag = 1;
178 185
179 // Load the config if it already exists 186 auto config_result = Service::FS::OpenFileFromArchive(*archive_result, config_path, open_mode);
180 if (file != nullptr) { 187
181 file->Read(0, CONFIG_SAVEFILE_SIZE, cfg_config_file_buffer.data()); 188 // Read the file if it already exists
189 if (config_result.Succeeded()) {
190 auto config = config_result.MoveFrom();
191 config->backend->Read(0, CONFIG_SAVEFILE_SIZE, cfg_config_file_buffer.data());
182 return; 192 return;
183 } 193 }
184 194
@@ -186,10 +196,12 @@ void CFGInit() {
186 // TODO(Subv): Initialize this directly in the variable when MSVC supports char16_t string literals 196 // TODO(Subv): Initialize this directly in the variable when MSVC supports char16_t string literals
187 CONSOLE_USERNAME_BLOCK.ng_word = 0; 197 CONSOLE_USERNAME_BLOCK.ng_word = 0;
188 CONSOLE_USERNAME_BLOCK.zero = 0; 198 CONSOLE_USERNAME_BLOCK.zero = 0;
199
189 // Copy string to buffer and pad with zeros at the end 200 // Copy string to buffer and pad with zeros at the end
190 auto size = Common::UTF8ToUTF16(CONSOLE_USERNAME).copy(CONSOLE_USERNAME_BLOCK.username, 0x14); 201 auto size = Common::UTF8ToUTF16(CONSOLE_USERNAME).copy(CONSOLE_USERNAME_BLOCK.username, 0x14);
191 std::fill(std::begin(CONSOLE_USERNAME_BLOCK.username) + size, 202 std::fill(std::begin(CONSOLE_USERNAME_BLOCK.username) + size,
192 std::end(CONSOLE_USERNAME_BLOCK.username), 0); 203 std::end(CONSOLE_USERNAME_BLOCK.username), 0);
204
193 FormatConfig(); 205 FormatConfig();
194} 206}
195 207
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index a69c4f25b..c5020cb24 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -18,6 +18,7 @@
18#include "core/file_sys/archive_savedata.h" 18#include "core/file_sys/archive_savedata.h"
19#include "core/file_sys/archive_savedatacheck.h" 19#include "core/file_sys/archive_savedatacheck.h"
20#include "core/file_sys/archive_sdmc.h" 20#include "core/file_sys/archive_sdmc.h"
21#include "core/file_sys/archive_systemsavedata.h"
21#include "core/file_sys/directory_backend.h" 22#include "core/file_sys/directory_backend.h"
22#include "core/hle/service/fs/archive.h" 23#include "core/hle/service/fs/archive.h"
23#include "core/hle/result.h" 24#include "core/hle/result.h"
@@ -449,6 +450,9 @@ void ArchiveInit() {
449 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive 450 // Create the SaveDataCheck archive, basically a small variation of the RomFS archive
450 auto savedatacheck_factory = Common::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory); 451 auto savedatacheck_factory = Common::make_unique<FileSys::ArchiveFactory_SaveDataCheck>(nand_directory);
451 RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck); 452 RegisterArchiveType(std::move(savedatacheck_factory), ArchiveIdCode::SaveDataCheck);
453
454 auto systemsavedata_factory = Common::make_unique<FileSys::ArchiveFactory_SystemSaveData>(nand_directory);
455 RegisterArchiveType(std::move(systemsavedata_factory), ArchiveIdCode::SystemSaveData);
452} 456}
453 457
454/// Shutdown archives 458/// Shutdown archives