From ed5fa10e9729cf55205533f62a428e646aa5ed7c Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Tue, 20 Dec 2022 13:23:31 -0600 Subject: core: hid: Enable pulling color data from controllers --- src/input_common/drivers/joycon.cpp | 11 +++++- src/input_common/input_engine.cpp | 37 ++++++++++++++++++++ src/input_common/input_engine.h | 6 ++++ src/input_common/input_poller.cpp | 67 +++++++++++++++++++++++++++++++++++++ src/input_common/input_poller.h | 11 ++++++ 5 files changed, 131 insertions(+), 1 deletion(-) (limited to 'src/input_common') diff --git a/src/input_common/drivers/joycon.cpp b/src/input_common/drivers/joycon.cpp index 1fca11d34..c6f78c989 100644 --- a/src/input_common/drivers/joycon.cpp +++ b/src/input_common/drivers/joycon.cpp @@ -335,7 +335,16 @@ void Joycons::OnBatteryUpdate(std::size_t port, Joycon::ControllerType type, } void Joycons::OnColorUpdate(std::size_t port, Joycon::ControllerType type, - const Joycon::Color& value) {} + const Joycon::Color& value) { + const auto identifier = GetIdentifier(port, type); + Common::Input::BodyColorStatus color{ + .body = value.body, + .buttons = value.buttons, + .left_grip = value.left_grip, + .right_grip = value.right_grip, + }; + SetColor(identifier, color); +} void Joycons::OnButtonUpdate(std::size_t port, Joycon::ControllerType type, int id, bool value) { const auto identifier = GetIdentifier(port, type); diff --git a/src/input_common/input_engine.cpp b/src/input_common/input_engine.cpp index 61cfd0911..91aa96aa7 100644 --- a/src/input_common/input_engine.cpp +++ b/src/input_common/input_engine.cpp @@ -79,6 +79,17 @@ void InputEngine::SetBattery(const PadIdentifier& identifier, Common::Input::Bat TriggerOnBatteryChange(identifier, value); } +void InputEngine::SetColor(const PadIdentifier& identifier, Common::Input::BodyColorStatus value) { + { + std::scoped_lock lock{mutex}; + ControllerData& controller = controller_list.at(identifier); + if (!configuring) { + controller.color = value; + } + } + TriggerOnColorChange(identifier, value); +} + void InputEngine::SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value) { { std::scoped_lock lock{mutex}; @@ -176,6 +187,18 @@ Common::Input::BatteryLevel InputEngine::GetBattery(const PadIdentifier& identif return controller.battery; } +Common::Input::BodyColorStatus InputEngine::GetColor(const PadIdentifier& identifier) const { + std::scoped_lock lock{mutex}; + const auto controller_iter = controller_list.find(identifier); + if (controller_iter == controller_list.cend()) { + LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.RawString(), + identifier.pad, identifier.port); + return {}; + } + const ControllerData& controller = controller_iter->second; + return controller.color; +} + BasicMotion InputEngine::GetMotion(const PadIdentifier& identifier, int motion) const { std::scoped_lock lock{mutex}; const auto controller_iter = controller_list.find(identifier); @@ -328,6 +351,20 @@ void InputEngine::TriggerOnBatteryChange(const PadIdentifier& identifier, } } +void InputEngine::TriggerOnColorChange(const PadIdentifier& identifier, + [[maybe_unused]] Common::Input::BodyColorStatus value) { + std::scoped_lock lock{mutex_callback}; + for (const auto& poller_pair : callback_list) { + const InputIdentifier& poller = poller_pair.second; + if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Color, 0)) { + continue; + } + if (poller.callback.on_change) { + poller.callback.on_change(); + } + } +} + void InputEngine::TriggerOnMotionChange(const PadIdentifier& identifier, int motion, const BasicMotion& value) { std::scoped_lock lock{mutex_callback}; diff --git a/src/input_common/input_engine.h b/src/input_common/input_engine.h index 6cbcf5207..6301c5719 100644 --- a/src/input_common/input_engine.h +++ b/src/input_common/input_engine.h @@ -40,6 +40,7 @@ enum class EngineInputType { Battery, Button, Camera, + Color, HatButton, Motion, Nfc, @@ -199,6 +200,7 @@ public: bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const; f32 GetAxis(const PadIdentifier& identifier, int axis) const; Common::Input::BatteryLevel GetBattery(const PadIdentifier& identifier) const; + Common::Input::BodyColorStatus GetColor(const PadIdentifier& identifier) const; BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const; Common::Input::CameraStatus GetCamera(const PadIdentifier& identifier) const; Common::Input::NfcStatus GetNfc(const PadIdentifier& identifier) const; @@ -212,6 +214,7 @@ protected: void SetHatButton(const PadIdentifier& identifier, int button, u8 value); void SetAxis(const PadIdentifier& identifier, int axis, f32 value); void SetBattery(const PadIdentifier& identifier, Common::Input::BatteryLevel value); + void SetColor(const PadIdentifier& identifier, Common::Input::BodyColorStatus value); void SetMotion(const PadIdentifier& identifier, int motion, const BasicMotion& value); void SetCamera(const PadIdentifier& identifier, const Common::Input::CameraStatus& value); void SetNfc(const PadIdentifier& identifier, const Common::Input::NfcStatus& value); @@ -227,6 +230,7 @@ private: std::unordered_map axes; std::unordered_map motions; Common::Input::BatteryLevel battery{}; + Common::Input::BodyColorStatus color{}; Common::Input::CameraStatus camera{}; Common::Input::NfcStatus nfc{}; }; @@ -235,6 +239,8 @@ private: void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value); void TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value); void TriggerOnBatteryChange(const PadIdentifier& identifier, Common::Input::BatteryLevel value); + void TriggerOnColorChange(const PadIdentifier& identifier, + Common::Input::BodyColorStatus value); void TriggerOnMotionChange(const PadIdentifier& identifier, int motion, const BasicMotion& value); void TriggerOnCameraChange(const PadIdentifier& identifier, diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp index fb8be42e2..368ffbdd5 100644 --- a/src/input_common/input_poller.cpp +++ b/src/input_common/input_poller.cpp @@ -498,6 +498,58 @@ private: InputEngine* input_engine; }; +class InputFromColor final : public Common::Input::InputDevice { +public: + explicit InputFromColor(PadIdentifier identifier_, InputEngine* input_engine_) + : identifier(identifier_), input_engine(input_engine_) { + UpdateCallback engine_callback{[this]() { OnChange(); }}; + const InputIdentifier input_identifier{ + .identifier = identifier, + .type = EngineInputType::Color, + .index = 0, + .callback = engine_callback, + }; + last_color_value = {}; + callback_key = input_engine->SetCallback(input_identifier); + } + + ~InputFromColor() override { + input_engine->DeleteCallback(callback_key); + } + + Common::Input::BodyColorStatus GetStatus() const { + return input_engine->GetColor(identifier); + } + + void ForceUpdate() override { + const Common::Input::CallbackStatus status{ + .type = Common::Input::InputType::Color, + .color_status = GetStatus(), + }; + + last_color_value = status.color_status; + TriggerOnChange(status); + } + + void OnChange() { + const Common::Input::CallbackStatus status{ + .type = Common::Input::InputType::Color, + .color_status = GetStatus(), + }; + + if (status.color_status.body != last_color_value.body) { + last_color_value = status.color_status; + TriggerOnChange(status); + } + } + +private: + const PadIdentifier identifier; + int callback_key; + Common::Input::BodyColorStatus last_color_value; + InputEngine* input_engine; +}; + class InputFromMotion final : public Common::Input::InputDevice { public: explicit InputFromMotion(PadIdentifier identifier_, int motion_sensor_, float gyro_threshold_, @@ -966,6 +1018,18 @@ std::unique_ptr InputFactory::CreateBatteryDevice( return std::make_unique(identifier, input_engine.get()); } +std::unique_ptr InputFactory::CreateColorDevice( + const Common::ParamPackage& params) { + const PadIdentifier identifier = { + .guid = Common::UUID{params.Get("guid", "")}, + .port = static_cast(params.Get("port", 0)), + .pad = static_cast(params.Get("pad", 0)), + }; + + input_engine->PreSetController(identifier); + return std::make_unique(identifier, input_engine.get()); +} + std::unique_ptr InputFactory::CreateMotionDevice( Common::ParamPackage params) { const PadIdentifier identifier = { @@ -1053,6 +1117,9 @@ std::unique_ptr InputFactory::Create( if (params.Has("battery")) { return CreateBatteryDevice(params); } + if (params.Has("color")) { + return CreateColorDevice(params); + } if (params.Has("camera")) { return CreateCameraDevice(params); } diff --git a/src/input_common/input_poller.h b/src/input_common/input_poller.h index d7db13ce4..e097e254c 100644 --- a/src/input_common/input_poller.h +++ b/src/input_common/input_poller.h @@ -190,6 +190,17 @@ private: std::unique_ptr CreateBatteryDevice( const Common::ParamPackage& params); + /** + * Creates a color device from the parameters given. + * @param params contains parameters for creating the device: + * - "guid": text string for identifying controllers + * - "port": port of the connected device + * - "pad": slot of the connected controller + * @returns a unique input device with the parameters specified + */ + std::unique_ptr CreateColorDevice( + const Common::ParamPackage& params); + /** * Creates a motion device from the parameters given. * @param params contains parameters for creating the device: -- cgit v1.2.3