summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/frontend/input.h7
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp48
-rw-r--r--src/core/hle/service/hid/controllers/npad.h11
-rw-r--r--src/core/hle/service/hid/hid.cpp1
4 files changed, 34 insertions, 33 deletions
diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h
index fb2ce2514..25ac5af46 100644
--- a/src/core/frontend/input.h
+++ b/src/core/frontend/input.h
@@ -122,6 +122,13 @@ using ButtonDevice = InputDevice<bool>;
122using AnalogDevice = InputDevice<std::tuple<float, float>>; 122using AnalogDevice = InputDevice<std::tuple<float, float>>;
123 123
124/** 124/**
125 * A vibration device is an input device that returns an unsigned byte as status.
126 * It represents whether the vibration device supports vibration or not.
127 * If the status returns 1, it supports vibration. Otherwise, it does not support vibration.
128 */
129using VibrationDevice = InputDevice<u8>;
130
131/**
125 * A motion status is an object that returns a tuple of accelerometer state vector, 132 * A motion status is an object that returns a tuple of accelerometer state vector,
126 * gyroscope state vector, rotation state vector and orientation state matrix. 133 * gyroscope state vector, rotation state vector and orientation state matrix.
127 * 134 *
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index dc9954377..27099de24 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -271,6 +271,10 @@ void Controller_NPad::OnLoadInputDevices() {
271 std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, 271 std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN,
272 players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END, 272 players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END,
273 sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>); 273 sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>);
274 std::transform(players[i].vibrations.begin() +
275 Settings::NativeVibration::VIBRATION_HID_BEGIN,
276 players[i].vibrations.begin() + Settings::NativeVibration::VIBRATION_HID_END,
277 vibrations[i].begin(), Input::CreateDevice<Input::VibrationDevice>);
274 std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN, 278 std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN,
275 players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END, 279 players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END,
276 motions[i].begin(), Input::CreateDevice<Input::MotionDevice>); 280 motions[i].begin(), Input::CreateDevice<Input::MotionDevice>);
@@ -278,8 +282,10 @@ void Controller_NPad::OnLoadInputDevices() {
278} 282}
279 283
280void Controller_NPad::OnRelease() { 284void Controller_NPad::OnRelease() {
281 for (std::size_t index = 0; index < connected_controllers.size(); ++index) { 285 for (std::size_t npad_idx = 0; npad_idx < vibrations.size(); ++npad_idx) {
282 VibrateControllerAtIndex(index, {}); 286 for (std::size_t device_idx = 0; device_idx < vibrations[npad_idx].size(); ++device_idx) {
287 VibrateControllerAtIndex(npad_idx, device_idx);
288 }
283 } 289 }
284} 290}
285 291
@@ -674,9 +680,9 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode)
674 } 680 }
675} 681}
676 682
677bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, 683bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
678 const VibrationValue& vibration_value) { 684 const VibrationValue& vibration_value) {
679 if (!connected_controllers[npad_index].is_connected) { 685 if (!connected_controllers[npad_index].is_connected || !vibrations[npad_index][device_index]) {
680 return false; 686 return false;
681 } 687 }
682 688
@@ -686,10 +692,7 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index,
686 return false; 692 return false;
687 } 693 }
688 694
689 using namespace Settings::NativeButton; 695 return vibrations[npad_index][device_index]->SetRumblePlay(
690 const auto& button_state = buttons[npad_index];
691
692 return button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
693 std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f), 696 std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f),
694 vibration_value.freq_low, 697 vibration_value.freq_low,
695 std::min(vibration_value.amp_high * player.vibration_strength / 100.0f, 1.0f), 698 std::min(vibration_value.amp_high * player.vibration_strength / 100.0f, 1.0f),
@@ -717,6 +720,11 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat
717 continue; 720 continue;
718 } 721 }
719 722
723 if (vibration_device_handles[i].device_index == DeviceIndex::None) {
724 UNREACHABLE_MSG("DeviceIndex should never be None!");
725 continue;
726 }
727
720 // Some games try to send mismatched parameters in the device handle, block these. 728 // Some games try to send mismatched parameters in the device handle, block these.
721 if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft && 729 if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft &&
722 (vibration_device_handles[i].npad_type == NpadType::JoyconRight || 730 (vibration_device_handles[i].npad_type == NpadType::JoyconRight ||
@@ -747,28 +755,8 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat
747 continue; 755 continue;
748 } 756 }
749 757
750 // TODO: Vibrate left/right vibration motors independently if possible. 758 if (VibrateControllerAtIndex(npad_index, device_index, vibration_values[i])) {
751 if (VibrateControllerAtIndex(npad_index, vibration_values[i])) { 759 latest_vibration_values[npad_index][device_index] = vibration_values[i];
752 switch (connected_controllers[npad_index].type) {
753 case NPadControllerType::None:
754 UNREACHABLE();
755 break;
756 case NPadControllerType::ProController:
757 case NPadControllerType::Handheld:
758 case NPadControllerType::JoyDual:
759 // Since we can't vibrate motors independently yet, we can reduce state changes by
760 // assigning all 3 device indices the current vibration value.
761 latest_vibration_values[npad_index][0] = vibration_values[i];
762 latest_vibration_values[npad_index][1] = vibration_values[i];
763 latest_vibration_values[npad_index][2] = vibration_values[i];
764 break;
765 case NPadControllerType::JoyLeft:
766 case NPadControllerType::JoyRight:
767 case NPadControllerType::Pokeball:
768 default:
769 latest_vibration_values[npad_index][device_index] = vibration_values[i];
770 break;
771 }
772 } 760 }
773 } 761 }
774} 762}
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 576ef1558..3ae9fb8e6 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -148,7 +148,8 @@ public:
148 148
149 void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode); 149 void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
150 150
151 bool VibrateControllerAtIndex(std::size_t npad_index, const VibrationValue& vibration_value); 151 bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
152 const VibrationValue& vibration_value = {});
152 153
153 void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles, 154 void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
154 const std::vector<VibrationValue>& vibration_values); 155 const std::vector<VibrationValue>& vibration_values);
@@ -399,18 +400,22 @@ private:
399 using StickArray = std::array< 400 using StickArray = std::array<
400 std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>, 401 std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>,
401 10>; 402 10>;
403 using VibrationArray = std::array<std::array<std::unique_ptr<Input::VibrationDevice>,
404 Settings::NativeVibration::NUM_VIBRATIONS_HID>,
405 10>;
402 using MotionArray = std::array< 406 using MotionArray = std::array<
403 std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTION_HID>, 407 std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>,
404 10>; 408 10>;
405 ButtonArray buttons; 409 ButtonArray buttons;
406 StickArray sticks; 410 StickArray sticks;
411 VibrationArray vibrations;
407 MotionArray motions; 412 MotionArray motions;
408 std::vector<u32> supported_npad_id_types{}; 413 std::vector<u32> supported_npad_id_types{};
409 NpadHoldType hold_type{NpadHoldType::Vertical}; 414 NpadHoldType hold_type{NpadHoldType::Vertical};
410 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; 415 NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
411 // Each controller should have their own styleset changed event 416 // Each controller should have their own styleset changed event
412 std::array<Kernel::EventPair, 10> styleset_changed_events; 417 std::array<Kernel::EventPair, 10> styleset_changed_events;
413 std::array<std::array<VibrationValue, 3>, 10> latest_vibration_values; 418 std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
414 std::array<ControllerHolder, 10> connected_controllers{}; 419 std::array<ControllerHolder, 10> connected_controllers{};
415 std::array<bool, 10> unintended_home_button_input_protection{}; 420 std::array<bool, 10> unintended_home_button_input_protection{};
416 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard}; 421 GyroscopeZeroDriftMode gyroscope_zero_drift_mode{GyroscopeZeroDriftMode::Standard};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index e88f30d6a..1d882a977 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -998,6 +998,7 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
998 break; 998 break;
999 case Controller_NPad::DeviceIndex::None: 999 case Controller_NPad::DeviceIndex::None:
1000 default: 1000 default:
1001 UNREACHABLE_MSG("DeviceIndex should never be None!");
1001 vibration_device_info.position = VibrationDevicePosition::None; 1002 vibration_device_info.position = VibrationDevicePosition::None;
1002 break; 1003 break;
1003 } 1004 }