diff options
Diffstat (limited to 'src/input_common')
| -rw-r--r-- | src/input_common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/input_common/drivers/gc_adapter.cpp | 4 | ||||
| -rw-r--r-- | src/input_common/drivers/mouse.cpp | 2 | ||||
| -rw-r--r-- | src/input_common/drivers/sdl_driver.cpp | 4 | ||||
| -rw-r--r-- | src/input_common/drivers/virtual_amiibo.cpp | 101 | ||||
| -rw-r--r-- | src/input_common/drivers/virtual_amiibo.h | 61 | ||||
| -rw-r--r-- | src/input_common/input_engine.cpp | 37 | ||||
| -rw-r--r-- | src/input_common/input_engine.h | 17 | ||||
| -rw-r--r-- | src/input_common/input_poller.cpp | 72 | ||||
| -rw-r--r-- | src/input_common/input_poller.h | 10 | ||||
| -rw-r--r-- | src/input_common/main.cpp | 21 | ||||
| -rw-r--r-- | src/input_common/main.h | 7 |
12 files changed, 332 insertions, 6 deletions
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index 4b91b88ce..2cf9eb97f 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt | |||
| @@ -18,6 +18,8 @@ add_library(input_common STATIC | |||
| 18 | drivers/touch_screen.h | 18 | drivers/touch_screen.h |
| 19 | drivers/udp_client.cpp | 19 | drivers/udp_client.cpp |
| 20 | drivers/udp_client.h | 20 | drivers/udp_client.h |
| 21 | drivers/virtual_amiibo.cpp | ||
| 22 | drivers/virtual_amiibo.h | ||
| 21 | helpers/stick_from_buttons.cpp | 23 | helpers/stick_from_buttons.cpp |
| 22 | helpers/stick_from_buttons.h | 24 | helpers/stick_from_buttons.h |
| 23 | helpers/touch_from_buttons.cpp | 25 | helpers/touch_from_buttons.cpp |
diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp index 27a0ffb0d..f4dd24e7d 100644 --- a/src/input_common/drivers/gc_adapter.cpp +++ b/src/input_common/drivers/gc_adapter.cpp | |||
| @@ -90,7 +90,7 @@ GCAdapter::~GCAdapter() { | |||
| 90 | 90 | ||
| 91 | void GCAdapter::AdapterInputThread(std::stop_token stop_token) { | 91 | void GCAdapter::AdapterInputThread(std::stop_token stop_token) { |
| 92 | LOG_DEBUG(Input, "Input thread started"); | 92 | LOG_DEBUG(Input, "Input thread started"); |
| 93 | Common::SetCurrentThreadName("yuzu:input:GCAdapter"); | 93 | Common::SetCurrentThreadName("GCAdapter"); |
| 94 | s32 payload_size{}; | 94 | s32 payload_size{}; |
| 95 | AdapterPayload adapter_payload{}; | 95 | AdapterPayload adapter_payload{}; |
| 96 | 96 | ||
| @@ -214,7 +214,7 @@ void GCAdapter::UpdateStateAxes(std::size_t port, const AdapterPayload& adapter_ | |||
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | void GCAdapter::AdapterScanThread(std::stop_token stop_token) { | 216 | void GCAdapter::AdapterScanThread(std::stop_token stop_token) { |
| 217 | Common::SetCurrentThreadName("yuzu:input:ScanGCAdapter"); | 217 | Common::SetCurrentThreadName("ScanGCAdapter"); |
| 218 | usb_adapter_handle = nullptr; | 218 | usb_adapter_handle = nullptr; |
| 219 | pads = {}; | 219 | pads = {}; |
| 220 | while (!stop_token.stop_requested() && !Setup()) { | 220 | while (!stop_token.stop_requested() && !Setup()) { |
diff --git a/src/input_common/drivers/mouse.cpp b/src/input_common/drivers/mouse.cpp index 4909fa8d7..98c3157a8 100644 --- a/src/input_common/drivers/mouse.cpp +++ b/src/input_common/drivers/mouse.cpp | |||
| @@ -37,7 +37,7 @@ Mouse::Mouse(std::string input_engine_) : InputEngine(std::move(input_engine_)) | |||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void Mouse::UpdateThread(std::stop_token stop_token) { | 39 | void Mouse::UpdateThread(std::stop_token stop_token) { |
| 40 | Common::SetCurrentThreadName("yuzu:input:Mouse"); | 40 | Common::SetCurrentThreadName("Mouse"); |
| 41 | constexpr int update_time = 10; | 41 | constexpr int update_time = 10; |
| 42 | while (!stop_token.stop_requested()) { | 42 | while (!stop_token.stop_requested()) { |
| 43 | if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) { | 43 | if (Settings::values.mouse_panning && !Settings::values.mouse_enabled) { |
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index 5cc1ccbd9..b72e4b397 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp | |||
| @@ -436,7 +436,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en | |||
| 436 | initialized = true; | 436 | initialized = true; |
| 437 | if (start_thread) { | 437 | if (start_thread) { |
| 438 | poll_thread = std::thread([this] { | 438 | poll_thread = std::thread([this] { |
| 439 | Common::SetCurrentThreadName("yuzu:input:SDL"); | 439 | Common::SetCurrentThreadName("SDL_MainLoop"); |
| 440 | using namespace std::chrono_literals; | 440 | using namespace std::chrono_literals; |
| 441 | while (initialized) { | 441 | while (initialized) { |
| 442 | SDL_PumpEvents(); | 442 | SDL_PumpEvents(); |
| @@ -444,7 +444,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en | |||
| 444 | } | 444 | } |
| 445 | }); | 445 | }); |
| 446 | vibration_thread = std::thread([this] { | 446 | vibration_thread = std::thread([this] { |
| 447 | Common::SetCurrentThreadName("yuzu:input:SDL_Vibration"); | 447 | Common::SetCurrentThreadName("SDL_Vibration"); |
| 448 | using namespace std::chrono_literals; | 448 | using namespace std::chrono_literals; |
| 449 | while (initialized) { | 449 | while (initialized) { |
| 450 | SendVibrations(); | 450 | SendVibrations(); |
diff --git a/src/input_common/drivers/virtual_amiibo.cpp b/src/input_common/drivers/virtual_amiibo.cpp new file mode 100644 index 000000000..0cd5129da --- /dev/null +++ b/src/input_common/drivers/virtual_amiibo.cpp | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include <cstring> | ||
| 5 | #include <fmt/format.h> | ||
| 6 | |||
| 7 | #include "common/fs/file.h" | ||
| 8 | #include "common/fs/fs.h" | ||
| 9 | #include "common/fs/path_util.h" | ||
| 10 | #include "common/logging/log.h" | ||
| 11 | #include "common/settings.h" | ||
| 12 | #include "input_common/drivers/virtual_amiibo.h" | ||
| 13 | |||
| 14 | namespace InputCommon { | ||
| 15 | constexpr PadIdentifier identifier = { | ||
| 16 | .guid = Common::UUID{}, | ||
| 17 | .port = 0, | ||
| 18 | .pad = 0, | ||
| 19 | }; | ||
| 20 | |||
| 21 | VirtualAmiibo::VirtualAmiibo(std::string input_engine_) : InputEngine(std::move(input_engine_)) {} | ||
| 22 | |||
| 23 | VirtualAmiibo::~VirtualAmiibo() = default; | ||
| 24 | |||
| 25 | Common::Input::PollingError VirtualAmiibo::SetPollingMode( | ||
| 26 | [[maybe_unused]] const PadIdentifier& identifier_, | ||
| 27 | const Common::Input::PollingMode polling_mode_) { | ||
| 28 | polling_mode = polling_mode_; | ||
| 29 | |||
| 30 | if (polling_mode == Common::Input::PollingMode::NFC) { | ||
| 31 | if (state == State::Initialized) { | ||
| 32 | state = State::WaitingForAmiibo; | ||
| 33 | } | ||
| 34 | } else { | ||
| 35 | if (state == State::AmiiboIsOpen) { | ||
| 36 | CloseAmiibo(); | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | return Common::Input::PollingError::None; | ||
| 41 | } | ||
| 42 | |||
| 43 | Common::Input::NfcState VirtualAmiibo::SupportsNfc( | ||
| 44 | [[maybe_unused]] const PadIdentifier& identifier_) const { | ||
| 45 | return Common::Input::NfcState::Success; | ||
| 46 | } | ||
| 47 | |||
| 48 | Common::Input::NfcState VirtualAmiibo::WriteNfcData( | ||
| 49 | [[maybe_unused]] const PadIdentifier& identifier_, const std::vector<u8>& data) { | ||
| 50 | const Common::FS::IOFile amiibo_file{file_path, Common::FS::FileAccessMode::ReadWrite, | ||
| 51 | Common::FS::FileType::BinaryFile}; | ||
| 52 | |||
| 53 | if (!amiibo_file.IsOpen()) { | ||
| 54 | LOG_ERROR(Core, "Amiibo is already on use"); | ||
| 55 | return Common::Input::NfcState::WriteFailed; | ||
| 56 | } | ||
| 57 | |||
| 58 | if (!amiibo_file.Write(data)) { | ||
| 59 | LOG_ERROR(Service_NFP, "Error writting to file"); | ||
| 60 | return Common::Input::NfcState::WriteFailed; | ||
| 61 | } | ||
| 62 | |||
| 63 | return Common::Input::NfcState::Success; | ||
| 64 | } | ||
| 65 | |||
| 66 | VirtualAmiibo::State VirtualAmiibo::GetCurrentState() const { | ||
| 67 | return state; | ||
| 68 | } | ||
| 69 | |||
| 70 | VirtualAmiibo::Info VirtualAmiibo::LoadAmiibo(const std::string& filename) { | ||
| 71 | const Common::FS::IOFile amiibo_file{filename, Common::FS::FileAccessMode::Read, | ||
| 72 | Common::FS::FileType::BinaryFile}; | ||
| 73 | |||
| 74 | if (state != State::WaitingForAmiibo) { | ||
| 75 | return Info::WrongDeviceState; | ||
| 76 | } | ||
| 77 | |||
| 78 | if (!amiibo_file.IsOpen()) { | ||
| 79 | return Info::UnableToLoad; | ||
| 80 | } | ||
| 81 | |||
| 82 | amiibo_data.resize(amiibo_size); | ||
| 83 | |||
| 84 | if (amiibo_file.Read(amiibo_data) < amiibo_size_without_password) { | ||
| 85 | return Info::NotAnAmiibo; | ||
| 86 | } | ||
| 87 | |||
| 88 | file_path = filename; | ||
| 89 | state = State::AmiiboIsOpen; | ||
| 90 | SetNfc(identifier, {Common::Input::NfcState::NewAmiibo, amiibo_data}); | ||
| 91 | return Info::Success; | ||
| 92 | } | ||
| 93 | |||
| 94 | VirtualAmiibo::Info VirtualAmiibo::CloseAmiibo() { | ||
| 95 | state = polling_mode == Common::Input::PollingMode::NFC ? State::WaitingForAmiibo | ||
| 96 | : State::Initialized; | ||
| 97 | SetNfc(identifier, {Common::Input::NfcState::AmiiboRemoved, {}}); | ||
| 98 | return Info::Success; | ||
| 99 | } | ||
| 100 | |||
| 101 | } // namespace InputCommon | ||
diff --git a/src/input_common/drivers/virtual_amiibo.h b/src/input_common/drivers/virtual_amiibo.h new file mode 100644 index 000000000..9eac07544 --- /dev/null +++ b/src/input_common/drivers/virtual_amiibo.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <array> | ||
| 7 | #include <string> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "input_common/input_engine.h" | ||
| 12 | |||
| 13 | namespace Common::FS { | ||
| 14 | class IOFile; | ||
| 15 | } | ||
| 16 | |||
| 17 | namespace InputCommon { | ||
| 18 | |||
| 19 | class VirtualAmiibo final : public InputEngine { | ||
| 20 | public: | ||
| 21 | enum class State { | ||
| 22 | Initialized, | ||
| 23 | WaitingForAmiibo, | ||
| 24 | AmiiboIsOpen, | ||
| 25 | }; | ||
| 26 | |||
| 27 | enum class Info { | ||
| 28 | Success, | ||
| 29 | UnableToLoad, | ||
| 30 | NotAnAmiibo, | ||
| 31 | WrongDeviceState, | ||
| 32 | Unknown, | ||
| 33 | }; | ||
| 34 | |||
| 35 | explicit VirtualAmiibo(std::string input_engine_); | ||
| 36 | ~VirtualAmiibo() override; | ||
| 37 | |||
| 38 | // Sets polling mode to a controller | ||
| 39 | Common::Input::PollingError SetPollingMode( | ||
| 40 | const PadIdentifier& identifier_, const Common::Input::PollingMode polling_mode_) override; | ||
| 41 | |||
| 42 | Common::Input::NfcState SupportsNfc(const PadIdentifier& identifier_) const override; | ||
| 43 | |||
| 44 | Common::Input::NfcState WriteNfcData(const PadIdentifier& identifier_, | ||
| 45 | const std::vector<u8>& data) override; | ||
| 46 | |||
| 47 | State GetCurrentState() const; | ||
| 48 | |||
| 49 | Info LoadAmiibo(const std::string& amiibo_file); | ||
| 50 | Info CloseAmiibo(); | ||
| 51 | |||
| 52 | private: | ||
| 53 | static constexpr std::size_t amiibo_size = 0x21C; | ||
| 54 | static constexpr std::size_t amiibo_size_without_password = amiibo_size - 0x8; | ||
| 55 | |||
| 56 | std::string file_path{}; | ||
| 57 | State state{State::Initialized}; | ||
| 58 | std::vector<u8> amiibo_data; | ||
| 59 | Common::Input::PollingMode polling_mode{Common::Input::PollingMode::Pasive}; | ||
| 60 | }; | ||
| 61 | } // namespace InputCommon | ||
diff --git a/src/input_common/input_engine.cpp b/src/input_common/input_engine.cpp index 6ede0e4b0..61cfd0911 100644 --- a/src/input_common/input_engine.cpp +++ b/src/input_common/input_engine.cpp | |||
| @@ -102,6 +102,17 @@ void InputEngine::SetCamera(const PadIdentifier& identifier, | |||
| 102 | TriggerOnCameraChange(identifier, value); | 102 | TriggerOnCameraChange(identifier, value); |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | void InputEngine::SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value) { | ||
| 106 | { | ||
| 107 | std::scoped_lock lock{mutex}; | ||
| 108 | ControllerData& controller = controller_list.at(identifier); | ||
| 109 | if (!configuring) { | ||
| 110 | controller.nfc = value; | ||
| 111 | } | ||
| 112 | } | ||
| 113 | TriggerOnNfcChange(identifier, value); | ||
| 114 | } | ||
| 115 | |||
| 105 | bool InputEngine::GetButton(const PadIdentifier& identifier, int button) const { | 116 | bool InputEngine::GetButton(const PadIdentifier& identifier, int button) const { |
| 106 | std::scoped_lock lock{mutex}; | 117 | std::scoped_lock lock{mutex}; |
| 107 | const auto controller_iter = controller_list.find(identifier); | 118 | const auto controller_iter = controller_list.find(identifier); |
| @@ -189,6 +200,18 @@ Common::Input::CameraStatus InputEngine::GetCamera(const PadIdentifier& identifi | |||
| 189 | return controller.camera; | 200 | return controller.camera; |
| 190 | } | 201 | } |
| 191 | 202 | ||
| 203 | Common::Input::NfcStatus InputEngine::GetNfc(const PadIdentifier& identifier) const { | ||
| 204 | std::scoped_lock lock{mutex}; | ||
| 205 | const auto controller_iter = controller_list.find(identifier); | ||
| 206 | if (controller_iter == controller_list.cend()) { | ||
| 207 | LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), | ||
| 208 | identifier.pad, identifier.port); | ||
| 209 | return {}; | ||
| 210 | } | ||
| 211 | const ControllerData& controller = controller_iter->second; | ||
| 212 | return controller.nfc; | ||
| 213 | } | ||
| 214 | |||
| 192 | void InputEngine::ResetButtonState() { | 215 | void InputEngine::ResetButtonState() { |
| 193 | for (const auto& controller : controller_list) { | 216 | for (const auto& controller : controller_list) { |
| 194 | for (const auto& button : controller.second.buttons) { | 217 | for (const auto& button : controller.second.buttons) { |
| @@ -355,6 +378,20 @@ void InputEngine::TriggerOnCameraChange(const PadIdentifier& identifier, | |||
| 355 | } | 378 | } |
| 356 | } | 379 | } |
| 357 | 380 | ||
| 381 | void InputEngine::TriggerOnNfcChange(const PadIdentifier& identifier, | ||
| 382 | [[maybe_unused]] const Common::Input::NfcStatus& value) { | ||
| 383 | std::scoped_lock lock{mutex_callback}; | ||
| 384 | for (const auto& poller_pair : callback_list) { | ||
| 385 | const InputIdentifier& poller = poller_pair.second; | ||
| 386 | if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Nfc, 0)) { | ||
| 387 | continue; | ||
| 388 | } | ||
| 389 | if (poller.callback.on_change) { | ||
| 390 | poller.callback.on_change(); | ||
| 391 | } | ||
| 392 | } | ||
| 393 | } | ||
| 394 | |||
| 358 | bool InputEngine::IsInputIdentifierEqual(const InputIdentifier& input_identifier, | 395 | bool InputEngine::IsInputIdentifierEqual(const InputIdentifier& input_identifier, |
| 359 | const PadIdentifier& identifier, EngineInputType type, | 396 | const PadIdentifier& identifier, EngineInputType type, |
| 360 | int index) const { | 397 | int index) const { |
diff --git a/src/input_common/input_engine.h b/src/input_common/input_engine.h index f6b3c4610..cfbdb26bd 100644 --- a/src/input_common/input_engine.h +++ b/src/input_common/input_engine.h | |||
| @@ -42,6 +42,7 @@ enum class EngineInputType { | |||
| 42 | Camera, | 42 | Camera, |
| 43 | HatButton, | 43 | HatButton, |
| 44 | Motion, | 44 | Motion, |
| 45 | Nfc, | ||
| 45 | }; | 46 | }; |
| 46 | 47 | ||
| 47 | namespace std { | 48 | namespace std { |
| @@ -127,6 +128,18 @@ public: | |||
| 127 | return Common::Input::CameraError::NotSupported; | 128 | return Common::Input::CameraError::NotSupported; |
| 128 | } | 129 | } |
| 129 | 130 | ||
| 131 | // Request nfc data from a controller | ||
| 132 | virtual Common::Input::NfcState SupportsNfc( | ||
| 133 | [[maybe_unused]] const PadIdentifier& identifier) const { | ||
| 134 | return Common::Input::NfcState::NotSupported; | ||
| 135 | } | ||
| 136 | |||
| 137 | // Writes data to an nfc tag | ||
| 138 | virtual Common::Input::NfcState WriteNfcData([[maybe_unused]] const PadIdentifier& identifier, | ||
| 139 | [[maybe_unused]] const std::vector<u8>& data) { | ||
| 140 | return Common::Input::NfcState::NotSupported; | ||
| 141 | } | ||
| 142 | |||
| 130 | // Returns the engine name | 143 | // Returns the engine name |
| 131 | [[nodiscard]] const std::string& GetEngineName() const; | 144 | [[nodiscard]] const std::string& GetEngineName() const; |
| 132 | 145 | ||
| @@ -183,6 +196,7 @@ public: | |||
| 183 | Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const; | 196 | Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const; |
| 184 | BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const; | 197 | BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const; |
| 185 | Common::Input::CameraStatus GetCamera(const PadIdentifier& identifier) const; | 198 | Common::Input::CameraStatus GetCamera(const PadIdentifier& identifier) const; |
| 199 | Common::Input::NfcStatus GetNfc(const PadIdentifier& identifier) const; | ||
| 186 | 200 | ||
| 187 | int SetCallback(InputIdentifier input_identifier); | 201 | int SetCallback(InputIdentifier input_identifier); |
| 188 | void SetMappingCallback(MappingCallback callback); | 202 | void SetMappingCallback(MappingCallback callback); |
| @@ -195,6 +209,7 @@ protected: | |||
| 195 | void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value); | 209 | void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value); |
| 196 | void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value); | 210 | void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value); |
| 197 | void SetCamera(const PadIdentifier& identifier, const Common::Input::CameraStatus& value); | 211 | void SetCamera(const PadIdentifier& identifier, const Common::Input::CameraStatus& value); |
| 212 | void SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value); | ||
| 198 | 213 | ||
| 199 | virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const { | 214 | virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const { |
| 200 | return "Unknown"; | 215 | return "Unknown"; |
| @@ -208,6 +223,7 @@ private: | |||
| 208 | std::unordered_map<int, BasicMotion> motions; | 223 | std::unordered_map<int, BasicMotion> motions; |
| 209 | Common::Input::BatteryLevel battery{}; | 224 | Common::Input::BatteryLevel battery{}; |
| 210 | Common::Input::CameraStatus camera{}; | 225 | Common::Input::CameraStatus camera{}; |
| 226 | Common::Input::NfcStatus nfc{}; | ||
| 211 | }; | 227 | }; |
| 212 | 228 | ||
| 213 | void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value); | 229 | void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value); |
| @@ -218,6 +234,7 @@ private: | |||
| 218 | const BasicMotion& value); | 234 | const BasicMotion& value); |
| 219 | void TriggerOnCameraChange(const PadIdentifier& identifier, | 235 | void TriggerOnCameraChange(const PadIdentifier& identifier, |
| 220 | const Common::Input::CameraStatus& value); | 236 | const Common::Input::CameraStatus& value); |
| 237 | void TriggerOnNfcChange(const PadIdentifier& identifier, const Common::Input::NfcStatus& value); | ||
| 221 | 238 | ||
| 222 | bool IsInputIdentifierEqual(const InputIdentifier& input_identifier, | 239 | bool IsInputIdentifierEqual(const InputIdentifier& input_identifier, |
| 223 | const PadIdentifier& identifier, EngineInputType type, | 240 | const PadIdentifier& identifier, EngineInputType type, |
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp index ffb9b945e..ca33fb4eb 100644 --- a/src/input_common/input_poller.cpp +++ b/src/input_common/input_poller.cpp | |||
| @@ -691,9 +691,56 @@ public: | |||
| 691 | } | 691 | } |
| 692 | 692 | ||
| 693 | void OnChange() { | 693 | void OnChange() { |
| 694 | const auto camera_status = GetStatus(); | ||
| 695 | |||
| 694 | const Common::Input::CallbackStatus status{ | 696 | const Common::Input::CallbackStatus status{ |
| 695 | .type = Common::Input::InputType::IrSensor, | 697 | .type = Common::Input::InputType::IrSensor, |
| 696 | .camera_status = GetStatus(), | 698 | .camera_status = camera_status.format, |
| 699 | .raw_data = camera_status.data, | ||
| 700 | }; | ||
| 701 | |||
| 702 | TriggerOnChange(status); | ||
| 703 | } | ||
| 704 | |||
| 705 | private: | ||
| 706 | const PadIdentifier identifier; | ||
| 707 | int callback_key; | ||
| 708 | InputEngine* input_engine; | ||
| 709 | }; | ||
| 710 | |||
| 711 | class InputFromNfc final : public Common::Input::InputDevice { | ||
| 712 | public: | ||
| 713 | explicit InputFromNfc(PadIdentifier identifier_, InputEngine* input_engine_) | ||
| 714 | : identifier(identifier_), input_engine(input_engine_) { | ||
| 715 | UpdateCallback engine_callback{[this]() { OnChange(); }}; | ||
| 716 | const InputIdentifier input_identifier{ | ||
| 717 | .identifier = identifier, | ||
| 718 | .type = EngineInputType::Nfc, | ||
| 719 | .index = 0, | ||
| 720 | .callback = engine_callback, | ||
| 721 | }; | ||
| 722 | callback_key = input_engine->SetCallback(input_identifier); | ||
| 723 | } | ||
| 724 | |||
| 725 | ~InputFromNfc() override { | ||
| 726 | input_engine->DeleteCallback(callback_key); | ||
| 727 | } | ||
| 728 | |||
| 729 | Common::Input::NfcStatus GetStatus() const { | ||
| 730 | return input_engine->GetNfc(identifier); | ||
| 731 | } | ||
| 732 | |||
| 733 | void ForceUpdate() override { | ||
| 734 | OnChange(); | ||
| 735 | } | ||
| 736 | |||
| 737 | void OnChange() { | ||
| 738 | const auto nfc_status = GetStatus(); | ||
| 739 | |||
| 740 | const Common::Input::CallbackStatus status{ | ||
| 741 | .type = Common::Input::InputType::Nfc, | ||
| 742 | .nfc_status = nfc_status.state, | ||
| 743 | .raw_data = nfc_status.data, | ||
| 697 | }; | 744 | }; |
| 698 | 745 | ||
| 699 | TriggerOnChange(status); | 746 | TriggerOnChange(status); |
| @@ -727,6 +774,14 @@ public: | |||
| 727 | return input_engine->SetCameraFormat(identifier, camera_format); | 774 | return input_engine->SetCameraFormat(identifier, camera_format); |
| 728 | } | 775 | } |
| 729 | 776 | ||
| 777 | Common::Input::NfcState SupportsNfc() const override { | ||
| 778 | return input_engine->SupportsNfc(identifier); | ||
| 779 | } | ||
| 780 | |||
| 781 | Common::Input::NfcState WriteNfcData(const std::vector<u8>& data) override { | ||
| 782 | return input_engine->WriteNfcData(identifier, data); | ||
| 783 | } | ||
| 784 | |||
| 730 | private: | 785 | private: |
| 731 | const PadIdentifier identifier; | 786 | const PadIdentifier identifier; |
| 732 | InputEngine* input_engine; | 787 | InputEngine* input_engine; |
| @@ -978,6 +1033,18 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateCameraDevice( | |||
| 978 | return std::make_unique<InputFromCamera>(identifier, input_engine.get()); | 1033 | return std::make_unique<InputFromCamera>(identifier, input_engine.get()); |
| 979 | } | 1034 | } |
| 980 | 1035 | ||
| 1036 | std::unique_ptr<Common::Input::InputDevice> InputFactory::CreateNfcDevice( | ||
| 1037 | const Common::ParamPackage& params) { | ||
| 1038 | const PadIdentifier identifier = { | ||
| 1039 | .guid = Common::UUID{params.Get("guid", "")}, | ||
| 1040 | .port = static_cast<std::size_t>(params.Get("port", 0)), | ||
| 1041 | .pad = static_cast<std::size_t>(params.Get("pad", 0)), | ||
| 1042 | }; | ||
| 1043 | |||
| 1044 | input_engine->PreSetController(identifier); | ||
| 1045 | return std::make_unique<InputFromNfc>(identifier, input_engine.get()); | ||
| 1046 | } | ||
| 1047 | |||
| 981 | InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_) | 1048 | InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_) |
| 982 | : input_engine(std::move(input_engine_)) {} | 1049 | : input_engine(std::move(input_engine_)) {} |
| 983 | 1050 | ||
| @@ -989,6 +1056,9 @@ std::unique_ptr<Common::Input::InputDevice> InputFactory::Create( | |||
| 989 | if (params.Has("camera")) { | 1056 | if (params.Has("camera")) { |
| 990 | return CreateCameraDevice(params); | 1057 | return CreateCameraDevice(params); |
| 991 | } | 1058 | } |
| 1059 | if (params.Has("nfc")) { | ||
| 1060 | return CreateNfcDevice(params); | ||
| 1061 | } | ||
| 992 | if (params.Has("button") && params.Has("axis")) { | 1062 | if (params.Has("button") && params.Has("axis")) { |
| 993 | return CreateTriggerDevice(params); | 1063 | return CreateTriggerDevice(params); |
| 994 | } | 1064 | } |
diff --git a/src/input_common/input_poller.h b/src/input_common/input_poller.h index 4410a8415..d7db13ce4 100644 --- a/src/input_common/input_poller.h +++ b/src/input_common/input_poller.h | |||
| @@ -222,6 +222,16 @@ private: | |||
| 222 | std::unique_ptr<Common::Input::InputDevice> CreateCameraDevice( | 222 | std::unique_ptr<Common::Input::InputDevice> CreateCameraDevice( |
| 223 | const Common::ParamPackage& params); | 223 | const Common::ParamPackage& params); |
| 224 | 224 | ||
| 225 | /** | ||
| 226 | * Creates a nfc device from the parameters given. | ||
| 227 | * @param params contains parameters for creating the device: | ||
| 228 | * - "guid": text string for identifying controllers | ||
| 229 | * - "port": port of the connected device | ||
| 230 | * - "pad": slot of the connected controller | ||
| 231 | * @returns a unique input device with the parameters specified | ||
| 232 | */ | ||
| 233 | std::unique_ptr<Common::Input::InputDevice> CreateNfcDevice(const Common::ParamPackage& params); | ||
| 234 | |||
| 225 | std::shared_ptr<InputEngine> input_engine; | 235 | std::shared_ptr<InputEngine> input_engine; |
| 226 | }; | 236 | }; |
| 227 | } // namespace InputCommon | 237 | } // namespace InputCommon |
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index 75a57b9fc..b2064ef95 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "input_common/drivers/tas_input.h" | 11 | #include "input_common/drivers/tas_input.h" |
| 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/helpers/stick_from_buttons.h" | 15 | #include "input_common/helpers/stick_from_buttons.h" |
| 15 | #include "input_common/helpers/touch_from_buttons.h" | 16 | #include "input_common/helpers/touch_from_buttons.h" |
| 16 | #include "input_common/input_engine.h" | 17 | #include "input_common/input_engine.h" |
| @@ -87,6 +88,15 @@ struct InputSubsystem::Impl { | |||
| 87 | Common::Input::RegisterFactory<Common::Input::OutputDevice>(camera->GetEngineName(), | 88 | Common::Input::RegisterFactory<Common::Input::OutputDevice>(camera->GetEngineName(), |
| 88 | camera_output_factory); | 89 | camera_output_factory); |
| 89 | 90 | ||
| 91 | virtual_amiibo = std::make_shared<VirtualAmiibo>("virtual_amiibo"); | ||
| 92 | virtual_amiibo->SetMappingCallback(mapping_callback); | ||
| 93 | virtual_amiibo_input_factory = std::make_shared<InputFactory>(virtual_amiibo); | ||
| 94 | virtual_amiibo_output_factory = std::make_shared<OutputFactory>(virtual_amiibo); | ||
| 95 | Common::Input::RegisterFactory<Common::Input::InputDevice>(virtual_amiibo->GetEngineName(), | ||
| 96 | virtual_amiibo_input_factory); | ||
| 97 | Common::Input::RegisterFactory<Common::Input::OutputDevice>(virtual_amiibo->GetEngineName(), | ||
| 98 | virtual_amiibo_output_factory); | ||
| 99 | |||
| 90 | #ifdef HAVE_SDL2 | 100 | #ifdef HAVE_SDL2 |
| 91 | sdl = std::make_shared<SDLDriver>("sdl"); | 101 | sdl = std::make_shared<SDLDriver>("sdl"); |
| 92 | sdl->SetMappingCallback(mapping_callback); | 102 | sdl->SetMappingCallback(mapping_callback); |
| @@ -327,6 +337,7 @@ struct InputSubsystem::Impl { | |||
| 327 | std::shared_ptr<TasInput::Tas> tas_input; | 337 | std::shared_ptr<TasInput::Tas> tas_input; |
| 328 | std::shared_ptr<CemuhookUDP::UDPClient> udp_client; | 338 | std::shared_ptr<CemuhookUDP::UDPClient> udp_client; |
| 329 | std::shared_ptr<Camera> camera; | 339 | std::shared_ptr<Camera> camera; |
| 340 | std::shared_ptr<VirtualAmiibo> virtual_amiibo; | ||
| 330 | 341 | ||
| 331 | std::shared_ptr<InputFactory> keyboard_factory; | 342 | std::shared_ptr<InputFactory> keyboard_factory; |
| 332 | std::shared_ptr<InputFactory> mouse_factory; | 343 | std::shared_ptr<InputFactory> mouse_factory; |
| @@ -335,6 +346,7 @@ struct InputSubsystem::Impl { | |||
| 335 | std::shared_ptr<InputFactory> udp_client_input_factory; | 346 | std::shared_ptr<InputFactory> udp_client_input_factory; |
| 336 | std::shared_ptr<InputFactory> tas_input_factory; | 347 | std::shared_ptr<InputFactory> tas_input_factory; |
| 337 | std::shared_ptr<InputFactory> camera_input_factory; | 348 | std::shared_ptr<InputFactory> camera_input_factory; |
| 349 | std::shared_ptr<InputFactory> virtual_amiibo_input_factory; | ||
| 338 | 350 | ||
| 339 | std::shared_ptr<OutputFactory> keyboard_output_factory; | 351 | std::shared_ptr<OutputFactory> keyboard_output_factory; |
| 340 | std::shared_ptr<OutputFactory> mouse_output_factory; | 352 | std::shared_ptr<OutputFactory> mouse_output_factory; |
| @@ -342,6 +354,7 @@ struct InputSubsystem::Impl { | |||
| 342 | std::shared_ptr<OutputFactory> udp_client_output_factory; | 354 | std::shared_ptr<OutputFactory> udp_client_output_factory; |
| 343 | std::shared_ptr<OutputFactory> tas_output_factory; | 355 | std::shared_ptr<OutputFactory> tas_output_factory; |
| 344 | std::shared_ptr<OutputFactory> camera_output_factory; | 356 | std::shared_ptr<OutputFactory> camera_output_factory; |
| 357 | std::shared_ptr<OutputFactory> virtual_amiibo_output_factory; | ||
| 345 | 358 | ||
| 346 | #ifdef HAVE_SDL2 | 359 | #ifdef HAVE_SDL2 |
| 347 | std::shared_ptr<SDLDriver> sdl; | 360 | std::shared_ptr<SDLDriver> sdl; |
| @@ -402,6 +415,14 @@ const Camera* InputSubsystem::GetCamera() const { | |||
| 402 | return impl->camera.get(); | 415 | return impl->camera.get(); |
| 403 | } | 416 | } |
| 404 | 417 | ||
| 418 | VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() { | ||
| 419 | return impl->virtual_amiibo.get(); | ||
| 420 | } | ||
| 421 | |||
| 422 | const VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() const { | ||
| 423 | return impl->virtual_amiibo.get(); | ||
| 424 | } | ||
| 425 | |||
| 405 | std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { | 426 | std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const { |
| 406 | return impl->GetInputDevices(); | 427 | return impl->GetInputDevices(); |
| 407 | } | 428 | } |
diff --git a/src/input_common/main.h b/src/input_common/main.h index 9a969e747..ced252383 100644 --- a/src/input_common/main.h +++ b/src/input_common/main.h | |||
| @@ -33,6 +33,7 @@ class Camera; | |||
| 33 | class Keyboard; | 33 | class Keyboard; |
| 34 | class Mouse; | 34 | class Mouse; |
| 35 | class TouchScreen; | 35 | class TouchScreen; |
| 36 | class VirtualAmiibo; | ||
| 36 | struct MappingData; | 37 | struct MappingData; |
| 37 | } // namespace InputCommon | 38 | } // namespace InputCommon |
| 38 | 39 | ||
| @@ -101,6 +102,12 @@ public: | |||
| 101 | /// Retrieves the underlying camera input device. | 102 | /// Retrieves the underlying camera input device. |
| 102 | [[nodiscard]] const Camera* GetCamera() const; | 103 | [[nodiscard]] const Camera* GetCamera() const; |
| 103 | 104 | ||
| 105 | /// Retrieves the underlying virtual amiibo input device. | ||
| 106 | [[nodiscard]] VirtualAmiibo* GetVirtualAmiibo(); | ||
| 107 | |||
| 108 | /// Retrieves the underlying virtual amiibo input device. | ||
| 109 | [[nodiscard]] const VirtualAmiibo* GetVirtualAmiibo() const; | ||
| 110 | |||
| 104 | /** | 111 | /** |
| 105 | * Returns all available input devices that this Factory can create a new device with. | 112 | * Returns all available input devices that this Factory can create a new device with. |
| 106 | * Each returned ParamPackage should have a `display` field used for display, a `engine` field | 113 | * Each returned ParamPackage should have a `display` field used for display, a `engine` field |