summaryrefslogtreecommitdiffstats
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>;
using AnalogDevice = InputDevice<std::tuple<float, float>>;
/**
+ * 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.
+ */
+using VibrationDevice = InputDevice<u8>;
+
+/**
* A motion status is an object that returns a tuple of accelerometer state vector,
* gyroscope state vector, rotation state vector and orientation state matrix.
*
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() {
std::transform(players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_BEGIN,
players[i].analogs.begin() + Settings::NativeAnalog::STICK_HID_END,
sticks[i].begin(), Input::CreateDevice<Input::AnalogDevice>);
+ std::transform(players[i].vibrations.begin() +
+ Settings::NativeVibration::VIBRATION_HID_BEGIN,
+ players[i].vibrations.begin() + Settings::NativeVibration::VIBRATION_HID_END,
+ vibrations[i].begin(), Input::CreateDevice<Input::VibrationDevice>);
std::transform(players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN,
players[i].motions.begin() + Settings::NativeMotion::MOTION_HID_END,
motions[i].begin(), Input::CreateDevice<Input::MotionDevice>);
@@ -278,8 +282,10 @@ void Controller_NPad::OnLoadInputDevices() {
}
void Controller_NPad::OnRelease() {
- for (std::size_t index = 0; index < connected_controllers.size(); ++index) {
- VibrateControllerAtIndex(index, {});
+ for (std::size_t npad_idx = 0; npad_idx < vibrations.size(); ++npad_idx) {
+ for (std::size_t device_idx = 0; device_idx < vibrations[npad_idx].size(); ++device_idx) {
+ VibrateControllerAtIndex(npad_idx, device_idx);
+ }
}
}
@@ -674,9 +680,9 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode)
}
}
-bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index,
+bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
const VibrationValue& vibration_value) {
- if (!connected_controllers[npad_index].is_connected) {
+ if (!connected_controllers[npad_index].is_connected || !vibrations[npad_index][device_index]) {
return false;
}
@@ -686,10 +692,7 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index,
return false;
}
- using namespace Settings::NativeButton;
- const auto& button_state = buttons[npad_index];
-
- return button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
+ return vibrations[npad_index][device_index]->SetRumblePlay(
std::min(vibration_value.amp_low * player.vibration_strength / 100.0f, 1.0f),
vibration_value.freq_low,
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
continue;
}
+ if (vibration_device_handles[i].device_index == DeviceIndex::None) {
+ UNREACHABLE_MSG("DeviceIndex should never be None!");
+ continue;
+ }
+
// Some games try to send mismatched parameters in the device handle, block these.
if ((connected_controllers[npad_index].type == NPadControllerType::JoyLeft &&
(vibration_device_handles[i].npad_type == NpadType::JoyconRight ||
@@ -747,28 +755,8 @@ void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibrat
continue;
}
- // TODO: Vibrate left/right vibration motors independently if possible.
- if (VibrateControllerAtIndex(npad_index, vibration_values[i])) {
- switch (connected_controllers[npad_index].type) {
- case NPadControllerType::None:
- UNREACHABLE();
- break;
- case NPadControllerType::ProController:
- case NPadControllerType::Handheld:
- case NPadControllerType::JoyDual:
- // Since we can't vibrate motors independently yet, we can reduce state changes by
- // assigning all 3 device indices the current vibration value.
- latest_vibration_values[npad_index][0] = vibration_values[i];
- latest_vibration_values[npad_index][1] = vibration_values[i];
- latest_vibration_values[npad_index][2] = vibration_values[i];
- break;
- case NPadControllerType::JoyLeft:
- case NPadControllerType::JoyRight:
- case NPadControllerType::Pokeball:
- default:
- latest_vibration_values[npad_index][device_index] = vibration_values[i];
- break;
- }
+ if (VibrateControllerAtIndex(npad_index, device_index, vibration_values[i])) {
+ latest_vibration_values[npad_index][device_index] = vibration_values[i];
}
}
}
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:
void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
- bool VibrateControllerAtIndex(std::size_t npad_index, const VibrationValue& vibration_value);
+ bool VibrateControllerAtIndex(std::size_t npad_index, std::size_t device_index,
+ const VibrationValue& vibration_value = {});
void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
const std::vector<VibrationValue>& vibration_values);
@@ -399,18 +400,22 @@ private:
using StickArray = std::array<
std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>,
10>;
+ using VibrationArray = std::array<std::array<std::unique_ptr<Input::VibrationDevice>,
+ Settings::NativeVibration::NUM_VIBRATIONS_HID>,
+ 10>;
using MotionArray = std::array<
- std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTION_HID>,
+ std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>,
10>;
ButtonArray buttons;
StickArray sticks;
+ VibrationArray vibrations;
MotionArray motions;
std::vector<u32> supported_npad_id_types{};
NpadHoldType hold_type{NpadHoldType::Vertical};
NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
// Each controller should have their own styleset changed event
std::array<Kernel::EventPair, 10> styleset_changed_events;
- std::array<std::array<VibrationValue, 3>, 10> latest_vibration_values;
+ std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
std::array<ControllerHolder, 10> connected_controllers{};
std::array<bool, 10> unintended_home_button_input_protection{};
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) {
break;
case Controller_NPad::DeviceIndex::None:
default:
+ UNREACHABLE_MSG("DeviceIndex should never be None!");
vibration_device_info.position = VibrationDevicePosition::None;
break;
}