[GPD] Implemented XamUserCreateTitlesPlayedEnumerator

This commit is contained in:
Gliniak 2019-11-23 21:47:44 +01:00 committed by illusion
parent dbcc155a5c
commit 96952c70e3
4 changed files with 55 additions and 7 deletions

View File

@ -9,14 +9,14 @@
#include <sstream> #include <sstream>
#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/clock.h"
#include "xenia/base/cvar.h"
#include "xenia/base/filesystem.h" #include "xenia/base/filesystem.h"
#include "xenia/base/logging.h" #include "xenia/base/logging.h"
#include "xenia/base/mapped_memory.h" #include "xenia/base/mapped_memory.h"
#include "xenia/kernel/kernel_state.h"
#include "xenia/kernel/util/crypto_utils.h" #include "xenia/kernel/util/crypto_utils.h"
#include "xenia/kernel/util/shim_utils.h"
#include "xenia/kernel/xam/user_profile.h" #include "xenia/kernel/xam/user_profile.h"
namespace xe { namespace xe {
@ -26,8 +26,6 @@ namespace xam {
DEFINE_string(profile_directory, "Content\\Profile\\", DEFINE_string(profile_directory, "Content\\Profile\\",
"The directory to store profile data inside", "Kernel"); "The directory to store profile data inside", "Kernel");
constexpr uint32_t kDashboardID = 0xFFFE07D1;
std::string X_XAMACCOUNTINFO::GetGamertagString() const { std::string X_XAMACCOUNTINFO::GetGamertagString() const {
return xe::to_string(std::wstring(gamertag)); return xe::to_string(std::wstring(gamertag));
} }
@ -240,7 +238,7 @@ void UserProfile::LoadProfile() {
title_gpds_[title.title_id] = title_gpd; 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) { 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 xam
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe

View File

@ -22,6 +22,8 @@ namespace xe {
namespace kernel { namespace kernel {
namespace xam { namespace xam {
constexpr uint32_t kDashboardID = 0xFFFE07D1;
// from https://github.com/xemio/testdev/blob/master/xkelib/xam/_xamext.h // from https://github.com/xemio/testdev/blob/master/xkelib/xam/_xamext.h
#pragma pack(push, 4) #pragma pack(push, 4)
struct X_XAMACCOUNTINFO { struct X_XAMACCOUNTINFO {
@ -320,6 +322,7 @@ class UserProfile {
xdbf::GpdFile* SetTitleSpaData(const xdbf::SpaFile& spa_data); xdbf::GpdFile* SetTitleSpaData(const xdbf::SpaFile& spa_data);
xdbf::GpdFile* GetTitleGpd(uint32_t title_id = -1); xdbf::GpdFile* GetTitleGpd(uint32_t title_id = -1);
xdbf::GpdFile* GetDashboardGpd();
void GetTitles(std::vector<xdbf::GpdFile*>& titles); void GetTitles(std::vector<xdbf::GpdFile*>& titles);

View File

@ -16,6 +16,7 @@
#include "xenia/kernel/xenumerator.h" #include "xenia/kernel/xenumerator.h"
#include "xenia/kernel/xthread.h" #include "xenia/kernel/xthread.h"
#include "xenia/xbox.h" #include "xenia/xbox.h"
#include "xenia/kernel/xam/xdbf/xdbf.h"
#include "xenia/base/cvar.h" #include "xenia/base/cvar.h"
@ -25,6 +26,7 @@ DEFINE_bool(signin_state, true,
namespace xe { namespace xe {
namespace kernel { namespace kernel {
namespace xam { namespace xam {
namespace xdbf {
struct X_PROFILEENUMRESULT { struct X_PROFILEENUMRESULT {
xe::be<uint64_t> xuid_offline; // E0..... xe::be<uint64_t> xuid_offline; // E0.....
@ -681,9 +683,50 @@ dword_result_t XamSessionRefObjByHandle(dword_t handle, lpdword_t obj_ptr) {
} }
DECLARE_XAM_EXPORT1(XamSessionRefObjByHandle, kUserProfiles, kStub); 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<xdbf::TitlePlayed> 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>((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 xam
} // namespace kernel } // namespace kernel
} // namespace xe } // namespace xe
void xe::kernel::xam::RegisterUserExports( void xe::kernel::xam::RegisterUserExports(
xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {} xe::cpu::ExportResolver* export_resolver, KernelState* kernel_state) {}

View File

@ -125,7 +125,7 @@ struct X_XDBF_GPD_TITLEPLAYED {
xe::be<uint16_t> female_avatar_awards; xe::be<uint16_t> female_avatar_awards;
xe::be<uint32_t> reserved_flags; xe::be<uint32_t> reserved_flags;
xe::be<uint64_t> last_played; xe::be<uint64_t> last_played;
// wchar_t* title_name; xe::be<wchar_t> title_name[64];
}; };
#pragma pack(pop) #pragma pack(pop)