Files
Xenia-Canary/src/xenia/kernel/xam/xdbf/spa_info.h
Gliniak e601b5ab87 [UI] Added modify profile UI
- Changed default icons size from 75x75 to 64x64 to match console icons size
- Added png_utils
- Removed all dialogs from xam_ui.cc into separate entities under xam/ui
- Added option to return INT32 and WSTRING type settings to host
- Added multiple enums related to user settings
- Added code to handle changing user pfp
- Fixed bug with system app being added to GPD played list
- Changed logic in: XamUserGetUserFlagsFromXUID
- Implemented: XamUserIsOnlineEnabled
- Implemented: XamUserGetMembershipTier
- Implemented: XamUserGetMembershipTierFromXUID
- Implemented: XamUserGetUserTenure
- Partially Implemented: XamUserGetSubscriptionType
2025-05-29 09:00:14 +02:00

226 lines
6.0 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2025 Xenia Canary. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_KERNEL_XAM_XDBF_SPA_INFO_H_
#define XENIA_KERNEL_XAM_XDBF_SPA_INFO_H_
#include "xenia/kernel/xam/xdbf/xdbf_io.h"
#include <map>
#include <numeric>
#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
enum class SpaSection : uint16_t {
kMetadata = 0x0001,
kImage = 0x0002,
kStringTable = 0x0003,
};
enum class TitleType : uint32_t {
kSystem = 0,
kFull = 1,
kDemo = 2,
kDownload = 3,
kUnknown = 4,
kApp = 5
};
enum class TitleFlags {
kAlwaysIncludeInProfile = 1,
kNeverIncludeInProfile = 2,
};
#pragma pack(push, 1)
struct TitleHeaderData {
xe::be<uint32_t> title_id;
xe::be<TitleType> title_type;
xe::be<uint16_t> major;
xe::be<uint16_t> minor;
xe::be<uint16_t> build;
xe::be<uint16_t> revision;
xe::be<uint32_t> flags;
xe::be<uint32_t> padding_1;
xe::be<uint32_t> padding_2;
xe::be<uint32_t> padding_3;
};
static_assert_size(TitleHeaderData, 32);
struct StatsViewTableEntry {
xe::be<uint32_t> id;
xe::be<uint32_t> flags;
xe::be<uint16_t> shared_index;
xe::be<uint16_t> string_id;
xe::be<uint32_t> unused;
};
static_assert_size(StatsViewTableEntry, 0x10);
struct ViewFieldEntry {
xe::be<uint32_t> size;
xe::be<uint32_t> property_id;
xe::be<uint32_t> flags;
xe::be<uint16_t> attribute_id;
xe::be<uint16_t> string_id;
xe::be<uint16_t> aggregation_type;
xe::be<uint8_t> ordinal;
xe::be<uint8_t> field_type;
xe::be<uint32_t> format_type;
xe::be<uint32_t> unused_1;
xe::be<uint32_t> unused_2;
};
static_assert_size(ViewFieldEntry, 0x20);
struct SharedViewMetaTableEntry {
xe::be<uint16_t> column_count;
xe::be<uint16_t> row_count;
xe::be<uint32_t> unused_1;
xe::be<uint32_t> unused_2;
};
static_assert_size(SharedViewMetaTableEntry, 0xC);
struct PropertyBag {
std::vector<xe::be<uint32_t>> contexts;
std::vector<xe::be<uint32_t>> properties;
};
struct SharedView {
std::vector<ViewFieldEntry> column_entries;
std::vector<ViewFieldEntry> row_entries;
PropertyBag property_bag;
};
struct ViewTable {
StatsViewTableEntry view_entry;
SharedView shared_view;
};
struct AchievementTableEntry {
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(AchievementTableEntry, 0x24);
#pragma pack(pop)
class SpaInfo : public XdbfFile {
public:
SpaInfo(const std::span<uint8_t> buffer);
void Load();
const uint8_t* ReadXLast(uint32_t& compressed_size,
uint32_t& decompressed_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.
std::span<const uint8_t> title_icon() const;
std::span<const uint8_t> GetIcon(uint64_t id) const;
// The game's default language.
XLanguage default_language() const;
bool is_system_app() const;
bool is_demo() const;
bool include_in_profile() const;
uint32_t title_id() const;
// The game's title in its default language.
std::string title_name() const;
std::string title_name(XLanguage language) const;
uint32_t achievement_count() const {
return static_cast<uint32_t>(achievements_.size());
}
const AchievementTableEntry* GetAchievement(uint32_t id);
std::vector<const AchievementTableEntry*> GetAchievements() const {
return achievements_;
}
std::vector<const XdbfContextTableEntry*> GetContexts() const {
return contexts_;
}
std::vector<const XdbfPropertyTableEntry*> GetProperties() const {
return properties_;
}
const XdbfContextTableEntry* GetContext(uint32_t id);
const XdbfPropertyTableEntry* GetProperty(uint32_t id);
uint32_t total_gamerscore() const {
return std::accumulate(achievements_.cbegin(), achievements_.cend(), 0,
[](uint32_t sum, const auto& entry) {
return sum + entry->gamerscore;
});
}
friend bool operator<(const SpaInfo& first, const SpaInfo& second);
friend bool operator<=(const SpaInfo& first, const SpaInfo& second);
friend bool operator==(const SpaInfo& first, const SpaInfo& second);
std::string GetStringTableEntry(XLanguage language, uint16_t string_id) const;
private:
// Base info. There should be comparator between different SpaInfos and entry
// with newer data should replace old one. Such situation can happen when game
// adds achievements and so on with DLC.
TitleHeaderData title_header_;
// SPA is Read-Only so it's reasonable to make it readonly.
std::vector<const AchievementTableEntry*> achievements_;
std::vector<const XdbfContextTableEntry*> contexts_;
std::vector<const XdbfPropertyTableEntry*> properties_;
typedef std::map<uint16_t, std::string> XdbfLanguageStrings;
std::map<XLanguage, XdbfLanguageStrings> language_strings_;
void LoadTitleInformation();
void LoadAchievements();
void LoadLanguageData();
void LoadContexts();
void LoadProperties();
template <typename T>
static T GetSpaEntry(std::vector<T>& container, uint32_t id);
};
} // namespace xam
} // namespace kernel
} // namespace xe
#endif // XENIA_KERNEL_XAM_XDBF_SPA_INFO_H_