From ad502093835868d5d3ae43caa9faa28c8cb621f2 Mon Sep 17 00:00:00 2001 From: Morph <39850852+Morph1984@users.noreply.github.com> Date: Tue, 10 Nov 2020 12:09:44 -0500 Subject: [PATCH] hid: Reimplement Begin/EndPermitVibrationSession Upon further investigation, these commands allow temporary vibrations even when the "Controller Vibration" system setting is disabled. As a result, vibrations are allowed when either the system setting or this flag is set to true. Therefore, we can only block vibrations when both flags are set to false. --- src/core/hle/service/hid/controllers/npad.cpp | 8 ++++++-- src/core/hle/service/hid/controllers/npad.h | 3 +++ src/core/hle/service/hid/hid.cpp | 11 ++++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index a606ceeec..e2539ded8 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -734,7 +734,7 @@ bool Controller_NPad::VibrateControllerAtIndex(std::size_t npad_index, std::size void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_handle, const VibrationValue& vibration_value) { - if (!Settings::values.vibration_enabled.GetValue()) { + if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { return; } @@ -774,7 +774,7 @@ void Controller_NPad::VibrateController(const DeviceHandle& vibration_device_han void Controller_NPad::VibrateControllers(const std::vector& vibration_device_handles, const std::vector& vibration_values) { - if (!Settings::values.vibration_enabled.GetValue()) { + if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { return; } @@ -811,6 +811,10 @@ void Controller_NPad::InitializeVibrationDeviceAtIndex(std::size_t npad_index, } } +void Controller_NPad::SetPermitVibrationSession(bool permit_vibration_session) { + permit_vibration_session_enabled = permit_vibration_session; +} + bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const { const auto npad_index = NPadIdToIndex(vibration_device_handle.npad_id); const auto device_index = static_cast(vibration_device_handle.device_index); diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 99384524b..160dcbbe3 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -163,6 +163,8 @@ public: void InitializeVibrationDeviceAtIndex(std::size_t npad_index, std::size_t device_index); + void SetPermitVibrationSession(bool permit_vibration_session); + bool IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const; std::shared_ptr GetStyleSetChangedEvent(u32 npad_id) const; @@ -426,6 +428,7 @@ private: std::array styleset_changed_events; std::array, 10> last_vibration_timepoints; std::array, 10> latest_vibration_values{}; + bool permit_vibration_session_enabled{false}; std::array, 10> vibration_devices_mounted{}; std::array connected_controllers{}; std::array unintended_home_button_input_protection{}; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 2e9682bed..902516b29 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -1119,15 +1119,20 @@ void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop()}; - LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", - applet_resource_user_id); + applet_resource->GetController(HidController::NPad) + .SetPermitVibrationSession(true); + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_HID, "(STUBBED) called"); + applet_resource->GetController(HidController::NPad) + .SetPermitVibrationSession(false); + + LOG_DEBUG(Service_HID, "called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS);