[Kernel] Move XDBF code to its own namespace
This commit is contained in:
parent
8f5a82b444
commit
c1eaf6879a
|
@ -33,8 +33,8 @@
|
|||
#include "xenia/kernel/kernel_state.h"
|
||||
#include "xenia/kernel/user_module.h"
|
||||
#include "xenia/kernel/util/gameinfo_utils.h"
|
||||
#include "xenia/kernel/util/xdbf_utils.h"
|
||||
#include "xenia/kernel/xam/xam_module.h"
|
||||
#include "xenia/kernel/xam/xdbf/xdbf.h"
|
||||
#include "xenia/kernel/xbdm/xbdm_module.h"
|
||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
||||
#include "xenia/memory.h"
|
||||
|
@ -662,7 +662,7 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
|
|||
uint32_t resource_size = 0;
|
||||
if (XSUCCEEDED(
|
||||
module->GetSection(title_id, &resource_data, &resource_size))) {
|
||||
kernel::util::SpaFile spa;
|
||||
kernel::xam::xdbf::SpaFile spa;
|
||||
if (spa.Read(module->memory()->TranslateVirtual(resource_data),
|
||||
resource_size)) {
|
||||
// Set title SPA and get title name/icon
|
||||
|
|
|
@ -70,7 +70,7 @@ X_RESULT XgiApp::DispatchMessageSync(uint32_t message, uint32_t buffer_ptr,
|
|||
bool modified = false;
|
||||
auto* achievement =
|
||||
(X_XUSER_ACHIEVEMENT*)memory_->TranslateVirtual(achievements_ptr);
|
||||
util::XdbfAchievement ach;
|
||||
xdbf::XdbfAchievement ach;
|
||||
for (uint32_t i = 0; i < achievement_count; i++, achievement++) {
|
||||
if (game_gpd->GetAchievement(achievement->achievement_id, &ach)) {
|
||||
if (!ach.IsUnlocked()) {
|
||||
|
|
|
@ -117,7 +117,7 @@ void UserProfile::LoadGpdFiles() {
|
|||
dash_gpd_.Read(mmap_->data(), mmap_->size());
|
||||
mmap_->Close();
|
||||
|
||||
std::vector<util::XdbfTitlePlayed> titles;
|
||||
std::vector<xdbf::XdbfTitlePlayed> titles;
|
||||
dash_gpd_.GetTitles(&titles);
|
||||
|
||||
for (auto title : titles) {
|
||||
|
@ -131,7 +131,7 @@ void UserProfile::LoadGpdFiles() {
|
|||
continue;
|
||||
}
|
||||
|
||||
util::GpdFile title_gpd(title.title_id);
|
||||
xdbf::GpdFile title_gpd(title.title_id);
|
||||
bool result = title_gpd.Read(mmap_->data(), mmap_->size());
|
||||
mmap_->Close();
|
||||
|
||||
|
@ -147,14 +147,14 @@ void UserProfile::LoadGpdFiles() {
|
|||
XELOGI("Loaded %d profile GPDs", title_gpds_.size() + 1);
|
||||
}
|
||||
|
||||
util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
||||
xdbf::GpdFile* UserProfile::SetTitleSpaData(const xdbf::SpaFile& spa_data) {
|
||||
uint32_t spa_title = spa_data.GetTitleId();
|
||||
|
||||
std::vector<util::XdbfAchievement> spa_achievements;
|
||||
std::vector<xdbf::XdbfAchievement> spa_achievements;
|
||||
// TODO: let user choose locale?
|
||||
spa_data.GetAchievements(spa_data.GetDefaultLocale(), &spa_achievements);
|
||||
|
||||
util::XdbfTitlePlayed title_info;
|
||||
xdbf::XdbfTitlePlayed title_info;
|
||||
|
||||
auto gpd = title_gpds_.find(spa_title);
|
||||
if (gpd != title_gpds_.end()) {
|
||||
|
@ -221,7 +221,7 @@ util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
|||
title_info.last_played = Clock::QueryHostSystemTime();
|
||||
|
||||
// Copy cheevos from SPA -> GPD
|
||||
util::GpdFile title_gpd(spa_title);
|
||||
xdbf::GpdFile title_gpd(spa_title);
|
||||
for (auto ach : spa_achievements) {
|
||||
title_gpd.UpdateAchievement(ach);
|
||||
|
||||
|
@ -232,7 +232,7 @@ util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
|||
// Try copying achievement images if we can...
|
||||
for (auto ach : spa_achievements) {
|
||||
auto* image_entry = spa_data.GetEntry(
|
||||
static_cast<uint16_t>(util::XdbfSpaSection::kImage), ach.image_id);
|
||||
static_cast<uint16_t>(xdbf::XdbfSpaSection::kImage), ach.image_id);
|
||||
if (image_entry) {
|
||||
title_gpd.UpdateEntry(*image_entry);
|
||||
}
|
||||
|
@ -240,18 +240,18 @@ util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
|||
|
||||
// Try adding title image & name
|
||||
auto* title_image =
|
||||
spa_data.GetEntry(static_cast<uint16_t>(util::XdbfSpaSection::kImage),
|
||||
static_cast<uint64_t>(util::XdbfSpaID::Title));
|
||||
spa_data.GetEntry(static_cast<uint16_t>(xdbf::XdbfSpaSection::kImage),
|
||||
static_cast<uint64_t>(xdbf::XdbfSpaID::Title));
|
||||
if (title_image) {
|
||||
title_gpd.UpdateEntry(*title_image);
|
||||
}
|
||||
|
||||
auto title_name = xe::to_wstring(spa_data.GetTitleName());
|
||||
if (title_name.length()) {
|
||||
util::XdbfEntry title_name_ent;
|
||||
xdbf::XdbfEntry title_name_ent;
|
||||
title_name_ent.info.section =
|
||||
static_cast<uint16_t>(util::XdbfGpdSection::kString);
|
||||
title_name_ent.info.id = static_cast<uint64_t>(util::XdbfSpaID::Title);
|
||||
static_cast<uint16_t>(xdbf::XdbfGpdSection::kString);
|
||||
title_name_ent.info.id = static_cast<uint64_t>(xdbf::XdbfSpaID::Title);
|
||||
title_name_ent.data.resize((title_name.length() + 1) * 2);
|
||||
xe::copy_and_swap((wchar_t*)title_name_ent.data.data(),
|
||||
title_name.c_str(), title_name.length());
|
||||
|
@ -272,7 +272,7 @@ util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
|||
|
||||
// Print achievement list to log, ATM there's no other way for users to see
|
||||
// achievement status...
|
||||
std::vector<util::XdbfAchievement> achievements;
|
||||
std::vector<xdbf::XdbfAchievement> achievements;
|
||||
if (curr_gpd_->GetAchievements(&achievements)) {
|
||||
XELOGI("Achievement list:");
|
||||
|
||||
|
@ -293,7 +293,7 @@ util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
|||
return curr_gpd_;
|
||||
}
|
||||
|
||||
util::GpdFile* UserProfile::GetTitleGpd(uint32_t title_id) {
|
||||
xdbf::GpdFile* UserProfile::GetTitleGpd(uint32_t title_id) {
|
||||
if (title_id == -1) {
|
||||
return curr_gpd_;
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ util::GpdFile* UserProfile::GetTitleGpd(uint32_t title_id) {
|
|||
return &(*gpd).second;
|
||||
}
|
||||
|
||||
void UserProfile::GetTitles(std::vector<util::GpdFile*>& titles) {
|
||||
void UserProfile::GetTitles(std::vector<xdbf::GpdFile*>& titles) {
|
||||
for (auto title : title_gpds_) {
|
||||
titles.push_back(&title.second);
|
||||
}
|
||||
|
@ -344,7 +344,7 @@ bool UserProfile::UpdateAllGpds() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool UserProfile::UpdateGpd(uint32_t title_id, util::GpdFile& gpd_data) {
|
||||
bool UserProfile::UpdateGpd(uint32_t title_id, xdbf::GpdFile& gpd_data) {
|
||||
size_t gpd_length = 0;
|
||||
if (!gpd_data.Write(nullptr, &gpd_length)) {
|
||||
XELOGE("Failed to get GPD size for title %X!", title_id);
|
||||
|
@ -375,9 +375,9 @@ bool UserProfile::UpdateGpd(uint32_t title_id, util::GpdFile& gpd_data) {
|
|||
} else {
|
||||
// Check if we need to update dashboard data...
|
||||
if (title_id != kDashboardID) {
|
||||
util::XdbfTitlePlayed title_info;
|
||||
xdbf::XdbfTitlePlayed title_info;
|
||||
if (dash_gpd_.GetTitle(title_id, &title_info)) {
|
||||
std::vector<util::XdbfAchievement> gpd_achievements;
|
||||
std::vector<xdbf::XdbfAchievement> gpd_achievements;
|
||||
gpd_data.GetAchievements(&gpd_achievements);
|
||||
|
||||
uint32_t num_ach_total = 0;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "xenia/kernel/util/xdbf_utils.h"
|
||||
#include "xenia/kernel/xam/xdbf/xdbf.h"
|
||||
#include "xenia/xbox.h"
|
||||
|
||||
namespace xe {
|
||||
|
@ -207,17 +207,17 @@ class UserProfile {
|
|||
void AddSetting(std::unique_ptr<Setting> setting);
|
||||
Setting* GetSetting(uint32_t setting_id);
|
||||
|
||||
util::GpdFile* SetTitleSpaData(const util::SpaFile& spa_data);
|
||||
util::GpdFile* GetTitleGpd(uint32_t title_id = -1);
|
||||
xdbf::GpdFile* SetTitleSpaData(const xdbf::SpaFile& spa_data);
|
||||
xdbf::GpdFile* GetTitleGpd(uint32_t title_id = -1);
|
||||
|
||||
void GetTitles(std::vector<util::GpdFile*>& titles);
|
||||
void GetTitles(std::vector<xdbf::GpdFile*>& titles);
|
||||
|
||||
bool UpdateTitleGpd(uint32_t title_id = -1);
|
||||
bool UpdateAllGpds();
|
||||
|
||||
private:
|
||||
void LoadGpdFiles();
|
||||
bool UpdateGpd(uint32_t title_id, util::GpdFile& gpd_data);
|
||||
bool UpdateGpd(uint32_t title_id, xdbf::GpdFile& gpd_data);
|
||||
|
||||
uint64_t xuid_;
|
||||
std::string name_;
|
||||
|
@ -226,10 +226,10 @@ class UserProfile {
|
|||
|
||||
void LoadSetting(UserProfile::Setting*);
|
||||
void SaveSetting(UserProfile::Setting*);
|
||||
|
||||
std::unordered_map<uint32_t, util::GpdFile> title_gpds_;
|
||||
util::GpdFile dash_gpd_;
|
||||
util::GpdFile* curr_gpd_ = nullptr;
|
||||
|
||||
std::unordered_map<uint32_t, xdbf::GpdFile> title_gpds_;
|
||||
xdbf::GpdFile dash_gpd_;
|
||||
xdbf::GpdFile* curr_gpd_ = nullptr;
|
||||
uint32_t curr_title_id_ = -1;
|
||||
};
|
||||
|
||||
|
|
|
@ -599,7 +599,7 @@ dword_result_t XamUserCreateAchievementEnumerator(dword_t title_id,
|
|||
xe::copy_and_swap(place_addr, placeholder_val, wcslen(placeholder_val));
|
||||
}
|
||||
|
||||
std::vector<util::XdbfAchievement> achievements;
|
||||
std::vector<xdbf::XdbfAchievement> achievements;
|
||||
game_gpd->GetAchievements(&achievements);
|
||||
|
||||
for (auto ach : achievements) {
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "xenia/kernel/util/xdbf_utils.h"
|
||||
#include "xenia/kernel/xam/xdbf/xdbf.h"
|
||||
#include "xenia/base/string.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace util {
|
||||
namespace xam {
|
||||
namespace xdbf {
|
||||
|
||||
constexpr uint32_t kXdbfMagicXdbf = 'XDBF';
|
||||
|
||||
|
@ -430,6 +431,7 @@ bool GpdFile::UpdateTitle(XdbfTitlePlayed title) {
|
|||
return UpdateEntry(ent);
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace xdbf
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
|
@ -7,8 +7,8 @@
|
|||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_KERNEL_UTIL_XDBF_UTILS_H_
|
||||
#define XENIA_KERNEL_UTIL_XDBF_UTILS_H_
|
||||
#ifndef XENIA_KERNEL_XAM_XDBF_XDBF_H_
|
||||
#define XENIA_KERNEL_XAM_XDBF_XDBF_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -16,9 +16,12 @@
|
|||
#include "xenia/base/clock.h"
|
||||
#include "xenia/base/memory.h"
|
||||
|
||||
#include "xenia/kernel/xam/xdbf/xdbf_xbox.h"
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace util {
|
||||
namespace xam {
|
||||
namespace xdbf {
|
||||
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.h
|
||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.cpp
|
||||
|
@ -59,118 +62,6 @@ enum class XdbfLocale : uint32_t {
|
|||
kChinese = 8,
|
||||
};
|
||||
|
||||
struct XdbfStringTableEntry {
|
||||
xe::be<uint16_t> id;
|
||||
xe::be<uint16_t> string_length;
|
||||
};
|
||||
static_assert_size(XdbfStringTableEntry, 4);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct X_XDBF_HEADER {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> version;
|
||||
xe::be<uint32_t> entry_count;
|
||||
xe::be<uint32_t> entry_used;
|
||||
xe::be<uint32_t> free_count;
|
||||
xe::be<uint32_t> free_used;
|
||||
};
|
||||
static_assert_size(X_XDBF_HEADER, 24);
|
||||
|
||||
struct X_XDBF_ENTRY {
|
||||
xe::be<uint16_t> section;
|
||||
xe::be<uint64_t> id;
|
||||
xe::be<uint32_t> offset;
|
||||
xe::be<uint32_t> size;
|
||||
};
|
||||
static_assert_size(X_XDBF_ENTRY, 18);
|
||||
|
||||
struct X_XDBF_FILELOC {
|
||||
xe::be<uint32_t> offset;
|
||||
xe::be<uint32_t> size;
|
||||
};
|
||||
static_assert_size(X_XDBF_FILELOC, 8);
|
||||
|
||||
struct X_XDBF_XSTC_DATA {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> version;
|
||||
xe::be<uint32_t> size;
|
||||
xe::be<uint32_t> default_language;
|
||||
};
|
||||
static_assert_size(X_XDBF_XSTC_DATA, 16);
|
||||
|
||||
struct X_XDBF_XTHD_DATA {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> version;
|
||||
xe::be<uint32_t> unk8;
|
||||
xe::be<uint32_t> title_id;
|
||||
xe::be<uint32_t> unk10; // always 1?
|
||||
xe::be<uint16_t> title_version_major;
|
||||
xe::be<uint16_t> title_version_minor;
|
||||
xe::be<uint16_t> title_version_build;
|
||||
xe::be<uint16_t> title_version_revision;
|
||||
xe::be<uint32_t> unk1C;
|
||||
xe::be<uint32_t> unk20;
|
||||
xe::be<uint32_t> unk24;
|
||||
xe::be<uint32_t> unk28;
|
||||
};
|
||||
static_assert_size(X_XDBF_XTHD_DATA, 0x2C);
|
||||
|
||||
struct X_XDBF_TABLE_HEADER {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> version;
|
||||
xe::be<uint32_t> size;
|
||||
xe::be<uint16_t> count;
|
||||
};
|
||||
static_assert_size(X_XDBF_TABLE_HEADER, 14);
|
||||
|
||||
struct X_XDBF_SPA_ACHIEVEMENT {
|
||||
xe::be<uint16_t> id;
|
||||
xe::be<uint16_t> label_id;
|
||||
xe::be<uint16_t> description_id;
|
||||
xe::be<uint16_t> unachieved_id;
|
||||
xe::be<uint32_t> image_id;
|
||||
xe::be<uint16_t> gamerscore;
|
||||
xe::be<uint16_t> unkE;
|
||||
xe::be<uint32_t> flags;
|
||||
xe::be<uint32_t> unk14;
|
||||
xe::be<uint32_t> unk18;
|
||||
xe::be<uint32_t> unk1C;
|
||||
xe::be<uint32_t> unk20;
|
||||
};
|
||||
static_assert_size(X_XDBF_SPA_ACHIEVEMENT, 0x24);
|
||||
|
||||
struct X_XDBF_GPD_ACHIEVEMENT {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> id;
|
||||
xe::be<uint32_t> image_id;
|
||||
xe::be<uint32_t> gamerscore;
|
||||
xe::be<uint32_t> flags;
|
||||
xe::be<uint64_t> unlock_time;
|
||||
// wchar_t* title;
|
||||
// wchar_t* description;
|
||||
// wchar_t* unlocked_description;
|
||||
};
|
||||
|
||||
// from https://github.com/xemio/testdev/blob/master/xkelib/xam/_xamext.h
|
||||
struct X_XDBF_GPD_TITLEPLAYED {
|
||||
xe::be<uint32_t> title_id;
|
||||
xe::be<uint32_t> achievements_possible;
|
||||
xe::be<uint32_t> achievements_earned;
|
||||
xe::be<uint32_t> gamerscore_total;
|
||||
xe::be<uint32_t> gamerscore_earned;
|
||||
xe::be<uint16_t> reserved_achievement_count;
|
||||
|
||||
// the following are meant to be split into possible/earned, 1 byte each
|
||||
// but who cares
|
||||
xe::be<uint16_t> all_avatar_awards;
|
||||
xe::be<uint16_t> male_avatar_awards;
|
||||
xe::be<uint16_t> female_avatar_awards;
|
||||
xe::be<uint32_t> reserved_flags;
|
||||
xe::be<uint64_t> last_played;
|
||||
// wchar_t* title_name;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
inline std::wstring ReadNullTermString(const wchar_t* ptr) {
|
||||
std::wstring retval;
|
||||
wchar_t data = xe::byte_swap(*ptr);
|
||||
|
@ -371,8 +262,9 @@ class GpdFile : public XdbfFile {
|
|||
uint32_t title_id_ = -1;
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace xdbf
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_KERNEL_UTIL_XDBF_UTILS_H_
|
||||
#endif // XENIA_KERNEL_XAM_XDBF_XDBF_H_
|
|
@ -0,0 +1,137 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2016 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_KERNEL_XAM_XDBF_XDBF_XBOX_H_
|
||||
#define XENIA_KERNEL_XAM_XDBF_XDBF_XBOX_H_
|
||||
|
||||
namespace xe {
|
||||
namespace kernel {
|
||||
namespace xam {
|
||||
namespace xdbf {
|
||||
|
||||
/* Native XDBF structs used by 360 are in this file */
|
||||
|
||||
struct XdbfStringTableEntry {
|
||||
xe::be<uint16_t> id;
|
||||
xe::be<uint16_t> string_length;
|
||||
};
|
||||
static_assert_size(XdbfStringTableEntry, 4);
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct X_XDBF_HEADER {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> version;
|
||||
xe::be<uint32_t> entry_count;
|
||||
xe::be<uint32_t> entry_used;
|
||||
xe::be<uint32_t> free_count;
|
||||
xe::be<uint32_t> free_used;
|
||||
};
|
||||
static_assert_size(X_XDBF_HEADER, 24);
|
||||
|
||||
struct X_XDBF_ENTRY {
|
||||
xe::be<uint16_t> section;
|
||||
xe::be<uint64_t> id;
|
||||
xe::be<uint32_t> offset;
|
||||
xe::be<uint32_t> size;
|
||||
};
|
||||
static_assert_size(X_XDBF_ENTRY, 18);
|
||||
|
||||
struct X_XDBF_FILELOC {
|
||||
xe::be<uint32_t> offset;
|
||||
xe::be<uint32_t> size;
|
||||
};
|
||||
static_assert_size(X_XDBF_FILELOC, 8);
|
||||
|
||||
struct X_XDBF_XSTC_DATA {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> version;
|
||||
xe::be<uint32_t> size;
|
||||
xe::be<uint32_t> default_language;
|
||||
};
|
||||
static_assert_size(X_XDBF_XSTC_DATA, 16);
|
||||
|
||||
struct X_XDBF_XTHD_DATA {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> version;
|
||||
xe::be<uint32_t> unk8;
|
||||
xe::be<uint32_t> title_id;
|
||||
xe::be<uint32_t> unk10; // always 1?
|
||||
xe::be<uint16_t> title_version_major;
|
||||
xe::be<uint16_t> title_version_minor;
|
||||
xe::be<uint16_t> title_version_build;
|
||||
xe::be<uint16_t> title_version_revision;
|
||||
xe::be<uint32_t> unk1C;
|
||||
xe::be<uint32_t> unk20;
|
||||
xe::be<uint32_t> unk24;
|
||||
xe::be<uint32_t> unk28;
|
||||
};
|
||||
static_assert_size(X_XDBF_XTHD_DATA, 0x2C);
|
||||
|
||||
struct X_XDBF_TABLE_HEADER {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> version;
|
||||
xe::be<uint32_t> size;
|
||||
xe::be<uint16_t> count;
|
||||
};
|
||||
static_assert_size(X_XDBF_TABLE_HEADER, 14);
|
||||
|
||||
struct X_XDBF_SPA_ACHIEVEMENT {
|
||||
xe::be<uint16_t> id;
|
||||
xe::be<uint16_t> label_id;
|
||||
xe::be<uint16_t> description_id;
|
||||
xe::be<uint16_t> unachieved_id;
|
||||
xe::be<uint32_t> image_id;
|
||||
xe::be<uint16_t> gamerscore;
|
||||
xe::be<uint16_t> unkE;
|
||||
xe::be<uint32_t> flags;
|
||||
xe::be<uint32_t> unk14;
|
||||
xe::be<uint32_t> unk18;
|
||||
xe::be<uint32_t> unk1C;
|
||||
xe::be<uint32_t> unk20;
|
||||
};
|
||||
static_assert_size(X_XDBF_SPA_ACHIEVEMENT, 0x24);
|
||||
|
||||
struct X_XDBF_GPD_ACHIEVEMENT {
|
||||
xe::be<uint32_t> magic;
|
||||
xe::be<uint32_t> id;
|
||||
xe::be<uint32_t> image_id;
|
||||
xe::be<uint32_t> gamerscore;
|
||||
xe::be<uint32_t> flags;
|
||||
xe::be<uint64_t> unlock_time;
|
||||
// wchar_t* title;
|
||||
// wchar_t* description;
|
||||
// wchar_t* unlocked_description;
|
||||
};
|
||||
|
||||
// from https://github.com/xemio/testdev/blob/master/xkelib/xam/_xamext.h
|
||||
struct X_XDBF_GPD_TITLEPLAYED {
|
||||
xe::be<uint32_t> title_id;
|
||||
xe::be<uint32_t> achievements_possible;
|
||||
xe::be<uint32_t> achievements_earned;
|
||||
xe::be<uint32_t> gamerscore_total;
|
||||
xe::be<uint32_t> gamerscore_earned;
|
||||
xe::be<uint16_t> reserved_achievement_count;
|
||||
|
||||
// the following are meant to be split into possible/earned, 1 byte each
|
||||
// but who cares
|
||||
xe::be<uint16_t> all_avatar_awards;
|
||||
xe::be<uint16_t> male_avatar_awards;
|
||||
xe::be<uint16_t> female_avatar_awards;
|
||||
xe::be<uint32_t> reserved_flags;
|
||||
xe::be<uint64_t> last_played;
|
||||
// wchar_t* title_name;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
} // namespace xdbf
|
||||
} // namespace xam
|
||||
} // namespace kernel
|
||||
} // namespace xe
|
||||
|
||||
#endif // XENIA_KERNEL_XAM_XDBF_XDBF_XBOX_H_
|
Loading…
Reference in New Issue