[GPD] Implemented XamUserCreateTitlesPlayedEnumerator
This commit is contained in:
parent
dbcc155a5c
commit
96952c70e3
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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) {}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue