Files
Xenia-Canary/src/xenia/kernel/xam/xdbf/xdbf_io.h
The-Little-Wolf 921a33a798 [XAM/AVATAR] - expanding on stubs
- Add structs
- Sketchy implementation of XamAvatarGetInstalledAssetPackageDescription
- Stub XamAvatarSetManifest
- Have XAvatarGetAssets return X_E_FAIL in overlapped to allow [58410907](https://github.com/xenia-project/game-compatibility/issues/1848) to start match in netplay
- Adrian helped find lots of the unknowns and stub XamAvatarGetManifestLocalUser

Co-Authored-By: Adrian <78108584+AdrianCassar@users.noreply.github.com>
2025-10-31 09:35:45 +01:00

231 lines
5.9 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2025 Xenia Emulator. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_XAM_XDBF_XDBF_IO_H_
#define XENIA_KERNEL_XAM_XDBF_XDBF_IO_H_
#include <span>
#include <string>
#include <vector>
#include "xenia/base/memory.h"
#include "xenia/xbox.h"
namespace xe {
namespace kernel {
namespace xam {
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.h
// https://github.com/oukiar/freestyledash/blob/master/Freestyle/Tools/XEX/SPA.cpp
constexpr fourcc_t kXdbfSignatureXdbf = make_fourcc("XDBF");
constexpr fourcc_t kXdbfSignatureXstc = make_fourcc("XSTC");
constexpr fourcc_t kXdbfSignatureXstr = make_fourcc("XSTR");
constexpr fourcc_t kXdbfSignatureXach = make_fourcc("XACH");
constexpr fourcc_t kXdbfSignatureXprp = make_fourcc("XPRP");
constexpr fourcc_t kXdbfSignatureXcxt = make_fourcc("XCXT");
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 uint64_t kXdbfIdTitle = 0x8000;
constexpr uint64_t kXdbfIdXstc = 0x58535443;
constexpr uint64_t kXdbfIdXach = 0x58414348;
constexpr uint64_t kXdbfIdXprp = 0x58505250;
constexpr uint64_t kXdbfIdXctx = 0x58435854;
constexpr uint64_t kXdbfIdXvc2 = 0x58564332;
constexpr uint64_t kXdbfIdXmat = 0x584D4154;
constexpr uint64_t kXdbfIdXsrc = 0x58535243;
constexpr uint64_t kXdbfIdXthd = 0x58544844;
#pragma pack(push, 1)
struct XdbfHeader {
XdbfHeader() {
magic = kXdbfSignatureXdbf;
version = 0x10000;
entry_count = 0;
entry_used = 0;
free_count = 0;
free_used = 0;
}
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(XdbfHeader, 24);
struct XdbfEntry {
xe::be<uint16_t> section;
xe::be<uint64_t> id;
xe::be<uint32_t> offset;
xe::be<uint32_t> size;
};
static_assert_size(XdbfEntry, 18);
struct XdbfFileLoc {
xe::be<uint32_t> offset;
xe::be<uint32_t> size;
};
static_assert_size(XdbfFileLoc, 8);
struct XdbfXstc {
xe::be<uint32_t> magic;
xe::be<uint32_t> version;
xe::be<uint32_t> size;
xe::be<uint32_t> default_language;
};
static_assert_size(XdbfXstc, 16);
struct XdbfSectionHeader {
xe::be<uint32_t> magic;
xe::be<uint32_t> version;
xe::be<uint32_t> size;
};
static_assert_size(XdbfSectionHeader, 12);
struct XdbfSectionHeaderEx {
xe::be<uint32_t> magic;
xe::be<uint32_t> version;
xe::be<uint32_t> size;
xe::be<uint16_t> count;
};
static_assert_size(XdbfSectionHeaderEx, 14);
struct XdbfStringTableEntry {
xe::be<uint16_t> id;
xe::be<uint16_t> string_length;
};
static_assert_size(XdbfStringTableEntry, 4);
struct XdbfContextTableEntry {
xe::be<uint32_t> id;
xe::be<uint16_t> unk1;
xe::be<uint16_t> string_id;
xe::be<uint32_t> max_value;
xe::be<uint32_t> default_value;
};
static_assert_size(XdbfContextTableEntry, 16);
struct XdbfPropertyTableEntry {
xe::be<uint32_t> id;
xe::be<uint16_t> string_id;
xe::be<uint16_t> data_size;
};
static_assert_size(XdbfPropertyTableEntry, 8);
#pragma pack(pop)
struct XdbfBlock {
const uint8_t* buffer;
size_t size;
operator bool() const { return buffer != nullptr; }
};
struct Entry {
Entry() {
info.id = 0;
info.offset = 0;
info.section = 0;
info.size = 0;
}
// Offset must be filled externally!
Entry(const uint64_t id, const uint16_t section, const uint32_t size) {
info.id = id;
info.section = section;
info.size = size;
data.resize(size);
}
Entry(const XdbfEntry* entry, const uint8_t* entry_data) {
info = *entry;
data.resize(info.size);
memcpy(data.data(), entry_data + info.offset, info.size);
}
XdbfEntry info;
std::vector<uint8_t> data;
};
// Wraps an XDBF (XboxDataBaseFormat) in-memory database.
// https://free60project.github.io/wiki/XDBF.html
class XdbfFile {
public:
XdbfFile() = default;
XdbfFile(const std::span<const uint8_t> buffer);
~XdbfFile() = default;
const Entry* const GetEntry(uint16_t section, uint64_t id) const;
protected:
XdbfHeader header_ = {};
std::vector<Entry> entries_ = {};
std::vector<XdbfFileLoc> free_entries_ = {};
// Gets an entry in the given section.
// If the entry is not found the returned block will be nullptr.
Entry* GetEntry(uint16_t section, uint64_t id);
uint32_t CalculateDataStartOffset() const;
uint32_t CalculateEntriesSize() const;
private:
bool LoadHeader(const XdbfHeader* header);
void LoadEntries(const XdbfEntry* table_of_content, const uint8_t* data_ptr);
void LoadFreeEntries(const XdbfFileLoc* free_entries);
};
struct X_STRB_HEADER {
uint32_t magic;
bool blockAlignmentStored;
bool littleEndian;
uint8_t guid[0x10];
uint8_t blockIDSize;
uint8_t blockSpanSize;
uint16_t unused;
uint8_t blockAlignment;
int32_t blockHeaderSize;
uint32_t blockStartAddress;
};
static_assert_size(X_STRB_HEADER, 36);
enum X_STRRB_BLOCK_ID : uint8_t {
STRBEof = 0xFF, // -1
STRBInvalid = 0,
STRBAnimation = 1,
STRBTexture = 2,
STRBModel = 3,
STRBShapeOverrides = 4,
STRBSkeleton = 5,
STRBAssetMetadata = 6,
STRBCustomColorTable = 7,
STRBAssetMetadataVersioned = 8,
};
struct X_STRB_BLOCK {
X_STRRB_BLOCK_ID id;
int32_t data_length;
int32_t field_size;
uint32_t data_ptr; // uint8_t*
uint32_t data_address;
};
static_assert_size(X_STRB_BLOCK, 20);
} // namespace xam
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XAM_XDBF_XDBF_IO_H_