Qt: Add RetroAchievements to Setup Wizard

Signed-off-by: SternXD <stern@sidestore.io>
This commit is contained in:
SternXD
2026-04-11 06:19:01 -04:00
committed by lightningterror
parent 6d0fbed646
commit 285dc0070f
3 changed files with 358 additions and 4 deletions
+94 -2
View File
@@ -1,17 +1,18 @@
// SPDX-FileCopyrightText: 2002-2026 PCSX2 Dev Team
// SPDX-License-Identifier: GPL-3.0+
#include "pcsx2/Achievements.h"
#include "pcsx2/SIO/Pad/Pad.h"
#include "QtHost.h"
#include "QtUtils.h"
#include "SettingWidgetBinder.h"
#include "Settings/AchievementLoginDialog.h"
#include "Settings/BIOSSettingsWidget.h"
#include "Settings/ControllerSettingWidgetBinder.h"
#include "Settings/InterfaceSettingsWidget.h"
#include "SetupWizardDialog.h"
#include <QtCore/QLocale>
#include <QtWidgets/QMessageBox>
#include "common/StringUtil.h"
SetupWizardDialog::SetupWizardDialog()
{
@@ -109,6 +110,10 @@ void SetupWizardDialog::pageChangedTo(int page)
resizeDirectoryListColumns();
break;
case Page_RetroAchievements:
refreshRetroAchievementsLoginState();
break;
default:
break;
}
@@ -160,6 +165,7 @@ void SetupWizardDialog::setupUi()
m_page_labels[Page_BIOS] = m_ui.labelBIOS;
m_page_labels[Page_GameList] = m_ui.labelGameList;
m_page_labels[Page_Controller] = m_ui.labelController;
m_page_labels[Page_RetroAchievements] = m_ui.labelRetroAchievements;
m_page_labels[Page_Complete] = m_ui.labelComplete;
connect(m_ui.back, &QPushButton::clicked, this, &SetupWizardDialog::previousPage);
@@ -170,6 +176,7 @@ void SetupWizardDialog::setupUi()
setupBIOSPage();
setupGameListPage();
setupControllerPage();
setupRetroAchievementsPage();
}
void SetupWizardDialog::setupLanguagePage()
@@ -407,6 +414,91 @@ void SetupWizardDialog::setupControllerPage()
g_emu_thread->enumerateInputDevices();
}
void SetupWizardDialog::setupRetroAchievementsPage()
{
const QString base_path(QtHost::GetResourcesBasePath());
QtUtils::SetScalableIcon(m_ui.raLogo, QIcon(QStringLiteral("%1/icons/ra-icon.svg").arg(base_path)), QSize(56, 56));
if (Achievements::IsUsingRAIntegration())
{
m_ui.raIntegrationLabel->setVisible(true);
m_ui.raContentWidget->setVisible(false);
return;
}
SettingWidgetBinder::BindWidgetToBoolSetting(
nullptr, m_ui.raEnableAchievements, "Achievements", "Enabled", false);
SettingWidgetBinder::BindWidgetToBoolSetting(
nullptr, m_ui.raHardcoreMode, "Achievements", "ChallengeMode", false);
connect(m_ui.raLoginButton, &QPushButton::clicked, this, &SetupWizardDialog::onRetroAchievementsLoginLogoutPressed);
connect(m_ui.raViewProfileButton, &QPushButton::clicked, this, &SetupWizardDialog::onRetroAchievementsViewProfilePressed);
refreshRetroAchievementsLoginState();
}
void SetupWizardDialog::refreshRetroAchievementsLoginState()
{
const std::string username(Host::GetBaseStringSettingValue("Achievements", "Username"));
const bool logged_in = !username.empty();
if (logged_in)
{
const u64 login_unix_timestamp =
StringUtil::FromChars<u64>(Host::GetBaseStringSettingValue("Achievements", "LoginTimestamp", "0")).value_or(0);
const QDateTime login_timestamp(QDateTime::fromSecsSinceEpoch(static_cast<qint64>(login_unix_timestamp)));
m_ui.raLoginStatus->setText(tr("Username: %1\nLogin token generated on %2.")
.arg(QString::fromStdString(username))
.arg(login_timestamp.toString(Qt::TextDate)));
m_ui.raLoginButton->setText(tr("Logout"));
}
else
{
m_ui.raLoginStatus->setText(tr("Not Logged In."));
m_ui.raLoginButton->setText(tr("Login..."));
}
m_ui.raViewProfileButton->setEnabled(logged_in);
}
void SetupWizardDialog::onRetroAchievementsLoginLogoutPressed()
{
if (!Host::GetBaseStringSettingValue("Achievements", "Username").empty())
{
Host::RunOnCPUThread([]() { Achievements::Logout(); }, true);
refreshRetroAchievementsLoginState();
return;
}
AchievementLoginDialog login(this, Achievements::LoginRequestReason::UserInitiated);
if (login.exec() != 0)
return;
refreshRetroAchievementsLoginState();
// Login can enable achievements, keep the checkbox state in sync.
if (!m_ui.raEnableAchievements->isChecked() &&
Host::GetBaseBoolSettingValue("Achievements", "Enabled", false))
{
QSignalBlocker sb(m_ui.raEnableAchievements);
m_ui.raEnableAchievements->setChecked(true);
}
if (!m_ui.raHardcoreMode->isChecked() &&
Host::GetBaseBoolSettingValue("Achievements", "ChallengeMode", false))
{
QSignalBlocker sb(m_ui.raHardcoreMode);
m_ui.raHardcoreMode->setChecked(true);
}
}
void SetupWizardDialog::onRetroAchievementsViewProfilePressed()
{
const std::string username(Host::GetBaseStringSettingValue("Achievements", "Username"));
if (username.empty())
return;
const QByteArray encoded_username(QUrl::toPercentEncoding(QString::fromStdString(username)));
QtUtils::OpenURL(this, QUrl(QStringLiteral("https://retroachievements.org/user/%1").arg(QString::fromUtf8(encoded_username))));
}
void SetupWizardDialog::openAutomaticMappingMenu(u32 port, QLabel* update_label)
{
QMenu menu(this);
+5
View File
@@ -42,6 +42,8 @@ private Q_SLOTS:
void onInputDevicesEnumerated(const QList<QPair<QString, QString>>& devices);
void onInputDeviceConnected(const QString& identifier, const QString& device_name);
void onInputDeviceDisconnected(const QString& identifier);
void onRetroAchievementsLoginLogoutPressed();
void onRetroAchievementsViewProfilePressed();
protected:
void resizeEvent(QResizeEvent* event);
@@ -53,6 +55,7 @@ private:
Page_BIOS,
Page_GameList,
Page_Controller,
Page_RetroAchievements,
Page_Complete,
Page_Count,
};
@@ -62,6 +65,8 @@ private:
void setupBIOSPage();
void setupGameListPage();
void setupControllerPage();
void setupRetroAchievementsPage();
void refreshRetroAchievementsLoginState();
void pageChangedTo(int page);
void updatePageLabels(int prev_page);
+259 -2
View File
@@ -91,6 +91,13 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelRetroAchievements">
<property name="text">
<string>RetroAchievements</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelComplete">
<property name="text">
@@ -118,12 +125,12 @@
<item row="0" column="1">
<widget class="QStackedWidget" name="pages">
<property name="currentIndex">
<number>3</number>
<number>4</number>
</property>
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>10</number>
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
@@ -628,6 +635,256 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="pageRetroAchievements">
<layout class="QVBoxLayout" name="verticalLayout_8">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_12">
<item>
<widget class="QLabel" name="raLogo">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>56</width>
<height>56</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>56</width>
<height>56</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="raSectionLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<pointsize>14</pointsize>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>RetroAchievements</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_11">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="raIntroLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;justify&quot;&gt;PCSX2 supports RetroAchievements, a service that adds achievements, leaderboards, and extra challenges to classic games.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;Sign in below to link your account and start earning achievements in supported titles, or create a free account at &lt;a href=&quot;https://retroachievements.org/createaccount.php&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#27bf73;&quot;&gt;retroachievements.org/createaccount.php&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p align=&quot;justify&quot;&gt;Using RetroAchievements is completely optional and not required to use PCSX2.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::TextFormat::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>2</number>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="raIntegrationLabel">
<property name="visible">
<bool>false</bool>
</property>
<property name="text">
<string>RAIntegration is being used, built-in RetroAchievements support is disabled.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="raContentWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_9">
<property name="spacing">
<number>4</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGroupBox" name="raSettingsBox">
<property name="title">
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QCheckBox" name="raEnableAchievements">
<property name="text">
<string>Enable Achievements</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="raHardcoreMode">
<property name="text">
<string>Enable Hardcore Mode</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_10">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="raAccountBox">
<property name="title">
<string>Account</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_7" stretch="1,0,0,0">
<item>
<widget class="QLabel" name="raLoginStatus">
<property name="text">
<string>Not Logged In.</string>
</property>
<property name="alignment">
<set>Qt::AlignmentFlag::AlignLeading|Qt::AlignmentFlag::AlignLeft|Qt::AlignmentFlag::AlignTop</set>
</property>
<property name="textInteractionFlags">
<set>Qt::TextInteractionFlag::TextBrowserInteraction</set>
</property>
<property name="buddy">
<cstring>raViewProfileButton</cstring>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_9">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="raViewProfileButton">
<property name="text">
<string>View Profile...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="raLoginButton">
<property name="text">
<string>Login...</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="raFooterLabel">
<property name="text">
<string>You can customize additional RetroAchievements options later in Settings &gt; Achievements.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_5">
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="leftMargin">