diff options
20 files changed, 312 insertions, 144 deletions
diff --git a/src/common/input.h b/src/common/input.h index 6eefc55f9..3a28b77a7 100644 --- a/src/common/input.h +++ b/src/common/input.h | |||
| @@ -38,6 +38,27 @@ enum class BatteryLevel { | |||
| 38 | Charging, | 38 | Charging, |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | enum class PollingMode { | ||
| 42 | Active, | ||
| 43 | Pasive, | ||
| 44 | Camera, | ||
| 45 | NCF, | ||
| 46 | IR, | ||
| 47 | }; | ||
| 48 | |||
| 49 | enum class VibrationError { | ||
| 50 | None, | ||
| 51 | NotSupported, | ||
| 52 | Disabled, | ||
| 53 | Unknown, | ||
| 54 | }; | ||
| 55 | |||
| 56 | enum class PollingError { | ||
| 57 | None, | ||
| 58 | NotSupported, | ||
| 59 | Unknown, | ||
| 60 | }; | ||
| 61 | |||
| 41 | struct AnalogProperties { | 62 | struct AnalogProperties { |
| 42 | float deadzone{}; | 63 | float deadzone{}; |
| 43 | float range{1.0f}; | 64 | float range{1.0f}; |
| @@ -149,6 +170,24 @@ private: | |||
| 149 | InputCallback callback; | 170 | InputCallback callback; |
| 150 | }; | 171 | }; |
| 151 | 172 | ||
| 173 | /// An abstract class template for an output device (rumble, LED pattern, polling mode). | ||
| 174 | class OutputDevice { | ||
| 175 | public: | ||
| 176 | virtual ~OutputDevice() = default; | ||
| 177 | |||
| 178 | virtual void SetLED([[maybe_unused]] LedStatus led_status) { | ||
| 179 | return; | ||
| 180 | } | ||
| 181 | |||
| 182 | virtual VibrationError SetVibration([[maybe_unused]] VibrationStatus vibration_status) { | ||
| 183 | return VibrationError::NotSupported; | ||
| 184 | } | ||
| 185 | |||
| 186 | virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) { | ||
| 187 | return PollingError::NotSupported; | ||
| 188 | } | ||
| 189 | }; | ||
| 190 | |||
| 152 | /// An abstract class template for a factory that can create input devices. | 191 | /// An abstract class template for a factory that can create input devices. |
| 153 | template <typename InputDeviceType> | 192 | template <typename InputDeviceType> |
| 154 | class Factory { | 193 | class Factory { |
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 4eb5d99bc..b9d16657a 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp | |||
| @@ -66,12 +66,32 @@ void EmulatedController::ReloadFromSettings() { | |||
| 66 | for (std::size_t index = 0; index < player.motions.size(); ++index) { | 66 | for (std::size_t index = 0; index < player.motions.size(); ++index) { |
| 67 | motion_params[index] = Common::ParamPackage(player.motions[index]); | 67 | motion_params[index] = Common::ParamPackage(player.motions[index]); |
| 68 | } | 68 | } |
| 69 | |||
| 70 | controller.colors_state.left = { | ||
| 71 | .body = player.body_color_left, | ||
| 72 | .button = player.button_color_left, | ||
| 73 | }; | ||
| 74 | |||
| 75 | controller.colors_state.right = { | ||
| 76 | .body = player.body_color_right, | ||
| 77 | .button = player.button_color_right, | ||
| 78 | }; | ||
| 79 | |||
| 80 | controller.colors_state.fullkey = controller.colors_state.left; | ||
| 81 | |||
| 82 | SetNpadType(MapSettingsTypeToNPad(player.controller_type)); | ||
| 83 | |||
| 84 | if (player.connected) { | ||
| 85 | Connect(); | ||
| 86 | } else { | ||
| 87 | Disconnect(); | ||
| 88 | } | ||
| 89 | |||
| 69 | ReloadInput(); | 90 | ReloadInput(); |
| 70 | } | 91 | } |
| 71 | 92 | ||
| 72 | void EmulatedController::ReloadInput() { | 93 | void EmulatedController::ReloadInput() { |
| 73 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | 94 | const auto player_index = NpadIdTypeToIndex(npad_id_type); |
| 74 | const auto& player = Settings::values.players.GetValue()[player_index]; | ||
| 75 | const auto left_side = button_params[Settings::NativeButton::ZL]; | 95 | const auto left_side = button_params[Settings::NativeButton::ZL]; |
| 76 | const auto right_side = button_params[Settings::NativeButton::ZR]; | 96 | const auto right_side = button_params[Settings::NativeButton::ZR]; |
| 77 | 97 | ||
| @@ -90,21 +110,13 @@ void EmulatedController::ReloadInput() { | |||
| 90 | trigger_devices[1] = | 110 | trigger_devices[1] = |
| 91 | Input::CreateDevice<Input::InputDevice>(button_params[Settings::NativeButton::ZR]); | 111 | Input::CreateDevice<Input::InputDevice>(button_params[Settings::NativeButton::ZR]); |
| 92 | 112 | ||
| 93 | controller.colors_state.left = { | ||
| 94 | .body = player.body_color_left, | ||
| 95 | .button = player.button_color_left, | ||
| 96 | }; | ||
| 97 | |||
| 98 | controller.colors_state.right = { | ||
| 99 | .body = player.body_color_right, | ||
| 100 | .button = player.button_color_right, | ||
| 101 | }; | ||
| 102 | |||
| 103 | controller.colors_state.fullkey = controller.colors_state.left; | ||
| 104 | |||
| 105 | battery_devices[0] = Input::CreateDevice<Input::InputDevice>(left_side); | 113 | battery_devices[0] = Input::CreateDevice<Input::InputDevice>(left_side); |
| 106 | battery_devices[1] = Input::CreateDevice<Input::InputDevice>(right_side); | 114 | battery_devices[1] = Input::CreateDevice<Input::InputDevice>(right_side); |
| 107 | 115 | ||
| 116 | button_params[Settings::NativeButton::ZL].Set("output",true); | ||
| 117 | output_devices[0] = | ||
| 118 | Input::CreateDevice<Input::OutputDevice>(button_params[Settings::NativeButton::ZL]); | ||
| 119 | |||
| 108 | for (std::size_t index = 0; index < button_devices.size(); ++index) { | 120 | for (std::size_t index = 0; index < button_devices.size(); ++index) { |
| 109 | if (!button_devices[index]) { | 121 | if (!button_devices[index]) { |
| 110 | continue; | 122 | continue; |
| @@ -149,14 +161,6 @@ void EmulatedController::ReloadInput() { | |||
| 149 | [this, index](Input::CallbackStatus callback) { SetMotion(callback, index); }}; | 161 | [this, index](Input::CallbackStatus callback) { SetMotion(callback, index); }}; |
| 150 | motion_devices[index]->SetCallback(motion_callback); | 162 | motion_devices[index]->SetCallback(motion_callback); |
| 151 | } | 163 | } |
| 152 | |||
| 153 | SetNpadType(MapSettingsTypeToNPad(player.controller_type)); | ||
| 154 | |||
| 155 | if (player.connected) { | ||
| 156 | Connect(); | ||
| 157 | } else { | ||
| 158 | Disconnect(); | ||
| 159 | } | ||
| 160 | } | 164 | } |
| 161 | 165 | ||
| 162 | void EmulatedController::UnloadInput() { | 166 | void EmulatedController::UnloadInput() { |
| @@ -197,7 +201,8 @@ void EmulatedController::SaveCurrentConfig() { | |||
| 197 | 201 | ||
| 198 | const auto player_index = NpadIdTypeToIndex(npad_id_type); | 202 | const auto player_index = NpadIdTypeToIndex(npad_id_type); |
| 199 | auto& player = Settings::values.players.GetValue()[player_index]; | 203 | auto& player = Settings::values.players.GetValue()[player_index]; |
| 200 | 204 | player.connected = is_connected; | |
| 205 | player.controller_type = MapNPadToSettingsType(npad_type); | ||
| 201 | for (std::size_t index = 0; index < player.buttons.size(); ++index) { | 206 | for (std::size_t index = 0; index < player.buttons.size(); ++index) { |
| 202 | player.buttons[index] = button_params[index].Serialize(); | 207 | player.buttons[index] = button_params[index].Serialize(); |
| 203 | } | 208 | } |
| @@ -601,13 +606,50 @@ void EmulatedController::SetBattery(Input::CallbackStatus callback, std::size_t | |||
| 601 | TriggerOnChange(ControllerTriggerType::Battery); | 606 | TriggerOnChange(ControllerTriggerType::Battery); |
| 602 | } | 607 | } |
| 603 | 608 | ||
| 604 | bool EmulatedController::SetVibration([[maybe_unused]] std::size_t device_index, | 609 | bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { |
| 605 | [[maybe_unused]] VibrationValue vibration) { | 610 | if (!output_devices[device_index]) { |
| 606 | return false; | 611 | return false; |
| 612 | } | ||
| 613 | |||
| 614 | const Input::VibrationStatus status = { | ||
| 615 | .low_amplitude = vibration.high_amplitude, | ||
| 616 | .low_frequency = vibration.high_amplitude, | ||
| 617 | .high_amplitude = vibration.high_amplitude, | ||
| 618 | .high_frequency = vibration.high_amplitude, | ||
| 619 | }; | ||
| 620 | return output_devices[device_index]->SetVibration(status) == Input::VibrationError::None; | ||
| 621 | } | ||
| 622 | |||
| 623 | bool EmulatedController::TestVibration(std::size_t device_index) { | ||
| 624 | if (!output_devices[device_index]) { | ||
| 625 | return false; | ||
| 626 | } | ||
| 627 | |||
| 628 | // Send a slight vibration to test for rumble support | ||
| 629 | constexpr Input::VibrationStatus status = { | ||
| 630 | .low_amplitude = 0.001f, | ||
| 631 | .low_frequency = 160.0f, | ||
| 632 | .high_amplitude = 0.001f, | ||
| 633 | .high_frequency = 320.0f, | ||
| 634 | }; | ||
| 635 | return output_devices[device_index]->SetVibration(status) == Input::VibrationError::None; | ||
| 607 | } | 636 | } |
| 608 | 637 | ||
| 609 | int EmulatedController::TestVibration(std::size_t device_index) { | 638 | void EmulatedController::SetLedPattern() { |
| 610 | return 1; | 639 | for (auto& device : output_devices) { |
| 640 | if (!device) { | ||
| 641 | continue; | ||
| 642 | } | ||
| 643 | |||
| 644 | const LedPattern pattern = GetLedPattern(); | ||
| 645 | const Input::LedStatus status = { | ||
| 646 | .led_1 = pattern.position1 != 0, | ||
| 647 | .led_2 = pattern.position2 != 0, | ||
| 648 | .led_3 = pattern.position3 != 0, | ||
| 649 | .led_4 = pattern.position4 != 0, | ||
| 650 | }; | ||
| 651 | device->SetLED(status); | ||
| 652 | } | ||
| 611 | } | 653 | } |
| 612 | 654 | ||
| 613 | void EmulatedController::Connect() { | 655 | void EmulatedController::Connect() { |
| @@ -655,6 +697,29 @@ void EmulatedController::SetNpadType(NpadType npad_type_) { | |||
| 655 | TriggerOnChange(ControllerTriggerType::Type); | 697 | TriggerOnChange(ControllerTriggerType::Type); |
| 656 | } | 698 | } |
| 657 | 699 | ||
| 700 | LedPattern EmulatedController::GetLedPattern() const { | ||
| 701 | switch (npad_id_type) { | ||
| 702 | case NpadIdType::Player1: | ||
| 703 | return LedPattern{1, 0, 0, 0}; | ||
| 704 | case NpadIdType::Player2: | ||
| 705 | return LedPattern{1, 1, 0, 0}; | ||
| 706 | case NpadIdType::Player3: | ||
| 707 | return LedPattern{1, 1, 1, 0}; | ||
| 708 | case NpadIdType::Player4: | ||
| 709 | return LedPattern{1, 1, 1, 1}; | ||
| 710 | case NpadIdType::Player5: | ||
| 711 | return LedPattern{1, 0, 0, 1}; | ||
| 712 | case NpadIdType::Player6: | ||
| 713 | return LedPattern{1, 0, 1, 0}; | ||
| 714 | case NpadIdType::Player7: | ||
| 715 | return LedPattern{1, 0, 1, 1}; | ||
| 716 | case NpadIdType::Player8: | ||
| 717 | return LedPattern{0, 1, 1, 0}; | ||
| 718 | default: | ||
| 719 | return LedPattern{0, 0, 0, 0}; | ||
| 720 | } | ||
| 721 | } | ||
| 722 | |||
| 658 | ButtonValues EmulatedController::GetButtonsValues() const { | 723 | ButtonValues EmulatedController::GetButtonsValues() const { |
| 659 | return controller.button_values; | 724 | return controller.button_values; |
| 660 | } | 725 | } |
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index 94db9b00b..322d2cab0 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h | |||
| @@ -33,12 +33,14 @@ using ControllerMotionDevices = | |||
| 33 | using TriggerDevices = | 33 | using TriggerDevices = |
| 34 | std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeTrigger::NumTriggers>; | 34 | std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeTrigger::NumTriggers>; |
| 35 | using BatteryDevices = std::array<std::unique_ptr<Input::InputDevice>, 2>; | 35 | using BatteryDevices = std::array<std::unique_ptr<Input::InputDevice>, 2>; |
| 36 | using OutputDevices = std::array<std::unique_ptr<Input::OutputDevice>, 2>; | ||
| 36 | 37 | ||
| 37 | using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>; | 38 | using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>; |
| 38 | using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>; | 39 | using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>; |
| 39 | using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>; | 40 | using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>; |
| 40 | using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>; | 41 | using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>; |
| 41 | using BatteryParams = std::array<Common::ParamPackage, 2>; | 42 | using BatteryParams = std::array<Common::ParamPackage, 2>; |
| 43 | using OutputParams = std::array<Common::ParamPackage, 2>; | ||
| 42 | 44 | ||
| 43 | using ButtonValues = std::array<Input::ButtonStatus, Settings::NativeButton::NumButtons>; | 45 | using ButtonValues = std::array<Input::ButtonStatus, Settings::NativeButton::NumButtons>; |
| 44 | using SticksValues = std::array<Input::StickStatus, Settings::NativeAnalog::NumAnalogs>; | 46 | using SticksValues = std::array<Input::StickStatus, Settings::NativeAnalog::NumAnalogs>; |
| @@ -94,6 +96,7 @@ struct ControllerStatus { | |||
| 94 | ControllerColors colors_state{}; | 96 | ControllerColors colors_state{}; |
| 95 | BatteryLevelState battery_state{}; | 97 | BatteryLevelState battery_state{}; |
| 96 | }; | 98 | }; |
| 99 | |||
| 97 | enum class ControllerTriggerType { | 100 | enum class ControllerTriggerType { |
| 98 | Button, | 101 | Button, |
| 99 | Stick, | 102 | Stick, |
| @@ -137,6 +140,9 @@ public: | |||
| 137 | /// Gets the NpadType for this controller. | 140 | /// Gets the NpadType for this controller. |
| 138 | NpadType GetNpadType() const; | 141 | NpadType GetNpadType() const; |
| 139 | 142 | ||
| 143 | /// Gets the NpadType for this controller. | ||
| 144 | LedPattern GetLedPattern() const; | ||
| 145 | |||
| 140 | void Connect(); | 146 | void Connect(); |
| 141 | void Disconnect(); | 147 | void Disconnect(); |
| 142 | 148 | ||
| @@ -179,7 +185,9 @@ public: | |||
| 179 | BatteryLevelState GetBattery() const; | 185 | BatteryLevelState GetBattery() const; |
| 180 | 186 | ||
| 181 | bool SetVibration(std::size_t device_index, VibrationValue vibration); | 187 | bool SetVibration(std::size_t device_index, VibrationValue vibration); |
| 182 | int TestVibration(std::size_t device_index); | 188 | bool TestVibration(std::size_t device_index); |
| 189 | |||
| 190 | void SetLedPattern(); | ||
| 183 | 191 | ||
| 184 | int SetCallback(ControllerUpdateCallback update_callback); | 192 | int SetCallback(ControllerUpdateCallback update_callback); |
| 185 | void DeleteCallback(int key); | 193 | void DeleteCallback(int key); |
| @@ -215,13 +223,14 @@ private: | |||
| 215 | ControllerMotionParams motion_params; | 223 | ControllerMotionParams motion_params; |
| 216 | TriggerParams trigger_params; | 224 | TriggerParams trigger_params; |
| 217 | BatteryParams battery_params; | 225 | BatteryParams battery_params; |
| 226 | OutputParams output_params; | ||
| 218 | 227 | ||
| 219 | ButtonDevices button_devices; | 228 | ButtonDevices button_devices; |
| 220 | StickDevices stick_devices; | 229 | StickDevices stick_devices; |
| 221 | ControllerMotionDevices motion_devices; | 230 | ControllerMotionDevices motion_devices; |
| 222 | TriggerDevices trigger_devices; | 231 | TriggerDevices trigger_devices; |
| 223 | BatteryDevices battery_devices; | 232 | BatteryDevices battery_devices; |
| 224 | // VibrationDevices vibration_devices; | 233 | OutputDevices output_devices; |
| 225 | 234 | ||
| 226 | mutable std::mutex mutex; | 235 | mutable std::mutex mutex; |
| 227 | std::unordered_map<int, ControllerUpdateCallback> callback_list; | 236 | std::unordered_map<int, ControllerUpdateCallback> callback_list; |
diff --git a/src/core/hid/hid_types.h b/src/core/hid/hid_types.h index d3f7930c9..f12a14cb8 100644 --- a/src/core/hid/hid_types.h +++ b/src/core/hid/hid_types.h | |||
| @@ -112,6 +112,8 @@ struct NpadStyleTag { | |||
| 112 | BitField<7, 1, u32> lark; | 112 | BitField<7, 1, u32> lark; |
| 113 | BitField<8, 1, u32> handheld_lark; | 113 | BitField<8, 1, u32> handheld_lark; |
| 114 | BitField<9, 1, u32> lucia; | 114 | BitField<9, 1, u32> lucia; |
| 115 | BitField<10, 1, u32> lagoon; | ||
| 116 | BitField<11, 1, u32> lager; | ||
| 115 | BitField<29, 1, u32> system_ext; | 117 | BitField<29, 1, u32> system_ext; |
| 116 | BitField<30, 1, u32> system; | 118 | BitField<30, 1, u32> system; |
| 117 | }; | 119 | }; |
| @@ -175,6 +177,22 @@ struct NpadPowerInfo { | |||
| 175 | }; | 177 | }; |
| 176 | static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size"); | 178 | static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size"); |
| 177 | 179 | ||
| 180 | struct LedPattern { | ||
| 181 | explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) { | ||
| 182 | position1.Assign(light1); | ||
| 183 | position2.Assign(light2); | ||
| 184 | position3.Assign(light3); | ||
| 185 | position4.Assign(light4); | ||
| 186 | } | ||
| 187 | union { | ||
| 188 | u64 raw{}; | ||
| 189 | BitField<0, 1, u64> position1; | ||
| 190 | BitField<1, 1, u64> position2; | ||
| 191 | BitField<2, 1, u64> position3; | ||
| 192 | BitField<3, 1, u64> position4; | ||
| 193 | }; | ||
| 194 | }; | ||
| 195 | |||
| 178 | // This is nn::hid::NpadButton | 196 | // This is nn::hid::NpadButton |
| 179 | enum class NpadButton : u64 { | 197 | enum class NpadButton : u64 { |
| 180 | None = 0, | 198 | None = 0, |
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 03cbd42f4..a2e9ddf4d 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -796,7 +796,7 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(std::size_t npad_index, | |||
| 796 | } | 796 | } |
| 797 | 797 | ||
| 798 | controller.vibration[device_index].device_mounted = | 798 | controller.vibration[device_index].device_mounted = |
| 799 | controller.device->TestVibration(device_index) == 1; | 799 | controller.device->TestVibration(device_index); |
| 800 | } | 800 | } |
| 801 | 801 | ||
| 802 | void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { | 802 | void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { |
| @@ -954,31 +954,12 @@ bool Controller_NPad::SwapNpadAssignment(u32 npad_id_1, u32 npad_id_2) { | |||
| 954 | return true; | 954 | return true; |
| 955 | } | 955 | } |
| 956 | 956 | ||
| 957 | Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { | 957 | Core::HID::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { |
| 958 | if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) { | 958 | if (npad_id == npad_id_list.back() || npad_id == npad_id_list[npad_id_list.size() - 2]) { |
| 959 | // These are controllers without led patterns | 959 | // These are controllers without led patterns |
| 960 | return LedPattern{0, 0, 0, 0}; | 960 | return Core::HID::LedPattern{0, 0, 0, 0}; |
| 961 | } | ||
| 962 | switch (npad_id) { | ||
| 963 | case 0: | ||
| 964 | return LedPattern{1, 0, 0, 0}; | ||
| 965 | case 1: | ||
| 966 | return LedPattern{1, 1, 0, 0}; | ||
| 967 | case 2: | ||
| 968 | return LedPattern{1, 1, 1, 0}; | ||
| 969 | case 3: | ||
| 970 | return LedPattern{1, 1, 1, 1}; | ||
| 971 | case 4: | ||
| 972 | return LedPattern{1, 0, 0, 1}; | ||
| 973 | case 5: | ||
| 974 | return LedPattern{1, 0, 1, 0}; | ||
| 975 | case 6: | ||
| 976 | return LedPattern{1, 0, 1, 1}; | ||
| 977 | case 7: | ||
| 978 | return LedPattern{0, 1, 1, 0}; | ||
| 979 | default: | ||
| 980 | return LedPattern{0, 0, 0, 0}; | ||
| 981 | } | 961 | } |
| 962 | return controller_data[npad_id].device->GetLedPattern(); | ||
| 982 | } | 963 | } |
| 983 | 964 | ||
| 984 | bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const { | 965 | bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const { |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 483cae5b6..b0e2f8430 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -115,22 +115,6 @@ public: | |||
| 115 | .freq_high = 320.0f, | 115 | .freq_high = 320.0f, |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | struct LedPattern { | ||
| 119 | explicit LedPattern(u64 light1, u64 light2, u64 light3, u64 light4) { | ||
| 120 | position1.Assign(light1); | ||
| 121 | position2.Assign(light2); | ||
| 122 | position3.Assign(light3); | ||
| 123 | position4.Assign(light4); | ||
| 124 | } | ||
| 125 | union { | ||
| 126 | u64 raw{}; | ||
| 127 | BitField<0, 1, u64> position1; | ||
| 128 | BitField<1, 1, u64> position2; | ||
| 129 | BitField<2, 1, u64> position3; | ||
| 130 | BitField<3, 1, u64> position4; | ||
| 131 | }; | ||
| 132 | }; | ||
| 133 | |||
| 134 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); | 118 | void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set); |
| 135 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; | 119 | Core::HID::NpadStyleTag GetSupportedStyleSet() const; |
| 136 | 120 | ||
| @@ -186,7 +170,7 @@ public: | |||
| 186 | void SetSixAxisFusionParameters(f32 parameter1, f32 parameter2); | 170 | void SetSixAxisFusionParameters(f32 parameter1, f32 parameter2); |
| 187 | std::pair<f32, f32> GetSixAxisFusionParameters(); | 171 | std::pair<f32, f32> GetSixAxisFusionParameters(); |
| 188 | void ResetSixAxisFusionParameters(); | 172 | void ResetSixAxisFusionParameters(); |
| 189 | LedPattern GetLedPattern(u32 npad_id); | 173 | Core::HID::LedPattern GetLedPattern(u32 npad_id); |
| 190 | bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const; | 174 | bool IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const; |
| 191 | void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id); | 175 | void SetUnintendedHomeButtonInputProtectionEnabled(bool is_protection_enabled, u32 npad_id); |
| 192 | void SetAnalogStickUseCenterClamp(bool use_center_clamp); | 176 | void SetAnalogStickUseCenterClamp(bool use_center_clamp); |
diff --git a/src/input_common/drivers/gc_adapter.cpp b/src/input_common/drivers/gc_adapter.cpp index 6721ba4f7..2aa5a16a6 100644 --- a/src/input_common/drivers/gc_adapter.cpp +++ b/src/input_common/drivers/gc_adapter.cpp | |||
| @@ -322,13 +322,17 @@ bool GCAdapter::GetGCEndpoint(libusb_device* device) { | |||
| 322 | return true; | 322 | return true; |
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | bool GCAdapter::SetRumble(const PadIdentifier& identifier, const Input::VibrationStatus vibration) { | 325 | Input::VibrationError GCAdapter::SetRumble(const PadIdentifier& identifier, const Input::VibrationStatus vibration) { |
| 326 | const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f; | 326 | const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f; |
| 327 | const auto processed_amplitude = | 327 | const auto processed_amplitude = |
| 328 | static_cast<u8>((mean_amplitude + std::pow(mean_amplitude, 0.3f)) * 0.5f * 0x8); | 328 | static_cast<u8>((mean_amplitude + std::pow(mean_amplitude, 0.3f)) * 0.5f * 0x8); |
| 329 | 329 | ||
| 330 | pads[identifier.port].rumble_amplitude = processed_amplitude; | 330 | pads[identifier.port].rumble_amplitude = processed_amplitude; |
| 331 | return rumble_enabled; | 331 | |
| 332 | if (!rumble_enabled) { | ||
| 333 | return Input::VibrationError::Disabled; | ||
| 334 | } | ||
| 335 | return Input::VibrationError::None; | ||
| 332 | } | 336 | } |
| 333 | 337 | ||
| 334 | void GCAdapter::UpdateVibrations() { | 338 | void GCAdapter::UpdateVibrations() { |
diff --git a/src/input_common/drivers/gc_adapter.h b/src/input_common/drivers/gc_adapter.h index c0bf1ed7a..dd23dd9f3 100644 --- a/src/input_common/drivers/gc_adapter.h +++ b/src/input_common/drivers/gc_adapter.h | |||
| @@ -24,7 +24,7 @@ public: | |||
| 24 | explicit GCAdapter(const std::string input_engine_); | 24 | explicit GCAdapter(const std::string input_engine_); |
| 25 | ~GCAdapter(); | 25 | ~GCAdapter(); |
| 26 | 26 | ||
| 27 | bool SetRumble(const PadIdentifier& identifier, | 27 | Input::VibrationError SetRumble(const PadIdentifier& identifier, |
| 28 | const Input::VibrationStatus vibration) override; | 28 | const Input::VibrationStatus vibration) override; |
| 29 | 29 | ||
| 30 | /// Used for automapping features | 30 | /// Used for automapping features |
diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index efb4a2106..f7f03c5f2 100644 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp | |||
| @@ -506,7 +506,8 @@ std::vector<Common::ParamPackage> SDLDriver::GetInputDevices() const { | |||
| 506 | } | 506 | } |
| 507 | return devices; | 507 | return devices; |
| 508 | } | 508 | } |
| 509 | bool SDLDriver::SetRumble(const PadIdentifier& identifier, const Input::VibrationStatus vibration) { | 509 | Input::VibrationError SDLDriver::SetRumble(const PadIdentifier& identifier, |
| 510 | const Input::VibrationStatus vibration) { | ||
| 510 | const auto joystick = | 511 | const auto joystick = |
| 511 | GetSDLJoystickByGUID(identifier.guid.Format(), static_cast<int>(identifier.port)); | 512 | GetSDLJoystickByGUID(identifier.guid.Format(), static_cast<int>(identifier.port)); |
| 512 | const auto process_amplitude = [](f32 amplitude) { | 513 | const auto process_amplitude = [](f32 amplitude) { |
| @@ -519,7 +520,10 @@ bool SDLDriver::SetRumble(const PadIdentifier& identifier, const Input::Vibratio | |||
| 519 | .high_frequency = vibration.high_frequency, | 520 | .high_frequency = vibration.high_frequency, |
| 520 | }; | 521 | }; |
| 521 | 522 | ||
| 522 | return joystick->RumblePlay(new_vibration); | 523 | if (!joystick->RumblePlay(new_vibration)) { |
| 524 | return Input::VibrationError::Unknown; | ||
| 525 | } | ||
| 526 | return Input::VibrationError::None; | ||
| 523 | } | 527 | } |
| 524 | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, | 528 | Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, |
| 525 | s32 axis, float value) const { | 529 | s32 axis, float value) const { |
diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index d8d350184..f66b33c77 100644 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h | |||
| @@ -58,7 +58,7 @@ public: | |||
| 58 | std::string GetHatButtonName(u8 direction_value) const override; | 58 | std::string GetHatButtonName(u8 direction_value) const override; |
| 59 | u8 GetHatButtonId(const std::string direction_name) const override; | 59 | u8 GetHatButtonId(const std::string direction_name) const override; |
| 60 | 60 | ||
| 61 | bool SetRumble(const PadIdentifier& identifier, | 61 | Input::VibrationError SetRumble(const PadIdentifier& identifier, |
| 62 | const Input::VibrationStatus vibration) override; | 62 | const Input::VibrationStatus vibration) override; |
| 63 | 63 | ||
| 64 | private: | 64 | private: |
diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp index 38f150746..89ba4aeb1 100644 --- a/src/input_common/helpers/stick_from_buttons.cpp +++ b/src/input_common/helpers/stick_from_buttons.cpp | |||
| @@ -251,7 +251,8 @@ private: | |||
| 251 | std::chrono::time_point<std::chrono::steady_clock> last_update; | 251 | std::chrono::time_point<std::chrono::steady_clock> last_update; |
| 252 | }; | 252 | }; |
| 253 | 253 | ||
| 254 | std::unique_ptr<Input::InputDevice> StickFromButton::Create(const Common::ParamPackage& params) { | 254 | std::unique_ptr<Input::InputDevice> StickFromButton::Create( |
| 255 | const Common::ParamPackage& params) { | ||
| 255 | const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); | 256 | const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); |
| 256 | auto up = Input::CreateDeviceFromString<Input::InputDevice>(params.Get("up", null_engine)); | 257 | auto up = Input::CreateDeviceFromString<Input::InputDevice>(params.Get("up", null_engine)); |
| 257 | auto down = Input::CreateDeviceFromString<Input::InputDevice>(params.Get("down", null_engine)); | 258 | auto down = Input::CreateDeviceFromString<Input::InputDevice>(params.Get("down", null_engine)); |
diff --git a/src/input_common/helpers/stick_from_buttons.h b/src/input_common/helpers/stick_from_buttons.h index 1d6e24c98..87165e022 100644 --- a/src/input_common/helpers/stick_from_buttons.h +++ b/src/input_common/helpers/stick_from_buttons.h | |||
| @@ -25,7 +25,8 @@ public: | |||
| 25 | * - "modifier": a serialized ParamPackage for creating a button device as the modifier | 25 | * - "modifier": a serialized ParamPackage for creating a button device as the modifier |
| 26 | * - "modifier_scale": a float for the multiplier the modifier gives to the position | 26 | * - "modifier_scale": a float for the multiplier the modifier gives to the position |
| 27 | */ | 27 | */ |
| 28 | std::unique_ptr<Input::InputDevice> Create(const Common::ParamPackage& params) override; | 28 | std::unique_ptr<Input::InputDevice> Create( |
| 29 | const Common::ParamPackage& params) override; | ||
| 29 | }; | 30 | }; |
| 30 | 31 | ||
| 31 | } // namespace InputCommon | 32 | } // namespace InputCommon |
diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp index 2abfaf841..6c9046ffb 100644 --- a/src/input_common/helpers/touch_from_buttons.cpp +++ b/src/input_common/helpers/touch_from_buttons.cpp | |||
| @@ -57,7 +57,9 @@ private: | |||
| 57 | const Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; | 57 | const Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false}; |
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | std::unique_ptr<Input::InputDevice> TouchFromButton::Create(const Common::ParamPackage& params) { | 60 | |
| 61 | std::unique_ptr<Input::InputDevice> TouchFromButton::Create( | ||
| 62 | const Common::ParamPackage& params) { | ||
| 61 | const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); | 63 | const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); |
| 62 | auto button = | 64 | auto button = |
| 63 | Input::CreateDeviceFromString<Input::InputDevice>(params.Get("button", null_engine)); | 65 | Input::CreateDeviceFromString<Input::InputDevice>(params.Get("button", null_engine)); |
diff --git a/src/input_common/input_engine.h b/src/input_common/input_engine.h index 86a8e00d8..8a953c382 100644 --- a/src/input_common/input_engine.h +++ b/src/input_common/input_engine.h | |||
| @@ -114,18 +114,24 @@ public: | |||
| 114 | // Disable configuring mode for mapping | 114 | // Disable configuring mode for mapping |
| 115 | void EndConfiguration(); | 115 | void EndConfiguration(); |
| 116 | 116 | ||
| 117 | // Sets rumble to a controller | ||
| 118 | virtual bool SetRumble([[maybe_unused]] const PadIdentifier& identifier, | ||
| 119 | [[maybe_unused]] const Input::VibrationStatus vibration) { | ||
| 120 | return false; | ||
| 121 | } | ||
| 122 | |||
| 123 | // Sets a led pattern for a controller | 117 | // Sets a led pattern for a controller |
| 124 | virtual void SetLeds([[maybe_unused]] const PadIdentifier& identifier, | 118 | virtual void SetLeds([[maybe_unused]] const PadIdentifier& identifier, |
| 125 | [[maybe_unused]] const Input::LedStatus led_status) { | 119 | [[maybe_unused]] const Input::LedStatus led_status) { |
| 126 | return; | 120 | return; |
| 127 | } | 121 | } |
| 128 | 122 | ||
| 123 | // Sets rumble to a controller | ||
| 124 | virtual Input::VibrationError SetRumble([[maybe_unused]] const PadIdentifier& identifier, | ||
| 125 | [[maybe_unused]] const Input::VibrationStatus vibration) { | ||
| 126 | return Input::VibrationError::NotSupported; | ||
| 127 | } | ||
| 128 | |||
| 129 | // Sets polling mode to a controller | ||
| 130 | virtual Input::PollingError SetPollingMode([[maybe_unused]] const PadIdentifier& identifier, | ||
| 131 | [[maybe_unused]] const Input::PollingMode vibration) { | ||
| 132 | return Input::PollingError::NotSupported; | ||
| 133 | } | ||
| 134 | |||
| 129 | // Returns the engine name | 135 | // Returns the engine name |
| 130 | [[nodiscard]] const std::string& GetEngineName() const; | 136 | [[nodiscard]] const std::string& GetEngineName() const; |
| 131 | 137 | ||
diff --git a/src/input_common/input_poller.cpp b/src/input_common/input_poller.cpp index 46a7dd276..781012886 100644 --- a/src/input_common/input_poller.cpp +++ b/src/input_common/input_poller.cpp | |||
| @@ -592,6 +592,28 @@ private: | |||
| 592 | InputEngine* input_engine; | 592 | InputEngine* input_engine; |
| 593 | }; | 593 | }; |
| 594 | 594 | ||
| 595 | class OutputFromIdentifier final : public Input::OutputDevice { | ||
| 596 | public: | ||
| 597 | explicit OutputFromIdentifier(PadIdentifier identifier_, InputEngine* input_engine_) | ||
| 598 | : identifier(identifier_), input_engine(input_engine_) {} | ||
| 599 | |||
| 600 | virtual void SetLED( Input::LedStatus led_status) { | ||
| 601 | input_engine->SetLeds(identifier, led_status); | ||
| 602 | } | ||
| 603 | |||
| 604 | virtual Input::VibrationError SetVibration(Input::VibrationStatus vibration_status) { | ||
| 605 | return input_engine->SetRumble(identifier, vibration_status); | ||
| 606 | } | ||
| 607 | |||
| 608 | virtual Input::PollingError SetPollingMode(Input::PollingMode polling_mode) { | ||
| 609 | return input_engine->SetPollingMode(identifier, polling_mode); | ||
| 610 | } | ||
| 611 | |||
| 612 | private: | ||
| 613 | const PadIdentifier identifier; | ||
| 614 | InputEngine* input_engine; | ||
| 615 | }; | ||
| 616 | |||
| 595 | std::unique_ptr<Input::InputDevice> InputFactory::CreateButtonDevice( | 617 | std::unique_ptr<Input::InputDevice> InputFactory::CreateButtonDevice( |
| 596 | const Common::ParamPackage& params) { | 618 | const Common::ParamPackage& params) { |
| 597 | const PadIdentifier identifier = { | 619 | const PadIdentifier identifier = { |
| @@ -825,7 +847,8 @@ std::unique_ptr<Input::InputDevice> InputFactory::CreateMotionDevice(Common::Par | |||
| 825 | InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_) | 847 | InputFactory::InputFactory(std::shared_ptr<InputEngine> input_engine_) |
| 826 | : input_engine(std::move(input_engine_)) {} | 848 | : input_engine(std::move(input_engine_)) {} |
| 827 | 849 | ||
| 828 | std::unique_ptr<Input::InputDevice> InputFactory::Create(const Common::ParamPackage& params) { | 850 | std::unique_ptr<Input::InputDevice> InputFactory::Create( |
| 851 | const Common::ParamPackage& params) { | ||
| 829 | if (params.Has("button") && params.Has("axis")) { | 852 | if (params.Has("button") && params.Has("axis")) { |
| 830 | return CreateTriggerDevice(params); | 853 | return CreateTriggerDevice(params); |
| 831 | } | 854 | } |
| @@ -857,4 +880,19 @@ std::unique_ptr<Input::InputDevice> InputFactory::Create(const Common::ParamPack | |||
| 857 | return std::make_unique<DummyInput>(); | 880 | return std::make_unique<DummyInput>(); |
| 858 | } | 881 | } |
| 859 | 882 | ||
| 883 | OutputFactory::OutputFactory(std::shared_ptr<InputEngine> input_engine_) | ||
| 884 | : input_engine(std::move(input_engine_)) {} | ||
| 885 | |||
| 886 | std::unique_ptr<Input::OutputDevice> OutputFactory::Create( | ||
| 887 | const Common::ParamPackage& params) { | ||
| 888 | const PadIdentifier identifier = { | ||
| 889 | .guid = Common::UUID{params.Get("guid", "")}, | ||
| 890 | .port = static_cast<std::size_t>(params.Get("port", 0)), | ||
| 891 | .pad = static_cast<std::size_t>(params.Get("pad", 0)), | ||
| 892 | }; | ||
| 893 | |||
| 894 | input_engine->PreSetController(identifier); | ||
| 895 | return std::make_unique<OutputFromIdentifier>(identifier, input_engine.get()); | ||
| 896 | } | ||
| 897 | |||
| 860 | } // namespace InputCommon | 898 | } // namespace InputCommon |
diff --git a/src/input_common/input_poller.h b/src/input_common/input_poller.h index 3c1e5b541..16cade5fa 100644 --- a/src/input_common/input_poller.h +++ b/src/input_common/input_poller.h | |||
| @@ -16,12 +16,32 @@ class InputEngine; | |||
| 16 | /** | 16 | /** |
| 17 | * An Input factory. It receives input events and forward them to all input devices it created. | 17 | * An Input factory. It receives input events and forward them to all input devices it created. |
| 18 | */ | 18 | */ |
| 19 | |||
| 20 | class OutputFactory final : public Input::Factory<Input::OutputDevice> { | ||
| 21 | public: | ||
| 22 | explicit OutputFactory(std::shared_ptr<InputEngine> input_engine_); | ||
| 23 | |||
| 24 | /** | ||
| 25 | * Creates an output device from the parameters given. | ||
| 26 | * @param params contains parameters for creating the device: | ||
| 27 | * @param - "guid": text string for identifing controllers | ||
| 28 | * @param - "port": port of the connected device | ||
| 29 | * @param - "pad": slot of the connected controller | ||
| 30 | * @return an unique ouput device with the parameters specified | ||
| 31 | */ | ||
| 32 | std::unique_ptr<Input::OutputDevice> Create( | ||
| 33 | const Common::ParamPackage& params) override; | ||
| 34 | |||
| 35 | private: | ||
| 36 | std::shared_ptr<InputEngine> input_engine; | ||
| 37 | }; | ||
| 38 | |||
| 19 | class InputFactory final : public Input::Factory<Input::InputDevice> { | 39 | class InputFactory final : public Input::Factory<Input::InputDevice> { |
| 20 | public: | 40 | public: |
| 21 | explicit InputFactory(std::shared_ptr<InputEngine> input_engine_); | 41 | explicit InputFactory(std::shared_ptr<InputEngine> input_engine_); |
| 22 | 42 | ||
| 23 | /** | 43 | /** |
| 24 | * Creates a input device from the parameters given. Identifies the type of input to be returned | 44 | * Creates an input device from the parameters given. Identifies the type of input to be returned |
| 25 | * if it contains the following parameters: | 45 | * if it contains the following parameters: |
| 26 | * - button: Contains "button" or "code" | 46 | * - button: Contains "button" or "code" |
| 27 | * - hat_button: Contains "hat" | 47 | * - hat_button: Contains "hat" |
| @@ -32,6 +52,7 @@ public: | |||
| 32 | * - motion: Contains "motion" | 52 | * - motion: Contains "motion" |
| 33 | * - touch: Contains "button", "axis_x" and "axis_y" | 53 | * - touch: Contains "button", "axis_x" and "axis_y" |
| 34 | * - battery: Contains "battery" | 54 | * - battery: Contains "battery" |
| 55 | * - output: Contains "output" | ||
| 35 | * @param params contains parameters for creating the device: | 56 | * @param params contains parameters for creating the device: |
| 36 | * @param - "code": the code of the keyboard key to bind with the input | 57 | * @param - "code": the code of the keyboard key to bind with the input |
| 37 | * @param - "button": same as "code" but for controller buttons | 58 | * @param - "button": same as "code" but for controller buttons |
| @@ -41,10 +62,11 @@ public: | |||
| 41 | * @param - "axis_x": same as axis but specifing horizontal direction | 62 | * @param - "axis_x": same as axis but specifing horizontal direction |
| 42 | * @param - "axis_y": same as axis but specifing vertical direction | 63 | * @param - "axis_y": same as axis but specifing vertical direction |
| 43 | * @param - "axis_z": same as axis but specifing forward direction | 64 | * @param - "axis_z": same as axis but specifing forward direction |
| 44 | * @param - "battery": Only used as a placeholder to set the input type | 65 | * @param - "battery": Only used as a placeholder to set the input type |
| 45 | * @return an unique input device with the parameters specified | 66 | * @return an unique input device with the parameters specified |
| 46 | */ | 67 | */ |
| 47 | std::unique_ptr<Input::InputDevice> Create(const Common::ParamPackage& params) override; | 68 | std::unique_ptr<Input::InputDevice> Create( |
| 69 | const Common::ParamPackage& params) override; | ||
| 48 | 70 | ||
| 49 | private: | 71 | private: |
| 50 | /** | 72 | /** |
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index 46ca6b76c..b7fe9cb37 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp | |||
| @@ -46,8 +46,10 @@ struct InputSubsystem::Impl { | |||
| 46 | 46 | ||
| 47 | gcadapter = std::make_shared<GCAdapter>("gcpad"); | 47 | gcadapter = std::make_shared<GCAdapter>("gcpad"); |
| 48 | gcadapter->SetMappingCallback(mapping_callback); | 48 | gcadapter->SetMappingCallback(mapping_callback); |
| 49 | gcadapter_factory = std::make_shared<InputFactory>(gcadapter); | 49 | gcadapter_input_factory = std::make_shared<InputFactory>(gcadapter); |
| 50 | Input::RegisterFactory<Input::InputDevice>(gcadapter->GetEngineName(), gcadapter_factory); | 50 | gcadapter_output_factory = std::make_shared<OutputFactory>(gcadapter); |
| 51 | Input::RegisterFactory<Input::InputDevice>(gcadapter->GetEngineName(), gcadapter_input_factory); | ||
| 52 | Input::RegisterFactory<Input::OutputDevice>(gcadapter->GetEngineName(), gcadapter_output_factory); | ||
| 51 | 53 | ||
| 52 | udp_client = std::make_shared<CemuhookUDP::UDPClient>("cemuhookudp"); | 54 | udp_client = std::make_shared<CemuhookUDP::UDPClient>("cemuhookudp"); |
| 53 | udp_client->SetMappingCallback(mapping_callback); | 55 | udp_client->SetMappingCallback(mapping_callback); |
| @@ -62,8 +64,10 @@ struct InputSubsystem::Impl { | |||
| 62 | #ifdef HAVE_SDL2 | 64 | #ifdef HAVE_SDL2 |
| 63 | sdl = std::make_shared<SDLDriver>("sdl"); | 65 | sdl = std::make_shared<SDLDriver>("sdl"); |
| 64 | sdl->SetMappingCallback(mapping_callback); | 66 | sdl->SetMappingCallback(mapping_callback); |
| 65 | sdl_factory = std::make_shared<InputFactory>(sdl); | 67 | sdl_input_factory = std::make_shared<InputFactory>(sdl); |
| 66 | Input::RegisterFactory<Input::InputDevice>(sdl->GetEngineName(), sdl_factory); | 68 | sdl_output_factory = std::make_shared<OutputFactory>(sdl); |
| 69 | Input::RegisterFactory<Input::InputDevice>(sdl->GetEngineName(), sdl_input_factory); | ||
| 70 | Input::RegisterFactory<Input::OutputDevice>(sdl->GetEngineName(), sdl_output_factory); | ||
| 67 | #endif | 71 | #endif |
| 68 | 72 | ||
| 69 | Input::RegisterFactory<Input::InputDevice>("touch_from_button", | 73 | Input::RegisterFactory<Input::InputDevice>("touch_from_button", |
| @@ -247,21 +251,27 @@ struct InputSubsystem::Impl { | |||
| 247 | } | 251 | } |
| 248 | 252 | ||
| 249 | std::shared_ptr<MappingFactory> mapping_factory; | 253 | std::shared_ptr<MappingFactory> mapping_factory; |
| 254 | |||
| 250 | std::shared_ptr<Keyboard> keyboard; | 255 | std::shared_ptr<Keyboard> keyboard; |
| 251 | std::shared_ptr<InputFactory> keyboard_factory; | ||
| 252 | std::shared_ptr<Mouse> mouse; | 256 | std::shared_ptr<Mouse> mouse; |
| 253 | std::shared_ptr<InputFactory> mouse_factory; | ||
| 254 | std::shared_ptr<GCAdapter> gcadapter; | 257 | std::shared_ptr<GCAdapter> gcadapter; |
| 255 | std::shared_ptr<InputFactory> gcadapter_factory; | ||
| 256 | std::shared_ptr<TouchScreen> touch_screen; | 258 | std::shared_ptr<TouchScreen> touch_screen; |
| 257 | std::shared_ptr<InputFactory> touch_screen_factory; | 259 | std::shared_ptr<TasInput::Tas> tas_input; |
| 258 | std::shared_ptr<CemuhookUDP::UDPClient> udp_client; | 260 | std::shared_ptr<CemuhookUDP::UDPClient> udp_client; |
| 261 | |||
| 262 | std::shared_ptr<InputFactory> keyboard_factory; | ||
| 263 | std::shared_ptr<InputFactory> mouse_factory; | ||
| 264 | std::shared_ptr<InputFactory> gcadapter_input_factory; | ||
| 265 | std::shared_ptr<InputFactory> touch_screen_factory; | ||
| 259 | std::shared_ptr<InputFactory> udp_client_factory; | 266 | std::shared_ptr<InputFactory> udp_client_factory; |
| 260 | std::shared_ptr<TasInput::Tas> tas_input; | ||
| 261 | std::shared_ptr<InputFactory> tas_input_factory; | 267 | std::shared_ptr<InputFactory> tas_input_factory; |
| 268 | |||
| 269 | std::shared_ptr<OutputFactory> gcadapter_output_factory; | ||
| 270 | |||
| 262 | #ifdef HAVE_SDL2 | 271 | #ifdef HAVE_SDL2 |
| 263 | std::shared_ptr<SDLDriver> sdl; | 272 | std::shared_ptr<SDLDriver> sdl; |
| 264 | std::shared_ptr<InputFactory> sdl_factory; | 273 | std::shared_ptr<InputFactory> sdl_input_factory; |
| 274 | std::shared_ptr<OutputFactory> sdl_output_factory; | ||
| 265 | #endif | 275 | #endif |
| 266 | }; | 276 | }; |
| 267 | 277 | ||
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index adc9706f1..ed9c3facf 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -465,6 +465,8 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i | |||
| 465 | UpdateControllerEnabledButtons(); | 465 | UpdateControllerEnabledButtons(); |
| 466 | UpdateControllerButtonNames(); | 466 | UpdateControllerButtonNames(); |
| 467 | UpdateMotionButtons(); | 467 | UpdateMotionButtons(); |
| 468 | emulated_controller->SetNpadType( | ||
| 469 | GetControllerTypeFromIndex(ui->comboControllerType->currentIndex())); | ||
| 468 | }); | 470 | }); |
| 469 | 471 | ||
| 470 | connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, | 472 | connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, |
| @@ -540,6 +542,11 @@ void ConfigureInputPlayer::LoadConfiguration() { | |||
| 540 | 542 | ||
| 541 | void ConfigureInputPlayer::ConnectPlayer(bool connected) { | 543 | void ConfigureInputPlayer::ConnectPlayer(bool connected) { |
| 542 | ui->groupConnectedController->setChecked(connected); | 544 | ui->groupConnectedController->setChecked(connected); |
| 545 | if (connected) { | ||
| 546 | emulated_controller->Connect(); | ||
| 547 | } else { | ||
| 548 | emulated_controller->Disconnect(); | ||
| 549 | } | ||
| 543 | } | 550 | } |
| 544 | 551 | ||
| 545 | void ConfigureInputPlayer::UpdateInputDeviceCombobox() { | 552 | void ConfigureInputPlayer::UpdateInputDeviceCombobox() { |
diff --git a/src/yuzu/configuration/configure_input_player_widget.cpp b/src/yuzu/configuration/configure_input_player_widget.cpp index 03d29f194..2ba9d7290 100644 --- a/src/yuzu/configuration/configure_input_player_widget.cpp +++ b/src/yuzu/configuration/configure_input_player_widget.cpp | |||
| @@ -24,34 +24,6 @@ PlayerControlPreview::~PlayerControlPreview() { | |||
| 24 | } | 24 | } |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | PlayerControlPreview::LedPattern PlayerControlPreview::GetColorPattern(std::size_t index, | ||
| 28 | bool player_on) { | ||
| 29 | if (!player_on) { | ||
| 30 | return {0, 0, 0, 0}; | ||
| 31 | } | ||
| 32 | |||
| 33 | switch (index) { | ||
| 34 | case 0: | ||
| 35 | return {1, 0, 0, 0}; | ||
| 36 | case 1: | ||
| 37 | return {1, 1, 0, 0}; | ||
| 38 | case 2: | ||
| 39 | return {1, 1, 1, 0}; | ||
| 40 | case 3: | ||
| 41 | return {1, 1, 1, 1}; | ||
| 42 | case 4: | ||
| 43 | return {1, 0, 0, 1}; | ||
| 44 | case 5: | ||
| 45 | return {1, 0, 1, 0}; | ||
| 46 | case 6: | ||
| 47 | return {1, 0, 1, 1}; | ||
| 48 | case 7: | ||
| 49 | return {0, 1, 1, 0}; | ||
| 50 | default: | ||
| 51 | return {0, 0, 0, 0}; | ||
| 52 | } | ||
| 53 | } | ||
| 54 | |||
| 55 | void PlayerControlPreview::SetController(Core::HID::EmulatedController* controller_) { | 27 | void PlayerControlPreview::SetController(Core::HID::EmulatedController* controller_) { |
| 56 | if (is_controller_set) { | 28 | if (is_controller_set) { |
| 57 | controller->DeleteCallback(callback_key); | 29 | controller->DeleteCallback(callback_key); |
| @@ -160,8 +132,13 @@ void PlayerControlPreview::ControllerUpdate(Core::HID::ControllerTriggerType typ | |||
| 160 | 132 | ||
| 161 | switch (type) { | 133 | switch (type) { |
| 162 | case Core::HID::ControllerTriggerType::Connected: | 134 | case Core::HID::ControllerTriggerType::Connected: |
| 135 | is_connected = true; | ||
| 136 | led_pattern = controller->GetLedPattern(); | ||
| 137 | needs_redraw = true; | ||
| 138 | break; | ||
| 163 | case Core::HID::ControllerTriggerType::Disconnected: | 139 | case Core::HID::ControllerTriggerType::Disconnected: |
| 164 | is_connected = controller->IsConnected(); | 140 | is_connected = false; |
| 141 | led_pattern.raw = 0; | ||
| 165 | needs_redraw = true; | 142 | needs_redraw = true; |
| 166 | break; | 143 | break; |
| 167 | case Core::HID::ControllerTriggerType::Type: | 144 | case Core::HID::ControllerTriggerType::Type: |
| @@ -1853,10 +1830,14 @@ void PlayerControlPreview::DrawLeftBody(QPainter& p, const QPointF center) { | |||
| 1853 | const float led_size = 5.0f; | 1830 | const float led_size = 5.0f; |
| 1854 | const QPointF led_position = sideview_center + QPointF(0, -36); | 1831 | const QPointF led_position = sideview_center + QPointF(0, -36); |
| 1855 | int led_count = 0; | 1832 | int led_count = 0; |
| 1856 | for (const auto& color : led_color) { | 1833 | p.setBrush(led_pattern.position1 ? colors.led_on : colors.led_off); |
| 1857 | p.setBrush(color); | 1834 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); |
| 1858 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); | 1835 | p.setBrush(led_pattern.position2 ? colors.led_on : colors.led_off); |
| 1859 | } | 1836 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); |
| 1837 | p.setBrush(led_pattern.position3 ? colors.led_on : colors.led_off); | ||
| 1838 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); | ||
| 1839 | p.setBrush(led_pattern.position4 ? colors.led_on : colors.led_off); | ||
| 1840 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); | ||
| 1860 | } | 1841 | } |
| 1861 | 1842 | ||
| 1862 | void PlayerControlPreview::DrawRightBody(QPainter& p, const QPointF center) { | 1843 | void PlayerControlPreview::DrawRightBody(QPainter& p, const QPointF center) { |
| @@ -1949,10 +1930,14 @@ void PlayerControlPreview::DrawRightBody(QPainter& p, const QPointF center) { | |||
| 1949 | const float led_size = 5.0f; | 1930 | const float led_size = 5.0f; |
| 1950 | const QPointF led_position = sideview_center + QPointF(0, -36); | 1931 | const QPointF led_position = sideview_center + QPointF(0, -36); |
| 1951 | int led_count = 0; | 1932 | int led_count = 0; |
| 1952 | for (const auto& color : led_color) { | 1933 | p.setBrush(led_pattern.position1 ? colors.led_on : colors.led_off); |
| 1953 | p.setBrush(color); | 1934 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); |
| 1954 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); | 1935 | p.setBrush(led_pattern.position2 ? colors.led_on : colors.led_off); |
| 1955 | } | 1936 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); |
| 1937 | p.setBrush(led_pattern.position3 ? colors.led_on : colors.led_off); | ||
| 1938 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); | ||
| 1939 | p.setBrush(led_pattern.position4 ? colors.led_on : colors.led_off); | ||
| 1940 | DrawRectangle(p, led_position + QPointF(0, 12 * led_count++), led_size, led_size); | ||
| 1956 | } | 1941 | } |
| 1957 | 1942 | ||
| 1958 | void PlayerControlPreview::DrawProTriggers(QPainter& p, const QPointF center, | 1943 | void PlayerControlPreview::DrawProTriggers(QPainter& p, const QPointF center, |
diff --git a/src/yuzu/configuration/configure_input_player_widget.h b/src/yuzu/configuration/configure_input_player_widget.h index b44a2e347..16f9748f5 100644 --- a/src/yuzu/configuration/configure_input_player_widget.h +++ b/src/yuzu/configuration/configure_input_player_widget.h | |||
| @@ -59,13 +59,6 @@ private: | |||
| 59 | SR, | 59 | SR, |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | struct LedPattern { | ||
| 63 | bool position1; | ||
| 64 | bool position2; | ||
| 65 | bool position3; | ||
| 66 | bool position4; | ||
| 67 | }; | ||
| 68 | |||
| 69 | struct ColorMapping { | 62 | struct ColorMapping { |
| 70 | QColor outline{}; | 63 | QColor outline{}; |
| 71 | QColor primary{}; | 64 | QColor primary{}; |
| @@ -88,7 +81,6 @@ private: | |||
| 88 | QColor deadzone{}; | 81 | QColor deadzone{}; |
| 89 | }; | 82 | }; |
| 90 | 83 | ||
| 91 | static LedPattern GetColorPattern(std::size_t index, bool player_on); | ||
| 92 | void UpdateColors(); | 84 | void UpdateColors(); |
| 93 | void ResetInputs(); | 85 | void ResetInputs(); |
| 94 | 86 | ||
| @@ -194,7 +186,7 @@ private: | |||
| 194 | int callback_key; | 186 | int callback_key; |
| 195 | QColor button_color{}; | 187 | QColor button_color{}; |
| 196 | ColorMapping colors{}; | 188 | ColorMapping colors{}; |
| 197 | std::array<QColor, 4> led_color{}; | 189 | Core::HID::LedPattern led_pattern{0, 0, 0, 0}; |
| 198 | std::size_t player_index{}; | 190 | std::size_t player_index{}; |
| 199 | Core::HID::EmulatedController* controller; | 191 | Core::HID::EmulatedController* controller; |
| 200 | std::size_t button_mapping_index{Settings::NativeButton::NumButtons}; | 192 | std::size_t button_mapping_index{Settings::NativeButton::NumButtons}; |