[XAM] Added option to remove titles with 0 achievements unlocked

This commit is contained in:
Gliniak 2025-08-01 22:15:08 +02:00 committed by Radosław Gliński
parent 4e8e789876
commit 70364e73ae
6 changed files with 50 additions and 13 deletions

View file

@ -112,18 +112,6 @@ void TitleListUI::DrawTitleEntry(ImGuiIO& io, TitleInfo& entry) {
if (ImGui::BeginPopupContextItem(
fmt::format("Title Menu {:08X}", entry.id).c_str())) {
selected_title_ = entry.id;
if (ImGui::MenuItem("Refresh title stats", nullptr, nullptr, true)) {
kernel_state()->xam_state()->user_tracker()->RefreshTitleSummary(
profile_->xuid(), entry.id);
const auto title_info =
kernel_state()->xam_state()->user_tracker()->GetUserTitleInfo(
profile_->xuid(), entry.id);
if (title_info) {
entry = title_info.value();
}
}
const auto savefile_path = profile_manager_->GetProfileContentPath(
profile_->xuid(), entry.id, XContentType::kSavedGame);
@ -150,6 +138,29 @@ void TitleListUI::DrawTitleEntry(ImGuiIO& io, TitleInfo& entry) {
path_open.detach();
}
ImGui::Separator();
const auto title_info =
kernel_state()->xam_state()->user_tracker()->GetUserTitleInfo(
profile_->xuid(), entry.id);
if (ImGui::MenuItem("Refresh title stats", nullptr, nullptr, true)) {
kernel_state()->xam_state()->user_tracker()->RefreshTitleSummary(
profile_->xuid(), entry.id);
if (title_info) {
entry = title_info.value();
}
}
if (title_info) {
if (ImGui::MenuItem("Delete title", nullptr, nullptr,
!title_info->unlocked_achievements_count)) {
kernel_state()->xam_state()->user_tracker()->RemoveTitleFromPlayedList(
profile_->xuid(), entry.id);
}
}
ImGui::EndPopup();
}
}

View file

@ -185,6 +185,19 @@ void UserTracker::AddTitleToPlayedList(uint64_t xuid) {
UpdateProfileGpd();
}
void UserTracker::RemoveTitleFromPlayedList(uint64_t xuid, uint32_t title_id) {
auto user = kernel_state()->xam_state()->GetUserProfile(xuid);
if (!user) {
return;
}
if (user->dashboard_gpd_.RemoveTitle(title_id)) {
UpdateSettingValue(xuid, kDashboardID,
UserSettingId::XPROFILE_GAMERCARD_TITLES_PLAYED, -1);
FlushUserData(xuid);
}
}
// Privates
bool UserTracker::IsUserTracked(uint64_t xuid) const {
return tracked_xuids_.find(xuid) != tracked_xuids_.cend();

View file

@ -84,6 +84,7 @@ class UserTracker {
// Titles
void AddTitleToPlayedList();
void RemoveTitleFromPlayedList(uint64_t xuid, uint32_t title_id);
std::vector<TitleInfo> GetPlayedTitles(uint64_t xuid) const;
std::optional<TitleInfo> GetUserTitleInfo(uint64_t xuid,
uint32_t title_id) const;

View file

@ -135,6 +135,7 @@ class GpdInfo : public XdbfFile {
const GpdSection section);
void UpsertEntry(Entry* entry);
void DeleteEntry(const Entry* entry);
uint32_t FindFreeLocation(const uint32_t entry_size);
@ -144,7 +145,6 @@ class GpdInfo : public XdbfFile {
uint32_t title_id_ = 0;
void InsertEntry(Entry* entry);
void DeleteEntry(const Entry* entry);
std::vector<const Entry*> GetSortedEntries() const;

View file

@ -88,6 +88,17 @@ void GpdInfoProfile::AddNewTitle(const SpaInfo* title_data) {
UpsertEntry(&entry);
}
bool GpdInfoProfile::RemoveTitle(const uint32_t title_id) {
const Entry* entry =
GetEntry(static_cast<uint16_t>(GpdSection::kTitle), title_id);
if (!entry) {
return false;
}
DeleteEntry(entry);
return true;
}
X_XDBF_GPD_TITLE_PLAYED GpdInfoProfile::FillTitlePlayedData(
const SpaInfo* title_data) const {
X_XDBF_GPD_TITLE_PLAYED title_gpd_data = {};

View file

@ -32,6 +32,7 @@ class GpdInfoProfile : public GpdInfo {
~GpdInfoProfile() = default;
void AddNewTitle(const SpaInfo* title_data);
bool RemoveTitle(const uint32_t title_id);
void UpdateTitleInfo(const uint32_t title_id,
X_XDBF_GPD_TITLE_PLAYED* title_data);