Skip to content

Commit

Permalink
[UI] Added played game list and achievements UI.
Browse files Browse the repository at this point in the history
This will be functional after GPD & SPA implementation, for now shows info about currently booted title
  • Loading branch information
Gliniak committed Dec 14, 2024
1 parent d94940f commit b06e93f
Show file tree
Hide file tree
Showing 6 changed files with 902 additions and 38 deletions.
41 changes: 35 additions & 6 deletions src/xenia/kernel/xam/achievement_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
DEFINE_bool(show_achievement_notification, false,
"Show achievement notification on screen.", "UI");

DEFINE_string(default_achievement_backend, "",
"Defines which achievement backend should be used as an default. "
"Possible options: [].",
"Achievements");
DEFINE_string(
default_achievements_backend, "GPD",
"Defines which achievements backend should be used as an default. "
"Possible options: GPD.",
"Kernel");

DECLARE_int32(user_language);

Expand Down Expand Up @@ -49,8 +50,11 @@ void GpdAchievementBackend::EarnAchievement(const uint64_t xuid,
achievement->achievement_name.c_str())));

const uint64_t unlock_time = Clock::QueryHostSystemTime();
achievement->flags =
achievement->flags | static_cast<uint32_t>(AchievementFlags::kAchieved);
// We're adding achieved online flag because on console locally achieved
// entries don't have valid unlock time.
achievement->flags = achievement->flags |
static_cast<uint32_t>(AchievementFlags::kAchieved) |
static_cast<uint32_t>(AchievementFlags::kAchievedOnline);
achievement->unlock_time.high_part = static_cast<uint32_t>(unlock_time >> 32);
achievement->unlock_time.low_part = static_cast<uint32_t>(unlock_time);

Expand Down Expand Up @@ -206,6 +210,31 @@ AchievementManager::GetTitleAchievements(const uint64_t xuid,
return default_achievements_backend_->GetTitleAchievements(xuid, title_id);
}

const std::optional<TitleAchievementsProfileInfo>
AchievementManager::GetTitleAchievementsInfo(const uint64_t xuid,
const uint32_t title_id) const {
TitleAchievementsProfileInfo info = {};

const auto achievements = GetTitleAchievements(xuid, title_id);

if (!achievements) {
return std::nullopt;
}

info.achievements_count = static_cast<uint32_t>(achievements->size());

for (const auto& entry : *achievements) {
if (!entry.IsUnlocked()) {
continue;
}

info.unlocked_achievements_count++;
info.gamerscore += entry.gamerscore;
}

return info;
}

bool AchievementManager::DoesAchievementExist(
const uint32_t achievement_id) const {
const util::XdbfGameData title_xdbf = kernel_state()->title_xdbf();
Expand Down
64 changes: 39 additions & 25 deletions src/xenia/kernel/xam/achievement_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <map>
#include <string>
#include <vector>
#include <optional>

#include "xenia/kernel/util/xdbf_utils.h"
#include "xenia/xbox.h"
Expand All @@ -21,6 +22,34 @@ namespace xe {
namespace kernel {
namespace xam {

enum class AchievementType : uint32_t {
kCompletion = 1,
kLeveling = 2,
kUnlock = 3,
kEvent = 4,
kTournament = 5,
kCheckpoint = 6,
kOther = 7,
};

enum class AchievementPlatform : uint32_t {
kX360 = 0x100000,
kPC = 0x200000,
kMobile = 0x300000,
kWebGames = 0x400000,
};

enum class AchievementFlags : uint32_t {
kTypeMask = 0x7,
kShowUnachieved = 0x8,
kAchievedOnline = 0x10000,
kAchieved = 0x20000,
kNotAchievable = 0x40000,
kWasNotAchievable = 0x80000,
kPlatformMask = 0x700000,
kColorizable = 0x1000000, // avatar awards only?
};

struct X_ACHIEVEMENT_UNLOCK_TIME {
xe::be<uint32_t> high_part;
xe::be<uint32_t> low_part;
Expand Down Expand Up @@ -81,34 +110,17 @@ struct AchievementGpdStructure {
std::u16string achievement_name;
std::u16string unlocked_description;
std::u16string locked_description;
};

enum class AchievementType : uint32_t {
kCompletion = 1,
kLeveling = 2,
kUnlock = 3,
kEvent = 4,
kTournament = 5,
kCheckpoint = 6,
kOther = 7,
};

enum class AchievementPlatform : uint32_t {
kX360 = 0x100000,
kPC = 0x200000,
kMobile = 0x300000,
kWebGames = 0x400000,
bool IsUnlocked() const {
return (flags & static_cast<uint32_t>(AchievementFlags::kAchieved)) ||
flags & static_cast<uint32_t>(AchievementFlags::kAchievedOnline);
}
};

enum class AchievementFlags : uint32_t {
kTypeMask = 0x7,
kShowUnachieved = 0x8,
kAchievedOnline = 0x10000,
kAchieved = 0x20000,
kNotAchievable = 0x40000,
kWasNotAchievable = 0x80000,
kPlatformMask = 0x700000,
kColorizable = 0x1000000, // avatar awards only?
struct TitleAchievementsProfileInfo {
uint32_t achievements_count;
uint32_t unlocked_achievements_count;
uint32_t gamerscore;
};

class AchievementBackendInterface {
Expand Down Expand Up @@ -183,6 +195,8 @@ class AchievementManager {
const uint32_t achievement_id) const;
const std::vector<AchievementGpdStructure>* GetTitleAchievements(
const uint64_t xuid, const uint32_t title_id) const;
const std::optional<TitleAchievementsProfileInfo> GetTitleAchievementsInfo(
const uint64_t xuid, const uint32_t title_id) const;

private:
bool DoesAchievementExist(const uint32_t achievement_id) const;
Expand Down
Loading

0 comments on commit b06e93f

Please sign in to comment.