mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-19 00:45:46 -04:00
Cheevos: Implement hardcore mode
This commit is contained in:
@ -66,7 +66,7 @@
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Please enter user name and password for retroachievements.org below. Your password will not be saved in DuckStation, instead an access token will be generated and used instead.</string>
|
||||
<string>Please enter user name and password for retroachievements.org below. Your password will not be saved in DuckStation, an access token will be generated and used instead.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "common/string_util.h"
|
||||
#include "core/system.h"
|
||||
#include "frontend-common/cheevos.h"
|
||||
#include "mainwindow.h"
|
||||
#include "qtutils.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
@ -15,11 +16,12 @@ AchievementSettingsWidget::AchievementSettingsWidget(QtHostInterface* host_inter
|
||||
{
|
||||
m_ui.setupUi(this);
|
||||
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.enable, "Cheevos", "Enabled", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.richPresence, "Cheevos", "RichPresence", true);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.testMode, "Cheevos", "TestMode", false);
|
||||
SettingWidgetBinder::BindWidgetToBoolSetting(m_host_interface, m_ui.useFirstDiscFromPlaylist, "Cheevos",
|
||||
"UseFirstDiscFromPlaylist", true);
|
||||
m_ui.enable->setChecked(m_host_interface->GetBoolSettingValue("Cheevos", "Enabled", false));
|
||||
m_ui.challengeMode->setChecked(m_host_interface->GetBoolSettingValue("Cheevos", "ChallengeMode", false));
|
||||
|
||||
dialog->registerWidgetHelp(m_ui.enable, tr("Enable Achievements"), tr("Unchecked"),
|
||||
tr("When enabled and logged in, DuckStation will scan for achievements on startup."));
|
||||
@ -33,10 +35,14 @@ AchievementSettingsWidget::AchievementSettingsWidget(QtHostInterface* host_inter
|
||||
m_ui.useFirstDiscFromPlaylist, tr("Use First Disc From Playlist"), tr("Unchecked"),
|
||||
tr(
|
||||
"When enabled, the first disc in a playlist will be used for achievements, regardless of which disc is active."));
|
||||
dialog->registerWidgetHelp(m_ui.challengeMode, tr("Enable Hardcore Mode"), tr("Unchecked"),
|
||||
tr("\"Challenge\" mode for achievements. Disables save state, cheats, and slowdown "
|
||||
"functions, but you receive double the achievement points."));
|
||||
|
||||
connect(m_ui.enable, &QCheckBox::stateChanged, this, &AchievementSettingsWidget::updateEnableState);
|
||||
connect(m_ui.enable, &QCheckBox::toggled, this, &AchievementSettingsWidget::onEnableToggled);
|
||||
connect(m_ui.loginButton, &QPushButton::clicked, this, &AchievementSettingsWidget::onLoginLogoutPressed);
|
||||
connect(m_ui.viewProfile, &QPushButton::clicked, this, &AchievementSettingsWidget::onViewProfilePressed);
|
||||
connect(m_ui.challengeMode, &QCheckBox::toggled, this, &AchievementSettingsWidget::onChallengeModeToggled);
|
||||
connect(host_interface, &QtHostInterface::achievementsLoaded, this, &AchievementSettingsWidget::onAchievementsLoaded);
|
||||
|
||||
updateEnableState();
|
||||
@ -51,9 +57,11 @@ AchievementSettingsWidget::~AchievementSettingsWidget() = default;
|
||||
void AchievementSettingsWidget::updateEnableState()
|
||||
{
|
||||
const bool enabled = m_host_interface->GetBoolSettingValue("Cheevos", "Enabled", false);
|
||||
const bool challenge_mode = m_host_interface->GetBoolSettingValue("Cheevos", "ChallengeMode", false);
|
||||
m_ui.testMode->setEnabled(enabled);
|
||||
m_ui.useFirstDiscFromPlaylist->setEnabled(enabled);
|
||||
m_ui.richPresence->setEnabled(enabled);
|
||||
m_ui.challengeMode->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void AchievementSettingsWidget::updateLoginState()
|
||||
@ -98,17 +106,73 @@ void AchievementSettingsWidget::onLoginLogoutPressed()
|
||||
|
||||
void AchievementSettingsWidget::onViewProfilePressed()
|
||||
{
|
||||
if (!Cheevos::IsLoggedIn())
|
||||
const std::string username(m_host_interface->GetStringSettingValue("Cheevos", "Username"));
|
||||
if (username.empty())
|
||||
return;
|
||||
|
||||
const QByteArray encoded_username(QUrl::toPercentEncoding(QString::fromStdString(Cheevos::GetUsername())));
|
||||
const QByteArray encoded_username(QUrl::toPercentEncoding(QString::fromStdString(username)));
|
||||
QtUtils::OpenURL(
|
||||
QtUtils::GetRootWidget(this),
|
||||
QUrl(QStringLiteral("https://retroachievements.org/user/%1").arg(QString::fromUtf8(encoded_username))));
|
||||
}
|
||||
|
||||
void AchievementSettingsWidget::onEnableToggled(bool checked)
|
||||
{
|
||||
const bool challenge_mode = m_host_interface->GetBoolSettingValue("Cheevos", "ChallengeMode", false);
|
||||
const bool challenge_mode_active = checked && challenge_mode;
|
||||
if (challenge_mode_active && !confirmChallengeModeEnable())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.challengeMode);
|
||||
m_ui.challengeMode->setChecked(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_host_interface->SetBoolSettingValue("Cheevos", "Enabled", checked);
|
||||
m_host_interface->applySettings(false);
|
||||
|
||||
if (challenge_mode)
|
||||
m_host_interface->getMainWindow()->onAchievementsChallengeModeToggled(challenge_mode_active);
|
||||
|
||||
updateEnableState();
|
||||
}
|
||||
|
||||
void AchievementSettingsWidget::onChallengeModeToggled(bool checked)
|
||||
{
|
||||
if (checked && !confirmChallengeModeEnable())
|
||||
{
|
||||
QSignalBlocker sb(m_ui.challengeMode);
|
||||
m_ui.challengeMode->setChecked(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_host_interface->SetBoolSettingValue("Cheevos", "ChallengeMode", checked);
|
||||
m_host_interface->applySettings(false);
|
||||
m_host_interface->getMainWindow()->onAchievementsChallengeModeToggled(checked);
|
||||
}
|
||||
|
||||
void AchievementSettingsWidget::onAchievementsLoaded(quint32 id, const QString& game_info_string, quint32 total,
|
||||
quint32 points)
|
||||
{
|
||||
m_ui.gameInfo->setText(game_info_string);
|
||||
}
|
||||
|
||||
bool AchievementSettingsWidget::confirmChallengeModeEnable()
|
||||
{
|
||||
if (!System::IsValid())
|
||||
return true;
|
||||
|
||||
QString message = tr("Enabling hardcore mode will shut down your current game.\n\n");
|
||||
|
||||
if (m_host_interface->ShouldSaveResumeState())
|
||||
{
|
||||
message +=
|
||||
tr("The current state will be saved, but you will be unable to load it until you disable hardcore mode.\n\n");
|
||||
}
|
||||
|
||||
message += tr("Do you want to continue?");
|
||||
if (QMessageBox::question(QtUtils::GetRootWidget(this), tr("Enable Hardcore Mode"), message) != QMessageBox::Yes)
|
||||
return false;
|
||||
|
||||
m_host_interface->synchronousPowerOffSystem();
|
||||
return true;
|
||||
}
|
||||
|
@ -14,13 +14,17 @@ public:
|
||||
~AchievementSettingsWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateEnableState();
|
||||
void updateLoginState();
|
||||
void onEnableToggled(bool checked);
|
||||
void onChallengeModeToggled(bool checked);
|
||||
void onLoginLogoutPressed();
|
||||
void onViewProfilePressed();
|
||||
void onAchievementsLoaded(quint32 id, const QString& game_info_string, quint32 total, quint32 points);
|
||||
|
||||
private:
|
||||
bool confirmChallengeModeEnable();
|
||||
void updateEnableState();
|
||||
void updateLoginState();
|
||||
|
||||
Ui::AchievementSettingsWidget m_ui;
|
||||
|
||||
QtHostInterface* m_host_interface;
|
||||
|
@ -60,6 +60,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="challengeMode">
|
||||
<property name="text">
|
||||
<string>Enable Hardcore Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@ -97,32 +104,6 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Account Settings</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="hardcoreMode">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Hardcore Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Enabling hardcore mode will disable cheats, save sates, and debugging features.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="minimumSize">
|
||||
|
@ -354,7 +354,7 @@ void MainWindow::updateMouseMode(bool paused)
|
||||
void MainWindow::onEmulationStarting()
|
||||
{
|
||||
m_emulation_running = true;
|
||||
updateEmulationActions(true, false);
|
||||
updateEmulationActions(true, false, m_host_interface->IsCheevosChallengeModeActive());
|
||||
|
||||
// ensure it gets updated, since the boot can take a while
|
||||
QGuiApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
@ -362,13 +362,13 @@ void MainWindow::onEmulationStarting()
|
||||
|
||||
void MainWindow::onEmulationStarted()
|
||||
{
|
||||
updateEmulationActions(false, true);
|
||||
updateEmulationActions(false, true, m_host_interface->IsCheevosChallengeModeActive());
|
||||
}
|
||||
|
||||
void MainWindow::onEmulationStopped()
|
||||
{
|
||||
m_emulation_running = false;
|
||||
updateEmulationActions(false, false);
|
||||
updateEmulationActions(false, false, m_host_interface->IsCheevosChallengeModeActive());
|
||||
switchToGameListView();
|
||||
|
||||
if (m_cheat_manager_dialog)
|
||||
@ -610,7 +610,8 @@ void MainWindow::onGameListEntryDoubleClicked(const GameListEntry* entry)
|
||||
QString path = QString::fromStdString(entry->path);
|
||||
if (!m_emulation_running)
|
||||
{
|
||||
if (!entry->code.empty() && m_host_interface->GetBoolSettingValue("Main", "SaveStateOnExit", true))
|
||||
if (!entry->code.empty() && m_host_interface->GetBoolSettingValue("Main", "SaveStateOnExit", true) &&
|
||||
!m_host_interface->IsCheevosChallengeModeActive())
|
||||
{
|
||||
m_host_interface->resumeSystemFromState(path, true);
|
||||
}
|
||||
@ -670,7 +671,7 @@ void MainWindow::onGameListContextMenuRequested(const QPoint& point, const GameL
|
||||
m_host_interface->bootSystem(std::move(boot_params));
|
||||
});
|
||||
|
||||
if (m_ui.menuDebug->menuAction()->isVisible())
|
||||
if (m_ui.menuDebug->menuAction()->isVisible() && !m_host_interface->IsCheevosChallengeModeActive())
|
||||
{
|
||||
connect(menu.addAction(tr("Boot and Debug")), &QAction::triggered, [this, entry]() {
|
||||
m_open_debugger_on_start = true;
|
||||
@ -841,27 +842,27 @@ void MainWindow::setupAdditionalUi()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateEmulationActions(bool starting, bool running)
|
||||
void MainWindow::updateEmulationActions(bool starting, bool running, bool cheevos_challenge_mode)
|
||||
{
|
||||
m_ui.actionStartDisc->setDisabled(starting || running);
|
||||
m_ui.actionStartBios->setDisabled(starting || running);
|
||||
m_ui.actionResumeLastState->setDisabled(starting || running);
|
||||
m_ui.actionResumeLastState->setDisabled(starting || running || cheevos_challenge_mode);
|
||||
|
||||
m_ui.actionPowerOff->setDisabled(starting || !running);
|
||||
m_ui.actionPowerOffWithoutSaving->setDisabled(starting || !running);
|
||||
m_ui.actionReset->setDisabled(starting || !running);
|
||||
m_ui.actionPause->setDisabled(starting || !running);
|
||||
m_ui.actionChangeDisc->setDisabled(starting || !running);
|
||||
m_ui.actionCheats->setDisabled(starting || !running);
|
||||
m_ui.actionCheats->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||
m_ui.actionScreenshot->setDisabled(starting || !running);
|
||||
m_ui.actionViewSystemDisplay->setEnabled(starting || running);
|
||||
m_ui.menuChangeDisc->setDisabled(starting || !running);
|
||||
m_ui.menuCheats->setDisabled(starting || !running);
|
||||
m_ui.actionCheatManager->setDisabled(starting || !running);
|
||||
m_ui.actionCPUDebugger->setDisabled(starting || !running);
|
||||
m_ui.actionDumpRAM->setDisabled(starting || !running);
|
||||
m_ui.actionDumpVRAM->setDisabled(starting || !running);
|
||||
m_ui.actionDumpSPURAM->setDisabled(starting || !running);
|
||||
m_ui.menuCheats->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||
m_ui.actionCheatManager->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||
m_ui.actionCPUDebugger->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||
m_ui.actionDumpRAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||
m_ui.actionDumpVRAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||
m_ui.actionDumpSPURAM->setDisabled(starting || !running || cheevos_challenge_mode);
|
||||
|
||||
m_ui.actionSaveState->setDisabled(starting || !running);
|
||||
m_ui.menuSaveState->setDisabled(starting || !running);
|
||||
@ -869,6 +870,9 @@ void MainWindow::updateEmulationActions(bool starting, bool running)
|
||||
|
||||
m_ui.actionFullscreen->setDisabled(starting || !running);
|
||||
|
||||
m_ui.actionLoadState->setDisabled(cheevos_challenge_mode);
|
||||
m_ui.menuLoadState->setDisabled(cheevos_challenge_mode);
|
||||
|
||||
if (running && m_status_speed_widget->isHidden())
|
||||
{
|
||||
m_status_speed_widget->show();
|
||||
@ -945,7 +949,7 @@ void MainWindow::switchToEmulationView()
|
||||
|
||||
void MainWindow::connectSignals()
|
||||
{
|
||||
updateEmulationActions(false, false);
|
||||
updateEmulationActions(false, false, m_host_interface->IsCheevosChallengeModeActive());
|
||||
onEmulationPaused(false);
|
||||
|
||||
connect(qApp, &QGuiApplication::applicationStateChanged, this, &MainWindow::onApplicationStateChanged);
|
||||
@ -1458,6 +1462,28 @@ void MainWindow::openMemoryCardEditor(const QString& card_a_path, const QString&
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onAchievementsChallengeModeToggled(bool enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
if (m_cheat_manager_dialog)
|
||||
{
|
||||
m_cheat_manager_dialog->close();
|
||||
delete m_cheat_manager_dialog;
|
||||
m_cheat_manager_dialog = nullptr;
|
||||
}
|
||||
|
||||
if (m_debugger_window)
|
||||
{
|
||||
m_debugger_window->close();
|
||||
delete m_debugger_window;
|
||||
m_debugger_window = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
updateEmulationActions(false, System::IsValid(), enabled);
|
||||
}
|
||||
|
||||
void MainWindow::onToolsMemoryCardEditorTriggered()
|
||||
{
|
||||
openMemoryCardEditor(QString(), QString());
|
||||
|
@ -40,6 +40,9 @@ public:
|
||||
/// Opens memory card editor with the specified paths.
|
||||
void openMemoryCardEditor(const QString& card_a_path, const QString& card_b_path);
|
||||
|
||||
/// Updates the state of the controls which should be disabled by achievements challenge mode.
|
||||
void onAchievementsChallengeModeToggled(bool enabled);
|
||||
|
||||
public Q_SLOTS:
|
||||
/// Updates debug menu visibility (hides if disabled).
|
||||
void updateDebugMenuVisibility();
|
||||
@ -113,7 +116,7 @@ private:
|
||||
void setupAdditionalUi();
|
||||
void connectSignals();
|
||||
void addThemeToMenu(const QString& name, const QString& key);
|
||||
void updateEmulationActions(bool starting, bool running);
|
||||
void updateEmulationActions(bool starting, bool running, bool cheevos_challenge_mode);
|
||||
bool isShowingGameList() const;
|
||||
void switchToGameListView();
|
||||
void switchToEmulationView();
|
||||
|
@ -957,6 +957,7 @@ void QtHostInterface::populateGameListContextMenu(const GameListEntry* entry, QW
|
||||
{
|
||||
const std::vector<SaveStateInfo> available_states(GetAvailableSaveStates(entry->code.c_str()));
|
||||
const QString timestamp_format = QLocale::system().dateTimeFormat(QLocale::ShortFormat);
|
||||
const bool challenge_mode = IsCheevosChallengeModeActive();
|
||||
for (const SaveStateInfo& ssi : available_states)
|
||||
{
|
||||
if (ssi.global)
|
||||
@ -971,7 +972,7 @@ void QtHostInterface::populateGameListContextMenu(const GameListEntry* entry, QW
|
||||
if (slot < 0)
|
||||
{
|
||||
resume_action->setText(tr("Resume (%1)").arg(timestamp_str));
|
||||
resume_action->setEnabled(true);
|
||||
resume_action->setEnabled(!challenge_mode);
|
||||
action = resume_action;
|
||||
}
|
||||
else
|
||||
@ -980,6 +981,7 @@ void QtHostInterface::populateGameListContextMenu(const GameListEntry* entry, QW
|
||||
action = load_state_menu->addAction(tr("Game Save %1 (%2)").arg(slot).arg(timestamp_str));
|
||||
}
|
||||
|
||||
action->setDisabled(challenge_mode);
|
||||
connect(action, &QAction::triggered, [this, path]() { loadState(path); });
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user