summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hid/emulated_controller.cpp119
-rw-r--r--src/core/hid/emulated_controller.h13
-rw-r--r--src/core/hid/hid_types.h18
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp27
-rw-r--r--src/core/hle/service/hid/controllers/npad.h18
5 files changed, 126 insertions, 69 deletions
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
72void EmulatedController::ReloadInput() { 93void 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
162void EmulatedController::UnloadInput() { 166void 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
604bool EmulatedController::SetVibration([[maybe_unused]] std::size_t device_index, 609bool 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
623bool 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
609int EmulatedController::TestVibration(std::size_t device_index) { 638void 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
613void EmulatedController::Connect() { 655void EmulatedController::Connect() {
@@ -655,6 +697,29 @@ void EmulatedController::SetNpadType(NpadType npad_type_) {
655 TriggerOnChange(ControllerTriggerType::Type); 697 TriggerOnChange(ControllerTriggerType::Type);
656} 698}
657 699
700LedPattern 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
658ButtonValues EmulatedController::GetButtonsValues() const { 723ButtonValues 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 =
33using TriggerDevices = 33using TriggerDevices =
34 std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeTrigger::NumTriggers>; 34 std::array<std::unique_ptr<Input::InputDevice>, Settings::NativeTrigger::NumTriggers>;
35using BatteryDevices = std::array<std::unique_ptr<Input::InputDevice>, 2>; 35using BatteryDevices = std::array<std::unique_ptr<Input::InputDevice>, 2>;
36using OutputDevices = std::array<std::unique_ptr<Input::OutputDevice>, 2>;
36 37
37using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>; 38using ButtonParams = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;
38using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>; 39using StickParams = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
39using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>; 40using ControllerMotionParams = std::array<Common::ParamPackage, Settings::NativeMotion::NumMotions>;
40using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>; 41using TriggerParams = std::array<Common::ParamPackage, Settings::NativeTrigger::NumTriggers>;
41using BatteryParams = std::array<Common::ParamPackage, 2>; 42using BatteryParams = std::array<Common::ParamPackage, 2>;
43using OutputParams = std::array<Common::ParamPackage, 2>;
42 44
43using ButtonValues = std::array<Input::ButtonStatus, Settings::NativeButton::NumButtons>; 45using ButtonValues = std::array<Input::ButtonStatus, Settings::NativeButton::NumButtons>;
44using SticksValues = std::array<Input::StickStatus, Settings::NativeAnalog::NumAnalogs>; 46using 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
97enum class ControllerTriggerType { 100enum 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};
176static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size"); 178static_assert(sizeof(NpadPowerInfo) == 0xC, "NpadPowerInfo is an invalid size");
177 179
180struct 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
179enum class NpadButton : u64 { 197enum 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
802void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { 802void 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
957Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) { 957Core::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
984bool Controller_NPad::IsUnintendedHomeButtonInputProtectionEnabled(u32 npad_id) const { 965bool 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);