summaryrefslogtreecommitdiff
path: root/src/input_common
diff options
context:
space:
mode:
Diffstat (limited to 'src/input_common')
-rw-r--r--src/input_common/CMakeLists.txt2
-rw-r--r--src/input_common/drivers/camera.cpp2
-rw-r--r--src/input_common/drivers/camera.h5
-rw-r--r--src/input_common/drivers/sdl_driver.cpp2
-rw-r--r--src/input_common/drivers/virtual_gamepad.cpp78
-rw-r--r--src/input_common/drivers/virtual_gamepad.h73
-rw-r--r--src/input_common/input_mapping.cpp6
-rw-r--r--src/input_common/main.cpp286
-rw-r--r--src/input_common/main.h7
9 files changed, 263 insertions, 198 deletions
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 7932aaab0..f24c89b04 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -20,6 +20,8 @@ add_library(input_common STATIC
20 drivers/udp_client.h 20 drivers/udp_client.h
21 drivers/virtual_amiibo.cpp 21 drivers/virtual_amiibo.cpp
22 drivers/virtual_amiibo.h 22 drivers/virtual_amiibo.h
23 drivers/virtual_gamepad.cpp
24 drivers/virtual_gamepad.h
23 helpers/stick_from_buttons.cpp 25 helpers/stick_from_buttons.cpp
24 helpers/stick_from_buttons.h 26 helpers/stick_from_buttons.h
25 helpers/touch_from_buttons.cpp 27 helpers/touch_from_buttons.cpp
diff --git a/src/input_common/drivers/camera.cpp b/src/input_common/drivers/camera.cpp
index dceea67e0..fad9177dc 100644
--- a/src/input_common/drivers/camera.cpp
+++ b/src/input_common/drivers/camera.cpp
@@ -17,7 +17,7 @@ Camera::Camera(std::string input_engine_) : InputEngine(std::move(input_engine_)
17 PreSetController(identifier); 17 PreSetController(identifier);
18} 18}
19 19
20void Camera::SetCameraData(std::size_t width, std::size_t height, std::vector<u32> data) { 20void Camera::SetCameraData(std::size_t width, std::size_t height, std::span<const u32> data) {
21 const std::size_t desired_width = getImageWidth(); 21 const std::size_t desired_width = getImageWidth();
22 const std::size_t desired_height = getImageHeight(); 22 const std::size_t desired_height = getImageHeight();
23 status.data.resize(desired_width * desired_height); 23 status.data.resize(desired_width * desired_height);
diff --git a/src/input_common/drivers/camera.h b/src/input_common/drivers/camera.h
index b8a7c75e5..ead3e0fde 100644
--- a/src/input_common/drivers/camera.h
+++ b/src/input_common/drivers/camera.h
@@ -3,6 +3,8 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <span>
7
6#include "input_common/input_engine.h" 8#include "input_common/input_engine.h"
7 9
8namespace InputCommon { 10namespace InputCommon {
@@ -15,7 +17,7 @@ class Camera final : public InputEngine {
15public: 17public:
16 explicit Camera(std::string input_engine_); 18 explicit Camera(std::string input_engine_);
17 19
18 void SetCameraData(std::size_t width, std::size_t height, std::vector<u32> data); 20 void SetCameraData(std::size_t width, std::size_t height, std::span<const u32> data);
19 21
20 std::size_t getImageWidth() const; 22 std::size_t getImageWidth() const;
21 std::size_t getImageHeight() const; 23 std::size_t getImageHeight() const;
@@ -23,6 +25,7 @@ public:
23 Common::Input::CameraError SetCameraFormat(const PadIdentifier& identifier_, 25 Common::Input::CameraError SetCameraFormat(const PadIdentifier& identifier_,
24 Common::Input::CameraFormat camera_format) override; 26 Common::Input::CameraFormat camera_format) override;
25 27
28private:
26 Common::Input::CameraStatus status{}; 29 Common::Input::CameraStatus status{};
27}; 30};
28 31
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp
index 8de86b61e..4818bb744 100644
--- a/src/input_common/drivers/sdl_driver.cpp
+++ b/src/input_common/drivers/sdl_driver.cpp
@@ -16,6 +16,8 @@ Common::UUID GetGUID(SDL_Joystick* joystick) {
16 const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick); 16 const SDL_JoystickGUID guid = SDL_JoystickGetGUID(joystick);
17 std::array<u8, 16> data{}; 17 std::array<u8, 16> data{};
18 std::memcpy(data.data(), guid.data, sizeof(data)); 18 std::memcpy(data.data(), guid.data, sizeof(data));
19 // Clear controller name crc
20 std::memset(data.data() + 2, 0, sizeof(u16));
19 return Common::UUID{data}; 21 return Common::UUID{data};
20} 22}
21} // Anonymous namespace 23} // Anonymous namespace
diff --git a/src/input_common/drivers/virtual_gamepad.cpp b/src/input_common/drivers/virtual_gamepad.cpp
new file mode 100644
index 000000000..7db945aa6
--- /dev/null
+++ b/src/input_common/drivers/virtual_gamepad.cpp
@@ -0,0 +1,78 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "input_common/drivers/virtual_gamepad.h"
5
6namespace InputCommon {
7constexpr std::size_t PlayerIndexCount = 10;
8
9VirtualGamepad::VirtualGamepad(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
10 for (std::size_t i = 0; i < PlayerIndexCount; i++) {
11 PreSetController(GetIdentifier(i));
12 }
13}
14
15void VirtualGamepad::SetButtonState(std::size_t player_index, int button_id, bool value) {
16 if (player_index > PlayerIndexCount) {
17 return;
18 }
19 const auto identifier = GetIdentifier(player_index);
20 SetButton(identifier, button_id, value);
21}
22
23void VirtualGamepad::SetButtonState(std::size_t player_index, VirtualButton button_id, bool value) {
24 SetButtonState(player_index, static_cast<int>(button_id), value);
25}
26
27void VirtualGamepad::SetStickPosition(std::size_t player_index, int axis_id, float x_value,
28 float y_value) {
29 if (player_index > PlayerIndexCount) {
30 return;
31 }
32 const auto identifier = GetIdentifier(player_index);
33 SetAxis(identifier, axis_id * 2, x_value);
34 SetAxis(identifier, (axis_id * 2) + 1, y_value);
35}
36
37void VirtualGamepad::SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value,
38 float y_value) {
39 SetStickPosition(player_index, static_cast<int>(axis_id), x_value, y_value);
40}
41
42void VirtualGamepad::ResetControllers() {
43 for (std::size_t i = 0; i < PlayerIndexCount; i++) {
44 SetStickPosition(i, VirtualStick::Left, 0.0f, 0.0f);
45 SetStickPosition(i, VirtualStick::Right, 0.0f, 0.0f);
46
47 SetButtonState(i, VirtualButton::ButtonA, false);
48 SetButtonState(i, VirtualButton::ButtonB, false);
49 SetButtonState(i, VirtualButton::ButtonX, false);
50 SetButtonState(i, VirtualButton::ButtonY, false);
51 SetButtonState(i, VirtualButton::StickL, false);
52 SetButtonState(i, VirtualButton::StickR, false);
53 SetButtonState(i, VirtualButton::TriggerL, false);
54 SetButtonState(i, VirtualButton::TriggerR, false);
55 SetButtonState(i, VirtualButton::TriggerZL, false);
56 SetButtonState(i, VirtualButton::TriggerZR, false);
57 SetButtonState(i, VirtualButton::ButtonPlus, false);
58 SetButtonState(i, VirtualButton::ButtonMinus, false);
59 SetButtonState(i, VirtualButton::ButtonLeft, false);
60 SetButtonState(i, VirtualButton::ButtonUp, false);
61 SetButtonState(i, VirtualButton::ButtonRight, false);
62 SetButtonState(i, VirtualButton::ButtonDown, false);
63 SetButtonState(i, VirtualButton::ButtonSL, false);
64 SetButtonState(i, VirtualButton::ButtonSR, false);
65 SetButtonState(i, VirtualButton::ButtonHome, false);
66 SetButtonState(i, VirtualButton::ButtonCapture, false);
67 }
68}
69
70PadIdentifier VirtualGamepad::GetIdentifier(std::size_t player_index) const {
71 return {
72 .guid = Common::UUID{},
73 .port = player_index,
74 .pad = 0,
75 };
76}
77
78} // namespace InputCommon
diff --git a/src/input_common/drivers/virtual_gamepad.h b/src/input_common/drivers/virtual_gamepad.h
new file mode 100644
index 000000000..3df91cc6f
--- /dev/null
+++ b/src/input_common/drivers/virtual_gamepad.h
@@ -0,0 +1,73 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "input_common/input_engine.h"
7
8namespace InputCommon {
9
10/**
11 * A virtual controller that is always assigned to the game input
12 */
13class VirtualGamepad final : public InputEngine {
14public:
15 enum class VirtualButton {
16 ButtonA,
17 ButtonB,
18 ButtonX,
19 ButtonY,
20 StickL,
21 StickR,
22 TriggerL,
23 TriggerR,
24 TriggerZL,
25 TriggerZR,
26 ButtonPlus,
27 ButtonMinus,
28 ButtonLeft,
29 ButtonUp,
30 ButtonRight,
31 ButtonDown,
32 ButtonSL,
33 ButtonSR,
34 ButtonHome,
35 ButtonCapture,
36 };
37
38 enum class VirtualStick {
39 Left = 0,
40 Right = 1,
41 };
42
43 explicit VirtualGamepad(std::string input_engine_);
44
45 /**
46 * Sets the status of all buttons bound with the key to pressed
47 * @param player_index the player number that will take this action
48 * @param button_id the id of the button
49 * @param value indicates if the button is pressed or not
50 */
51 void SetButtonState(std::size_t player_index, int button_id, bool value);
52 void SetButtonState(std::size_t player_index, VirtualButton button_id, bool value);
53
54 /**
55 * Sets the status of all buttons bound with the key to released
56 * @param player_index the player number that will take this action
57 * @param axis_id the id of the axis to move
58 * @param x_value the position of the stick in the x axis
59 * @param y_value the position of the stick in the y axis
60 */
61 void SetStickPosition(std::size_t player_index, int axis_id, float x_value, float y_value);
62 void SetStickPosition(std::size_t player_index, VirtualStick axis_id, float x_value,
63 float y_value);
64
65 /// Restores all inputs into the neutral position
66 void ResetControllers();
67
68private:
69 /// Returns the correct identifier corresponding to the player index
70 PadIdentifier GetIdentifier(std::size_t player_index) const;
71};
72
73} // namespace InputCommon
diff --git a/src/input_common/input_mapping.cpp b/src/input_common/input_mapping.cpp
index 0fa4b1ddb..edd5287c1 100644
--- a/src/input_common/input_mapping.cpp
+++ b/src/input_common/input_mapping.cpp
@@ -200,12 +200,6 @@ bool MappingFactory::IsDriverValid(const MappingData& data) const {
200 return false; 200 return false;
201 } 201 }
202 // The following drivers don't need to be mapped 202 // The following drivers don't need to be mapped
203 if (data.engine == "tas") {
204 return false;
205 }
206 if (data.engine == "touch") {
207 return false;
208 }
209 if (data.engine == "touch_from_button") { 203 if (data.engine == "touch_from_button") {
210 return false; 204 return false;
211 } 205 }
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index 942a13535..86deb4c7c 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -12,6 +12,7 @@
12#include "input_common/drivers/touch_screen.h" 12#include "input_common/drivers/touch_screen.h"
13#include "input_common/drivers/udp_client.h" 13#include "input_common/drivers/udp_client.h"
14#include "input_common/drivers/virtual_amiibo.h" 14#include "input_common/drivers/virtual_amiibo.h"
15#include "input_common/drivers/virtual_gamepad.h"
15#include "input_common/helpers/stick_from_buttons.h" 16#include "input_common/helpers/stick_from_buttons.h"
16#include "input_common/helpers/touch_from_buttons.h" 17#include "input_common/helpers/touch_from_buttons.h"
17#include "input_common/input_engine.h" 18#include "input_common/input_engine.h"
@@ -25,73 +26,33 @@
25namespace InputCommon { 26namespace InputCommon {
26 27
27struct InputSubsystem::Impl { 28struct InputSubsystem::Impl {
28 void Initialize() { 29 template <typename Engine>
29 mapping_factory = std::make_shared<MappingFactory>(); 30 void RegisterEngine(std::string name, std::shared_ptr<Engine>& engine) {
30 MappingCallback mapping_callback{[this](const MappingData& data) { RegisterInput(data); }}; 31 MappingCallback mapping_callback{[this](const MappingData& data) { RegisterInput(data); }};
31 32
32 keyboard = std::make_shared<Keyboard>("keyboard"); 33 engine = std::make_shared<Engine>(name);
33 keyboard->SetMappingCallback(mapping_callback); 34 engine->SetMappingCallback(mapping_callback);
34 keyboard_factory = std::make_shared<InputFactory>(keyboard); 35
35 keyboard_output_factory = std::make_shared<OutputFactory>(keyboard); 36 std::shared_ptr<InputFactory> input_factory = std::make_shared<InputFactory>(engine);
36 Common::Input::RegisterInputFactory(keyboard->GetEngineName(), keyboard_factory); 37 std::shared_ptr<OutputFactory> output_factory = std::make_shared<OutputFactory>(engine);
37 Common::Input::RegisterOutputFactory(keyboard->GetEngineName(), keyboard_output_factory); 38 Common::Input::RegisterInputFactory(engine->GetEngineName(), std::move(input_factory));
38 39 Common::Input::RegisterOutputFactory(engine->GetEngineName(), std::move(output_factory));
39 mouse = std::make_shared<Mouse>("mouse"); 40 }
40 mouse->SetMappingCallback(mapping_callback); 41
41 mouse_factory = std::make_shared<InputFactory>(mouse); 42 void Initialize() {
42 mouse_output_factory = std::make_shared<OutputFactory>(mouse); 43 mapping_factory = std::make_shared<MappingFactory>();
43 Common::Input::RegisterInputFactory(mouse->GetEngineName(), mouse_factory);
44 Common::Input::RegisterOutputFactory(mouse->GetEngineName(), mouse_output_factory);
45
46 touch_screen = std::make_shared<TouchScreen>("touch");
47 touch_screen_factory = std::make_shared<InputFactory>(touch_screen);
48 Common::Input::RegisterInputFactory(touch_screen->GetEngineName(), touch_screen_factory);
49
50 gcadapter = std::make_shared<GCAdapter>("gcpad");
51 gcadapter->SetMappingCallback(mapping_callback);
52 gcadapter_input_factory = std::make_shared<InputFactory>(gcadapter);
53 gcadapter_output_factory = std::make_shared<OutputFactory>(gcadapter);
54 Common::Input::RegisterInputFactory(gcadapter->GetEngineName(), gcadapter_input_factory);
55 Common::Input::RegisterOutputFactory(gcadapter->GetEngineName(), gcadapter_output_factory);
56
57 udp_client = std::make_shared<CemuhookUDP::UDPClient>("cemuhookudp");
58 udp_client->SetMappingCallback(mapping_callback);
59 udp_client_input_factory = std::make_shared<InputFactory>(udp_client);
60 udp_client_output_factory = std::make_shared<OutputFactory>(udp_client);
61 Common::Input::RegisterInputFactory(udp_client->GetEngineName(), udp_client_input_factory);
62 Common::Input::RegisterOutputFactory(udp_client->GetEngineName(),
63 udp_client_output_factory);
64
65 tas_input = std::make_shared<TasInput::Tas>("tas");
66 tas_input->SetMappingCallback(mapping_callback);
67 tas_input_factory = std::make_shared<InputFactory>(tas_input);
68 tas_output_factory = std::make_shared<OutputFactory>(tas_input);
69 Common::Input::RegisterInputFactory(tas_input->GetEngineName(), tas_input_factory);
70 Common::Input::RegisterOutputFactory(tas_input->GetEngineName(), tas_output_factory);
71
72 camera = std::make_shared<Camera>("camera");
73 camera->SetMappingCallback(mapping_callback);
74 camera_input_factory = std::make_shared<InputFactory>(camera);
75 camera_output_factory = std::make_shared<OutputFactory>(camera);
76 Common::Input::RegisterInputFactory(camera->GetEngineName(), camera_input_factory);
77 Common::Input::RegisterOutputFactory(camera->GetEngineName(), camera_output_factory);
78
79 virtual_amiibo = std::make_shared<VirtualAmiibo>("virtual_amiibo");
80 virtual_amiibo->SetMappingCallback(mapping_callback);
81 virtual_amiibo_input_factory = std::make_shared<InputFactory>(virtual_amiibo);
82 virtual_amiibo_output_factory = std::make_shared<OutputFactory>(virtual_amiibo);
83 Common::Input::RegisterInputFactory(virtual_amiibo->GetEngineName(),
84 virtual_amiibo_input_factory);
85 Common::Input::RegisterOutputFactory(virtual_amiibo->GetEngineName(),
86 virtual_amiibo_output_factory);
87 44
45 RegisterEngine("keyboard", keyboard);
46 RegisterEngine("mouse", mouse);
47 RegisterEngine("touch", touch_screen);
48 RegisterEngine("gcpad", gcadapter);
49 RegisterEngine("cemuhookudp", udp_client);
50 RegisterEngine("tas", tas_input);
51 RegisterEngine("camera", camera);
52 RegisterEngine("virtual_amiibo", virtual_amiibo);
53 RegisterEngine("virtual_gamepad", virtual_gamepad);
88#ifdef HAVE_SDL2 54#ifdef HAVE_SDL2
89 sdl = std::make_shared<SDLDriver>("sdl"); 55 RegisterEngine("sdl", sdl);
90 sdl->SetMappingCallback(mapping_callback);
91 sdl_input_factory = std::make_shared<InputFactory>(sdl);
92 sdl_output_factory = std::make_shared<OutputFactory>(sdl);
93 Common::Input::RegisterInputFactory(sdl->GetEngineName(), sdl_input_factory);
94 Common::Input::RegisterOutputFactory(sdl->GetEngineName(), sdl_output_factory);
95#endif 56#endif
96 57
97 Common::Input::RegisterInputFactory("touch_from_button", 58 Common::Input::RegisterInputFactory("touch_from_button",
@@ -100,42 +61,25 @@ struct InputSubsystem::Impl {
100 std::make_shared<StickFromButton>()); 61 std::make_shared<StickFromButton>());
101 } 62 }
102 63
103 void Shutdown() { 64 template <typename Engine>
104 Common::Input::UnregisterInputFactory(keyboard->GetEngineName()); 65 void UnregisterEngine(std::shared_ptr<Engine>& engine) {
105 Common::Input::UnregisterOutputFactory(keyboard->GetEngineName()); 66 Common::Input::UnregisterInputFactory(engine->GetEngineName());
106 keyboard.reset(); 67 Common::Input::UnregisterOutputFactory(engine->GetEngineName());
107 68 engine.reset();
108 Common::Input::UnregisterInputFactory(mouse->GetEngineName()); 69 }
109 Common::Input::UnregisterOutputFactory(mouse->GetEngineName());
110 mouse.reset();
111
112 Common::Input::UnregisterInputFactory(touch_screen->GetEngineName());
113 touch_screen.reset();
114
115 Common::Input::UnregisterInputFactory(gcadapter->GetEngineName());
116 Common::Input::UnregisterOutputFactory(gcadapter->GetEngineName());
117 gcadapter.reset();
118
119 Common::Input::UnregisterInputFactory(udp_client->GetEngineName());
120 Common::Input::UnregisterOutputFactory(udp_client->GetEngineName());
121 udp_client.reset();
122
123 Common::Input::UnregisterInputFactory(tas_input->GetEngineName());
124 Common::Input::UnregisterOutputFactory(tas_input->GetEngineName());
125 tas_input.reset();
126
127 Common::Input::UnregisterInputFactory(camera->GetEngineName());
128 Common::Input::UnregisterOutputFactory(camera->GetEngineName());
129 camera.reset();
130
131 Common::Input::UnregisterInputFactory(virtual_amiibo->GetEngineName());
132 Common::Input::UnregisterOutputFactory(virtual_amiibo->GetEngineName());
133 virtual_amiibo.reset();
134 70
71 void Shutdown() {
72 UnregisterEngine(keyboard);
73 UnregisterEngine(mouse);
74 UnregisterEngine(touch_screen);
75 UnregisterEngine(gcadapter);
76 UnregisterEngine(udp_client);
77 UnregisterEngine(tas_input);
78 UnregisterEngine(camera);
79 UnregisterEngine(virtual_amiibo);
80 UnregisterEngine(virtual_gamepad);
135#ifdef HAVE_SDL2 81#ifdef HAVE_SDL2
136 Common::Input::UnregisterInputFactory(sdl->GetEngineName()); 82 UnregisterEngine(sdl);
137 Common::Input::UnregisterOutputFactory(sdl->GetEngineName());
138 sdl.reset();
139#endif 83#endif
140 84
141 Common::Input::UnregisterInputFactory("touch_from_button"); 85 Common::Input::UnregisterInputFactory("touch_from_button");
@@ -163,117 +107,86 @@ struct InputSubsystem::Impl {
163 return devices; 107 return devices;
164 } 108 }
165 109
166 [[nodiscard]] AnalogMapping GetAnalogMappingForDevice( 110 [[nodiscard]] std::shared_ptr<InputEngine> GetInputEngine(
167 const Common::ParamPackage& params) const { 111 const Common::ParamPackage& params) const {
168 if (!params.Has("engine") || params.Get("engine", "") == "any") { 112 if (!params.Has("engine") || params.Get("engine", "") == "any") {
169 return {}; 113 return nullptr;
170 } 114 }
171 const std::string engine = params.Get("engine", ""); 115 const std::string engine = params.Get("engine", "");
116 if (engine == keyboard->GetEngineName()) {
117 return keyboard;
118 }
172 if (engine == mouse->GetEngineName()) { 119 if (engine == mouse->GetEngineName()) {
173 return mouse->GetAnalogMappingForDevice(params); 120 return mouse;
174 } 121 }
175 if (engine == gcadapter->GetEngineName()) { 122 if (engine == gcadapter->GetEngineName()) {
176 return gcadapter->GetAnalogMappingForDevice(params); 123 return gcadapter;
177 } 124 }
178 if (engine == udp_client->GetEngineName()) { 125 if (engine == udp_client->GetEngineName()) {
179 return udp_client->GetAnalogMappingForDevice(params); 126 return udp_client;
180 }
181 if (engine == tas_input->GetEngineName()) {
182 return tas_input->GetAnalogMappingForDevice(params);
183 } 127 }
184#ifdef HAVE_SDL2 128#ifdef HAVE_SDL2
185 if (engine == sdl->GetEngineName()) { 129 if (engine == sdl->GetEngineName()) {
186 return sdl->GetAnalogMappingForDevice(params); 130 return sdl;
187 } 131 }
188#endif 132#endif
189 return {}; 133 return nullptr;
190 } 134 }
191 135
192 [[nodiscard]] ButtonMapping GetButtonMappingForDevice( 136 [[nodiscard]] AnalogMapping GetAnalogMappingForDevice(
193 const Common::ParamPackage& params) const { 137 const Common::ParamPackage& params) const {
194 if (!params.Has("engine") || params.Get("engine", "") == "any") { 138 const auto input_engine = GetInputEngine(params);
139
140 if (input_engine == nullptr) {
195 return {}; 141 return {};
196 } 142 }
197 const std::string engine = params.Get("engine", ""); 143
198 if (engine == gcadapter->GetEngineName()) { 144 return input_engine->GetAnalogMappingForDevice(params);
199 return gcadapter->GetButtonMappingForDevice(params); 145 }
200 } 146
201 if (engine == udp_client->GetEngineName()) { 147 [[nodiscard]] ButtonMapping GetButtonMappingForDevice(
202 return udp_client->GetButtonMappingForDevice(params); 148 const Common::ParamPackage& params) const {
203 } 149 const auto input_engine = GetInputEngine(params);
204 if (engine == tas_input->GetEngineName()) { 150
205 return tas_input->GetButtonMappingForDevice(params); 151 if (input_engine == nullptr) {
206 } 152 return {};
207#ifdef HAVE_SDL2
208 if (engine == sdl->GetEngineName()) {
209 return sdl->GetButtonMappingForDevice(params);
210 } 153 }
211#endif 154
212 return {}; 155 return input_engine->GetButtonMappingForDevice(params);
213 } 156 }
214 157
215 [[nodiscard]] MotionMapping GetMotionMappingForDevice( 158 [[nodiscard]] MotionMapping GetMotionMappingForDevice(
216 const Common::ParamPackage& params) const { 159 const Common::ParamPackage& params) const {
217 if (!params.Has("engine") || params.Get("engine", "") == "any") { 160 const auto input_engine = GetInputEngine(params);
161
162 if (input_engine == nullptr) {
218 return {}; 163 return {};
219 } 164 }
220 const std::string engine = params.Get("engine", ""); 165
221 if (engine == udp_client->GetEngineName()) { 166 return input_engine->GetMotionMappingForDevice(params);
222 return udp_client->GetMotionMappingForDevice(params);
223 }
224#ifdef HAVE_SDL2
225 if (engine == sdl->GetEngineName()) {
226 return sdl->GetMotionMappingForDevice(params);
227 }
228#endif
229 return {};
230 } 167 }
231 168
232 Common::Input::ButtonNames GetButtonName(const Common::ParamPackage& params) const { 169 Common::Input::ButtonNames GetButtonName(const Common::ParamPackage& params) const {
233 if (!params.Has("engine") || params.Get("engine", "") == "any") { 170 if (!params.Has("engine") || params.Get("engine", "") == "any") {
234 return Common::Input::ButtonNames::Undefined; 171 return Common::Input::ButtonNames::Undefined;
235 } 172 }
236 const std::string engine = params.Get("engine", ""); 173 const auto input_engine = GetInputEngine(params);
237 if (engine == mouse->GetEngineName()) { 174
238 return mouse->GetUIName(params); 175 if (input_engine == nullptr) {
239 } 176 return Common::Input::ButtonNames::Invalid;
240 if (engine == gcadapter->GetEngineName()) {
241 return gcadapter->GetUIName(params);
242 }
243 if (engine == udp_client->GetEngineName()) {
244 return udp_client->GetUIName(params);
245 }
246 if (engine == tas_input->GetEngineName()) {
247 return tas_input->GetUIName(params);
248 }
249#ifdef HAVE_SDL2
250 if (engine == sdl->GetEngineName()) {
251 return sdl->GetUIName(params);
252 } 177 }
253#endif 178
254 return Common::Input::ButtonNames::Invalid; 179 return input_engine->GetUIName(params);
255 } 180 }
256 181
257 bool IsStickInverted(const Common::ParamPackage& params) { 182 bool IsStickInverted(const Common::ParamPackage& params) {
258 const std::string engine = params.Get("engine", ""); 183 const auto input_engine = GetInputEngine(params);
259 if (engine == mouse->GetEngineName()) { 184
260 return mouse->IsStickInverted(params); 185 if (input_engine == nullptr) {
261 } 186 return false;
262 if (engine == gcadapter->GetEngineName()) {
263 return gcadapter->IsStickInverted(params);
264 }
265 if (engine == udp_client->GetEngineName()) {
266 return udp_client->IsStickInverted(params);
267 }
268 if (engine == tas_input->GetEngineName()) {
269 return tas_input->IsStickInverted(params);
270 }
271#ifdef HAVE_SDL2
272 if (engine == sdl->GetEngineName()) {
273 return sdl->IsStickInverted(params);
274 } 187 }
275#endif 188
276 return false; 189 return input_engine->IsStickInverted(params);
277 } 190 }
278 191
279 bool IsController(const Common::ParamPackage& params) { 192 bool IsController(const Common::ParamPackage& params) {
@@ -290,6 +203,9 @@ struct InputSubsystem::Impl {
290 if (engine == tas_input->GetEngineName()) { 203 if (engine == tas_input->GetEngineName()) {
291 return true; 204 return true;
292 } 205 }
206 if (engine == virtual_gamepad->GetEngineName()) {
207 return true;
208 }
293#ifdef HAVE_SDL2 209#ifdef HAVE_SDL2
294 if (engine == sdl->GetEngineName()) { 210 if (engine == sdl->GetEngineName()) {
295 return true; 211 return true;
@@ -338,28 +254,10 @@ struct InputSubsystem::Impl {
338 std::shared_ptr<CemuhookUDP::UDPClient> udp_client; 254 std::shared_ptr<CemuhookUDP::UDPClient> udp_client;
339 std::shared_ptr<Camera> camera; 255 std::shared_ptr<Camera> camera;
340 std::shared_ptr<VirtualAmiibo> virtual_amiibo; 256 std::shared_ptr<VirtualAmiibo> virtual_amiibo;
341 257 std::shared_ptr<VirtualGamepad> virtual_gamepad;
342 std::shared_ptr<InputFactory> keyboard_factory;
343 std::shared_ptr<InputFactory> mouse_factory;
344 std::shared_ptr<InputFactory> gcadapter_input_factory;
345 std::shared_ptr<InputFactory> touch_screen_factory;
346 std::shared_ptr<InputFactory> udp_client_input_factory;
347 std::shared_ptr<InputFactory> tas_input_factory;
348 std::shared_ptr<InputFactory> camera_input_factory;
349 std::shared_ptr<InputFactory> virtual_amiibo_input_factory;
350
351 std::shared_ptr<OutputFactory> keyboard_output_factory;
352 std::shared_ptr<OutputFactory> mouse_output_factory;
353 std::shared_ptr<OutputFactory> gcadapter_output_factory;
354 std::shared_ptr<OutputFactory> udp_client_output_factory;
355 std::shared_ptr<OutputFactory> tas_output_factory;
356 std::shared_ptr<OutputFactory> camera_output_factory;
357 std::shared_ptr<OutputFactory> virtual_amiibo_output_factory;
358 258
359#ifdef HAVE_SDL2 259#ifdef HAVE_SDL2
360 std::shared_ptr<SDLDriver> sdl; 260 std::shared_ptr<SDLDriver> sdl;
361 std::shared_ptr<InputFactory> sdl_input_factory;
362 std::shared_ptr<OutputFactory> sdl_output_factory;
363#endif 261#endif
364}; 262};
365 263
@@ -423,6 +321,14 @@ const VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() const {
423 return impl->virtual_amiibo.get(); 321 return impl->virtual_amiibo.get();
424} 322}
425 323
324VirtualGamepad* InputSubsystem::GetVirtualGamepad() {
325 return impl->virtual_gamepad.get();
326}
327
328const VirtualGamepad* InputSubsystem::GetVirtualGamepad() const {
329 return impl->virtual_gamepad.get();
330}
331
426std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { 332std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
427 return impl->GetInputDevices(); 333 return impl->GetInputDevices();
428} 334}
diff --git a/src/input_common/main.h b/src/input_common/main.h
index 6218c37f6..1207d786c 100644
--- a/src/input_common/main.h
+++ b/src/input_common/main.h
@@ -34,6 +34,7 @@ class Keyboard;
34class Mouse; 34class Mouse;
35class TouchScreen; 35class TouchScreen;
36class VirtualAmiibo; 36class VirtualAmiibo;
37class VirtualGamepad;
37struct MappingData; 38struct MappingData;
38} // namespace InputCommon 39} // namespace InputCommon
39 40
@@ -108,6 +109,12 @@ public:
108 /// Retrieves the underlying virtual amiibo input device. 109 /// Retrieves the underlying virtual amiibo input device.
109 [[nodiscard]] const VirtualAmiibo* GetVirtualAmiibo() const; 110 [[nodiscard]] const VirtualAmiibo* GetVirtualAmiibo() const;
110 111
112 /// Retrieves the underlying virtual gamepad input device.
113 [[nodiscard]] VirtualGamepad* GetVirtualGamepad();
114
115 /// Retrieves the underlying virtual gamepad input device.
116 [[nodiscard]] const VirtualGamepad* GetVirtualGamepad() const;
117
111 /** 118 /**
112 * Returns all available input devices that this Factory can create a new device with. 119 * Returns all available input devices that this Factory can create a new device with.
113 * Each returned ParamPackage should have a `display` field used for display, a `engine` field 120 * Each returned ParamPackage should have a `display` field used for display, a `engine` field