summaryrefslogtreecommitdiff
path: root/src/yuzu/configuration
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu/configuration')
-rw-r--r--src/yuzu/configuration/config.cpp20
-rw-r--r--src/yuzu/configuration/config.h2
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp9
-rw-r--r--src/yuzu/configuration/configure_cpu.h1
-rw-r--r--src/yuzu/configuration/configure_cpu.ui12
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp8
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui29
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp2
-rw-r--r--src/yuzu/configuration/configure_filesystem.cpp16
-rw-r--r--src/yuzu/configuration/configure_filesystem.h8
-rw-r--r--src/yuzu/configuration/configure_general.cpp11
-rw-r--r--src/yuzu/configuration/configure_general.h1
-rw-r--r--src/yuzu/configuration/configure_general.ui14
-rw-r--r--src/yuzu/configuration/configure_hotkeys.cpp32
-rw-r--r--src/yuzu/configuration/configure_input.cpp2
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp56
-rw-r--r--src/yuzu/configuration/configure_input_player_widget.cpp89
-rw-r--r--src/yuzu/configuration/configure_input_player_widget.h2
-rw-r--r--src/yuzu/configuration/configure_motion_touch.cpp38
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp10
-rw-r--r--src/yuzu/configuration/configure_touch_from_button.cpp3
-rw-r--r--src/yuzu/configuration/configure_vibration.cpp74
-rw-r--r--src/yuzu/configuration/configure_vibration.h18
-rw-r--r--src/yuzu/configuration/configure_vibration.ui7
24 files changed, 358 insertions, 106 deletions
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 2c8c10c50..4b943c6ba 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -65,23 +65,25 @@ const std::array<int, 2> Config::default_stick_mod = {
// This must be in alphabetical order according to action name as it must have the same order as
// UISetting::values.shortcuts, which is alphabetically ordered.
// clang-format off
-const std::array<UISettings::Shortcut, 20> Config::default_hotkeys{{
+const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{
{QStringLiteral("Audio Mute/Unmute"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}},
{QStringLiteral("Audio Volume Down"), QStringLiteral("Main Window"), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}},
{QStringLiteral("Audio Volume Up"), QStringLiteral("Main Window"), {QStringLiteral("+"), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}},
{QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}},
+ {QStringLiteral("Change Adapting Filter"), QStringLiteral("Main Window"), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}},
{QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Change GPU Accuracy"), QStringLiteral("Main Window"), {QStringLiteral("F9"), QStringLiteral("Home+R"), Qt::ApplicationShortcut}},
{QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), QStringLiteral("Home+Plus"), Qt::WindowShortcut}},
{QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), QStringLiteral(""), Qt::WindowShortcut}},
{QStringLiteral("Exit yuzu"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), QStringLiteral("Home+Minus"), Qt::WindowShortcut}},
{QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut}},
- {QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut}},
+ {QStringLiteral("Load/Remove Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut}},
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut}},
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut}},
- {QStringLiteral("TAS Start/Stop"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut}},
- {QStringLiteral("TAS Reset"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("TAS Record"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut}},
+ {QStringLiteral("TAS Reset"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut}},
+ {QStringLiteral("TAS Start/Stop"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), QStringLiteral(""), Qt::WindowShortcut}},
{QStringLiteral("Toggle Framerate Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+U"), QStringLiteral("Home+Y"), Qt::ApplicationShortcut}},
{QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F9"), QStringLiteral(""), Qt::ApplicationShortcut}},
@@ -443,6 +445,7 @@ void Config::ReadCoreValues() {
qt_config->beginGroup(QStringLiteral("Core"));
ReadGlobalSetting(Settings::values.use_multi_core);
+ ReadGlobalSetting(Settings::values.use_extended_memory_layout);
qt_config->endGroup();
}
@@ -606,6 +609,7 @@ void Config::ReadCpuValues() {
ReadGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
ReadGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan);
ReadGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
+ ReadGlobalSetting(Settings::values.cpuopt_unsafe_ignore_global_monitor);
if (global) {
ReadBasicSetting(Settings::values.cpu_debug_mode);
@@ -618,6 +622,8 @@ void Config::ReadCpuValues() {
ReadBasicSetting(Settings::values.cpuopt_misc_ir);
ReadBasicSetting(Settings::values.cpuopt_reduce_misalign_checks);
ReadBasicSetting(Settings::values.cpuopt_fastmem);
+ ReadBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
+ ReadBasicSetting(Settings::values.cpuopt_recompile_exclusives);
}
qt_config->endGroup();
@@ -767,6 +773,7 @@ void Config::ReadUIValues() {
ReadBasicSetting(UISettings::values.callout_flags);
ReadBasicSetting(UISettings::values.show_console);
ReadBasicSetting(UISettings::values.pause_when_in_background);
+ ReadBasicSetting(UISettings::values.mute_when_in_background);
ReadBasicSetting(UISettings::values.hide_mouse);
qt_config->endGroup();
@@ -1016,6 +1023,7 @@ void Config::SaveCoreValues() {
qt_config->beginGroup(QStringLiteral("Core"));
WriteGlobalSetting(Settings::values.use_multi_core);
+ WriteGlobalSetting(Settings::values.use_extended_memory_layout);
qt_config->endGroup();
}
@@ -1134,6 +1142,7 @@ void Config::SaveCpuValues() {
WriteGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
WriteGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan);
WriteGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
+ WriteGlobalSetting(Settings::values.cpuopt_unsafe_ignore_global_monitor);
if (global) {
WriteBasicSetting(Settings::values.cpu_debug_mode);
@@ -1146,6 +1155,8 @@ void Config::SaveCpuValues() {
WriteBasicSetting(Settings::values.cpuopt_misc_ir);
WriteBasicSetting(Settings::values.cpuopt_reduce_misalign_checks);
WriteBasicSetting(Settings::values.cpuopt_fastmem);
+ WriteBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
+ WriteBasicSetting(Settings::values.cpuopt_recompile_exclusives);
}
qt_config->endGroup();
@@ -1295,6 +1306,7 @@ void Config::SaveUIValues() {
WriteBasicSetting(UISettings::values.callout_flags);
WriteBasicSetting(UISettings::values.show_console);
WriteBasicSetting(UISettings::values.pause_when_in_background);
+ WriteBasicSetting(UISettings::values.mute_when_in_background);
WriteBasicSetting(UISettings::values.hide_mouse);
qt_config->endGroup();
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 60b20a62f..ae3e36a11 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -46,7 +46,7 @@ public:
default_mouse_buttons;
static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys;
static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods;
- static const std::array<UISettings::Shortcut, 20> default_hotkeys;
+ static const std::array<UISettings::Shortcut, 22> default_hotkeys;
static constexpr UISettings::Theme default_theme{
#ifdef _WIN32
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index f66cab5d4..bf74ccc7c 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -36,6 +36,7 @@ void ConfigureCpu::SetConfiguration() {
ui->cpuopt_unsafe_ignore_standard_fpcr->setEnabled(runtime_lock);
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
ui->cpuopt_unsafe_fastmem_check->setEnabled(runtime_lock);
+ ui->cpuopt_unsafe_ignore_global_monitor->setEnabled(runtime_lock);
ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue());
ui->cpuopt_unsafe_reduce_fp_error->setChecked(
@@ -46,6 +47,8 @@ void ConfigureCpu::SetConfiguration() {
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
ui->cpuopt_unsafe_fastmem_check->setChecked(
Settings::values.cpuopt_unsafe_fastmem_check.GetValue());
+ ui->cpuopt_unsafe_ignore_global_monitor->setChecked(
+ Settings::values.cpuopt_unsafe_ignore_global_monitor.GetValue());
if (Settings::IsConfiguringGlobal()) {
ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue()));
@@ -82,6 +85,9 @@ void ConfigureCpu::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check,
ui->cpuopt_unsafe_fastmem_check,
cpuopt_unsafe_fastmem_check);
+ ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_global_monitor,
+ ui->cpuopt_unsafe_ignore_global_monitor,
+ cpuopt_unsafe_ignore_global_monitor);
}
void ConfigureCpu::changeEvent(QEvent* event) {
@@ -120,4 +126,7 @@ void ConfigureCpu::SetupPerGameUI() {
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_fastmem_check,
Settings::values.cpuopt_unsafe_fastmem_check,
cpuopt_unsafe_fastmem_check);
+ ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_ignore_global_monitor,
+ Settings::values.cpuopt_unsafe_ignore_global_monitor,
+ cpuopt_unsafe_ignore_global_monitor);
}
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index ed9af0e9f..733e38be4 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -45,6 +45,7 @@ private:
ConfigurationShared::CheckState cpuopt_unsafe_ignore_standard_fpcr;
ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
ConfigurationShared::CheckState cpuopt_unsafe_fastmem_check;
+ ConfigurationShared::CheckState cpuopt_unsafe_ignore_global_monitor;
const Core::System& system;
};
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index d8064db24..5d80a8c91 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -150,6 +150,18 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_unsafe_ignore_global_monitor">
+ <property name="toolTip">
+ <string>
+ &lt;div&gt;This option improves speed by relying only on the semantics of cmpxchg to ensure safety of exclusive access instructions. Please note this may result in deadlocks and other race conditions.&lt;/div&gt;
+ </string>
+ </property>
+ <property name="text">
+ <string>Ignore global monitor</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index 05a90963d..616a0be75 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -44,6 +44,12 @@ void ConfigureCpuDebug::SetConfiguration() {
Settings::values.cpuopt_reduce_misalign_checks.GetValue());
ui->cpuopt_fastmem->setEnabled(runtime_lock);
ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem.GetValue());
+ ui->cpuopt_fastmem_exclusives->setEnabled(runtime_lock);
+ ui->cpuopt_fastmem_exclusives->setChecked(
+ Settings::values.cpuopt_fastmem_exclusives.GetValue());
+ ui->cpuopt_recompile_exclusives->setEnabled(runtime_lock);
+ ui->cpuopt_recompile_exclusives->setChecked(
+ Settings::values.cpuopt_recompile_exclusives.GetValue());
}
void ConfigureCpuDebug::ApplyConfiguration() {
@@ -56,6 +62,8 @@ void ConfigureCpuDebug::ApplyConfiguration() {
Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked();
+ Settings::values.cpuopt_fastmem_exclusives = ui->cpuopt_fastmem_exclusives->isChecked();
+ Settings::values.cpuopt_recompile_exclusives = ui->cpuopt_recompile_exclusives->isChecked();
}
void ConfigureCpuDebug::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
index 6e635bb2f..2bc268810 100644
--- a/src/yuzu/configuration/configure_cpu_debug.ui
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -144,7 +144,34 @@
</string>
</property>
<property name="text">
- <string>Enable Host MMU Emulation</string>
+ <string>Enable Host MMU Emulation (general memory instructions)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_fastmem_exclusives">
+ <property name="toolTip">
+ <string>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up exclusive memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it causes guest exclusive memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all exclusive memory accesses to use Software MMU Emulation.&lt;/div&gt;
+ </string>
+ </property>
+ <property name="text">
+ <string>Enable Host MMU Emulation (exclusive memory instructions)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="cpuopt_recompile_exclusives">
+ <property name="toolTip">
+ <string>
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up exclusive memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it reduces the overhead of fastmem failure of exclusive memory accesses.&lt;/div&gt;
+ </string>
+ </property>
+ <property name="text">
+ <string>Enable recompilation of exclusive memory instructions</string>
</property>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 464e7a489..19133ccf5 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -109,7 +109,7 @@ void ConfigureDialog::ApplyConfiguration() {
ui_tab->ApplyConfiguration();
system_tab->ApplyConfiguration();
profile_tab->ApplyConfiguration();
- filesystem_tab->applyConfiguration();
+ filesystem_tab->ApplyConfiguration();
input_tab->ApplyConfiguration();
hotkeys_tab->ApplyConfiguration(registry);
cpu_tab->ApplyConfiguration();
diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp
index 9cb317822..d6fb43f8b 100644
--- a/src/yuzu/configuration/configure_filesystem.cpp
+++ b/src/yuzu/configuration/configure_filesystem.cpp
@@ -14,7 +14,7 @@
ConfigureFilesystem::ConfigureFilesystem(QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureFilesystem>()) {
ui->setupUi(this);
- this->setConfiguration();
+ SetConfiguration();
connect(ui->nand_directory_button, &QToolButton::pressed, this,
[this] { SetDirectory(DirectoryTarget::NAND, ui->nand_directory_edit); });
@@ -38,7 +38,15 @@ ConfigureFilesystem::ConfigureFilesystem(QWidget* parent)
ConfigureFilesystem::~ConfigureFilesystem() = default;
-void ConfigureFilesystem::setConfiguration() {
+void ConfigureFilesystem::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QWidget::changeEvent(event);
+}
+
+void ConfigureFilesystem::SetConfiguration() {
ui->nand_directory_edit->setText(
QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir)));
ui->sdmc_directory_edit->setText(
@@ -60,7 +68,7 @@ void ConfigureFilesystem::setConfiguration() {
UpdateEnabledControls();
}
-void ConfigureFilesystem::applyConfiguration() {
+void ConfigureFilesystem::ApplyConfiguration() {
Common::FS::SetYuzuPath(Common::FS::YuzuPath::NANDDir,
ui->nand_directory_edit->text().toStdString());
Common::FS::SetYuzuPath(Common::FS::YuzuPath::SDMCDir,
@@ -143,6 +151,6 @@ void ConfigureFilesystem::UpdateEnabledControls() {
!ui->gamecard_current_game->isChecked());
}
-void ConfigureFilesystem::retranslateUi() {
+void ConfigureFilesystem::RetranslateUI() {
ui->retranslateUi(this);
}
diff --git a/src/yuzu/configuration/configure_filesystem.h b/src/yuzu/configuration/configure_filesystem.h
index 2147cd405..b4f9355eb 100644
--- a/src/yuzu/configuration/configure_filesystem.h
+++ b/src/yuzu/configuration/configure_filesystem.h
@@ -20,11 +20,13 @@ public:
explicit ConfigureFilesystem(QWidget* parent = nullptr);
~ConfigureFilesystem() override;
- void applyConfiguration();
- void retranslateUi();
+ void ApplyConfiguration();
private:
- void setConfiguration();
+ void changeEvent(QEvent* event) override;
+
+ void RetranslateUI();
+ void SetConfiguration();
enum class DirectoryTarget {
NAND,
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 566879317..08d5444ec 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -42,10 +42,14 @@ void ConfigureGeneral::SetConfiguration() {
ui->use_multi_core->setEnabled(runtime_lock);
ui->use_multi_core->setChecked(Settings::values.use_multi_core.GetValue());
+ ui->use_extended_memory_layout->setEnabled(runtime_lock);
+ ui->use_extended_memory_layout->setChecked(
+ Settings::values.use_extended_memory_layout.GetValue());
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing.GetValue());
ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot.GetValue());
ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background.GetValue());
+ ui->toggle_background_mute->setChecked(UISettings::values.mute_when_in_background.GetValue());
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue());
ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue());
@@ -90,11 +94,15 @@ void ConfigureGeneral::ResetDefaults() {
void ConfigureGeneral::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, ui->use_multi_core,
use_multi_core);
+ ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_extended_memory_layout,
+ ui->use_extended_memory_layout,
+ use_extended_memory_layout);
if (Settings::IsConfiguringGlobal()) {
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked();
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
+ UISettings::values.mute_when_in_background = ui->toggle_background_mute->isChecked();
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
Settings::values.fps_cap.SetValue(ui->fps_cap->value());
@@ -158,6 +166,9 @@ void ConfigureGeneral::SetupPerGameUI() {
Settings::values.use_speed_limit, use_speed_limit);
ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core,
use_multi_core);
+ ConfigurationShared::SetColoredTristate(ui->use_extended_memory_layout,
+ Settings::values.use_extended_memory_layout,
+ use_extended_memory_layout);
connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h
index 85c1dd4a8..b6f3bb5ed 100644
--- a/src/yuzu/configuration/configure_general.h
+++ b/src/yuzu/configuration/configure_general.h
@@ -48,6 +48,7 @@ private:
ConfigurationShared::CheckState use_speed_limit;
ConfigurationShared::CheckState use_multi_core;
+ ConfigurationShared::CheckState use_extended_memory_layout;
const Core::System& system;
};
diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui
index 112dc72b3..c6ef2ab70 100644
--- a/src/yuzu/configuration/configure_general.ui
+++ b/src/yuzu/configuration/configure_general.ui
@@ -143,6 +143,13 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="use_extended_memory_layout">
+ <property name="text">
+ <string>Extended memory layout (6GB DRAM)</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QCheckBox" name="toggle_check_exit">
<property name="text">
<string>Confirm exit while emulation is running</string>
@@ -164,6 +171,13 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="toggle_background_mute">
+ <property name="text">
+ <string>Mute audio when in background</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QCheckBox" name="toggle_hide_mouse">
<property name="text">
<string>Hide mouse on inactivity</string>
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp
index be10e0a31..53e629a5e 100644
--- a/src/yuzu/configuration/configure_hotkeys.cpp
+++ b/src/yuzu/configuration/configure_hotkeys.cpp
@@ -178,52 +178,52 @@ void ConfigureHotkeys::SetPollingResult(Core::HID::NpadButton button, const bool
QString ConfigureHotkeys::GetButtonName(Core::HID::NpadButton button) const {
Core::HID::NpadButtonState state{button};
if (state.a) {
- return tr("A");
+ return QStringLiteral("A");
}
if (state.b) {
- return tr("B");
+ return QStringLiteral("B");
}
if (state.x) {
- return tr("X");
+ return QStringLiteral("X");
}
if (state.y) {
- return tr("Y");
+ return QStringLiteral("Y");
}
if (state.l || state.right_sl || state.left_sl) {
- return tr("L");
+ return QStringLiteral("L");
}
if (state.r || state.right_sr || state.left_sr) {
- return tr("R");
+ return QStringLiteral("R");
}
if (state.zl) {
- return tr("ZL");
+ return QStringLiteral("ZL");
}
if (state.zr) {
- return tr("ZR");
+ return QStringLiteral("ZR");
}
if (state.left) {
- return tr("Dpad_Left");
+ return QStringLiteral("Dpad_Left");
}
if (state.right) {
- return tr("Dpad_Right");
+ return QStringLiteral("Dpad_Right");
}
if (state.up) {
- return tr("Dpad_Up");
+ return QStringLiteral("Dpad_Up");
}
if (state.down) {
- return tr("Dpad_Down");
+ return QStringLiteral("Dpad_Down");
}
if (state.stick_l) {
- return tr("Left_Stick");
+ return QStringLiteral("Left_Stick");
}
if (state.stick_r) {
- return tr("Right_Stick");
+ return QStringLiteral("Right_Stick");
}
if (state.minus) {
- return tr("Minus");
+ return QStringLiteral("Minus");
}
if (state.plus) {
- return tr("Plus");
+ return QStringLiteral("Plus");
}
return tr("Invalid");
}
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index d53179dbb..7c5776189 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -164,7 +164,7 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
});
connect(ui->vibrationButton, &QPushButton::clicked,
- [this] { CallConfigureDialog<ConfigureVibration>(*this); });
+ [this, &hid_core] { CallConfigureDialog<ConfigureVibration>(*this, hid_core); });
connect(ui->motionButton, &QPushButton::clicked, [this, input_subsystem] {
CallConfigureDialog<ConfigureMotionTouch>(*this, input_subsystem);
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 752504236..0aa4ac3e4 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -102,6 +102,10 @@ QString GetButtonName(Common::Input::ButtonNames button_name) {
return QObject::tr("Share");
case Common::Input::ButtonNames::Options:
return QObject::tr("Options");
+ case Common::Input::ButtonNames::Home:
+ return QObject::tr("Home");
+ case Common::Input::ButtonNames::Touch:
+ return QObject::tr("Touch");
case Common::Input::ButtonNames::ButtonMouseWheel:
return QObject::tr("Wheel", "Indicates the mouse wheel");
case Common::Input::ButtonNames::ButtonBackward:
@@ -326,7 +330,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
connect(button, &QPushButton::clicked, [=, this] {
HandleClick(
button, button_id,
- [=, this](Common::ParamPackage params) {
+ [=, this](const Common::ParamPackage& params) {
emulated_controller->SetButtonParam(button_id, params);
},
InputCommon::Polling::InputType::Button);
@@ -392,7 +396,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
connect(button, &QPushButton::clicked, [=, this] {
HandleClick(
button, motion_id,
- [=, this](Common::ParamPackage params) {
+ [=, this](const Common::ParamPackage& params) {
emulated_controller->SetMotionParam(motion_id, params);
},
InputCommon::Polling::InputType::Motion);
@@ -484,6 +488,32 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
emulated_controller->SetStickParam(analog_id, {});
analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]"));
});
+ context_menu.addAction(tr("Center axis"), [&] {
+ const auto stick_value =
+ emulated_controller->GetSticksValues()[analog_id];
+ const float offset_x = stick_value.x.properties.offset;
+ const float offset_y = stick_value.y.properties.offset;
+ float raw_value_x = stick_value.x.raw_value;
+ float raw_value_y = stick_value.y.raw_value;
+ // See Core::HID::SanitizeStick() to obtain the original raw axis value
+ if (std::abs(offset_x) < 0.5f) {
+ if (raw_value_x > 0) {
+ raw_value_x *= 1 + offset_x;
+ } else {
+ raw_value_x *= 1 - offset_x;
+ }
+ }
+ if (std::abs(offset_x) < 0.5f) {
+ if (raw_value_y > 0) {
+ raw_value_y *= 1 + offset_y;
+ } else {
+ raw_value_y *= 1 - offset_y;
+ }
+ }
+ param.Set("offset_x", -raw_value_x + offset_x);
+ param.Set("offset_y", -raw_value_y + offset_y);
+ emulated_controller->SetStickParam(analog_id, param);
+ });
context_menu.addAction(tr("Invert axis"), [&] {
if (sub_button_id == 2 || sub_button_id == 3) {
const bool invert_value = param.Get("invert_x", "+") == "-";
@@ -497,10 +527,11 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
param.Set("invert_y", invert_str);
emulated_controller->SetStickParam(analog_id, param);
}
- for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM;
- ++sub_button_id) {
- analog_map_buttons[analog_id][sub_button_id]->setText(
- AnalogToText(param, analog_sub_buttons[sub_button_id]));
+ for (int analog_sub_button_id = 0;
+ analog_sub_button_id < ANALOG_SUB_BUTTONS_NUM;
+ ++analog_sub_button_id) {
+ analog_map_buttons[analog_id][analog_sub_button_id]->setText(
+ AnalogToText(param, analog_sub_buttons[analog_sub_button_id]));
}
});
context_menu.exec(analog_map_buttons[analog_id][sub_button_id]->mapToGlobal(
@@ -783,7 +814,7 @@ void ConfigureInputPlayer::UpdateInputDeviceCombobox() {
if (devices.size() == 1) {
const auto devices_it = std::find_if(
input_devices.begin(), input_devices.end(),
- [first_engine, first_guid, first_port, first_pad](const Common::ParamPackage param) {
+ [first_engine, first_guid, first_port, first_pad](const Common::ParamPackage& param) {
return param.Get("engine", "") == first_engine &&
param.Get("guid", "") == first_guid && param.Get("port", 0) == first_port &&
param.Get("pad", 0) == first_pad;
@@ -814,7 +845,7 @@ void ConfigureInputPlayer::UpdateInputDeviceCombobox() {
if (is_engine_equal && is_port_equal) {
const auto devices_it = std::find_if(
input_devices.begin(), input_devices.end(),
- [first_engine, first_guid, second_guid, first_port](const Common::ParamPackage param) {
+ [first_engine, first_guid, second_guid, first_port](const Common::ParamPackage& param) {
const bool is_guid_valid =
(param.Get("guid", "") == first_guid &&
param.Get("guid2", "") == second_guid) ||
@@ -1026,7 +1057,7 @@ int ConfigureInputPlayer::GetIndexFromControllerType(Core::HID::NpadStyleIndex t
void ConfigureInputPlayer::UpdateInputDevices() {
input_devices = input_subsystem->GetInputDevices();
ui->comboDevices->clear();
- for (auto device : input_devices) {
+ for (const auto& device : input_devices) {
ui->comboDevices->addItem(QString::fromStdString(device.Get("display", "Unknown")), {});
}
}
@@ -1301,6 +1332,9 @@ void ConfigureInputPlayer::HandleClick(
QPushButton* button, std::size_t button_id,
std::function<void(const Common::ParamPackage&)> new_input_setter,
InputCommon::Polling::InputType type) {
+ if (timeout_timer->isActive()) {
+ return;
+ }
if (button == ui->buttonMotionLeft || button == ui->buttonMotionRight) {
button->setText(tr("Shake!"));
} else {
@@ -1308,7 +1342,7 @@ void ConfigureInputPlayer::HandleClick(
}
button->setFocus();
- input_setter = new_input_setter;
+ input_setter = std::move(new_input_setter);
input_subsystem->BeginMapping(type);
@@ -1358,7 +1392,7 @@ bool ConfigureInputPlayer::IsInputAcceptable(const Common::ParamPackage& params)
return params.Get("engine", "") == "keyboard" || params.Get("engine", "") == "mouse";
}
- const auto current_input_device = input_devices[ui->comboDevices->currentIndex()];
+ const auto& current_input_device = input_devices[ui->comboDevices->currentIndex()];
return params.Get("engine", "") == current_input_device.Get("engine", "") &&
(params.Get("guid", "") == current_input_device.Get("guid", "") ||
params.Get("guid", "") == current_input_device.Get("guid2", "")) &&
diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp
index 6630321cb..fb168b2ca 100644
--- a/src/yuzu/configuration/configure_input_player_widget.cpp
+++ b/src/yuzu/configuration/configure_input_player_widget.cpp
@@ -70,7 +70,6 @@ void PlayerControlPreview::UpdateColors() {
colors.slider_arrow = QColor(14, 15, 18);
colors.font2 = QColor(255, 255, 255);
colors.indicator = QColor(170, 238, 255);
- colors.indicator2 = QColor(100, 255, 100);
colors.deadzone = QColor(204, 136, 136);
colors.slider_button = colors.button;
}
@@ -88,7 +87,6 @@ void PlayerControlPreview::UpdateColors() {
colors.slider_arrow = QColor(65, 68, 73);
colors.font2 = QColor(0, 0, 0);
colors.indicator = QColor(0, 0, 200);
- colors.indicator2 = QColor(0, 150, 0);
colors.deadzone = QColor(170, 0, 0);
colors.slider_button = QColor(153, 149, 149);
}
@@ -101,6 +99,8 @@ void PlayerControlPreview::UpdateColors() {
colors.font = QColor(255, 255, 255);
colors.led_on = QColor(255, 255, 0);
colors.led_off = QColor(170, 238, 255);
+ colors.indicator2 = QColor(59, 165, 93);
+ colors.charging = QColor(250, 168, 26);
colors.left = colors.primary;
colors.right = colors.primary;
@@ -357,7 +357,7 @@ void PlayerControlPreview::DrawLeftController(QPainter& p, const QPointF center)
DrawCircle(p, center + QPoint(26, 71), 5);
// Draw battery
- DrawBattery(p, center + QPoint(-170, -140),
+ DrawBattery(p, center + QPoint(-160, -140),
battery_values[Core::HID::EmulatedDeviceIndex::LeftIndex]);
}
@@ -484,7 +484,7 @@ void PlayerControlPreview::DrawRightController(QPainter& p, const QPointF center
DrawSymbol(p, center + QPoint(-26, 66), Symbol::House, 5);
// Draw battery
- DrawBattery(p, center + QPoint(110, -140),
+ DrawBattery(p, center + QPoint(120, -140),
battery_values[Core::HID::EmulatedDeviceIndex::RightIndex]);
}
@@ -621,9 +621,9 @@ void PlayerControlPreview::DrawDualController(QPainter& p, const QPointF center)
DrawSymbol(p, center + QPoint(50, 60), Symbol::House, 4.2f);
// Draw battery
- DrawBattery(p, center + QPoint(-100, -160),
+ DrawBattery(p, center + QPoint(-200, -10),
battery_values[Core::HID::EmulatedDeviceIndex::LeftIndex]);
- DrawBattery(p, center + QPoint(40, -160),
+ DrawBattery(p, center + QPoint(160, -10),
battery_values[Core::HID::EmulatedDeviceIndex::RightIndex]);
}
@@ -694,12 +694,12 @@ void PlayerControlPreview::DrawHandheldController(QPainter& p, const QPointF cen
// ZL and ZR buttons
p.setPen(colors.outline);
- DrawTriggerButton(p, center + QPoint(-210, -130), Direction::Left, button_values[ZL]);
- DrawTriggerButton(p, center + QPoint(210, -130), Direction::Right, button_values[ZR]);
+ DrawTriggerButton(p, center + QPoint(-210, -120), Direction::Left, button_values[ZL]);
+ DrawTriggerButton(p, center + QPoint(210, -120), Direction::Right, button_values[ZR]);
p.setPen(colors.transparent);
p.setBrush(colors.font);
- DrawSymbol(p, center + QPoint(-210, -130), Symbol::ZL, 1.5f);
- DrawSymbol(p, center + QPoint(210, -130), Symbol::ZR, 1.5f);
+ DrawSymbol(p, center + QPoint(-210, -120), Symbol::ZL, 1.5f);
+ DrawSymbol(p, center + QPoint(210, -120), Symbol::ZR, 1.5f);
// Minus and Plus button
p.setPen(colors.outline);
@@ -725,9 +725,9 @@ void PlayerControlPreview::DrawHandheldController(QPainter& p, const QPointF cen
DrawSymbol(p, center + QPoint(161, 37), Symbol::House, 2.75f);
// Draw battery
- DrawBattery(p, center + QPoint(-200, 110),
+ DrawBattery(p, center + QPoint(-188, 95),
battery_values[Core::HID::EmulatedDeviceIndex::LeftIndex]);
- DrawBattery(p, center + QPoint(130, 110),
+ DrawBattery(p, center + QPoint(150, 95),
battery_values[Core::HID::EmulatedDeviceIndex::RightIndex]);
}
@@ -781,12 +781,12 @@ void PlayerControlPreview::DrawProController(QPainter& p, const QPointF center)
// ZL and ZR buttons
p.setPen(colors.outline);
- DrawTriggerButton(p, center + QPoint(-210, -130), Direction::Left, button_values[ZL]);
- DrawTriggerButton(p, center + QPoint(210, -130), Direction::Right, button_values[ZR]);
+ DrawTriggerButton(p, center + QPoint(-210, -120), Direction::Left, button_values[ZL]);
+ DrawTriggerButton(p, center + QPoint(210, -120), Direction::Right, button_values[ZR]);
p.setPen(colors.transparent);
p.setBrush(colors.font);
- DrawSymbol(p, center + QPoint(-210, -130), Symbol::ZL, 1.5f);
- DrawSymbol(p, center + QPoint(210, -130), Symbol::ZR, 1.5f);
+ DrawSymbol(p, center + QPoint(-210, -120), Symbol::ZL, 1.5f);
+ DrawSymbol(p, center + QPoint(210, -120), Symbol::ZR, 1.5f);
// Minus and Plus buttons
p.setPen(colors.outline);
@@ -818,7 +818,7 @@ void PlayerControlPreview::DrawProController(QPainter& p, const QPointF center)
DrawSymbol(p, center + QPoint(29, -56), Symbol::House, 3.9f);
// Draw battery
- DrawBattery(p, center + QPoint(-30, -160),
+ DrawBattery(p, center + QPoint(-20, -160),
battery_values[Core::HID::EmulatedDeviceIndex::LeftIndex]);
}
@@ -875,7 +875,7 @@ void PlayerControlPreview::DrawGCController(QPainter& p, const QPointF center) {
DrawCircleButton(p, center + QPoint(0, -44), button_values[Plus], 8);
// Draw battery
- DrawBattery(p, center + QPoint(-30, -165),
+ DrawBattery(p, center + QPoint(-20, 110),
battery_values[Core::HID::EmulatedDeviceIndex::LeftIndex]);
}
@@ -1030,6 +1030,10 @@ constexpr std::array<float, 30 * 2> symbol_c = {
-2.37f, 5.64f, -0.65f, 6.44f, 1.25f, 6.47f, 3.06f, 5.89f, 4.63f, 4.92f, 4.63f, 6.83f,
};
+constexpr std::array<float, 6 * 2> symbol_charging = {
+ 6.5f, -1.0f, 1.0f, -1.0f, 1.0f, -3.0f, -6.5f, 1.0f, -1.0f, 1.0f, -1.0f, 3.0f,
+};
+
constexpr std::array<float, 12 * 2> house = {
-1.3f, 0.0f, -0.93f, 0.0f, -0.93f, 1.15f, 0.93f, 1.15f, 0.93f, 0.0f, 1.3f, 0.0f,
0.0f, -1.2f, -1.3f, 0.0f, -0.43f, 0.0f, -0.43f, .73f, 0.43f, .73f, 0.43f, 0.0f,
@@ -2674,36 +2678,43 @@ void PlayerControlPreview::DrawBattery(QPainter& p, QPointF center,
if (battery == Common::Input::BatteryLevel::None) {
return;
}
- p.setPen(colors.outline);
+ // Draw outline
+ p.setPen(QPen(colors.button, 5));
+ p.setBrush(colors.transparent);
+ p.drawRoundedRect(center.x(), center.y(), 34, 16, 2, 2);
+
+ p.setPen(QPen(colors.button, 3));
+ p.drawRect(center.x() + 35, center.y() + 4.5f, 4, 7);
+
+ // Draw Battery shape
+ p.setPen(QPen(colors.indicator2, 3));
p.setBrush(colors.transparent);
- p.drawRect(center.x(), center.y(), 56, 20);
- p.drawRect(center.x() + 56, center.y() + 6, 3, 8);
- p.setBrush(colors.deadzone);
+ p.drawRoundedRect(center.x(), center.y(), 34, 16, 2, 2);
+
+ p.setPen(QPen(colors.indicator2, 1));
+ p.setBrush(colors.indicator2);
+ p.drawRect(center.x() + 35, center.y() + 4.5f, 4, 7);
switch (battery) {
case Common::Input::BatteryLevel::Charging:
- p.setBrush(colors.indicator2);
- p.drawText(center + QPoint(2, 14), tr("Charging"));
+ p.drawRect(center.x(), center.y(), 34, 16);
+ p.setPen(colors.slider);
+ p.setBrush(colors.charging);
+ DrawSymbol(p, center + QPointF(17.0f, 8.0f), Symbol::Charging, 2.1f);
break;
case Common::Input::BatteryLevel::Full:
- p.drawRect(center.x() + 42, center.y(), 14, 20);
- p.drawRect(center.x() + 28, center.y(), 14, 20);
- p.drawRect(center.x() + 14, center.y(), 14, 20);
- p.drawRect(center.x(), center.y(), 14, 20);
+ p.drawRect(center.x(), center.y(), 34, 16);
break;
case Common::Input::BatteryLevel::Medium:
- p.drawRect(center.x() + 28, center.y(), 14, 20);
- p.drawRect(center.x() + 14, center.y(), 14, 20);
- p.drawRect(center.x(), center.y(), 14, 20);
+ p.drawRect(center.x(), center.y(), 25, 16);
break;
case Common::Input::BatteryLevel::Low:
- p.drawRect(center.x() + 14, center.y(), 14, 20);
- p.drawRect(center.x(), center.y(), 14, 20);
+ p.drawRect(center.x(), center.y(), 17, 16);
break;
case Common::Input::BatteryLevel::Critical:
- p.drawRect(center.x(), center.y(), 14, 20);
+ p.drawRect(center.x(), center.y(), 6, 16);
break;
case Common::Input::BatteryLevel::Empty:
- p.drawRect(center.x(), center.y(), 5, 20);
+ p.drawRect(center.x(), center.y(), 3, 16);
break;
default:
break;
@@ -2724,6 +2735,7 @@ void PlayerControlPreview::DrawSymbol(QPainter& p, const QPointF center, Symbol
std::array<QPointF, symbol_sl.size() / 2> sl_icon;
std::array<QPointF, symbol_zr.size() / 2> zr_icon;
std::array<QPointF, symbol_sr.size() / 2> sr_icon;
+ std::array<QPointF, symbol_charging.size() / 2> charging_icon;
switch (symbol) {
case Symbol::House:
for (std::size_t point = 0; point < house.size() / 2; ++point) {
@@ -2809,6 +2821,13 @@ void PlayerControlPreview::DrawSymbol(QPainter& p, const QPointF center, Symbol
}
p.drawPolygon(sr_icon.data(), static_cast<int>(sr_icon.size()));
break;
+ case Symbol::Charging:
+ for (std::size_t point = 0; point < symbol_charging.size() / 2; ++point) {
+ charging_icon[point] = center + QPointF(symbol_charging[point * 2] * icon_size,
+ symbol_charging[point * 2 + 1] * icon_size);
+ }
+ p.drawPolygon(charging_icon.data(), static_cast<int>(charging_icon.size()));
+ break;
}
}
diff --git a/src/yuzu/configuration/configure_input_player_widget.h b/src/yuzu/configuration/configure_input_player_widget.h
index 4cd5c3be0..3582ef77a 100644
--- a/src/yuzu/configuration/configure_input_player_widget.h
+++ b/src/yuzu/configuration/configure_input_player_widget.h
@@ -72,6 +72,7 @@ private:
ZL,
ZR,
SR,
+ Charging,
};
struct ColorMapping {
@@ -94,6 +95,7 @@ private:
QColor slider_button{};
QColor slider_arrow{};
QColor deadzone{};
+ QColor charging{};
};
void UpdateColors();
diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp
index 8539a5c8b..4340de304 100644
--- a/src/yuzu/configuration/configure_motion_touch.cpp
+++ b/src/yuzu/configuration/configure_motion_touch.cpp
@@ -42,23 +42,25 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
job = std::make_unique<CalibrationConfigurationJob>(
host, port,
[this](CalibrationConfigurationJob::Status status) {
- QString text;
- switch (status) {
- case CalibrationConfigurationJob::Status::Ready:
- text = tr("Touch the top left corner <br>of your touchpad.");
- break;
- case CalibrationConfigurationJob::Status::Stage1Completed:
- text = tr("Now touch the bottom right corner <br>of your touchpad.");
- break;
- case CalibrationConfigurationJob::Status::Completed:
- text = tr("Configuration completed!");
- break;
- default:
- break;
- }
- QMetaObject::invokeMethod(this, "UpdateLabelText", Q_ARG(QString, text));
+ QMetaObject::invokeMethod(this, [status, this] {
+ QString text;
+ switch (status) {
+ case CalibrationConfigurationJob::Status::Ready:
+ text = tr("Touch the top left corner <br>of your touchpad.");
+ break;
+ case CalibrationConfigurationJob::Status::Stage1Completed:
+ text = tr("Now touch the bottom right corner <br>of your touchpad.");
+ break;
+ case CalibrationConfigurationJob::Status::Completed:
+ text = tr("Configuration completed!");
+ break;
+ default:
+ break;
+ }
+ UpdateLabelText(text);
+ });
if (status == CalibrationConfigurationJob::Status::Completed) {
- QMetaObject::invokeMethod(this, "UpdateButtonText", Q_ARG(QString, tr("OK")));
+ QMetaObject::invokeMethod(this, [this] { UpdateButtonText(tr("OK")); });
}
},
[this](u16 min_x_, u16 min_y_, u16 max_x_, u16 max_y_) {
@@ -215,11 +217,11 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()),
[this] {
LOG_INFO(Frontend, "UDP input test success");
- QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));
+ QMetaObject::invokeMethod(this, [this] { ShowUDPTestResult(true); });
},
[this] {
LOG_ERROR(Frontend, "UDP input test failed");
- QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, false));
+ QMetaObject::invokeMethod(this, [this] { ShowUDPTestResult(false); });
});
}
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 78b6374c0..d9f6dee4e 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -33,10 +33,10 @@ constexpr std::array<u8, 107> backup_jpeg{
0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 0xd2, 0xcf, 0x20, 0xff, 0xd9,
};
-QString GetImagePath(Common::UUID uuid) {
+QString GetImagePath(const Common::UUID& uuid) {
const auto path =
Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) /
- fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormatSwitch());
+ fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormattedString());
return QString::fromStdString(Common::FS::PathToUTF8String(path));
}
@@ -55,10 +55,10 @@ QString FormatUserEntryText(const QString& username, Common::UUID uuid) {
return ConfigureProfileManager::tr("%1\n%2",
"%1 is the profile username, %2 is the formatted UUID (e.g. "
"00112233-4455-6677-8899-AABBCCDDEEFF))")
- .arg(username, QString::fromStdString(uuid.FormatSwitch()));
+ .arg(username, QString::fromStdString(uuid.FormattedString()));
}
-QPixmap GetIcon(Common::UUID uuid) {
+QPixmap GetIcon(const Common::UUID& uuid) {
QPixmap icon{GetImagePath(uuid)};
if (!icon) {
@@ -200,7 +200,7 @@ void ConfigureProfileManager::AddUser() {
return;
}
- const auto uuid = Common::UUID::Generate();
+ const auto uuid = Common::UUID::MakeRandom();
profile_manager->CreateNewUser(uuid, username.toStdString());
item_model->appendRow(new QStandardItem{GetIcon(uuid), FormatUserEntryText(username, uuid)});
diff --git a/src/yuzu/configuration/configure_touch_from_button.cpp b/src/yuzu/configuration/configure_touch_from_button.cpp
index bde0a08c4..211a00217 100644
--- a/src/yuzu/configuration/configure_touch_from_button.cpp
+++ b/src/yuzu/configuration/configure_touch_from_button.cpp
@@ -227,6 +227,9 @@ void ConfigureTouchFromButton::RenameMapping() {
}
void ConfigureTouchFromButton::GetButtonInput(const int row_index, const bool is_new) {
+ if (timeout_timer->isActive()) {
+ return;
+ }
binding_list_model->item(row_index, 0)->setText(tr("[press key]"));
input_setter = [this, row_index, is_new](const Common::ParamPackage& params,
diff --git a/src/yuzu/configuration/configure_vibration.cpp b/src/yuzu/configuration/configure_vibration.cpp
index adce04b27..779b6401c 100644
--- a/src/yuzu/configuration/configure_vibration.cpp
+++ b/src/yuzu/configuration/configure_vibration.cpp
@@ -9,11 +9,14 @@
#include "common/param_package.h"
#include "common/settings.h"
+#include "core/hid/emulated_controller.h"
+#include "core/hid/hid_core.h"
+#include "core/hid/hid_types.h"
#include "ui_configure_vibration.h"
#include "yuzu/configuration/configure_vibration.h"
-ConfigureVibration::ConfigureVibration(QWidget* parent)
- : QDialog(parent), ui(std::make_unique<Ui::ConfigureVibration>()) {
+ConfigureVibration::ConfigureVibration(QWidget* parent, Core::HID::HIDCore& hid_core_)
+ : QDialog(parent), ui(std::make_unique<Ui::ConfigureVibration>()), hid_core{hid_core_} {
ui->setupUi(this);
vibration_groupboxes = {
@@ -31,6 +34,13 @@ ConfigureVibration::ConfigureVibration(QWidget* parent)
const auto& players = Settings::values.players.GetValue();
for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
+ auto controller = hid_core.GetEmulatedControllerByIndex(i);
+ Core::HID::ControllerUpdateCallback engine_callback{
+ .on_change = [this,
+ i](Core::HID::ControllerTriggerType type) { VibrateController(type, i); },
+ .is_npad_service = false,
+ };
+ controller_callback_key[i] = controller->SetCallback(engine_callback);
vibration_groupboxes[i]->setChecked(players[i].vibration_enabled);
vibration_spinboxes[i]->setValue(players[i].vibration_strength);
}
@@ -45,7 +55,14 @@ ConfigureVibration::ConfigureVibration(QWidget* parent)
RetranslateUI();
}
-ConfigureVibration::~ConfigureVibration() = default;
+ConfigureVibration::~ConfigureVibration() {
+ StopVibrations();
+
+ for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
+ auto controller = hid_core.GetEmulatedControllerByIndex(i);
+ controller->DeleteCallback(controller_callback_key[i]);
+ }
+};
void ConfigureVibration::ApplyConfiguration() {
auto& players = Settings::values.players.GetValue();
@@ -70,3 +87,54 @@ void ConfigureVibration::changeEvent(QEvent* event) {
void ConfigureVibration::RetranslateUI() {
ui->retranslateUi(this);
}
+
+void ConfigureVibration::VibrateController(Core::HID::ControllerTriggerType type,
+ std::size_t player_index) {
+ if (type != Core::HID::ControllerTriggerType::Button) {
+ return;
+ }
+
+ auto& player = Settings::values.players.GetValue()[player_index];
+ auto controller = hid_core.GetEmulatedControllerByIndex(player_index);
+ const int vibration_strenght = vibration_spinboxes[player_index]->value();
+ const auto& buttons = controller->GetButtonsValues();
+
+ bool button_is_pressed = false;
+ for (std::size_t i = 0; i < buttons.size(); ++i) {
+ if (buttons[i].value) {
+ button_is_pressed = true;
+ break;
+ }
+ }
+
+ if (!button_is_pressed) {
+ StopVibrations();
+ return;
+ }
+
+ const int old_vibration_enabled = player.vibration_enabled;
+ const bool old_vibration_strenght = player.vibration_strength;
+ player.vibration_enabled = true;
+ player.vibration_strength = vibration_strenght;
+
+ const Core::HID::VibrationValue vibration{
+ .low_amplitude = 1.0f,
+ .low_frequency = 160.0f,
+ .high_amplitude = 1.0f,
+ .high_frequency = 320.0f,
+ };
+ controller->SetVibration(0, vibration);
+ controller->SetVibration(1, vibration);
+
+ // Restore previous values
+ player.vibration_enabled = old_vibration_enabled;
+ player.vibration_strength = old_vibration_strenght;
+}
+
+void ConfigureVibration::StopVibrations() {
+ for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
+ auto controller = hid_core.GetEmulatedControllerByIndex(i);
+ controller->SetVibration(0, Core::HID::DEFAULT_VIBRATION_VALUE);
+ controller->SetVibration(1, Core::HID::DEFAULT_VIBRATION_VALUE);
+ }
+}
diff --git a/src/yuzu/configuration/configure_vibration.h b/src/yuzu/configuration/configure_vibration.h
index 37bbc2653..50b8195fa 100644
--- a/src/yuzu/configuration/configure_vibration.h
+++ b/src/yuzu/configuration/configure_vibration.h
@@ -15,11 +15,16 @@ namespace Ui {
class ConfigureVibration;
}
+namespace Core::HID {
+enum class ControllerTriggerType;
+class HIDCore;
+} // namespace Core::HID
+
class ConfigureVibration : public QDialog {
Q_OBJECT
public:
- explicit ConfigureVibration(QWidget* parent);
+ explicit ConfigureVibration(QWidget* parent, Core::HID::HIDCore& hid_core_);
~ConfigureVibration() override;
void ApplyConfiguration();
@@ -27,14 +32,21 @@ public:
private:
void changeEvent(QEvent* event) override;
void RetranslateUI();
+ void VibrateController(Core::HID::ControllerTriggerType type, std::size_t player_index);
+ void StopVibrations();
std::unique_ptr<Ui::ConfigureVibration> ui;
static constexpr std::size_t NUM_PLAYERS = 8;
- // Groupboxes encapsulating the vibration strength spinbox.
+ /// Groupboxes encapsulating the vibration strength spinbox.
std::array<QGroupBox*, NUM_PLAYERS> vibration_groupboxes;
- // Spinboxes representing the vibration strength percentage.
+ /// Spinboxes representing the vibration strength percentage.
std::array<QSpinBox*, NUM_PLAYERS> vibration_spinboxes;
+
+ /// Callback index to stop the controllers events
+ std::array<int, NUM_PLAYERS> controller_callback_key;
+
+ Core::HID::HIDCore& hid_core;
};
diff --git a/src/yuzu/configuration/configure_vibration.ui b/src/yuzu/configuration/configure_vibration.ui
index efdf317a9..447a18eb1 100644
--- a/src/yuzu/configuration/configure_vibration.ui
+++ b/src/yuzu/configuration/configure_vibration.ui
@@ -17,6 +17,13 @@
<string notr="true"/>
</property>
<layout class="QVBoxLayout">
+ <item row="0" column="0" colspan="4">
+ <widget class="QLabel" name="label_1">
+ <property name="text">
+ <string>Press any controller button to vibrate the controller.</string>
+ </property>
+ </widget>
+ </item>
<item>
<widget class="QGroupBox" name="vibrationStrengthGroup">
<property name="title">