diff --git a/src/xenia/emulator.cc b/src/xenia/emulator.cc index 392569319..5125d9d72 100644 --- a/src/xenia/emulator.cc +++ b/src/xenia/emulator.cc @@ -1525,14 +1525,18 @@ X_STATUS Emulator::CompleteLaunch(const std::filesystem::path& path, // Show achievments data tabulate::Table table; table.format().multi_byte_characters(true); - table.add_row({"ID", "Title", "Description", "Gamerscore"}); + table.add_row({"ID", "Title", "Description", "Type", "Gamerscore"}); const std::vector achievement_list = game_info_database_->GetAchievements(); for (const kernel::util::GameInfoDatabase::Achievement& entry : achievement_list) { + const std::string type = GetAchievementTypeName( + kernel::xam::GetAchievementType(entry.flags)); + table.add_row({fmt::format("{}", entry.id), entry.label, - entry.description, fmt::format("{}", entry.gamerscore)}); + entry.description, type, + fmt::format("{}", entry.gamerscore)}); } XELOGI("-------------------- ACHIEVEMENTS --------------------\n{}", table.str()); diff --git a/src/xenia/kernel/xam/xdbf/gpd_info.h b/src/xenia/kernel/xam/xdbf/gpd_info.h index 44113654a..2d23ff6c3 100644 --- a/src/xenia/kernel/xam/xdbf/gpd_info.h +++ b/src/xenia/kernel/xam/xdbf/gpd_info.h @@ -34,6 +34,16 @@ enum class GpdSection : uint16_t { kProtectedAchievement = 0x6, // GFWL only }; +enum class AchievementTypeFlags : uint32_t { + kCompletion = 0x1, + kLeveling = 0x2, + kUnlock = 0x3, + kEvent = 0x4, + kTournament = 0x5, + kCheckpoint = 0x6, + kOther = 0x7, +}; + enum class AchievementFlags : uint32_t { kTypeMask = 0x7, kShowUnachieved = 0x8, @@ -105,6 +115,39 @@ struct X_XDBF_GPD_SETTING_HEADER { static_assert_size(X_XDBF_GPD_SETTING_HEADER, 0x18); #pragma pack(pop) +inline AchievementTypeFlags constexpr GetAchievementType(const uint32_t flags) { + return static_cast( + flags & static_cast(AchievementFlags::kTypeMask)); +} + +inline std::string constexpr GetAchievementTypeName( + const AchievementTypeFlags type) { + switch (type) { + case AchievementTypeFlags::kCompletion: + return "Completion"; + break; + case AchievementTypeFlags::kLeveling: + return "Leveling"; + break; + case AchievementTypeFlags::kUnlock: + return "Unlock"; + break; + case AchievementTypeFlags::kEvent: + return "Event"; + break; + case AchievementTypeFlags::kTournament: + return "Tournament"; + break; + case AchievementTypeFlags::kCheckpoint: + return "Checkpoint"; + break; + case AchievementTypeFlags::kOther: + default: + return "Other"; + break; + } +} + class GpdInfo : public XdbfFile { public: GpdInfo();