/** ****************************************************************************** * 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. * ****************************************************************************** * * @modified Tom Clay, 2026 - Adapted for ReXGlue runtime */ #pragma once #include #include #include #include #include namespace rex { namespace system { namespace util { // https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.h // https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.cpp enum class XdbfSection : uint16_t { kMetadata = 0x0001, kImage = 0x0002, kStringTable = 0x0003, }; #pragma pack(push, 1) struct XbdfHeader { rex::be magic; rex::be version; rex::be entry_count; rex::be entry_used; rex::be free_count; rex::be free_used; }; static_assert_size(XbdfHeader, 24); struct XbdfEntry { rex::be section; rex::be id; rex::be offset; rex::be size; }; static_assert_size(XbdfEntry, 18); struct XbdfFileLoc { rex::be offset; rex::be size; }; static_assert_size(XbdfFileLoc, 8); struct XdbfXstc { rex::be magic; rex::be version; rex::be size; rex::be default_language; }; static_assert_size(XdbfXstc, 16); struct XdbfSectionHeader { rex::be magic; rex::be version; rex::be size; rex::be count; }; static_assert_size(XdbfSectionHeader, 14); struct XdbfStringTableEntry { rex::be id; rex::be string_length; }; static_assert_size(XdbfStringTableEntry, 4); struct XdbfAchievementTableEntry { rex::be id; rex::be label_id; rex::be description_id; rex::be unachieved_id; rex::be image_id; rex::be gamerscore; rex::be unkE; rex::be flags; rex::be unk14; rex::be unk18; rex::be unk1C; rex::be unk20; }; static_assert_size(XdbfAchievementTableEntry, 0x24); #pragma pack(pop) struct XdbfBlock { const uint8_t* buffer; size_t size; operator bool() const { return buffer != nullptr; } }; // Wraps an XBDF (XboxDataBaseFormat) in-memory database. // https://free60project.github.io/wiki/XDBF.html class XdbfWrapper { public: XdbfWrapper(const uint8_t* data, size_t data_size); // True if the target memory contains a valid XDBF instance. bool is_valid() const { return data_ != nullptr; } // Gets an entry in the given section. // If the entry is not found the returned block will be nullptr. XdbfBlock GetEntry(XdbfSection section, uint64_t id) const; // Gets a string from the string table in the given language. // Returns the empty string if the entry is not found. std::string GetStringTableEntry(XLanguage language, uint16_t string_id) const; std::vector GetAchievements() const; private: const uint8_t* data_ = nullptr; size_t data_size_ = 0; const uint8_t* content_offset_ = nullptr; const XbdfHeader* header_ = nullptr; const XbdfEntry* entries_ = nullptr; const XbdfFileLoc* files_ = nullptr; }; class XdbfGameData : public XdbfWrapper { public: XdbfGameData(const uint8_t* data, size_t data_size) : XdbfWrapper(data, data_size) {} // Checks if provided language exist, if not returns default title language. XLanguage GetExistingLanguage(XLanguage language_to_check) const; // The game icon image, if found. XdbfBlock icon() const; // The game's default language. XLanguage default_language() const; // The game's title in its default language. std::string title() const; std::string title(XLanguage language) const; }; } // namespace util } // namespace system } // namespace rex