From 9d4edd4e88d291aa4b778b74f6e9daa9dd358d2b Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sun, 13 Sep 2020 09:25:22 -0400
Subject: ui/themes: Cleanup UI
---
src/yuzu/aboutdialog.ui | 20 --
src/yuzu/applets/controller.ui | 31 +--
src/yuzu/configuration/configure.ui | 20 --
.../configuration/configure_debug_controller.ui | 20 --
src/yuzu/configuration/configure_input.ui | 24 +-
.../configuration/configure_input_advanced.cpp | 4 +-
src/yuzu/configuration/configure_input_advanced.ui | 192 ++++++++--------
src/yuzu/configuration/configure_input_player.ui | 241 +++++++++++----------
src/yuzu/configuration/configure_motion_touch.ui | 10 -
src/yuzu/configuration/configure_mouse_advanced.ui | 46 ++--
src/yuzu/configuration/configure_per_game.ui | 20 --
.../configuration/configure_touch_from_button.ui | 10 -
.../configure_touchscreen_advanced.ui | 22 +-
13 files changed, 263 insertions(+), 397 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/yuzu/aboutdialog.ui b/src/yuzu/aboutdialog.ui
index f122ba39d..1b320630c 100644
--- a/src/yuzu/aboutdialog.ui
+++ b/src/yuzu/aboutdialog.ui
@@ -160,32 +160,12 @@ p, li { white-space: pre-wrap; }
accepted()
AboutDialog
accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
buttonBox
rejected()
AboutDialog
reject()
-
-
- 316
- 260
-
-
- 286
- 274
-
-
diff --git a/src/yuzu/applets/controller.ui b/src/yuzu/applets/controller.ui
index c4108a979..2ab69a2d3 100644
--- a/src/yuzu/applets/controller.ui
+++ b/src/yuzu/applets/controller.ui
@@ -1217,9 +1217,6 @@
-
-
- false
-
-
Pro Controller
@@ -2279,7 +2276,7 @@
6
- 6
+ 8
6
@@ -2335,13 +2332,13 @@
- 65
- 0
+ 68
+ 21
- 65
+ 68
16777215
@@ -2387,18 +2384,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Configure
@@ -2430,12 +2427,12 @@
- 65
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Open
@@ -2657,16 +2654,6 @@
accepted()
QtControllerSelectorDialog
accept()
-
-
- 20
- 20
-
-
- 20
- 20
-
-
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui
index fcf42cdcb..f92c3aff3 100644
--- a/src/yuzu/configuration/configure.ui
+++ b/src/yuzu/configuration/configure.ui
@@ -275,32 +275,12 @@
accepted()
ConfigureDialog
accept()
-
-
- 220
- 380
-
-
- 220
- 200
-
-
buttonBox
rejected()
ConfigureDialog
reject()
-
-
- 220
- 380
-
-
- 220
- 200
-
-
diff --git a/src/yuzu/configuration/configure_debug_controller.ui b/src/yuzu/configuration/configure_debug_controller.ui
index a95ed50ff..7b7e6582c 100644
--- a/src/yuzu/configuration/configure_debug_controller.ui
+++ b/src/yuzu/configuration/configure_debug_controller.ui
@@ -66,32 +66,12 @@
accepted()
ConfigureDebugController
accept()
-
-
- 140
- 318
-
-
- 140
- 169
-
-
buttonBox
rejected()
ConfigureDebugController
reject()
-
-
- 140
- 318
-
-
- 140
- 169
-
-
diff --git a/src/yuzu/configuration/configure_input.ui b/src/yuzu/configuration/configure_input.ui
index 136955224..b74481bda 100644
--- a/src/yuzu/configuration/configure_input.ui
+++ b/src/yuzu/configuration/configure_input.ui
@@ -142,7 +142,7 @@
6
- 3
+ 8
6
@@ -198,13 +198,13 @@
- 65
+ 68
21
- 65
+ 68
16777215
@@ -250,18 +250,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Configure
@@ -468,13 +468,13 @@
- 57
+ 68
0
- 55
+ 68
16777215
@@ -494,7 +494,7 @@
Qt::LeftToRight
- min-width: 55px;
+ min-width: 68px;
Defaults
@@ -511,13 +511,13 @@
- 57
+ 68
0
- 55
+ 68
16777215
@@ -537,7 +537,7 @@
Qt::LeftToRight
- min-width: 55px;
+ min-width: 68px;
Clear
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index 81f9dc16c..3715db0ab 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -101,7 +101,7 @@ void ConfigureInputAdvanced::OnControllerButtonClick(int player_idx, int button_
}
controllers_colors[player_idx][button_idx] = new_bg_color;
controllers_color_buttons[player_idx][button_idx]->setStyleSheet(
- QStringLiteral("background-color: %1; min-width: 55px;")
+ QStringLiteral("background-color: %1; min-width: 60px;")
.arg(controllers_colors[player_idx][button_idx].name()));
}
@@ -139,7 +139,7 @@ void ConfigureInputAdvanced::LoadConfiguration() {
for (std::size_t button_idx = 0; button_idx < colors.size(); ++button_idx) {
controllers_color_buttons[player_idx][button_idx]->setStyleSheet(
- QStringLiteral("background-color: %1; min-width: 55px;")
+ QStringLiteral("background-color: %1; min-width: 60px;")
.arg(controllers_colors[player_idx][button_idx].name()));
}
}
diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui
index 5958435fc..a880a7c68 100644
--- a/src/yuzu/configuration/configure_input_advanced.ui
+++ b/src/yuzu/configuration/configure_input_advanced.ui
@@ -192,18 +192,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -247,18 +247,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -323,18 +323,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -378,18 +378,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -478,18 +478,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -533,18 +533,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -609,18 +609,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -664,18 +664,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -782,18 +782,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -837,18 +837,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -913,18 +913,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -968,18 +968,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1068,18 +1068,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1123,18 +1123,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1199,18 +1199,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1254,18 +1254,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1393,18 +1393,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1448,18 +1448,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1524,18 +1524,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1579,18 +1579,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1679,18 +1679,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1734,18 +1734,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1810,18 +1810,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1865,18 +1865,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -1983,18 +1983,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -2038,18 +2038,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -2114,18 +2114,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -2169,18 +2169,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -2269,18 +2269,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -2324,18 +2324,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -2400,18 +2400,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
@@ -2455,18 +2455,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
diff --git a/src/yuzu/configuration/configure_input_player.ui b/src/yuzu/configuration/configure_input_player.ui
index e03461d9d..1e78b4c10 100644
--- a/src/yuzu/configuration/configure_input_player.ui
+++ b/src/yuzu/configuration/configure_input_player.ui
@@ -83,6 +83,12 @@
-
+
+
+ 0
+ 21
+
+
-
Pro Controller
@@ -136,6 +142,12 @@
-
+
+
+ 0
+ 21
+
+
-
Any
@@ -152,14 +164,14 @@
- 24
- 22
+ 21
+ 21
- 24
- 22
+ 21
+ 21
@@ -198,18 +210,25 @@
5
-
-
+
+
+
+ 0
+ 21
+
+
+
-
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Save
@@ -220,12 +239,12 @@
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
New
@@ -236,12 +255,12 @@
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Delete
@@ -393,18 +412,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Up
@@ -463,18 +482,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Left
@@ -512,18 +531,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Right
@@ -594,18 +613,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Down
@@ -664,18 +683,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Pressed
@@ -713,18 +732,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Modifier
@@ -759,13 +778,13 @@
- 55
+ 68
21
- 55
+ 68
16777215
@@ -966,18 +985,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Up
@@ -1036,18 +1055,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Left
@@ -1085,18 +1104,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Right
@@ -1167,18 +1186,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Down
@@ -1292,18 +1311,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
L
@@ -1341,18 +1360,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
ZL
@@ -1445,18 +1464,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Minus
@@ -1494,18 +1513,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Capture
@@ -1564,18 +1583,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Plus
@@ -1613,18 +1632,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Home
@@ -1717,18 +1736,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
R
@@ -1766,18 +1785,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
ZR
@@ -1870,18 +1889,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
SL
@@ -1919,18 +1938,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
SR
@@ -2027,18 +2046,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Left
@@ -2076,18 +2095,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Right
@@ -2225,18 +2244,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
X
@@ -2295,18 +2314,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Y
@@ -2344,18 +2363,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
A
@@ -2426,18 +2445,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
B
@@ -2580,18 +2599,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Up
@@ -2650,18 +2669,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Left
@@ -2699,18 +2718,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Right
@@ -2781,18 +2800,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Down
@@ -2851,18 +2870,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Pressed
@@ -2900,18 +2919,18 @@
- 57
+ 68
0
- 55
+ 68
16777215
- min-width: 55px;
+ min-width: 68px;
Modifier
@@ -2946,13 +2965,13 @@
- 55
+ 68
21
- 55
+ 68
16777215
diff --git a/src/yuzu/configuration/configure_motion_touch.ui b/src/yuzu/configuration/configure_motion_touch.ui
index 602cf8cd8..5b78c5a4b 100644
--- a/src/yuzu/configuration/configure_motion_touch.ui
+++ b/src/yuzu/configuration/configure_motion_touch.ui
@@ -312,16 +312,6 @@
accepted()
ConfigureMotionTouch
ApplyConfiguration()
-
-
- 220
- 380
-
-
- 220
- 200
-
-
diff --git a/src/yuzu/configuration/configure_mouse_advanced.ui b/src/yuzu/configuration/configure_mouse_advanced.ui
index 74552fdbd..5b99e1c37 100644
--- a/src/yuzu/configuration/configure_mouse_advanced.ui
+++ b/src/yuzu/configuration/configure_mouse_advanced.ui
@@ -15,7 +15,7 @@
QPushButton {
- min-width: 55px;
+ min-width: 60px;
}
@@ -42,13 +42,13 @@
- 57
+ 68
0
- 16777215
+ 68
16777215
@@ -82,7 +82,7 @@
- 57
+ 68
0
@@ -110,7 +110,7 @@
- 57
+ 68
0
@@ -138,13 +138,13 @@
- 57
+ 68
0
- 16777215
+ 68
16777215
@@ -204,13 +204,13 @@
- 57
+ 68
0
- 16777215
+ 68
16777215
@@ -256,13 +256,13 @@
- 57
+ 68
0
- 16777215
+ 68
16777215
@@ -275,13 +275,13 @@
- 57
+ 68
0
- 16777215
+ 68
16777215
@@ -324,32 +324,12 @@
accepted()
ConfigureMouseAdvanced
accept()
-
-
- 124
- 266
-
-
- 124
- 143
-
-
buttonBox
rejected()
ConfigureMouseAdvanced
reject()
-
-
- 124
- 266
-
-
- 124
- 143
-
-
diff --git a/src/yuzu/configuration/configure_per_game.ui b/src/yuzu/configuration/configure_per_game.ui
index d2057c4ab..25975b3b9 100644
--- a/src/yuzu/configuration/configure_per_game.ui
+++ b/src/yuzu/configuration/configure_per_game.ui
@@ -319,32 +319,12 @@
accepted()
ConfigurePerGame
accept()
-
-
- 248
- 254
-
-
- 157
- 274
-
-
buttonBox
rejected()
ConfigurePerGame
reject()
-
-
- 316
- 260
-
-
- 286
- 274
-
-
diff --git a/src/yuzu/configuration/configure_touch_from_button.ui b/src/yuzu/configuration/configure_touch_from_button.ui
index f581e27e0..757219d54 100644
--- a/src/yuzu/configuration/configure_touch_from_button.ui
+++ b/src/yuzu/configuration/configure_touch_from_button.ui
@@ -216,16 +216,6 @@ Drag points to change position, or double-click table cells to edit values.rejected()
ConfigureTouchFromButton
reject()
-
-
- 249
- 428
-
-
- 249
- 224
-
-
diff --git a/src/yuzu/configuration/configure_touchscreen_advanced.ui b/src/yuzu/configuration/configure_touchscreen_advanced.ui
index 1171c2dd1..30ceccddb 100644
--- a/src/yuzu/configuration/configure_touchscreen_advanced.ui
+++ b/src/yuzu/configuration/configure_touchscreen_advanced.ui
@@ -168,32 +168,12 @@
accepted()
ConfigureTouchscreenAdvanced
accept()
-
-
- 140
- 318
-
-
- 140
- 169
-
-
buttonBox
rejected()
ConfigureTouchscreenAdvanced
reject()
-
-
- 140
- 318
-
-
- 140
- 169
-
-
-
+
--
cgit v1.2.3
From 75eaab2e0f48eb588c1bfb85f96630e199fbc1da Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Thu, 17 Sep 2020 12:00:29 -0400
Subject: configure_input_player: Implement input exclusivity and persistence
With this, the "Input Devices" combobox should accurately reflect the input device being used and disallows inputs from other input devices unless the input device is set to "Any".
---
src/input_common/main.cpp | 6 +-
src/yuzu/configuration/configure_input.cpp | 2 +-
src/yuzu/configuration/configure_input_player.cpp | 318 +++++++++++++---------
src/yuzu/configuration/configure_input_player.h | 17 +-
4 files changed, 205 insertions(+), 138 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index d32fd8b81..354c734fe 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -78,7 +78,7 @@ struct InputSubsystem::Impl {
[[nodiscard]] std::vector GetInputDevices() const {
std::vector devices = {
Common::ParamPackage{{"display", "Any"}, {"class", "any"}},
- Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}},
+ Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "keyboard"}},
};
#ifdef HAVE_SDL2
auto sdl_devices = sdl->GetInputDevices();
@@ -96,7 +96,7 @@ struct InputSubsystem::Impl {
if (!params.Has("class") || params.Get("class", "") == "any") {
return {};
}
- if (params.Get("class", "") == "key") {
+ if (params.Get("class", "") == "keyboard") {
// TODO consider returning the SDL key codes for the default keybindings
return {};
}
@@ -116,7 +116,7 @@ struct InputSubsystem::Impl {
if (!params.Has("class") || params.Get("class", "") == "any") {
return {};
}
- if (params.Get("class", "") == "key") {
+ if (params.Get("class", "") == "keyboard") {
// TODO consider returning the SDL key codes for the default keybindings
return {};
}
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 2725fcb2b..f2932aa0b 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -242,6 +242,6 @@ void ConfigureInput::UpdateDockedState(bool is_handheld) {
void ConfigureInput::UpdateAllInputDevices() {
for (const auto& player : player_controllers) {
- player->UpdateInputDevices();
+ player->UpdateInputDeviceCombobox();
}
}
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index f58ca29d7..0de0c6999 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -477,11 +477,12 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
UpdateMotionButtons();
});
- connect(ui->comboDevices, qOverload(&QComboBox::currentIndexChanged), this,
+ connect(ui->comboDevices, qOverload(&QComboBox::activated), this,
&ConfigureInputPlayer::UpdateMappingWithDefaults);
+ ui->comboDevices->setCurrentIndex(-1);
+
ui->buttonRefreshDevices->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh")));
- UpdateInputDevices();
connect(ui->buttonRefreshDevices, &QPushButton::clicked,
[this] { emit RefreshInputDevices(); });
@@ -492,14 +493,14 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
Common::ParamPackage params;
if (input_subsystem->GetGCButtons()->IsPolling()) {
params = input_subsystem->GetGCButtons()->GetNextInput();
- if (params.Has("engine")) {
+ if (params.Has("engine") && IsInputAcceptable(params)) {
SetPollingResult(params, false);
return;
}
}
if (input_subsystem->GetGCAnalogs()->IsPolling()) {
params = input_subsystem->GetGCAnalogs()->GetNextInput();
- if (params.Has("engine")) {
+ if (params.Has("engine") && IsInputAcceptable(params)) {
SetPollingResult(params, false);
return;
}
@@ -513,7 +514,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
}
for (auto& poller : device_pollers) {
params = poller->GetNextInput();
- if (params.Has("engine")) {
+ if (params.Has("engine") && IsInputAcceptable(params)) {
SetPollingResult(params, false);
return;
}
@@ -572,6 +573,14 @@ void ConfigureInputPlayer::ApplyConfiguration() {
UpdateController(Settings::ControllerType::Handheld, HANDHELD_INDEX, handheld.connected);
}
+void ConfigureInputPlayer::showEvent(QShowEvent* event) {
+ if (bottom_row == nullptr) {
+ return;
+ }
+ QWidget::showEvent(event);
+ ui->main->addWidget(bottom_row);
+}
+
void ConfigureInputPlayer::changeEvent(QEvent* event) {
if (event->type() == QEvent::LanguageChange) {
RetranslateUI();
@@ -604,6 +613,7 @@ void ConfigureInputPlayer::LoadConfiguration() {
}
UpdateUI();
+ UpdateInputDeviceCombobox();
if (debug) {
return;
@@ -615,11 +625,56 @@ void ConfigureInputPlayer::LoadConfiguration() {
(player_index == 0 && Settings::values.players[HANDHELD_INDEX].connected));
}
-void ConfigureInputPlayer::UpdateInputDevices() {
- input_devices = input_subsystem->GetInputDevices();
- ui->comboDevices->clear();
- for (auto device : input_devices) {
- ui->comboDevices->addItem(QString::fromStdString(device.Get("display", "Unknown")), {});
+void ConfigureInputPlayer::ConnectPlayer(bool connected) {
+ ui->groupConnectedController->setChecked(connected);
+}
+
+void ConfigureInputPlayer::UpdateInputDeviceCombobox() {
+ // Skip input device persistence if "Input Devices" is set to "Any".
+ if (ui->comboDevices->currentIndex() == 0) {
+ UpdateInputDevices();
+ return;
+ }
+
+ // Find the first button that isn't empty.
+ const auto button_param =
+ std::find_if(buttons_param.begin(), buttons_param.end(),
+ [](const Common::ParamPackage param) { return param.Has("engine"); });
+ const bool buttons_empty = button_param == buttons_param.end();
+
+ const auto current_engine = button_param->Get("engine", "");
+ const auto current_guid = button_param->Get("guid", "");
+ const auto current_port = button_param->Get("port", "");
+
+ UpdateInputDevices();
+
+ if (buttons_empty) {
+ return;
+ }
+
+ const bool all_one_device =
+ std::all_of(buttons_param.begin(), buttons_param.end(),
+ [current_engine, current_guid, current_port](const Common::ParamPackage param) {
+ return !param.Has("engine") || (param.Get("engine", "") == current_engine &&
+ param.Get("guid", "") == current_guid &&
+ param.Get("port", "") == current_port);
+ });
+
+ if (all_one_device) {
+ const auto devices_it = std::find_if(
+ input_devices.begin(), input_devices.end(),
+ [current_engine, current_guid, current_port](const Common::ParamPackage param) {
+ return param.Get("class", "") == current_engine &&
+ param.Get("guid", "") == current_guid &&
+ param.Get("port", "") == current_port;
+ });
+ const int device_index =
+ devices_it != input_devices.end()
+ ? static_cast(std::distance(input_devices.begin(), devices_it))
+ : 0;
+ ui->comboDevices->setCurrentIndex(device_index);
+ } else {
+ ui->comboDevices->setCurrentIndex(0);
}
}
@@ -648,7 +703,7 @@ void ConfigureInputPlayer::RestoreDefaults() {
}
UpdateUI();
- UpdateInputDevices();
+ UpdateInputDeviceCombobox();
ui->comboControllerType->setCurrentIndex(0);
}
@@ -752,117 +807,12 @@ void ConfigureInputPlayer::UpdateUI() {
}
}
-void ConfigureInputPlayer::UpdateMappingWithDefaults() {
- if (ui->comboDevices->currentIndex() < 2) {
- return;
- }
- const auto& device = input_devices[ui->comboDevices->currentIndex()];
- auto button_mapping = input_subsystem->GetButtonMappingForDevice(device);
- auto analog_mapping = input_subsystem->GetAnalogMappingForDevice(device);
- for (std::size_t i = 0; i < buttons_param.size(); ++i) {
- buttons_param[i] = button_mapping[static_cast(i)];
- }
- for (std::size_t i = 0; i < analogs_param.size(); ++i) {
- analogs_param[i] = analog_mapping[static_cast(i)];
- }
-
- UpdateUI();
-}
-
-void ConfigureInputPlayer::HandleClick(
- QPushButton* button, std::function new_input_setter,
- InputCommon::Polling::DeviceType type) {
- if (button == ui->buttonMotionLeft || button == ui->buttonMotionRight) {
- button->setText(tr("Shake!"));
- } else {
- button->setText(tr("[waiting]"));
- }
- button->setFocus();
-
- // The first two input devices are always Any and Keyboard/Mouse. If the user filtered to a
- // controller, then they don't want keyboard/mouse input
- want_keyboard_mouse = ui->comboDevices->currentIndex() < 2;
-
- input_setter = new_input_setter;
-
- device_pollers = input_subsystem->GetPollers(type);
-
- for (auto& poller : device_pollers) {
- poller->Start();
- }
-
- QWidget::grabMouse();
- QWidget::grabKeyboard();
-
- if (type == InputCommon::Polling::DeviceType::Button) {
- input_subsystem->GetGCButtons()->BeginConfiguration();
- } else {
- input_subsystem->GetGCAnalogs()->BeginConfiguration();
- }
-
- if (type == InputCommon::Polling::DeviceType::Motion) {
- input_subsystem->GetUDPMotions()->BeginConfiguration();
- }
-
- timeout_timer->start(2500); // Cancel after 2.5 seconds
- poll_timer->start(50); // Check for new inputs every 50ms
-}
-
-void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params, bool abort) {
- timeout_timer->stop();
- poll_timer->stop();
- for (auto& poller : device_pollers) {
- poller->Stop();
- }
-
- QWidget::releaseMouse();
- QWidget::releaseKeyboard();
-
- input_subsystem->GetGCButtons()->EndConfiguration();
- input_subsystem->GetGCAnalogs()->EndConfiguration();
-
- input_subsystem->GetUDPMotions()->EndConfiguration();
-
- if (!abort) {
- (*input_setter)(params);
- }
-
- UpdateUI();
- input_setter = std::nullopt;
-}
-
-void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
- if (!input_setter || !event) {
- return;
- }
-
- if (want_keyboard_mouse) {
- SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->button())},
- false);
- } else {
- // We don't want any mouse buttons, so don't stop polling
- return;
- }
-
- SetPollingResult({}, true);
-}
-
-void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
- if (!input_setter || !event) {
- return;
- }
-
- if (event->key() != Qt::Key_Escape) {
- if (want_keyboard_mouse) {
- SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->key())},
- false);
- } else {
- // Escape key wasn't pressed and we don't want any keyboard keys, so don't stop polling
- return;
- }
+void ConfigureInputPlayer::UpdateInputDevices() {
+ input_devices = input_subsystem->GetInputDevices();
+ ui->comboDevices->clear();
+ for (auto device : input_devices) {
+ ui->comboDevices->addItem(QString::fromStdString(device.Get("display", "Unknown")), {});
}
-
- SetPollingResult({}, true);
}
void ConfigureInputPlayer::UpdateControllerIcon() {
@@ -986,14 +936,128 @@ void ConfigureInputPlayer::UpdateMotionButtons() {
}
}
-void ConfigureInputPlayer::showEvent(QShowEvent* event) {
- if (bottom_row == nullptr) {
+void ConfigureInputPlayer::UpdateMappingWithDefaults() {
+ if (ui->comboDevices->currentIndex() < 2) {
return;
}
- QWidget::showEvent(event);
- ui->main->addWidget(bottom_row);
+ const auto& device = input_devices[ui->comboDevices->currentIndex()];
+ auto button_mapping = input_subsystem->GetButtonMappingForDevice(device);
+ auto analog_mapping = input_subsystem->GetAnalogMappingForDevice(device);
+ for (std::size_t i = 0; i < buttons_param.size(); ++i) {
+ buttons_param[i] = button_mapping[static_cast(i)];
+ }
+ for (std::size_t i = 0; i < analogs_param.size(); ++i) {
+ analogs_param[i] = analog_mapping[static_cast(i)];
+ }
+
+ UpdateUI();
}
-void ConfigureInputPlayer::ConnectPlayer(bool connected) {
- ui->groupConnectedController->setChecked(connected);
+void ConfigureInputPlayer::HandleClick(
+ QPushButton* button, std::function new_input_setter,
+ InputCommon::Polling::DeviceType type) {
+ if (button == ui->buttonMotionLeft || button == ui->buttonMotionRight) {
+ button->setText(tr("Shake!"));
+ } else {
+ button->setText(tr("[waiting]"));
+ }
+ button->setFocus();
+
+ // The first two input devices are always Any and Keyboard/Mouse. If the user filtered to a
+ // controller, then they don't want keyboard/mouse input
+ want_keyboard_mouse = ui->comboDevices->currentIndex() < 2;
+
+ input_setter = new_input_setter;
+
+ device_pollers = input_subsystem->GetPollers(type);
+
+ for (auto& poller : device_pollers) {
+ poller->Start();
+ }
+
+ QWidget::grabMouse();
+ QWidget::grabKeyboard();
+
+ if (type == InputCommon::Polling::DeviceType::Button) {
+ input_subsystem->GetGCButtons()->BeginConfiguration();
+ } else {
+ input_subsystem->GetGCAnalogs()->BeginConfiguration();
+ }
+
+ if (type == InputCommon::Polling::DeviceType::Motion) {
+ input_subsystem->GetUDPMotions()->BeginConfiguration();
+ }
+
+ timeout_timer->start(2500); // Cancel after 2.5 seconds
+ poll_timer->start(50); // Check for new inputs every 50ms
+}
+
+void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params, bool abort) {
+ timeout_timer->stop();
+ poll_timer->stop();
+ for (auto& poller : device_pollers) {
+ poller->Stop();
+ }
+
+ QWidget::releaseMouse();
+ QWidget::releaseKeyboard();
+
+ input_subsystem->GetGCButtons()->EndConfiguration();
+ input_subsystem->GetGCAnalogs()->EndConfiguration();
+
+ input_subsystem->GetUDPMotions()->EndConfiguration();
+
+ if (!abort) {
+ (*input_setter)(params);
+ }
+
+ UpdateUI();
+ UpdateInputDeviceCombobox();
+
+ input_setter = std::nullopt;
+}
+
+bool ConfigureInputPlayer::IsInputAcceptable(const Common::ParamPackage& params) const {
+ if (ui->comboDevices->currentIndex() == 0) {
+ return true;
+ }
+
+ const auto current_input_device = input_devices[ui->comboDevices->currentIndex()];
+ return params.Get("engine", "") == current_input_device.Get("class", "") &&
+ params.Get("guid", "") == current_input_device.Get("guid", "") &&
+ params.Get("port", "") == current_input_device.Get("port", "");
+}
+
+void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) {
+ if (!input_setter || !event) {
+ return;
+ }
+
+ if (want_keyboard_mouse) {
+ SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->button())},
+ false);
+ } else {
+ // We don't want any mouse buttons, so don't stop polling
+ return;
+ }
+
+ SetPollingResult({}, true);
+}
+
+void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
+ if (!input_setter || !event) {
+ return;
+ }
+
+ if (event->key() != Qt::Key_Escape) {
+ if (want_keyboard_mouse) {
+ SetPollingResult(Common::ParamPackage{InputCommon::GenerateKeyboardParam(event->key())},
+ false);
+ } else {
+ // Escape key wasn't pressed and we don't want any keyboard keys, so don't stop polling
+ return;
+ }
+ }
+
+ SetPollingResult({}, true);
}
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index c19aefffa..a5414e624 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -51,8 +51,11 @@ public:
/// Save all button configurations to settings file.
void ApplyConfiguration();
+ /// Set the connection state checkbox (used to sync state).
+ void ConnectPlayer(bool connected);
+
/// Update the input devices combobox.
- void UpdateInputDevices();
+ void UpdateInputDeviceCombobox();
/// Restore all buttons to their default values.
void RestoreDefaults();
@@ -60,9 +63,6 @@ public:
/// Clear all input configuration.
void ClearAll();
- /// Set the connection state checkbox (used to sync state).
- void ConnectPlayer(bool connected);
-
signals:
/// Emitted when this controller is connected by the user.
void Connected(bool connected);
@@ -89,6 +89,9 @@ private:
/// Finish polling and configure input using the input_setter.
void SetPollingResult(const Common::ParamPackage& params, bool abort);
+ /// Checks whether a given input can be accepted.
+ bool IsInputAcceptable(const Common::ParamPackage& params) const;
+
/// Handle mouse button press events.
void mousePressEvent(QMouseEvent* event) override;
@@ -98,8 +101,8 @@ private:
/// Update UI to reflect current configuration.
void UpdateUI();
- /// Update the controller selection combobox
- void UpdateControllerCombobox();
+ /// Update the available input devices.
+ void UpdateInputDevices();
/// Update the current controller icon.
void UpdateControllerIcon();
@@ -164,7 +167,7 @@ private:
bool want_keyboard_mouse = false;
/// List of physical devices users can map with. If a SDL backed device is selected, then you
- /// can usue this device to get a default mapping.
+ /// can use this device to get a default mapping.
std::vector input_devices;
/// Bottom row is where console wide settings are held, and its "owned" by the parent
--
cgit v1.2.3
From 57d89e291de0eacfd368784309a0cbf89d38dcc8 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Wed, 23 Sep 2020 09:52:25 -0400
Subject: input_profiles: Implement input profiles
---
src/yuzu/CMakeLists.txt | 2 +
src/yuzu/configuration/config.cpp | 271 +++++++++++++--------
src/yuzu/configuration/config.h | 20 +-
.../configuration/configure_debug_controller.cpp | 6 +-
.../configuration/configure_debug_controller.h | 6 +-
src/yuzu/configuration/configure_input.cpp | 30 ++-
src/yuzu/configuration/configure_input.h | 4 +
src/yuzu/configuration/configure_input_player.cpp | 111 ++++++++-
src/yuzu/configuration/configure_input_player.h | 21 +-
src/yuzu/configuration/configure_per_game.cpp | 3 +-
src/yuzu/configuration/input_profiles.cpp | 131 ++++++++++
src/yuzu/configuration/input_profiles.h | 32 +++
src/yuzu/main.cpp | 2 +-
13 files changed, 509 insertions(+), 130 deletions(-)
create mode 100644 src/yuzu/configuration/input_profiles.cpp
create mode 100644 src/yuzu/configuration/input_profiles.h
(limited to 'src/yuzu')
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 8abb74d56..22fe0a2a6 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -108,6 +108,8 @@ add_executable(yuzu
configuration/configure_web.cpp
configuration/configure_web.h
configuration/configure_web.ui
+ configuration/input_profiles.cpp
+ configuration/input_profiles.h
debugger/console.cpp
debugger/console.h
debugger/profiler.cpp
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 1ce62e4a6..5c8b02fbe 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -5,6 +5,7 @@
#include
#include
#include
+#include "common/common_paths.h"
#include "common/file_util.h"
#include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/hid/controllers/npad.h"
@@ -14,14 +15,27 @@
namespace FS = Common::FS;
-Config::Config(const std::string& config_file, bool is_global) {
- // TODO: Don't hardcode the path; let the frontend decide where to put the config files.
- qt_config_loc = FS::GetUserPath(FS::UserPath::ConfigDir) + config_file;
- FS::CreateFullPath(qt_config_loc);
- qt_config =
- std::make_unique(QString::fromStdString(qt_config_loc), QSettings::IniFormat);
- global = is_global;
- Reload();
+Config::Config(const std::string& config_file, ConfigType config_type) : type(config_type) {
+ global = config_type == ConfigType::GlobalConfig;
+
+ switch (config_type) {
+ case ConfigType::GlobalConfig:
+ case ConfigType::PerGameConfig:
+ qt_config_loc = fmt::format("{}" DIR_SEP "{}.ini", FS::GetUserPath(FS::UserPath::ConfigDir),
+ config_file);
+ FS::CreateFullPath(qt_config_loc);
+ qt_config = std::make_unique(QString::fromStdString(qt_config_loc),
+ QSettings::IniFormat);
+ Reload();
+ break;
+ case ConfigType::InputProfile:
+ qt_config_loc = fmt::format("{}input" DIR_SEP "{}.ini",
+ FS::GetUserPath(FS::UserPath::ConfigDir), config_file);
+ FS::CreateFullPath(qt_config_loc);
+ qt_config = std::make_unique(QString::fromStdString(qt_config_loc),
+ QSettings::IniFormat);
+ break;
+ }
}
Config::~Config() {
@@ -242,84 +256,103 @@ const std::array Config::default_hotkeys{{
}};
// clang-format on
-void Config::ReadPlayerValues() {
- for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
- auto& player = Settings::values.players[p];
+void Config::ReadPlayerValue(std::size_t player_index) {
+ const QString player_prefix = [this, player_index] {
+ if (type == ConfigType::InputProfile) {
+ return QString{};
+ } else {
+ return QStringLiteral("player_%1_").arg(player_index);
+ }
+ }();
+
+ auto& player = Settings::values.players[player_index];
+
+ if (player_prefix.isEmpty()) {
+ const auto controller = static_cast(
+ qt_config
+ ->value(QStringLiteral("%1type").arg(player_prefix),
+ static_cast(Settings::ControllerType::ProController))
+ .toUInt());
+ if (controller == Settings::ControllerType::LeftJoycon ||
+ controller == Settings::ControllerType::RightJoycon) {
+ player.controller_type = controller;
+ }
+ } else {
player.connected =
- ReadSetting(QStringLiteral("player_%1_connected").arg(p), false).toBool();
+ ReadSetting(QStringLiteral("%1connected").arg(player_prefix), false).toBool();
player.controller_type = static_cast(
qt_config
- ->value(QStringLiteral("player_%1_type").arg(p),
+ ->value(QStringLiteral("%1type").arg(player_prefix),
static_cast(Settings::ControllerType::ProController))
.toUInt());
player.body_color_left = qt_config
- ->value(QStringLiteral("player_%1_body_color_left").arg(p),
+ ->value(QStringLiteral("%1body_color_left").arg(player_prefix),
Settings::JOYCON_BODY_NEON_BLUE)
.toUInt();
- player.body_color_right = qt_config
- ->value(QStringLiteral("player_%1_body_color_right").arg(p),
- Settings::JOYCON_BODY_NEON_RED)
- .toUInt();
- player.button_color_left = qt_config
- ->value(QStringLiteral("player_%1_button_color_left").arg(p),
- Settings::JOYCON_BUTTONS_NEON_BLUE)
- .toUInt();
+ player.body_color_right =
+ qt_config
+ ->value(QStringLiteral("%1body_color_right").arg(player_prefix),
+ Settings::JOYCON_BODY_NEON_RED)
+ .toUInt();
+ player.button_color_left =
+ qt_config
+ ->value(QStringLiteral("%1button_color_left").arg(player_prefix),
+ Settings::JOYCON_BUTTONS_NEON_BLUE)
+ .toUInt();
player.button_color_right =
qt_config
- ->value(QStringLiteral("player_%1_button_color_right").arg(p),
+ ->value(QStringLiteral("%1button_color_right").arg(player_prefix),
Settings::JOYCON_BUTTONS_NEON_RED)
.toUInt();
+ }
- for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- const std::string default_param =
- InputCommon::GenerateKeyboardParam(default_buttons[i]);
- auto& player_buttons = player.buttons[i];
-
- player_buttons = qt_config
- ->value(QStringLiteral("player_%1_").arg(p) +
- QString::fromUtf8(Settings::NativeButton::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player_buttons.empty()) {
- player_buttons = default_param;
- }
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ auto& player_buttons = player.buttons[i];
+
+ player_buttons = qt_config
+ ->value(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromUtf8(Settings::NativeButton::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (player_buttons.empty()) {
+ player_buttons = default_param;
}
+ }
- for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
- const std::string default_param =
- InputCommon::GenerateKeyboardParam(default_motions[i]);
- auto& player_motions = player.motions[i];
-
- player_motions = qt_config
- ->value(QStringLiteral("player_%1_").arg(p) +
- QString::fromUtf8(Settings::NativeMotion::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player_motions.empty()) {
- player_motions = default_param;
- }
+ for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
+ auto& player_motions = player.motions[i];
+
+ player_motions = qt_config
+ ->value(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromUtf8(Settings::NativeMotion::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (player_motions.empty()) {
+ player_motions = default_param;
}
+ }
- for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
- default_analogs[i][3], default_stick_mod[i], 0.5f);
- auto& player_analogs = player.analogs[i];
-
- player_analogs = qt_config
- ->value(QStringLiteral("player_%1_").arg(p) +
- QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player_analogs.empty()) {
- player_analogs = default_param;
- }
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ auto& player_analogs = player.analogs[i];
+
+ player_analogs = qt_config
+ ->value(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (player_analogs.empty()) {
+ player_analogs = default_param;
}
}
}
@@ -436,7 +469,9 @@ void Config::ReadAudioValues() {
void Config::ReadControlValues() {
qt_config->beginGroup(QStringLiteral("Controls"));
- ReadPlayerValues();
+ for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
+ ReadPlayerValue(p);
+ }
ReadDebugValues();
ReadKeyboardValues();
ReadMouseValues();
@@ -920,49 +955,55 @@ void Config::ReadValues() {
ReadSystemValues();
}
-void Config::SavePlayerValues() {
- for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
- const auto& player = Settings::values.players[p];
+void Config::SavePlayerValue(std::size_t player_index) {
+ const QString player_prefix = [this, player_index] {
+ if (type == ConfigType::InputProfile) {
+ return QString{};
+ } else {
+ return QStringLiteral("player_%1_").arg(player_index);
+ }
+ }();
+
+ const auto& player = Settings::values.players[player_index];
- WriteSetting(QStringLiteral("player_%1_connected").arg(p), player.connected, false);
- WriteSetting(QStringLiteral("player_%1_type").arg(p),
- static_cast(player.controller_type),
- static_cast(Settings::ControllerType::ProController));
+ WriteSetting(QStringLiteral("%1type").arg(player_prefix),
+ static_cast(player.controller_type),
+ static_cast(Settings::ControllerType::ProController));
- WriteSetting(QStringLiteral("player_%1_body_color_left").arg(p), player.body_color_left,
+ if (!player_prefix.isEmpty()) {
+ WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, false);
+ WriteSetting(QStringLiteral("%1body_color_left").arg(player_prefix), player.body_color_left,
Settings::JOYCON_BODY_NEON_BLUE);
- WriteSetting(QStringLiteral("player_%1_body_color_right").arg(p), player.body_color_right,
- Settings::JOYCON_BODY_NEON_RED);
- WriteSetting(QStringLiteral("player_%1_button_color_left").arg(p), player.button_color_left,
- Settings::JOYCON_BUTTONS_NEON_BLUE);
- WriteSetting(QStringLiteral("player_%1_button_color_right").arg(p),
+ WriteSetting(QStringLiteral("%1body_color_right").arg(player_prefix),
+ player.body_color_right, Settings::JOYCON_BODY_NEON_RED);
+ WriteSetting(QStringLiteral("%1button_color_left").arg(player_prefix),
+ player.button_color_left, Settings::JOYCON_BUTTONS_NEON_BLUE);
+ WriteSetting(QStringLiteral("%1button_color_right").arg(player_prefix),
player.button_color_right, Settings::JOYCON_BUTTONS_NEON_RED);
+ }
- for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- const std::string default_param =
- InputCommon::GenerateKeyboardParam(default_buttons[i]);
- WriteSetting(QStringLiteral("player_%1_").arg(p) +
- QString::fromStdString(Settings::NativeButton::mapping[i]),
- QString::fromStdString(player.buttons[i]),
- QString::fromStdString(default_param));
- }
- for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
- const std::string default_param =
- InputCommon::GenerateKeyboardParam(default_motions[i]);
- WriteSetting(QStringLiteral("player_%1_").arg(p) +
- QString::fromStdString(Settings::NativeMotion::mapping[i]),
- QString::fromStdString(player.motions[i]),
- QString::fromStdString(default_param));
- }
- for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
- default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
- default_analogs[i][3], default_stick_mod[i], 0.5f);
- WriteSetting(QStringLiteral("player_%1_").arg(p) +
- QString::fromStdString(Settings::NativeAnalog::mapping[i]),
- QString::fromStdString(player.analogs[i]),
- QString::fromStdString(default_param));
- }
+ for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ WriteSetting(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromStdString(Settings::NativeButton::mapping[i]),
+ QString::fromStdString(player.buttons[i]),
+ QString::fromStdString(default_param));
+ }
+ for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
+ WriteSetting(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromStdString(Settings::NativeMotion::mapping[i]),
+ QString::fromStdString(player.motions[i]),
+ QString::fromStdString(default_param));
+ }
+ for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
+ const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
+ default_analogs[i][3], default_stick_mod[i], 0.5f);
+ WriteSetting(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromStdString(Settings::NativeAnalog::mapping[i]),
+ QString::fromStdString(player.analogs[i]),
+ QString::fromStdString(default_param));
}
}
@@ -1087,7 +1128,9 @@ void Config::SaveAudioValues() {
void Config::SaveControlValues() {
qt_config->beginGroup(QStringLiteral("Controls"));
- SavePlayerValues();
+ for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
+ SavePlayerValue(p);
+ }
SaveDebugValues();
SaveMouseValues();
SaveTouchscreenValues();
@@ -1515,3 +1558,19 @@ void Config::Save() {
Settings::Sanitize();
SaveValues();
}
+
+void Config::ReadControlPlayerValue(std::size_t player_index) {
+ qt_config->beginGroup(QStringLiteral("Controls"));
+ ReadPlayerValue(player_index);
+ qt_config->endGroup();
+}
+
+void Config::SaveControlPlayerValue(std::size_t player_index) {
+ qt_config->beginGroup(QStringLiteral("Controls"));
+ SavePlayerValue(player_index);
+ qt_config->endGroup();
+}
+
+const std::string& Config::GetConfigFilePath() const {
+ return qt_config_loc;
+}
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 5d8e45d78..a1ffca48f 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -16,12 +16,24 @@ class QSettings;
class Config {
public:
- explicit Config(const std::string& config_loc = "qt-config.ini", bool is_global = true);
+ enum class ConfigType {
+ GlobalConfig,
+ PerGameConfig,
+ InputProfile,
+ };
+
+ explicit Config(const std::string& config_loc = "qt-config",
+ ConfigType config_type = ConfigType::GlobalConfig);
~Config();
void Reload();
void Save();
+ void ReadControlPlayerValue(std::size_t player_index);
+ void SaveControlPlayerValue(std::size_t player_index);
+
+ const std::string& GetConfigFilePath() const;
+
static const std::array default_buttons;
static const std::array default_motions;
static const std::array, Settings::NativeAnalog::NumAnalogs> default_analogs;
@@ -34,7 +46,7 @@ public:
private:
void ReadValues();
- void ReadPlayerValues();
+ void ReadPlayerValue(std::size_t player_index);
void ReadDebugValues();
void ReadKeyboardValues();
void ReadMouseValues();
@@ -62,7 +74,7 @@ private:
void ReadWebServiceValues();
void SaveValues();
- void SavePlayerValues();
+ void SavePlayerValue(std::size_t player_index);
void SaveDebugValues();
void SaveMouseValues();
void SaveTouchscreenValues();
@@ -111,9 +123,9 @@ private:
void WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
const QVariant& default_value);
+ ConfigType type;
std::unique_ptr qt_config;
std::string qt_config_loc;
-
bool global;
};
diff --git a/src/yuzu/configuration/configure_debug_controller.cpp b/src/yuzu/configuration/configure_debug_controller.cpp
index 0097c9a29..6dc9c5e57 100644
--- a/src/yuzu/configuration/configure_debug_controller.cpp
+++ b/src/yuzu/configuration/configure_debug_controller.cpp
@@ -6,9 +6,11 @@
#include "yuzu/configuration/configure_debug_controller.h"
ConfigureDebugController::ConfigureDebugController(QWidget* parent,
- InputCommon::InputSubsystem* input_subsystem)
+ InputCommon::InputSubsystem* input_subsystem,
+ InputProfiles* profiles)
: QDialog(parent), ui(std::make_unique()),
- debug_controller(new ConfigureInputPlayer(this, 9, nullptr, input_subsystem, true)) {
+ debug_controller(
+ new ConfigureInputPlayer(this, 9, nullptr, input_subsystem, profiles, true)) {
ui->setupUi(this);
ui->controllerLayout->addWidget(debug_controller);
diff --git a/src/yuzu/configuration/configure_debug_controller.h b/src/yuzu/configuration/configure_debug_controller.h
index 34dcf705f..2694b3419 100644
--- a/src/yuzu/configuration/configure_debug_controller.h
+++ b/src/yuzu/configuration/configure_debug_controller.h
@@ -10,6 +10,8 @@
class QPushButton;
+class InputProfiles;
+
namespace InputCommon {
class InputSubsystem;
}
@@ -22,8 +24,8 @@ class ConfigureDebugController : public QDialog {
Q_OBJECT
public:
- explicit ConfigureDebugController(QWidget* parent,
- InputCommon::InputSubsystem* input_subsystem);
+ explicit ConfigureDebugController(QWidget* parent, InputCommon::InputSubsystem* input_subsystem,
+ InputProfiles* profiles);
~ConfigureDebugController() override;
void ApplyConfiguration();
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index f2932aa0b..523ece426 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -23,6 +23,7 @@
#include "yuzu/configuration/configure_motion_touch.h"
#include "yuzu/configuration/configure_mouse_advanced.h"
#include "yuzu/configuration/configure_touchscreen_advanced.h"
+#include "yuzu/configuration/input_profiles.h"
namespace {
template
@@ -64,7 +65,8 @@ void OnDockedModeChanged(bool last_state, bool new_state) {
}
ConfigureInput::ConfigureInput(QWidget* parent)
- : QWidget(parent), ui(std::make_unique()) {
+ : QWidget(parent), ui(std::make_unique()),
+ profiles(std::make_unique()) {
ui->setupUi(this);
}
@@ -73,14 +75,22 @@ ConfigureInput::~ConfigureInput() = default;
void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
std::size_t max_players) {
player_controllers = {
- new ConfigureInputPlayer(this, 0, ui->consoleInputSettings, input_subsystem),
- new ConfigureInputPlayer(this, 1, ui->consoleInputSettings, input_subsystem),
- new ConfigureInputPlayer(this, 2, ui->consoleInputSettings, input_subsystem),
- new ConfigureInputPlayer(this, 3, ui->consoleInputSettings, input_subsystem),
- new ConfigureInputPlayer(this, 4, ui->consoleInputSettings, input_subsystem),
- new ConfigureInputPlayer(this, 5, ui->consoleInputSettings, input_subsystem),
- new ConfigureInputPlayer(this, 6, ui->consoleInputSettings, input_subsystem),
- new ConfigureInputPlayer(this, 7, ui->consoleInputSettings, input_subsystem),
+ new ConfigureInputPlayer(this, 0, ui->consoleInputSettings, input_subsystem,
+ profiles.get()),
+ new ConfigureInputPlayer(this, 1, ui->consoleInputSettings, input_subsystem,
+ profiles.get()),
+ new ConfigureInputPlayer(this, 2, ui->consoleInputSettings, input_subsystem,
+ profiles.get()),
+ new ConfigureInputPlayer(this, 3, ui->consoleInputSettings, input_subsystem,
+ profiles.get()),
+ new ConfigureInputPlayer(this, 4, ui->consoleInputSettings, input_subsystem,
+ profiles.get()),
+ new ConfigureInputPlayer(this, 5, ui->consoleInputSettings, input_subsystem,
+ profiles.get()),
+ new ConfigureInputPlayer(this, 6, ui->consoleInputSettings, input_subsystem,
+ profiles.get()),
+ new ConfigureInputPlayer(this, 7, ui->consoleInputSettings, input_subsystem,
+ profiles.get()),
};
player_tabs = {
@@ -134,7 +144,7 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
ui->tabAdvanced->setLayout(new QHBoxLayout(ui->tabAdvanced));
ui->tabAdvanced->layout()->addWidget(advanced);
connect(advanced, &ConfigureInputAdvanced::CallDebugControllerDialog, [this, input_subsystem] {
- CallConfigureDialog(*this, input_subsystem);
+ CallConfigureDialog(*this, input_subsystem, profiles.get());
});
connect(advanced, &ConfigureInputAdvanced::CallMouseConfigDialog, [this, input_subsystem] {
CallConfigureDialog(*this, input_subsystem);
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h
index 0e8b2fd4e..f135a4299 100644
--- a/src/yuzu/configuration/configure_input.h
+++ b/src/yuzu/configuration/configure_input.h
@@ -19,6 +19,8 @@ class QCheckBox;
class QString;
class QTimer;
+class InputProfiles;
+
namespace InputCommon {
class InputSubsystem;
}
@@ -61,6 +63,8 @@ private:
std::unique_ptr ui;
+ std::unique_ptr profiles;
+
std::array player_controllers;
std::array player_tabs;
std::array player_connected;
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 0de0c6999..b4de2f6af 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -22,6 +22,8 @@
#include "ui_configure_input_player.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input_player.h"
+#include "yuzu/configuration/input_profiles.h"
+#include "yuzu/util/limitable_input_dialog.h"
constexpr std::size_t HANDHELD_INDEX = 8;
@@ -240,10 +242,11 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir)
ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index,
QWidget* bottom_row,
InputCommon::InputSubsystem* input_subsystem_,
- bool debug)
+ InputProfiles* profiles_, bool debug)
: QWidget(parent), ui(std::make_unique()), player_index(player_index),
- debug(debug), input_subsystem{input_subsystem_}, timeout_timer(std::make_unique()),
- poll_timer(std::make_unique()), bottom_row(bottom_row) {
+ debug(debug), input_subsystem{input_subsystem_}, profiles(profiles_),
+ timeout_timer(std::make_unique()), poll_timer(std::make_unique()),
+ bottom_row(bottom_row) {
ui->setupUi(this);
setFocusPolicy(Qt::ClickFocus);
@@ -521,6 +524,17 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
}
});
+ RefreshInputProfiles();
+
+ connect(ui->buttonProfilesNew, &QPushButton::clicked, this,
+ &ConfigureInputPlayer::CreateProfile);
+ connect(ui->buttonProfilesDelete, &QPushButton::clicked, this,
+ &ConfigureInputPlayer::DeleteProfile);
+ connect(ui->comboProfiles, qOverload(&QComboBox::activated), this,
+ &ConfigureInputPlayer::LoadProfile);
+ connect(ui->buttonProfilesSave, &QPushButton::clicked, this,
+ &ConfigureInputPlayer::SaveProfile);
+
LoadConfiguration();
// TODO(wwylele): enable this when we actually emulate it
@@ -1061,3 +1075,94 @@ void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
SetPollingResult({}, true);
}
+
+void ConfigureInputPlayer::CreateProfile() {
+ const auto profile_name =
+ LimitableInputDialog::GetText(this, tr("New Profile"), tr("Enter a profile name:"), 1, 20);
+
+ if (profile_name.isEmpty()) {
+ return;
+ }
+
+ if (!profiles->IsProfileNameValid(profile_name.toStdString())) {
+ QMessageBox::critical(this, tr("Create Input Profile"),
+ tr("The given profile name is not valid!"));
+ return;
+ }
+
+ ApplyConfiguration();
+
+ if (!profiles->CreateProfile(profile_name.toStdString(), player_index)) {
+ QMessageBox::critical(this, tr("Create Input Profile"),
+ tr("Failed to create the input profile \"%1\"").arg(profile_name));
+ RefreshInputProfiles();
+ return;
+ }
+
+ ui->comboProfiles->addItem(profile_name);
+ ui->comboProfiles->setCurrentIndex(ui->comboProfiles->count() - 1);
+}
+
+void ConfigureInputPlayer::DeleteProfile() {
+ const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
+
+ if (profile_name.isEmpty()) {
+ return;
+ }
+
+ if (!profiles->DeleteProfile(profile_name.toStdString())) {
+ QMessageBox::critical(this, tr("Delete Input Profile"),
+ tr("Failed to delete the input profile \"%1\"").arg(profile_name));
+ RefreshInputProfiles();
+ return;
+ }
+
+ ui->comboProfiles->removeItem(ui->comboProfiles->currentIndex());
+ ui->comboProfiles->setCurrentIndex(-1);
+}
+
+void ConfigureInputPlayer::LoadProfile() {
+ const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
+
+ if (profile_name.isEmpty()) {
+ return;
+ }
+
+ ApplyConfiguration();
+
+ if (!profiles->LoadProfile(profile_name.toStdString(), player_index)) {
+ QMessageBox::critical(this, tr("Load Input Profile"),
+ tr("Failed to load the input profile \"%1\"").arg(profile_name));
+ RefreshInputProfiles();
+ return;
+ }
+
+ LoadConfiguration();
+}
+
+void ConfigureInputPlayer::SaveProfile() {
+ const QString profile_name = ui->comboProfiles->itemText(ui->comboProfiles->currentIndex());
+
+ if (profile_name.isEmpty()) {
+ return;
+ }
+
+ ApplyConfiguration();
+
+ if (!profiles->SaveProfile(profile_name.toStdString(), player_index)) {
+ QMessageBox::critical(this, tr("Save Input Profile"),
+ tr("Failed to save the input profile \"%1\"").arg(profile_name));
+ RefreshInputProfiles();
+ return;
+ }
+}
+
+void ConfigureInputPlayer::RefreshInputProfiles() {
+ ui->comboProfiles->clear();
+
+ for (const auto& profile_name : profiles->GetInputProfileNames()) {
+ ui->comboProfiles->addItem(QString::fromStdString(profile_name));
+ }
+
+ ui->comboProfiles->setCurrentIndex(-1);
+}
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index a5414e624..05dee5af5 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -26,6 +26,8 @@ class QString;
class QTimer;
class QWidget;
+class InputProfiles;
+
namespace InputCommon {
class InputSubsystem;
}
@@ -45,7 +47,7 @@ class ConfigureInputPlayer : public QWidget {
public:
explicit ConfigureInputPlayer(QWidget* parent, std::size_t player_index, QWidget* bottom_row,
InputCommon::InputSubsystem* input_subsystem_,
- bool debug = false);
+ InputProfiles* profiles_, bool debug = false);
~ConfigureInputPlayer() override;
/// Save all button configurations to settings file.
@@ -116,6 +118,21 @@ private:
/// Gets the default controller mapping for this device and auto configures the input to match.
void UpdateMappingWithDefaults();
+ /// Creates a controller profile.
+ void CreateProfile();
+
+ /// Deletes the selected controller profile.
+ void DeleteProfile();
+
+ /// Loads the selected controller profile.
+ void LoadProfile();
+
+ /// Saves the current controller configuration into a selected controller profile.
+ void SaveProfile();
+
+ /// Refreshes the list of controller profiles.
+ void RefreshInputProfiles();
+
std::unique_ptr ui;
std::size_t player_index;
@@ -123,6 +140,8 @@ private:
InputCommon::InputSubsystem* input_subsystem;
+ InputProfiles* profiles;
+
std::unique_ptr timeout_timer;
std::unique_ptr poll_timer;
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index 002db3f93..81464dd37 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -29,7 +29,8 @@
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id)
: QDialog(parent), ui(std::make_unique()), title_id(title_id) {
- game_config = std::make_unique(fmt::format("{:016X}.ini", title_id), false);
+ game_config = std::make_unique(fmt::format("{:016X}", title_id),
+ Config::ConfigType::PerGameConfig);
Settings::SetConfiguringGlobal(false);
diff --git a/src/yuzu/configuration/input_profiles.cpp b/src/yuzu/configuration/input_profiles.cpp
new file mode 100644
index 000000000..e87aededb
--- /dev/null
+++ b/src/yuzu/configuration/input_profiles.cpp
@@ -0,0 +1,131 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include
+
+#include "common/common_paths.h"
+#include "common/file_util.h"
+#include "yuzu/configuration/config.h"
+#include "yuzu/configuration/input_profiles.h"
+
+namespace FS = Common::FS;
+
+namespace {
+
+bool ProfileExistsInFilesystem(std::string_view profile_name) {
+ return FS::Exists(fmt::format("{}input" DIR_SEP "{}.ini",
+ FS::GetUserPath(FS::UserPath::ConfigDir), profile_name));
+}
+
+bool IsINI(std::string_view filename) {
+ const std::size_t index = filename.rfind('.');
+
+ if (index == std::string::npos) {
+ return false;
+ }
+
+ return filename.substr(index) == ".ini";
+}
+
+std::string GetNameWithoutExtension(const std::string& filename) {
+ const std::size_t index = filename.rfind('.');
+
+ if (index == std::string::npos) {
+ return filename;
+ }
+
+ return filename.substr(0, index);
+}
+
+} // namespace
+
+InputProfiles::InputProfiles() {
+ const std::string input_profile_loc =
+ fmt::format("{}input", FS::GetUserPath(FS::UserPath::ConfigDir));
+
+ FS::ForeachDirectoryEntry(
+ nullptr, input_profile_loc,
+ [this](u64* entries_out, const std::string& directory, const std::string& filename) {
+ if (IsINI(filename) && IsProfileNameValid(GetNameWithoutExtension(filename))) {
+ map_profiles.insert_or_assign(
+ GetNameWithoutExtension(filename),
+ std::make_unique(GetNameWithoutExtension(filename),
+ Config::ConfigType::InputProfile));
+ }
+ return true;
+ });
+}
+
+InputProfiles::~InputProfiles() = default;
+
+std::vector InputProfiles::GetInputProfileNames() {
+ std::vector profile_names;
+ profile_names.reserve(map_profiles.size());
+
+ for (const auto& [profile_name, config] : map_profiles) {
+ if (!ProfileExistsInFilesystem(profile_name)) {
+ DeleteProfile(profile_name);
+ continue;
+ }
+
+ profile_names.push_back(profile_name);
+ }
+
+ return profile_names;
+}
+
+bool InputProfiles::IsProfileNameValid(std::string_view profile_name) {
+ return profile_name.find_first_of("<>:;\"/\\|,.!?*") == std::string::npos;
+}
+
+bool InputProfiles::CreateProfile(const std::string& profile_name, std::size_t player_index) {
+ if (ProfileExistsInMap(profile_name)) {
+ return false;
+ }
+
+ map_profiles.insert_or_assign(
+ profile_name, std::make_unique(profile_name, Config::ConfigType::InputProfile));
+
+ return SaveProfile(profile_name, player_index);
+}
+
+bool InputProfiles::DeleteProfile(const std::string& profile_name) {
+ if (!ProfileExistsInMap(profile_name)) {
+ return false;
+ }
+
+ if (!ProfileExistsInFilesystem(profile_name) ||
+ FS::Delete(map_profiles[profile_name]->GetConfigFilePath())) {
+ map_profiles.erase(profile_name);
+ }
+
+ return !ProfileExistsInMap(profile_name) && !ProfileExistsInFilesystem(profile_name);
+}
+
+bool InputProfiles::LoadProfile(const std::string& profile_name, std::size_t player_index) {
+ if (!ProfileExistsInMap(profile_name)) {
+ return false;
+ }
+
+ if (!ProfileExistsInFilesystem(profile_name)) {
+ map_profiles.erase(profile_name);
+ return false;
+ }
+
+ map_profiles[profile_name]->ReadControlPlayerValue(player_index);
+ return true;
+}
+
+bool InputProfiles::SaveProfile(const std::string& profile_name, std::size_t player_index) {
+ if (!ProfileExistsInMap(profile_name)) {
+ return false;
+ }
+
+ map_profiles[profile_name]->SaveControlPlayerValue(player_index);
+ return true;
+}
+
+bool InputProfiles::ProfileExistsInMap(const std::string& profile_name) const {
+ return map_profiles.find(profile_name) != map_profiles.end();
+}
diff --git a/src/yuzu/configuration/input_profiles.h b/src/yuzu/configuration/input_profiles.h
new file mode 100644
index 000000000..cb41fd9be
--- /dev/null
+++ b/src/yuzu/configuration/input_profiles.h
@@ -0,0 +1,32 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+#include
+#include
+
+class Config;
+
+class InputProfiles {
+
+public:
+ explicit InputProfiles();
+ virtual ~InputProfiles();
+
+ std::vector GetInputProfileNames();
+
+ static bool IsProfileNameValid(std::string_view profile_name);
+
+ bool CreateProfile(const std::string& profile_name, std::size_t player_index);
+ bool DeleteProfile(const std::string& profile_name);
+ bool LoadProfile(const std::string& profile_name, std::size_t player_index);
+ bool SaveProfile(const std::string& profile_name, std::size_t player_index);
+
+private:
+ bool ProfileExistsInMap(const std::string& profile_name) const;
+
+ std::unordered_map> map_profiles;
+};
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 18e68e590..4ff7fd92f 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1087,7 +1087,7 @@ void GMainWindow::BootGame(const QString& filename) {
const auto loader = Loader::GetLoader(v_file);
if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) {
// Load per game settings
- Config per_game_config(fmt::format("{:016X}.ini", title_id), false);
+ Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig);
}
Settings::LogSettings();
--
cgit v1.2.3
From 484623cd613b01a029a8a837ed7e2e5657d27202 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sun, 27 Sep 2020 09:50:35 -0400
Subject: bootmanager: Allow mouse clicks only if touch is disabled
Previously mouse clicks will not register when touch is disabled.
This rectifies that and allows mouse clicks to be mapped to other buttons if the touchscreen is disabled.
---
src/yuzu/bootmanager.cpp | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index e38bc7a9a..d62b0efc2 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -382,7 +382,12 @@ void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
}
void GRenderWindow::mousePressEvent(QMouseEvent* event) {
- // touch input is handled in TouchBeginEvent
+ if (!Settings::values.touchscreen.enabled) {
+ input_subsystem->GetKeyboard()->PressKey(event->button());
+ return;
+ }
+
+ // Touch input is handled in TouchBeginEvent
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
@@ -398,7 +403,7 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
}
void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
- // touch input is handled in TouchUpdateEvent
+ // Touch input is handled in TouchUpdateEvent
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
@@ -411,7 +416,12 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
}
void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
- // touch input is handled in TouchEndEvent
+ if (!Settings::values.touchscreen.enabled) {
+ input_subsystem->GetKeyboard()->ReleaseKey(event->button());
+ return;
+ }
+
+ // Touch input is handled in TouchEndEvent
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
--
cgit v1.2.3
From 5cafa70d3b7f24881b578d2d473dc993fc47364b Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sun, 27 Sep 2020 11:18:07 -0400
Subject: applets/controller: Auto accept a valid single player configuration
---
src/yuzu/applets/controller.cpp | 29 ++++++++++++++++++-----------
src/yuzu/applets/controller.h | 8 +++++---
src/yuzu/main.cpp | 1 +
3 files changed, 24 insertions(+), 14 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index c6fa3e4f6..ee770f315 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -229,6 +229,13 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
&QtControllerSelectorDialog::ApplyConfiguration);
+ // Enhancement: Check if the parameters have already been met before disconnecting controllers.
+ // If all the parameters are met AND only allows a single player,
+ // stop the constructor here as we do not need to continue.
+ if (CheckIfParametersMet() && parameters.enable_single_mode) {
+ return;
+ }
+
// If keep_controllers_connected is false, forcefully disconnect all controllers
if (!parameters.keep_controllers_connected) {
for (auto player : player_groupboxes) {
@@ -236,13 +243,18 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
}
}
- CheckIfParametersMet();
-
resize(0, 0);
}
QtControllerSelectorDialog::~QtControllerSelectorDialog() = default;
+int QtControllerSelectorDialog::exec() {
+ if (parameters_met && parameters.enable_single_mode) {
+ return QDialog::Accepted;
+ }
+ return QDialog::exec();
+}
+
void QtControllerSelectorDialog::ApplyConfiguration() {
// Update the controller state once more, just to be sure they are properly applied.
for (std::size_t index = 0; index < NUM_PLAYERS; ++index) {
@@ -287,7 +299,7 @@ void QtControllerSelectorDialog::CallConfigureInputDialog() {
CheckIfParametersMet();
}
-void QtControllerSelectorDialog::CheckIfParametersMet() {
+bool QtControllerSelectorDialog::CheckIfParametersMet() {
// Here, we check and validate the current configuration against all applicable parameters.
const auto num_connected_players = static_cast(
std::count_if(player_groupboxes.begin(), player_groupboxes.end(),
@@ -301,7 +313,7 @@ void QtControllerSelectorDialog::CheckIfParametersMet() {
num_connected_players > max_supported_players) {
parameters_met = false;
ui->buttonBox->setEnabled(parameters_met);
- return;
+ return parameters_met;
}
// Next, check against all connected controllers.
@@ -326,14 +338,9 @@ void QtControllerSelectorDialog::CheckIfParametersMet() {
return true;
}();
- if (!all_controllers_compatible) {
- parameters_met = false;
- ui->buttonBox->setEnabled(parameters_met);
- return;
- }
-
- parameters_met = true;
+ parameters_met = all_controllers_compatible;
ui->buttonBox->setEnabled(parameters_met);
+ return parameters_met;
}
void QtControllerSelectorDialog::SetSupportedControllers() {
diff --git a/src/yuzu/applets/controller.h b/src/yuzu/applets/controller.h
index 729ecc831..8fefecf05 100644
--- a/src/yuzu/applets/controller.h
+++ b/src/yuzu/applets/controller.h
@@ -33,6 +33,8 @@ public:
InputCommon::InputSubsystem* input_subsystem_);
~QtControllerSelectorDialog() override;
+ int exec() override;
+
private:
// Applies the current configuration.
void ApplyConfiguration();
@@ -43,9 +45,9 @@ private:
// Initializes the "Configure Input" Dialog.
void CallConfigureInputDialog();
- // Checks the current configuration against the given parameters and
- // sets the value of parameters_met.
- void CheckIfParametersMet();
+ // Checks the current configuration against the given parameters.
+ // This sets and returns the value of parameters_met.
+ bool CheckIfParametersMet();
// Sets the controller icons for "Supported Controller Types".
void SetSupportedControllers();
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 4ff7fd92f..5f9f416ea 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -288,6 +288,7 @@ GMainWindow::~GMainWindow() {
void GMainWindow::ControllerSelectorReconfigureControllers(
const Core::Frontend::ControllerParameters& parameters) {
QtControllerSelectorDialog dialog(this, parameters, input_subsystem.get());
+
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
dialog.setWindowModality(Qt::WindowModal);
--
cgit v1.2.3
From c0c4ed0d3bff9670bfaab6a8de304e37ec9e0896 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sun, 27 Sep 2020 11:40:15 -0400
Subject: controllers/npad: Connect a controller on init if none are connected
---
src/core/hle/service/hid/controllers/npad.cpp | 13 +++++++++++++
src/yuzu/configuration/config.cpp | 3 ++-
2 files changed, 15 insertions(+), 1 deletion(-)
(limited to 'src/yuzu')
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index e311bc18c..c4b26196a 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -224,6 +224,19 @@ void Controller_NPad::OnInit() {
player.connected};
});
+ // Connect the Player 1 or Handheld controller if none are connected.
+ if (std::none_of(connected_controllers.begin(), connected_controllers.end(),
+ [](const ControllerHolder& controller) { return controller.is_connected; })) {
+ const auto controller = MapSettingsTypeToNPad(Settings::values.players[0].controller_type);
+ if (controller == NPadControllerType::Handheld) {
+ Settings::values.players[HANDHELD_INDEX].connected = true;
+ connected_controllers[HANDHELD_INDEX] = {controller, true};
+ } else {
+ Settings::values.players[0].connected = true;
+ connected_controllers[0] = {controller, true};
+ }
+ }
+
// Account for handheld
if (connected_controllers[HANDHELD_INDEX].is_connected) {
connected_controllers[HANDHELD_INDEX].type = NPadControllerType::Handheld;
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 5c8b02fbe..545cafca9 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -280,7 +280,8 @@ void Config::ReadPlayerValue(std::size_t player_index) {
}
} else {
player.connected =
- ReadSetting(QStringLiteral("%1connected").arg(player_prefix), false).toBool();
+ ReadSetting(QStringLiteral("%1connected").arg(player_prefix), player_index == 0)
+ .toBool();
player.controller_type = static_cast(
qt_config
--
cgit v1.2.3
From 64e174237e7ad9ae082e24303d321534f4e78bca Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sun, 27 Sep 2020 14:20:22 -0400
Subject: config: Migrate config files into config/custom
Co-authored-by: lat9nq
---
src/yuzu/configuration/config.cpp | 49 ++++++++++++++++++++++++---------------
src/yuzu/configuration/config.h | 4 +++-
src/yuzu/main.cpp | 28 +++++++++++++++++++++-
src/yuzu/main.h | 1 +
4 files changed, 61 insertions(+), 21 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 545cafca9..618f991b0 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -15,27 +15,10 @@
namespace FS = Common::FS;
-Config::Config(const std::string& config_file, ConfigType config_type) : type(config_type) {
+Config::Config(const std::string& config_name, ConfigType config_type) : type(config_type) {
global = config_type == ConfigType::GlobalConfig;
- switch (config_type) {
- case ConfigType::GlobalConfig:
- case ConfigType::PerGameConfig:
- qt_config_loc = fmt::format("{}" DIR_SEP "{}.ini", FS::GetUserPath(FS::UserPath::ConfigDir),
- config_file);
- FS::CreateFullPath(qt_config_loc);
- qt_config = std::make_unique(QString::fromStdString(qt_config_loc),
- QSettings::IniFormat);
- Reload();
- break;
- case ConfigType::InputProfile:
- qt_config_loc = fmt::format("{}input" DIR_SEP "{}.ini",
- FS::GetUserPath(FS::UserPath::ConfigDir), config_file);
- FS::CreateFullPath(qt_config_loc);
- qt_config = std::make_unique(QString::fromStdString(qt_config_loc),
- QSettings::IniFormat);
- break;
- }
+ Initialize(config_name);
}
Config::~Config() {
@@ -256,6 +239,34 @@ const std::array Config::default_hotkeys{{
}};
// clang-format on
+void Config::Initialize(const std::string& config_name) {
+ switch (type) {
+ case ConfigType::GlobalConfig:
+ qt_config_loc = fmt::format("{}" DIR_SEP "{}.ini", FS::GetUserPath(FS::UserPath::ConfigDir),
+ config_name);
+ FS::CreateFullPath(qt_config_loc);
+ qt_config = std::make_unique(QString::fromStdString(qt_config_loc),
+ QSettings::IniFormat);
+ Reload();
+ break;
+ case ConfigType::PerGameConfig:
+ qt_config_loc = fmt::format("{}custom" DIR_SEP "{}.ini",
+ FS::GetUserPath(FS::UserPath::ConfigDir), config_name);
+ FS::CreateFullPath(qt_config_loc);
+ qt_config = std::make_unique(QString::fromStdString(qt_config_loc),
+ QSettings::IniFormat);
+ Reload();
+ break;
+ case ConfigType::InputProfile:
+ qt_config_loc = fmt::format("{}input" DIR_SEP "{}.ini",
+ FS::GetUserPath(FS::UserPath::ConfigDir), config_name);
+ FS::CreateFullPath(qt_config_loc);
+ qt_config = std::make_unique(QString::fromStdString(qt_config_loc),
+ QSettings::IniFormat);
+ break;
+ }
+}
+
void Config::ReadPlayerValue(std::size_t player_index) {
const QString player_prefix = [this, player_index] {
if (type == ConfigType::InputProfile) {
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index a1ffca48f..8a600e19d 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -22,7 +22,7 @@ public:
InputProfile,
};
- explicit Config(const std::string& config_loc = "qt-config",
+ explicit Config(const std::string& config_name = "qt-config",
ConfigType config_type = ConfigType::GlobalConfig);
~Config();
@@ -45,6 +45,8 @@ public:
static const std::array default_hotkeys;
private:
+ void Initialize(const std::string& config_name);
+
void ReadValues();
void ReadPlayerValue(std::size_t player_index);
void ReadDebugValues();
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 5f9f416ea..4a3dea2a5 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -50,6 +50,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include
#include
#include
+#include
#include
#include
#include
@@ -277,6 +278,8 @@ GMainWindow::GMainWindow()
if (args.length() >= 2) {
BootGame(args[1]);
}
+
+ MigrateConfigFiles();
}
GMainWindow::~GMainWindow() {
@@ -1578,7 +1581,8 @@ void GMainWindow::RemoveCustomConfiguration(u64 program_id) {
const QString config_dir =
QString::fromStdString(Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir));
const QString custom_config_file_path =
- config_dir + QString::fromStdString(fmt::format("{:016X}.ini", program_id));
+ config_dir + QStringLiteral("custom") + QDir::separator() +
+ QString::fromStdString(fmt::format("{:016X}.ini", program_id));
if (!QFile::exists(custom_config_file_path)) {
QMessageBox::warning(this, tr("Error Removing Custom Configuration"),
@@ -2394,6 +2398,28 @@ void GMainWindow::OnCaptureScreenshot() {
OnStartGame();
}
+// TODO: Written 2020-10-01: Remove per-game config migration code when it is irrelevant
+void GMainWindow::MigrateConfigFiles() {
+ const std::string& config_dir_str = Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir);
+ const QDir config_dir = QDir(QString::fromStdString(config_dir_str));
+ const QStringList config_dir_list = config_dir.entryList(QStringList(QStringLiteral("*.ini")));
+
+ Common::FS::CreateFullPath(fmt::format("{}custom" DIR_SEP, config_dir_str));
+ for (QStringList::const_iterator it = config_dir_list.constBegin(); it != config_dir_list.constEnd(); ++it) {
+ const auto filename = it->toStdString();
+ if (filename.find_first_not_of("0123456789abcdefACBDEF", 0) < 16) {
+ continue;
+ }
+ const auto origin = fmt::format("{}{}", config_dir_str, filename);
+ const auto destination = fmt::format("{}custom" DIR_SEP "{}", config_dir_str, filename);
+ LOG_INFO(Frontend, "Migrating config file from {} to {}", origin, destination);
+ if (!Common::FS::Rename(origin, destination)) {
+ // Delete the old config file if one already exists in the new location.
+ Common::FS::Delete(origin);
+ }
+ }
+}
+
void GMainWindow::UpdateWindowTitle(const std::string& title_name,
const std::string& title_version) {
const auto full_name = std::string(Common::g_build_fullname);
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index afcfa68a9..b380a66f3 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -251,6 +251,7 @@ private:
std::optional SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
InstallResult InstallNSPXCI(const QString& filename);
InstallResult InstallNCA(const QString& filename);
+ void MigrateConfigFiles();
void UpdateWindowTitle(const std::string& title_name = {},
const std::string& title_version = {});
void UpdateStatusBar();
--
cgit v1.2.3
From 8f2959f6804e0d1048ecaa6f4046622e069fe7db Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Mon, 28 Sep 2020 10:00:15 -0400
Subject: settings: Preparation for per-game input settings
---
src/core/frontend/applets/controller.cpp | 4 +-
src/core/frontend/framebuffer_layout.cpp | 2 +-
src/core/hle/service/am/am.cpp | 4 +-
src/core/hle/service/am/applets/controller.cpp | 2 +-
src/core/hle/service/apm/controller.cpp | 3 +-
src/core/hle/service/hid/controllers/npad.cpp | 42 +++++++++-------
src/core/hle/service/hid/hid.cpp | 4 +-
src/core/hle/service/vi/vi.cpp | 2 +-
src/core/settings.cpp | 8 ++-
src/core/settings.h | 57 +++++++++++++++++-----
src/core/telemetry_session.cpp | 2 +-
src/yuzu/applets/controller.cpp | 30 ++++++------
src/yuzu/configuration/config.cpp | 24 ++++-----
src/yuzu/configuration/configure_input.cpp | 24 ++++-----
.../configuration/configure_input_advanced.cpp | 4 +-
src/yuzu/configuration/configure_input_player.cpp | 8 +--
src/yuzu/main.cpp | 23 +++++----
src/yuzu_cmd/config.cpp | 25 +++++-----
src/yuzu_tester/config.cpp | 14 +++---
19 files changed, 167 insertions(+), 115 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp
index 5582091f4..1ac2fb80c 100644
--- a/src/core/frontend/applets/controller.cpp
+++ b/src/core/frontend/applets/controller.cpp
@@ -27,7 +27,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function callb
->GetAppletResource()
->GetController(Service::HID::HidController::NPad);
- auto& players = Settings::values.players;
+ auto& players = Settings::values.players.GetValue();
const std::size_t min_supported_players =
parameters.enable_single_mode ? 1 : parameters.min_players;
@@ -66,7 +66,7 @@ void DefaultControllerApplet::ReconfigureControllers(std::function callb
npad.MapSettingsTypeToNPad(Settings::ControllerType::RightJoycon), index);
}
} else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld &&
- !Settings::values.use_docked_mode) {
+ !Settings::values.use_docked_mode.GetValue()) {
// We should *never* reach here under any normal circumstances.
npad.AddNewControllerAt(npad.MapSettingsTypeToNPad(Settings::ControllerType::Handheld),
index);
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 1acc82497..b9a270a55 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -47,7 +47,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale) {
u32 width, height;
- if (Settings::values.use_docked_mode) {
+ if (Settings::values.use_docked_mode.GetValue()) {
width = ScreenDocked::Width * res_scale;
height = ScreenDocked::Height * res_scale;
} else {
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 2ce742e35..eb097738a 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -751,7 +751,7 @@ void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext&
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- if (Settings::values.use_docked_mode) {
+ if (Settings::values.use_docked_mode.GetValue()) {
rb.Push(static_cast(Service::VI::DisplayResolution::DockedWidth) *
static_cast(Settings::values.resolution_factor.GetValue()));
rb.Push(static_cast(Service::VI::DisplayResolution::DockedHeight) *
@@ -824,7 +824,7 @@ void IStorage::Open(Kernel::HLERequestContext& ctx) {
}
void ICommonStateGetter::GetOperationMode(Kernel::HLERequestContext& ctx) {
- const bool use_docked_mode{Settings::values.use_docked_mode};
+ const bool use_docked_mode{Settings::values.use_docked_mode.GetValue()};
LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
IPC::ResponseBuilder rb{ctx, 3};
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp
index a0152b4ea..43b79412e 100644
--- a/src/core/hle/service/am/applets/controller.cpp
+++ b/src/core/hle/service/am/applets/controller.cpp
@@ -222,7 +222,7 @@ void Controller::Execute() {
void Controller::ConfigurationComplete() {
ControllerSupportResultInfo result_info{};
- const auto& players = Settings::values.players;
+ const auto& players = Settings::values.players.GetValue();
// If enable_single_mode is enabled, player_count is 1 regardless of any other parameters.
// Otherwise, only count connected players from P1-P8.
diff --git a/src/core/hle/service/apm/controller.cpp b/src/core/hle/service/apm/controller.cpp
index 25a886238..ce993bad3 100644
--- a/src/core/hle/service/apm/controller.cpp
+++ b/src/core/hle/service/apm/controller.cpp
@@ -69,7 +69,8 @@ void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
}
PerformanceMode Controller::GetCurrentPerformanceMode() const {
- return Settings::values.use_docked_mode ? PerformanceMode::Docked : PerformanceMode::Handheld;
+ return Settings::values.use_docked_mode.GetValue() ? PerformanceMode::Docked
+ : PerformanceMode::Handheld;
}
PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) {
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index c4b26196a..15d5fa6e8 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -184,11 +184,14 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
controller.single_color.button_color = 0;
controller.dual_color_error = ColorReadError::ReadOk;
- controller.left_color.body_color = Settings::values.players[controller_idx].body_color_left;
- controller.left_color.button_color = Settings::values.players[controller_idx].button_color_left;
- controller.right_color.body_color = Settings::values.players[controller_idx].body_color_right;
+ controller.left_color.body_color =
+ Settings::values.players.GetValue()[controller_idx].body_color_left;
+ controller.left_color.button_color =
+ Settings::values.players.GetValue()[controller_idx].button_color_left;
+ controller.right_color.body_color =
+ Settings::values.players.GetValue()[controller_idx].body_color_right;
controller.right_color.button_color =
- Settings::values.players[controller_idx].button_color_right;
+ Settings::values.players.GetValue()[controller_idx].button_color_right;
controller.battery_level[0] = BATTERY_FULL;
controller.battery_level[1] = BATTERY_FULL;
@@ -218,8 +221,9 @@ void Controller_NPad::OnInit() {
style.pokeball.Assign(1);
}
- std::transform(Settings::values.players.begin(), Settings::values.players.end(),
- connected_controllers.begin(), [](const Settings::PlayerInput& player) {
+ std::transform(Settings::values.players.GetValue().begin(),
+ Settings::values.players.GetValue().end(), connected_controllers.begin(),
+ [](const Settings::PlayerInput& player) {
return ControllerHolder{MapSettingsTypeToNPad(player.controller_type),
player.connected};
});
@@ -227,12 +231,13 @@ void Controller_NPad::OnInit() {
// Connect the Player 1 or Handheld controller if none are connected.
if (std::none_of(connected_controllers.begin(), connected_controllers.end(),
[](const ControllerHolder& controller) { return controller.is_connected; })) {
- const auto controller = MapSettingsTypeToNPad(Settings::values.players[0].controller_type);
+ const auto controller =
+ MapSettingsTypeToNPad(Settings::values.players.GetValue()[0].controller_type);
if (controller == NPadControllerType::Handheld) {
- Settings::values.players[HANDHELD_INDEX].connected = true;
+ Settings::values.players.GetValue()[HANDHELD_INDEX].connected = true;
connected_controllers[HANDHELD_INDEX] = {controller, true};
} else {
- Settings::values.players[0].connected = true;
+ Settings::values.players.GetValue()[0].connected = true;
connected_controllers[0] = {controller, true};
}
}
@@ -255,7 +260,7 @@ void Controller_NPad::OnInit() {
}
void Controller_NPad::OnLoadInputDevices() {
- const auto& players = Settings::values.players;
+ const auto& players = Settings::values.players.GetValue();
for (std::size_t i = 0; i < players.size(); ++i) {
std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
@@ -528,7 +533,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
// Try to read sixaxis sensor states
std::array motion_devices;
- if (sixaxis_sensors_enabled && Settings::values.motion_enabled) {
+ if (sixaxis_sensors_enabled && Settings::values.motion_enabled.GetValue()) {
sixaxis_at_rest = true;
for (std::size_t e = 0; e < motion_devices.size(); ++e) {
const auto& device = motions[i][e];
@@ -666,7 +671,7 @@ void Controller_NPad::VibrateController(const std::vector& controllers,
const std::vector& vibrations) {
LOG_TRACE(Service_HID, "called");
- if (!Settings::values.vibration_enabled || !can_controllers_vibrate) {
+ if (!Settings::values.vibration_enabled.GetValue() || !can_controllers_vibrate) {
return;
}
bool success = true;
@@ -714,16 +719,17 @@ void Controller_NPad::UpdateControllerAt(NPadControllerType controller, std::siz
}
if (controller == NPadControllerType::Handheld) {
- Settings::values.players[HANDHELD_INDEX].controller_type =
+ Settings::values.players.GetValue()[HANDHELD_INDEX].controller_type =
MapNPadToSettingsType(controller);
- Settings::values.players[HANDHELD_INDEX].connected = true;
+ Settings::values.players.GetValue()[HANDHELD_INDEX].connected = true;
connected_controllers[HANDHELD_INDEX] = {controller, true};
InitNewlyAddedController(HANDHELD_INDEX);
return;
}
- Settings::values.players[npad_index].controller_type = MapNPadToSettingsType(controller);
- Settings::values.players[npad_index].connected = true;
+ Settings::values.players.GetValue()[npad_index].controller_type =
+ MapNPadToSettingsType(controller);
+ Settings::values.players.GetValue()[npad_index].connected = true;
connected_controllers[npad_index] = {controller, true};
InitNewlyAddedController(npad_index);
}
@@ -733,7 +739,7 @@ void Controller_NPad::DisconnectNPad(u32 npad_id) {
}
void Controller_NPad::DisconnectNPadAtIndex(std::size_t npad_index) {
- Settings::values.players[npad_index].connected = false;
+ Settings::values.players.GetValue()[npad_index].connected = false;
connected_controllers[npad_index].is_connected = false;
auto& controller = shared_memory_entries[npad_index];
@@ -895,7 +901,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const
return false;
}
// Handheld should not be supported in docked mode
- if (Settings::values.use_docked_mode) {
+ if (Settings::values.use_docked_mode.GetValue()) {
return false;
}
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 50f709b25..fb57dec02 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -935,7 +935,7 @@ void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto can_vibrate{rp.Pop()};
- Settings::values.vibration_enabled = can_vibrate;
+ Settings::values.vibration_enabled.SetValue(can_vibrate);
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
@@ -948,7 +948,7 @@ void Hid::IsVibrationPermitted(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
- rb.Push(Settings::values.vibration_enabled);
+ rb.Push(Settings::values.vibration_enabled.GetValue());
}
void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 5b0e371fe..55e00dd93 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -771,7 +771,7 @@ private:
IPC::ResponseBuilder rb{ctx, 6};
rb.Push(RESULT_SUCCESS);
- if (Settings::values.use_docked_mode) {
+ if (Settings::values.use_docked_mode.GetValue()) {
rb.Push(static_cast(Service::VI::DisplayResolution::DockedWidth) *
static_cast(Settings::values.resolution_factor.GetValue()));
rb.Push(static_cast(Service::VI::DisplayResolution::DockedHeight) *
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 0587b9374..aadbc3932 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -49,7 +49,7 @@ void LogSettings() {
};
LOG_INFO(Config, "yuzu Configuration:");
- log_setting("Controls_UseDockedMode", values.use_docked_mode);
+ log_setting("Controls_UseDockedMode", values.use_docked_mode.GetValue());
log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0));
log_setting("System_CurrentUser", values.current_user);
log_setting("System_LanguageIndex", values.language_index.GetValue());
@@ -145,6 +145,12 @@ void RestoreGlobalState() {
values.rng_seed.SetGlobal(true);
values.custom_rtc.SetGlobal(true);
values.sound_index.SetGlobal(true);
+
+ // Controls
+ values.players.SetGlobal(true);
+ values.use_docked_mode.SetGlobal(true);
+ values.vibration_enabled.SetGlobal(true);
+ values.motion_enabled.SetGlobal(true);
}
void Sanitize() {
diff --git a/src/core/settings.h b/src/core/settings.h
index 28616a574..edd2a00ca 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -65,6 +65,38 @@ private:
Type local{};
};
+/**
+ * The InputSetting class allows for getting a reference to either the global or local members.
+ * This is required as we cannot easily modify the values of user-defined types within containers
+ * using the SetValue() member function found in the Setting class. The primary purpose of this
+ * class is to store an array of 10 PlayerInput structs for both the global and local (per-game)
+ * setting and allows for easily accessing and modifying both settings.
+ */
+template
+class InputSetting final {
+public:
+ InputSetting() = default;
+ explicit InputSetting(Type val) : global{val} {}
+ ~InputSetting() = default;
+ void SetGlobal(bool to_global) {
+ use_global = to_global;
+ }
+ bool UsingGlobal() const {
+ return use_global;
+ }
+ Type& GetValue(bool need_global = false) {
+ if (use_global || need_global) {
+ return global;
+ }
+ return local;
+ }
+
+private:
+ bool use_global = true;
+ Type global{};
+ Type local{};
+};
+
struct TouchFromButtonMap {
std::string name;
std::vector buttons;
@@ -133,9 +165,17 @@ struct Values {
Setting sound_index;
// Controls
- std::array players;
+ InputSetting> players;
+
+ Setting use_docked_mode;
- bool use_docked_mode;
+ Setting vibration_enabled;
+
+ Setting motion_enabled;
+ std::string motion_device;
+ std::string udp_input_address;
+ u16 udp_input_port;
+ u8 udp_pad_index;
bool mouse_enabled;
std::string mouse_device;
@@ -149,20 +189,15 @@ struct Values {
ButtonsRaw debug_pad_buttons;
AnalogsRaw debug_pad_analogs;
- bool vibration_enabled;
-
- bool motion_enabled;
- std::string motion_device;
- std::string touch_device;
TouchscreenInput touchscreen;
- std::atomic_bool is_device_reload_pending{true};
+
bool use_touch_from_button;
+ std::string touch_device;
int touch_from_button_map_index;
- std::string udp_input_address;
- u16 udp_input_port;
- u8 udp_pad_index;
std::vector touch_from_button_maps;
+ std::atomic_bool is_device_reload_pending{true};
+
// Data Storage
bool use_virtual_sd;
bool gamecard_inserted;
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp
index ebc19e18a..e0908186b 100644
--- a/src/core/telemetry_session.cpp
+++ b/src/core/telemetry_session.cpp
@@ -213,7 +213,7 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
Settings::values.use_assembly_shaders.GetValue());
AddField(field_type, "Renderer_UseAsynchronousShaders",
Settings::values.use_asynchronous_shaders.GetValue());
- AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode);
+ AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode.GetValue());
}
bool TelemetrySession::SubmitTestcase() {
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index ee770f315..7697fe434 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -261,26 +261,26 @@ void QtControllerSelectorDialog::ApplyConfiguration() {
UpdateControllerState(index);
}
- const bool pre_docked_mode = Settings::values.use_docked_mode;
- Settings::values.use_docked_mode = ui->radioDocked->isChecked();
- OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode);
+ const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
+ Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked());
+ OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
- Settings::values.vibration_enabled = ui->vibrationGroup->isChecked();
+ Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
}
void QtControllerSelectorDialog::LoadConfiguration() {
for (std::size_t index = 0; index < NUM_PLAYERS; ++index) {
- const auto connected = Settings::values.players[index].connected ||
- (index == 0 && Settings::values.players[8].connected);
+ const auto connected = Settings::values.players.GetValue()[index].connected ||
+ (index == 0 && Settings::values.players.GetValue()[8].connected);
player_groupboxes[index]->setChecked(connected);
connected_controller_checkboxes[index]->setChecked(connected);
emulated_controllers[index]->setCurrentIndex(
- GetIndexFromControllerType(Settings::values.players[index].controller_type));
+ GetIndexFromControllerType(Settings::values.players.GetValue()[index].controller_type));
}
- UpdateDockedState(Settings::values.players[8].connected);
+ UpdateDockedState(Settings::values.players.GetValue()[8].connected);
- ui->vibrationGroup->setChecked(Settings::values.vibration_enabled);
+ ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
}
void QtControllerSelectorDialog::CallConfigureInputDialog() {
@@ -448,7 +448,7 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)
}
void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index) {
- auto& player = Settings::values.players[player_index];
+ auto& player = Settings::values.players.GetValue()[player_index];
player.controller_type =
GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex());
@@ -461,7 +461,7 @@ void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index)
}
// Player 1 and Handheld
- auto& handheld = Settings::values.players[8];
+ auto& handheld = Settings::values.players.GetValue()[8];
// If Handheld is selected, copy all the settings from Player 1 to Handheld.
if (player.controller_type == Settings::ControllerType::Handheld) {
handheld = player;
@@ -527,8 +527,8 @@ void QtControllerSelectorDialog::UpdateDockedState(bool is_handheld) {
ui->radioDocked->setEnabled(!is_handheld);
ui->radioUndocked->setEnabled(!is_handheld);
- ui->radioDocked->setChecked(Settings::values.use_docked_mode);
- ui->radioUndocked->setChecked(!Settings::values.use_docked_mode);
+ ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue());
+ ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue());
// Also force into undocked mode if the controller type is handheld.
if (is_handheld) {
@@ -571,8 +571,8 @@ void QtControllerSelectorDialog::DisableUnsupportedPlayers() {
for (std::size_t index = max_supported_players; index < NUM_PLAYERS; ++index) {
// Disconnect any unsupported players here and disable or hide them if applicable.
- Settings::values.players[index].connected = false;
- UpdateController(Settings::values.players[index].controller_type, index, false);
+ Settings::values.players.GetValue()[index].connected = false;
+ UpdateController(Settings::values.players.GetValue()[index].controller_type, index, false);
// Hide the player widgets when max_supported_controllers is less than or equal to 4.
if (max_supported_players <= 4) {
player_widgets[index]->hide();
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 618f991b0..296c58f58 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -276,7 +276,7 @@ void Config::ReadPlayerValue(std::size_t player_index) {
}
}();
- auto& player = Settings::values.players[player_index];
+ auto& player = Settings::values.players.GetValue()[player_index];
if (player_prefix.isEmpty()) {
const auto controller = static_cast(
@@ -481,7 +481,7 @@ void Config::ReadAudioValues() {
void Config::ReadControlValues() {
qt_config->beginGroup(QStringLiteral("Controls"));
- for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
ReadPlayerValue(p);
}
ReadDebugValues();
@@ -490,11 +490,10 @@ void Config::ReadControlValues() {
ReadTouchscreenValues();
ReadMotionTouchValues();
- Settings::values.vibration_enabled =
- ReadSetting(QStringLiteral("vibration_enabled"), true).toBool();
- Settings::values.motion_enabled = ReadSetting(QStringLiteral("motion_enabled"), true).toBool();
- Settings::values.use_docked_mode =
- ReadSetting(QStringLiteral("use_docked_mode"), false).toBool();
+ ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), false);
+ ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"),
+ true);
+ ReadSettingGlobal(Settings::values.motion_enabled, QStringLiteral("motion_enabled"), true);
qt_config->endGroup();
}
@@ -976,7 +975,7 @@ void Config::SavePlayerValue(std::size_t player_index) {
}
}();
- const auto& player = Settings::values.players[player_index];
+ const auto& player = Settings::values.players.GetValue()[player_index];
WriteSetting(QStringLiteral("%1type").arg(player_prefix),
static_cast(player.controller_type),
@@ -1140,7 +1139,7 @@ void Config::SaveAudioValues() {
void Config::SaveControlValues() {
qt_config->beginGroup(QStringLiteral("Controls"));
- for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
SavePlayerValue(p);
}
SaveDebugValues();
@@ -1148,8 +1147,10 @@ void Config::SaveControlValues() {
SaveTouchscreenValues();
SaveMotionTouchValues();
- WriteSetting(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled, true);
- WriteSetting(QStringLiteral("motion_enabled"), Settings::values.motion_enabled, true);
+ WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
+ WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled,
+ true);
+ WriteSettingGlobal(QStringLiteral("motion_enabled"), Settings::values.motion_enabled, true);
WriteSetting(QStringLiteral("motion_device"),
QString::fromStdString(Settings::values.motion_device),
QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01"));
@@ -1157,7 +1158,6 @@ void Config::SaveControlValues() {
QString::fromStdString(Settings::values.touch_device),
QStringLiteral("engine:emu_window"));
WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false);
- WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
qt_config->endGroup();
}
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 523ece426..9a4de4c5d 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -181,12 +181,12 @@ void ConfigureInput::ApplyConfiguration() {
advanced->ApplyConfiguration();
- const bool pre_docked_mode = Settings::values.use_docked_mode;
- Settings::values.use_docked_mode = ui->radioDocked->isChecked();
- OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode);
+ const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
+ Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked());
+ OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
- Settings::values.vibration_enabled = ui->vibrationGroup->isChecked();
- Settings::values.motion_enabled = ui->motionGroup->isChecked();
+ Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
+ Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
}
void ConfigureInput::changeEvent(QEvent* event) {
@@ -203,16 +203,16 @@ void ConfigureInput::RetranslateUI() {
void ConfigureInput::LoadConfiguration() {
LoadPlayerControllerIndices();
- UpdateDockedState(Settings::values.players[8].connected);
+ UpdateDockedState(Settings::values.players.GetValue()[8].connected);
- ui->vibrationGroup->setChecked(Settings::values.vibration_enabled);
- ui->motionGroup->setChecked(Settings::values.motion_enabled);
+ ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
+ ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
}
void ConfigureInput::LoadPlayerControllerIndices() {
for (std::size_t i = 0; i < player_connected.size(); ++i) {
- const auto connected = Settings::values.players[i].connected ||
- (i == 0 && Settings::values.players[8].connected);
+ const auto connected = Settings::values.players.GetValue()[i].connected ||
+ (i == 0 && Settings::values.players.GetValue()[8].connected);
player_connected[i]->setChecked(connected);
}
}
@@ -241,8 +241,8 @@ void ConfigureInput::UpdateDockedState(bool is_handheld) {
ui->radioDocked->setEnabled(!is_handheld);
ui->radioUndocked->setEnabled(!is_handheld);
- ui->radioDocked->setChecked(Settings::values.use_docked_mode);
- ui->radioUndocked->setChecked(!Settings::values.use_docked_mode);
+ ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue());
+ ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue());
// Also force into undocked mode if the controller type is handheld.
if (is_handheld) {
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index 3715db0ab..3074be833 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -107,7 +107,7 @@ void ConfigureInputAdvanced::OnControllerButtonClick(int player_idx, int button_
void ConfigureInputAdvanced::ApplyConfiguration() {
for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) {
- auto& player = Settings::values.players[player_idx];
+ auto& player = Settings::values.players.GetValue()[player_idx];
std::array colors{};
std::transform(controllers_colors[player_idx].begin(), controllers_colors[player_idx].end(),
colors.begin(), [](QColor color) { return color.rgb(); });
@@ -126,7 +126,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() {
void ConfigureInputAdvanced::LoadConfiguration() {
for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) {
- auto& player = Settings::values.players[player_idx];
+ auto& player = Settings::values.players.GetValue()[player_idx];
std::array colors = {
player.body_color_left,
player.button_color_left,
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index b4de2f6af..213a76224 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -544,7 +544,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
ConfigureInputPlayer::~ConfigureInputPlayer() = default;
void ConfigureInputPlayer::ApplyConfiguration() {
- auto& player = Settings::values.players[player_index];
+ auto& player = Settings::values.players.GetValue()[player_index];
auto& buttons = debug ? Settings::values.debug_pad_buttons : player.buttons;
auto& analogs = debug ? Settings::values.debug_pad_analogs : player.analogs;
@@ -572,7 +572,7 @@ void ConfigureInputPlayer::ApplyConfiguration() {
}
// Player 1 and Handheld
- auto& handheld = Settings::values.players[HANDHELD_INDEX];
+ auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
// If Handheld is selected, copy all the settings from Player 1 to Handheld.
if (player.controller_type == Settings::ControllerType::Handheld) {
handheld = player;
@@ -609,7 +609,7 @@ void ConfigureInputPlayer::RetranslateUI() {
}
void ConfigureInputPlayer::LoadConfiguration() {
- auto& player = Settings::values.players[player_index];
+ auto& player = Settings::values.players.GetValue()[player_index];
if (debug) {
std::transform(Settings::values.debug_pad_buttons.begin(),
Settings::values.debug_pad_buttons.end(), buttons_param.begin(),
@@ -636,7 +636,7 @@ void ConfigureInputPlayer::LoadConfiguration() {
ui->comboControllerType->setCurrentIndex(static_cast(player.controller_type));
ui->groupConnectedController->setChecked(
player.connected ||
- (player_index == 0 && Settings::values.players[HANDHELD_INDEX].connected));
+ (player_index == 0 && Settings::values.players.GetValue()[HANDHELD_INDEX].connected));
}
void ConfigureInputPlayer::ConnectPlayer(bool connected) {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 4a3dea2a5..54a46827f 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -551,13 +551,14 @@ void GMainWindow::InitializeWidgets() {
dock_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
dock_status_button->setFocusPolicy(Qt::NoFocus);
connect(dock_status_button, &QPushButton::clicked, [&] {
- Settings::values.use_docked_mode = !Settings::values.use_docked_mode;
- dock_status_button->setChecked(Settings::values.use_docked_mode);
- OnDockedModeChanged(!Settings::values.use_docked_mode, Settings::values.use_docked_mode);
+ Settings::values.use_docked_mode.SetValue(!Settings::values.use_docked_mode.GetValue());
+ dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
+ OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(),
+ Settings::values.use_docked_mode.GetValue());
});
dock_status_button->setText(tr("DOCK"));
dock_status_button->setCheckable(true);
- dock_status_button->setChecked(Settings::values.use_docked_mode);
+ dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
statusBar()->insertPermanentWidget(0, dock_status_button);
// Setup ASync button
@@ -796,10 +797,11 @@ void GMainWindow::InitializeHotkeys() {
});
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Change Docked Mode"), this),
&QShortcut::activated, this, [&] {
- Settings::values.use_docked_mode = !Settings::values.use_docked_mode;
- OnDockedModeChanged(!Settings::values.use_docked_mode,
- Settings::values.use_docked_mode);
- dock_status_button->setChecked(Settings::values.use_docked_mode);
+ Settings::values.use_docked_mode.SetValue(
+ !Settings::values.use_docked_mode.GetValue());
+ OnDockedModeChanged(!Settings::values.use_docked_mode.GetValue(),
+ Settings::values.use_docked_mode.GetValue());
+ dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
});
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this),
&QShortcut::activated, this,
@@ -2405,7 +2407,8 @@ void GMainWindow::MigrateConfigFiles() {
const QStringList config_dir_list = config_dir.entryList(QStringList(QStringLiteral("*.ini")));
Common::FS::CreateFullPath(fmt::format("{}custom" DIR_SEP, config_dir_str));
- for (QStringList::const_iterator it = config_dir_list.constBegin(); it != config_dir_list.constEnd(); ++it) {
+ for (QStringList::const_iterator it = config_dir_list.constBegin();
+ it != config_dir_list.constEnd(); ++it) {
const auto filename = it->toStdString();
if (filename.find_first_not_of("0123456789abcdefACBDEF", 0) < 16) {
continue;
@@ -2477,7 +2480,7 @@ void GMainWindow::UpdateStatusBar() {
}
void GMainWindow::UpdateStatusButtons() {
- dock_status_button->setChecked(Settings::values.use_docked_mode);
+ dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
Settings::values.use_asynchronous_gpu_emulation.SetValue(
Settings::values.use_asynchronous_gpu_emulation.GetValue() ||
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 334038ef9..feee02fcd 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -228,24 +228,24 @@ static const std::array keyboard_mods{
void Config::ReadValues() {
// Controls
- for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
const auto group = fmt::format("ControlsP{}", p);
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- Settings::values.players[p].buttons[i] =
+ Settings::values.players.GetValue()[p].buttons[i] =
sdl2_config->Get(group, Settings::NativeButton::mapping[i], default_param);
- if (Settings::values.players[p].buttons[i].empty())
- Settings::values.players[p].buttons[i] = default_param;
+ if (Settings::values.players.GetValue()[p].buttons[i].empty())
+ Settings::values.players.GetValue()[p].buttons[i] = default_param;
}
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
default_analogs[i][3], default_analogs[i][4], 0.5f);
- Settings::values.players[p].analogs[i] =
+ Settings::values.players.GetValue()[p].analogs[i] =
sdl2_config->Get(group, Settings::NativeAnalog::mapping[i], default_param);
- if (Settings::values.players[p].analogs[i].empty())
- Settings::values.players[p].analogs[i] = default_param;
+ if (Settings::values.players.GetValue()[p].analogs[i].empty())
+ Settings::values.players.GetValue()[p].analogs[i] = default_param;
}
}
@@ -288,10 +288,10 @@ void Config::ReadValues() {
Settings::values.debug_pad_analogs[i] = default_param;
}
- Settings::values.vibration_enabled =
- sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true);
- Settings::values.motion_enabled =
- sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true);
+ Settings::values.vibration_enabled.SetValue(
+ sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true));
+ Settings::values.motion_enabled.SetValue(
+ sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true));
Settings::values.touchscreen.enabled =
sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true);
Settings::values.touchscreen.device =
@@ -343,7 +343,8 @@ void Config::ReadValues() {
Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", "");
// System
- Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false);
+ Settings::values.use_docked_mode.SetValue(
+ sdl2_config->GetBoolean("System", "use_docked_mode", false));
const auto size = sdl2_config->GetInteger("System", "users_size", 0);
Settings::values.current_user = std::clamp(
diff --git a/src/yuzu_tester/config.cpp b/src/yuzu_tester/config.cpp
index bc273fb51..3a8a333f0 100644
--- a/src/yuzu_tester/config.cpp
+++ b/src/yuzu_tester/config.cpp
@@ -47,13 +47,13 @@ bool Config::LoadINI(const std::string& default_contents, bool retry) {
void Config::ReadValues() {
// Controls
- for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
+ for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- Settings::values.players[p].buttons[i] = "";
+ Settings::values.players.GetValue()[p].buttons[i] = "";
}
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- Settings::values.players[p].analogs[i] = "";
+ Settings::values.players.GetValue()[p].analogs[i] = "";
}
}
@@ -75,8 +75,8 @@ void Config::ReadValues() {
Settings::values.debug_pad_analogs[i] = "";
}
- Settings::values.vibration_enabled = true;
- Settings::values.motion_enabled = true;
+ Settings::values.vibration_enabled.SetValue(true);
+ Settings::values.motion_enabled.SetValue(true);
Settings::values.touchscreen.enabled = "";
Settings::values.touchscreen.device = "";
Settings::values.touchscreen.finger = 0;
@@ -84,8 +84,8 @@ void Config::ReadValues() {
Settings::values.touchscreen.diameter_x = 15;
Settings::values.touchscreen.diameter_y = 15;
- Settings::values.use_docked_mode =
- sdl2_config->GetBoolean("Controls", "use_docked_mode", false);
+ Settings::values.use_docked_mode.SetValue(
+ sdl2_config->GetBoolean("Controls", "use_docked_mode", false));
// Data Storage
Settings::values.use_virtual_sd =
--
cgit v1.2.3
From ceb7b11f166a4e59945a6296d364980c37ca681e Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Mon, 28 Sep 2020 10:27:29 -0400
Subject: configure_input_player: Change "Defaults" button behavior
RestoreDefaults() now restores the selected devices' mappings using UpdateMappingWithDefaults().
This allows us to move the keyboard mapping from RestoreDefaults() to UpdateMappingWithDefaults().
---
src/input_common/main.cpp | 8 ----
src/yuzu/configuration/configure_input_player.cpp | 57 ++++++++++++-----------
2 files changed, 30 insertions(+), 35 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index 354c734fe..b438482cc 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -96,10 +96,6 @@ struct InputSubsystem::Impl {
if (!params.Has("class") || params.Get("class", "") == "any") {
return {};
}
- if (params.Get("class", "") == "keyboard") {
- // TODO consider returning the SDL key codes for the default keybindings
- return {};
- }
if (params.Get("class", "") == "gcpad") {
return gcadapter->GetAnalogMappingForDevice(params);
}
@@ -116,10 +112,6 @@ struct InputSubsystem::Impl {
if (!params.Has("class") || params.Get("class", "") == "any") {
return {};
}
- if (params.Get("class", "") == "keyboard") {
- // TODO consider returning the SDL key codes for the default keybindings
- return {};
- }
if (params.Get("class", "") == "gcpad") {
return gcadapter->GetButtonMappingForDevice(params);
}
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 213a76224..460ff08a4 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -693,32 +693,7 @@ void ConfigureInputPlayer::UpdateInputDeviceCombobox() {
}
void ConfigureInputPlayer::RestoreDefaults() {
- // Reset Buttons
- for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; ++button_id) {
- buttons_param[button_id] = Common::ParamPackage{
- InputCommon::GenerateKeyboardParam(Config::default_buttons[button_id])};
- }
-
- // Reset Analogs and Modifier Buttons
- for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; ++analog_id) {
- for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
- Common::ParamPackage params{InputCommon::GenerateKeyboardParam(
- Config::default_analogs[analog_id][sub_button_id])};
- SetAnalogParam(params, analogs_param[analog_id], analog_sub_buttons[sub_button_id]);
- }
-
- analogs_param[analog_id].Set(
- "modifier", InputCommon::GenerateKeyboardParam(Config::default_stick_mod[analog_id]));
- }
-
- for (int motion_id = 0; motion_id < Settings::NativeMotion::NumMotions; ++motion_id) {
- motions_param[motion_id] = Common::ParamPackage{
- InputCommon::GenerateKeyboardParam(Config::default_motions[motion_id])};
- }
-
- UpdateUI();
- UpdateInputDeviceCombobox();
- ui->comboControllerType->setCurrentIndex(0);
+ UpdateMappingWithDefaults();
}
void ConfigureInputPlayer::ClearAll() {
@@ -951,9 +926,37 @@ void ConfigureInputPlayer::UpdateMotionButtons() {
}
void ConfigureInputPlayer::UpdateMappingWithDefaults() {
- if (ui->comboDevices->currentIndex() < 2) {
+ if (ui->comboDevices->currentIndex() == 0) {
return;
}
+
+ if (ui->comboDevices->currentIndex() == 1) {
+ // Reset keyboard bindings
+ for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; ++button_id) {
+ buttons_param[button_id] = Common::ParamPackage{
+ InputCommon::GenerateKeyboardParam(Config::default_buttons[button_id])};
+ }
+ for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; ++analog_id) {
+ for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
+ Common::ParamPackage params{InputCommon::GenerateKeyboardParam(
+ Config::default_analogs[analog_id][sub_button_id])};
+ SetAnalogParam(params, analogs_param[analog_id], analog_sub_buttons[sub_button_id]);
+ }
+
+ analogs_param[analog_id].Set("modifier", InputCommon::GenerateKeyboardParam(
+ Config::default_stick_mod[analog_id]));
+ }
+
+ for (int motion_id = 0; motion_id < Settings::NativeMotion::NumMotions; ++motion_id) {
+ motions_param[motion_id] = Common::ParamPackage{
+ InputCommon::GenerateKeyboardParam(Config::default_motions[motion_id])};
+ }
+
+ UpdateUI();
+ return;
+ }
+
+ // Reset controller bindings
const auto& device = input_devices[ui->comboDevices->currentIndex()];
auto button_mapping = input_subsystem->GetButtonMappingForDevice(device);
auto analog_mapping = input_subsystem->GetAnalogMappingForDevice(device);
--
cgit v1.2.3
From 652d6766d55acec6416dccb900a45c6660a86607 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Thu, 8 Oct 2020 23:43:07 -0400
Subject: configure_input: Hook up the vibration percentage spinbox
This allows setting the vibration strength percentage anywhere from 1% to 100%.
Also hooks up the remaining motion button and checkbox in the Controller Applet.
---
src/core/hle/service/hid/controllers/npad.cpp | 3 ++-
src/core/settings.cpp | 1 +
src/core/settings.h | 1 +
src/yuzu/applets/controller.cpp | 4 ++++
src/yuzu/applets/controller.ui | 2 +-
src/yuzu/configuration/config.cpp | 4 ++++
src/yuzu/configuration/configure_input.cpp | 2 ++
src/yuzu/configuration/configure_input.ui | 2 +-
src/yuzu_cmd/config.cpp | 2 ++
src/yuzu_cmd/default_ini.h | 7 +++++++
src/yuzu_tester/config.cpp | 1 +
11 files changed, 26 insertions(+), 3 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index f865e3f5f..924f209c0 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -703,7 +703,8 @@ void Controller_NPad::VibrateController(const std::vector& vibrati
// TODO: Vibrate left/right vibration motors independently if possible.
button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
- vibration_values[i].amp_high, vibration_values[i].amp_low,
+ vibration_values[i].amp_high * Settings::values.vibration_strength.GetValue() / 100,
+ vibration_values[i].amp_low * Settings::values.vibration_strength.GetValue() / 100,
vibration_values[i].freq_high, vibration_values[i].freq_low);
latest_vibration_values[npad_index][device_index] = vibration_values[i];
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index aadbc3932..6e39aebb5 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -150,6 +150,7 @@ void RestoreGlobalState() {
values.players.SetGlobal(true);
values.use_docked_mode.SetGlobal(true);
values.vibration_enabled.SetGlobal(true);
+ values.vibration_strength.SetGlobal(true);
values.motion_enabled.SetGlobal(true);
}
diff --git a/src/core/settings.h b/src/core/settings.h
index edd2a00ca..496f47747 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -170,6 +170,7 @@ struct Values {
Setting use_docked_mode;
Setting vibration_enabled;
+ Setting vibration_strength;
Setting motion_enabled;
std::string motion_device;
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index 7697fe434..196b4f163 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -266,6 +266,8 @@ void QtControllerSelectorDialog::ApplyConfiguration() {
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
+ Settings::values.vibration_strength.SetValue(ui->vibrationSpin->value());
+ Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
}
void QtControllerSelectorDialog::LoadConfiguration() {
@@ -281,6 +283,8 @@ void QtControllerSelectorDialog::LoadConfiguration() {
UpdateDockedState(Settings::values.players.GetValue()[8].connected);
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
+ ui->vibrationSpin->setValue(Settings::values.vibration_strength.GetValue());
+ ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
}
void QtControllerSelectorDialog::CallConfigureInputDialog() {
diff --git a/src/yuzu/applets/controller.ui b/src/yuzu/applets/controller.ui
index 2ab69a2d3..cc27b8ef4 100644
--- a/src/yuzu/applets/controller.ui
+++ b/src/yuzu/applets/controller.ui
@@ -2349,7 +2349,7 @@
1
- 200
+ 100
100
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 296c58f58..820ef4098 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -493,6 +493,8 @@ void Config::ReadControlValues() {
ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), false);
ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"),
true);
+ ReadSettingGlobal(Settings::values.vibration_strength, QStringLiteral("vibration_strength"),
+ 100);
ReadSettingGlobal(Settings::values.motion_enabled, QStringLiteral("motion_enabled"), true);
qt_config->endGroup();
@@ -1150,6 +1152,8 @@ void Config::SaveControlValues() {
WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled,
true);
+ WriteSettingGlobal(QStringLiteral("vibration_strength"), Settings::values.vibration_strength,
+ 100);
WriteSettingGlobal(QStringLiteral("motion_enabled"), Settings::values.motion_enabled, true);
WriteSetting(QStringLiteral("motion_device"),
QString::fromStdString(Settings::values.motion_device),
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 9a4de4c5d..84df547b9 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -186,6 +186,7 @@ void ConfigureInput::ApplyConfiguration() {
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
+ Settings::values.vibration_strength.SetValue(ui->vibrationSpin->value());
Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
}
@@ -206,6 +207,7 @@ void ConfigureInput::LoadConfiguration() {
UpdateDockedState(Settings::values.players.GetValue()[8].connected);
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
+ ui->vibrationSpin->setValue(Settings::values.vibration_strength.GetValue());
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
}
diff --git a/src/yuzu/configuration/configure_input.ui b/src/yuzu/configuration/configure_input.ui
index b74481bda..cbd67d4c7 100644
--- a/src/yuzu/configuration/configure_input.ui
+++ b/src/yuzu/configuration/configure_input.ui
@@ -215,7 +215,7 @@
1
- 200
+ 100
100
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index feee02fcd..209350837 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -290,6 +290,8 @@ void Config::ReadValues() {
Settings::values.vibration_enabled.SetValue(
sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true));
+ Settings::values.vibration_strength.SetValue(
+ sdl2_config->GetInteger("ControlsGeneral", "vibration_strength", 100));
Settings::values.motion_enabled.SetValue(
sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true));
Settings::values.touchscreen.enabled =
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 796e27df4..53057c01c 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -65,6 +65,13 @@ button_screenshot=
lstick=
rstick=
+# Whether to enable or disable vibration
+# 0: Disabled, 1 (default): Enabled
+vibration_enabled=
+
+# Vibration strength percentage (Default: 100)
+vibration_strength=
+
# for motion input, the following devices are available:
# - "motion_emu" (default) for emulating motion input from mouse input. Required parameters:
# - "update_period": update period in milliseconds (default to 100)
diff --git a/src/yuzu_tester/config.cpp b/src/yuzu_tester/config.cpp
index 3a8a333f0..437302520 100644
--- a/src/yuzu_tester/config.cpp
+++ b/src/yuzu_tester/config.cpp
@@ -76,6 +76,7 @@ void Config::ReadValues() {
}
Settings::values.vibration_enabled.SetValue(true);
+ Settings::values.vibration_strength.SetValue(100);
Settings::values.motion_enabled.SetValue(true);
Settings::values.touchscreen.enabled = "";
Settings::values.touchscreen.device = "";
--
cgit v1.2.3
From d6a41cfc21a75349ca79e73da5ca1dcecd1af901 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Fri, 16 Oct 2020 11:55:45 -0400
Subject: settings: Remove global vibration strength modifier
This will be replaced in favor of per-player vibration strength modifiers.
---
src/core/hle/service/hid/controllers/npad.cpp | 4 +---
src/core/settings.cpp | 1 -
src/core/settings.h | 1 -
src/yuzu/applets/controller.cpp | 2 --
src/yuzu/configuration/config.cpp | 4 ----
src/yuzu/configuration/configure_input.cpp | 2 --
src/yuzu_cmd/config.cpp | 2 --
src/yuzu_cmd/default_ini.h | 3 ---
src/yuzu_tester/config.cpp | 1 -
9 files changed, 1 insertion(+), 19 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 1fc06ef3f..ba20d3f59 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -684,9 +684,7 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index,
const auto& button_state = buttons[npad_index];
return button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
- vibration_value.amp_low * Settings::values.vibration_strength.GetValue() / 100,
- vibration_value.freq_low,
- vibration_value.amp_high * Settings::values.vibration_strength.GetValue() / 100,
+ vibration_value.amp_low, vibration_value.freq_low, vibration_value.amp_high,
vibration_value.freq_high);
}
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index 6e39aebb5..aadbc3932 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.cpp
@@ -150,7 +150,6 @@ void RestoreGlobalState() {
values.players.SetGlobal(true);
values.use_docked_mode.SetGlobal(true);
values.vibration_enabled.SetGlobal(true);
- values.vibration_strength.SetGlobal(true);
values.motion_enabled.SetGlobal(true);
}
diff --git a/src/core/settings.h b/src/core/settings.h
index 496f47747..edd2a00ca 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -170,7 +170,6 @@ struct Values {
Setting use_docked_mode;
Setting vibration_enabled;
- Setting vibration_strength;
Setting motion_enabled;
std::string motion_device;
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index 196b4f163..0fc713a6e 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -266,7 +266,6 @@ void QtControllerSelectorDialog::ApplyConfiguration() {
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
- Settings::values.vibration_strength.SetValue(ui->vibrationSpin->value());
Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
}
@@ -283,7 +282,6 @@ void QtControllerSelectorDialog::LoadConfiguration() {
UpdateDockedState(Settings::values.players.GetValue()[8].connected);
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
- ui->vibrationSpin->setValue(Settings::values.vibration_strength.GetValue());
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
}
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 820ef4098..296c58f58 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -493,8 +493,6 @@ void Config::ReadControlValues() {
ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), false);
ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"),
true);
- ReadSettingGlobal(Settings::values.vibration_strength, QStringLiteral("vibration_strength"),
- 100);
ReadSettingGlobal(Settings::values.motion_enabled, QStringLiteral("motion_enabled"), true);
qt_config->endGroup();
@@ -1152,8 +1150,6 @@ void Config::SaveControlValues() {
WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled,
true);
- WriteSettingGlobal(QStringLiteral("vibration_strength"), Settings::values.vibration_strength,
- 100);
WriteSettingGlobal(QStringLiteral("motion_enabled"), Settings::values.motion_enabled, true);
WriteSetting(QStringLiteral("motion_device"),
QString::fromStdString(Settings::values.motion_device),
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 84df547b9..9a4de4c5d 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -186,7 +186,6 @@ void ConfigureInput::ApplyConfiguration() {
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
- Settings::values.vibration_strength.SetValue(ui->vibrationSpin->value());
Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
}
@@ -207,7 +206,6 @@ void ConfigureInput::LoadConfiguration() {
UpdateDockedState(Settings::values.players.GetValue()[8].connected);
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
- ui->vibrationSpin->setValue(Settings::values.vibration_strength.GetValue());
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
}
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 209350837..feee02fcd 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -290,8 +290,6 @@ void Config::ReadValues() {
Settings::values.vibration_enabled.SetValue(
sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true));
- Settings::values.vibration_strength.SetValue(
- sdl2_config->GetInteger("ControlsGeneral", "vibration_strength", 100));
Settings::values.motion_enabled.SetValue(
sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true));
Settings::values.touchscreen.enabled =
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 53057c01c..b6f6a3bb0 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -69,9 +69,6 @@ rstick=
# 0: Disabled, 1 (default): Enabled
vibration_enabled=
-# Vibration strength percentage (Default: 100)
-vibration_strength=
-
# for motion input, the following devices are available:
# - "motion_emu" (default) for emulating motion input from mouse input. Required parameters:
# - "update_period": update period in milliseconds (default to 100)
diff --git a/src/yuzu_tester/config.cpp b/src/yuzu_tester/config.cpp
index 437302520..3a8a333f0 100644
--- a/src/yuzu_tester/config.cpp
+++ b/src/yuzu_tester/config.cpp
@@ -76,7 +76,6 @@ void Config::ReadValues() {
}
Settings::values.vibration_enabled.SetValue(true);
- Settings::values.vibration_strength.SetValue(100);
Settings::values.motion_enabled.SetValue(true);
Settings::values.touchscreen.enabled = "";
Settings::values.touchscreen.device = "";
--
cgit v1.2.3
From 38110dd485e329fa39e2e4c02b91a89dfebcbc88 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Sat, 17 Oct 2020 09:38:12 -0400
Subject: configure_input: Add per-player vibration
Allows for enabling and modifying vibration and vibration strength per player.
Also adds a toggle for enabling/disabling accurate vibrations.
Co-authored-by: Its-Rei
---
dist/qt_themes/qdarkstyle/style.qss | 11 +-
dist/qt_themes/qdarkstyle_midnight_blue/style.qss | 12 +-
src/core/hle/service/hid/controllers/npad.cpp | 13 +-
src/core/settings.h | 1 +
src/input_common/settings.h | 3 +
src/yuzu/CMakeLists.txt | 3 +
src/yuzu/applets/controller.cpp | 16 +
src/yuzu/applets/controller.h | 3 +
src/yuzu/applets/controller.ui | 18 +-
src/yuzu/configuration/config.cpp | 16 +
src/yuzu/configuration/configure_input.cpp | 4 +
src/yuzu/configuration/configure_input.ui | 22 +-
src/yuzu/configuration/configure_vibration.cpp | 66 +++
src/yuzu/configuration/configure_vibration.h | 40 ++
src/yuzu/configuration/configure_vibration.ui | 546 ++++++++++++++++++++++
src/yuzu_cmd/config.cpp | 2 +
src/yuzu_cmd/default_ini.h | 4 +
src/yuzu_tester/config.cpp | 1 +
18 files changed, 751 insertions(+), 30 deletions(-)
create mode 100644 src/yuzu/configuration/configure_vibration.cpp
create mode 100644 src/yuzu/configuration/configure_vibration.h
create mode 100644 src/yuzu/configuration/configure_vibration.ui
(limited to 'src/yuzu')
diff --git a/dist/qt_themes/qdarkstyle/style.qss b/dist/qt_themes/qdarkstyle/style.qss
index aca6531ac..2a1e8ddeb 100644
--- a/dist/qt_themes/qdarkstyle/style.qss
+++ b/dist/qt_themes/qdarkstyle/style.qss
@@ -1293,15 +1293,24 @@ QPushButton#buttonRefreshDevices {
QSpinBox#spinboxLStickRange,
QSpinBox#spinboxRStickRange,
-QSpinBox#vibrationSpin {
+QSpinBox#vibrationSpinPlayer1,
+QSpinBox#vibrationSpinPlayer2,
+QSpinBox#vibrationSpinPlayer3,
+QSpinBox#vibrationSpinPlayer4,
+QSpinBox#vibrationSpinPlayer5,
+QSpinBox#vibrationSpinPlayer6,
+QSpinBox#vibrationSpinPlayer7,
+QSpinBox#vibrationSpinPlayer8 {
min-width: 68px;
}
+QDialog#ConfigureVibration QGroupBox::indicator,
QGroupBox#motionGroup::indicator,
QGroupBox#vibrationGroup::indicator {
margin-left: 0px;
}
+QDialog#ConfigureVibration QGroupBox::title,
QGroupBox#motionGroup::title,
QGroupBox#vibrationGroup::title {
spacing: 2px;
diff --git a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
index ad032a966..70e540b06 100644
--- a/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
+++ b/dist/qt_themes/qdarkstyle_midnight_blue/style.qss
@@ -2200,21 +2200,31 @@ QPushButton#buttonRefreshDevices {
QSpinBox#spinboxLStickRange,
QSpinBox#spinboxRStickRange,
-QSpinBox#vibrationSpin {
+QSpinBox#vibrationSpinPlayer1,
+QSpinBox#vibrationSpinPlayer2,
+QSpinBox#vibrationSpinPlayer3,
+QSpinBox#vibrationSpinPlayer4,
+QSpinBox#vibrationSpinPlayer5,
+QSpinBox#vibrationSpinPlayer6,
+QSpinBox#vibrationSpinPlayer7,
+QSpinBox#vibrationSpinPlayer8 {
min-width: 68px;
}
+QDialog#ConfigureVibration QGroupBox::indicator,
QGroupBox#motionGroup::indicator,
QGroupBox#vibrationGroup::indicator {
margin-left: 0px;
}
+QDialog#ConfigureVibration QGroupBox,
QWidget#bottomPerGameInput QGroupBox#motionGroup,
QWidget#bottomPerGameInput QGroupBox#vibrationGroup,
QWidget#bottomPerGameInput QGroupBox#inputConfigGroup {
padding: 0px;
}
+QDialog#ConfigureVibration QGroupBox::title,
QGroupBox#motionGroup::title,
QGroupBox#vibrationGroup::title {
spacing: 2px;
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index ba20d3f59..dc9954377 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -680,11 +680,19 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index,
return false;
}
+ const auto& player = Settings::values.players.GetValue()[npad_index];
+
+ if (!player.vibration_enabled) {
+ return false;
+ }
+
using namespace Settings::NativeButton;
const auto& button_state = buttons[npad_index];
return button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
- vibration_value.amp_low, vibration_value.freq_low, vibration_value.amp_high,
+ std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f),
+ vibration_value.freq_low,
+ std::min(vibration_value.amp_high * player.vibration_strength / 100.0f, 1.0f),
vibration_value.freq_high);
}
@@ -728,7 +736,8 @@ void Controller_NPad::VibrateControllers(const std::vector& vibrat
}
// Filter out non-zero vibrations that are within 0.015625 absolute amplitude of each other.
- if ((vibration_values[i].amp_low != 0.0f || vibration_values[i].amp_high != 0.0f) &&
+ if (!Settings::values.enable_accurate_vibrations.GetValue() &&
+ (vibration_values[i].amp_low != 0.0f || vibration_values[i].amp_high != 0.0f) &&
(latest_vibration_values[npad_index][device_index].amp_low != 0.0f ||
latest_vibration_values[npad_index][device_index].amp_high != 0.0f) &&
(abs(vibration_values[i].amp_low -
diff --git a/src/core/settings.h b/src/core/settings.h
index edd2a00ca..476c3fdf3 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -170,6 +170,7 @@ struct Values {
Setting use_docked_mode;
Setting vibration_enabled;
+ Setting enable_accurate_vibrations;
Setting motion_enabled;
std::string motion_device;
diff --git a/src/input_common/settings.h b/src/input_common/settings.h
index f52d28540..2763ed991 100644
--- a/src/input_common/settings.h
+++ b/src/input_common/settings.h
@@ -332,6 +332,9 @@ struct PlayerInput {
AnalogsRaw analogs;
MotionRaw motions;
+ bool vibration_enabled;
+ int vibration_strength;
+
u32 body_color_left;
u32 body_color_right;
u32 button_color_left;
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 22fe0a2a6..bf1fae9fa 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -105,6 +105,9 @@ add_executable(yuzu
configuration/configure_ui.cpp
configuration/configure_ui.h
configuration/configure_ui.ui
+ configuration/configure_vibration.cpp
+ configuration/configure_vibration.h
+ configuration/configure_vibration.ui
configuration/configure_web.cpp
configuration/configure_web.h
configuration/configure_web.ui
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index 0fc713a6e..c5e671309 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -14,6 +14,7 @@
#include "ui_controller.h"
#include "yuzu/applets/controller.h"
#include "yuzu/configuration/configure_input_dialog.h"
+#include "yuzu/configuration/configure_vibration.h"
#include "yuzu/main.h"
namespace {
@@ -223,6 +224,9 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
}
}
+ connect(ui->vibrationButton, &QPushButton::clicked, this,
+ &QtControllerSelectorDialog::CallConfigureVibrationDialog);
+
connect(ui->inputConfigButton, &QPushButton::clicked, this,
&QtControllerSelectorDialog::CallConfigureInputDialog);
@@ -285,6 +289,18 @@ void QtControllerSelectorDialog::LoadConfiguration() {
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
}
+void QtControllerSelectorDialog::CallConfigureVibrationDialog() {
+ ConfigureVibration dialog(this);
+
+ dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
+ Qt::WindowSystemMenuHint);
+ dialog.setWindowModality(Qt::WindowModal);
+
+ if (dialog.exec() == QDialog::Accepted) {
+ dialog.ApplyConfiguration();
+ }
+}
+
void QtControllerSelectorDialog::CallConfigureInputDialog() {
const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players;
diff --git a/src/yuzu/applets/controller.h b/src/yuzu/applets/controller.h
index 8fefecf05..a2ce03c8f 100644
--- a/src/yuzu/applets/controller.h
+++ b/src/yuzu/applets/controller.h
@@ -42,6 +42,9 @@ private:
// Loads the current input configuration into the frontend applet.
void LoadConfiguration();
+ // Initializes the "Configure Vibration" Dialog.
+ void CallConfigureVibrationDialog();
+
// Initializes the "Configure Input" Dialog.
void CallConfigureInputDialog();
diff --git a/src/yuzu/applets/controller.ui b/src/yuzu/applets/controller.ui
index cc27b8ef4..8e571ba8f 100644
--- a/src/yuzu/applets/controller.ui
+++ b/src/yuzu/applets/controller.ui
@@ -2329,11 +2329,11 @@
3
-
-
+
68
- 21
+ 0
@@ -2342,17 +2342,11 @@
16777215
-
- %
-
-
- 1
-
-
- 100
+
+ min-width: 68px;
-
- 100
+
+ Configure
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 296c58f58..7f66f29aa 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -300,6 +300,14 @@ void Config::ReadPlayerValue(std::size_t player_index) {
static_cast(Settings::ControllerType::ProController))
.toUInt());
+ player.vibration_enabled =
+ qt_config->value(QStringLiteral("%1vibration_enabled").arg(player_prefix), true)
+ .toBool();
+
+ player.vibration_strength =
+ qt_config->value(QStringLiteral("%1vibration_strength").arg(player_prefix), 100)
+ .toInt();
+
player.body_color_left = qt_config
->value(QStringLiteral("%1body_color_left").arg(player_prefix),
Settings::JOYCON_BODY_NEON_BLUE)
@@ -493,6 +501,8 @@ void Config::ReadControlValues() {
ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), false);
ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"),
true);
+ ReadSettingGlobal(Settings::values.enable_accurate_vibrations,
+ QStringLiteral("enable_accurate_vibrations"), false);
ReadSettingGlobal(Settings::values.motion_enabled, QStringLiteral("motion_enabled"), true);
qt_config->endGroup();
@@ -983,6 +993,10 @@ void Config::SavePlayerValue(std::size_t player_index) {
if (!player_prefix.isEmpty()) {
WriteSetting(QStringLiteral("%1connected").arg(player_prefix), player.connected, false);
+ WriteSetting(QStringLiteral("%1vibration_enabled").arg(player_prefix),
+ player.vibration_enabled, true);
+ WriteSetting(QStringLiteral("%1vibration_strength").arg(player_prefix),
+ player.vibration_strength, 100);
WriteSetting(QStringLiteral("%1body_color_left").arg(player_prefix), player.body_color_left,
Settings::JOYCON_BODY_NEON_BLUE);
WriteSetting(QStringLiteral("%1body_color_right").arg(player_prefix),
@@ -1150,6 +1164,8 @@ void Config::SaveControlValues() {
WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled,
true);
+ WriteSettingGlobal(QStringLiteral("enable_accurate_vibrations"),
+ Settings::values.enable_accurate_vibrations, false);
WriteSettingGlobal(QStringLiteral("motion_enabled"), Settings::values.motion_enabled, true);
WriteSetting(QStringLiteral("motion_device"),
QString::fromStdString(Settings::values.motion_device),
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 9a4de4c5d..600cc03ae 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -23,6 +23,7 @@
#include "yuzu/configuration/configure_motion_touch.h"
#include "yuzu/configuration/configure_mouse_advanced.h"
#include "yuzu/configuration/configure_touchscreen_advanced.h"
+#include "yuzu/configuration/configure_vibration.h"
#include "yuzu/configuration/input_profiles.h"
namespace {
@@ -156,6 +157,9 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
CallConfigureDialog(*this, input_subsystem);
});
+ connect(ui->vibrationButton, &QPushButton::clicked,
+ [this] { CallConfigureDialog(*this); });
+
connect(ui->motionButton, &QPushButton::clicked, [this, input_subsystem] {
CallConfigureDialog(*this, input_subsystem);
});
diff --git a/src/yuzu/configuration/configure_input.ui b/src/yuzu/configuration/configure_input.ui
index cbd67d4c7..2707025e7 100644
--- a/src/yuzu/configuration/configure_input.ui
+++ b/src/yuzu/configuration/configure_input.ui
@@ -6,7 +6,7 @@
0
0
- 700
+ 680
540
@@ -195,11 +195,11 @@
3
-
-
+
68
- 21
+ 0
@@ -208,17 +208,11 @@
16777215
-
- %
-
-
- 1
-
-
- 100
+
+ min-width: 68px;
-
- 100
+
+ Configure
@@ -272,7 +266,7 @@
-
-
+
5
diff --git a/src/yuzu/configuration/configure_vibration.cpp b/src/yuzu/configuration/configure_vibration.cpp
new file mode 100644
index 000000000..1c68f28f3
--- /dev/null
+++ b/src/yuzu/configuration/configure_vibration.cpp
@@ -0,0 +1,66 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/settings.h"
+#include "ui_configure_vibration.h"
+#include "yuzu/configuration/configure_vibration.h"
+
+ConfigureVibration::ConfigureVibration(QWidget* parent)
+ : QDialog(parent), ui(std::make_unique()) {
+ ui->setupUi(this);
+
+ vibration_groupboxes = {
+ ui->vibrationGroupPlayer1, ui->vibrationGroupPlayer2, ui->vibrationGroupPlayer3,
+ ui->vibrationGroupPlayer4, ui->vibrationGroupPlayer5, ui->vibrationGroupPlayer6,
+ ui->vibrationGroupPlayer7, ui->vibrationGroupPlayer8,
+ };
+
+ vibration_spinboxes = {
+ ui->vibrationSpinPlayer1, ui->vibrationSpinPlayer2, ui->vibrationSpinPlayer3,
+ ui->vibrationSpinPlayer4, ui->vibrationSpinPlayer5, ui->vibrationSpinPlayer6,
+ ui->vibrationSpinPlayer7, ui->vibrationSpinPlayer8,
+ };
+
+ const auto& players = Settings::values.players.GetValue();
+
+ for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
+ vibration_groupboxes[i]->setChecked(players[i].vibration_enabled);
+ vibration_spinboxes[i]->setValue(players[i].vibration_strength);
+ }
+
+ ui->checkBoxAccurateVibration->setChecked(
+ Settings::values.enable_accurate_vibrations.GetValue());
+
+ if (!Settings::IsConfiguringGlobal()) {
+ ui->checkBoxAccurateVibration->setDisabled(true);
+ }
+
+ RetranslateUI();
+}
+
+ConfigureVibration::~ConfigureVibration() = default;
+
+void ConfigureVibration::ApplyConfiguration() {
+ auto& players = Settings::values.players.GetValue();
+
+ for (std::size_t i = 0; i < NUM_PLAYERS; ++i) {
+ players[i].vibration_enabled = vibration_groupboxes[i]->isChecked();
+ players[i].vibration_strength = vibration_spinboxes[i]->value();
+ }
+
+ Settings::values.enable_accurate_vibrations.SetValue(
+ ui->checkBoxAccurateVibration->isChecked());
+}
+
+void ConfigureVibration::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QDialog::changeEvent(event);
+}
+
+void ConfigureVibration::RetranslateUI() {
+ ui->retranslateUi(this);
+}
diff --git a/src/yuzu/configuration/configure_vibration.h b/src/yuzu/configuration/configure_vibration.h
new file mode 100644
index 000000000..37bbc2653
--- /dev/null
+++ b/src/yuzu/configuration/configure_vibration.h
@@ -0,0 +1,40 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+#include
+#include
+
+class QGroupBox;
+class QSpinBox;
+
+namespace Ui {
+class ConfigureVibration;
+}
+
+class ConfigureVibration : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit ConfigureVibration(QWidget* parent);
+ ~ConfigureVibration() override;
+
+ void ApplyConfiguration();
+
+private:
+ void changeEvent(QEvent* event) override;
+ void RetranslateUI();
+
+ std::unique_ptr ui;
+
+ static constexpr std::size_t NUM_PLAYERS = 8;
+
+ // Groupboxes encapsulating the vibration strength spinbox.
+ std::array vibration_groupboxes;
+
+ // Spinboxes representing the vibration strength percentage.
+ std::array vibration_spinboxes;
+};
diff --git a/src/yuzu/configuration/configure_vibration.ui b/src/yuzu/configuration/configure_vibration.ui
new file mode 100644
index 000000000..efdf317a9
--- /dev/null
+++ b/src/yuzu/configuration/configure_vibration.ui
@@ -0,0 +1,546 @@
+
+
+ ConfigureVibration
+
+
+
+ 0
+ 0
+ 364
+ 242
+
+
+
+ Configure Vibration
+
+
+
+
+
+
-
+
+
+ Vibration
+
+
+
+ 9
+
+
+ 9
+
+
+ 9
+
+
+ 9
+
+
-
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Player 1
+
+
+ true
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 68
+ 21
+
+
+
+
+ 68
+ 16777215
+
+
+
+ %
+
+
+ 1
+
+
+ 150
+
+
+ 100
+
+
+
+
+
+
+ -
+
+
+ Player 2
+
+
+ true
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 68
+ 21
+
+
+
+
+ 68
+ 16777215
+
+
+
+ %
+
+
+ 1
+
+
+ 150
+
+
+ 100
+
+
+
+
+
+
+ -
+
+
+ Player 3
+
+
+ true
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 68
+ 21
+
+
+
+
+ 68
+ 16777215
+
+
+
+ %
+
+
+ 1
+
+
+ 150
+
+
+ 100
+
+
+
+
+
+
+ -
+
+
+ Player 4
+
+
+ true
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 68
+ 21
+
+
+
+
+ 68
+ 16777215
+
+
+
+ %
+
+
+ 1
+
+
+ 150
+
+
+ 100
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Player 5
+
+
+ true
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 68
+ 21
+
+
+
+
+ 68
+ 16777215
+
+
+
+ %
+
+
+ 1
+
+
+ 150
+
+
+ 100
+
+
+
+
+
+
+ -
+
+
+ Player 6
+
+
+ true
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 68
+ 21
+
+
+
+
+ 68
+ 16777215
+
+
+
+ %
+
+
+ 1
+
+
+ 150
+
+
+ 100
+
+
+
+
+
+
+ -
+
+
+ Player 7
+
+
+ true
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 68
+ 21
+
+
+
+
+ 68
+ 16777215
+
+
+
+ %
+
+
+ 1
+
+
+ 150
+
+
+ 100
+
+
+
+
+
+
+ -
+
+
+ Player 8
+
+
+ true
+
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
+ 3
+
+
-
+
+
+
+ 68
+ 21
+
+
+
+
+ 68
+ 16777215
+
+
+
+ %
+
+
+ 1
+
+
+ 150
+
+
+ 100
+
+
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+ Settings
+
+
+
-
+
+
+ Enable Accurate Vibration
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 167
+ 55
+
+
+
+
+ -
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+ buttonBoxVibration
+ accepted()
+ ConfigureVibration
+ accept()
+
+
+ buttonBoxVibration
+ rejected()
+ ConfigureVibration
+ reject()
+
+
+
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index feee02fcd..e1adbbf2b 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -290,6 +290,8 @@ void Config::ReadValues() {
Settings::values.vibration_enabled.SetValue(
sdl2_config->GetBoolean("ControlsGeneral", "vibration_enabled", true));
+ Settings::values.enable_accurate_vibrations.SetValue(
+ sdl2_config->GetBoolean("ControlsGeneral", "enable_accurate_vibrations", false));
Settings::values.motion_enabled.SetValue(
sdl2_config->GetBoolean("ControlsGeneral", "motion_enabled", true));
Settings::values.touchscreen.enabled =
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index b6f6a3bb0..bcbbcd4ca 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -69,6 +69,10 @@ rstick=
# 0: Disabled, 1 (default): Enabled
vibration_enabled=
+# Whether to enable or disable accurate vibrations
+# 0 (default): Disabled, 1: Enabled
+enable_accurate_vibrations=
+
# for motion input, the following devices are available:
# - "motion_emu" (default) for emulating motion input from mouse input. Required parameters:
# - "update_period": update period in milliseconds (default to 100)
diff --git a/src/yuzu_tester/config.cpp b/src/yuzu_tester/config.cpp
index 3a8a333f0..b6cdc7c1c 100644
--- a/src/yuzu_tester/config.cpp
+++ b/src/yuzu_tester/config.cpp
@@ -76,6 +76,7 @@ void Config::ReadValues() {
}
Settings::values.vibration_enabled.SetValue(true);
+ Settings::values.enable_accurate_vibrations.SetValue(false);
Settings::values.motion_enabled.SetValue(true);
Settings::values.touchscreen.enabled = "";
Settings::values.touchscreen.device = "";
--
cgit v1.2.3
From e9e1876e821b8bd1bb5c8254ec93e2cc479e16dd Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Tue, 20 Oct 2020 13:55:25 -0400
Subject: input_common: Add VibrationDevice and VibrationDeviceFactory
A vibration device is an input device that returns an unsigned byte as status.
It represents whether the vibration device supports vibration or not.
If the status returns 1, it supports vibration. Otherwise, it does not support vibration.
---
src/core/frontend/input.h | 7 ++
src/core/hle/service/hid/controllers/npad.cpp | 48 +++++---------
src/core/hle/service/hid/controllers/npad.h | 11 +++-
src/core/hle/service/hid/hid.cpp | 1 +
src/input_common/gcadapter/gc_adapter.cpp | 6 +-
src/input_common/gcadapter/gc_adapter.h | 4 +-
src/input_common/gcadapter/gc_poller.cpp | 50 +++++++++++---
src/input_common/gcadapter/gc_poller.h | 11 ++++
src/input_common/main.cpp | 5 ++
src/input_common/sdl/sdl_impl.cpp | 74 ++++++++++++++++-----
src/input_common/sdl/sdl_impl.h | 2 +
src/input_common/settings.cpp | 21 ++++--
src/input_common/settings.h | 32 +++++++--
src/yuzu/applets/controller.cpp | 2 +
src/yuzu/configuration/config.cpp | 61 ++++++++++-------
src/yuzu/configuration/configure_input_player.cpp | 7 ++
src/yuzu/configuration/configure_vibration.cpp | 80 +++++++++++++++++++++++
src/yuzu/configuration/configure_vibration.h | 3 +
src/yuzu/main.cpp | 3 +
19 files changed, 327 insertions(+), 101 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h
index fb2ce2514..25ac5af46 100644
--- a/src/core/frontend/input.h
+++ b/src/core/frontend/input.h
@@ -121,6 +121,13 @@ using ButtonDevice = InputDevice;
*/
using AnalogDevice = InputDevice>;
+/**
+ * A vibration device is an input device that returns an unsigned byte as status.
+ * It represents whether the vibration device supports vibration or not.
+ * If the status returns 1, it supports vibration. Otherwise, it does not support vibration.
+ */
+using VibrationDevice = InputDevice;
+
/**
* A motion status is an object that returns a tuple of accelerometer state vector,
* gyroscope state vector, rotation state vector and orientation state matrix.
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index dc9954377..27099de24 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -271,6 +271,10 @@ void Controller_NPad::OnLoadInputDevices() {
std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN,
players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END,
sticks[i].begin(), Input::CreateDevice);
+ std::transform(players[i].vibrations.begin() +
+ Settings::NativeVibration::VIBRATION_HID_BEGIN,
+ players[i].vibrations.begin() + Settings::NativeVibration::VIBRATION_HID_END,
+ vibrations[i].begin(), Input::CreateDevice);
std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN,
players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END,
motions[i].begin(), Input::CreateDevice);
@@ -278,8 +282,10 @@ void Controller_NPad::OnLoadInputDevices() {
}
void Controller_NPad::OnRelease() {
- for (std::size_t index = 0; index < connected_controllers.size(); ++index) {
- VibrateControllerAtIndex(index, {});
+ for (std::size_t npad_idx = 0; npad_idx < vibrations.size(); ++npad_idx) {
+ for (std::size_t device_idx = 0; device_idx < vibrations[npad_idx].size(); ++device_idx) {
+ VibrateControllerAtIndex(npad_idx, device_idx);
+ }
}
}
@@ -674,9 +680,9 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode)
}
}
-bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index,
+bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
const VibrationValue& vibration_value) {
- if (!connected_controllers[npad_index].is_connected) {
+ if (!connected_controllers[npad_index].is_connected || !vibrations[npad_index][device_index]) {
return false;
}
@@ -686,10 +692,7 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index,
return false;
}
- using namespace Settings::NativeButton;
- const auto& button_state = buttons[npad_index];
-
- return button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
+ return vibrations[npad_index][device_index]->SetRumblePlay(
std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f),
vibration_value.freq_low,
std::min(vibration_value.amp_high * player.vibration_strength / 100.0f, 1.0f),
@@ -717,6 +720,11 @@ void Controller_NPad::VibrateControllers(const std::vector& vibrat
continue;
}
+ if (vibration_device_handles[i].device_index == DeviceIndex::None) {
+ UNREACHABLE_MSG("DeviceIndex should never be None!");
+ continue;
+ }
+
// Some games try to send mismatched parameters in the device handle, block these.
if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft &&
(vibration_device_handles[i].npad_type == NpadType::JoyconRight ||
@@ -747,28 +755,8 @@ void Controller_NPad::VibrateControllers(const std::vector& vibrat
continue;
}
- // TODO: Vibrate left/right vibration motors independently if possible.
- if (VibrateControllerAtIndex(npad_index, vibration_values[i])) {
- switch (connected_controllers[npad_index].type) {
- case NPadControllerType::None:
- UNREACHABLE();
- break;
- case NPadControllerType::ProController:
- case NPadControllerType::Handheld:
- case NPadControllerType::JoyDual:
- // Since we can't vibrate motors independently yet, we can reduce state changes by
- // assigning all 3 device indices the current vibration value.
- latest_vibration_values[npad_index][0] = vibration_values[i];
- latest_vibration_values[npad_index][1] = vibration_values[i];
- latest_vibration_values[npad_index][2] = vibration_values[i];
- break;
- case NPadControllerType::JoyLeft:
- case NPadControllerType::JoyRight:
- case NPadControllerType::Pokeball:
- default:
- latest_vibration_values[npad_index][device_index] = vibration_values[i];
- break;
- }
+ if (VibrateControllerAtIndex(npad_index, device_index, vibration_values[i])) {
+ latest_vibration_values[npad_index][device_index] = vibration_values[i];
}
}
}
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 576ef1558..3ae9fb8e6 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -148,7 +148,8 @@ public:
void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
- bool VibrateControllerAtIndex(std::size_t npad_index, const VibrationValue& vibration_value);
+ bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
+ const VibrationValue& vibration_value = {});
void VibrateControllers(const std::vector& vibration_device_handles,
const std::vector& vibration_values);
@@ -399,18 +400,22 @@ private:
using StickArray = std::array<
std::array, Settings::NativeAnalog::NUM_STICKS_HID>,
10>;
+ using VibrationArray = std::array,
+ Settings::NativeVibration::NUM_VIBRATIONS_HID>,
+ 10>;
using MotionArray = std::array<
- std::array, Settings::NativeMotion::NUM_MOTION_HID>,
+ std::array, Settings::NativeMotion::NUM_MOTIONS_HID>,
10>;
ButtonArray buttons;
StickArray sticks;
+ VibrationArray vibrations;
MotionArray motions;
std::vector supported_npad_id_types{};
NpadHoldType hold_type{NpadHoldType::Vertical};
NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
// Each controller should have their own styleset changed event
std::array styleset_changed_events;
- std::array, 10> latest_vibration_values;
+ std::array, 10> latest_vibration_values{};
std::array connected_controllers{};
std::array unintended_home_button_input_protection{};
GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index e88f30d6a..1d882a977 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -998,6 +998,7 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
break;
case Controller_NPad::DeviceIndex::None:
default:
+ UNREACHABLE_MSG("DeviceIndex should never be None!");
vibration_device_info.position = VibrationDevicePosition::None;
break;
}
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp
index b912188b6..d80195c82 100644
--- a/src/input_common/gcadapter/gc_adapter.cpp
+++ b/src/input_common/gcadapter/gc_adapter.cpp
@@ -230,10 +230,8 @@ void Adapter::SendVibrations() {
vibration_changed = false;
}
-bool Adapter::RumblePlay(std::size_t port, f32 amplitude) {
- amplitude = std::clamp(amplitude, 0.0f, 1.0f);
- const auto raw_amp = static_cast(amplitude * 0x8);
- pads[port].rumble_amplitude = raw_amp;
+bool Adapter::RumblePlay(std::size_t port, u8 amplitude) {
+ pads[port].rumble_amplitude = amplitude;
return rumble_enabled;
}
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h
index d28dcfad3..f1256c9da 100644
--- a/src/input_common/gcadapter/gc_adapter.h
+++ b/src/input_common/gcadapter/gc_adapter.h
@@ -77,8 +77,8 @@ public:
Adapter();
~Adapter();
- /// Request a vibration for a controlelr
- bool RumblePlay(std::size_t port, f32 amplitude);
+ /// Request a vibration for a controller
+ bool RumblePlay(std::size_t port, u8 amplitude);
/// Used for polling
void BeginConfiguration();
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp
index 6bd6f57fc..fe57c13a5 100644
--- a/src/input_common/gcadapter/gc_poller.cpp
+++ b/src/input_common/gcadapter/gc_poller.cpp
@@ -15,7 +15,7 @@ namespace InputCommon {
class GCButton final : public Input::ButtonDevice {
public:
- explicit GCButton(u32 port_, s32 button_, GCAdapter::Adapter* adapter)
+ explicit GCButton(u32 port_, s32 button_, const GCAdapter::Adapter* adapter)
: port(port_), button(button_), gcadapter(adapter) {}
~GCButton() override;
@@ -27,18 +27,10 @@ public:
return false;
}
- bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const override {
- const float amplitude = amp_high + amp_low > 2.0f ? 1.0f : (amp_high + amp_low) * 0.5f;
- const auto new_amp =
- static_cast(pow(amplitude, 0.5f) * (3.0f - 2.0f * pow(amplitude, 0.15f)));
-
- return gcadapter->RumblePlay(port, new_amp);
- }
-
private:
const u32 port;
const s32 button;
- GCAdapter::Adapter* gcadapter;
+ const GCAdapter::Adapter* gcadapter;
};
class GCAxisButton final : public Input::ButtonDevice {
@@ -299,4 +291,42 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
return params;
}
+class GCVibration final : public Input::VibrationDevice {
+public:
+ explicit GCVibration(u32 port_, GCAdapter::Adapter* adapter)
+ : port(port_), gcadapter(adapter) {}
+
+ u8 GetStatus() const override {
+ return gcadapter->RumblePlay(port, 0);
+ }
+
+ bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
+ const auto mean_amplitude = (amp_low + amp_high) * 0.5f;
+ const auto processed_amplitude = static_cast(
+ pow(mean_amplitude, 0.5f) * (3.0f - 2.0f * pow(mean_amplitude, 0.15f)) * 0x8);
+
+ return gcadapter->RumblePlay(port, processed_amplitude);
+ }
+
+private:
+ const u32 port;
+ GCAdapter::Adapter* gcadapter;
+};
+
+/// An vibration device factory that creates vibration devices from GC Adapter
+GCVibrationFactory::GCVibrationFactory(std::shared_ptr adapter_)
+ : adapter(std::move(adapter_)) {}
+
+/**
+ * Creates a vibration device from a joystick
+ * @param params contains parameters for creating the device:
+ * - "port": the nth gcpad on the adapter
+ */
+std::unique_ptr GCVibrationFactory::Create(
+ const Common::ParamPackage& params) {
+ const auto port = static_cast(params.Get("port", 0));
+
+ return std::make_unique(port, adapter.get());
+}
+
} // namespace InputCommon
diff --git a/src/input_common/gcadapter/gc_poller.h b/src/input_common/gcadapter/gc_poller.h
index 0527f328f..d1271e3ea 100644
--- a/src/input_common/gcadapter/gc_poller.h
+++ b/src/input_common/gcadapter/gc_poller.h
@@ -64,4 +64,15 @@ private:
bool polling = false;
};
+/// A vibration device factory creates vibration devices from GC Adapter
+class GCVibrationFactory final : public Input::Factory {
+public:
+ explicit GCVibrationFactory(std::shared_ptr adapter_);
+
+ std::unique_ptr Create(const Common::ParamPackage& params) override;
+
+private:
+ std::shared_ptr adapter;
+};
+
} // namespace InputCommon
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index b438482cc..e59ad4ff5 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -28,6 +28,8 @@ struct InputSubsystem::Impl {
Input::RegisterFactory("gcpad", gcbuttons);
gcanalog = std::make_shared(gcadapter);
Input::RegisterFactory("gcpad", gcanalog);
+ gcvibration = std::make_shared(gcadapter);
+ Input::RegisterFactory("gcpad", gcvibration);
keyboard = std::make_shared();
Input::RegisterFactory("keyboard", keyboard);
@@ -64,9 +66,11 @@ struct InputSubsystem::Impl {
#endif
Input::UnregisterFactory("gcpad");
Input::UnregisterFactory("gcpad");
+ Input::UnregisterFactory("gcpad");
gcbuttons.reset();
gcanalog.reset();
+ gcvibration.reset();
Input::UnregisterFactory("cemuhookudp");
Input::UnregisterFactory("cemuhookudp");
@@ -142,6 +146,7 @@ struct InputSubsystem::Impl {
#endif
std::shared_ptr gcbuttons;
std::shared_ptr gcanalog;
+ std::shared_ptr gcvibration;
std::shared_ptr udpmotion;
std::shared_ptr udptouch;
std::shared_ptr udp;
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index 18fb2ac5e..a2a83cdc9 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -85,16 +85,17 @@ public:
using std::chrono::milliseconds;
using std::chrono::steady_clock;
- // Prevent vibrations less than 10ms apart from each other.
- if (duration_cast(steady_clock::now() - last_vibration) < milliseconds(10)) {
+ // Block non-zero vibrations less than 10ms apart from each other.
+ if ((amp_low != 0 || amp_high != 0) &&
+ duration_cast(steady_clock::now() - last_vibration) < milliseconds(10)) {
return false;
- };
+ }
last_vibration = steady_clock::now();
- if (sdl_controller != nullptr) {
+ if (sdl_controller) {
return SDL_GameControllerRumble(sdl_controller.get(), amp_low, amp_high, 0) == 0;
- } else if (sdl_joystick != nullptr) {
+ } else if (sdl_joystick) {
return SDL_JoystickRumble(sdl_joystick.get(), amp_low, amp_high, 0) == 0;
}
@@ -321,14 +322,6 @@ public:
return joystick->GetButton(button);
}
- bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
- const u16 processed_amp_low =
- static_cast(pow(amp_low, 0.5f) * (3.0f - 2.0f * pow(amp_low, 0.15f)) * 0xFFFF);
- const u16 processed_amp_high =
- static_cast(pow(amp_high, 0.5f) * (3.0f - 2.0f * pow(amp_high, 0.15f)) * 0xFFFF);
- return joystick->RumblePlay(processed_amp_low, processed_amp_high);
- }
-
private:
std::shared_ptr joystick;
int button;
@@ -412,6 +405,32 @@ private:
const float range;
};
+class SDLVibration final : public Input::VibrationDevice {
+public:
+ explicit SDLVibration(std::shared_ptr joystick_)
+ : joystick(std::move(joystick_)) {}
+
+ u8 GetStatus() const override {
+ joystick->RumblePlay(1, 1);
+ return joystick->RumblePlay(0, 0);
+ }
+
+ bool SetRumblePlay(f32 amp_low, f32 freq_low, f32 amp_high, f32 freq_high) const override {
+ const auto process_amplitude = [](f32 amplitude) {
+ return static_cast(std::pow(amplitude, 0.5f) *
+ (3.0f - 2.0f * std::pow(amplitude, 0.15f)) * 0xFFFF);
+ };
+
+ const auto processed_amp_low = process_amplitude(amp_low);
+ const auto processed_amp_high = process_amplitude(amp_high);
+
+ return joystick->RumblePlay(processed_amp_low, processed_amp_high);
+ }
+
+private:
+ std::shared_ptr joystick;
+};
+
class SDLDirectionMotion final : public Input::MotionDevice {
public:
explicit SDLDirectionMotion(std::shared_ptr joystick_, int hat_, Uint8 direction_)
@@ -554,7 +573,7 @@ class SDLAnalogFactory final : public Input::Factory {
public:
explicit SDLAnalogFactory(SDLState& state_) : state(state_) {}
/**
- * Creates analog device from joystick axes
+ * Creates an analog device from joystick axes
* @param params contains parameters for creating the device:
* - "guid": the guid of the joystick to bind
* - "port": the nth joystick of the same type
@@ -580,6 +599,26 @@ private:
SDLState& state;
};
+/// An vibration device factory that creates vibration devices from SDL joystick
+class SDLVibrationFactory final : public Input::Factory {
+public:
+ explicit SDLVibrationFactory(SDLState& state_) : state(state_) {}
+ /**
+ * Creates a vibration device from a joystick
+ * @param params contains parameters for creating the device:
+ * - "guid": the guid of the joystick to bind
+ * - "port": the nth joystick of the same type
+ */
+ std::unique_ptr Create(const Common::ParamPackage& params) override {
+ const std::string guid = params.Get("guid", "0");
+ const int port = params.Get("port", 0);
+ return std::make_unique(state.GetSDLJoystickByGUID(guid, port));
+ }
+
+private:
+ SDLState& state;
+};
+
/// A motion device factory that creates motion devices from SDL joystick
class SDLMotionFactory final : public Input::Factory {
public:
@@ -646,11 +685,13 @@ private:
SDLState::SDLState() {
using namespace Input;
- analog_factory = std::make_shared(*this);
button_factory = std::make_shared(*this);
+ analog_factory = std::make_shared(*this);
+ vibration_factory = std::make_shared(*this);
motion_factory = std::make_shared(*this);
- RegisterFactory("sdl", analog_factory);
RegisterFactory("sdl", button_factory);
+ RegisterFactory("sdl", analog_factory);
+ RegisterFactory("sdl", vibration_factory);
RegisterFactory("sdl", motion_factory);
// If the frontend is going to manage the event loop, then we don't start one here
@@ -687,6 +728,7 @@ SDLState::~SDLState() {
using namespace Input;
UnregisterFactory("sdl");
UnregisterFactory("sdl");
+ UnregisterFactory("sdl");
UnregisterFactory("sdl");
CloseJoysticks();
diff --git a/src/input_common/sdl/sdl_impl.h b/src/input_common/sdl/sdl_impl.h
index b9bb4dc56..08044b00d 100644
--- a/src/input_common/sdl/sdl_impl.h
+++ b/src/input_common/sdl/sdl_impl.h
@@ -22,6 +22,7 @@ namespace InputCommon::SDL {
class SDLAnalogFactory;
class SDLButtonFactory;
class SDLMotionFactory;
+class SDLVibrationFactory;
class SDLJoystick;
class SDLState : public State {
@@ -72,6 +73,7 @@ private:
std::shared_ptr button_factory;
std::shared_ptr analog_factory;
+ std::shared_ptr vibration_factory;
std::shared_ptr motion_factory;
bool start_thread = false;
diff --git a/src/input_common/settings.cpp b/src/input_common/settings.cpp
index b66c05856..557e7a9a0 100644
--- a/src/input_common/settings.cpp
+++ b/src/input_common/settings.cpp
@@ -14,13 +14,6 @@ const std::array mapping = {{
}};
}
-namespace NativeMotion {
-const std::array mapping = {{
- "motionleft",
- "motionright",
-}};
-}
-
namespace NativeAnalog {
const std::array mapping = {{
"lstick",
@@ -28,6 +21,20 @@ const std::array mapping = {{
}};
}
+namespace NativeVibration {
+const std::array mapping = {{
+ "left_vibration_device",
+ "right_vibration_device",
+}};
+}
+
+namespace NativeMotion {
+const std::array mapping = {{
+ "motionleft",
+ "motionright",
+}};
+}
+
namespace NativeMouseButton {
const std::array mapping = {{
"left",
diff --git a/src/input_common/settings.h b/src/input_common/settings.h
index 2763ed991..75486554b 100644
--- a/src/input_common/settings.h
+++ b/src/input_common/settings.h
@@ -66,17 +66,32 @@ constexpr int NUM_STICKS_HID = NumAnalogs;
extern const std::array mapping;
} // namespace NativeAnalog
+namespace NativeVibration {
+enum Values : int {
+ LeftVibrationDevice,
+ RightVibrationDevice,
+
+ NumVibrations,
+};
+
+constexpr int VIBRATION_HID_BEGIN = LeftVibrationDevice;
+constexpr int VIBRATION_HID_END = NumVibrations;
+constexpr int NUM_VIBRATIONS_HID = NumVibrations;
+
+extern const std::array mapping;
+}; // namespace NativeVibration
+
namespace NativeMotion {
enum Values : int {
- MOTIONLEFT,
- MOTIONRIGHT,
+ MotionLeft,
+ MotionRight,
NumMotions,
};
-constexpr int MOTION_HID_BEGIN = MOTIONLEFT;
+constexpr int MOTION_HID_BEGIN = MotionLeft;
constexpr int MOTION_HID_END = NumMotions;
-constexpr int NUM_MOTION_HID = NumMotions;
+constexpr int NUM_MOTIONS_HID = NumMotions;
extern const std::array mapping;
} // namespace NativeMotion
@@ -305,9 +320,11 @@ constexpr int NUM_KEYBOARD_MODS_HID = NumKeyboardMods;
} // namespace NativeKeyboard
-using ButtonsRaw = std::array;
using AnalogsRaw = std::array;
-using MotionRaw = std::array;
+using ButtonsRaw = std::array;
+using MotionsRaw = std::array;
+using VibrationsRaw = std::array;
+
using MouseButtonsRaw = std::array;
using KeyboardKeysRaw = std::array;
using KeyboardModsRaw = std::array;
@@ -330,7 +347,8 @@ struct PlayerInput {
ControllerType controller_type;
ButtonsRaw buttons;
AnalogsRaw analogs;
- MotionRaw motions;
+ VibrationsRaw vibrations;
+ MotionsRaw motions;
bool vibration_enabled;
int vibration_strength;
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index c5e671309..cdcd3d28d 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -478,6 +478,8 @@ void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index)
return;
}
+ ConfigureVibration::SetVibrationDevices(player_index);
+
// Player 1 and Handheld
auto& handheld = Settings::values.players.GetValue()[8];
// If Handheld is selected, copy all the settings from Player 1 to Handheld.
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 7f66f29aa..6fa842cd5 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -344,21 +344,6 @@ void Config::ReadPlayerValue(std::size_t player_index) {
}
}
- for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
- const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
- auto& player_motions = player.motions[i];
-
- player_motions = qt_config
- ->value(QStringLiteral("%1").arg(player_prefix) +
- QString::fromUtf8(Settings::NativeMotion::mapping[i]),
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player_motions.empty()) {
- player_motions = default_param;
- }
- }
-
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
@@ -375,6 +360,33 @@ void Config::ReadPlayerValue(std::size_t player_index) {
player_analogs = default_param;
}
}
+
+ for (int i = 0; i < Settings::NativeVibration::NumVibrations; ++i) {
+ auto& player_vibrations = player.vibrations[i];
+
+ player_vibrations =
+ qt_config
+ ->value(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromUtf8(Settings::NativeVibration::mapping[i]),
+ QString{})
+ .toString()
+ .toStdString();
+ }
+
+ for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
+ auto& player_motions = player.motions[i];
+
+ player_motions = qt_config
+ ->value(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromUtf8(Settings::NativeMotion::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (player_motions.empty()) {
+ player_motions = default_param;
+ }
+ }
}
void Config::ReadDebugValues() {
@@ -1014,13 +1026,6 @@ void Config::SavePlayerValue(std::size_t player_index) {
QString::fromStdString(player.buttons[i]),
QString::fromStdString(default_param));
}
- for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
- const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
- WriteSetting(QStringLiteral("%1").arg(player_prefix) +
- QString::fromStdString(Settings::NativeMotion::mapping[i]),
- QString::fromStdString(player.motions[i]),
- QString::fromStdString(default_param));
- }
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
@@ -1030,6 +1035,18 @@ void Config::SavePlayerValue(std::size_t player_index) {
QString::fromStdString(player.analogs[i]),
QString::fromStdString(default_param));
}
+ for (int i = 0; i < Settings::NativeVibration::NumVibrations; ++i) {
+ WriteSetting(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromStdString(Settings::NativeVibration::mapping[i]),
+ QString::fromStdString(player.vibrations[i]), QString{});
+ }
+ for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
+ WriteSetting(QStringLiteral("%1").arg(player_prefix) +
+ QString::fromStdString(Settings::NativeMotion::mapping[i]),
+ QString::fromStdString(player.motions[i]),
+ QString::fromStdString(default_param));
+ }
}
void Config::SaveDebugValues() {
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 460ff08a4..3e785c224 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -22,6 +22,7 @@
#include "ui_configure_input_player.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input_player.h"
+#include "yuzu/configuration/configure_vibration.h"
#include "yuzu/configuration/input_profiles.h"
#include "yuzu/util/limitable_input_dialog.h"
@@ -39,6 +40,10 @@ namespace {
void UpdateController(Settings::ControllerType controller_type, std::size_t npad_index,
bool connected) {
+ auto& player = Settings::values.players.GetValue()[npad_index];
+ player.controller_type = controller_type;
+ player.connected = connected;
+
Core::System& system{Core::System::GetInstance()};
if (!system.IsPoweredOn()) {
return;
@@ -565,6 +570,8 @@ void ConfigureInputPlayer::ApplyConfiguration() {
static_cast(ui->comboControllerType->currentIndex());
player.connected = ui->groupConnectedController->isChecked();
+ ConfigureVibration::SetVibrationDevices(player_index);
+
// Player 2-8
if (player_index != 0) {
UpdateController(player.controller_type, player_index, player.connected);
diff --git a/src/yuzu/configuration/configure_vibration.cpp b/src/yuzu/configuration/configure_vibration.cpp
index 1c68f28f3..714db5b80 100644
--- a/src/yuzu/configuration/configure_vibration.cpp
+++ b/src/yuzu/configuration/configure_vibration.cpp
@@ -2,6 +2,12 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include
+#include
+
+#include
+
+#include "common/param_package.h"
#include "core/settings.h"
#include "ui_configure_vibration.h"
#include "yuzu/configuration/configure_vibration.h"
@@ -53,6 +59,80 @@ void ConfigureVibration::ApplyConfiguration() {
ui->checkBoxAccurateVibration->isChecked());
}
+void ConfigureVibration::SetVibrationDevices(std::size_t player_index) {
+ using namespace Settings::NativeButton;
+ static constexpr std::array, 2> buttons{{
+ {DLeft, DUp, DRight, DDown, L, ZL}, // Left Buttons
+ {A, B, X, Y, R, ZR}, // Right Buttons
+ }};
+
+ auto& player = Settings::values.players.GetValue()[player_index];
+
+ for (std::size_t device_idx = 0; device_idx < buttons.size(); ++device_idx) {
+ std::unordered_map params_count;
+
+ for (const auto button_index : buttons[device_idx]) {
+ const auto& player_button = player.buttons[button_index];
+
+ if (params_count.find(player_button) != params_count.end()) {
+ ++params_count[player_button];
+ continue;
+ }
+
+ params_count.insert_or_assign(player_button, 1);
+ }
+
+ const auto it = std::max_element(
+ params_count.begin(), params_count.end(),
+ [](const auto& lhs, const auto& rhs) { return lhs.second < rhs.second; });
+
+ auto& vibration_param_str = player.vibrations[device_idx];
+ vibration_param_str.clear();
+
+ if (it->first.empty()) {
+ continue;
+ }
+
+ const auto param = Common::ParamPackage(it->first);
+
+ const auto engine = param.Get("engine", "");
+ const auto guid = param.Get("guid", "");
+ const auto port = param.Get("port", "");
+
+ if (engine.empty() || engine == "keyboard") {
+ continue;
+ }
+
+ vibration_param_str += fmt::format("engine:{}", engine);
+
+ if (!port.empty()) {
+ vibration_param_str += fmt::format(",port:{}", port);
+ }
+ if (!guid.empty()) {
+ vibration_param_str += fmt::format(",guid:{}", guid);
+ }
+ }
+
+ if (player.vibrations[0] != player.vibrations[1]) {
+ return;
+ }
+
+ if (!player.vibrations[0].empty() &&
+ player.controller_type != Settings::ControllerType::RightJoycon) {
+ player.vibrations[1].clear();
+ } else if (!player.vibrations[1].empty() &&
+ player.controller_type == Settings::ControllerType::RightJoycon) {
+ player.vibrations[0].clear();
+ }
+}
+
+void ConfigureVibration::SetAllVibrationDevices() {
+ // Set vibration devices for all player indices including handheld
+ for (std::size_t player_idx = 0; player_idx < NUM_PLAYERS + 1; ++player_idx) {
+ SetVibrationDevices(player_idx);
+ }
+}
+
void ConfigureVibration::changeEvent(QEvent* event) {
if (event->type() == QEvent::LanguageChange) {
RetranslateUI();
diff --git a/src/yuzu/configuration/configure_vibration.h b/src/yuzu/configuration/configure_vibration.h
index 37bbc2653..07411a86f 100644
--- a/src/yuzu/configuration/configure_vibration.h
+++ b/src/yuzu/configuration/configure_vibration.h
@@ -24,6 +24,9 @@ public:
void ApplyConfiguration();
+ static void SetVibrationDevices(std::size_t player_index);
+ static void SetAllVibrationDevices();
+
private:
void changeEvent(QEvent* event) override;
void RetranslateUI();
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 54a46827f..76a5c32f4 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -18,6 +18,7 @@
#include "applets/web_browser.h"
#include "configuration/configure_input.h"
#include "configuration/configure_per_game.h"
+#include "configuration/configure_vibration.h"
#include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_real.h"
#include "core/frontend/applets/controller.h"
@@ -1096,6 +1097,8 @@ void GMainWindow::BootGame(const QString& filename) {
Config per_game_config(fmt::format("{:016X}", title_id), Config::ConfigType::PerGameConfig);
}
+ ConfigureVibration::SetAllVibrationDevices();
+
Settings::LogSettings();
if (UISettings::values.select_user_on_boot) {
--
cgit v1.2.3
From 91c06dae1a68efb2d6ae110d0aa28d7b3aafd573 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Fri, 23 Oct 2020 12:09:28 -0400
Subject: input: Disconnect a controller prior to connecting a new one
Some games do not respond to a change in controller type if 1) The controller is not disconnected prior to being reconnected and/or 2) The controller is reconnected instantly after being disconnected.
Since it is not possible to change controllers instantly on hardware and requiring a disconnect prior to connecting a new one, we should emulate this as well with a small delay, fixing the aforementioned issue.
---
src/yuzu/applets/controller.cpp | 62 ++++++++++++++---------
src/yuzu/configuration/configure_input_player.cpp | 61 +++++++++++++---------
2 files changed, 73 insertions(+), 50 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index cdcd3d28d..552cb7204 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -19,6 +19,8 @@
namespace {
+constexpr std::size_t HANDHELD_INDEX = 8;
+
constexpr std::array, 8> led_patterns{{
{true, false, false, false},
{true, true, false, false},
@@ -260,11 +262,6 @@ int QtControllerSelectorDialog::exec() {
}
void QtControllerSelectorDialog::ApplyConfiguration() {
- // Update the controller state once more, just to be sure they are properly applied.
- for (std::size_t index = 0; index < NUM_PLAYERS; ++index) {
- UpdateControllerState(index);
- }
-
const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue();
Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked());
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue());
@@ -275,15 +272,16 @@ void QtControllerSelectorDialog::ApplyConfiguration() {
void QtControllerSelectorDialog::LoadConfiguration() {
for (std::size_t index = 0; index < NUM_PLAYERS; ++index) {
- const auto connected = Settings::values.players.GetValue()[index].connected ||
- (index == 0 && Settings::values.players.GetValue()[8].connected);
+ const auto connected =
+ Settings::values.players.GetValue()[index].connected ||
+ (index == 0 && Settings::values.players.GetValue()[HANDHELD_INDEX].connected);
player_groupboxes[index]->setChecked(connected);
connected_controller_checkboxes[index]->setChecked(connected);
emulated_controllers[index]->setCurrentIndex(
GetIndexFromControllerType(Settings::values.players.GetValue()[index].controller_type));
}
- UpdateDockedState(Settings::values.players.GetValue()[8].connected);
+ UpdateDockedState(Settings::values.players.GetValue()[HANDHELD_INDEX].connected);
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
@@ -468,32 +466,46 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)
void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index) {
auto& player = Settings::values.players.GetValue()[player_index];
- player.controller_type =
+ const auto controller_type =
GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex());
- player.connected = player_groupboxes[player_index]->isChecked();
+ const auto player_connected = player_groupboxes[player_index]->isChecked() &&
+ controller_type != Settings::ControllerType::Handheld;
- // Player 2-8
- if (player_index != 0) {
- UpdateController(player.controller_type, player_index, player.connected);
+ if (player.controller_type == controller_type && player.connected == player_connected) {
+ // Set vibration devices in the event that the input device has changed.
+ ConfigureVibration::SetVibrationDevices(player_index);
return;
}
+ // Disconnect the controller first.
+ UpdateController(controller_type, player_index, false);
+
+ player.controller_type = controller_type;
+ player.connected = player_connected;
+
ConfigureVibration::SetVibrationDevices(player_index);
- // Player 1 and Handheld
- auto& handheld = Settings::values.players.GetValue()[8];
- // If Handheld is selected, copy all the settings from Player 1 to Handheld.
- if (player.controller_type == Settings::ControllerType::Handheld) {
- handheld = player;
- handheld.connected = player_groupboxes[player_index]->isChecked();
- player.connected = false; // Disconnect Player 1
- } else {
- player.connected = player_groupboxes[player_index]->isChecked();
- handheld.connected = false; // Disconnect Handheld
+ // Handheld
+ if (player_index == 0) {
+ auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
+ if (controller_type == Settings::ControllerType::Handheld) {
+ handheld = player;
+ }
+ handheld.connected = player_groupboxes[player_index]->isChecked() &&
+ controller_type == Settings::ControllerType::Handheld;
+ UpdateController(Settings::ControllerType::Handheld, 8, handheld.connected);
+ }
+
+ if (!player.connected) {
+ return;
}
- UpdateController(player.controller_type, player_index, player.connected);
- UpdateController(Settings::ControllerType::Handheld, 8, handheld.connected);
+ // This emulates a delay between disconnecting and reconnecting controllers as some games
+ // do not respond to a change in controller type if it was instantaneous.
+ using namespace std::chrono_literals;
+ std::this_thread::sleep_for(20ms);
+
+ UpdateController(controller_type, player_index, player_connected);
}
void QtControllerSelectorDialog::UpdateLEDPattern(std::size_t player_index) {
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 3e785c224..1ee4725ef 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -26,8 +26,6 @@
#include "yuzu/configuration/input_profiles.h"
#include "yuzu/util/limitable_input_dialog.h"
-constexpr std::size_t HANDHELD_INDEX = 8;
-
const std::array
ConfigureInputPlayer::analog_sub_buttons{{
"up",
@@ -38,12 +36,10 @@ const std::array
namespace {
+constexpr std::size_t HANDHELD_INDEX = 8;
+
void UpdateController(Settings::ControllerType controller_type, std::size_t npad_index,
bool connected) {
- auto& player = Settings::values.players.GetValue()[npad_index];
- player.controller_type = controller_type;
- player.connected = connected;
-
Core::System& system{Core::System::GetInstance()};
if (!system.IsPoweredOn()) {
return;
@@ -563,35 +559,50 @@ void ConfigureInputPlayer::ApplyConfiguration() {
}
auto& motions = player.motions;
+
std::transform(motions_param.begin(), motions_param.end(), motions.begin(),
[](const Common::ParamPackage& param) { return param.Serialize(); });
- player.controller_type =
- static_cast(ui->comboControllerType->currentIndex());
- player.connected = ui->groupConnectedController->isChecked();
+ const auto controller_type =
+ GetControllerTypeFromIndex(ui->comboControllerType->currentIndex());
+ const auto player_connected = ui->groupConnectedController->isChecked() &&
+ controller_type != Settings::ControllerType::Handheld;
+
+ if (player.controller_type == controller_type && player.connected == player_connected) {
+ // Set vibration devices in the event that the input device has changed.
+ ConfigureVibration::SetVibrationDevices(player_index);
+ return;
+ }
+
+ // Disconnect the controller first.
+ UpdateController(controller_type, player_index, false);
+
+ player.controller_type = controller_type;
+ player.connected = player_connected;
ConfigureVibration::SetVibrationDevices(player_index);
- // Player 2-8
- if (player_index != 0) {
- UpdateController(player.controller_type, player_index, player.connected);
- return;
+ // Handheld
+ if (player_index == 0) {
+ auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
+ if (controller_type == Settings::ControllerType::Handheld) {
+ handheld = player;
+ }
+ handheld.connected = ui->groupConnectedController->isChecked() &&
+ controller_type == Settings::ControllerType::Handheld;
+ UpdateController(Settings::ControllerType::Handheld, HANDHELD_INDEX, handheld.connected);
}
- // Player 1 and Handheld
- auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
- // If Handheld is selected, copy all the settings from Player 1 to Handheld.
- if (player.controller_type == Settings::ControllerType::Handheld) {
- handheld = player;
- handheld.connected = ui->groupConnectedController->isChecked();
- player.connected = false; // Disconnect Player 1
- } else {
- player.connected = ui->groupConnectedController->isChecked();
- handheld.connected = false; // Disconnect Handheld
+ if (!player.connected) {
+ return;
}
- UpdateController(player.controller_type, player_index, player.connected);
- UpdateController(Settings::ControllerType::Handheld, HANDHELD_INDEX, handheld.connected);
+ // This emulates a delay between disconnecting and reconnecting controllers as some games
+ // do not respond to a change in controller type if it was instantaneous.
+ using namespace std::chrono_literals;
+ std::this_thread::sleep_for(20ms);
+
+ UpdateController(controller_type, player_index, player_connected);
}
void ConfigureInputPlayer::showEvent(QShowEvent* event) {
--
cgit v1.2.3
From 760a9e869322cbda51416f7001842557b90754af Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Mon, 26 Oct 2020 03:28:03 -0400
Subject: applets/controller: Change the input button to create input profiles
Co-authored-by: Its-Rei
---
src/yuzu/CMakeLists.txt | 6 +-
src/yuzu/applets/controller.cpp | 20 +++---
src/yuzu/applets/controller.h | 8 ++-
src/yuzu/applets/controller.ui | 4 +-
src/yuzu/configuration/configure_input_dialog.cpp | 37 -----------
src/yuzu/configuration/configure_input_dialog.h | 38 ------------
src/yuzu/configuration/configure_input_dialog.ui | 57 -----------------
src/yuzu/configuration/configure_input_player.cpp | 5 +-
.../configure_input_profile_dialog.cpp | 36 +++++++++++
.../configuration/configure_input_profile_dialog.h | 39 ++++++++++++
.../configure_input_profile_dialog.ui | 71 ++++++++++++++++++++++
11 files changed, 169 insertions(+), 152 deletions(-)
delete mode 100644 src/yuzu/configuration/configure_input_dialog.cpp
delete mode 100644 src/yuzu/configuration/configure_input_dialog.h
delete mode 100644 src/yuzu/configuration/configure_input_dialog.ui
create mode 100644 src/yuzu/configuration/configure_input_profile_dialog.cpp
create mode 100644 src/yuzu/configuration/configure_input_profile_dialog.h
create mode 100644 src/yuzu/configuration/configure_input_profile_dialog.ui
(limited to 'src/yuzu')
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index bf1fae9fa..b16b54032 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -68,12 +68,12 @@ add_executable(yuzu
configuration/configure_input_advanced.cpp
configuration/configure_input_advanced.h
configuration/configure_input_advanced.ui
- configuration/configure_input_dialog.cpp
- configuration/configure_input_dialog.h
- configuration/configure_input_dialog.ui
configuration/configure_input_player.cpp
configuration/configure_input_player.h
configuration/configure_input_player.ui
+ configuration/configure_input_profile_dialog.cpp
+ configuration/configure_input_profile_dialog.h
+ configuration/configure_input_profile_dialog.ui
configuration/configure_motion_touch.cpp
configuration/configure_motion_touch.h
configuration/configure_motion_touch.ui
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index 552cb7204..5112d48d2 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -13,8 +13,10 @@
#include "core/hle/service/sm/sm.h"
#include "ui_controller.h"
#include "yuzu/applets/controller.h"
-#include "yuzu/configuration/configure_input_dialog.h"
+#include "yuzu/configuration/configure_input.h"
+#include "yuzu/configuration/configure_input_profile_dialog.h"
#include "yuzu/configuration/configure_vibration.h"
+#include "yuzu/configuration/input_profiles.h"
#include "yuzu/main.h"
namespace {
@@ -109,7 +111,8 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
QWidget* parent, Core::Frontend::ControllerParameters parameters_,
InputCommon::InputSubsystem* input_subsystem_)
: QDialog(parent), ui(std::make_unique()),
- parameters(std::move(parameters_)), input_subsystem(input_subsystem_) {
+ parameters(std::move(parameters_)), input_subsystem{input_subsystem_},
+ input_profiles(std::make_unique()) {
ui->setupUi(this);
player_widgets = {
@@ -230,7 +233,7 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
&QtControllerSelectorDialog::CallConfigureVibrationDialog);
connect(ui->inputConfigButton, &QPushButton::clicked, this,
- &QtControllerSelectorDialog::CallConfigureInputDialog);
+ &QtControllerSelectorDialog::CallConfigureInputProfileDialog);
connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
&QtControllerSelectorDialog::ApplyConfiguration);
@@ -299,20 +302,13 @@ void QtControllerSelectorDialog::CallConfigureVibrationDialog() {
}
}
-void QtControllerSelectorDialog::CallConfigureInputDialog() {
- const auto max_supported_players = parameters.enable_single_mode ? 1 : parameters.max_players;
-
- ConfigureInputDialog dialog(this, max_supported_players, input_subsystem);
+void QtControllerSelectorDialog::CallConfigureInputProfileDialog() {
+ ConfigureInputProfileDialog dialog(this, input_subsystem, input_profiles.get());
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
Qt::WindowSystemMenuHint);
dialog.setWindowModality(Qt::WindowModal);
dialog.exec();
-
- dialog.ApplyConfiguration();
-
- LoadConfiguration();
- CheckIfParametersMet();
}
bool QtControllerSelectorDialog::CheckIfParametersMet() {
diff --git a/src/yuzu/applets/controller.h b/src/yuzu/applets/controller.h
index a2ce03c8f..4344e1dd0 100644
--- a/src/yuzu/applets/controller.h
+++ b/src/yuzu/applets/controller.h
@@ -16,6 +16,8 @@ class QDialogButtonBox;
class QGroupBox;
class QLabel;
+class InputProfiles;
+
namespace InputCommon {
class InputSubsystem;
}
@@ -45,8 +47,8 @@ private:
// Initializes the "Configure Vibration" Dialog.
void CallConfigureVibrationDialog();
- // Initializes the "Configure Input" Dialog.
- void CallConfigureInputDialog();
+ // Initializes the "Create Input Profile" Dialog.
+ void CallConfigureInputProfileDialog();
// Checks the current configuration against the given parameters.
// This sets and returns the value of parameters_met.
@@ -83,6 +85,8 @@ private:
InputCommon::InputSubsystem* input_subsystem;
+ std::unique_ptr input_profiles;
+
// This is true if and only if all parameters are met. Otherwise, this is false.
// This determines whether the "OK" button can be clicked to exit the applet.
bool parameters_met{false};
diff --git a/src/yuzu/applets/controller.ui b/src/yuzu/applets/controller.ui
index 8e571ba8f..c8cb6bcf3 100644
--- a/src/yuzu/applets/controller.ui
+++ b/src/yuzu/applets/controller.ui
@@ -2402,7 +2402,7 @@
-
- Input Config
+ Profiles
@@ -2429,7 +2429,7 @@
min-width: 68px;
- Open
+ Create
diff --git a/src/yuzu/configuration/configure_input_dialog.cpp b/src/yuzu/configuration/configure_input_dialog.cpp
deleted file mode 100644
index 1866003c2..000000000
--- a/src/yuzu/configuration/configure_input_dialog.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2020 yuzu Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "ui_configure_input_dialog.h"
-#include "yuzu/configuration/configure_input_dialog.h"
-
-ConfigureInputDialog::ConfigureInputDialog(QWidget* parent, std::size_t max_players,
- InputCommon::InputSubsystem* input_subsystem)
- : QDialog(parent), ui(std::make_unique()),
- input_widget(new ConfigureInput(this)) {
- ui->setupUi(this);
-
- input_widget->Initialize(input_subsystem, max_players);
-
- ui->inputLayout->addWidget(input_widget);
-
- RetranslateUI();
-}
-
-ConfigureInputDialog::~ConfigureInputDialog() = default;
-
-void ConfigureInputDialog::ApplyConfiguration() {
- input_widget->ApplyConfiguration();
-}
-
-void ConfigureInputDialog::changeEvent(QEvent* event) {
- if (event->type() == QEvent::LanguageChange) {
- RetranslateUI();
- }
-
- QDialog::changeEvent(event);
-}
-
-void ConfigureInputDialog::RetranslateUI() {
- ui->retranslateUi(this);
-}
diff --git a/src/yuzu/configuration/configure_input_dialog.h b/src/yuzu/configuration/configure_input_dialog.h
deleted file mode 100644
index d1bd865f9..000000000
--- a/src/yuzu/configuration/configure_input_dialog.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2020 yuzu Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include
-#include
-#include "yuzu/configuration/configure_input.h"
-
-class QPushButton;
-
-namespace InputCommon {
-class InputSubsystem;
-}
-
-namespace Ui {
-class ConfigureInputDialog;
-}
-
-class ConfigureInputDialog : public QDialog {
- Q_OBJECT
-
-public:
- explicit ConfigureInputDialog(QWidget* parent, std::size_t max_players,
- InputCommon::InputSubsystem* input_subsystem);
- ~ConfigureInputDialog() override;
-
- void ApplyConfiguration();
-
-private:
- void changeEvent(QEvent* event) override;
- void RetranslateUI();
-
- std::unique_ptr ui;
-
- ConfigureInput* input_widget;
-};
diff --git a/src/yuzu/configuration/configure_input_dialog.ui b/src/yuzu/configuration/configure_input_dialog.ui
deleted file mode 100644
index b92ddb200..000000000
--- a/src/yuzu/configuration/configure_input_dialog.ui
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
- ConfigureInputDialog
-
-
-
- 0
- 0
- 70
- 540
-
-
-
- Configure Input
-
-
-
- 2
-
-
- 9
-
-
- 9
-
-
- 9
-
-
- 9
-
- -
-
-
- -
-
-
-
-
-
- QDialogButtonBox::Ok
-
-
-
-
-
-
-
-
-
-
- buttonBox
- accepted()
- ConfigureInputDialog
- accept()
-
-
-
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 1ee4725ef..4ed704793 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -459,11 +459,14 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
});
}
+ if (debug || player_index == 9) {
+ ui->groupConnectedController->setCheckable(false);
+ }
+
// The Debug Controller can only choose the Pro Controller.
if (debug) {
ui->buttonScreenshot->setEnabled(false);
ui->buttonHome->setEnabled(false);
- ui->groupConnectedController->setCheckable(false);
QStringList debug_controller_types = {
tr("Pro Controller"),
};
diff --git a/src/yuzu/configuration/configure_input_profile_dialog.cpp b/src/yuzu/configuration/configure_input_profile_dialog.cpp
new file mode 100644
index 000000000..818399b47
--- /dev/null
+++ b/src/yuzu/configuration/configure_input_profile_dialog.cpp
@@ -0,0 +1,36 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "ui_configure_input_profile_dialog.h"
+#include "yuzu/configuration/configure_input_profile_dialog.h"
+
+ConfigureInputProfileDialog::ConfigureInputProfileDialog(
+ QWidget* parent, InputCommon::InputSubsystem* input_subsystem, InputProfiles* profiles)
+ : QDialog(parent), ui(std::make_unique()),
+ profile_widget(new ConfigureInputPlayer(this, 9, nullptr, input_subsystem, profiles, false)) {
+ ui->setupUi(this);
+
+ ui->controllerLayout->addWidget(profile_widget);
+
+ connect(ui->clear_all_button, &QPushButton::clicked, this,
+ [this] { profile_widget->ClearAll(); });
+ connect(ui->restore_defaults_button, &QPushButton::clicked, this,
+ [this] { profile_widget->RestoreDefaults(); });
+
+ RetranslateUI();
+}
+
+ConfigureInputProfileDialog::~ConfigureInputProfileDialog() = default;
+
+void ConfigureInputProfileDialog::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QDialog::changeEvent(event);
+}
+
+void ConfigureInputProfileDialog::RetranslateUI() {
+ ui->retranslateUi(this);
+}
diff --git a/src/yuzu/configuration/configure_input_profile_dialog.h b/src/yuzu/configuration/configure_input_profile_dialog.h
new file mode 100644
index 000000000..d4a3973d9
--- /dev/null
+++ b/src/yuzu/configuration/configure_input_profile_dialog.h
@@ -0,0 +1,39 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include
+#include
+#include "yuzu/configuration/configure_input_player.h"
+
+class QPushButton;
+
+class InputProfiles;
+
+namespace InputCommon {
+class InputSubsystem;
+}
+
+namespace Ui {
+class ConfigureInputProfileDialog;
+}
+
+class ConfigureInputProfileDialog : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit ConfigureInputProfileDialog(QWidget* parent,
+ InputCommon::InputSubsystem* input_subsystem,
+ InputProfiles* profiles);
+ ~ConfigureInputProfileDialog() override;
+
+private:
+ void changeEvent(QEvent* event) override;
+ void RetranslateUI();
+
+ std::unique_ptr ui;
+
+ ConfigureInputPlayer* profile_widget;
+};
diff --git a/src/yuzu/configuration/configure_input_profile_dialog.ui b/src/yuzu/configuration/configure_input_profile_dialog.ui
new file mode 100644
index 000000000..726cf6905
--- /dev/null
+++ b/src/yuzu/configuration/configure_input_profile_dialog.ui
@@ -0,0 +1,71 @@
+
+
+ ConfigureInputProfileDialog
+
+
+
+ 0
+ 0
+ 70
+ 540
+
+
+
+ Create Input Profile
+
+
+
+ 2
+
+
+ 9
+
+
+ 9
+
+
+ 9
+
+
+ 9
+
+ -
+
+
+ -
+
+
-
+
+
+ Clear
+
+
+
+ -
+
+
+ Defaults
+
+
+
+ -
+
+
+ QDialogButtonBox::Ok
+
+
+
+
+
+
+
+
+
+
+ buttonBox
+ accepted()
+ ConfigureInputProfileDialog
+ accept()
+
+
+
--
cgit v1.2.3
From 117bdc71e016629b9355b33a6d64655f0245f833 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Tue, 27 Oct 2020 13:15:57 -0400
Subject: sdl_impl: Revert to the "old" method of mapping sticks
Not all controllers have a SDL_GameController binding. This caused controllers not present in the SDL GameController database to have buttons mapped instead of axes.
Furthermore, it was not possible to invert the axes when it could be useful such as emulating a horizontal single joycon or other potential cases. This allows us to invert the axes by reversing the order of mapping (vertical, then horizontal).
---
src/input_common/sdl/sdl_impl.cpp | 45 +++++++----------------
src/yuzu/configuration/configure_input_player.cpp | 12 ++++++
src/yuzu/configuration/configure_input_player.h | 5 ++-
3 files changed, 29 insertions(+), 33 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index a9f7e5103..6024ed97a 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -1068,7 +1068,6 @@ public:
void Start(const std::string& device_id) override {
SDLPoller::Start(device_id);
- // Load the game controller
// Reset stored axes
analog_x_axis = -1;
analog_y_axis = -1;
@@ -1081,40 +1080,21 @@ public:
if (event.type == SDL_JOYAXISMOTION && std::abs(event.jaxis.value / 32767.0) < 0.5) {
continue;
}
- // Simplify controller config by testing if game controller support is enabled.
if (event.type == SDL_JOYAXISMOTION) {
const auto axis = event.jaxis.axis;
- if (const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which);
- auto* const controller = joystick->GetSDLGameController()) {
- const auto axis_left_x =
- SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX)
- .value.axis;
- const auto axis_left_y =
- SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTY)
- .value.axis;
- const auto axis_right_x =
- SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTX)
- .value.axis;
- const auto axis_right_y =
- SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_RIGHTY)
- .value.axis;
-
- if (axis == axis_left_x || axis == axis_left_y) {
- analog_x_axis = axis_left_x;
- analog_y_axis = axis_left_y;
- break;
- } else if (axis == axis_right_x || axis == axis_right_y) {
- analog_x_axis = axis_right_x;
- analog_y_axis = axis_right_y;
- break;
- }
+ // In order to return a complete analog param, we need inputs for both axes.
+ // First we take the x-axis (horizontal) input, then the y-axis (vertical) input.
+ if (analog_x_axis == -1) {
+ analog_x_axis = axis;
+ } else if (analog_y_axis == -1 && analog_x_axis != axis) {
+ analog_y_axis = axis;
+ }
+ } else {
+ // If the press wasn't accepted as a joy axis, check for a button press
+ auto button_press = button_poller.FromEvent(event);
+ if (button_press) {
+ return *button_press;
}
- }
-
- // If the press wasn't accepted as a joy axis, check for a button press
- auto button_press = button_poller.FromEvent(event);
- if (button_press) {
- return *button_press;
}
}
@@ -1127,6 +1107,7 @@ public:
return params;
}
}
+
return {};
}
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 4ed704793..5abf9f0bf 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -370,6 +370,18 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
}
connect(analog_button, &QPushButton::clicked, [=, this] {
+ if (!map_analog_stick_accepted) {
+ map_analog_stick_accepted =
+ QMessageBox::information(
+ this, tr("Map Analog Stick"),
+ tr("After pressing OK, first move your joystick horizontally, and then "
+ "vertically.\nTo invert the axes, first move your joystick "
+ "vertically, and then horizontally."),
+ QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok;
+ if (!map_analog_stick_accepted) {
+ return;
+ }
+ }
HandleClick(
analog_map_buttons[analog_id][sub_button_id],
[=, this](const Common::ParamPackage& params) {
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index 05dee5af5..4895e8850 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -181,9 +181,12 @@ private:
std::vector> device_pollers;
+ /// A flag to indicate that the "Map Analog Stick" pop-up has been shown and accepted once.
+ bool map_analog_stick_accepted{};
+
/// A flag to indicate if keyboard keys are okay when configuring an input. If this is false,
/// keyboard events are ignored.
- bool want_keyboard_mouse = false;
+ bool want_keyboard_mouse{};
/// List of physical devices users can map with. If a SDL backed device is selected, then you
/// can use this device to get a default mapping.
--
cgit v1.2.3
From 97b2220a822548eed83993fceebe0e611dbec84b Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Tue, 27 Oct 2020 13:33:25 -0400
Subject: general: Fix compiler warnings on linux and miscellaneous changes
---
src/core/hle/service/hid/controllers/npad.cpp | 17 ++++++++++-------
src/core/hle/service/hid/controllers/npad.h | 2 +-
src/yuzu/applets/controller.cpp | 5 +++--
src/yuzu/configuration/configure_debug_controller.cpp | 1 +
src/yuzu/configuration/configure_debug_controller.h | 3 ++-
src/yuzu/configuration/configure_input.h | 9 ++++-----
src/yuzu/configuration/configure_input_advanced.cpp | 6 +++---
src/yuzu/configuration/configure_input_advanced.h | 2 +-
src/yuzu/configuration/configure_input_player.cpp | 3 ++-
.../configuration/configure_input_profile_dialog.cpp | 1 +
src/yuzu/configuration/configure_input_profile_dialog.h | 3 ++-
src/yuzu/main.cpp | 1 +
12 files changed, 31 insertions(+), 22 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index cfafabbd8..30715267c 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -287,7 +287,7 @@ void Controller_NPad::OnLoadInputDevices() {
void Controller_NPad::OnRelease() {
for (std::size_t npad_idx = 0; npad_idx < vibrations.size(); ++npad_idx) {
for (std::size_t device_idx = 0; device_idx < vibrations[npad_idx].size(); ++device_idx) {
- VibrateControllerAtIndex(npad_idx, device_idx);
+ VibrateControllerAtIndex(npad_idx, device_idx, {});
}
}
}
@@ -720,11 +720,14 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size
last_vibration_timepoints[npad_index][device_index] = now;
}
- return vibrations[npad_index][device_index]->SetRumblePlay(
- std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f),
- vibration_value.freq_low,
- std::min(vibration_value.amp_high * player.vibration_strength / 100.0f, 1.0f),
- vibration_value.freq_high);
+ auto& vibration = vibrations[npad_index][device_index];
+ const auto player_vibration_strength = static_cast(player.vibration_strength);
+ const auto amp_low =
+ std::min(vibration_value.amp_low * player_vibration_strength / 100.0f, 1.0f);
+ const auto amp_high =
+ std::min(vibration_value.amp_high * player_vibration_strength / 100.0f, 1.0f);
+ return vibration->SetRumblePlay(amp_low, vibration_value.freq_low, amp_high,
+ vibration_value.freq_high);
}
void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle,
@@ -855,7 +858,7 @@ void Controller_NPad::DisconnectNpad(u32 npad_id) {
void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) {
for (std::size_t device_idx = 0; device_idx < vibrations[npad_index].size(); ++device_idx) {
// Send an empty vibration to stop any vibrations.
- VibrateControllerAtIndex(npad_index, device_idx);
+ VibrateControllerAtIndex(npad_index, device_idx, {});
vibration_devices_mounted[npad_index][device_idx] = false;
}
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index f5122124c..99384524b 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -149,7 +149,7 @@ public:
void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
- const VibrationValue& vibration_value = {});
+ const VibrationValue& vibration_value);
void VibrateController(const DeviceHandle& vibration_device_handle,
const VibrationValue& vibration_value);
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index 5112d48d2..8ecfec770 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include
+#include
#include "common/assert.h"
#include "common/string_util.h"
@@ -356,7 +357,7 @@ bool QtControllerSelectorDialog::CheckIfParametersMet() {
}
void QtControllerSelectorDialog::SetSupportedControllers() {
- const QString theme = [this] {
+ const QString theme = [] {
if (QIcon::themeName().contains(QStringLiteral("dark"))) {
return QStringLiteral("_dark");
} else if (QIcon::themeName().contains(QStringLiteral("midnight"))) {
@@ -445,7 +446,7 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)
}
}();
- const QString theme = [this] {
+ const QString theme = [] {
if (QIcon::themeName().contains(QStringLiteral("dark"))) {
return QStringLiteral("_dark");
} else if (QIcon::themeName().contains(QStringLiteral("midnight"))) {
diff --git a/src/yuzu/configuration/configure_debug_controller.cpp b/src/yuzu/configuration/configure_debug_controller.cpp
index 6dc9c5e57..a878ef9c6 100644
--- a/src/yuzu/configuration/configure_debug_controller.cpp
+++ b/src/yuzu/configuration/configure_debug_controller.cpp
@@ -4,6 +4,7 @@
#include "ui_configure_debug_controller.h"
#include "yuzu/configuration/configure_debug_controller.h"
+#include "yuzu/configuration/configure_input_player.h"
ConfigureDebugController::ConfigureDebugController(QWidget* parent,
InputCommon::InputSubsystem* input_subsystem,
diff --git a/src/yuzu/configuration/configure_debug_controller.h b/src/yuzu/configuration/configure_debug_controller.h
index 2694b3419..b4f53fad5 100644
--- a/src/yuzu/configuration/configure_debug_controller.h
+++ b/src/yuzu/configuration/configure_debug_controller.h
@@ -6,10 +6,11 @@
#include
#include
-#include "yuzu/configuration/configure_input_player.h"
class QPushButton;
+class ConfigureInputPlayer;
+
class InputProfiles;
namespace InputCommon {
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h
index f135a4299..9eba9b523 100644
--- a/src/yuzu/configuration/configure_input.h
+++ b/src/yuzu/configuration/configure_input.h
@@ -8,17 +8,16 @@
#include
#include
+#include
#include
-#include "yuzu/configuration/configure_input_advanced.h"
-#include "yuzu/configuration/configure_input_player.h"
-
-#include "ui_configure_input.h"
-
class QCheckBox;
class QString;
class QTimer;
+class ConfigureInputAdvanced;
+class ConfigureInputPlayer;
+
class InputProfiles;
namespace InputCommon {
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index 3074be833..abaf03630 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -68,8 +68,7 @@ ConfigureInputAdvanced::ConfigureInputAdvanced(QWidget* parent)
for (std::size_t button_idx = 0; button_idx < color_buttons.size(); ++button_idx) {
connect(color_buttons[button_idx], &QPushButton::clicked, this,
[this, player_idx, button_idx] {
- OnControllerButtonClick(static_cast(player_idx),
- static_cast(button_idx));
+ OnControllerButtonClick(player_idx, button_idx);
});
}
}
@@ -94,7 +93,8 @@ ConfigureInputAdvanced::ConfigureInputAdvanced(QWidget* parent)
ConfigureInputAdvanced::~ConfigureInputAdvanced() = default;
-void ConfigureInputAdvanced::OnControllerButtonClick(int player_idx, int button_idx) {
+void ConfigureInputAdvanced::OnControllerButtonClick(std::size_t player_idx,
+ std::size_t button_idx) {
const QColor new_bg_color = QColorDialog::getColor(controllers_colors[player_idx][button_idx]);
if (!new_bg_color.isValid()) {
return;
diff --git a/src/yuzu/configuration/configure_input_advanced.h b/src/yuzu/configuration/configure_input_advanced.h
index 50bb87768..3083d55c1 100644
--- a/src/yuzu/configuration/configure_input_advanced.h
+++ b/src/yuzu/configuration/configure_input_advanced.h
@@ -35,7 +35,7 @@ private:
void RetranslateUI();
void UpdateUIEnabled();
- void OnControllerButtonClick(int player_idx, int button_idx);
+ void OnControllerButtonClick(std::size_t player_idx, std::size_t button_idx);
void LoadConfiguration();
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 5abf9f0bf..0d10c1360 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -4,6 +4,7 @@
#include
#include
+#include
#include
#include
#include
@@ -857,7 +858,7 @@ void ConfigureInputPlayer::UpdateControllerIcon() {
}
}();
- const QString theme = [this] {
+ const QString theme = [] {
if (QIcon::themeName().contains(QStringLiteral("dark"))) {
return QStringLiteral("_dark");
} else if (QIcon::themeName().contains(QStringLiteral("midnight"))) {
diff --git a/src/yuzu/configuration/configure_input_profile_dialog.cpp b/src/yuzu/configuration/configure_input_profile_dialog.cpp
index 818399b47..1f5cfa75b 100644
--- a/src/yuzu/configuration/configure_input_profile_dialog.cpp
+++ b/src/yuzu/configuration/configure_input_profile_dialog.cpp
@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include "ui_configure_input_profile_dialog.h"
+#include "yuzu/configuration/configure_input_player.h"
#include "yuzu/configuration/configure_input_profile_dialog.h"
ConfigureInputProfileDialog::ConfigureInputProfileDialog(
diff --git a/src/yuzu/configuration/configure_input_profile_dialog.h b/src/yuzu/configuration/configure_input_profile_dialog.h
index d4a3973d9..e6386bdbb 100644
--- a/src/yuzu/configuration/configure_input_profile_dialog.h
+++ b/src/yuzu/configuration/configure_input_profile_dialog.h
@@ -6,10 +6,11 @@
#include
#include
-#include "yuzu/configuration/configure_input_player.h"
class QPushButton;
+class ConfigureInputPlayer;
+
class InputProfiles;
namespace InputCommon {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 76a5c32f4..9dabd8889 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -58,6 +58,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include
#include
#include
+#include
#include
#include
#include
--
cgit v1.2.3
From 6f5b9428971904ad8815a56d50c9aab4805a1c56 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Thu, 29 Oct 2020 12:15:35 -0400
Subject: configure_input: Update the input profiles for other player tabs
---
src/yuzu/configuration/configure_input.cpp | 16 ++++++++++++++--
src/yuzu/configuration/configure_input.h | 1 +
src/yuzu/configuration/configure_input_player.cpp | 20 ++++++++++++++------
src/yuzu/configuration/configure_input_player.h | 12 +++++++++---
4 files changed, 38 insertions(+), 11 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index 600cc03ae..d9009091b 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -124,8 +124,10 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem,
}
}
});
- connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputDevices,
- [this] { UpdateAllInputDevices(); });
+ connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputDevices, this,
+ &ConfigureInput::UpdateAllInputDevices);
+ connect(player_controllers[i], &ConfigureInputPlayer::RefreshInputProfiles, this,
+ &ConfigureInput::UpdateAllInputProfiles, Qt::QueuedConnection);
connect(player_connected[i], &QCheckBox::stateChanged, [this, i](int state) {
player_controllers[i]->ConnectPlayer(state == Qt::Checked);
});
@@ -259,3 +261,13 @@ void ConfigureInput::UpdateAllInputDevices() {
player->UpdateInputDeviceCombobox();
}
}
+
+void ConfigureInput::UpdateAllInputProfiles(std::size_t player_index) {
+ for (std::size_t i = 0; i < player_controllers.size(); ++i) {
+ if (i == player_index) {
+ continue;
+ }
+
+ player_controllers[i]->UpdateInputProfiles();
+ }
+}
diff --git a/src/yuzu/configuration/configure_input.h b/src/yuzu/configuration/configure_input.h
index 9eba9b523..f4eb0d78b 100644
--- a/src/yuzu/configuration/configure_input.h
+++ b/src/yuzu/configuration/configure_input.h
@@ -52,6 +52,7 @@ private:
void UpdateDockedState(bool is_handheld);
void UpdateAllInputDevices();
+ void UpdateAllInputProfiles(std::size_t player_index);
/// Load configuration settings.
void LoadConfiguration();
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 0d10c1360..f65a7fe73 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -541,7 +541,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
}
});
- RefreshInputProfiles();
+ UpdateInputProfiles();
connect(ui->buttonProfilesNew, &QPushButton::clicked, this,
&ConfigureInputPlayer::CreateProfile);
@@ -1132,10 +1132,13 @@ void ConfigureInputPlayer::CreateProfile() {
if (!profiles->CreateProfile(profile_name.toStdString(), player_index)) {
QMessageBox::critical(this, tr("Create Input Profile"),
tr("Failed to create the input profile \"%1\"").arg(profile_name));
- RefreshInputProfiles();
+ UpdateInputProfiles();
+ emit RefreshInputProfiles(player_index);
return;
}
+ emit RefreshInputProfiles(player_index);
+
ui->comboProfiles->addItem(profile_name);
ui->comboProfiles->setCurrentIndex(ui->comboProfiles->count() - 1);
}
@@ -1150,10 +1153,13 @@ void ConfigureInputPlayer::DeleteProfile() {
if (!profiles->DeleteProfile(profile_name.toStdString())) {
QMessageBox::critical(this, tr("Delete Input Profile"),
tr("Failed to delete the input profile \"%1\"").arg(profile_name));
- RefreshInputProfiles();
+ UpdateInputProfiles();
+ emit RefreshInputProfiles(player_index);
return;
}
+ emit RefreshInputProfiles(player_index);
+
ui->comboProfiles->removeItem(ui->comboProfiles->currentIndex());
ui->comboProfiles->setCurrentIndex(-1);
}
@@ -1170,7 +1176,8 @@ void ConfigureInputPlayer::LoadProfile() {
if (!profiles->LoadProfile(profile_name.toStdString(), player_index)) {
QMessageBox::critical(this, tr("Load Input Profile"),
tr("Failed to load the input profile \"%1\"").arg(profile_name));
- RefreshInputProfiles();
+ UpdateInputProfiles();
+ emit RefreshInputProfiles(player_index);
return;
}
@@ -1189,12 +1196,13 @@ void ConfigureInputPlayer::SaveProfile() {
if (!profiles->SaveProfile(profile_name.toStdString(), player_index)) {
QMessageBox::critical(this, tr("Save Input Profile"),
tr("Failed to save the input profile \"%1\"").arg(profile_name));
- RefreshInputProfiles();
+ UpdateInputProfiles();
+ emit RefreshInputProfiles(player_index);
return;
}
}
-void ConfigureInputPlayer::RefreshInputProfiles() {
+void ConfigureInputPlayer::UpdateInputProfiles() {
ui->comboProfiles->clear();
for (const auto& profile_name : profiles->GetInputProfileNames()) {
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index 4895e8850..23cf6f958 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -59,6 +59,9 @@ public:
/// Update the input devices combobox.
void UpdateInputDeviceCombobox();
+ /// Updates the list of controller profiles.
+ void UpdateInputProfiles();
+
/// Restore all buttons to their default values.
void RestoreDefaults();
@@ -72,6 +75,12 @@ signals:
void HandheldStateChanged(bool is_handheld);
/// Emitted when the input devices combobox is being refreshed.
void RefreshInputDevices();
+ /**
+ * Emitted when the input profiles combobox is being refreshed.
+ * The player_index represents the current player's index, and the profile combobox
+ * will not be updated for this index as they are already updated by other mechanisms.
+ */
+ void RefreshInputProfiles(std::size_t player_index);
protected:
void showEvent(QShowEvent* event) override;
@@ -130,9 +139,6 @@ private:
/// Saves the current controller configuration into a selected controller profile.
void SaveProfile();
- /// Refreshes the list of controller profiles.
- void RefreshInputProfiles();
-
std::unique_ptr ui;
std::size_t player_index;
--
cgit v1.2.3
From b254d528bcdd8d826c87ef720b2c247a08cc5049 Mon Sep 17 00:00:00 2001
From: Morph <39850852+Morph1984@users.noreply.github.com>
Date: Wed, 11 Nov 2020 07:46:41 -0500
Subject: configure_input: Accommodate for the mouse input device engine
---
src/yuzu/configuration/configure_input_player.cpp | 18 +++++++++++++++++-
src/yuzu/configuration/configure_vibration.cpp | 2 +-
2 files changed, 18 insertions(+), 2 deletions(-)
(limited to 'src/yuzu')
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index f65a7fe73..72640f5e7 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -694,6 +694,8 @@ void ConfigureInputPlayer::UpdateInputDeviceCombobox() {
const auto current_guid = button_param->Get("guid", "");
const auto current_port = button_param->Get("port", "");
+ const bool is_keyboard_mouse = current_engine == "keyboard" || current_engine == "mouse";
+
UpdateInputDevices();
if (buttons_empty) {
@@ -702,13 +704,22 @@ void ConfigureInputPlayer::UpdateInputDeviceCombobox() {
const bool all_one_device =
std::all_of(buttons_param.begin(), buttons_param.end(),
- [current_engine, current_guid, current_port](const Common::ParamPackage param) {
+ [current_engine, current_guid, current_port,
+ is_keyboard_mouse](const Common::ParamPackage param) {
+ if (is_keyboard_mouse) {
+ return !param.Has("engine") || param.Get("engine", "") == "keyboard" ||
+ param.Get("engine", "") == "mouse";
+ }
return !param.Has("engine") || (param.Get("engine", "") == current_engine &&
param.Get("guid", "") == current_guid &&
param.Get("port", "") == current_port);
});
if (all_one_device) {
+ if (is_keyboard_mouse) {
+ ui->comboDevices->setCurrentIndex(1);
+ return;
+ }
const auto devices_it = std::find_if(
input_devices.begin(), input_devices.end(),
[current_engine, current_guid, current_port](const Common::ParamPackage param) {
@@ -1073,6 +1084,11 @@ bool ConfigureInputPlayer::IsInputAcceptable(const Common::ParamPackage& params)
return true;
}
+ // Keyboard/Mouse
+ if (ui->comboDevices->currentIndex() == 1) {
+ return params.Get("engine", "") == "keyboard" || params.Get("engine", "") == "mouse";
+ }
+
const auto current_input_device = input_devices[ui->comboDevices->currentIndex()];
return params.Get("engine", "") == current_input_device.Get("class", "") &&
params.Get("guid", "") == current_input_device.Get("guid", "") &&
diff --git a/src/yuzu/configuration/configure_vibration.cpp b/src/yuzu/configuration/configure_vibration.cpp
index 714db5b80..7dcb2c5b9 100644
--- a/src/yuzu/configuration/configure_vibration.cpp
+++ b/src/yuzu/configuration/configure_vibration.cpp
@@ -99,7 +99,7 @@ void ConfigureVibration::SetVibrationDevices(std::size_t player_index) {
const auto guid = param.Get("guid", "");
const auto port = param.Get("port", "");
- if (engine.empty() || engine == "keyboard") {
+ if (engine.empty() || engine == "keyboard" || engine == "mouse") {
continue;
}
--
cgit v1.2.3