summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ameerj2022-11-17 19:23:48 -0500
committerGravatar ameerj2022-11-20 14:06:31 -0500
commit9efdad6a2733e701b24e9edcbad1851692ca8863 (patch)
treea0ba33591b59e59bcea565e3d5ec5b8b1846a687 /src
parentMerge pull request #9250 from v1993/patch-10 (diff)
downloadyuzu-9efdad6a2733e701b24e9edcbad1851692ca8863.tar.gz
yuzu-9efdad6a2733e701b24e9edcbad1851692ca8863.tar.xz
yuzu-9efdad6a2733e701b24e9edcbad1851692ca8863.zip
Configuration: Add per-game input profiles
Diffstat (limited to 'src')
-rw-r--r--src/common/settings_input.h1
-rw-r--r--src/core/hid/emulated_controller.cpp3
-rw-r--r--src/yuzu/CMakeLists.txt3
-rw-r--r--src/yuzu/configuration/config.cpp24
-rw-r--r--src/yuzu/configuration/configure_input_per_game.cpp76
-rw-r--r--src/yuzu/configuration/configure_input_per_game.h44
-rw-r--r--src/yuzu/configuration/configure_input_per_game.ui298
-rw-r--r--src/yuzu/configuration/configure_input_player.h2
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp5
-rw-r--r--src/yuzu/configuration/configure_per_game.h6
-rw-r--r--src/yuzu/main.cpp17
11 files changed, 465 insertions, 14 deletions
diff --git a/src/common/settings_input.h b/src/common/settings_input.h
index 485e4ad22..46f38c703 100644
--- a/src/common/settings_input.h
+++ b/src/common/settings_input.h
@@ -391,6 +391,7 @@ struct PlayerInput {
391 u32 body_color_right; 391 u32 body_color_right;
392 u32 button_color_left; 392 u32 button_color_left;
393 u32 button_color_right; 393 u32 button_color_right;
394 std::string profile_name;
394}; 395};
395 396
396struct TouchscreenInput { 397struct TouchscreenInput {
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index ec1364452..a2d106245 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -107,10 +107,9 @@ void EmulatedController::ReloadFromSettings() {
107 original_npad_type = npad_type; 107 original_npad_type = npad_type;
108 } 108 }
109 109
110 Disconnect();
110 if (player.connected) { 111 if (player.connected) {
111 Connect(); 112 Connect();
112 } else {
113 Disconnect();
114 } 113 }
115 114
116 ReloadInput(); 115 ReloadInput();
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 5cc1fbf32..8a252bd5d 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -85,6 +85,9 @@ add_executable(yuzu
85 configuration/configure_input_advanced.cpp 85 configuration/configure_input_advanced.cpp
86 configuration/configure_input_advanced.h 86 configuration/configure_input_advanced.h
87 configuration/configure_input_advanced.ui 87 configuration/configure_input_advanced.ui
88 configuration/configure_input_per_game.cpp
89 configuration/configure_input_per_game.h
90 configuration/configure_input_per_game.ui
88 configuration/configure_input_player.cpp 91 configuration/configure_input_player.cpp
89 configuration/configure_input_player.h 92 configuration/configure_input_player.h
90 configuration/configure_input_player.ui 93 configuration/configure_input_player.ui
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 343f3b8e5..4067ea607 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -186,7 +186,7 @@ void Config::WriteGlobalSetting(const Settings::SwitchableSetting<Type, ranged>&
186 186
187void Config::ReadPlayerValue(std::size_t player_index) { 187void Config::ReadPlayerValue(std::size_t player_index) {
188 const QString player_prefix = [this, player_index] { 188 const QString player_prefix = [this, player_index] {
189 if (type == ConfigType::InputProfile) { 189 if (type == ConfigType::InputProfile && global) {
190 return QString{}; 190 return QString{};
191 } else { 191 } else {
192 return QStringLiteral("player_%1_").arg(player_index); 192 return QStringLiteral("player_%1_").arg(player_index);
@@ -244,6 +244,14 @@ void Config::ReadPlayerValue(std::size_t player_index) {
244 ->value(QStringLiteral("%1button_color_right").arg(player_prefix), 244 ->value(QStringLiteral("%1button_color_right").arg(player_prefix),
245 Settings::JOYCON_BUTTONS_NEON_RED) 245 Settings::JOYCON_BUTTONS_NEON_RED)
246 .toUInt(); 246 .toUInt();
247
248 // This only applies to per-game configs
249 if (!global) {
250 player.profile_name =
251 qt_config->value(QStringLiteral("%1profile_name").arg(player_prefix), QString{})
252 .toString()
253 .toStdString();
254 }
247 } 255 }
248 256
249 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { 257 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
@@ -386,6 +394,7 @@ void Config::ReadAudioValues() {
386} 394}
387 395
388void Config::ReadControlValues() { 396void Config::ReadControlValues() {
397 Settings::values.players.SetGlobal(global);
389 qt_config->beginGroup(QStringLiteral("Controls")); 398 qt_config->beginGroup(QStringLiteral("Controls"));
390 399
391 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { 400 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
@@ -904,7 +913,6 @@ void Config::ReadMultiplayerValues() {
904 913
905void Config::ReadValues() { 914void Config::ReadValues() {
906 if (global) { 915 if (global) {
907 ReadControlValues();
908 ReadDataStorageValues(); 916 ReadDataStorageValues();
909 ReadDebuggingValues(); 917 ReadDebuggingValues();
910 ReadDisabledAddOnValues(); 918 ReadDisabledAddOnValues();
@@ -913,6 +921,7 @@ void Config::ReadValues() {
913 ReadWebServiceValues(); 921 ReadWebServiceValues();
914 ReadMiscellaneousValues(); 922 ReadMiscellaneousValues();
915 } 923 }
924 ReadControlValues();
916 ReadCoreValues(); 925 ReadCoreValues();
917 ReadCpuValues(); 926 ReadCpuValues();
918 ReadRendererValues(); 927 ReadRendererValues();
@@ -923,7 +932,7 @@ void Config::ReadValues() {
923 932
924void Config::SavePlayerValue(std::size_t player_index) { 933void Config::SavePlayerValue(std::size_t player_index) {
925 const QString player_prefix = [this, player_index] { 934 const QString player_prefix = [this, player_index] {
926 if (type == ConfigType::InputProfile) { 935 if (type == ConfigType::InputProfile && global) {
927 return QString{}; 936 return QString{};
928 } else { 937 } else {
929 return QStringLiteral("player_%1_").arg(player_index); 938 return QStringLiteral("player_%1_").arg(player_index);
@@ -951,6 +960,12 @@ void Config::SavePlayerValue(std::size_t player_index) {
951 player.button_color_left, Settings::JOYCON_BUTTONS_NEON_BLUE); 960 player.button_color_left, Settings::JOYCON_BUTTONS_NEON_BLUE);
952 WriteSetting(QStringLiteral("%1button_color_right").arg(player_prefix), 961 WriteSetting(QStringLiteral("%1button_color_right").arg(player_prefix),
953 player.button_color_right, Settings::JOYCON_BUTTONS_NEON_RED); 962 player.button_color_right, Settings::JOYCON_BUTTONS_NEON_RED);
963
964 // This only applies to per-game configs
965 if (!global) {
966 WriteSetting(QStringLiteral("%1profile_name").arg(player_prefix),
967 QString::fromStdString(player.profile_name), QString{});
968 }
954 } 969 }
955 970
956 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { 971 for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
@@ -1054,7 +1069,6 @@ void Config::SaveIrCameraValues() {
1054 1069
1055void Config::SaveValues() { 1070void Config::SaveValues() {
1056 if (global) { 1071 if (global) {
1057 SaveControlValues();
1058 SaveDataStorageValues(); 1072 SaveDataStorageValues();
1059 SaveDebuggingValues(); 1073 SaveDebuggingValues();
1060 SaveDisabledAddOnValues(); 1074 SaveDisabledAddOnValues();
@@ -1063,6 +1077,7 @@ void Config::SaveValues() {
1063 SaveWebServiceValues(); 1077 SaveWebServiceValues();
1064 SaveMiscellaneousValues(); 1078 SaveMiscellaneousValues();
1065 } 1079 }
1080 SaveControlValues();
1066 SaveCoreValues(); 1081 SaveCoreValues();
1067 SaveCpuValues(); 1082 SaveCpuValues();
1068 SaveRendererValues(); 1083 SaveRendererValues();
@@ -1085,6 +1100,7 @@ void Config::SaveAudioValues() {
1085} 1100}
1086 1101
1087void Config::SaveControlValues() { 1102void Config::SaveControlValues() {
1103 Settings::values.players.SetGlobal(global);
1088 qt_config->beginGroup(QStringLiteral("Controls")); 1104 qt_config->beginGroup(QStringLiteral("Controls"));
1089 1105
1090 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { 1106 for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
diff --git a/src/yuzu/configuration/configure_input_per_game.cpp b/src/yuzu/configuration/configure_input_per_game.cpp
new file mode 100644
index 000000000..5773c268d
--- /dev/null
+++ b/src/yuzu/configuration/configure_input_per_game.cpp
@@ -0,0 +1,76 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/settings.h"
5#include "core/core.h"
6#include "core/hid/emulated_controller.h"
7#include "core/hid/hid_core.h"
8#include "ui_configure_input_per_game.h"
9#include "yuzu/configuration/configure_input_per_game.h"
10#include "yuzu/configuration/input_profiles.h"
11
12ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, QWidget* parent)
13 : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPerGame>()),
14 profiles(std::make_unique<InputProfiles>()), system{system_} {
15 ui->setupUi(this);
16
17 Settings::values.players.SetGlobal(false);
18 const auto previous_profile = Settings::values.players.GetValue()[0].profile_name;
19
20 const auto& profile_names = profiles->GetInputProfileNames();
21
22 ui->profile_player_1->addItem(QString::fromStdString("Use global configuration"));
23 for (size_t index = 0; index < profile_names.size(); ++index) {
24 const auto& profile_name = profile_names[index];
25 ui->profile_player_1->addItem(QString::fromStdString(profile_name));
26 if (profile_name == previous_profile) {
27 // offset by 1 since the first element is the global config
28 ui->profile_player_1->setCurrentIndex(static_cast<int>(index + 1));
29 }
30 }
31 LoadConfiguration();
32}
33
34void ConfigureInputPerGame::ApplyConfiguration() {
35 LoadConfiguration();
36
37 auto& hid_core = system.HIDCore();
38 auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(0);
39
40 const auto selection_index = ui->profile_player_1->currentIndex();
41 if (selection_index == 0) {
42 Settings::values.players.SetGlobal(true);
43 emulated_controller->ReloadFromSettings();
44 return;
45 } else {
46 Settings::values.players.SetGlobal(false);
47 }
48 const QString profile_name = ui->profile_player_1->itemText(selection_index);
49 if (profile_name.isEmpty()) {
50 return;
51 }
52 profiles->SaveProfile(Settings::values.players.GetValue()[0].profile_name, 0);
53 emulated_controller->ReloadFromSettings();
54}
55
56void ConfigureInputPerGame::LoadConfiguration() {
57 auto& hid_core = system.HIDCore();
58 auto* emulated_controller = hid_core.GetEmulatedControllerByIndex(0);
59
60 Settings::values.players.SetGlobal(false);
61
62 const auto selection_index = ui->profile_player_1->currentIndex();
63 if (selection_index == 0) {
64 Settings::values.players.GetValue()[0].profile_name = "";
65 Settings::values.players.SetGlobal(true);
66 emulated_controller->ReloadFromSettings();
67 return;
68 }
69 const QString profile_name = ui->profile_player_1->itemText(selection_index);
70 if (profile_name.isEmpty()) {
71 return;
72 }
73 profiles->LoadProfile(profile_name.toStdString(), 0);
74 Settings::values.players.GetValue()[0].profile_name = profile_name.toStdString();
75 emulated_controller->ReloadFromSettings();
76}
diff --git a/src/yuzu/configuration/configure_input_per_game.h b/src/yuzu/configuration/configure_input_per_game.h
new file mode 100644
index 000000000..6feb608b7
--- /dev/null
+++ b/src/yuzu/configuration/configure_input_per_game.h
@@ -0,0 +1,44 @@
1// SPDX-FileCopyrightText: 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <memory>
7
8#include <QWidget>
9
10namespace Core {
11class System;
12}
13
14namespace InputCommon {
15class InputSubsystem;
16}
17
18namespace Ui {
19class ConfigureInputPerGame;
20}
21
22class InputProfiles;
23
24class ConfigureInputPerGame : public QWidget {
25 Q_OBJECT
26
27public:
28 explicit ConfigureInputPerGame(Core::System& system_, QWidget* parent = nullptr);
29
30 /// Initializes the input dialog with the given input subsystem.
31 // void Initialize(InputCommon::InputSubsystem* input_subsystem_, std::size_t max_players = 8);
32
33 /// Save configurations to settings file.
34 void ApplyConfiguration();
35
36private:
37 /// Load configuration from settings file.
38 void LoadConfiguration();
39
40 std::unique_ptr<Ui::ConfigureInputPerGame> ui;
41 std::unique_ptr<InputProfiles> profiles;
42
43 Core::System& system;
44};
diff --git a/src/yuzu/configuration/configure_input_per_game.ui b/src/yuzu/configuration/configure_input_per_game.ui
new file mode 100644
index 000000000..8a384c0df
--- /dev/null
+++ b/src/yuzu/configuration/configure_input_per_game.ui
@@ -0,0 +1,298 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigureInputPerGame</class>
4 <widget class="QWidget" name="PerGameInput">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>541</width>
10 <height>759</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <property name="accessibleName">
17 <string>Graphics</string>
18 </property>
19 <layout class="QVBoxLayout" name="verticalLayout_1">
20 <item>
21 <layout class="QVBoxLayout" name="verticalLayout_2">
22 <property name="spacing">
23 <number>0</number>
24 </property>
25 <item>
26 <widget class="QGroupBox" name="groupBox">
27 <property name="title">
28 <string>Input Profiles</string>
29 </property>
30 <layout class="QVBoxLayout" name="verticalLayout_4">
31 <item>
32 <widget class="QWidget" name="player_1" native="true">
33 <layout class="QHBoxLayout" name="input_profile_layout">
34 <property name="leftMargin">
35 <number>0</number>
36 </property>
37 <property name="topMargin">
38 <number>0</number>
39 </property>
40 <property name="rightMargin">
41 <number>0</number>
42 </property>
43 <property name="bottomMargin">
44 <number>0</number>
45 </property>
46 <item>
47 <widget class="QLabel" name="label_player_1">
48 <property name="text">
49 <string>Player 1 Profile</string>
50 </property>
51 </widget>
52 </item>
53 <item>
54 <widget class="QComboBox" name="profile_player_1">
55 <property name="sizePolicy">
56 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
57 <horstretch>0</horstretch>
58 <verstretch>0</verstretch>
59 </sizepolicy>
60 </property>
61 </widget>
62 </item>
63 </layout>
64 </widget>
65 </item>
66 <item>
67 <widget class="QWidget" name="player_3" native="true">
68 <layout class="QHBoxLayout" name="input_profile_layout">
69 <property name="leftMargin">
70 <number>0</number>
71 </property>
72 <property name="topMargin">
73 <number>0</number>
74 </property>
75 <property name="rightMargin">
76 <number>0</number>
77 </property>
78 <property name="bottomMargin">
79 <number>0</number>
80 </property>
81 <item>
82 <widget class="QLabel" name="label_player_3">
83 <property name="text">
84 <string>Player 3 Profile</string>
85 </property>
86 </widget>
87 </item>
88 <item>
89 <widget class="QComboBox" name="profile_player_3">
90 <property name="sizePolicy">
91 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
92 <horstretch>0</horstretch>
93 <verstretch>0</verstretch>
94 </sizepolicy>
95 </property>
96 </widget>
97 </item>
98 </layout>
99 </widget>
100 </item>
101 <item>
102 <widget class="QWidget" name="player_4" native="true">
103 <layout class="QHBoxLayout" name="input_profile_layout">
104 <property name="leftMargin">
105 <number>0</number>
106 </property>
107 <property name="topMargin">
108 <number>0</number>
109 </property>
110 <property name="rightMargin">
111 <number>0</number>
112 </property>
113 <property name="bottomMargin">
114 <number>0</number>
115 </property>
116 <item>
117 <widget class="QLabel" name="label_player_4">
118 <property name="text">
119 <string>Player 4 Profile</string>
120 </property>
121 </widget>
122 </item>
123 <item>
124 <widget class="QComboBox" name="profile_player_4">
125 <property name="sizePolicy">
126 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
127 <horstretch>0</horstretch>
128 <verstretch>0</verstretch>
129 </sizepolicy>
130 </property>
131 </widget>
132 </item>
133 </layout>
134 </widget>
135 </item>
136 <item>
137 <widget class="QWidget" name="player_5" native="true">
138 <layout class="QHBoxLayout" name="input_profile_layout">
139 <property name="leftMargin">
140 <number>0</number>
141 </property>
142 <property name="topMargin">
143 <number>0</number>
144 </property>
145 <property name="rightMargin">
146 <number>0</number>
147 </property>
148 <property name="bottomMargin">
149 <number>0</number>
150 </property>
151 <item>
152 <widget class="QLabel" name="label_player_5">
153 <property name="text">
154 <string>Player 5 Profile</string>
155 </property>
156 </widget>
157 </item>
158 <item>
159 <widget class="QComboBox" name="profile_player_5">
160 <property name="sizePolicy">
161 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
162 <horstretch>0</horstretch>
163 <verstretch>0</verstretch>
164 </sizepolicy>
165 </property>
166 </widget>
167 </item>
168 </layout>
169 </widget>
170 </item>
171 <item>
172 <widget class="QWidget" name="player_6" native="true">
173 <layout class="QHBoxLayout" name="input_profile_layout">
174 <property name="leftMargin">
175 <number>0</number>
176 </property>
177 <property name="topMargin">
178 <number>0</number>
179 </property>
180 <property name="rightMargin">
181 <number>0</number>
182 </property>
183 <property name="bottomMargin">
184 <number>0</number>
185 </property>
186 <item>
187 <widget class="QLabel" name="label_player_6">
188 <property name="text">
189 <string>Player 6 Profile</string>
190 </property>
191 </widget>
192 </item>
193 <item>
194 <widget class="QComboBox" name="profile_player_6">
195 <property name="sizePolicy">
196 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
197 <horstretch>0</horstretch>
198 <verstretch>0</verstretch>
199 </sizepolicy>
200 </property>
201 </widget>
202 </item>
203 </layout>
204 </widget>
205 </item>
206 <item>
207 <widget class="QWidget" name="player_7" native="true">
208 <layout class="QHBoxLayout" name="input_profile_layout">
209 <property name="leftMargin">
210 <number>0</number>
211 </property>
212 <property name="topMargin">
213 <number>0</number>
214 </property>
215 <property name="rightMargin">
216 <number>0</number>
217 </property>
218 <property name="bottomMargin">
219 <number>0</number>
220 </property>
221 <item>
222 <widget class="QLabel" name="label_player_7">
223 <property name="text">
224 <string>Player 7 Profile</string>
225 </property>
226 </widget>
227 </item>
228 <item>
229 <widget class="QComboBox" name="profile_player_7">
230 <property name="sizePolicy">
231 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
232 <horstretch>0</horstretch>
233 <verstretch>0</verstretch>
234 </sizepolicy>
235 </property>
236 </widget>
237 </item>
238 </layout>
239 </widget>
240 </item>
241 <item>
242 <widget class="QWidget" name="player_8" native="true">
243 <layout class="QHBoxLayout" name="input_profile_layout">
244 <property name="leftMargin">
245 <number>0</number>
246 </property>
247 <property name="topMargin">
248 <number>0</number>
249 </property>
250 <property name="rightMargin">
251 <number>0</number>
252 </property>
253 <property name="bottomMargin">
254 <number>0</number>
255 </property>
256 <item>
257 <widget class="QLabel" name="label_player_8">
258 <property name="text">
259 <string>Player 8 Profile</string>
260 </property>
261 </widget>
262 </item>
263 <item>
264 <widget class="QComboBox" name="profile_player_8">
265 <property name="sizePolicy">
266 <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
267 <horstretch>0</horstretch>
268 <verstretch>0</verstretch>
269 </sizepolicy>
270 </property>
271 </widget>
272 </item>
273 </layout>
274 </widget>
275 </item>
276 </layout>
277 </widget>
278 </item>
279 </layout>
280 </item>
281 <item>
282 <spacer name="verticalSpacer">
283 <property name="orientation">
284 <enum>Qt::Vertical</enum>
285 </property>
286 <property name="sizeHint" stdset="0">
287 <size>
288 <width>20</width>
289 <height>40</height>
290 </size>
291 </property>
292 </spacer>
293 </item>
294 </layout>
295 </widget>
296 <resources/>
297 <connections/>
298</ui>
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index 79434fdd8..26f60d121 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -38,7 +38,7 @@ enum class InputType;
38 38
39namespace Ui { 39namespace Ui {
40class ConfigureInputPlayer; 40class ConfigureInputPlayer;
41} 41} // namespace Ui
42 42
43namespace Core::HID { 43namespace Core::HID {
44class HIDCore; 44class HIDCore;
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index c3cb8f61d..cf0a6dc0e 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -28,7 +28,7 @@
28#include "yuzu/configuration/configure_general.h" 28#include "yuzu/configuration/configure_general.h"
29#include "yuzu/configuration/configure_graphics.h" 29#include "yuzu/configuration/configure_graphics.h"
30#include "yuzu/configuration/configure_graphics_advanced.h" 30#include "yuzu/configuration/configure_graphics_advanced.h"
31#include "yuzu/configuration/configure_input.h" 31#include "yuzu/configuration/configure_input_per_game.h"
32#include "yuzu/configuration/configure_per_game.h" 32#include "yuzu/configuration/configure_per_game.h"
33#include "yuzu/configuration/configure_per_game_addons.h" 33#include "yuzu/configuration/configure_per_game_addons.h"
34#include "yuzu/configuration/configure_system.h" 34#include "yuzu/configuration/configure_system.h"
@@ -50,6 +50,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
50 general_tab = std::make_unique<ConfigureGeneral>(system_, this); 50 general_tab = std::make_unique<ConfigureGeneral>(system_, this);
51 graphics_tab = std::make_unique<ConfigureGraphics>(system_, this); 51 graphics_tab = std::make_unique<ConfigureGraphics>(system_, this);
52 graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this); 52 graphics_advanced_tab = std::make_unique<ConfigureGraphicsAdvanced>(system_, this);
53 input_tab = std::make_unique<ConfigureInputPerGame>(system_, this);
53 system_tab = std::make_unique<ConfigureSystem>(system_, this); 54 system_tab = std::make_unique<ConfigureSystem>(system_, this);
54 55
55 ui->setupUi(this); 56 ui->setupUi(this);
@@ -61,6 +62,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
61 ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); 62 ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
62 ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics")); 63 ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics"));
63 ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); 64 ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
65 ui->tabWidget->addTab(input_tab.get(), tr("Input Profiles"));
64 66
65 setFocusPolicy(Qt::ClickFocus); 67 setFocusPolicy(Qt::ClickFocus);
66 setWindowTitle(tr("Properties")); 68 setWindowTitle(tr("Properties"));
@@ -91,6 +93,7 @@ void ConfigurePerGame::ApplyConfiguration() {
91 graphics_tab->ApplyConfiguration(); 93 graphics_tab->ApplyConfiguration();
92 graphics_advanced_tab->ApplyConfiguration(); 94 graphics_advanced_tab->ApplyConfiguration();
93 audio_tab->ApplyConfiguration(); 95 audio_tab->ApplyConfiguration();
96 input_tab->ApplyConfiguration();
94 97
95 system.ApplySettings(); 98 system.ApplySettings();
96 Settings::LogSettings(); 99 Settings::LogSettings();
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h
index 17a98a0f3..4ecc43541 100644
--- a/src/yuzu/configuration/configure_per_game.h
+++ b/src/yuzu/configuration/configure_per_game.h
@@ -16,12 +16,17 @@ namespace Core {
16class System; 16class System;
17} 17}
18 18
19namespace InputCommon {
20class InputSubsystem;
21}
22
19class ConfigurePerGameAddons; 23class ConfigurePerGameAddons;
20class ConfigureAudio; 24class ConfigureAudio;
21class ConfigureCpu; 25class ConfigureCpu;
22class ConfigureGeneral; 26class ConfigureGeneral;
23class ConfigureGraphics; 27class ConfigureGraphics;
24class ConfigureGraphicsAdvanced; 28class ConfigureGraphicsAdvanced;
29class ConfigureInputPerGame;
25class ConfigureSystem; 30class ConfigureSystem;
26 31
27class QGraphicsScene; 32class QGraphicsScene;
@@ -72,5 +77,6 @@ private:
72 std::unique_ptr<ConfigureGeneral> general_tab; 77 std::unique_ptr<ConfigureGeneral> general_tab;
73 std::unique_ptr<ConfigureGraphics> graphics_tab; 78 std::unique_ptr<ConfigureGraphics> graphics_tab;
74 std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab; 79 std::unique_ptr<ConfigureGraphicsAdvanced> graphics_advanced_tab;
80 std::unique_ptr<ConfigureInputPerGame> input_tab;
75 std::unique_ptr<ConfigureSystem> system_tab; 81 std::unique_ptr<ConfigureSystem> system_tab;
76}; 82};
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 72498f52a..e0c353788 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -124,6 +124,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
124#include "yuzu/compatibility_list.h" 124#include "yuzu/compatibility_list.h"
125#include "yuzu/configuration/config.h" 125#include "yuzu/configuration/config.h"
126#include "yuzu/configuration/configure_dialog.h" 126#include "yuzu/configuration/configure_dialog.h"
127#include "yuzu/configuration/configure_input_per_game.h"
127#include "yuzu/debugger/console.h" 128#include "yuzu/debugger/console.h"
128#include "yuzu/debugger/controller.h" 129#include "yuzu/debugger/controller.h"
129#include "yuzu/debugger/profiler.h" 130#include "yuzu/debugger/profiler.h"
@@ -1647,6 +1648,11 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1647 LOG_INFO(Frontend, "yuzu starting..."); 1648 LOG_INFO(Frontend, "yuzu starting...");
1648 StoreRecentFile(filename); // Put the filename on top of the list 1649 StoreRecentFile(filename); // Put the filename on top of the list
1649 1650
1651 // Save configurations
1652 UpdateUISettings();
1653 game_list->SaveInterfaceLayout();
1654 config->Save();
1655
1650 u64 title_id{0}; 1656 u64 title_id{0};
1651 1657
1652 last_filename_booted = filename; 1658 last_filename_booted = filename;
@@ -1666,11 +1672,6 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
1666 system->ApplySettings(); 1672 system->ApplySettings();
1667 } 1673 }
1668 1674
1669 // Save configurations
1670 UpdateUISettings();
1671 game_list->SaveInterfaceLayout();
1672 config->Save();
1673
1674 Settings::LogSettings(); 1675 Settings::LogSettings();
1675 1676
1676 if (UISettings::values.select_user_on_boot) { 1677 if (UISettings::values.select_user_on_boot) {
@@ -2790,6 +2791,7 @@ void GMainWindow::OnStopGame() {
2790 ShutdownGame(); 2791 ShutdownGame();
2791 2792
2792 Settings::RestoreGlobalState(system->IsPoweredOn()); 2793 Settings::RestoreGlobalState(system->IsPoweredOn());
2794 system->HIDCore().ReloadInputDevices();
2793 UpdateStatusButtons(); 2795 UpdateStatusButtons();
2794} 2796}
2795 2797
@@ -3250,6 +3252,7 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
3250 // Do not cause the global config to write local settings into the config file 3252 // Do not cause the global config to write local settings into the config file
3251 const bool is_powered_on = system->IsPoweredOn(); 3253 const bool is_powered_on = system->IsPoweredOn();
3252 Settings::RestoreGlobalState(is_powered_on); 3254 Settings::RestoreGlobalState(is_powered_on);
3255 system->HIDCore().ReloadInputDevices();
3253 3256
3254 UISettings::values.configuration_applied = false; 3257 UISettings::values.configuration_applied = false;
3255 3258
@@ -3709,6 +3712,7 @@ void GMainWindow::OnCoreError(Core::SystemResultStatus result, std::string detai
3709 ShutdownGame(); 3712 ShutdownGame();
3710 3713
3711 Settings::RestoreGlobalState(system->IsPoweredOn()); 3714 Settings::RestoreGlobalState(system->IsPoweredOn());
3715 system->HIDCore().ReloadInputDevices();
3712 UpdateStatusButtons(); 3716 UpdateStatusButtons();
3713 } 3717 }
3714 } else { 3718 } else {
@@ -3860,18 +3864,19 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
3860 // Unload controllers early 3864 // Unload controllers early
3861 controller_dialog->UnloadController(); 3865 controller_dialog->UnloadController();
3862 game_list->UnloadController(); 3866 game_list->UnloadController();
3863 system->HIDCore().UnloadInputDevices();
3864 3867
3865 // Shutdown session if the emu thread is active... 3868 // Shutdown session if the emu thread is active...
3866 if (emu_thread != nullptr) { 3869 if (emu_thread != nullptr) {
3867 ShutdownGame(); 3870 ShutdownGame();
3868 3871
3869 Settings::RestoreGlobalState(system->IsPoweredOn()); 3872 Settings::RestoreGlobalState(system->IsPoweredOn());
3873 system->HIDCore().ReloadInputDevices();
3870 UpdateStatusButtons(); 3874 UpdateStatusButtons();
3871 } 3875 }
3872 3876
3873 render_window->close(); 3877 render_window->close();
3874 multiplayer_state->Close(); 3878 multiplayer_state->Close();
3879 system->HIDCore().UnloadInputDevices();
3875 system->GetRoomNetwork().Shutdown(); 3880 system->GetRoomNetwork().Shutdown();
3876 3881
3877 QWidget::closeEvent(event); 3882 QWidget::closeEvent(event);