Persist title-specific profile content

This commit is contained in:
Unknown
2018-06-09 16:08:57 -07:00
committed by Jeremy517
parent 5f16e46282
commit 86443dd28a
5 changed files with 99 additions and 3 deletions

View File

@@ -7,6 +7,10 @@
******************************************************************************
*/
#include <sstream>
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/xam/user_profile.h"
namespace xe {
@@ -87,6 +91,10 @@ void UserProfile::AddSetting(std::unique_ptr<Setting> setting) {
Setting* previous_setting = setting.get();
std::swap(settings_[setting->setting_id], previous_setting);
if (setting->is_set && setting->is_title_specific()) {
SaveSetting(setting.get());
}
if (previous_setting) {
// replace: swap out the old setting from the owning list
for (auto vec_it = setting_list_.begin(); vec_it != setting_list_.end();
@@ -107,7 +115,58 @@ UserProfile::Setting* UserProfile::GetSetting(uint32_t setting_id) {
if (it == settings_.end()) {
return nullptr;
}
return it->second;
UserProfile::Setting* setting = it->second;
if (setting->is_title_specific()) {
// If what we have loaded in memory isn't for the title that is running
// right now, then load it from disk.
if (kernel_state()->title_id() != setting->loaded_title_id) {
LoadSetting(setting);
}
}
return setting;
}
void UserProfile::LoadSetting(UserProfile::Setting* setting) {
if (setting->is_title_specific()) {
auto content_dir =
kernel_state()->content_manager()->ResolveGameUserContentPath();
auto setting_id = xe::format_string(L"%.8X", setting->setting_id);
auto file_path = xe::join_paths(content_dir, setting_id);
auto file = xe::filesystem::OpenFile(file_path, "rb");
if (file) {
fseek(file, 0, SEEK_END);
uint32_t input_file_size = static_cast<uint32_t>(ftell(file));
fseek(file, 0, SEEK_SET);
std::vector<uint8_t> serialized_data(input_file_size);
fread(serialized_data.data(), 1, serialized_data.size(), file);
fclose(file);
setting->Deserialize(serialized_data);
setting->loaded_title_id = kernel_state()->title_id();
}
} else {
// Unsupported for now. Other settings aren't per-game and need to be
// stored some other way.
XELOGW("Attempting to load unsupported profile setting from disk");
}
}
void UserProfile::SaveSetting(UserProfile::Setting* setting) {
if (setting->is_title_specific()) {
auto serialized_setting = setting->Serialize();
auto content_dir =
kernel_state()->content_manager()->ResolveGameUserContentPath();
xe::filesystem::CreateFolder(content_dir);
auto setting_id = xe::format_string(L"%.8X", setting->setting_id);
auto file_path = xe::join_paths(content_dir, setting_id);
auto file = xe::filesystem::OpenFile(file_path, "wb");
fwrite(serialized_setting.data(), 1, serialized_setting.size(), file);
fclose(file);
} else {
// Unsupported for now. Other settings aren't per-game and need to be
// stored some other way.
XELOGW("Attempting to save unsupported profile setting to disk");
}
}
} // namespace xam