forked from suyu/suyu
controllers/npad: Send an empty vibration on destruction/deactivation
This stops all controllers from continuously vibrating when emulation is stopped.
This commit is contained in:
parent
70f16f1722
commit
373408ae8c
3 changed files with 38 additions and 22 deletions
|
@ -117,7 +117,10 @@ u32 Controller_NPad::IndexToNPad(std::size_t index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
|
Controller_NPad::Controller_NPad(Core::System& system) : ControllerBase(system), system(system) {}
|
||||||
Controller_NPad::~Controller_NPad() = default;
|
|
||||||
|
Controller_NPad::~Controller_NPad() {
|
||||||
|
OnRelease();
|
||||||
|
}
|
||||||
|
|
||||||
void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
|
void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
|
||||||
const auto controller_type = connected_controllers[controller_idx].type;
|
const auto controller_type = connected_controllers[controller_idx].type;
|
||||||
|
@ -274,7 +277,11 @@ void Controller_NPad::OnLoadInputDevices() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::OnRelease() {}
|
void Controller_NPad::OnRelease() {
|
||||||
|
for (std::size_t index = 0; index < connected_controllers.size(); ++index) {
|
||||||
|
VibrateControllerAtIndex(index, {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
|
void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
|
||||||
const auto controller_idx = NPadIdToIndex(npad_id);
|
const auto controller_idx = NPadIdToIndex(npad_id);
|
||||||
|
@ -667,8 +674,24 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::VibrateController(const std::vector<DeviceHandle>& vibration_device_handles,
|
bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index,
|
||||||
const std::vector<VibrationValue>& vibration_values) {
|
const VibrationValue& vibration_value) {
|
||||||
|
if (!connected_controllers[npad_index].is_connected) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Settings::NativeButton;
|
||||||
|
const auto& button_state = buttons[npad_index];
|
||||||
|
|
||||||
|
return button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
|
||||||
|
vibration_value.amp_low * Settings::values.vibration_strength.GetValue() / 100,
|
||||||
|
vibration_value.freq_low,
|
||||||
|
vibration_value.amp_high * Settings::values.vibration_strength.GetValue() / 100,
|
||||||
|
vibration_value.freq_high);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller_NPad::VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
|
||||||
|
const std::vector<VibrationValue>& vibration_values) {
|
||||||
LOG_TRACE(Service_HID, "called");
|
LOG_TRACE(Service_HID, "called");
|
||||||
|
|
||||||
if (!Settings::values.vibration_enabled.GetValue() || !can_controllers_vibrate) {
|
if (!Settings::values.vibration_enabled.GetValue() || !can_controllers_vibrate) {
|
||||||
|
@ -717,17 +740,8 @@ void Controller_NPad::VibrateController(const std::vector<DeviceHandle>& vibrati
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Settings::NativeButton;
|
|
||||||
const auto& button_state = buttons[npad_index];
|
|
||||||
|
|
||||||
// TODO: Vibrate left/right vibration motors independently if possible.
|
// TODO: Vibrate left/right vibration motors independently if possible.
|
||||||
const bool success = button_state[A - BUTTON_HID_BEGIN]->SetRumblePlay(
|
if (VibrateControllerAtIndex(npad_index, vibration_values[i])) {
|
||||||
vibration_values[i].amp_low * Settings::values.vibration_strength.GetValue() / 100,
|
|
||||||
vibration_values[i].freq_low,
|
|
||||||
vibration_values[i].amp_high * Settings::values.vibration_strength.GetValue() / 100,
|
|
||||||
vibration_values[i].freq_high);
|
|
||||||
|
|
||||||
if (success) {
|
|
||||||
switch (connected_controllers[npad_index].type) {
|
switch (connected_controllers[npad_index].type) {
|
||||||
case NPadControllerType::None:
|
case NPadControllerType::None:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
|
|
@ -110,10 +110,10 @@ public:
|
||||||
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
|
static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size");
|
||||||
|
|
||||||
struct VibrationValue {
|
struct VibrationValue {
|
||||||
f32 amp_low;
|
f32 amp_low{0.0f};
|
||||||
f32 freq_low;
|
f32 freq_low{160.0f};
|
||||||
f32 amp_high;
|
f32 amp_high{0.0f};
|
||||||
f32 freq_high;
|
f32 freq_high{320.0f};
|
||||||
};
|
};
|
||||||
static_assert(sizeof(VibrationValue) == 0x10, "Vibration is an invalid size");
|
static_assert(sizeof(VibrationValue) == 0x10, "Vibration is an invalid size");
|
||||||
|
|
||||||
|
@ -148,8 +148,10 @@ public:
|
||||||
|
|
||||||
void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
|
void SetNpadMode(u32 npad_id, NpadAssignments assignment_mode);
|
||||||
|
|
||||||
void VibrateController(const std::vector<DeviceHandle>& vibration_device_handles,
|
bool VibrateControllerAtIndex(std::size_t npad_index, const VibrationValue& vibration_value);
|
||||||
const std::vector<VibrationValue>& vibration_values);
|
|
||||||
|
void VibrateControllers(const std::vector<DeviceHandle>& vibration_device_handles,
|
||||||
|
const std::vector<VibrationValue>& vibration_values);
|
||||||
|
|
||||||
VibrationValue GetLastVibration(const DeviceHandle& vibration_device_handle) const;
|
VibrationValue GetLastVibration(const DeviceHandle& vibration_device_handle) const;
|
||||||
|
|
||||||
|
|
|
@ -1022,7 +1022,7 @@ void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
|
||||||
const auto parameters{rp.PopRaw<Parameters>()};
|
const auto parameters{rp.PopRaw<Parameters>()};
|
||||||
|
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.VibrateController({parameters.vibration_device_handle}, {parameters.vibration_value});
|
.VibrateControllers({parameters.vibration_device_handle}, {parameters.vibration_value});
|
||||||
|
|
||||||
LOG_DEBUG(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
||||||
|
@ -1100,7 +1100,7 @@ void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
|
||||||
std::memcpy(vibration_values.data(), vibrations.data(), vibrations.size());
|
std::memcpy(vibration_values.data(), vibrations.data(), vibrations.size());
|
||||||
|
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.VibrateController(vibration_device_handles, vibration_values);
|
.VibrateControllers(vibration_device_handles, vibration_values);
|
||||||
|
|
||||||
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue