[XAM] Implemented SPA XRPT
This commit is contained in:
@@ -24,6 +24,7 @@ void SpaInfo::Load() {
|
||||
LoadAchievements();
|
||||
LoadProperties();
|
||||
LoadContexts();
|
||||
LoadPresenceModes();
|
||||
LoadStatsViews();
|
||||
}
|
||||
|
||||
@@ -252,6 +253,82 @@ void SpaInfo::LoadStatsViews() {
|
||||
}
|
||||
}
|
||||
|
||||
void SpaInfo::LoadPresenceModes() {
|
||||
auto presence_modes_table =
|
||||
GetEntry(static_cast<uint16_t>(SpaSection::kMetadata), kXdbfIdXrpt);
|
||||
if (!presence_modes_table) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto xrpt_head = reinterpret_cast<const XdbfSectionHeader*>(
|
||||
presence_modes_table->data.data());
|
||||
assert_true(xrpt_head->magic == kXdbfSignatureXrpt);
|
||||
assert_true(xrpt_head->version == 1);
|
||||
|
||||
auto xpbm_head_start_ptr = reinterpret_cast<const uint8_t*>(xrpt_head + 1);
|
||||
|
||||
auto xpbm_head =
|
||||
reinterpret_cast<const XdbfSectionHeader*>(xpbm_head_start_ptr);
|
||||
|
||||
assert_true(xpbm_head->magic == kXdbfSignatureXpbm);
|
||||
assert_true(xpbm_head->version == 1);
|
||||
|
||||
const PropertyBagEntry* property_bag_header_ptr =
|
||||
reinterpret_cast<const PropertyBagEntry*>(xpbm_head + 1);
|
||||
|
||||
auto contexts_ptr =
|
||||
reinterpret_cast<const xe::be<uint32_t>*>(property_bag_header_ptr + 1);
|
||||
|
||||
auto properties_ptr = reinterpret_cast<const xe::be<uint32_t>*>(
|
||||
contexts_ptr + property_bag_header_ptr->contexts_count);
|
||||
|
||||
for (uint32_t i = 0; i < property_bag_header_ptr->contexts_count; i++) {
|
||||
presence_.property_bag.contexts.insert(contexts_ptr[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < property_bag_header_ptr->properties_count; i++) {
|
||||
presence_.property_bag.properties.insert(properties_ptr[i]);
|
||||
}
|
||||
|
||||
xpbm_head_start_ptr += xpbm_head->size + sizeof(uint32_t);
|
||||
|
||||
const uint16_t presence_modes_count =
|
||||
xe::load_and_swap<uint16_t>(xpbm_head_start_ptr);
|
||||
|
||||
xpbm_head_start_ptr += sizeof(uint16_t);
|
||||
|
||||
for (size_t i = 0; i < presence_modes_count; i++) {
|
||||
PropertyBag property_bag = {};
|
||||
|
||||
auto xpbm_head =
|
||||
reinterpret_cast<const XdbfSectionHeader*>(xpbm_head_start_ptr);
|
||||
|
||||
assert_true(xpbm_head->magic == kXdbfSignatureXpbm);
|
||||
assert_true(xpbm_head->version == 1);
|
||||
|
||||
const PropertyBagEntry* property_bag_header_ptr =
|
||||
reinterpret_cast<const PropertyBagEntry*>(xpbm_head + 1);
|
||||
|
||||
auto contexts_ptr =
|
||||
reinterpret_cast<const xe::be<uint32_t>*>(property_bag_header_ptr + 1);
|
||||
|
||||
auto properties_ptr = reinterpret_cast<const xe::be<uint32_t>*>(
|
||||
contexts_ptr + property_bag_header_ptr->contexts_count);
|
||||
|
||||
for (uint32_t i = 0; i < property_bag_header_ptr->contexts_count; i++) {
|
||||
property_bag.contexts.insert(contexts_ptr[i]);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < property_bag_header_ptr->properties_count; i++) {
|
||||
property_bag.properties.insert(properties_ptr[i]);
|
||||
}
|
||||
|
||||
xpbm_head_start_ptr += xpbm_head->size + sizeof(uint32_t);
|
||||
|
||||
presence_.presence_modes.push_back(property_bag);
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t* SpaInfo::ReadXLast(uint32_t& compressed_size,
|
||||
uint32_t& decompressed_size) {
|
||||
auto xlast_table =
|
||||
@@ -380,6 +457,17 @@ const XdbfPropertyTableEntry* SpaInfo::GetProperty(uint32_t id) {
|
||||
return GetSpaEntry<const XdbfPropertyTableEntry*>(properties_, id);
|
||||
}
|
||||
|
||||
const std::optional<PropertyBag> SpaInfo::GetPresenceMode(
|
||||
uint32_t context_value) const {
|
||||
std::optional<PropertyBag> entry = std::nullopt;
|
||||
|
||||
if (context_value < presence_.presence_modes.size()) {
|
||||
entry = presence_.presence_modes.at(context_value);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
const std::optional<ViewTable> SpaInfo::GetStatsView(uint32_t id) {
|
||||
const auto itr = std::ranges::find_if(
|
||||
stats_views_,
|
||||
|
||||
@@ -222,6 +222,11 @@ struct ViewTable {
|
||||
SharedView shared_view;
|
||||
};
|
||||
|
||||
struct PresenceTableEntry {
|
||||
PropertyBag property_bag;
|
||||
std::vector<PropertyBag> presence_modes;
|
||||
};
|
||||
|
||||
struct AchievementTableEntry {
|
||||
xe::be<uint16_t> id;
|
||||
xe::be<uint16_t> label_id;
|
||||
@@ -290,9 +295,13 @@ class SpaInfo : public XdbfFile {
|
||||
|
||||
const std::vector<ViewTable>* GetStatsViews() const { return &stats_views_; }
|
||||
|
||||
const PresenceTableEntry* GetPresence() const { return &presence_; }
|
||||
|
||||
const XdbfContextTableEntry* GetContext(uint32_t id);
|
||||
const XdbfPropertyTableEntry* GetProperty(uint32_t id);
|
||||
const std::optional<ViewTable> GetStatsView(uint32_t id);
|
||||
const std::optional<PropertyBag> GetPresenceMode(
|
||||
uint32_t context_value) const;
|
||||
|
||||
uint32_t total_gamerscore() const {
|
||||
return std::accumulate(achievements_.cbegin(), achievements_.cend(), 0,
|
||||
@@ -318,6 +327,7 @@ class SpaInfo : public XdbfFile {
|
||||
std::vector<const XdbfContextTableEntry*> contexts_;
|
||||
std::vector<const XdbfPropertyTableEntry*> properties_;
|
||||
std::vector<ViewTable> stats_views_;
|
||||
PresenceTableEntry presence_;
|
||||
|
||||
using XdbfLanguageStrings = std::map<uint16_t, std::string>;
|
||||
|
||||
@@ -333,6 +343,8 @@ class SpaInfo : public XdbfFile {
|
||||
|
||||
void LoadStatsViews();
|
||||
|
||||
void LoadPresenceModes();
|
||||
|
||||
template <typename T>
|
||||
static T GetSpaEntry(std::vector<T>& container, uint32_t id);
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@ constexpr fourcc_t kXdbfSignatureXvc2 = make_fourcc("XVC2");
|
||||
constexpr fourcc_t kXdbfSignatureXmat = make_fourcc("XMAT");
|
||||
constexpr fourcc_t kXdbfSignatureXsrc = make_fourcc("XSRC");
|
||||
constexpr fourcc_t kXdbfSignatureXthd = make_fourcc("XTHD");
|
||||
constexpr fourcc_t kXdbfSignatureXrpt = make_fourcc("XRPT");
|
||||
constexpr fourcc_t kXdbfSignatureXpbm = make_fourcc("XPBM");
|
||||
|
||||
constexpr uint64_t kXdbfIdTitle = 0x8000;
|
||||
@@ -46,6 +47,7 @@ constexpr uint64_t kXdbfIdXmat = 0x584D4154;
|
||||
constexpr uint64_t kXdbfIdXsrc = 0x58535243;
|
||||
constexpr uint64_t kXdbfIdXthd = 0x58544844;
|
||||
constexpr uint64_t kXdbfIdXpbm = 0x5850424D;
|
||||
constexpr uint64_t kXdbfIdXrpt = 0x58525054;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct XdbfHeader {
|
||||
|
||||
Reference in New Issue
Block a user