[Kernel] Move XDBF code to its own namespace

This commit is contained in:
emoose 2018-11-18 06:06:38 +00:00
parent 8f5a82b444
commit c1eaf6879a
No known key found for this signature in database
GPG Key ID: 3735C67912F5FF97
8 changed files with 182 additions and 151 deletions

View File

@ -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

View File

@ -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()) {

View File

@ -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;

View File

@ -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;
};

View File

@ -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) {

View File

@ -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

View File

@ -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_

View File

@ -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_