summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar Morph2020-10-20 13:55:25 -0400
committerGravatar Morph2020-11-15 23:33:20 -0500
commite9e1876e821b8bd1bb5c8254ec93e2cc479e16dd (patch)
tree344b40a5a874cb188c6e7aa7d1622c77a215090d /src/core
parentconfigure_input: Add per-player vibration (diff)
downloadyuzu-e9e1876e821b8bd1bb5c8254ec93e2cc479e16dd.tar.gz
yuzu-e9e1876e821b8bd1bb5c8254ec93e2cc479e16dd.tar.xz
yuzu-e9e1876e821b8bd1bb5c8254ec93e2cc479e16dd.zip
input_common: Add VibrationDevice and VibrationDeviceFactory
A vibration device is an input device that returns an unsigned byte as status. It represents whether the vibration device supports vibration or not. If the status returns 1, it supports vibration. Otherwise, it does not support vibration.
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 }