mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 22:29:39 -06:00
Move DolphinQt2 to DolphinQt
This commit is contained in:
150
Source/Core/DolphinQt/Settings/AdvancedPane.cpp
Normal file
150
Source/Core/DolphinQt/Settings/AdvancedPane.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt/Settings/AdvancedPane.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDateTimeEdit>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QSlider>
|
||||
#include <QVBoxLayout>
|
||||
#include <cmath>
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
AdvancedPane::AdvancedPane(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
CreateLayout();
|
||||
Update();
|
||||
|
||||
ConnectLayout();
|
||||
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this, &AdvancedPane::Update);
|
||||
}
|
||||
|
||||
void AdvancedPane::CreateLayout()
|
||||
{
|
||||
auto* main_layout = new QVBoxLayout();
|
||||
setLayout(main_layout);
|
||||
|
||||
auto* cpu_options = new QGroupBox(tr("CPU Options"));
|
||||
auto* cpu_options_layout = new QVBoxLayout();
|
||||
cpu_options->setLayout(cpu_options_layout);
|
||||
main_layout->addWidget(cpu_options);
|
||||
|
||||
m_cpu_clock_override_checkbox = new QCheckBox(tr("Enable Emulated CPU Clock Override"));
|
||||
cpu_options_layout->addWidget(m_cpu_clock_override_checkbox);
|
||||
|
||||
auto* cpu_clock_override_slider_layout = new QHBoxLayout();
|
||||
cpu_clock_override_slider_layout->setContentsMargins(0, 0, 0, 0);
|
||||
cpu_options_layout->addLayout(cpu_clock_override_slider_layout);
|
||||
|
||||
m_cpu_clock_override_slider = new QSlider(Qt::Horizontal);
|
||||
m_cpu_clock_override_slider->setRange(0, 150);
|
||||
cpu_clock_override_slider_layout->addWidget(m_cpu_clock_override_slider);
|
||||
|
||||
m_cpu_clock_override_slider_label = new QLabel();
|
||||
cpu_clock_override_slider_layout->addWidget(m_cpu_clock_override_slider_label);
|
||||
|
||||
auto* cpu_clock_override_description =
|
||||
new QLabel(tr("Adjusts the emulated CPU's clock rate.\n\n"
|
||||
"Higher values may make variable-framerate games run at a higher framerate, "
|
||||
"at the expense of performance. Lower values may activate a game's "
|
||||
"internal frameskip, potentially improving performance.\n\n"
|
||||
"WARNING: Changing this from the default (100%) can and will "
|
||||
"break games and cause glitches. Do so at your own risk. "
|
||||
"Please do not report bugs that occur with a non-default clock."));
|
||||
cpu_clock_override_description->setWordWrap(true);
|
||||
cpu_options_layout->addWidget(cpu_clock_override_description);
|
||||
|
||||
auto* rtc_options = new QGroupBox(tr("Custom RTC Options"));
|
||||
rtc_options->setLayout(new QVBoxLayout());
|
||||
main_layout->addWidget(rtc_options);
|
||||
|
||||
m_custom_rtc_checkbox = new QCheckBox(tr("Enable Custom RTC"));
|
||||
rtc_options->layout()->addWidget(m_custom_rtc_checkbox);
|
||||
|
||||
m_custom_rtc_datetime = new QDateTimeEdit();
|
||||
|
||||
// Show seconds
|
||||
m_custom_rtc_datetime->setDisplayFormat(m_custom_rtc_datetime->displayFormat().replace(
|
||||
QStringLiteral("mm"), QStringLiteral("mm:ss")));
|
||||
|
||||
if (!m_custom_rtc_datetime->displayFormat().contains(QStringLiteral("yyyy")))
|
||||
{
|
||||
// Always show the full year, no matter what the locale specifies. Otherwise, two-digit years
|
||||
// will always be interpreted as in the 21st century.
|
||||
m_custom_rtc_datetime->setDisplayFormat(m_custom_rtc_datetime->displayFormat().replace(
|
||||
QStringLiteral("yy"), QStringLiteral("yyyy")));
|
||||
}
|
||||
m_custom_rtc_datetime->setDateRange({2000, 1, 1}, {2099, 12, 31});
|
||||
rtc_options->layout()->addWidget(m_custom_rtc_datetime);
|
||||
|
||||
auto* custom_rtc_description =
|
||||
new QLabel(tr("This setting allows you to set a custom real time clock (RTC) separate from "
|
||||
"your current system time.\n\nIf you're unsure, leave this disabled."));
|
||||
custom_rtc_description->setWordWrap(true);
|
||||
rtc_options->layout()->addWidget(custom_rtc_description);
|
||||
|
||||
main_layout->addStretch(1);
|
||||
}
|
||||
|
||||
void AdvancedPane::ConnectLayout()
|
||||
{
|
||||
m_cpu_clock_override_checkbox->setChecked(SConfig::GetInstance().m_OCEnable);
|
||||
connect(m_cpu_clock_override_checkbox, &QCheckBox::toggled, [this](bool enable_clock_override) {
|
||||
SConfig::GetInstance().m_OCEnable = enable_clock_override;
|
||||
Update();
|
||||
});
|
||||
|
||||
connect(m_cpu_clock_override_slider, &QSlider::valueChanged, [this](int oc_factor) {
|
||||
// Vaguely exponential scaling?
|
||||
SConfig::GetInstance().m_OCFactor =
|
||||
std::exp2f((m_cpu_clock_override_slider->value() - 100.f) / 25.f);
|
||||
Update();
|
||||
});
|
||||
|
||||
m_custom_rtc_checkbox->setChecked(SConfig::GetInstance().bEnableCustomRTC);
|
||||
connect(m_custom_rtc_checkbox, &QCheckBox::toggled, [this](bool enable_custom_rtc) {
|
||||
SConfig::GetInstance().bEnableCustomRTC = enable_custom_rtc;
|
||||
Update();
|
||||
});
|
||||
|
||||
QDateTime initial_date_time;
|
||||
initial_date_time.setTime_t(SConfig::GetInstance().m_customRTCValue);
|
||||
m_custom_rtc_datetime->setDateTime(initial_date_time);
|
||||
connect(m_custom_rtc_datetime, &QDateTimeEdit::dateTimeChanged, [this](QDateTime date_time) {
|
||||
SConfig::GetInstance().m_customRTCValue = date_time.toTime_t();
|
||||
Update();
|
||||
});
|
||||
}
|
||||
|
||||
void AdvancedPane::Update()
|
||||
{
|
||||
const bool running = Core::GetState() != Core::State::Uninitialized;
|
||||
const bool enable_cpu_clock_override_widgets = SConfig::GetInstance().m_OCEnable;
|
||||
const bool enable_custom_rtc_widgets = SConfig::GetInstance().bEnableCustomRTC && !running;
|
||||
|
||||
m_cpu_clock_override_slider->setEnabled(enable_cpu_clock_override_widgets);
|
||||
m_cpu_clock_override_slider_label->setEnabled(enable_cpu_clock_override_widgets);
|
||||
|
||||
m_cpu_clock_override_slider->setValue(
|
||||
static_cast<int>(std::ceil(std::log2f(SConfig::GetInstance().m_OCFactor) * 25.f + 100.f)));
|
||||
|
||||
m_cpu_clock_override_slider_label->setText([] {
|
||||
int core_clock = SystemTimers::GetTicksPerSecond() / std::pow(10, 6);
|
||||
int percent = static_cast<int>(std::round(SConfig::GetInstance().m_OCFactor * 100.f));
|
||||
int clock = static_cast<int>(std::round(SConfig::GetInstance().m_OCFactor * core_clock));
|
||||
return tr("%1 % (%2 MHz)").arg(QString::number(percent), QString::number(clock));
|
||||
}());
|
||||
|
||||
m_custom_rtc_checkbox->setEnabled(!running);
|
||||
m_custom_rtc_datetime->setEnabled(enable_custom_rtc_widgets);
|
||||
}
|
32
Source/Core/DolphinQt/Settings/AdvancedPane.h
Normal file
32
Source/Core/DolphinQt/Settings/AdvancedPane.h
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
class QSlider;
|
||||
class QDateTimeEdit;
|
||||
|
||||
class AdvancedPane final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AdvancedPane(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
void CreateLayout();
|
||||
void ConnectLayout();
|
||||
void Update();
|
||||
|
||||
QCheckBox* m_cpu_clock_override_checkbox;
|
||||
QSlider* m_cpu_clock_override_slider;
|
||||
QLabel* m_cpu_clock_override_slider_label;
|
||||
QLabel* m_cpu_clock_override_description;
|
||||
|
||||
QCheckBox* m_custom_rtc_checkbox;
|
||||
QDateTimeEdit* m_custom_rtc_datetime;
|
||||
};
|
333
Source/Core/DolphinQt/Settings/AudioPane.cpp
Normal file
333
Source/Core/DolphinQt/Settings/AudioPane.cpp
Normal file
@ -0,0 +1,333 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt/Settings/AudioPane.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QFormLayout>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QRadioButton>
|
||||
#include <QSlider>
|
||||
#include <QSpacerItem>
|
||||
#include <QSpinBox>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "AudioCommon/AudioCommon.h"
|
||||
#include "AudioCommon/WASAPIStream.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
|
||||
#include "DolphinQt/Config/SettingsWindow.h"
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
AudioPane::AudioPane()
|
||||
{
|
||||
CheckNeedForLatencyControl();
|
||||
CreateWidgets();
|
||||
LoadSettings();
|
||||
ConnectWidgets();
|
||||
|
||||
connect(&Settings::Instance(), &Settings::VolumeChanged, this, &AudioPane::OnVolumeChanged);
|
||||
connect(&Settings::Instance(), &Settings::EmulationStateChanged, this,
|
||||
[=](Core::State state) { OnEmulationStateChanged(state != Core::State::Uninitialized); });
|
||||
}
|
||||
|
||||
void AudioPane::CreateWidgets()
|
||||
{
|
||||
auto* dsp_box = new QGroupBox(tr("DSP Emulation Engine"));
|
||||
auto* dsp_layout = new QVBoxLayout;
|
||||
|
||||
dsp_box->setLayout(dsp_layout);
|
||||
m_dsp_hle = new QRadioButton(tr("DSP HLE Emulation (fast)"));
|
||||
m_dsp_lle = new QRadioButton(tr("DSP LLE Recompiler"));
|
||||
m_dsp_interpreter = new QRadioButton(tr("DSP LLE Interpreter (slow)"));
|
||||
|
||||
dsp_layout->addStretch(1);
|
||||
dsp_layout->addWidget(m_dsp_hle);
|
||||
dsp_layout->addWidget(m_dsp_lle);
|
||||
dsp_layout->addWidget(m_dsp_interpreter);
|
||||
dsp_layout->addStretch(1);
|
||||
|
||||
auto* volume_box = new QGroupBox(tr("Volume"));
|
||||
auto* volume_layout = new QVBoxLayout;
|
||||
m_volume_slider = new QSlider;
|
||||
m_volume_indicator = new QLabel();
|
||||
|
||||
volume_box->setLayout(volume_layout);
|
||||
|
||||
m_volume_slider->setMinimum(0);
|
||||
m_volume_slider->setMaximum(100);
|
||||
|
||||
m_volume_indicator->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);
|
||||
|
||||
volume_layout->addWidget(m_volume_slider, 0, Qt::AlignHCenter);
|
||||
volume_layout->addWidget(m_volume_indicator, 0, Qt::AlignHCenter);
|
||||
|
||||
auto* backend_box = new QGroupBox(tr("Backend Settings"));
|
||||
auto* backend_layout = new QFormLayout;
|
||||
backend_box->setLayout(backend_layout);
|
||||
m_backend_label = new QLabel(tr("Audio Backend:"));
|
||||
m_backend_combo = new QComboBox();
|
||||
m_dolby_pro_logic = new QCheckBox(tr("Dolby Pro Logic II Decoder"));
|
||||
|
||||
if (m_latency_control_supported)
|
||||
{
|
||||
m_latency_label = new QLabel(tr("Latency:"));
|
||||
m_latency_spin = new QSpinBox();
|
||||
m_latency_spin->setMinimum(0);
|
||||
m_latency_spin->setMaximum(200);
|
||||
m_latency_spin->setToolTip(tr("Sets the latency (in ms). Higher values may reduce audio "
|
||||
"crackling. Certain backends only."));
|
||||
}
|
||||
|
||||
m_dolby_pro_logic->setToolTip(
|
||||
tr("Enables Dolby Pro Logic II emulation using 5.1 surround. Certain backends only."));
|
||||
|
||||
backend_layout->setFormAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
backend_layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
||||
backend_layout->addRow(m_backend_label, m_backend_combo);
|
||||
if (m_latency_control_supported)
|
||||
backend_layout->addRow(m_latency_label, m_latency_spin);
|
||||
|
||||
#ifdef _WIN32
|
||||
m_wasapi_device_label = new QLabel(tr("Device:"));
|
||||
m_wasapi_device_combo = new QComboBox;
|
||||
|
||||
backend_layout->addRow(m_wasapi_device_label, m_wasapi_device_combo);
|
||||
#endif
|
||||
|
||||
backend_layout->addRow(m_dolby_pro_logic);
|
||||
|
||||
auto* stretching_box = new QGroupBox(tr("Audio Stretching Settings"));
|
||||
auto* stretching_layout = new QGridLayout;
|
||||
m_stretching_enable = new QCheckBox(tr("Enable Audio Stretching"));
|
||||
m_stretching_buffer_slider = new QSlider(Qt::Horizontal);
|
||||
m_stretching_buffer_indicator = new QLabel();
|
||||
m_stretching_buffer_label = new QLabel(tr("Buffer Size:"));
|
||||
stretching_box->setLayout(stretching_layout);
|
||||
|
||||
m_stretching_buffer_slider->setMinimum(5);
|
||||
m_stretching_buffer_slider->setMaximum(300);
|
||||
|
||||
m_stretching_enable->setToolTip(tr("Enables stretching of the audio to match emulation speed."));
|
||||
m_stretching_buffer_slider->setToolTip(tr("Size of stretch buffer in milliseconds. "
|
||||
"Values too low may cause audio crackling."));
|
||||
|
||||
stretching_layout->addWidget(m_stretching_enable, 0, 0, 1, -1);
|
||||
stretching_layout->addWidget(m_stretching_buffer_label, 1, 0);
|
||||
stretching_layout->addWidget(m_stretching_buffer_slider, 1, 1);
|
||||
stretching_layout->addWidget(m_stretching_buffer_indicator, 1, 2);
|
||||
|
||||
m_main_layout = new QGridLayout;
|
||||
|
||||
m_main_layout->setRowStretch(0, 0);
|
||||
|
||||
dsp_box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
|
||||
m_main_layout->addWidget(dsp_box, 0, 0);
|
||||
m_main_layout->addWidget(volume_box, 0, 1, -1, 1);
|
||||
m_main_layout->addWidget(backend_box, 1, 0);
|
||||
m_main_layout->addWidget(stretching_box, 2, 0);
|
||||
|
||||
setLayout(m_main_layout);
|
||||
}
|
||||
|
||||
void AudioPane::ConnectWidgets()
|
||||
{
|
||||
connect(m_backend_combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &AudioPane::SaveSettings);
|
||||
connect(m_volume_slider, &QSlider::valueChanged, this, &AudioPane::SaveSettings);
|
||||
if (m_latency_control_supported)
|
||||
{
|
||||
connect(m_latency_spin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this,
|
||||
&AudioPane::SaveSettings);
|
||||
}
|
||||
connect(m_stretching_buffer_slider, &QSlider::valueChanged, this, &AudioPane::SaveSettings);
|
||||
connect(m_dolby_pro_logic, &QCheckBox::toggled, this, &AudioPane::SaveSettings);
|
||||
connect(m_stretching_enable, &QCheckBox::toggled, this, &AudioPane::SaveSettings);
|
||||
connect(m_dsp_hle, &QRadioButton::toggled, this, &AudioPane::SaveSettings);
|
||||
connect(m_dsp_lle, &QRadioButton::toggled, this, &AudioPane::SaveSettings);
|
||||
connect(m_dsp_interpreter, &QRadioButton::toggled, this, &AudioPane::SaveSettings);
|
||||
|
||||
#ifdef _WIN32
|
||||
connect(m_wasapi_device_combo,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&AudioPane::SaveSettings);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioPane::LoadSettings()
|
||||
{
|
||||
auto& settings = Settings::Instance();
|
||||
|
||||
// DSP
|
||||
if (SConfig::GetInstance().bDSPHLE)
|
||||
{
|
||||
m_dsp_hle->setChecked(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dsp_lle->setChecked(SConfig::GetInstance().m_DSPEnableJIT);
|
||||
m_dsp_interpreter->setChecked(!SConfig::GetInstance().m_DSPEnableJIT);
|
||||
}
|
||||
|
||||
// Backend
|
||||
const auto current = SConfig::GetInstance().sBackend;
|
||||
for (const auto& backend : AudioCommon::GetSoundBackends())
|
||||
{
|
||||
m_backend_combo->addItem(tr(backend.c_str()), QVariant(QString::fromStdString(backend)));
|
||||
if (backend == current)
|
||||
m_backend_combo->setCurrentIndex(m_backend_combo->count() - 1);
|
||||
}
|
||||
|
||||
OnBackendChanged();
|
||||
|
||||
// Volume
|
||||
OnVolumeChanged(settings.GetVolume());
|
||||
|
||||
// DPL2
|
||||
m_dolby_pro_logic->setChecked(SConfig::GetInstance().bDPL2Decoder);
|
||||
|
||||
// Latency
|
||||
if (m_latency_control_supported)
|
||||
m_latency_spin->setValue(SConfig::GetInstance().iLatency);
|
||||
|
||||
// Stretch
|
||||
m_stretching_enable->setChecked(SConfig::GetInstance().m_audio_stretch);
|
||||
m_stretching_buffer_slider->setValue(SConfig::GetInstance().m_audio_stretch_max_latency);
|
||||
m_stretching_buffer_slider->setEnabled(m_stretching_enable->isChecked());
|
||||
m_stretching_buffer_indicator->setText(tr("%1 ms").arg(m_stretching_buffer_slider->value()));
|
||||
|
||||
#ifdef _WIN32
|
||||
if (SConfig::GetInstance().sWASAPIDevice == "default")
|
||||
{
|
||||
m_wasapi_device_combo->setCurrentIndex(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_wasapi_device_combo->setCurrentText(
|
||||
QString::fromStdString(SConfig::GetInstance().sWASAPIDevice));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioPane::SaveSettings()
|
||||
{
|
||||
auto& settings = Settings::Instance();
|
||||
|
||||
// DSP
|
||||
SConfig::GetInstance().bDSPHLE = m_dsp_hle->isChecked();
|
||||
SConfig::GetInstance().m_DSPEnableJIT = m_dsp_lle->isChecked();
|
||||
|
||||
// Backend
|
||||
const auto selection =
|
||||
m_backend_combo->itemData(m_backend_combo->currentIndex()).toString().toStdString();
|
||||
auto& backend = SConfig::GetInstance().sBackend;
|
||||
|
||||
if (selection != backend)
|
||||
{
|
||||
backend = selection;
|
||||
OnBackendChanged();
|
||||
}
|
||||
|
||||
// Volume
|
||||
if (m_volume_slider->value() != settings.GetVolume())
|
||||
{
|
||||
settings.SetVolume(m_volume_slider->value());
|
||||
OnVolumeChanged(settings.GetVolume());
|
||||
}
|
||||
|
||||
// DPL2
|
||||
SConfig::GetInstance().bDPL2Decoder = m_dolby_pro_logic->isChecked();
|
||||
|
||||
// Latency
|
||||
if (m_latency_control_supported)
|
||||
SConfig::GetInstance().iLatency = m_latency_spin->value();
|
||||
|
||||
// Stretch
|
||||
SConfig::GetInstance().m_audio_stretch = m_stretching_enable->isChecked();
|
||||
SConfig::GetInstance().m_audio_stretch_max_latency = m_stretching_buffer_slider->value();
|
||||
m_stretching_buffer_label->setEnabled(m_stretching_enable->isChecked());
|
||||
m_stretching_buffer_slider->setEnabled(m_stretching_enable->isChecked());
|
||||
m_stretching_buffer_indicator->setEnabled(m_stretching_enable->isChecked());
|
||||
m_stretching_buffer_indicator->setText(
|
||||
tr("%1 ms").arg(SConfig::GetInstance().m_audio_stretch_max_latency));
|
||||
|
||||
#ifdef _WIN32
|
||||
std::string device = "default";
|
||||
|
||||
if (m_wasapi_device_combo->currentIndex() != 0)
|
||||
device = m_wasapi_device_combo->currentText().toStdString();
|
||||
|
||||
SConfig::GetInstance().sWASAPIDevice = device;
|
||||
#endif
|
||||
|
||||
AudioCommon::UpdateSoundStream();
|
||||
}
|
||||
|
||||
void AudioPane::OnBackendChanged()
|
||||
{
|
||||
const auto backend = SConfig::GetInstance().sBackend;
|
||||
|
||||
m_dolby_pro_logic->setEnabled(AudioCommon::SupportsDPL2Decoder(backend));
|
||||
if (m_latency_control_supported)
|
||||
{
|
||||
m_latency_label->setEnabled(AudioCommon::SupportsLatencyControl(backend));
|
||||
m_latency_spin->setEnabled(AudioCommon::SupportsLatencyControl(backend));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
bool is_wasapi = backend == BACKEND_WASAPI;
|
||||
m_wasapi_device_label->setHidden(!is_wasapi);
|
||||
m_wasapi_device_combo->setHidden(!is_wasapi);
|
||||
|
||||
if (is_wasapi)
|
||||
{
|
||||
m_wasapi_device_combo->clear();
|
||||
m_wasapi_device_combo->addItem(tr("Default Device"));
|
||||
|
||||
for (const auto device : WASAPIStream::GetAvailableDevices())
|
||||
m_wasapi_device_combo->addItem(QString::fromStdString(device));
|
||||
}
|
||||
#endif
|
||||
|
||||
m_volume_slider->setEnabled(AudioCommon::SupportsVolumeChanges(backend));
|
||||
m_volume_indicator->setEnabled(AudioCommon::SupportsVolumeChanges(backend));
|
||||
}
|
||||
|
||||
void AudioPane::OnEmulationStateChanged(bool running)
|
||||
{
|
||||
m_dsp_hle->setEnabled(!running);
|
||||
m_dsp_lle->setEnabled(!running);
|
||||
m_dsp_interpreter->setEnabled(!running);
|
||||
m_dolby_pro_logic->setEnabled(!running);
|
||||
m_backend_label->setEnabled(!running);
|
||||
m_backend_combo->setEnabled(!running);
|
||||
if (m_latency_control_supported)
|
||||
{
|
||||
m_latency_label->setEnabled(!running);
|
||||
m_latency_spin->setEnabled(!running);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
m_wasapi_device_combo->setEnabled(!running);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioPane::OnVolumeChanged(int volume)
|
||||
{
|
||||
m_volume_slider->setValue(volume);
|
||||
m_volume_indicator->setText(tr("%1 %").arg(volume));
|
||||
}
|
||||
|
||||
void AudioPane::CheckNeedForLatencyControl()
|
||||
{
|
||||
std::vector<std::string> backends = AudioCommon::GetSoundBackends();
|
||||
m_latency_control_supported =
|
||||
std::any_of(backends.cbegin(), backends.cend(), AudioCommon::SupportsLatencyControl);
|
||||
}
|
65
Source/Core/DolphinQt/Settings/AudioPane.h
Normal file
65
Source/Core/DolphinQt/Settings/AudioPane.h
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QGridLayout;
|
||||
class QRadioButton;
|
||||
class QSlider;
|
||||
class QSpinBox;
|
||||
class SettingsWindow;
|
||||
|
||||
class AudioPane final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AudioPane();
|
||||
|
||||
private:
|
||||
void CreateWidgets();
|
||||
void ConnectWidgets();
|
||||
|
||||
void LoadSettings();
|
||||
void SaveSettings();
|
||||
|
||||
void OnEmulationStateChanged(bool running);
|
||||
void OnBackendChanged();
|
||||
void OnVolumeChanged(int volume);
|
||||
|
||||
void CheckNeedForLatencyControl();
|
||||
bool m_latency_control_supported;
|
||||
|
||||
QGridLayout* m_main_layout;
|
||||
|
||||
// DSP Engine
|
||||
QRadioButton* m_dsp_hle;
|
||||
QRadioButton* m_dsp_lle;
|
||||
QRadioButton* m_dsp_interpreter;
|
||||
|
||||
// Volume
|
||||
QSlider* m_volume_slider;
|
||||
QLabel* m_volume_indicator;
|
||||
|
||||
// Backend
|
||||
QLabel* m_backend_label;
|
||||
QComboBox* m_backend_combo;
|
||||
QCheckBox* m_dolby_pro_logic;
|
||||
QLabel* m_latency_label;
|
||||
QSpinBox* m_latency_spin;
|
||||
#ifdef _WIN32
|
||||
QLabel* m_wasapi_device_label;
|
||||
QComboBox* m_wasapi_device_combo;
|
||||
#endif
|
||||
|
||||
// Audio Stretching
|
||||
QCheckBox* m_stretching_enable;
|
||||
QLabel* m_stretching_buffer_label;
|
||||
QSlider* m_stretching_buffer_slider;
|
||||
QLabel* m_stretching_buffer_indicator;
|
||||
};
|
393
Source/Core/DolphinQt/Settings/GameCubePane.cpp
Normal file
393
Source/Core/DolphinQt/Settings/GameCubePane.cpp
Normal file
@ -0,0 +1,393 @@
|
||||
// Copyright 2018 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt/Settings/GameCubePane.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/FileUtil.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/HW/EXI/EXI.h"
|
||||
#include "Core/HW/GCMemcard/GCMemcard.h"
|
||||
|
||||
#include "DolphinQt/Config/Mapping/MappingWindow.h"
|
||||
|
||||
constexpr int SLOT_A_INDEX = 0;
|
||||
constexpr int SLOT_B_INDEX = 1;
|
||||
constexpr int SLOT_SP1_INDEX = 2;
|
||||
constexpr int SLOT_COUNT = 3;
|
||||
|
||||
enum ExpansionSelection
|
||||
{
|
||||
EXP_NOTHING = 0,
|
||||
EXP_DUMMY = 1,
|
||||
EXP_MEMORYCARD = 2,
|
||||
EXP_BROADBAND = 2,
|
||||
EXP_GCI_FOLDER = 3,
|
||||
EXP_GECKO = 4,
|
||||
EXP_AGP = 5,
|
||||
EXP_MICROPHONE = 6
|
||||
};
|
||||
|
||||
GameCubePane::GameCubePane()
|
||||
{
|
||||
CreateWidgets();
|
||||
LoadSettings();
|
||||
ConnectWidgets();
|
||||
}
|
||||
|
||||
void GameCubePane::CreateWidgets()
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout;
|
||||
|
||||
// IPL Settings
|
||||
QGroupBox* ipl_box = new QGroupBox(tr("IPL Settings"));
|
||||
QGridLayout* ipl_layout = new QGridLayout;
|
||||
ipl_box->setLayout(ipl_layout);
|
||||
|
||||
m_skip_main_menu = new QCheckBox(tr("Skip Main Menu"));
|
||||
m_override_language_ntsc = new QCheckBox(tr("Override Language on NTSC Games"));
|
||||
m_language_combo = new QComboBox;
|
||||
|
||||
// Add languages
|
||||
for (const auto& language :
|
||||
{tr("English"), tr("German"), tr("French"), tr("Spanish"), tr("Italian"), tr("Dutch")})
|
||||
m_language_combo->addItem(language);
|
||||
|
||||
ipl_layout->addWidget(m_skip_main_menu, 0, 0);
|
||||
ipl_layout->addWidget(new QLabel(tr("System Language:")), 1, 0);
|
||||
ipl_layout->addWidget(m_language_combo, 1, 1);
|
||||
ipl_layout->addWidget(m_override_language_ntsc, 2, 0);
|
||||
|
||||
// Device Settings
|
||||
QGroupBox* device_box = new QGroupBox(tr("Device Settings"));
|
||||
QGridLayout* device_layout = new QGridLayout;
|
||||
device_box->setLayout(device_layout);
|
||||
|
||||
m_slot_combos[0] = new QComboBox;
|
||||
m_slot_combos[1] = new QComboBox;
|
||||
m_slot_combos[2] = new QComboBox;
|
||||
|
||||
m_slot_buttons[0] = new QPushButton(tr("..."));
|
||||
m_slot_buttons[1] = new QPushButton(tr("..."));
|
||||
|
||||
m_slot_buttons[0]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
m_slot_buttons[1]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
|
||||
const QString i10n_nothing = tr("<Nothing>");
|
||||
const QString i10n_dummy = tr("Dummy");
|
||||
|
||||
// Add slot devices
|
||||
|
||||
for (const auto& device : {i10n_nothing, i10n_dummy, tr("Memory Card"), tr("GCI Folder"),
|
||||
tr("USB Gecko"), tr("Advance Game Port"), tr("Microphone")})
|
||||
{
|
||||
m_slot_combos[0]->addItem(device);
|
||||
m_slot_combos[1]->addItem(device);
|
||||
}
|
||||
|
||||
// Add SP1 devices
|
||||
|
||||
for (const auto& device : {i10n_nothing, i10n_dummy, tr("Broadband Adapter")})
|
||||
{
|
||||
m_slot_combos[2]->addItem(device);
|
||||
}
|
||||
|
||||
device_layout->addWidget(new QLabel(tr("Slot A:")), 0, 0);
|
||||
device_layout->addWidget(m_slot_combos[0], 0, 1);
|
||||
device_layout->addWidget(m_slot_buttons[0], 0, 2);
|
||||
device_layout->addWidget(new QLabel(tr("Slot B:")), 1, 0);
|
||||
device_layout->addWidget(m_slot_combos[1], 1, 1);
|
||||
device_layout->addWidget(m_slot_buttons[1], 1, 2);
|
||||
device_layout->addWidget(new QLabel(tr("SP1:")), 2, 0);
|
||||
device_layout->addWidget(m_slot_combos[2], 2, 1);
|
||||
|
||||
layout->addWidget(ipl_box);
|
||||
layout->addWidget(device_box);
|
||||
|
||||
layout->addStretch();
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void GameCubePane::ConnectWidgets()
|
||||
{
|
||||
// IPL Settings
|
||||
connect(m_skip_main_menu, &QCheckBox::stateChanged, this, &GameCubePane::SaveSettings);
|
||||
connect(m_language_combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||
this, &GameCubePane::SaveSettings);
|
||||
connect(m_override_language_ntsc, &QCheckBox::stateChanged, this, &GameCubePane::SaveSettings);
|
||||
|
||||
// Device Settings
|
||||
for (int i = 0; i < SLOT_COUNT; i++)
|
||||
{
|
||||
connect(m_slot_combos[i],
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&GameCubePane::SaveSettings);
|
||||
if (i <= SLOT_B_INDEX)
|
||||
{
|
||||
connect(m_slot_buttons[i], &QPushButton::pressed, this, [this, i] { OnConfigPressed(i); });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GameCubePane::OnConfigPressed(int slot)
|
||||
{
|
||||
QString filter;
|
||||
bool memcard = false;
|
||||
|
||||
switch (m_slot_combos[slot]->currentIndex())
|
||||
{
|
||||
// Memory card
|
||||
case 2:
|
||||
filter = tr("GameCube Memory Cards (*.raw *.gcp)");
|
||||
memcard = true;
|
||||
break;
|
||||
// Advance Game Port
|
||||
case 5:
|
||||
filter = tr("Game Boy Advance Carts (*.gba)");
|
||||
memcard = false;
|
||||
break;
|
||||
// Microphone
|
||||
case 6:
|
||||
MappingWindow(this, MappingWindow::Type::MAPPING_GC_MICROPHONE, slot).exec();
|
||||
return;
|
||||
}
|
||||
|
||||
QString filename = QFileDialog::getSaveFileName(
|
||||
this, tr("Choose a file to open"), QString::fromStdString(File::GetUserPath(D_GCUSER_IDX)),
|
||||
filter, 0, QFileDialog::DontConfirmOverwrite);
|
||||
|
||||
if (filename.isEmpty())
|
||||
return;
|
||||
|
||||
QString path_abs = QFileInfo(filename).absoluteFilePath();
|
||||
|
||||
// Memcard validity checks
|
||||
if (memcard)
|
||||
{
|
||||
if (File::Exists(filename.toStdString()))
|
||||
{
|
||||
GCMemcard mc(filename.toStdString());
|
||||
|
||||
if (!mc.IsValid())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Cannot use that file as a memory card.\n%1\n"
|
||||
"is not a valid GameCube memory card file")
|
||||
.arg(filename));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool other_slot_memcard =
|
||||
m_slot_combos[slot == 0 ? SLOT_B_INDEX : SLOT_A_INDEX]->currentIndex() == EXP_MEMORYCARD;
|
||||
|
||||
if (other_slot_memcard)
|
||||
{
|
||||
QString path_b =
|
||||
QFileInfo(QString::fromStdString(slot == 0 ? SConfig::GetInstance().m_strMemoryCardB :
|
||||
SConfig::GetInstance().m_strMemoryCardA))
|
||||
.absoluteFilePath();
|
||||
|
||||
if (path_abs == path_b)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"), tr("The same file can't be used in both slots."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString path_old;
|
||||
if (memcard)
|
||||
{
|
||||
path_old =
|
||||
QFileInfo(QString::fromStdString(slot == 0 ? SConfig::GetInstance().m_strMemoryCardA :
|
||||
SConfig::GetInstance().m_strMemoryCardB))
|
||||
.absoluteFilePath();
|
||||
}
|
||||
else
|
||||
{
|
||||
path_old = QFileInfo(QString::fromStdString(slot == 0 ? SConfig::GetInstance().m_strGbaCartA :
|
||||
SConfig::GetInstance().m_strGbaCartB))
|
||||
.absoluteFilePath();
|
||||
}
|
||||
|
||||
if (memcard)
|
||||
{
|
||||
if (slot == SLOT_A_INDEX)
|
||||
{
|
||||
SConfig::GetInstance().m_strMemoryCardA = path_abs.toStdString();
|
||||
}
|
||||
else
|
||||
{
|
||||
SConfig::GetInstance().m_strMemoryCardB = path_abs.toStdString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (slot == SLOT_A_INDEX)
|
||||
{
|
||||
SConfig::GetInstance().m_strGbaCartA = path_abs.toStdString();
|
||||
}
|
||||
else
|
||||
{
|
||||
SConfig::GetInstance().m_strGbaCartB = path_abs.toStdString();
|
||||
}
|
||||
}
|
||||
|
||||
if (Core::IsRunning() && path_abs != path_old)
|
||||
{
|
||||
ExpansionInterface::ChangeDevice(
|
||||
// SlotB is on channel 1, slotA and SP1 are on 0
|
||||
slot,
|
||||
// The device enum to change to
|
||||
memcard ? ExpansionInterface::EXIDEVICE_MEMORYCARD : ExpansionInterface::EXIDEVICE_AGP,
|
||||
// SP1 is device 2, slots are device 0
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
void GameCubePane::LoadSettings()
|
||||
{
|
||||
const SConfig& params = SConfig::GetInstance();
|
||||
|
||||
// IPL Settings
|
||||
m_skip_main_menu->setChecked(params.bHLE_BS2);
|
||||
m_language_combo->setCurrentIndex(params.SelectedLanguage);
|
||||
m_override_language_ntsc->setChecked(params.bOverrideGCLanguage);
|
||||
|
||||
bool have_menu = false;
|
||||
|
||||
for (const std::string& dir : {USA_DIR, JAP_DIR, EUR_DIR})
|
||||
{
|
||||
const auto path = DIR_SEP + dir + DIR_SEP GC_IPL;
|
||||
if (File::Exists(File::GetUserPath(D_GCUSER_IDX) + path) ||
|
||||
File::Exists(File::GetSysDirectory() + GC_SYS_DIR + path))
|
||||
{
|
||||
have_menu = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_skip_main_menu->setEnabled(have_menu);
|
||||
m_skip_main_menu->setToolTip(have_menu ? QStringLiteral("") :
|
||||
tr("Put Main Menu roms in User/GC/{region}."));
|
||||
|
||||
// Device Settings
|
||||
|
||||
for (int i = 0; i < SLOT_COUNT; i++)
|
||||
{
|
||||
int index = EXP_NOTHING;
|
||||
switch (SConfig::GetInstance().m_EXIDevice[i])
|
||||
{
|
||||
case ExpansionInterface::EXIDEVICE_NONE:
|
||||
index = EXP_NOTHING;
|
||||
break;
|
||||
case ExpansionInterface::EXIDEVICE_DUMMY:
|
||||
index = EXP_DUMMY;
|
||||
break;
|
||||
case ExpansionInterface::EXIDEVICE_MEMORYCARD:
|
||||
index = EXP_MEMORYCARD;
|
||||
break;
|
||||
case ExpansionInterface::EXIDEVICE_ETH:
|
||||
index = EXP_BROADBAND;
|
||||
break;
|
||||
case ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER:
|
||||
index = EXP_GCI_FOLDER;
|
||||
break;
|
||||
case ExpansionInterface::EXIDEVICE_GECKO:
|
||||
index = EXP_GECKO;
|
||||
break;
|
||||
case ExpansionInterface::EXIDEVICE_AGP:
|
||||
index = EXP_AGP;
|
||||
break;
|
||||
case ExpansionInterface::EXIDEVICE_MIC:
|
||||
index = EXP_MICROPHONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (i <= SLOT_B_INDEX)
|
||||
{
|
||||
bool has_config = (index == EXP_MEMORYCARD || index > EXP_GECKO);
|
||||
m_slot_buttons[i]->setEnabled(has_config);
|
||||
}
|
||||
|
||||
m_slot_combos[i]->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
void GameCubePane::SaveSettings()
|
||||
{
|
||||
SConfig& params = SConfig::GetInstance();
|
||||
|
||||
// IPL Settings
|
||||
params.bHLE_BS2 = m_skip_main_menu->isChecked();
|
||||
params.SelectedLanguage = m_language_combo->currentIndex();
|
||||
params.bOverrideGCLanguage = m_override_language_ntsc->isChecked();
|
||||
|
||||
for (int i = 0; i < SLOT_COUNT; i++)
|
||||
{
|
||||
auto dev = SConfig::GetInstance().m_EXIDevice[i];
|
||||
|
||||
int index = m_slot_combos[i]->currentIndex();
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case EXP_NOTHING:
|
||||
dev = ExpansionInterface::EXIDEVICE_NONE;
|
||||
break;
|
||||
case EXP_DUMMY:
|
||||
dev = ExpansionInterface::EXIDEVICE_DUMMY;
|
||||
break;
|
||||
case EXP_MEMORYCARD:
|
||||
if (i == SLOT_SP1_INDEX)
|
||||
dev = ExpansionInterface::EXIDEVICE_ETH;
|
||||
else
|
||||
dev = ExpansionInterface::EXIDEVICE_MEMORYCARD;
|
||||
break;
|
||||
case EXP_GCI_FOLDER:
|
||||
dev = ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER;
|
||||
break;
|
||||
case EXP_GECKO:
|
||||
dev = ExpansionInterface::EXIDEVICE_GECKO;
|
||||
break;
|
||||
case EXP_AGP:
|
||||
dev = ExpansionInterface::EXIDEVICE_AGP;
|
||||
break;
|
||||
case EXP_MICROPHONE:
|
||||
dev = ExpansionInterface::EXIDEVICE_MIC;
|
||||
break;
|
||||
}
|
||||
|
||||
if (Core::IsRunning() && SConfig::GetInstance().m_EXIDevice[i] != dev)
|
||||
{
|
||||
ExpansionInterface::ChangeDevice(
|
||||
// SlotB is on channel 1, slotA and SP1 are on 0
|
||||
(i == 1) ? 1 : 0,
|
||||
// The device enum to change to
|
||||
dev,
|
||||
// SP1 is device 2, slots are device 0
|
||||
(i == 2) ? 2 : 0);
|
||||
}
|
||||
|
||||
SConfig::GetInstance().m_EXIDevice[i] = dev;
|
||||
}
|
||||
LoadSettings();
|
||||
}
|
34
Source/Core/DolphinQt/Settings/GameCubePane.h
Normal file
34
Source/Core/DolphinQt/Settings/GameCubePane.h
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2018 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QPushButton;
|
||||
|
||||
class GameCubePane : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GameCubePane();
|
||||
|
||||
private:
|
||||
void CreateWidgets();
|
||||
void ConnectWidgets();
|
||||
|
||||
void LoadSettings();
|
||||
void SaveSettings();
|
||||
|
||||
void OnConfigPressed(int slot);
|
||||
|
||||
QCheckBox* m_skip_main_menu;
|
||||
QCheckBox* m_override_language_ntsc;
|
||||
QComboBox* m_language_combo;
|
||||
|
||||
QPushButton* m_slot_buttons[2];
|
||||
QComboBox* m_slot_combos[3];
|
||||
};
|
315
Source/Core/DolphinQt/Settings/GeneralPane.cpp
Normal file
315
Source/Core/DolphinQt/Settings/GeneralPane.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
// 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/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);
|
||||
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();
|
||||
Settings::Instance().SetCheatsEnabled(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];
|
||||
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
|
62
Source/Core/DolphinQt/Settings/GeneralPane.h
Normal file
62
Source/Core/DolphinQt/Settings/GeneralPane.h
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QRadioButton;
|
||||
class QSlider;
|
||||
class QVBoxLayout;
|
||||
|
||||
namespace Core
|
||||
{
|
||||
enum class State;
|
||||
}
|
||||
|
||||
class GeneralPane final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GeneralPane(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
void CreateLayout();
|
||||
void ConnectLayout();
|
||||
void CreateBasic();
|
||||
void CreateAutoUpdate();
|
||||
void CreateAdvanced();
|
||||
|
||||
void LoadConfig();
|
||||
void OnSaveConfig();
|
||||
void OnEmulationStateChanged(Core::State state);
|
||||
|
||||
// Widgets
|
||||
QVBoxLayout* m_main_layout;
|
||||
QComboBox* m_combobox_speedlimit;
|
||||
QComboBox* m_combobox_update_track;
|
||||
QCheckBox* m_checkbox_dualcore;
|
||||
QCheckBox* m_checkbox_cheats;
|
||||
#ifdef USE_DISCORD_PRESENCE
|
||||
QCheckBox* m_checkbox_discord_presence;
|
||||
#endif
|
||||
QLabel* m_label_speedlimit;
|
||||
|
||||
std::vector<QRadioButton*> m_cpu_cores;
|
||||
|
||||
// Analytics related
|
||||
#if defined(USE_ANALYTICS) && USE_ANALYTICS
|
||||
void CreateAnalytics();
|
||||
void GenerateNewIdentity();
|
||||
|
||||
QPushButton* m_button_generate_new_identity;
|
||||
QCheckBox* m_checkbox_enable_analytics;
|
||||
#endif
|
||||
};
|
268
Source/Core/DolphinQt/Settings/InterfacePane.cpp
Normal file
268
Source/Core/DolphinQt/Settings/InterfacePane.cpp
Normal file
@ -0,0 +1,268 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt/Settings/InterfacePane.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QFormLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
#include "Common/CommonPaths.h"
|
||||
#include "Common/FileSearch.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include "DolphinQt/Settings.h"
|
||||
|
||||
static QComboBox* MakeLanguageComboBox()
|
||||
{
|
||||
static const struct
|
||||
{
|
||||
const QString name;
|
||||
const char* id;
|
||||
} languages[] = {
|
||||
{QStringLiteral(u"Bahasa Melayu"), "ms"}, // Malay
|
||||
{QStringLiteral(u"Catal\u00E0"), "ca"}, // Catalan
|
||||
{QStringLiteral(u"\u010Ce\u0161tina"), "cs"}, // Czech
|
||||
{QStringLiteral(u"Dansk"), "da"}, // Danish
|
||||
{QStringLiteral(u"Deutsch"), "de"}, // German
|
||||
{QStringLiteral(u"English"), "en"}, // English
|
||||
{QStringLiteral(u"Espa\u00F1ol"), "es"}, // Spanish
|
||||
{QStringLiteral(u"Fran\u00E7ais"), "fr"}, // French
|
||||
{QStringLiteral(u"Hrvatski"), "hr"}, // Croatian
|
||||
{QStringLiteral(u"Italiano"), "it"}, // Italian
|
||||
{QStringLiteral(u"Magyar"), "hu"}, // Hungarian
|
||||
{QStringLiteral(u"Nederlands"), "nl"}, // Dutch
|
||||
{QStringLiteral(u"Norsk bokm\u00E5l"), "nb"}, // Norwegian
|
||||
{QStringLiteral(u"Polski"), "pl"}, // Polish
|
||||
{QStringLiteral(u"Portugu\u00EAs"), "pt"}, // Portuguese
|
||||
{QStringLiteral(u"Portugu\u00EAs (Brasil)"), "pt_BR"}, // Portuguese (Brazil)
|
||||
{QStringLiteral(u"Rom\u00E2n\u0103"), "ro"}, // Romanian
|
||||
{QStringLiteral(u"Srpski"), "sr"}, // Serbian
|
||||
{QStringLiteral(u"Svenska"), "sv"}, // Swedish
|
||||
{QStringLiteral(u"T\u00FCrk\u00E7e"), "tr"}, // Turkish
|
||||
{QStringLiteral(u"\u0395\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC"), "el"}, // Greek
|
||||
{QStringLiteral(u"\u0420\u0443\u0441\u0441\u043A\u0438\u0439"), "ru"}, // Russian
|
||||
{QStringLiteral(u"\u0627\u0644\u0639\u0631\u0628\u064A\u0629"), "ar"}, // Arabic
|
||||
{QStringLiteral(u"\u0641\u0627\u0631\u0633\u06CC"), "fa"}, // Farsi
|
||||
{QStringLiteral(u"\uD55C\uAD6D\uC5B4"), "ko"}, // Korean
|
||||
{QStringLiteral(u"\u65E5\u672C\u8A9E"), "ja"}, // Japanese
|
||||
{QStringLiteral(u"\u7B80\u4F53\u4E2D\u6587"), "zh_CN"}, // Simplified Chinese
|
||||
{QStringLiteral(u"\u7E41\u9AD4\u4E2D\u6587"), "zh_TW"}, // Traditional Chinese
|
||||
};
|
||||
|
||||
auto* combobox = new QComboBox();
|
||||
combobox->addItem(QObject::tr("<System Language>"), QStringLiteral(""));
|
||||
for (const auto& lang : languages)
|
||||
combobox->addItem(lang.name, QString::fromLatin1(lang.id));
|
||||
|
||||
// The default, QComboBox::AdjustToContentsOnFirstShow, causes a noticeable pause when opening the
|
||||
// SettingWindow for the first time. The culprit seems to be non-Latin graphemes in the above
|
||||
// list. QComboBox::AdjustToContents still has some lag but it's much less noticeable.
|
||||
combobox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
|
||||
return combobox;
|
||||
}
|
||||
|
||||
InterfacePane::InterfacePane(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
CreateLayout();
|
||||
LoadConfig();
|
||||
ConnectLayout();
|
||||
}
|
||||
|
||||
void InterfacePane::CreateLayout()
|
||||
{
|
||||
m_main_layout = new QVBoxLayout;
|
||||
// Create layout here
|
||||
CreateUI();
|
||||
CreateInGame();
|
||||
|
||||
m_main_layout->addStretch(1);
|
||||
setLayout(m_main_layout);
|
||||
}
|
||||
|
||||
void InterfacePane::CreateUI()
|
||||
{
|
||||
auto* groupbox = new QGroupBox(tr("User Interface"));
|
||||
auto* groupbox_layout = new QVBoxLayout;
|
||||
groupbox->setLayout(groupbox_layout);
|
||||
m_main_layout->addWidget(groupbox);
|
||||
|
||||
auto* combobox_layout = new QFormLayout;
|
||||
combobox_layout->setFormAlignment(Qt::AlignLeft | Qt::AlignTop);
|
||||
combobox_layout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
||||
|
||||
groupbox_layout->addLayout(combobox_layout);
|
||||
|
||||
m_combobox_language = MakeLanguageComboBox();
|
||||
combobox_layout->addRow(tr("&Language:"), m_combobox_language);
|
||||
|
||||
// Theme Combobox
|
||||
m_combobox_theme = new QComboBox;
|
||||
combobox_layout->addRow(tr("&Theme:"), m_combobox_theme);
|
||||
|
||||
// List avalable themes
|
||||
auto theme_search_results =
|
||||
Common::DoFileSearch({File::GetUserPath(D_THEMES_IDX), File::GetSysDirectory() + THEMES_DIR});
|
||||
for (const std::string& filename : theme_search_results)
|
||||
{
|
||||
std::string name, ext;
|
||||
SplitPath(filename, nullptr, &name, &ext);
|
||||
name += ext;
|
||||
QString qt_name = QString::fromStdString(name);
|
||||
m_combobox_theme->addItem(qt_name);
|
||||
}
|
||||
|
||||
// User Style Combobox
|
||||
m_combobox_userstyle = new QComboBox;
|
||||
m_label_userstyle = new QLabel(tr("User Style:"));
|
||||
combobox_layout->addRow(m_label_userstyle, m_combobox_userstyle);
|
||||
|
||||
auto userstyle_search_results = Common::DoFileSearch({File::GetUserPath(D_STYLES_IDX)});
|
||||
|
||||
m_combobox_userstyle->addItem(tr("(None)"), QStringLiteral(""));
|
||||
|
||||
for (const std::string& filename : userstyle_search_results)
|
||||
{
|
||||
std::string name, ext;
|
||||
SplitPath(filename, nullptr, &name, &ext);
|
||||
QString qt_name = QString::fromStdString(name);
|
||||
m_combobox_userstyle->addItem(qt_name, QString::fromStdString(filename));
|
||||
}
|
||||
|
||||
// Checkboxes
|
||||
m_checkbox_top_window = new QCheckBox(tr("Keep Window on Top"));
|
||||
m_checkbox_use_builtin_title_database = new QCheckBox(tr("Use Built-In Database of Game Names"));
|
||||
m_checkbox_use_userstyle = new QCheckBox(tr("Use Custom User Style"));
|
||||
m_checkbox_show_debugging_ui = new QCheckBox(tr("Show Debugging UI"));
|
||||
|
||||
groupbox_layout->addWidget(m_checkbox_top_window);
|
||||
groupbox_layout->addWidget(m_checkbox_use_builtin_title_database);
|
||||
groupbox_layout->addWidget(m_checkbox_use_userstyle);
|
||||
groupbox_layout->addWidget(m_checkbox_show_debugging_ui);
|
||||
}
|
||||
|
||||
void InterfacePane::CreateInGame()
|
||||
{
|
||||
auto* groupbox = new QGroupBox(tr("In Game"));
|
||||
auto* groupbox_layout = new QVBoxLayout;
|
||||
groupbox->setLayout(groupbox_layout);
|
||||
m_main_layout->addWidget(groupbox);
|
||||
|
||||
m_checkbox_confirm_on_stop = new QCheckBox(tr("Confirm on Stop"));
|
||||
m_checkbox_use_panic_handlers = new QCheckBox(tr("Use Panic Handlers"));
|
||||
m_checkbox_enable_osd = new QCheckBox(tr("Show On-Screen Display Messages"));
|
||||
m_checkbox_show_active_title = new QCheckBox(tr("Show Active Title in Window Title"));
|
||||
m_checkbox_pause_on_focus_lost = new QCheckBox(tr("Pause on Focus Loss"));
|
||||
m_checkbox_hide_mouse = new QCheckBox(tr("Always Hide Mouse Cursor"));
|
||||
|
||||
groupbox_layout->addWidget(m_checkbox_confirm_on_stop);
|
||||
groupbox_layout->addWidget(m_checkbox_use_panic_handlers);
|
||||
groupbox_layout->addWidget(m_checkbox_enable_osd);
|
||||
groupbox_layout->addWidget(m_checkbox_show_active_title);
|
||||
groupbox_layout->addWidget(m_checkbox_pause_on_focus_lost);
|
||||
groupbox_layout->addWidget(m_checkbox_hide_mouse);
|
||||
}
|
||||
|
||||
void InterfacePane::ConnectLayout()
|
||||
{
|
||||
connect(m_checkbox_top_window, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
|
||||
connect(m_checkbox_use_builtin_title_database, &QCheckBox::toggled, this,
|
||||
&InterfacePane::OnSaveConfig);
|
||||
connect(m_checkbox_show_debugging_ui, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
|
||||
connect(m_combobox_theme,
|
||||
static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged),
|
||||
&Settings::Instance(), &Settings::SetThemeName);
|
||||
connect(m_combobox_userstyle,
|
||||
static_cast<void (QComboBox::*)(const QString&)>(&QComboBox::currentIndexChanged), this,
|
||||
&InterfacePane::OnSaveConfig);
|
||||
connect(m_combobox_language,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&InterfacePane::OnSaveConfig);
|
||||
connect(m_checkbox_confirm_on_stop, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
|
||||
connect(m_checkbox_use_panic_handlers, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
|
||||
connect(m_checkbox_enable_osd, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
|
||||
connect(m_checkbox_pause_on_focus_lost, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
|
||||
connect(m_checkbox_hide_mouse, &QCheckBox::toggled, &Settings::Instance(),
|
||||
&Settings::SetHideCursor);
|
||||
connect(m_checkbox_use_userstyle, &QCheckBox::toggled, this, &InterfacePane::OnSaveConfig);
|
||||
}
|
||||
|
||||
void InterfacePane::LoadConfig()
|
||||
{
|
||||
const SConfig& startup_params = SConfig::GetInstance();
|
||||
m_checkbox_top_window->setChecked(Settings::Instance().IsKeepWindowOnTopEnabled());
|
||||
m_checkbox_use_builtin_title_database->setChecked(startup_params.m_use_builtin_title_database);
|
||||
m_checkbox_show_debugging_ui->setChecked(Settings::Instance().IsDebugModeEnabled());
|
||||
m_combobox_language->setCurrentIndex(m_combobox_language->findData(
|
||||
QString::fromStdString(SConfig::GetInstance().m_InterfaceLanguage)));
|
||||
m_combobox_theme->setCurrentIndex(
|
||||
m_combobox_theme->findText(QString::fromStdString(SConfig::GetInstance().theme_name)));
|
||||
|
||||
const QString userstyle = Settings::Instance().GetCurrentUserStyle();
|
||||
|
||||
if (userstyle.isEmpty())
|
||||
m_combobox_userstyle->setCurrentIndex(0);
|
||||
else
|
||||
m_combobox_userstyle->setCurrentText(userstyle);
|
||||
|
||||
m_checkbox_use_userstyle->setChecked(Settings::Instance().AreUserStylesEnabled());
|
||||
|
||||
const bool visible = m_checkbox_use_userstyle->isChecked();
|
||||
|
||||
m_combobox_userstyle->setVisible(visible);
|
||||
m_label_userstyle->setVisible(visible);
|
||||
|
||||
// In Game Options
|
||||
m_checkbox_confirm_on_stop->setChecked(startup_params.bConfirmStop);
|
||||
m_checkbox_use_panic_handlers->setChecked(startup_params.bUsePanicHandlers);
|
||||
m_checkbox_enable_osd->setChecked(startup_params.bOnScreenDisplayMessages);
|
||||
m_checkbox_show_active_title->setChecked(startup_params.m_show_active_title);
|
||||
m_checkbox_pause_on_focus_lost->setChecked(startup_params.m_PauseOnFocusLost);
|
||||
m_checkbox_hide_mouse->setChecked(Settings::Instance().GetHideCursor());
|
||||
}
|
||||
|
||||
void InterfacePane::OnSaveConfig()
|
||||
{
|
||||
SConfig& settings = SConfig::GetInstance();
|
||||
Settings::Instance().SetKeepWindowOnTop(m_checkbox_top_window->isChecked());
|
||||
settings.m_use_builtin_title_database = m_checkbox_use_builtin_title_database->isChecked();
|
||||
Settings::Instance().SetDebugModeEnabled(m_checkbox_show_debugging_ui->isChecked());
|
||||
Settings::Instance().SetCurrentUserStyle(m_combobox_userstyle->currentData().toString());
|
||||
Settings::Instance().SetUserStylesEnabled(m_checkbox_use_userstyle->isChecked());
|
||||
|
||||
const bool visible = m_checkbox_use_userstyle->isChecked();
|
||||
|
||||
m_combobox_userstyle->setVisible(visible);
|
||||
m_label_userstyle->setVisible(visible);
|
||||
|
||||
// In Game Options
|
||||
settings.bConfirmStop = m_checkbox_confirm_on_stop->isChecked();
|
||||
settings.bUsePanicHandlers = m_checkbox_use_panic_handlers->isChecked();
|
||||
settings.bOnScreenDisplayMessages = m_checkbox_enable_osd->isChecked();
|
||||
settings.m_show_active_title = m_checkbox_show_active_title->isChecked();
|
||||
settings.m_PauseOnFocusLost = m_checkbox_pause_on_focus_lost->isChecked();
|
||||
|
||||
SetEnableAlert(settings.bUsePanicHandlers);
|
||||
|
||||
auto new_language = m_combobox_language->currentData().toString().toStdString();
|
||||
if (new_language != SConfig::GetInstance().m_InterfaceLanguage)
|
||||
{
|
||||
SConfig::GetInstance().m_InterfaceLanguage = new_language;
|
||||
QMessageBox::information(
|
||||
this, tr("Restart Required"),
|
||||
tr("You must restart Dolphin in order for the change to take effect."));
|
||||
}
|
||||
|
||||
settings.SaveSettings();
|
||||
}
|
45
Source/Core/DolphinQt/Settings/InterfacePane.h
Normal file
45
Source/Core/DolphinQt/Settings/InterfacePane.h
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QVBoxLayout;
|
||||
|
||||
class InterfacePane final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InterfacePane(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
void CreateLayout();
|
||||
void CreateUI();
|
||||
void CreateInGame();
|
||||
void ConnectLayout();
|
||||
void LoadConfig();
|
||||
void OnSaveConfig();
|
||||
|
||||
QVBoxLayout* m_main_layout;
|
||||
QComboBox* m_combobox_language;
|
||||
|
||||
QComboBox* m_combobox_theme;
|
||||
QComboBox* m_combobox_userstyle;
|
||||
QLabel* m_label_userstyle;
|
||||
QCheckBox* m_checkbox_top_window;
|
||||
QCheckBox* m_checkbox_use_builtin_title_database;
|
||||
QCheckBox* m_checkbox_use_userstyle;
|
||||
QCheckBox* m_checkbox_show_debugging_ui;
|
||||
|
||||
QCheckBox* m_checkbox_confirm_on_stop;
|
||||
QCheckBox* m_checkbox_use_panic_handlers;
|
||||
QCheckBox* m_checkbox_enable_osd;
|
||||
QCheckBox* m_checkbox_show_active_title;
|
||||
QCheckBox* m_checkbox_pause_on_focus_lost;
|
||||
QCheckBox* m_checkbox_hide_mouse;
|
||||
};
|
203
Source/Core/DolphinQt/Settings/PathPane.cpp
Normal file
203
Source/Core/DolphinQt/Settings/PathPane.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
// Copyright 2015 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Common/Config/Config.h"
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include "DolphinQt/Settings.h"
|
||||
#include "DolphinQt/Settings/PathPane.h"
|
||||
|
||||
PathPane::PathPane(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
setWindowTitle(tr("Paths"));
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout;
|
||||
layout->addWidget(MakeGameFolderBox());
|
||||
layout->addLayout(MakePathsLayout());
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
|
||||
void PathPane::Browse()
|
||||
{
|
||||
QString dir = QDir::toNativeSeparators(
|
||||
QFileDialog::getExistingDirectory(this, tr("Select a Directory"), QDir::currentPath()));
|
||||
if (!dir.isEmpty())
|
||||
Settings::Instance().AddPath(dir);
|
||||
}
|
||||
|
||||
void PathPane::BrowseDefaultGame()
|
||||
{
|
||||
QString file = QDir::toNativeSeparators(QFileDialog::getOpenFileName(
|
||||
this, tr("Select a Game"), Settings::Instance().GetDefaultGame(),
|
||||
tr("All GC/Wii files (*.elf *.dol *.gcm *.iso *.tgc *.wbfs *.ciso *.gcz *.wad);;"
|
||||
"All Files (*)")));
|
||||
|
||||
if (!file.isEmpty())
|
||||
Settings::Instance().SetDefaultGame(file);
|
||||
}
|
||||
|
||||
void PathPane::BrowseWiiNAND()
|
||||
{
|
||||
QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(
|
||||
this, tr("Select Wii NAND Root"), QString::fromStdString(Config::Get(Config::MAIN_FS_PATH))));
|
||||
if (!dir.isEmpty())
|
||||
{
|
||||
m_nand_edit->setText(dir);
|
||||
OnNANDPathChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void PathPane::BrowseDump()
|
||||
{
|
||||
QString dir = QDir::toNativeSeparators(QFileDialog::getExistingDirectory(
|
||||
this, tr("Select Dump Path"), QString::fromStdString(Config::Get(Config::MAIN_DUMP_PATH))));
|
||||
if (!dir.isEmpty())
|
||||
{
|
||||
m_dump_edit->setText(dir);
|
||||
Config::SetBase(Config::MAIN_DUMP_PATH, dir.toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
void PathPane::BrowseSDCard()
|
||||
{
|
||||
QString file = QDir::toNativeSeparators(QFileDialog::getOpenFileName(
|
||||
this, tr("Select a SD Card Image"), QString::fromStdString(Config::Get(Config::MAIN_SD_PATH)),
|
||||
tr("SD Card Image (*.raw);;"
|
||||
"All Files (*)")));
|
||||
if (!file.isEmpty())
|
||||
{
|
||||
m_sdcard_edit->setText(file);
|
||||
OnSDCardPathChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void PathPane::OnSDCardPathChanged()
|
||||
{
|
||||
Config::SetBase(Config::MAIN_SD_PATH, m_sdcard_edit->text().toStdString());
|
||||
}
|
||||
|
||||
void PathPane::OnNANDPathChanged()
|
||||
{
|
||||
Config::SetBase(Config::MAIN_FS_PATH, m_nand_edit->text().toStdString());
|
||||
}
|
||||
|
||||
QGroupBox* PathPane::MakeGameFolderBox()
|
||||
{
|
||||
QGroupBox* game_box = new QGroupBox(tr("Game Folders"));
|
||||
QVBoxLayout* vlayout = new QVBoxLayout;
|
||||
|
||||
m_path_list = new QListWidget;
|
||||
m_path_list->insertItems(0, Settings::Instance().GetPaths());
|
||||
m_path_list->setSpacing(1);
|
||||
connect(&Settings::Instance(), &Settings::PathAdded,
|
||||
[this](const QString& dir) { m_path_list->addItem(dir); });
|
||||
connect(&Settings::Instance(), &Settings::PathRemoved, [this](const QString& dir) {
|
||||
auto items = m_path_list->findItems(dir, Qt::MatchExactly);
|
||||
for (auto& item : items)
|
||||
delete item;
|
||||
});
|
||||
connect(m_path_list, &QListWidget::itemSelectionChanged, this,
|
||||
[this] { m_remove_path->setEnabled(m_path_list->selectedItems().count()); });
|
||||
|
||||
vlayout->addWidget(m_path_list);
|
||||
|
||||
QHBoxLayout* hlayout = new QHBoxLayout;
|
||||
|
||||
hlayout->addStretch();
|
||||
QPushButton* add = new QPushButton(tr("Add..."));
|
||||
m_remove_path = new QPushButton(tr("Remove"));
|
||||
|
||||
m_remove_path->setEnabled(false);
|
||||
|
||||
auto* recursive_checkbox = new QCheckBox(tr("Search Subfolders"));
|
||||
recursive_checkbox->setChecked(SConfig::GetInstance().m_RecursiveISOFolder);
|
||||
|
||||
auto* auto_checkbox = new QCheckBox(tr("Check for Game List Changes in the Background"));
|
||||
auto_checkbox->setChecked(Settings::Instance().IsAutoRefreshEnabled());
|
||||
|
||||
hlayout->addWidget(add);
|
||||
hlayout->addWidget(m_remove_path);
|
||||
vlayout->addLayout(hlayout);
|
||||
vlayout->addWidget(recursive_checkbox);
|
||||
vlayout->addWidget(auto_checkbox);
|
||||
|
||||
connect(recursive_checkbox, &QCheckBox::toggled, this, [](bool checked) {
|
||||
SConfig::GetInstance().m_RecursiveISOFolder = checked;
|
||||
Settings::Instance().RefreshGameList();
|
||||
});
|
||||
|
||||
connect(auto_checkbox, &QCheckBox::toggled, &Settings::Instance(),
|
||||
&Settings::SetAutoRefreshEnabled);
|
||||
|
||||
connect(add, &QPushButton::pressed, this, &PathPane::Browse);
|
||||
connect(m_remove_path, &QPushButton::pressed, this, &PathPane::RemovePath);
|
||||
|
||||
game_box->setLayout(vlayout);
|
||||
return game_box;
|
||||
}
|
||||
|
||||
QGridLayout* PathPane::MakePathsLayout()
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout;
|
||||
layout->setColumnStretch(1, 1);
|
||||
|
||||
m_game_edit = new QLineEdit(Settings::Instance().GetDefaultGame());
|
||||
connect(m_game_edit, &QLineEdit::editingFinished,
|
||||
[this] { Settings::Instance().SetDefaultGame(m_game_edit->text()); });
|
||||
connect(&Settings::Instance(), &Settings::DefaultGameChanged,
|
||||
[this](const QString& path) { m_game_edit->setText(path); });
|
||||
QPushButton* game_open = new QPushButton(QStringLiteral("..."));
|
||||
connect(game_open, &QPushButton::pressed, this, &PathPane::BrowseDefaultGame);
|
||||
layout->addWidget(new QLabel(tr("Default ISO:")), 0, 0);
|
||||
layout->addWidget(m_game_edit, 0, 1);
|
||||
layout->addWidget(game_open, 0, 2);
|
||||
|
||||
m_nand_edit = new QLineEdit(QString::fromStdString(Config::Get(Config::MAIN_FS_PATH)));
|
||||
connect(m_nand_edit, &QLineEdit::editingFinished, this, &PathPane::OnNANDPathChanged);
|
||||
QPushButton* nand_open = new QPushButton(QStringLiteral("..."));
|
||||
connect(nand_open, &QPushButton::pressed, this, &PathPane::BrowseWiiNAND);
|
||||
layout->addWidget(new QLabel(tr("Wii NAND Root:")), 1, 0);
|
||||
layout->addWidget(m_nand_edit, 1, 1);
|
||||
layout->addWidget(nand_open, 1, 2);
|
||||
|
||||
m_dump_edit = new QLineEdit(QString::fromStdString(Config::Get(Config::MAIN_DUMP_PATH)));
|
||||
connect(m_dump_edit, &QLineEdit::editingFinished,
|
||||
[=] { Config::SetBase(Config::MAIN_DUMP_PATH, m_dump_edit->text().toStdString()); });
|
||||
QPushButton* dump_open = new QPushButton(QStringLiteral("..."));
|
||||
connect(dump_open, &QPushButton::pressed, this, &PathPane::BrowseDump);
|
||||
layout->addWidget(new QLabel(tr("Dump Path:")), 2, 0);
|
||||
layout->addWidget(m_dump_edit, 2, 1);
|
||||
layout->addWidget(dump_open, 2, 2);
|
||||
|
||||
m_sdcard_edit = new QLineEdit(QString::fromStdString(Config::Get(Config::MAIN_SD_PATH)));
|
||||
connect(m_sdcard_edit, &QLineEdit::editingFinished, this, &PathPane::OnSDCardPathChanged);
|
||||
QPushButton* sdcard_open = new QPushButton(QStringLiteral("..."));
|
||||
connect(sdcard_open, &QPushButton::pressed, this, &PathPane::BrowseSDCard);
|
||||
layout->addWidget(new QLabel(tr("SD Card Path:")), 3, 0);
|
||||
layout->addWidget(m_sdcard_edit, 3, 1);
|
||||
layout->addWidget(sdcard_open, 3, 2);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void PathPane::RemovePath()
|
||||
{
|
||||
auto item = m_path_list->currentItem();
|
||||
if (!item)
|
||||
return;
|
||||
Settings::Instance().RemovePath(item->text());
|
||||
}
|
41
Source/Core/DolphinQt/Settings/PathPane.h
Normal file
41
Source/Core/DolphinQt/Settings/PathPane.h
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2015 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QGridLayout;
|
||||
class QGroupBox;
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
|
||||
class PathPane final : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PathPane(QWidget* parent = nullptr);
|
||||
|
||||
private:
|
||||
void Browse();
|
||||
void BrowseDefaultGame();
|
||||
void BrowseWiiNAND();
|
||||
void BrowseDump();
|
||||
void BrowseSDCard();
|
||||
QGroupBox* MakeGameFolderBox();
|
||||
QGridLayout* MakePathsLayout();
|
||||
void RemovePath();
|
||||
|
||||
void OnSDCardPathChanged();
|
||||
void OnNANDPathChanged();
|
||||
|
||||
QListWidget* m_path_list;
|
||||
QLineEdit* m_game_edit;
|
||||
QLineEdit* m_nand_edit;
|
||||
QLineEdit* m_dump_edit;
|
||||
QLineEdit* m_sdcard_edit;
|
||||
|
||||
QPushButton* m_remove_path;
|
||||
};
|
171
Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp
Normal file
171
Source/Core/DolphinQt/Settings/USBDeviceAddToWhitelistDialog.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h"
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QErrorMessage>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
|
||||
#include "DolphinQt/Settings/WiiPane.h"
|
||||
|
||||
#include "UICommon/USBUtils.h"
|
||||
|
||||
static bool IsValidUSBIDString(const std::string& string)
|
||||
{
|
||||
if (string.empty() || string.length() > 4)
|
||||
return false;
|
||||
return std::all_of(string.begin(), string.end(),
|
||||
[](const auto character) { return std::isxdigit(character) != 0; });
|
||||
}
|
||||
|
||||
USBDeviceAddToWhitelistDialog::USBDeviceAddToWhitelistDialog(QWidget* parent) : QDialog(parent)
|
||||
{
|
||||
InitControls();
|
||||
setLayout(main_layout);
|
||||
}
|
||||
|
||||
void USBDeviceAddToWhitelistDialog::InitControls()
|
||||
{
|
||||
setWindowTitle(tr("Add New USB Device"));
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
m_whitelist_buttonbox = new QDialogButtonBox();
|
||||
auto* add_button = new QPushButton(tr("Add"));
|
||||
m_whitelist_buttonbox->addButton(add_button, QDialogButtonBox::AcceptRole);
|
||||
connect(add_button, &QPushButton::clicked, this,
|
||||
&USBDeviceAddToWhitelistDialog::AddUSBDeviceToWhitelist);
|
||||
add_button->setDefault(true);
|
||||
|
||||
main_layout = new QVBoxLayout();
|
||||
enter_device_id_label = new QLabel(tr("Enter USB device ID"));
|
||||
enter_device_id_label->setAlignment(Qt::AlignCenter);
|
||||
main_layout->addWidget(enter_device_id_label);
|
||||
|
||||
entry_hbox_layout = new QHBoxLayout();
|
||||
device_vid_textbox = new QLineEdit();
|
||||
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
sizePolicy.setHorizontalStretch(1);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
sizePolicy.setHeightForWidth(device_vid_textbox->sizePolicy().hasHeightForWidth());
|
||||
device_vid_textbox->setSizePolicy(sizePolicy);
|
||||
|
||||
// entry_hbox_layout->setWidget(2, QFormLayout::LabelRole, device_vid_textbox);
|
||||
entry_hbox_layout->addWidget(device_vid_textbox);
|
||||
|
||||
device_pid_textbox = new QLineEdit();
|
||||
sizePolicy.setHeightForWidth(device_pid_textbox->sizePolicy().hasHeightForWidth());
|
||||
device_pid_textbox->setSizePolicy(sizePolicy);
|
||||
|
||||
entry_hbox_layout->addWidget(device_pid_textbox);
|
||||
main_layout->addLayout(entry_hbox_layout);
|
||||
|
||||
select_label = new QLabel(tr("or select a device"));
|
||||
select_label->setAlignment(Qt::AlignCenter);
|
||||
|
||||
main_layout->addWidget(select_label);
|
||||
|
||||
usb_inserted_devices_list = new QListWidget();
|
||||
m_refresh_devices_timer = new QTimer(this);
|
||||
connect(usb_inserted_devices_list, &QListWidget::currentItemChanged, this,
|
||||
&USBDeviceAddToWhitelistDialog::OnDeviceSelection);
|
||||
connect(m_refresh_devices_timer, &QTimer::timeout, this,
|
||||
&USBDeviceAddToWhitelistDialog::RefreshDeviceList);
|
||||
m_refresh_devices_timer->start(1000);
|
||||
|
||||
main_layout->addWidget(usb_inserted_devices_list);
|
||||
main_layout->addWidget(m_whitelist_buttonbox);
|
||||
|
||||
// i18n: VID means Vendor ID (in the context of a USB device)
|
||||
device_vid_textbox->setPlaceholderText(tr("Device VID (e.g., 057e)"));
|
||||
// i18n: PID means Product ID (in the context of a USB device), not Process ID
|
||||
device_pid_textbox->setPlaceholderText(tr("Device PID (e.g., 0305)"));
|
||||
}
|
||||
|
||||
void USBDeviceAddToWhitelistDialog::RefreshDeviceList()
|
||||
{
|
||||
const auto& current_devices = USBUtils::GetInsertedDevices();
|
||||
if (current_devices == m_shown_devices)
|
||||
return;
|
||||
const auto selection_string = usb_inserted_devices_list->currentItem();
|
||||
usb_inserted_devices_list->clear();
|
||||
for (const auto& device : current_devices)
|
||||
{
|
||||
if (SConfig::GetInstance().IsUSBDeviceWhitelisted(device.first))
|
||||
continue;
|
||||
usb_inserted_devices_list->addItem(QString::fromStdString(device.second));
|
||||
}
|
||||
|
||||
usb_inserted_devices_list->setCurrentItem(selection_string);
|
||||
|
||||
m_shown_devices = current_devices;
|
||||
}
|
||||
|
||||
void USBDeviceAddToWhitelistDialog::AddUSBDeviceToWhitelist()
|
||||
{
|
||||
const std::string vid_string = StripSpaces(device_vid_textbox->text().toStdString());
|
||||
const std::string pid_string = StripSpaces(device_pid_textbox->text().toStdString());
|
||||
if (!IsValidUSBIDString(vid_string))
|
||||
{
|
||||
// i18n: Here, VID means Vendor ID (for a USB device).
|
||||
QMessageBox vid_warning_box;
|
||||
vid_warning_box.setIcon(QMessageBox::Warning);
|
||||
vid_warning_box.setWindowTitle(tr("USB Whitelist Error"));
|
||||
vid_warning_box.setText(tr("The entered VID is invalid."));
|
||||
vid_warning_box.setStandardButtons(QMessageBox::Ok);
|
||||
vid_warning_box.exec();
|
||||
return;
|
||||
}
|
||||
if (!IsValidUSBIDString(pid_string))
|
||||
{
|
||||
// i18n: Here, PID means Product ID (for a USB device).
|
||||
QMessageBox pid_warning_box;
|
||||
pid_warning_box.setIcon(QMessageBox::Warning);
|
||||
pid_warning_box.setWindowTitle(tr("USB Whitelist Error"));
|
||||
pid_warning_box.setText(tr("The entered PID is invalid."));
|
||||
pid_warning_box.setStandardButtons(QMessageBox::Ok);
|
||||
pid_warning_box.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
const u16 vid = static_cast<u16>(std::stoul(vid_string, nullptr, 16));
|
||||
const u16 pid = static_cast<u16>(std::stoul(pid_string, nullptr, 16));
|
||||
|
||||
if (SConfig::GetInstance().IsUSBDeviceWhitelisted({vid, pid}))
|
||||
{
|
||||
QErrorMessage* error = new QErrorMessage();
|
||||
error->showMessage(tr("This USB device is already whitelisted."));
|
||||
return;
|
||||
}
|
||||
SConfig::GetInstance().m_usb_passthrough_devices.emplace(vid, pid);
|
||||
SConfig::GetInstance().SaveSettings();
|
||||
accept();
|
||||
}
|
||||
|
||||
void USBDeviceAddToWhitelistDialog::OnDeviceSelection()
|
||||
{
|
||||
// Not the nicest way of doing this but...
|
||||
QString device = usb_inserted_devices_list->currentItem()->text().left(9);
|
||||
QString* vid = new QString(
|
||||
device.split(QString::fromStdString(":"), QString::SplitBehavior::KeepEmptyParts)[0]);
|
||||
QString* pid = new QString(
|
||||
device.split(QString::fromStdString(":"), QString::SplitBehavior::KeepEmptyParts)[1]);
|
||||
device_vid_textbox->setText(*vid);
|
||||
device_pid_textbox->setText(*pid);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QTimer;
|
||||
class QDialog;
|
||||
class QButtonGroup;
|
||||
class QHeaderView;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QDialogButtonBox;
|
||||
class QVBoxLayout;
|
||||
class QHBoxLayout;
|
||||
class QListView;
|
||||
class QPushButton;
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
class QErrorMessage;
|
||||
class QMessageBox;
|
||||
|
||||
class USBDeviceAddToWhitelistDialog final : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit USBDeviceAddToWhitelistDialog(QWidget* parent);
|
||||
|
||||
private:
|
||||
static constexpr int DEVICE_REFRESH_INTERVAL_MS = 100;
|
||||
QTimer* m_refresh_devices_timer;
|
||||
QDialogButtonBox* m_whitelist_buttonbox;
|
||||
QVBoxLayout* main_layout;
|
||||
QLabel* enter_device_id_label;
|
||||
QHBoxLayout* entry_hbox_layout;
|
||||
QLineEdit* device_vid_textbox;
|
||||
QLineEdit* device_pid_textbox;
|
||||
QLabel* select_label;
|
||||
QListWidget* usb_inserted_devices_list;
|
||||
|
||||
void InitControls();
|
||||
void RefreshDeviceList();
|
||||
void AddUSBDeviceToWhitelist();
|
||||
|
||||
void OnDeviceSelection();
|
||||
|
||||
std::map<std::pair<quint16, quint16>, std::string> m_shown_devices;
|
||||
};
|
272
Source/Core/DolphinQt/Settings/WiiPane.cpp
Normal file
272
Source/Core/DolphinQt/Settings/WiiPane.cpp
Normal file
@ -0,0 +1,272 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "DolphinQt/Settings/WiiPane.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QSlider>
|
||||
#include <QSpacerItem>
|
||||
#include <QStringList>
|
||||
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "Core/Config/SYSCONFSettings.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
|
||||
#include "DolphinQt/Settings/USBDeviceAddToWhitelistDialog.h"
|
||||
|
||||
#include "UICommon/USBUtils.h"
|
||||
|
||||
// SYSCONF uses 0 for bottom and 1 for top, but we place them in
|
||||
// the other order in the GUI so that Top will be above Bottom,
|
||||
// matching the respective physical placements of the sensor bar.
|
||||
// This also matches the layout of the settings in the Wii Menu.
|
||||
static int TranslateSensorBarPosition(int position)
|
||||
{
|
||||
if (position == 0)
|
||||
return 1;
|
||||
if (position == 1)
|
||||
return 0;
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
WiiPane::WiiPane(QWidget* parent) : QWidget(parent)
|
||||
{
|
||||
CreateLayout();
|
||||
LoadConfig();
|
||||
ConnectLayout();
|
||||
ValidateSelectionState();
|
||||
}
|
||||
|
||||
void WiiPane::CreateLayout()
|
||||
{
|
||||
m_main_layout = new QVBoxLayout;
|
||||
CreateMisc();
|
||||
CreateWhitelistedUSBPassthroughDevices();
|
||||
CreateWiiRemoteSettings();
|
||||
m_main_layout->addStretch(1);
|
||||
setLayout(m_main_layout);
|
||||
}
|
||||
|
||||
void WiiPane::ConnectLayout()
|
||||
{
|
||||
// Misc Settings
|
||||
connect(m_aspect_ratio_choice,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&WiiPane::OnSaveConfig);
|
||||
connect(m_system_language_choice,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&WiiPane::OnSaveConfig);
|
||||
connect(m_screensaver_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
|
||||
connect(m_pal60_mode_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
|
||||
connect(m_sd_card_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
|
||||
connect(m_connect_keyboard_checkbox, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
|
||||
|
||||
// Whitelisted USB Passthrough Devices
|
||||
connect(m_whitelist_usb_list, &QListWidget::itemClicked, this, &WiiPane::ValidateSelectionState);
|
||||
connect(m_whitelist_usb_add_button, &QPushButton::pressed, this,
|
||||
&WiiPane::OnUSBWhitelistAddButton);
|
||||
connect(m_whitelist_usb_remove_button, &QPushButton::pressed, this,
|
||||
&WiiPane::OnUSBWhitelistRemoveButton);
|
||||
|
||||
// Wii Remote Settings
|
||||
connect(m_wiimote_ir_sensor_position,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||
&WiiPane::OnSaveConfig);
|
||||
connect(m_wiimote_ir_sensitivity, &QSlider::valueChanged, this, &WiiPane::OnSaveConfig);
|
||||
connect(m_wiimote_speaker_volume, &QSlider::valueChanged, this, &WiiPane::OnSaveConfig);
|
||||
connect(m_wiimote_motor, &QCheckBox::toggled, this, &WiiPane::OnSaveConfig);
|
||||
}
|
||||
|
||||
void WiiPane::CreateMisc()
|
||||
{
|
||||
auto* misc_settings_group = new QGroupBox(tr("Misc Settings"));
|
||||
auto* misc_settings_group_layout = new QGridLayout();
|
||||
misc_settings_group->setLayout(misc_settings_group_layout);
|
||||
m_main_layout->addWidget(misc_settings_group);
|
||||
m_pal60_mode_checkbox = new QCheckBox(tr("Use PAL60 Mode (EuRGB60)"));
|
||||
m_screensaver_checkbox = new QCheckBox(tr("Enable Screen Saver"));
|
||||
m_sd_card_checkbox = new QCheckBox(tr("Insert SD Card"));
|
||||
m_connect_keyboard_checkbox = new QCheckBox(tr("Connect USB Keyboard"));
|
||||
m_aspect_ratio_choice_label = new QLabel(tr("Aspect Ratio:"));
|
||||
m_aspect_ratio_choice = new QComboBox();
|
||||
m_aspect_ratio_choice->addItem(tr("4:3"));
|
||||
m_aspect_ratio_choice->addItem(tr("16:9"));
|
||||
m_system_language_choice_label = new QLabel(tr("System Language:"));
|
||||
m_system_language_choice = new QComboBox();
|
||||
m_system_language_choice->addItem(tr("Japanese"));
|
||||
m_system_language_choice->addItem(tr("English"));
|
||||
m_system_language_choice->addItem(tr("German"));
|
||||
m_system_language_choice->addItem(tr("French"));
|
||||
m_system_language_choice->addItem(tr("Spanish"));
|
||||
m_system_language_choice->addItem(tr("Italian"));
|
||||
m_system_language_choice->addItem(tr("Dutch"));
|
||||
m_system_language_choice->addItem(tr("Simplified Chinese"));
|
||||
m_system_language_choice->addItem(tr("Traditional Chinese"));
|
||||
m_system_language_choice->addItem(tr("Korean"));
|
||||
|
||||
m_pal60_mode_checkbox->setToolTip(tr("Sets the Wii display mode to 60Hz (480i) instead of 50Hz "
|
||||
"(576i) for PAL games.\nMay not work for all games."));
|
||||
m_screensaver_checkbox->setToolTip(tr("Dims the screen after five minutes of inactivity."));
|
||||
m_system_language_choice->setToolTip(tr("Sets the Wii system language."));
|
||||
m_sd_card_checkbox->setToolTip(tr("Saved to /Wii/sd.raw (default size is 128mb)."));
|
||||
m_connect_keyboard_checkbox->setToolTip(tr("May cause slow down in Wii Menu and some games."));
|
||||
|
||||
misc_settings_group_layout->addWidget(m_pal60_mode_checkbox, 0, 0, 1, 1);
|
||||
misc_settings_group_layout->addWidget(m_sd_card_checkbox, 0, 1, 1, 1);
|
||||
misc_settings_group_layout->addWidget(m_screensaver_checkbox, 1, 0, 1, 1);
|
||||
misc_settings_group_layout->addWidget(m_connect_keyboard_checkbox, 1, 1, 1, 1);
|
||||
misc_settings_group_layout->addWidget(m_aspect_ratio_choice_label, 2, 0, 1, 1);
|
||||
misc_settings_group_layout->addWidget(m_aspect_ratio_choice, 2, 1, 1, 1);
|
||||
misc_settings_group_layout->addWidget(m_system_language_choice_label, 3, 0, 1, 1);
|
||||
misc_settings_group_layout->addWidget(m_system_language_choice, 3, 1, 1, 1);
|
||||
}
|
||||
|
||||
void WiiPane::CreateWhitelistedUSBPassthroughDevices()
|
||||
{
|
||||
auto* whitelisted_usb_passthrough_devices_group =
|
||||
new QGroupBox(tr("Whitelisted USB Passthrough Devices"));
|
||||
auto* whitelist_layout = new QGridLayout();
|
||||
m_whitelist_usb_list = new QListWidget();
|
||||
whitelist_layout->addWidget(m_whitelist_usb_list, 0, 0, 1, -1);
|
||||
whitelist_layout->setColumnStretch(0, 1);
|
||||
m_whitelist_usb_add_button = new QPushButton(tr("Add..."));
|
||||
m_whitelist_usb_remove_button = new QPushButton(tr("Remove"));
|
||||
whitelist_layout->addWidget(m_whitelist_usb_add_button, 1, 1);
|
||||
whitelist_layout->addWidget(m_whitelist_usb_remove_button, 1, 2);
|
||||
whitelist_layout->addWidget(m_whitelist_usb_list, 0, 0);
|
||||
whitelisted_usb_passthrough_devices_group->setLayout(whitelist_layout);
|
||||
m_main_layout->addWidget(whitelisted_usb_passthrough_devices_group);
|
||||
}
|
||||
|
||||
void WiiPane::CreateWiiRemoteSettings()
|
||||
{
|
||||
auto* wii_remote_settings_group = new QGroupBox(tr("Wii Remote Settings"));
|
||||
auto* wii_remote_settings_group_layout = new QGridLayout();
|
||||
wii_remote_settings_group->setLayout(wii_remote_settings_group_layout);
|
||||
m_main_layout->addWidget(wii_remote_settings_group);
|
||||
m_wiimote_motor = new QCheckBox(tr("Wii Remote Rumble"));
|
||||
|
||||
m_wiimote_sensor_position_label = new QLabel(tr("Sensor Bar Position:"));
|
||||
m_wiimote_ir_sensor_position = new QComboBox();
|
||||
m_wiimote_ir_sensor_position->addItem(tr("Top"));
|
||||
m_wiimote_ir_sensor_position->addItem(tr("Bottom"));
|
||||
|
||||
// IR Sensitivity Slider
|
||||
m_wiimote_ir_sensitivity_label = new QLabel(tr("IR Sensitivity:"));
|
||||
m_wiimote_ir_sensitivity = new QSlider(Qt::Horizontal);
|
||||
m_wiimote_ir_sensitivity->setMinimum(4);
|
||||
m_wiimote_ir_sensitivity->setMaximum(127);
|
||||
|
||||
// Speaker Volume Slider
|
||||
m_wiimote_speaker_volume_label = new QLabel(tr("Speaker Volume:"));
|
||||
m_wiimote_speaker_volume = new QSlider(Qt::Horizontal);
|
||||
m_wiimote_speaker_volume->setMinimum(0);
|
||||
m_wiimote_speaker_volume->setMaximum(127);
|
||||
|
||||
wii_remote_settings_group_layout->addWidget(m_wiimote_sensor_position_label, 0, 0);
|
||||
wii_remote_settings_group_layout->addWidget(m_wiimote_ir_sensor_position, 0, 1);
|
||||
wii_remote_settings_group_layout->addWidget(m_wiimote_ir_sensitivity_label, 1, 0);
|
||||
wii_remote_settings_group_layout->addWidget(m_wiimote_ir_sensitivity, 1, 1);
|
||||
wii_remote_settings_group_layout->addWidget(m_wiimote_speaker_volume_label, 2, 0);
|
||||
wii_remote_settings_group_layout->addWidget(m_wiimote_speaker_volume, 2, 1);
|
||||
wii_remote_settings_group_layout->addWidget(m_wiimote_motor, 3, 0, 1, -1);
|
||||
}
|
||||
|
||||
void WiiPane::OnEmulationStateChanged(bool running)
|
||||
{
|
||||
m_screensaver_checkbox->setEnabled(!running);
|
||||
m_pal60_mode_checkbox->setEnabled(!running);
|
||||
m_sd_card_checkbox->setEnabled(!running);
|
||||
m_connect_keyboard_checkbox->setEnabled(!running);
|
||||
m_system_language_choice->setEnabled(!running);
|
||||
m_aspect_ratio_choice->setEnabled(!running);
|
||||
m_wiimote_motor->setEnabled(!running);
|
||||
m_wiimote_speaker_volume->setEnabled(!running);
|
||||
m_wiimote_ir_sensitivity->setEnabled(!running);
|
||||
m_wiimote_ir_sensor_position->setEnabled(!running);
|
||||
}
|
||||
|
||||
void WiiPane::LoadConfig()
|
||||
{
|
||||
m_screensaver_checkbox->setChecked(Config::Get(Config::SYSCONF_SCREENSAVER));
|
||||
m_pal60_mode_checkbox->setChecked(Config::Get(Config::SYSCONF_PAL60));
|
||||
m_connect_keyboard_checkbox->setChecked(SConfig::GetInstance().m_WiiKeyboard);
|
||||
m_sd_card_checkbox->setChecked(SConfig::GetInstance().m_WiiSDCard);
|
||||
m_aspect_ratio_choice->setCurrentIndex(Config::Get(Config::SYSCONF_WIDESCREEN));
|
||||
m_system_language_choice->setCurrentIndex(Config::Get(Config::SYSCONF_LANGUAGE));
|
||||
|
||||
PopulateUSBPassthroughListWidget();
|
||||
|
||||
m_wiimote_ir_sensor_position->setCurrentIndex(
|
||||
TranslateSensorBarPosition(Config::Get(Config::SYSCONF_SENSOR_BAR_POSITION)));
|
||||
m_wiimote_ir_sensitivity->setValue(Config::Get(Config::SYSCONF_SENSOR_BAR_SENSITIVITY));
|
||||
m_wiimote_speaker_volume->setValue(Config::Get(Config::SYSCONF_SPEAKER_VOLUME));
|
||||
m_wiimote_motor->setChecked(Config::Get(Config::SYSCONF_WIIMOTE_MOTOR));
|
||||
}
|
||||
|
||||
void WiiPane::OnSaveConfig()
|
||||
{
|
||||
Config::SetBase(Config::SYSCONF_SCREENSAVER, m_screensaver_checkbox->isChecked());
|
||||
Config::SetBase(Config::SYSCONF_PAL60, m_pal60_mode_checkbox->isChecked());
|
||||
SConfig::GetInstance().m_WiiKeyboard = m_connect_keyboard_checkbox->isChecked();
|
||||
SConfig::GetInstance().m_WiiSDCard = m_sd_card_checkbox->isChecked();
|
||||
Config::SetBase<u32>(Config::SYSCONF_SENSOR_BAR_POSITION,
|
||||
TranslateSensorBarPosition(m_wiimote_ir_sensor_position->currentIndex()));
|
||||
Config::SetBase<u32>(Config::SYSCONF_SENSOR_BAR_SENSITIVITY, m_wiimote_ir_sensitivity->value());
|
||||
Config::SetBase<u32>(Config::SYSCONF_SPEAKER_VOLUME, m_wiimote_speaker_volume->value());
|
||||
Config::SetBase<u32>(Config::SYSCONF_LANGUAGE, m_system_language_choice->currentIndex());
|
||||
Config::SetBase<bool>(Config::SYSCONF_WIDESCREEN, m_aspect_ratio_choice->currentIndex());
|
||||
Config::SetBase(Config::SYSCONF_WIIMOTE_MOTOR, m_wiimote_motor->isChecked());
|
||||
}
|
||||
|
||||
void WiiPane::ValidateSelectionState()
|
||||
{
|
||||
m_whitelist_usb_remove_button->setEnabled(m_whitelist_usb_list->currentIndex().isValid());
|
||||
}
|
||||
|
||||
void WiiPane::OnUSBWhitelistAddButton()
|
||||
{
|
||||
USBDeviceAddToWhitelistDialog* usb_whitelist_dialog = new USBDeviceAddToWhitelistDialog(this);
|
||||
connect(usb_whitelist_dialog, &USBDeviceAddToWhitelistDialog::accepted, this,
|
||||
&WiiPane::PopulateUSBPassthroughListWidget);
|
||||
usb_whitelist_dialog->setModal(true);
|
||||
usb_whitelist_dialog->show();
|
||||
}
|
||||
|
||||
void WiiPane::OnUSBWhitelistRemoveButton()
|
||||
{
|
||||
QString device = m_whitelist_usb_list->currentItem()->text().left(9);
|
||||
QString vid =
|
||||
QString(device.split(QString::fromStdString(":"), QString::SplitBehavior::KeepEmptyParts)[0]);
|
||||
QString pid =
|
||||
QString(device.split(QString::fromStdString(":"), QString::SplitBehavior::KeepEmptyParts)[1]);
|
||||
const u16 vid_u16 = static_cast<u16>(std::stoul(vid.toStdString(), nullptr, 16));
|
||||
const u16 pid_u16 = static_cast<u16>(std::stoul(pid.toStdString(), nullptr, 16));
|
||||
SConfig::GetInstance().m_usb_passthrough_devices.erase({vid_u16, pid_u16});
|
||||
PopulateUSBPassthroughListWidget();
|
||||
}
|
||||
|
||||
void WiiPane::PopulateUSBPassthroughListWidget()
|
||||
{
|
||||
m_whitelist_usb_list->clear();
|
||||
for (const auto& device : SConfig::GetInstance().m_usb_passthrough_devices)
|
||||
{
|
||||
QListWidgetItem* usb_lwi =
|
||||
new QListWidgetItem(QString::fromStdString(USBUtils::GetDeviceName(device)));
|
||||
m_whitelist_usb_list->addItem(usb_lwi);
|
||||
}
|
||||
ValidateSelectionState();
|
||||
}
|
66
Source/Core/DolphinQt/Settings/WiiPane.h
Normal file
66
Source/Core/DolphinQt/Settings/WiiPane.h
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright 2017 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class QLabel;
|
||||
class QSlider;
|
||||
class QVBoxLayout;
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
class QComboBox;
|
||||
class QCheckBox;
|
||||
|
||||
class WiiPane : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WiiPane(QWidget* parent = nullptr);
|
||||
void OnEmulationStateChanged(bool running);
|
||||
|
||||
private:
|
||||
void PopulateUSBPassthroughListWidget();
|
||||
void CreateLayout();
|
||||
void ConnectLayout();
|
||||
void CreateMisc();
|
||||
void CreateWhitelistedUSBPassthroughDevices();
|
||||
void CreateWiiRemoteSettings();
|
||||
|
||||
void LoadConfig();
|
||||
void OnSaveConfig();
|
||||
|
||||
void ValidateSelectionState();
|
||||
|
||||
void OnUSBWhitelistAddButton();
|
||||
void OnUSBWhitelistRemoveButton();
|
||||
|
||||
// Widgets
|
||||
QVBoxLayout* m_main_layout;
|
||||
|
||||
// Misc Settings
|
||||
QCheckBox* m_screensaver_checkbox;
|
||||
QCheckBox* m_pal60_mode_checkbox;
|
||||
QCheckBox* m_sd_card_checkbox;
|
||||
QCheckBox* m_connect_keyboard_checkbox;
|
||||
QComboBox* m_system_language_choice;
|
||||
QLabel* m_system_language_choice_label;
|
||||
QComboBox* m_aspect_ratio_choice;
|
||||
QLabel* m_aspect_ratio_choice_label;
|
||||
|
||||
// Whitelisted USB Passthrough Devices
|
||||
QListWidget* m_whitelist_usb_list;
|
||||
QPushButton* m_whitelist_usb_add_button;
|
||||
QPushButton* m_whitelist_usb_remove_button;
|
||||
|
||||
// Wii Remote Settings
|
||||
QLabel* m_wiimote_sensor_position_label;
|
||||
QComboBox* m_wiimote_ir_sensor_position;
|
||||
QSlider* m_wiimote_ir_sensitivity;
|
||||
QLabel* m_wiimote_ir_sensitivity_label;
|
||||
QSlider* m_wiimote_speaker_volume;
|
||||
QLabel* m_wiimote_speaker_volume_label;
|
||||
QCheckBox* m_wiimote_motor;
|
||||
};
|
Reference in New Issue
Block a user