Persist title-specific profile content
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user