mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 13:57:57 -07:00
7036299a92
Most settings which affect determinism will now be synced on NetPlay. Additionally, there's a strict sync mode which will sync various enhancements to prevent desync in games that use EFB reads. This also adds a check for all players having the IPL.bin file, and doesn't load it for anyone if someone is missing it. This prevents desyncs caused by mismatched system fonts. Additionally, the NetPlay window was getting too wide with checkboxes, so FlowLayout has been introduced to make the checkboxes take up multiple rows dynamically. However, there's some minor vertical centering issues I haven't been able to solve, but it's better than a ridiculously wide window.
324 lines
10 KiB
C++
324 lines
10 KiB
C++
// Copyright 2017 Dolphin Emulator Project
|
|
// Licensed under GPLv2+
|
|
// Refer to the license.txt file included.
|
|
|
|
#include "DolphinQt/Settings/GeneralPane.h"
|
|
|
|
#include <map>
|
|
|
|
#include <QCheckBox>
|
|
#include <QComboBox>
|
|
#include <QFormLayout>
|
|
#include <QGroupBox>
|
|
#include <QLabel>
|
|
#include <QMessageBox>
|
|
#include <QPushButton>
|
|
#include <QRadioButton>
|
|
#include <QSlider>
|
|
#include <QVBoxLayout>
|
|
#include <QWidget>
|
|
|
|
#include "Core/Analytics.h"
|
|
#include "Core/Config/MainSettings.h"
|
|
#include "Core/Config/UISettings.h"
|
|
#include "Core/ConfigManager.h"
|
|
#include "Core/Core.h"
|
|
#include "Core/PowerPC/PowerPC.h"
|
|
|
|
#include "DolphinQt/Settings.h"
|
|
|
|
#include "UICommon/AutoUpdate.h"
|
|
#ifdef USE_DISCORD_PRESENCE
|
|
#include "UICommon/DiscordPresence.h"
|
|
#endif
|
|
|
|
constexpr int AUTO_UPDATE_DISABLE_INDEX = 0;
|
|
constexpr int AUTO_UPDATE_STABLE_INDEX = 1;
|
|
constexpr int AUTO_UPDATE_BETA_INDEX = 2;
|
|
constexpr int AUTO_UPDATE_DEV_INDEX = 3;
|
|
|
|
constexpr const char* AUTO_UPDATE_DISABLE_STRING = "";
|
|
constexpr const char* AUTO_UPDATE_STABLE_STRING = "stable";
|
|
constexpr const char* AUTO_UPDATE_BETA_STRING = "beta";
|
|
constexpr const char* AUTO_UPDATE_DEV_STRING = "dev";
|
|
|
|
static const std::map<PowerPC::CPUCore, const char*> CPU_CORE_NAMES = {
|
|
{PowerPC::CPUCore::Interpreter, QT_TR_NOOP("Interpreter (slowest)")},
|
|
{PowerPC::CPUCore::CachedInterpreter, QT_TR_NOOP("Cached Interpreter (slower)")},
|
|
{PowerPC::CPUCore::JIT64, QT_TR_NOOP("JIT Recompiler (recommended)")},
|
|
{PowerPC::CPUCore::JITARM64, QT_TR_NOOP("JIT Arm64 (experimental)")},
|
|
};
|
|
|
|
GeneralPane::GeneralPane(QWidget* parent) : QWidget(parent)
|
|
{
|
|
CreateLayout();
|
|
LoadConfig();
|
|
|
|
ConnectLayout();
|
|
|
|
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
|
|
&GeneralPane::OnEmulationStateChanged);
|
|
}
|
|
|
|
void GeneralPane::CreateLayout()
|
|
{
|
|
m_main_layout = new QVBoxLayout;
|
|
// Create layout here
|
|
CreateBasic();
|
|
|
|
if (AutoUpdateChecker::SystemSupportsAutoUpdates())
|
|
CreateAutoUpdate();
|
|
|
|
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
|
CreateAnalytics();
|
|
#endif
|
|
CreateAdvanced();
|
|
|
|
m_main_layout->addStretch(1);
|
|
setLayout(m_main_layout);
|
|
}
|
|
|
|
void GeneralPane::OnEmulationStateChanged(Core::State state)
|
|
{
|
|
const bool running = state != Core::State::Uninitialized;
|
|
|
|
m_checkbox_dualcore->setEnabled(!running);
|
|
m_checkbox_cheats->setEnabled(!running);
|
|
#ifdef USE_DISCORD_PRESENCE
|
|
m_checkbox_discord_presence->setEnabled(!running);
|
|
#endif
|
|
|
|
for (QRadioButton* radio_button : m_cpu_cores)
|
|
radio_button->setEnabled(!running);
|
|
}
|
|
|
|
void GeneralPane::ConnectLayout()
|
|
{
|
|
connect(m_checkbox_dualcore, &QCheckBox::toggled, this, &GeneralPane::OnSaveConfig);
|
|
connect(m_checkbox_cheats, &QCheckBox::toggled, this, &GeneralPane::OnSaveConfig);
|
|
#ifdef USE_DISCORD_PRESENCE
|
|
connect(m_checkbox_discord_presence, &QCheckBox::toggled, this, &GeneralPane::OnSaveConfig);
|
|
#endif
|
|
|
|
if (AutoUpdateChecker::SystemSupportsAutoUpdates())
|
|
{
|
|
connect(m_combobox_update_track,
|
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
|
&GeneralPane::OnSaveConfig);
|
|
connect(&Settings::Instance(), &Settings::AutoUpdateTrackChanged, this,
|
|
&GeneralPane::LoadConfig);
|
|
}
|
|
|
|
// Advanced
|
|
connect(m_combobox_speedlimit,
|
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
|
[this]() { OnSaveConfig(); });
|
|
for (QRadioButton* radio_button : m_cpu_cores)
|
|
connect(radio_button, &QRadioButton::toggled, this, &GeneralPane::OnSaveConfig);
|
|
|
|
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
|
connect(&Settings::Instance(), &Settings::AnalyticsToggled, this, &GeneralPane::LoadConfig);
|
|
connect(m_checkbox_enable_analytics, &QCheckBox::toggled, this, &GeneralPane::OnSaveConfig);
|
|
connect(m_button_generate_new_identity, &QPushButton::pressed, this,
|
|
&GeneralPane::GenerateNewIdentity);
|
|
#endif
|
|
}
|
|
|
|
void GeneralPane::CreateBasic()
|
|
{
|
|
auto* basic_group = new QGroupBox(tr("Basic Settings"));
|
|
auto* basic_group_layout = new QVBoxLayout;
|
|
basic_group->setLayout(basic_group_layout);
|
|
m_main_layout->addWidget(basic_group);
|
|
|
|
m_checkbox_dualcore = new QCheckBox(tr("Enable Dual Core (speedup)"));
|
|
basic_group_layout->addWidget(m_checkbox_dualcore);
|
|
|
|
m_checkbox_cheats = new QCheckBox(tr("Enable Cheats"));
|
|
basic_group_layout->addWidget(m_checkbox_cheats);
|
|
|
|
#ifdef USE_DISCORD_PRESENCE
|
|
m_checkbox_discord_presence = new QCheckBox(tr("Show Current Game on Discord"));
|
|
basic_group_layout->addWidget(m_checkbox_discord_presence);
|
|
#endif
|
|
|
|
auto* speed_limit_layout = new QFormLayout;
|
|
speed_limit_layout->setFormAlignment(Qt::AlignLeft | Qt::AlignTop);
|
|
speed_limit_layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
|
basic_group_layout->addLayout(speed_limit_layout);
|
|
|
|
m_combobox_speedlimit = new QComboBox();
|
|
|
|
m_combobox_speedlimit->addItem(tr("Unlimited"));
|
|
for (int i = 10; i <= 200; i += 10) // from 10% to 200%
|
|
{
|
|
QString str;
|
|
if (i != 100)
|
|
str = QStringLiteral("%1%").arg(i);
|
|
else
|
|
str = tr("%1% (Normal Speed)").arg(i);
|
|
|
|
m_combobox_speedlimit->addItem(str);
|
|
}
|
|
|
|
speed_limit_layout->addRow(tr("&Speed Limit:"), m_combobox_speedlimit);
|
|
}
|
|
|
|
void GeneralPane::CreateAutoUpdate()
|
|
{
|
|
auto* auto_update_group = new QGroupBox(tr("Auto Update Settings"));
|
|
auto* layout = new QFormLayout;
|
|
auto_update_group->setLayout(layout);
|
|
m_main_layout->addWidget(auto_update_group);
|
|
|
|
m_combobox_update_track = new QComboBox(this);
|
|
|
|
layout->addRow(tr("&Auto Update:"), m_combobox_update_track);
|
|
|
|
for (const QString& option : {tr("Don't Update"), tr("Stable (once a year)"),
|
|
tr("Beta (once a month)"), tr("Dev (multiple times a day)")})
|
|
m_combobox_update_track->addItem(option);
|
|
}
|
|
|
|
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
|
void GeneralPane::CreateAnalytics()
|
|
{
|
|
auto* analytics_group = new QGroupBox(tr("Usage Statistics Reporting Settings"));
|
|
auto* analytics_group_layout = new QVBoxLayout;
|
|
analytics_group->setLayout(analytics_group_layout);
|
|
m_main_layout->addWidget(analytics_group);
|
|
|
|
m_checkbox_enable_analytics = new QCheckBox(tr("Enable Usage Statistics Reporting"));
|
|
m_button_generate_new_identity = new QPushButton(tr("Generate a New Statistics Identity"));
|
|
analytics_group_layout->addWidget(m_checkbox_enable_analytics);
|
|
analytics_group_layout->addWidget(m_button_generate_new_identity);
|
|
}
|
|
#endif
|
|
|
|
void GeneralPane::CreateAdvanced()
|
|
{
|
|
auto* advanced_group = new QGroupBox(tr("Advanced Settings"));
|
|
auto* advanced_group_layout = new QVBoxLayout;
|
|
advanced_group->setLayout(advanced_group_layout);
|
|
m_main_layout->addWidget(advanced_group);
|
|
|
|
// Speed Limit
|
|
auto* engine_group = new QGroupBox(tr("CPU Emulation Engine"));
|
|
auto* engine_group_layout = new QVBoxLayout;
|
|
engine_group->setLayout(engine_group_layout);
|
|
advanced_group_layout->addWidget(engine_group);
|
|
|
|
for (PowerPC::CPUCore cpu_core : PowerPC::AvailableCPUCores())
|
|
{
|
|
m_cpu_cores.emplace_back(new QRadioButton(tr(CPU_CORE_NAMES.at(cpu_core))));
|
|
engine_group_layout->addWidget(m_cpu_cores.back());
|
|
}
|
|
}
|
|
|
|
void GeneralPane::LoadConfig()
|
|
{
|
|
if (AutoUpdateChecker::SystemSupportsAutoUpdates())
|
|
{
|
|
const auto track = Settings::Instance().GetAutoUpdateTrack().toStdString();
|
|
|
|
if (track == AUTO_UPDATE_DISABLE_STRING)
|
|
m_combobox_update_track->setCurrentIndex(AUTO_UPDATE_DISABLE_INDEX);
|
|
else if (track == AUTO_UPDATE_STABLE_STRING)
|
|
m_combobox_update_track->setCurrentIndex(AUTO_UPDATE_STABLE_INDEX);
|
|
else if (track == AUTO_UPDATE_BETA_STRING)
|
|
m_combobox_update_track->setCurrentIndex(AUTO_UPDATE_BETA_INDEX);
|
|
else
|
|
m_combobox_update_track->setCurrentIndex(AUTO_UPDATE_DEV_INDEX);
|
|
}
|
|
|
|
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
|
m_checkbox_enable_analytics->setChecked(Settings::Instance().IsAnalyticsEnabled());
|
|
#endif
|
|
m_checkbox_dualcore->setChecked(SConfig::GetInstance().bCPUThread);
|
|
m_checkbox_cheats->setChecked(Settings::Instance().GetCheatsEnabled());
|
|
#ifdef USE_DISCORD_PRESENCE
|
|
m_checkbox_discord_presence->setChecked(Config::Get(Config::MAIN_USE_DISCORD_PRESENCE));
|
|
#endif
|
|
int selection = qRound(SConfig::GetInstance().m_EmulationSpeed * 10);
|
|
if (selection < m_combobox_speedlimit->count())
|
|
m_combobox_speedlimit->setCurrentIndex(selection);
|
|
m_checkbox_dualcore->setChecked(SConfig::GetInstance().bCPUThread);
|
|
|
|
const std::vector<PowerPC::CPUCore>& available_cpu_cores = PowerPC::AvailableCPUCores();
|
|
for (size_t i = 0; i < available_cpu_cores.size(); ++i)
|
|
{
|
|
if (available_cpu_cores[i] == SConfig::GetInstance().cpu_core)
|
|
m_cpu_cores[i]->setChecked(true);
|
|
}
|
|
}
|
|
|
|
static QString UpdateTrackFromIndex(int index)
|
|
{
|
|
QString value;
|
|
|
|
switch (index)
|
|
{
|
|
case AUTO_UPDATE_DISABLE_INDEX:
|
|
value = QString::fromStdString(AUTO_UPDATE_DISABLE_STRING);
|
|
break;
|
|
case AUTO_UPDATE_STABLE_INDEX:
|
|
value = QString::fromStdString(AUTO_UPDATE_STABLE_STRING);
|
|
break;
|
|
case AUTO_UPDATE_BETA_INDEX:
|
|
value = QString::fromStdString(AUTO_UPDATE_BETA_STRING);
|
|
break;
|
|
case AUTO_UPDATE_DEV_INDEX:
|
|
value = QString::fromStdString(AUTO_UPDATE_DEV_STRING);
|
|
break;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
void GeneralPane::OnSaveConfig()
|
|
{
|
|
auto& settings = SConfig::GetInstance();
|
|
if (AutoUpdateChecker::SystemSupportsAutoUpdates())
|
|
{
|
|
Settings::Instance().SetAutoUpdateTrack(
|
|
UpdateTrackFromIndex(m_combobox_update_track->currentIndex()));
|
|
}
|
|
|
|
#ifdef USE_DISCORD_PRESENCE
|
|
Discord::SetDiscordPresenceEnabled(m_checkbox_discord_presence->isChecked());
|
|
#endif
|
|
|
|
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
|
Settings::Instance().SetAnalyticsEnabled(m_checkbox_enable_analytics->isChecked());
|
|
#endif
|
|
settings.bCPUThread = m_checkbox_dualcore->isChecked();
|
|
Config::SetBaseOrCurrent(Config::MAIN_CPU_THREAD, m_checkbox_dualcore->isChecked());
|
|
Settings::Instance().SetCheatsEnabled(m_checkbox_cheats->isChecked());
|
|
Config::SetBaseOrCurrent(Config::MAIN_ENABLE_CHEATS, m_checkbox_cheats->isChecked());
|
|
settings.m_EmulationSpeed = m_combobox_speedlimit->currentIndex() * 0.1f;
|
|
|
|
for (size_t i = 0; i < m_cpu_cores.size(); ++i)
|
|
{
|
|
if (m_cpu_cores[i]->isChecked())
|
|
{
|
|
settings.cpu_core = PowerPC::AvailableCPUCores()[i];
|
|
Config::SetBaseOrCurrent(Config::MAIN_CPU_CORE, PowerPC::AvailableCPUCores()[i]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
settings.SaveSettings();
|
|
}
|
|
|
|
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
|
void GeneralPane::GenerateNewIdentity()
|
|
{
|
|
DolphinAnalytics::Instance()->GenerateNewIdentity();
|
|
QMessageBox message_box;
|
|
message_box.setIcon(QMessageBox::Information);
|
|
message_box.setWindowTitle(tr("Identity Generation"));
|
|
message_box.setText(tr("New identity generated."));
|
|
message_box.exec();
|
|
}
|
|
#endif
|