[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/kernel_state.h"
|
||||||
#include "xenia/kernel/user_module.h"
|
#include "xenia/kernel/user_module.h"
|
||||||
#include "xenia/kernel/util/gameinfo_utils.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/xam_module.h"
|
||||||
|
#include "xenia/kernel/xam/xdbf/xdbf.h"
|
||||||
#include "xenia/kernel/xbdm/xbdm_module.h"
|
#include "xenia/kernel/xbdm/xbdm_module.h"
|
||||||
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
#include "xenia/kernel/xboxkrnl/xboxkrnl_module.h"
|
||||||
#include "xenia/memory.h"
|
#include "xenia/memory.h"
|
||||||
|
@ -662,7 +662,7 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
|
||||||
uint32_t resource_size = 0;
|
uint32_t resource_size = 0;
|
||||||
if (XSUCCEEDED(
|
if (XSUCCEEDED(
|
||||||
module->GetSection(title_id, &resource_data, &resource_size))) {
|
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),
|
if (spa.Read(module->memory()->TranslateVirtual(resource_data),
|
||||||
resource_size)) {
|
resource_size)) {
|
||||||
// Set title SPA and get title name/icon
|
// 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;
|
bool modified = false;
|
||||||
auto* achievement =
|
auto* achievement =
|
||||||
(X_XUSER_ACHIEVEMENT*)memory_->TranslateVirtual(achievements_ptr);
|
(X_XUSER_ACHIEVEMENT*)memory_->TranslateVirtual(achievements_ptr);
|
||||||
util::XdbfAchievement ach;
|
xdbf::XdbfAchievement ach;
|
||||||
for (uint32_t i = 0; i < achievement_count; i++, achievement++) {
|
for (uint32_t i = 0; i < achievement_count; i++, achievement++) {
|
||||||
if (game_gpd->GetAchievement(achievement->achievement_id, &ach)) {
|
if (game_gpd->GetAchievement(achievement->achievement_id, &ach)) {
|
||||||
if (!ach.IsUnlocked()) {
|
if (!ach.IsUnlocked()) {
|
||||||
|
|
|
@ -117,7 +117,7 @@ void UserProfile::LoadGpdFiles() {
|
||||||
dash_gpd_.Read(mmap_->data(), mmap_->size());
|
dash_gpd_.Read(mmap_->data(), mmap_->size());
|
||||||
mmap_->Close();
|
mmap_->Close();
|
||||||
|
|
||||||
std::vector<util::XdbfTitlePlayed> titles;
|
std::vector<xdbf::XdbfTitlePlayed> titles;
|
||||||
dash_gpd_.GetTitles(&titles);
|
dash_gpd_.GetTitles(&titles);
|
||||||
|
|
||||||
for (auto title : titles) {
|
for (auto title : titles) {
|
||||||
|
@ -131,7 +131,7 @@ void UserProfile::LoadGpdFiles() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::GpdFile title_gpd(title.title_id);
|
xdbf::GpdFile title_gpd(title.title_id);
|
||||||
bool result = title_gpd.Read(mmap_->data(), mmap_->size());
|
bool result = title_gpd.Read(mmap_->data(), mmap_->size());
|
||||||
mmap_->Close();
|
mmap_->Close();
|
||||||
|
|
||||||
|
@ -147,14 +147,14 @@ void UserProfile::LoadGpdFiles() {
|
||||||
XELOGI("Loaded %d profile GPDs", title_gpds_.size() + 1);
|
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();
|
uint32_t spa_title = spa_data.GetTitleId();
|
||||||
|
|
||||||
std::vector<util::XdbfAchievement> spa_achievements;
|
std::vector<xdbf::XdbfAchievement> spa_achievements;
|
||||||
// TODO: let user choose locale?
|
// TODO: let user choose locale?
|
||||||
spa_data.GetAchievements(spa_data.GetDefaultLocale(), &spa_achievements);
|
spa_data.GetAchievements(spa_data.GetDefaultLocale(), &spa_achievements);
|
||||||
|
|
||||||
util::XdbfTitlePlayed title_info;
|
xdbf::XdbfTitlePlayed title_info;
|
||||||
|
|
||||||
auto gpd = title_gpds_.find(spa_title);
|
auto gpd = title_gpds_.find(spa_title);
|
||||||
if (gpd != title_gpds_.end()) {
|
if (gpd != title_gpds_.end()) {
|
||||||
|
@ -221,7 +221,7 @@ util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
||||||
title_info.last_played = Clock::QueryHostSystemTime();
|
title_info.last_played = Clock::QueryHostSystemTime();
|
||||||
|
|
||||||
// Copy cheevos from SPA -> GPD
|
// Copy cheevos from SPA -> GPD
|
||||||
util::GpdFile title_gpd(spa_title);
|
xdbf::GpdFile title_gpd(spa_title);
|
||||||
for (auto ach : spa_achievements) {
|
for (auto ach : spa_achievements) {
|
||||||
title_gpd.UpdateAchievement(ach);
|
title_gpd.UpdateAchievement(ach);
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
||||||
// Try copying achievement images if we can...
|
// Try copying achievement images if we can...
|
||||||
for (auto ach : spa_achievements) {
|
for (auto ach : spa_achievements) {
|
||||||
auto* image_entry = spa_data.GetEntry(
|
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) {
|
if (image_entry) {
|
||||||
title_gpd.UpdateEntry(*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
|
// Try adding title image & name
|
||||||
auto* title_image =
|
auto* title_image =
|
||||||
spa_data.GetEntry(static_cast<uint16_t>(util::XdbfSpaSection::kImage),
|
spa_data.GetEntry(static_cast<uint16_t>(xdbf::XdbfSpaSection::kImage),
|
||||||
static_cast<uint64_t>(util::XdbfSpaID::Title));
|
static_cast<uint64_t>(xdbf::XdbfSpaID::Title));
|
||||||
if (title_image) {
|
if (title_image) {
|
||||||
title_gpd.UpdateEntry(*title_image);
|
title_gpd.UpdateEntry(*title_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto title_name = xe::to_wstring(spa_data.GetTitleName());
|
auto title_name = xe::to_wstring(spa_data.GetTitleName());
|
||||||
if (title_name.length()) {
|
if (title_name.length()) {
|
||||||
util::XdbfEntry title_name_ent;
|
xdbf::XdbfEntry title_name_ent;
|
||||||
title_name_ent.info.section =
|
title_name_ent.info.section =
|
||||||
static_cast<uint16_t>(util::XdbfGpdSection::kString);
|
static_cast<uint16_t>(xdbf::XdbfGpdSection::kString);
|
||||||
title_name_ent.info.id = static_cast<uint64_t>(util::XdbfSpaID::Title);
|
title_name_ent.info.id = static_cast<uint64_t>(xdbf::XdbfSpaID::Title);
|
||||||
title_name_ent.data.resize((title_name.length() + 1) * 2);
|
title_name_ent.data.resize((title_name.length() + 1) * 2);
|
||||||
xe::copy_and_swap((wchar_t*)title_name_ent.data.data(),
|
xe::copy_and_swap((wchar_t*)title_name_ent.data.data(),
|
||||||
title_name.c_str(), title_name.length());
|
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
|
// Print achievement list to log, ATM there's no other way for users to see
|
||||||
// achievement status...
|
// achievement status...
|
||||||
std::vector<util::XdbfAchievement> achievements;
|
std::vector<xdbf::XdbfAchievement> achievements;
|
||||||
if (curr_gpd_->GetAchievements(&achievements)) {
|
if (curr_gpd_->GetAchievements(&achievements)) {
|
||||||
XELOGI("Achievement list:");
|
XELOGI("Achievement list:");
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ util::GpdFile* UserProfile::SetTitleSpaData(const util::SpaFile& spa_data) {
|
||||||
return curr_gpd_;
|
return curr_gpd_;
|
||||||
}
|
}
|
||||||
|
|
||||||
util::GpdFile* UserProfile::GetTitleGpd(uint32_t title_id) {
|
xdbf::GpdFile* UserProfile::GetTitleGpd(uint32_t title_id) {
|
||||||
if (title_id == -1) {
|
if (title_id == -1) {
|
||||||
return curr_gpd_;
|
return curr_gpd_;
|
||||||
}
|
}
|
||||||
|
@ -306,7 +306,7 @@ util::GpdFile* UserProfile::GetTitleGpd(uint32_t title_id) {
|
||||||
return &(*gpd).second;
|
return &(*gpd).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserProfile::GetTitles(std::vector<util::GpdFile*>& titles) {
|
void UserProfile::GetTitles(std::vector<xdbf::GpdFile*>& titles) {
|
||||||
for (auto title : title_gpds_) {
|
for (auto title : title_gpds_) {
|
||||||
titles.push_back(&title.second);
|
titles.push_back(&title.second);
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ bool UserProfile::UpdateAllGpds() {
|
||||||
return true;
|
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;
|
size_t gpd_length = 0;
|
||||||
if (!gpd_data.Write(nullptr, &gpd_length)) {
|
if (!gpd_data.Write(nullptr, &gpd_length)) {
|
||||||
XELOGE("Failed to get GPD size for title %X!", title_id);
|
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 {
|
} else {
|
||||||
// Check if we need to update dashboard data...
|
// Check if we need to update dashboard data...
|
||||||
if (title_id != kDashboardID) {
|
if (title_id != kDashboardID) {
|
||||||
util::XdbfTitlePlayed title_info;
|
xdbf::XdbfTitlePlayed title_info;
|
||||||
if (dash_gpd_.GetTitle(title_id, &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);
|
gpd_data.GetAchievements(&gpd_achievements);
|
||||||
|
|
||||||
uint32_t num_ach_total = 0;
|
uint32_t num_ach_total = 0;
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/kernel/util/xdbf_utils.h"
|
#include "xenia/kernel/xam/xdbf/xdbf.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -207,17 +207,17 @@ class UserProfile {
|
||||||
void AddSetting(std::unique_ptr<Setting> setting);
|
void AddSetting(std::unique_ptr<Setting> setting);
|
||||||
Setting* GetSetting(uint32_t setting_id);
|
Setting* GetSetting(uint32_t setting_id);
|
||||||
|
|
||||||
util::GpdFile* SetTitleSpaData(const util::SpaFile& spa_data);
|
xdbf::GpdFile* SetTitleSpaData(const xdbf::SpaFile& spa_data);
|
||||||
util::GpdFile* GetTitleGpd(uint32_t title_id = -1);
|
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 UpdateTitleGpd(uint32_t title_id = -1);
|
||||||
bool UpdateAllGpds();
|
bool UpdateAllGpds();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadGpdFiles();
|
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_;
|
uint64_t xuid_;
|
||||||
std::string name_;
|
std::string name_;
|
||||||
|
@ -226,10 +226,10 @@ class UserProfile {
|
||||||
|
|
||||||
void LoadSetting(UserProfile::Setting*);
|
void LoadSetting(UserProfile::Setting*);
|
||||||
void SaveSetting(UserProfile::Setting*);
|
void SaveSetting(UserProfile::Setting*);
|
||||||
|
|
||||||
std::unordered_map<uint32_t, util::GpdFile> title_gpds_;
|
std::unordered_map<uint32_t, xdbf::GpdFile> title_gpds_;
|
||||||
util::GpdFile dash_gpd_;
|
xdbf::GpdFile dash_gpd_;
|
||||||
util::GpdFile* curr_gpd_ = nullptr;
|
xdbf::GpdFile* curr_gpd_ = nullptr;
|
||||||
uint32_t curr_title_id_ = -1;
|
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));
|
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);
|
game_gpd->GetAchievements(&achievements);
|
||||||
|
|
||||||
for (auto ach : 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"
|
#include "xenia/base/string.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
namespace kernel {
|
||||||
namespace util {
|
namespace xam {
|
||||||
|
namespace xdbf {
|
||||||
|
|
||||||
constexpr uint32_t kXdbfMagicXdbf = 'XDBF';
|
constexpr uint32_t kXdbfMagicXdbf = 'XDBF';
|
||||||
|
|
||||||
|
@ -430,6 +431,7 @@ bool GpdFile::UpdateTitle(XdbfTitlePlayed title) {
|
||||||
return UpdateEntry(ent);
|
return UpdateEntry(ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace util
|
} // namespace xdbf
|
||||||
|
} // namespace xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // namespace xe
|
|
@ -7,8 +7,8 @@
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef XENIA_KERNEL_UTIL_XDBF_UTILS_H_
|
#ifndef XENIA_KERNEL_XAM_XDBF_XDBF_H_
|
||||||
#define XENIA_KERNEL_UTIL_XDBF_UTILS_H_
|
#define XENIA_KERNEL_XAM_XDBF_XDBF_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -16,9 +16,12 @@
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/memory.h"
|
#include "xenia/base/memory.h"
|
||||||
|
|
||||||
|
#include "xenia/kernel/xam/xdbf/xdbf_xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace kernel {
|
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.h
|
||||||
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.cpp
|
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.cpp
|
||||||
|
@ -59,118 +62,6 @@ enum class XdbfLocale : uint32_t {
|
||||||
kChinese = 8,
|
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) {
|
inline std::wstring ReadNullTermString(const wchar_t* ptr) {
|
||||||
std::wstring retval;
|
std::wstring retval;
|
||||||
wchar_t data = xe::byte_swap(*ptr);
|
wchar_t data = xe::byte_swap(*ptr);
|
||||||
|
@ -371,8 +262,9 @@ class GpdFile : public XdbfFile {
|
||||||
uint32_t title_id_ = -1;
|
uint32_t title_id_ = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace util
|
} // namespace xdbf
|
||||||
|
} // namespace xam
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
} // namespace xe
|
} // 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