From 5079dec87276565e1284bcbef8156ec8dec01076 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sat, 23 Nov 2019 21:47:44 +0100 Subject: [PATCH] [GPD] Implemented XamUserCreateTitlesPlayedEnumerator --- src/xenia/kernel/xam/user_profile.cc | 14 +++++---- src/xenia/kernel/xam/user_profile.h | 3 ++ src/xenia/kernel/xam/xam_user.cc | 43 +++++++++++++++++++++++++++ src/xenia/kernel/xam/xdbf/xdbf_xbox.h | 2 +- 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/xenia/kernel/xam/user_profile.cc b/src/xenia/kernel/xam/user_profile.cc index 1369b2361..c3e56d70f 100644 --- a/src/xenia/kernel/xam/user_profile.cc +++ b/src/xenia/kernel/xam/user_profile.cc @@ -9,14 +9,14 @@ #include -#include "xenia/kernel/kernel_state.h" -#include "xenia/kernel/util/shim_utils.h" -#include "xenia/base/cvar.h" #include "xenia/base/clock.h" +#include "xenia/base/cvar.h" #include "xenia/base/filesystem.h" #include "xenia/base/logging.h" #include "xenia/base/mapped_memory.h" +#include "xenia/kernel/kernel_state.h" #include "xenia/kernel/util/crypto_utils.h" +#include "xenia/kernel/util/shim_utils.h" #include "xenia/kernel/xam/user_profile.h" namespace xe { @@ -26,8 +26,6 @@ namespace xam { DEFINE_string(profile_directory, "Content\\Profile\\", "The directory to store profile data inside", "Kernel"); -constexpr uint32_t kDashboardID = 0xFFFE07D1; - std::string X_XAMACCOUNTINFO::GetGamertagString() const { return xe::to_string(std::wstring(gamertag)); } @@ -240,7 +238,7 @@ void UserProfile::LoadProfile() { title_gpds_[title.title_id] = title_gpd; } - XELOGI("Loaded %d profile GPDs", title_gpds_.size() + 1); + XELOGI("Loaded %d profile GPDs", title_gpds_.size()); } xdbf::GpdFile* UserProfile::SetTitleSpaData(const xdbf::SpaFile& spa_data) { @@ -595,6 +593,10 @@ void UserProfile::SaveSetting(UserProfile::Setting* setting) { } } +xdbf::GpdFile* UserProfile::GetDashboardGpd() { + return &dash_gpd_; +} + } // namespace xam } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam/user_profile.h b/src/xenia/kernel/xam/user_profile.h index f56f149f4..f253436d3 100644 --- a/src/xenia/kernel/xam/user_profile.h +++ b/src/xenia/kernel/xam/user_profile.h @@ -22,6 +22,8 @@ namespace xe { namespace kernel { namespace xam { +constexpr uint32_t kDashboardID = 0xFFFE07D1; + // from https://github.com/xemio/testdev/blob/master/xkelib/xam/_xamext.h #pragma pack(push, 4) struct X_XAMACCOUNTINFO { @@ -320,6 +322,7 @@ class UserProfile { xdbf::GpdFile* SetTitleSpaData(const xdbf::SpaFile& spa_data); xdbf::GpdFile* GetTitleGpd(uint32_t title_id = -1); + xdbf::GpdFile* GetDashboardGpd(); void GetTitles(std::vector& titles); diff --git a/src/xenia/kernel/xam/xam_user.cc b/src/xenia/kernel/xam/xam_user.cc index cd932695a..96a498181 100644 --- a/src/xenia/kernel/xam/xam_user.cc +++ b/src/xenia/kernel/xam/xam_user.cc @@ -16,6 +16,7 @@ #include "xenia/kernel/xenumerator.h" #include "xenia/kernel/xthread.h" #include "xenia/xbox.h" +#include "xenia/kernel/xam/xdbf/xdbf.h" #include "xenia/base/cvar.h" @@ -25,6 +26,7 @@ DEFINE_bool(signin_state, true, namespace xe { namespace kernel { namespace xam { +namespace xdbf { struct X_PROFILEENUMRESULT { xe::be xuid_offline; // E0..... @@ -675,9 +677,50 @@ dword_result_t XamSessionRefObjByHandle(dword_t handle, lpdword_t obj_ptr) { } DECLARE_XAM_EXPORT1(XamSessionRefObjByHandle, kUserProfiles, kStub); +dword_result_t XamUserCreateTitlesPlayedEnumerator( + dword_t user_index, dword_t xuid, dword_t flags, dword_t offset, + dword_t games_count, lpdword_t buffer_size_ptr, lpdword_t handle_ptr) { + std::vector titles; + kernel_state()->user_profile()->GetDashboardGpd()->GetTitles(&titles); + + auto e = new XStaticEnumerator(kernel_state(), games_count, + sizeof(xdbf::X_XDBF_GPD_TITLEPLAYED)); + e->Initialize(); + + *handle_ptr = e->handle(); + + for (auto title : titles) { + // For some reason dashboard gpd stores info about itself + if (title.title_id == kDashboardID) + continue; + + auto* details = (xdbf::X_XDBF_GPD_TITLEPLAYED*)e->AppendItem(); + details->title_id = title.title_id; + details->achievements_possible = title.achievements_possible; + details->achievements_earned = title.achievements_earned; + details->gamerscore_total = title.gamerscore_total; + details->gamerscore_earned = title.gamerscore_earned; + details->reserved_achievement_count = title.reserved_achievement_count; + details->all_avatar_awards = title.all_avatar_awards; + details->male_avatar_awards = title.male_avatar_awards; + details->female_avatar_awards = title.female_avatar_awards; + details->reserved_flags = title.reserved_flags; + details->last_played = title.last_played; + + xe::copy_and_swap((wchar_t*)details->title_name, + title.title_name.c_str(), + title.title_name.size()); + } + + return X_ERROR_SUCCESS; +} +DECLARE_XAM_EXPORT1(XamUserCreateTitlesPlayedEnumerator, kUserProfiles, kStub); + +} // namespace xdbf } // namespace xam } // namespace kernel } // namespace xe + void xe::kernel::xam::RegisterUserExports( xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {} diff --git a/src/xenia/kernel/xam/xdbf/xdbf_xbox.h b/src/xenia/kernel/xam/xdbf/xdbf_xbox.h index cff02d68d..1a070b225 100644 --- a/src/xenia/kernel/xam/xdbf/xdbf_xbox.h +++ b/src/xenia/kernel/xam/xdbf/xdbf_xbox.h @@ -125,7 +125,7 @@ struct X_XDBF_GPD_TITLEPLAYED { xe::be female_avatar_awards; xe::be reserved_flags; xe::be last_played; - // wchar_t* title_name; + xe::be title_name[64]; }; #pragma pack(pop)