2023-06-02 19:25:01 -06:00
|
|
|
// Copyright 2023 Dolphin Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
#ifdef USE_RETRO_ACHIEVEMENTS
|
|
|
|
#include "DolphinQt/Achievements/AchievementProgressWidget.h"
|
|
|
|
|
|
|
|
#include <QCheckBox>
|
|
|
|
#include <QGroupBox>
|
|
|
|
#include <QLabel>
|
|
|
|
#include <QLineEdit>
|
|
|
|
#include <QProgressBar>
|
|
|
|
#include <QPushButton>
|
|
|
|
#include <QString>
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
|
|
|
|
#include <fmt/format.h>
|
|
|
|
|
|
|
|
#include <rcheevos/include/rc_api_runtime.h>
|
|
|
|
#include <rcheevos/include/rc_api_user.h>
|
|
|
|
#include <rcheevos/include/rc_runtime.h>
|
|
|
|
|
|
|
|
#include "Core/AchievementManager.h"
|
|
|
|
#include "Core/Config/AchievementSettings.h"
|
|
|
|
#include "Core/Config/MainSettings.h"
|
|
|
|
#include "Core/Core.h"
|
|
|
|
|
|
|
|
#include "DolphinQt/Config/ControllerInterface/ControllerInterfaceWindow.h"
|
2023-10-15 10:36:11 -06:00
|
|
|
#include "DolphinQt/QtUtils/ClearLayoutRecursively.h"
|
2023-06-02 19:25:01 -06:00
|
|
|
#include "DolphinQt/QtUtils/ModalMessageBox.h"
|
|
|
|
#include "DolphinQt/QtUtils/NonDefaultQPushButton.h"
|
|
|
|
#include "DolphinQt/QtUtils/SignalBlocking.h"
|
|
|
|
#include "DolphinQt/Settings.h"
|
|
|
|
|
2023-07-04 14:17:10 -06:00
|
|
|
static constexpr bool hardcore_mode_enabled = false;
|
|
|
|
|
2023-06-02 19:25:01 -06:00
|
|
|
AchievementProgressWidget::AchievementProgressWidget(QWidget* parent) : QWidget(parent)
|
|
|
|
{
|
|
|
|
m_common_box = new QGroupBox();
|
|
|
|
m_common_layout = new QVBoxLayout();
|
|
|
|
|
2023-07-04 14:50:54 -06:00
|
|
|
{
|
|
|
|
std::lock_guard lg{*AchievementManager::GetInstance()->GetLock()};
|
|
|
|
UpdateData();
|
|
|
|
}
|
2023-06-02 19:25:01 -06:00
|
|
|
|
|
|
|
m_common_box->setLayout(m_common_layout);
|
|
|
|
|
|
|
|
auto* layout = new QVBoxLayout;
|
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
layout->setAlignment(Qt::AlignTop);
|
|
|
|
layout->addWidget(m_common_box);
|
|
|
|
setLayout(layout);
|
|
|
|
}
|
|
|
|
|
|
|
|
QGroupBox*
|
|
|
|
AchievementProgressWidget::CreateAchievementBox(const rc_api_achievement_definition_t* achievement)
|
|
|
|
{
|
2023-09-26 05:21:22 -06:00
|
|
|
if (!AchievementManager::GetInstance()->IsGameLoaded())
|
|
|
|
return new QGroupBox();
|
2023-07-04 14:50:54 -06:00
|
|
|
QLabel* a_badge = new QLabel();
|
|
|
|
const auto unlock_status = AchievementManager::GetInstance()->GetUnlockStatus(achievement->id);
|
|
|
|
const AchievementManager::BadgeStatus* badge = &unlock_status.locked_badge;
|
2023-07-04 14:17:10 -06:00
|
|
|
std::string_view color = AchievementManager::GRAY;
|
2023-07-04 14:50:54 -06:00
|
|
|
if (unlock_status.remote_unlock_status == AchievementManager::UnlockStatus::UnlockType::HARDCORE)
|
|
|
|
{
|
|
|
|
badge = &unlock_status.unlocked_badge;
|
2023-07-04 14:17:10 -06:00
|
|
|
color = AchievementManager::GOLD;
|
2023-07-04 14:50:54 -06:00
|
|
|
}
|
|
|
|
else if (hardcore_mode_enabled && unlock_status.session_unlock_count > 1)
|
|
|
|
{
|
|
|
|
badge = &unlock_status.unlocked_badge;
|
2023-07-04 14:17:10 -06:00
|
|
|
color = AchievementManager::GOLD;
|
2023-07-04 14:50:54 -06:00
|
|
|
}
|
|
|
|
else if (unlock_status.remote_unlock_status ==
|
|
|
|
AchievementManager::UnlockStatus::UnlockType::SOFTCORE)
|
|
|
|
{
|
|
|
|
badge = &unlock_status.unlocked_badge;
|
2023-07-04 14:17:10 -06:00
|
|
|
color = AchievementManager::BLUE;
|
2023-07-04 14:50:54 -06:00
|
|
|
}
|
|
|
|
else if (unlock_status.session_unlock_count > 1)
|
|
|
|
{
|
|
|
|
badge = &unlock_status.unlocked_badge;
|
2023-07-04 14:17:10 -06:00
|
|
|
color = AchievementManager::BLUE;
|
2023-07-04 14:50:54 -06:00
|
|
|
}
|
|
|
|
if (Config::Get(Config::RA_BADGES_ENABLED) && badge->name != "")
|
|
|
|
{
|
|
|
|
QImage i_badge{};
|
|
|
|
if (i_badge.loadFromData(&badge->badge.front(), (int)badge->badge.size()))
|
|
|
|
{
|
|
|
|
a_badge->setPixmap(QPixmap::fromImage(i_badge).scaled(64, 64, Qt::KeepAspectRatio,
|
|
|
|
Qt::SmoothTransformation));
|
|
|
|
a_badge->adjustSize();
|
2023-07-04 14:17:10 -06:00
|
|
|
a_badge->setStyleSheet(
|
|
|
|
QStringLiteral("border: 4px solid %1").arg(QString::fromStdString(std::string(color))));
|
2023-07-04 14:50:54 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-02 19:25:01 -06:00
|
|
|
QLabel* a_title = new QLabel(QString::fromUtf8(achievement->title, strlen(achievement->title)));
|
|
|
|
QLabel* a_description =
|
|
|
|
new QLabel(QString::fromUtf8(achievement->description, strlen(achievement->description)));
|
|
|
|
QLabel* a_points = new QLabel(tr("%1 points").arg(achievement->points));
|
|
|
|
QLabel* a_status = new QLabel(GetStatusString(achievement->id));
|
|
|
|
QProgressBar* a_progress_bar = new QProgressBar();
|
2023-07-04 14:50:54 -06:00
|
|
|
QSizePolicy sp_retain = a_progress_bar->sizePolicy();
|
|
|
|
sp_retain.setRetainSizeWhenHidden(true);
|
|
|
|
a_progress_bar->setSizePolicy(sp_retain);
|
2023-06-02 19:25:01 -06:00
|
|
|
unsigned int value = 0;
|
|
|
|
unsigned int target = 0;
|
2023-09-30 22:59:43 -06:00
|
|
|
if (AchievementManager::GetInstance()->GetAchievementProgress(achievement->id, &value, &target) ==
|
|
|
|
AchievementManager::ResponseType::SUCCESS &&
|
|
|
|
target > 0)
|
2023-06-02 19:25:01 -06:00
|
|
|
{
|
|
|
|
a_progress_bar->setRange(0, target);
|
|
|
|
a_progress_bar->setValue(value);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
a_progress_bar->setVisible(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
QVBoxLayout* a_col_right = new QVBoxLayout();
|
|
|
|
a_col_right->addWidget(a_title);
|
|
|
|
a_col_right->addWidget(a_description);
|
|
|
|
a_col_right->addWidget(a_points);
|
|
|
|
a_col_right->addWidget(a_status);
|
|
|
|
a_col_right->addWidget(a_progress_bar);
|
|
|
|
QHBoxLayout* a_total = new QHBoxLayout();
|
2023-07-04 14:50:54 -06:00
|
|
|
a_total->addWidget(a_badge);
|
2023-06-02 19:25:01 -06:00
|
|
|
a_total->addLayout(a_col_right);
|
|
|
|
QGroupBox* a_group_box = new QGroupBox();
|
|
|
|
a_group_box->setLayout(a_total);
|
|
|
|
return a_group_box;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AchievementProgressWidget::UpdateData()
|
|
|
|
{
|
2023-10-15 10:36:11 -06:00
|
|
|
ClearLayoutRecursively(m_common_layout);
|
2023-06-02 19:25:01 -06:00
|
|
|
|
2023-09-26 05:21:22 -06:00
|
|
|
if (!AchievementManager::GetInstance()->IsGameLoaded())
|
|
|
|
return;
|
2023-06-02 19:25:01 -06:00
|
|
|
const auto* game_data = AchievementManager::GetInstance()->GetGameData();
|
|
|
|
for (u32 ix = 0; ix < game_data->num_achievements; ix++)
|
|
|
|
{
|
|
|
|
m_common_layout->addWidget(CreateAchievementBox(game_data->achievements + ix));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QString AchievementProgressWidget::GetStatusString(u32 achievement_id) const
|
|
|
|
{
|
|
|
|
const auto unlock_status = AchievementManager::GetInstance()->GetUnlockStatus(achievement_id);
|
|
|
|
if (unlock_status.session_unlock_count > 0)
|
|
|
|
{
|
|
|
|
if (Config::Get(Config::RA_ENCORE_ENABLED))
|
|
|
|
{
|
|
|
|
return tr("Unlocked %1 times this session").arg(unlock_status.session_unlock_count);
|
|
|
|
}
|
|
|
|
return tr("Unlocked this session");
|
|
|
|
}
|
|
|
|
switch (unlock_status.remote_unlock_status)
|
|
|
|
{
|
|
|
|
case AchievementManager::UnlockStatus::UnlockType::LOCKED:
|
|
|
|
return tr("Locked");
|
|
|
|
case AchievementManager::UnlockStatus::UnlockType::SOFTCORE:
|
|
|
|
return tr("Unlocked (Casual)");
|
|
|
|
case AchievementManager::UnlockStatus::UnlockType::HARDCORE:
|
|
|
|
return tr("Unlocked");
|
|
|
|
}
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // USE_RETRO_ACHIEVEMENTS
|