diff options
| -rw-r--r-- | src/core/hid/emulated_controller.cpp | 82 | ||||
| -rw-r--r-- | src/core/hid/emulated_controller.h | 9 | ||||
| -rw-r--r-- | src/input_common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/input_common/drivers/virtual_gamepad.cpp | 78 | ||||
| -rw-r--r-- | src/input_common/drivers/virtual_gamepad.h | 73 | ||||
| -rw-r--r-- | src/input_common/main.cpp | 23 | ||||
| -rw-r--r-- | src/input_common/main.h | 7 |
7 files changed, 274 insertions, 0 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 67969e938..f238d6ccd 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -145,6 +145,7 @@ void EmulatedController::LoadDevices() { | |||
| 145 | output_params[3].Set("output", true); | 145 | output_params[3].Set("output", true); |
| 146 | 146 | ||
| 147 | LoadTASParams(); | 147 | LoadTASParams(); |
| 148 | LoadVirtualGamepadParams(); | ||
| 148 | 149 | ||
| 149 | std::ranges::transform(button_params, button_devices.begin(), Common::Input::CreateInputDevice); | 150 | std::ranges::transform(button_params, button_devices.begin(), Common::Input::CreateInputDevice); |
| 150 | std::ranges::transform(stick_params, stick_devices.begin(), Common::Input::CreateInputDevice); | 151 | std::ranges::transform(stick_params, stick_devices.begin(), Common::Input::CreateInputDevice); |
| @@ -163,6 +164,12 @@ void EmulatedController::LoadDevices() { | |||
| 163 | Common::Input::CreateInputDevice); | 164 | Common::Input::CreateInputDevice); |
| 164 | std::ranges::transform(tas_stick_params, tas_stick_devices.begin(), | 165 | std::ranges::transform(tas_stick_params, tas_stick_devices.begin(), |
| 165 | Common::Input::CreateInputDevice); | 166 | Common::Input::CreateInputDevice); |
| 167 | |||
| 168 | // Initialize virtual gamepad devices | ||
| 169 | std::ranges::transform(virtual_button_params, virtual_button_devices.begin(), | ||
| 170 | Common::Input::CreateInputDevice); | ||
| 171 | std::ranges::transform(virtual_stick_params, virtual_stick_devices.begin(), | ||
| 172 | Common::Input::CreateInputDevice); | ||
| 166 | } | 173 | } |
| 167 | 174 | ||
| 168 | void EmulatedController::LoadTASParams() { | 175 | void EmulatedController::LoadTASParams() { |
| @@ -205,6 +212,46 @@ void EmulatedController::LoadTASParams() { | |||
| 205 | tas_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3); | 212 | tas_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3); |
| 206 | } | 213 | } |
| 207 | 214 | ||
| 215 | void EmulatedController::LoadVirtualGamepadParams() { | ||
| 216 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | ||
| 217 | Common::ParamPackage common_params{}; | ||
| 218 | common_params.Set("engine", "virtual_gamepad"); | ||
| 219 | common_params.Set("port", static_cast<int>(player_index)); | ||
| 220 | for (auto& param : virtual_button_params) { | ||
| 221 | param = common_params; | ||
| 222 | } | ||
| 223 | for (auto& param : virtual_stick_params) { | ||
| 224 | param = common_params; | ||
| 225 | } | ||
| 226 | |||
| 227 | // TODO(german77): Replace this with an input profile or something better | ||
| 228 | virtual_button_params[Settings::NativeButton::A].Set("button", 0); | ||
| 229 | virtual_button_params[Settings::NativeButton::B].Set("button", 1); | ||
| 230 | virtual_button_params[Settings::NativeButton::X].Set("button", 2); | ||
| 231 | virtual_button_params[Settings::NativeButton::Y].Set("button", 3); | ||
| 232 | virtual_button_params[Settings::NativeButton::LStick].Set("button", 4); | ||
| 233 | virtual_button_params[Settings::NativeButton::RStick].Set("button", 5); | ||
| 234 | virtual_button_params[Settings::NativeButton::L].Set("button", 6); | ||
| 235 | virtual_button_params[Settings::NativeButton::R].Set("button", 7); | ||
| 236 | virtual_button_params[Settings::NativeButton::ZL].Set("button", 8); | ||
| 237 | virtual_button_params[Settings::NativeButton::ZR].Set("button", 9); | ||
| 238 | virtual_button_params[Settings::NativeButton::Plus].Set("button", 10); | ||
| 239 | virtual_button_params[Settings::NativeButton::Minus].Set("button", 11); | ||
| 240 | virtual_button_params[Settings::NativeButton::DLeft].Set("button", 12); | ||
| 241 | virtual_button_params[Settings::NativeButton::DUp].Set("button", 13); | ||
| 242 | virtual_button_params[Settings::NativeButton::DRight].Set("button", 14); | ||
| 243 | virtual_button_params[Settings::NativeButton::DDown].Set("button", 15); | ||
| 244 | virtual_button_params[Settings::NativeButton::SL].Set("button", 16); | ||
| 245 | virtual_button_params[Settings::NativeButton::SR].Set("button", 17); | ||
| 246 | virtual_button_params[Settings::NativeButton::Home].Set("button", 18); | ||
| 247 | virtual_button_params[Settings::NativeButton::Screenshot].Set("button", 19); | ||
| 248 | |||
| 249 | virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_x", 0); | ||
| 250 | virtual_stick_params[Settings::NativeAnalog::LStick].Set("axis_y", 1); | ||
| 251 | virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_x", 2); | ||
| 252 | virtual_stick_params[Settings::NativeAnalog::RStick].Set("axis_y", 3); | ||
| 253 | } | ||
| 254 | |||
| 208 | void EmulatedController::ReloadInput() { | 255 | void EmulatedController::ReloadInput() { |
| 209 | // If you load any device here add the equivalent to the UnloadInput() function | 256 | // If you load any device here add the equivalent to the UnloadInput() function |
| 210 | LoadDevices(); | 257 | LoadDevices(); |
| @@ -322,6 +369,35 @@ void EmulatedController::ReloadInput() { | |||
| 322 | }, | 369 | }, |
| 323 | }); | 370 | }); |
| 324 | } | 371 | } |
| 372 | |||
| 373 | // Use a common UUID for Virtual Gamepad | ||
| 374 | static constexpr Common::UUID VIRTUAL_UUID = Common::UUID{ | ||
| 375 | {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xFF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; | ||
| 376 | |||
| 377 | // Register virtual devices. No need to force update | ||
| 378 | for (std::size_t index = 0; index < virtual_button_devices.size(); ++index) { | ||
| 379 | if (!virtual_button_devices[index]) { | ||
| 380 | continue; | ||
| 381 | } | ||
| 382 | virtual_button_devices[index]->SetCallback({ | ||
| 383 | .on_change = | ||
| 384 | [this, index](const Common::Input::CallbackStatus& callback) { | ||
| 385 | SetButton(callback, index, VIRTUAL_UUID); | ||
| 386 | }, | ||
| 387 | }); | ||
| 388 | } | ||
| 389 | |||
| 390 | for (std::size_t index = 0; index < virtual_stick_devices.size(); ++index) { | ||
| 391 | if (!virtual_stick_devices[index]) { | ||
| 392 | continue; | ||
| 393 | } | ||
| 394 | virtual_stick_devices[index]->SetCallback({ | ||
| 395 | .on_change = | ||
| 396 | [this, index](const Common::Input::CallbackStatus& callback) { | ||
| 397 | SetStick(callback, index, VIRTUAL_UUID); | ||
| 398 | }, | ||
| 399 | }); | ||
| 400 | } | ||
| 325 | } | 401 | } |
| 326 | 402 | ||
| 327 | void EmulatedController::UnloadInput() { | 403 | void EmulatedController::UnloadInput() { |
| @@ -349,6 +425,12 @@ void EmulatedController::UnloadInput() { | |||
| 349 | for (auto& stick : tas_stick_devices) { | 425 | for (auto& stick : tas_stick_devices) { |
| 350 | stick.reset(); | 426 | stick.reset(); |
| 351 | } | 427 | } |
| 428 | for (auto& button : virtual_button_devices) { | ||
| 429 | button.reset(); | ||
| 430 | } | ||
| 431 | for (auto& stick : virtual_stick_devices) { | ||
| 432 | stick.reset(); | ||
| 433 | } | ||
| 352 | camera_devices.reset(); | 434 | camera_devices.reset(); |
| 353 | nfc_devices.reset(); | 435 | nfc_devices.reset(); |
| 354 | } | 436 | } |
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index fa7a34278..a398543a6 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -385,6 +385,9 @@ private: | |||
| 385 | /// Set the params for TAS devices | 385 | /// Set the params for TAS devices |
| 386 | void LoadTASParams(); | 386 | void LoadTASParams(); |
| 387 | 387 | ||
| 388 | /// Set the params for virtual pad devices | ||
| 389 | void LoadVirtualGamepadParams(); | ||
| 390 | |||
| 388 | /** | 391 | /** |
| 389 | * @param use_temporary_value If true tmp_npad_type will be used | 392 | * @param use_temporary_value If true tmp_npad_type will be used |
| 390 | * @return true if the controller style is fullkey | 393 | * @return true if the controller style is fullkey |
| @@ -500,6 +503,12 @@ private: | |||
| 500 | ButtonDevices tas_button_devices; | 503 | ButtonDevices tas_button_devices; |
| 501 | StickDevices tas_stick_devices; | 504 | StickDevices tas_stick_devices; |
| 502 | 505 | ||
| 506 | // Virtual gamepad related variables | ||
| 507 | ButtonParams virtual_button_params; | ||
| 508 | StickParams virtual_stick_params; | ||
| 509 | ButtonDevices virtual_button_devices; | ||
| 510 | StickDevices virtual_stick_devices; | ||
| 511 | |||
| 503 | mutable std::mutex mutex; | 512 | mutable std::mutex mutex; |
| 504 | mutable std::mutex callback_mutex; | 513 | mutable std::mutex callback_mutex; |
| 505 | std::unordered_map<int, ControllerUpdateCallback> callback_list; | 514 | std::unordered_map<int, ControllerUpdateCallback> callback_list; |
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/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 | |||
| 6 | namespace InputCommon { | ||
| 7 | constexpr std::size_t PlayerIndexCount = 10; | ||
| 8 | |||
| 9 | VirtualGamepad::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 | |||
| 15 | void 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 | |||
| 23 | void VirtualGamepad::SetButtonState(std::size_t player_index, VirtualButton button_id, bool value) { | ||
| 24 | SetButtonState(player_index, static_cast<int>(button_id), value); | ||
| 25 | } | ||
| 26 | |||
| 27 | void 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 | |||
| 37 | void 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 | |||
| 42 | void 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 | |||
| 70 | PadIdentifier 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 | |||
| 8 | namespace InputCommon { | ||
| 9 | |||
| 10 | /** | ||
| 11 | * A virtual controller that is always assigned to the game input | ||
| 12 | */ | ||
| 13 | class VirtualGamepad final : public InputEngine { | ||
| 14 | public: | ||
| 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 | |||
| 68 | private: | ||
| 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/main.cpp b/src/input_common/main.cpp index 942a13535..75b856c95 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" |
| @@ -85,6 +86,12 @@ struct InputSubsystem::Impl { | |||
| 85 | Common::Input::RegisterOutputFactory(virtual_amiibo->GetEngineName(), | 86 | Common::Input::RegisterOutputFactory(virtual_amiibo->GetEngineName(), |
| 86 | virtual_amiibo_output_factory); | 87 | virtual_amiibo_output_factory); |
| 87 | 88 | ||
| 89 | virtual_gamepad = std::make_shared<VirtualGamepad>("virtual_gamepad"); | ||
| 90 | virtual_gamepad->SetMappingCallback(mapping_callback); | ||
| 91 | virtual_gamepad_input_factory = std::make_shared<InputFactory>(virtual_gamepad); | ||
| 92 | Common::Input::RegisterInputFactory(virtual_gamepad->GetEngineName(), | ||
| 93 | virtual_gamepad_input_factory); | ||
| 94 | |||
| 88 | #ifdef HAVE_SDL2 | 95 | #ifdef HAVE_SDL2 |
| 89 | sdl = std::make_shared<SDLDriver>("sdl"); | 96 | sdl = std::make_shared<SDLDriver>("sdl"); |
| 90 | sdl->SetMappingCallback(mapping_callback); | 97 | sdl->SetMappingCallback(mapping_callback); |
| @@ -132,6 +139,9 @@ struct InputSubsystem::Impl { | |||
| 132 | Common::Input::UnregisterOutputFactory(virtual_amiibo->GetEngineName()); | 139 | Common::Input::UnregisterOutputFactory(virtual_amiibo->GetEngineName()); |
| 133 | virtual_amiibo.reset(); | 140 | virtual_amiibo.reset(); |
| 134 | 141 | ||
| 142 | Common::Input::UnregisterInputFactory(virtual_gamepad->GetEngineName()); | ||
| 143 | virtual_gamepad.reset(); | ||
| 144 | |||
| 135 | #ifdef HAVE_SDL2 | 145 | #ifdef HAVE_SDL2 |
| 136 | Common::Input::UnregisterInputFactory(sdl->GetEngineName()); | 146 | Common::Input::UnregisterInputFactory(sdl->GetEngineName()); |
| 137 | Common::Input::UnregisterOutputFactory(sdl->GetEngineName()); | 147 | Common::Input::UnregisterOutputFactory(sdl->GetEngineName()); |
| @@ -290,6 +300,9 @@ struct InputSubsystem::Impl { | |||
| 290 | if (engine == tas_input->GetEngineName()) { | 300 | if (engine == tas_input->GetEngineName()) { |
| 291 | return true; | 301 | return true; |
| 292 | } | 302 | } |
| 303 | if (engine == virtual_gamepad->GetEngineName()) { | ||
| 304 | return true; | ||
| 305 | } | ||
| 293 | #ifdef HAVE_SDL2 | 306 | #ifdef HAVE_SDL2 |
| 294 | if (engine == sdl->GetEngineName()) { | 307 | if (engine == sdl->GetEngineName()) { |
| 295 | return true; | 308 | return true; |
| @@ -338,6 +351,7 @@ struct InputSubsystem::Impl { | |||
| 338 | std::shared_ptr<CemuhookUDP::UDPClient> udp_client; | 351 | std::shared_ptr<CemuhookUDP::UDPClient> udp_client; |
| 339 | std::shared_ptr<Camera> camera; | 352 | std::shared_ptr<Camera> camera; |
| 340 | std::shared_ptr<VirtualAmiibo> virtual_amiibo; | 353 | std::shared_ptr<VirtualAmiibo> virtual_amiibo; |
| 354 | std::shared_ptr<VirtualGamepad> virtual_gamepad; | ||
| 341 | 355 | ||
| 342 | std::shared_ptr<InputFactory> keyboard_factory; | 356 | std::shared_ptr<InputFactory> keyboard_factory; |
| 343 | std::shared_ptr<InputFactory> mouse_factory; | 357 | std::shared_ptr<InputFactory> mouse_factory; |
| @@ -347,6 +361,7 @@ struct InputSubsystem::Impl { | |||
| 347 | std::shared_ptr<InputFactory> tas_input_factory; | 361 | std::shared_ptr<InputFactory> tas_input_factory; |
| 348 | std::shared_ptr<InputFactory> camera_input_factory; | 362 | std::shared_ptr<InputFactory> camera_input_factory; |
| 349 | std::shared_ptr<InputFactory> virtual_amiibo_input_factory; | 363 | std::shared_ptr<InputFactory> virtual_amiibo_input_factory; |
| 364 | std::shared_ptr<InputFactory> virtual_gamepad_input_factory; | ||
| 350 | 365 | ||
| 351 | std::shared_ptr<OutputFactory> keyboard_output_factory; | 366 | std::shared_ptr<OutputFactory> keyboard_output_factory; |
| 352 | std::shared_ptr<OutputFactory> mouse_output_factory; | 367 | std::shared_ptr<OutputFactory> mouse_output_factory; |
| @@ -423,6 +438,14 @@ const VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() const { | |||
| 423 | return impl->virtual_amiibo.get(); | 438 | return impl->virtual_amiibo.get(); |
| 424 | } | 439 | } |
| 425 | 440 | ||
| 441 | VirtualGamepad* InputSubsystem::GetVirtualGamepad() { | ||
| 442 | return impl->virtual_gamepad.get(); | ||
| 443 | } | ||
| 444 | |||
| 445 | const VirtualGamepad* InputSubsystem::GetVirtualGamepad() const { | ||
| 446 | return impl->virtual_gamepad.get(); | ||
| 447 | } | ||
| 448 | |||
| 426 | std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { | 449 | std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { |
| 427 | return impl->GetInputDevices(); | 450 | return impl->GetInputDevices(); |
| 428 | } | 451 | } |
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; | |||
| 34 | class Mouse; | 34 | class Mouse; |
| 35 | class TouchScreen; | 35 | class TouchScreen; |
| 36 | class VirtualAmiibo; | 36 | class VirtualAmiibo; |
| 37 | class VirtualGamepad; | ||
| 37 | struct MappingData; | 38 | struct 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 |