From 919b8fa000aef33000f685364560408da62d91eb Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Sun, 31 Dec 2023 13:07:29 -0600 Subject: [PATCH] vibration --- .../abstract/abstract_battery_handler.h | 2 +- .../abstract/abstract_button_handler.h | 2 +- .../abstract/abstract_led_handler.h | 2 +- .../abstract/abstract_mcu_handler.h | 2 +- .../abstract/abstract_pad_holder.h | 2 +- .../abstract/abstract_properties_handler.h | 2 +- .../abstract/abstract_sixaxis_handler.h | 2 +- .../abstract/abstract_vibration_handler.h | 2 +- src/core/hle/service/hid/controllers/npad.cpp | 1 - src/core/hle/service/hid/controllers/npad.h | 3 +- .../hid/controllers/npad/assignment_handler.h | 2 +- .../hid/controllers/npad/vibration_device.cpp | 333 +++++++++++------- .../hid/controllers/npad/vibration_device.h | 19 +- src/core/hle/service/hid/errors.h | 1 + src/core/hle/service/hid/hid_server.cpp | 68 ++-- src/core/hle/service/hid/resource_manager.cpp | 34 +- src/core/hle/service/hid/resource_manager.h | 8 +- 17 files changed, 319 insertions(+), 166 deletions(-) diff --git a/src/core/hle/service/hid/controllers/abstract/abstract_battery_handler.h b/src/core/hle/service/hid/controllers/abstract/abstract_battery_handler.h index 85730c5b9..d81043ec6 100644 --- a/src/core/hle/service/hid/controllers/abstract/abstract_battery_handler.h +++ b/src/core/hle/service/hid/controllers/abstract/abstract_battery_handler.h @@ -12,7 +12,7 @@ class System; } namespace Service::HID { -class AppletResourceHolder; +struct AppletResourceHolder; class NpadAbstractedPadHolder; class NpadAbstractPropertiesHandler; diff --git a/src/core/hle/service/hid/controllers/abstract/abstract_button_handler.h b/src/core/hle/service/hid/controllers/abstract/abstract_button_handler.h index 35a62b792..1fae4efaf 100644 --- a/src/core/hle/service/hid/controllers/abstract/abstract_button_handler.h +++ b/src/core/hle/service/hid/controllers/abstract/abstract_button_handler.h @@ -10,7 +10,7 @@ namespace Service::HID { struct NpadSharedMemoryEntry; -class AppletResourceHolder; +struct AppletResourceHolder; class NpadAbstractedPadHolder; class NpadAbstractPropertiesHandler; diff --git a/src/core/hle/service/hid/controllers/abstract/abstract_led_handler.h b/src/core/hle/service/hid/controllers/abstract/abstract_led_handler.h index 6ad1f48ce..be9b74896 100644 --- a/src/core/hle/service/hid/controllers/abstract/abstract_led_handler.h +++ b/src/core/hle/service/hid/controllers/abstract/abstract_led_handler.h @@ -12,7 +12,7 @@ class System; } namespace Service::HID { -class AppletResourceHolder; +struct AppletResourceHolder; class NpadAbstractedPadHolder; class NpadAbstractPropertiesHandler; diff --git a/src/core/hle/service/hid/controllers/abstract/abstract_mcu_handler.h b/src/core/hle/service/hid/controllers/abstract/abstract_mcu_handler.h index d5e7ba136..8597d5577 100644 --- a/src/core/hle/service/hid/controllers/abstract/abstract_mcu_handler.h +++ b/src/core/hle/service/hid/controllers/abstract/abstract_mcu_handler.h @@ -8,7 +8,7 @@ #include "core/hle/result.h" namespace Service::HID { -class IAbstractedPad; +struct IAbstractedPad; class NpadAbstractedPadHolder; class NpadAbstractPropertiesHandler; diff --git a/src/core/hle/service/hid/controllers/abstract/abstract_pad_holder.h b/src/core/hle/service/hid/controllers/abstract/abstract_pad_holder.h index 39d7ab5fc..fe3bfa571 100644 --- a/src/core/hle/service/hid/controllers/abstract/abstract_pad_holder.h +++ b/src/core/hle/service/hid/controllers/abstract/abstract_pad_holder.h @@ -13,7 +13,7 @@ #include "core/hle/service/hid/controllers/types/npad_types.h" namespace Service::HID { -class IAbstractedPad; +struct IAbstractedPad; struct AbstracAssignmentHolder { IAbstractedPad* abstracted_pad; diff --git a/src/core/hle/service/hid/controllers/abstract/abstract_properties_handler.h b/src/core/hle/service/hid/controllers/abstract/abstract_properties_handler.h index 825078ac0..b2f016159 100644 --- a/src/core/hle/service/hid/controllers/abstract/abstract_properties_handler.h +++ b/src/core/hle/service/hid/controllers/abstract/abstract_properties_handler.h @@ -10,7 +10,7 @@ namespace Service::HID { struct NpadSharedMemoryEntry; -class AppletResourceHolder; +struct AppletResourceHolder; class NpadAbstractedPadHolder; struct ColorProperties { diff --git a/src/core/hle/service/hid/controllers/abstract/abstract_sixaxis_handler.h b/src/core/hle/service/hid/controllers/abstract/abstract_sixaxis_handler.h index 481bebf3a..6ea918a78 100644 --- a/src/core/hle/service/hid/controllers/abstract/abstract_sixaxis_handler.h +++ b/src/core/hle/service/hid/controllers/abstract/abstract_sixaxis_handler.h @@ -9,7 +9,7 @@ namespace Service::HID { class SixAxisResource; -class AppletResourceHolder; +struct AppletResourceHolder; class NpadAbstractedPadHolder; class NpadAbstractPropertiesHandler; diff --git a/src/core/hle/service/hid/controllers/abstract/abstract_vibration_handler.h b/src/core/hle/service/hid/controllers/abstract/abstract_vibration_handler.h index 3855d7616..6a9ecbdf3 100644 --- a/src/core/hle/service/hid/controllers/abstract/abstract_vibration_handler.h +++ b/src/core/hle/service/hid/controllers/abstract/abstract_vibration_handler.h @@ -10,7 +10,7 @@ #include "core/hle/result.h" namespace Service::HID { -class AppletResourceHolder; +struct AppletResourceHolder; class NpadAbstractedPadHolder; class NpadAbstractPropertiesHandler; class NpadGcVibrationDevice; diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 3f7f1de6f..5179af332 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -11,7 +11,6 @@ #include "core/hle/service/hid/controllers/abstract/abstract_vibration_handler.h" #include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/controllers/npad/unique_pad.h" -#include "core/hle/service/hid/controllers/npad/vibration_handler.h" #include "core/hle/service/hid/controllers/types/npad_types.h" #include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hid_util.h" diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 7ad97be69..6f3f220b8 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -14,6 +14,7 @@ #include "core/hle/service/hid/controllers/npad/assignment_handler.h" #include "core/hle/service/hid/controllers/npad/npad_resource.h" #include "core/hle/service/hid/controllers/npad/palma_handler.h" +#include "core/hle/service/hid/controllers/npad/vibration_handler.h" #include "core/hle/service/hid/controllers/types/npad_types.h" namespace Kernel { @@ -31,7 +32,7 @@ class UniquePads; class UniquePadResource; class NpadVibrationHandler; class NpadHighestBattery; -class AppletResourceHolder; +struct AppletResourceHolder; class NpadAppletResource; class NpadN64VibrationDevice; class NpadGcVibrationDevice; diff --git a/src/core/hle/service/hid/controllers/npad/assignment_handler.h b/src/core/hle/service/hid/controllers/npad/assignment_handler.h index 924dd5fa6..b0a069169 100644 --- a/src/core/hle/service/hid/controllers/npad/assignment_handler.h +++ b/src/core/hle/service/hid/controllers/npad/assignment_handler.h @@ -13,7 +13,7 @@ #include "core/hle/service/hid/controllers/types/npad_types.h" namespace Service::HID { -class AppletResourceHolder; +struct AppletResourceHolder; class AbstractPad; using FullAbstractPad = std::array; class LastActiveNpad; diff --git a/src/core/hle/service/hid/controllers/npad/vibration_device.cpp b/src/core/hle/service/hid/controllers/npad/vibration_device.cpp index 0a61be99b..e8c209883 100644 --- a/src/core/hle/service/hid/controllers/npad/vibration_device.cpp +++ b/src/core/hle/service/hid/controllers/npad/vibration_device.cpp @@ -7,148 +7,239 @@ #include "core/hle/service/hid/errors.h" namespace Service::HID { -void NpadGcVibration::FUN_7100087ed4(u64 param_2) { - *(u64*)&field_0x20 = param_2; + +Result NpadVibrationDevice::IncrementRefCounter() { + int iVar1; + char local_4[4]; + + iVar1 = field10_0x14; + field10_0x14 = iVar1 + 1; + if (iVar1 == 0) { + FUN_71000b6a1c(param_1); + } + if (((is_mounted != false) && + (iVar1 = FUN_710011a950(local_4, field9_0x10, field8_0x8), iVar1 == 0)) && + (local_4[0] != '\x01')) { + FUN_710011a8f0(1, field9_0x10, field8_0x8); + } + return ResultSuccess; +} + +void NpadVibrationDevice::FUN_71000b6a1c() { + char cVar1; + Result nVar2; + float local_30; + u32 local_2c; + float local_28; + u32 local_24; + float local_4; + + cVar1 = is_mounted; + if (0 < (int)field10_0x14 && (bool)cVar1 != false) { + local_4 = 1.0; + nVar2 = VibrationVolume::GetVibrationVolume(npad_vibration, &local_4); + if (nVar2 == ResultSuccess) { + local_2c = 0x43200000; + local_24 = 0x43a00000; + local_30 = local_4 * 0.0; + if (local_4 <= 0.0) { + local_30 = 0.0; + } + local_28 = local_30; + FUN_710011a9b0(&local_30, field9_0x10, field8_0x8); + } + cVar1 = is_mounted; + } + if (cVar1 != '\0') { + local_30 = 1.0; + nVar2 = VibrationVolume::GetVibrationVolume(npad_vibration, &local_30); + if (nVar2 == ResultSuccess) { + FUN_710011ab70(field8_0x8, 0); + return; + } + } return; } -Result NpadGcVibration::IncrementRefCounter() { - if (ref_counter == 0 && is_initialized) { - f32 volume = 1.0f; - const auto result = vibration_handler->GetVibrationVolume(volume); - if (result.IsSuccess()) { - FUN_7100088f4c(field_0x20, field_0x10, '\0'); - } +Result NpadVibrationDevice::DecrementRefCounter() { + int iVar1; + char local_4[4]; + + iVar1 = field10_0x14; + if (iVar1 == 1) { + FUN_71000b6a1c(param_1); + iVar1 = field10_0x14; + } + field10_0x14 = iVar1 + -1; + if ((((iVar1 + -1 == 0 || iVar1 < 1) && (field10_0x14 = 0, is_mounted != false)) && + (iVar1 = FUN_710011a950(local_4, field9_0x10, field8_0x8), iVar1 == 0)) && + (local_4[0] != '\0')) { + FUN_710011a8f0(0, field9_0x10, field8_0x8); } - ref_counter++; return ResultSuccess; } -Result NpadGcVibration::SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command) { - char cVar2; +Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& value) { + Result nVar1; + float local_38; + float local_34; + float fStack_30; + float local_2c; + float local_24; - if (!is_initialized) { + if ((int)field10_0x14 < 1) { + return Hid_0121_VibrationDisabled; + } + if (is_mounted != false) { + local_24 = 1.0; + nVar1 = VibrationVolume::GetVibrationVolume(npad_vibration, &local_24); + if (nVar1 != ResultSuccess) { + return nVar1; + } + if (local_24 <= 0.0) { + fStack_30 = 0.0; + local_38 = 0.0; + local_2c = 320.0; + local_34 = 160.0; + } else { + local_34 = param_2[1]; + local_38 = local_24 * *param_2; + local_2c = param_2[3]; + fStack_30 = local_24 * param_2[2]; + } + nVar1 = FUN_710011a9b0(&local_38, field9_0x10, field8_0x8); + return nVar1; + } + return ResultSuccess; +} + +Result NpadVibrationDevice::FUN_71000b6c40(u32 param_2) { + Result nVar1; + float local_24; + + if (is_mounted == false) { return ResultSuccess; } - f32 volume = 1.0f; - const auto result = vibration_handler->GetVibrationVolume(volume); - if (result.IsError()) { - return result; + local_24 = 1.0; + nVar1 = VibrationVolume::GetVibrationVolume(npad_vibration, &local_24); + if (nVar1 != ResultSuccess) { + return nVar1; } - if (volume == 0.0) { - cVar2 = '\0'; - } else { - if (command > Core::HID::VibrationGcErmCommand::StopHard) { - // Abort - } - cVar2 = (char)(0x100100 >> (u64)(((u32)*param_2 & 3) << 3)); + if (local_24 <= 0.0) { + param_2 = 0; } - FUN_7100088f4c(field_0x20, field_0x10, cVar2); - return ResultSuccess; + nVar1 = FUN_710011ab70(field8_0x8, param_2); + return nVar1; } -Result NpadGcVibration::DecrementRefCounter() { - if (ref_counter == 1 && !is_initialized) { - f32 volume = 1.0f; - const auto result = vibration_handler->GetVibrationVolume(volume); - if (result.IsSuccess()) { - FUN_7100088f4c(field_0x20, field_0x10, '\0'); - } - } - - if (ref_counter > 1) { - ref_counter--; - } - return ResultSuccess; -} - -NpadGcVibration* NpadGcVibration::FUN_7100088080() { - pNVar2 = param_1; - if (param_1->is_initialized) { - f32 volume = 1.0f; - const auto result = vibration_handler->GetVibrationVolume(volume); - if (result.IsSuccess()) { - nVar1 = FUN_7100088f4c(field_0x20, field_0x10, '\0'); - return (NpadGcVibration*)(u64)nVar1; - } - } - return pNVar2; -} - -Result NpadGcVibration::FUN_71000880d8(u64 param_2, u64 param_3, NpadVibrationHandler* handler) { +Result NpadVibrationDevice::FUN_71000b6cc0(long* param_2, int param_3, NpadVibration* param_4) { int iVar1; + Result nVar2; + u64 uVar3; + u32 uVar4; + undefined auVar5[16]; + float local_48; + u32 local_44; + float local_40; + u32 local_3c; + float local_34; + + iVar1 = (**(code**)(*param_2 + 0x18))(param_2); + if ((iVar1 == 0) && ((*(byte*)(param_2 + 1) >> 1 & 1) != 0)) { + auVar5 = GetXcdHandle(param_2); + uVar3 = auVar5._0_8_; + field8_0x8 = uVar3; + if (param_3 == 1) { + uVar4 = 0; + } else { + if (param_3 != 2) { + // WARNING: Subroutine does not return + nn::detail::UnexpectedDefaultImpl(uVar3, auVar5._8_8_, uVar3); + } + uVar4 = 1; + } + field9_0x10 = uVar4; + npad_vibration = param_4; + is_mounted = true; + if (0 < (int)field10_0x14) { + iVar1 = FUN_710011a950(&local_48); + if ((iVar1 == 0) && (local_48._0_1_ != '\x01')) { + FUN_710011a8f0(1, field9_0x10, field8_0x8); + } + if ((0 < (int)field10_0x14) && (is_mounted != false)) { + local_34 = 1.0; + nVar2 = VibrationVolume::GetVibrationVolume(npad_vibration, &local_34); + if (nVar2 == ResultSuccess) { + local_44 = 0x43200000; + local_3c = 0x43a00000; + local_48 = local_34 * 0.0; + if (local_34 <= 0.0) { + local_48 = 0.0; + } + local_40 = local_48; + FUN_710011a9b0(&local_48, field9_0x10, field8_0x8); + return ResultSuccess; + } + } + } + } + return ResultSuccess; +} + +Result NpadVibrationDevice::FUN_71000b6e0c() { + Result nVar1; + float local_30; + u32 local_2c; + float local_28; + u32 local_24; + float local_4; + + if (0 < (int)field10_0x14 && is_mounted != false) { + local_4 = 1.0; + nVar1 = VibrationVolume::GetVibrationVolume(npad_vibration, &local_4); + if (nVar1 == ResultSuccess) { + local_2c = 0x43200000; + local_24 = 0x43a00000; + local_30 = local_4 * 0.0; + if (local_4 <= 0.0) { + local_30 = 0.0; + } + local_28 = local_30; + FUN_710011a9b0(&local_30, field9_0x10, field8_0x8); + is_mounted = false; + return ResultSuccess; + } + } + is_mounted = false; + return ResultSuccess; +} + +Result NpadVibrationDevice::FUN_71000b6eb8(u64* param_2) { + Result nVar1; + u32 local_30; + u64 local_2c; u32 local_24; - *(u64*)&field_0x10 = param_2; - *(u64*)&field_0x18 = param_3; - is_initialized = true; - vibration_handler = handler; - - f32 volume = 1.0f; - const auto result = vibration_handler->GetVibrationVolume(volume); - if (result.IsError()) { - return ResultSuccess; + if ((int)field10_0x14 < 1) { + return Hid_0121_VibrationDisabled; + } + *param_2 = 0x4320000000000000; + param_2[1] = 0x43a0000000000000; + if (is_mounted != false) { + nVar1 = FUN_710011aa90(&local_30, field9_0x10, field8_0x8); + if (nVar1 != ResultSuccess) { + return nVar1; + } + *(u32*)param_2 = local_30; + *(u64*)((long)param_2 + 4) = local_2c; + *(u32*)((long)param_2 + 0xc) = local_24; + return nVar1; } - - FUN_7100088f4c(field_0x20, field_0x10, '\0'); return ResultSuccess; } -Result NpadGcVibration::FUN_7100088150() { - if (!is_initialized) { - return ResultSuccess; - } - - f32 volume = 1.0f; - const auto result = vibration_handler->GetVibrationVolume(volume); - if (result.IsSuccess()) { - FUN_7100088f4c(field_0x20, field_0x10, '\0'); - } - - is_initialized = false; - return ResultSuccess; -} - -Result NpadGcVibration::GetActualVibrationGcErmCommand(Core::HID::VibrationGcErmCommand& command) { - if (!is_initialized) { - command = Core::HID::VibrationGcErmCommand::Stop; - return ResultSuccess; - } - - f32 volume = 1.0f; - const auto result = vibration_handler->GetVibrationVolume(volume); - if (result.IsError()) { - return result; - } - if (volume == 0.0f) { - command = Core::HID::VibrationGcErmCommand::Stop; - return ResultSuccess; - } - - command = FUN_7100089310(field_0x20, field_0x10); - return ResultSuccess; -} - -Result NpadGcVibration::FUN_7100088270(Core::HID::VibrationGcErmCommand command) { - if (!is_initialized) { - return ResultSuccess; - } - - f32 volume = 1.0f; - const auto result = vibration_handler->GetVibrationVolume(volume); - if (result.IsError()) { - return result; - } - if (volume <= 0.0f) { - command = Core::HID::VibrationGcErmCommand::Stop; - } - if (command > Core::HID::VibrationGcErmCommand::StopHard) { - // Abort - return ResultSuccess; - } - - FUN_71000891d0(field_0x20, field_0x10, (&DAT_71001b99a0 + (long)(int)command * 4)); - return ResultSuccess; +bool NpadVibrationDevice::IsVibrationMounted() { + return is_mounted; } } // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad/vibration_device.h b/src/core/hle/service/hid/controllers/npad/vibration_device.h index 370ec3a1d..5f98fc035 100644 --- a/src/core/hle/service/hid/controllers/npad/vibration_device.h +++ b/src/core/hle/service/hid/controllers/npad/vibration_device.h @@ -20,24 +20,23 @@ public: explicit NpadVibrationDevice(); ~NpadVibrationDevice(); - void FUN_7100087ed4(u64 param_2); - Result IncrementRefCounter(); - Result SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command); + void FUN_71000b6a1c(); Result DecrementRefCounter(); - NpadGcVibration* FUN_7100088080(); + Result SendVibrationValue(const Core::HID::VibrationValue& value); + Result FUN_71000b6c40(u32 param_2); - Result FUN_71000880d8(u64 param_2, u64 param_3, NpadVibrationHandler* handler); - Result FUN_7100088150(); - - Result GetActualVibrationGcErmCommand(Core::HID::VibrationGcErmCommand& command); - Result FUN_7100088270(Core::HID::VibrationGcErmCommand command); + Result FUN_71000b6cc0(long* param_2, int param_3, NpadVibration* param_4); + Result FUN_71000b6e0c(); + Result FUN_71000b6eb8(u64* param_2); + bool IsVibrationMounted(); private: + u64 xcd_handle; s32 ref_counter; - bool is_initialized; + bool is_mounted; NpadVibrationHandler* vibration_handler; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index be6a06360..bb14aa61e 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h @@ -16,6 +16,7 @@ constexpr Result ResultVibrationInvalidStyleIndex{ErrorModule::HID, 122}; constexpr Result ResultVibrationInvalidNpadId{ErrorModule::HID, 123}; constexpr Result ResultVibrationDeviceIndexOutOfRange{ErrorModule::HID, 124}; constexpr Result ResultVibrationStrenghtOutOfRange{ErrorModule::HID, 126}; +constexpr Result ResultVibrationArraySizeMismatch{ErrorModule::HID, 131}; constexpr Result InvalidSixAxisFusionRange{ErrorModule::HID, 423}; diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index 638913e1c..a30bea7ce 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -24,7 +24,9 @@ #include "core/hle/service/hid/controllers/keyboard.h" #include "core/hle/service/hid/controllers/mouse.h" #include "core/hle/service/hid/controllers/npad.h" -#include "core/hle/service/hid/controllers/npad/vibration_gc_handler.h" +#include "core/hle/service/hid/controllers/npad/gc_vibration_device.h" +#include "core/hle/service/hid/controllers/npad/n64_vibration_device.h" +#include "core/hle/service/hid/controllers/npad/vibration_device.h" #include "core/hle/service/hid/controllers/npad/vibration_handler.h" #include "core/hle/service/hid/controllers/palma.h" #include "core/hle/service/hid/controllers/seven_six_axis.h" @@ -1555,15 +1557,16 @@ void IHidServer::SendVibrationValue(HLERequestContext& ctx) { const auto parameters{rp.PopRaw()}; - GetResourceManager()->GetNpad()->VibrateController(parameters.vibration_device_handle, - parameters.vibration_value); - LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", parameters.vibration_device_handle.npad_type, parameters.vibration_device_handle.npad_id, parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); + GetResourceManager()->SendVibrationValue(parameters.applet_resource_user_id, + parameters.vibration_device_handle, + parameters.vibration_value); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -1603,25 +1606,27 @@ void IHidServer::PermitVibration(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto can_vibrate{rp.Pop()}; - // nnSDK saves this value as a float. Since it can only be 1.0f or 0.0f we simplify this value - // by converting it to a bool - Settings::values.vibration_enabled.SetValue(can_vibrate); - LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate); + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->SetVibrationMasterVolume( + can_vibrate ? 1.0f : 0.0f); + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void IHidServer::IsVibrationPermitted(HLERequestContext& ctx) { LOG_DEBUG(Service_HID, "called"); - // nnSDK checks if a float is greater than zero. We return the bool we stored earlier - const auto is_enabled = Settings::values.vibration_enabled.GetValue(); + f32 master_volume{}; + const auto result = + GetResourceManager()->GetNpad()->GetVibrationHandler()->GetVibrationMasterVolume( + master_volume); IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(is_enabled); + rb.Push(result); + rb.Push(master_volume > 0.0f); } void IHidServer::SendVibrationValues(HLERequestContext& ctx) { @@ -1639,12 +1644,22 @@ void IHidServer::SendVibrationValues(HLERequestContext& ctx) { auto vibration_values = std::span( reinterpret_cast(vibration_data.data()), vibration_count); - GetResourceManager()->GetNpad()->VibrateControllers(vibration_device_handles, vibration_values); - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + Result result = ResultSuccess; + if (handle_count != vibration_count) { + result = ResultVibrationArraySizeMismatch; + } + + for (std::size_t i = 0; i < handle_count; i++) { + if (result.IsSuccess()) { + result = GetResourceManager()->SendVibrationValue( + applet_resource_user_id, vibration_device_handles[i], vibration_values[i]); + } + } + IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + rb.Push(result); } void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) { @@ -1668,7 +1683,7 @@ void IHidServer::SendVibrationGcErmCommand(HLERequestContext& ctx) { parameters.gc_erm_command); bool has_active_aruid{}; - NpadGcVibration* gc_device{nullptr}; + NpadGcVibrationDevice* gc_device{nullptr}; Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id, has_active_aruid); @@ -1703,7 +1718,7 @@ void IHidServer::GetActualVibrationGcErmCommand(HLERequestContext& ctx) { parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); bool has_active_aruid{}; - NpadGcVibration* gc_device{nullptr}; + NpadGcVibrationDevice* gc_device{nullptr}; Core::HID::VibrationGcErmCommand gc_erm_command{}; Result result = GetResourceManager()->IsVibrationAruidActive(parameters.applet_resource_user_id, has_active_aruid); @@ -1766,10 +1781,21 @@ void IHidServer::IsVibrationDeviceMounted(HLERequestContext& ctx) { parameters.vibration_device_handle.npad_id, parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); + bool is_mounted{}; + NpadVibrationDevice* device{nullptr}; + Result result = IsVibrationHandleValid(parameters.vibration_device_handle); + + if (result.IsSuccess()) { + device = GetResourceManager()->GetVibrationDevice(parameters.vibration_device_handle); + } + + if (device != nullptr) { + is_mounted = device->IsVibrationMounted(); + } + IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(GetResourceManager()->GetNpad()->IsVibrationDeviceMounted( - parameters.vibration_device_handle)); + rb.Push(result); + rb.Push(is_mounted); } void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) { diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp index d744e90ec..959623793 100644 --- a/src/core/hle/service/hid/resource_manager.cpp +++ b/src/core/hle/service/hid/resource_manager.cpp @@ -6,6 +6,7 @@ #include "core/core_timing.h" #include "core/hid/hid_core.h" #include "core/hle/kernel/k_shared_memory.h" +#include "core/hle/service/hid/hid_util.h" #include "core/hle/service/hid/resource_manager.h" #include "core/hle/service/ipc_helpers.h" @@ -267,11 +268,42 @@ Result ResourceManager::IsVibrationAruidActive(u64 aruid, bool& is_active) { return ResultSuccess; } -NpadGcVibration* ResourceManager::GetGcVibrationDevice( +NpadN64VibrationDevice* ResourceManager::GetN64VibrationDevice( + const Core::HID::VibrationDeviceHandle& handle) { + return npad->GetN64VibrationDevice(handle); +} + +NpadVibrationDevice* ResourceManager::GetVibrationDevice( + const Core::HID::VibrationDeviceHandle& handle) { + return npad->GetVibrationDevice(handle); +} + +NpadGcVibrationDevice* ResourceManager::GetGcVibrationDevice( const Core::HID::VibrationDeviceHandle& handle) { return npad->GetGCVibrationDevice(handle); } +Result ResourceManager::SendVibrationValue(u64 aruid, + const Core::HID::VibrationDeviceHandle& handle, + const Core::HID::VibrationValue& value) { + + bool has_active_aruid{}; + NpadVibrationDevice* device{nullptr}; + Core::HID::VibrationGcErmCommand gc_erm_command{}; + Result result = IsVibrationAruidActive(aruid, has_active_aruid); + + if (result.IsSuccess() && has_active_aruid) { + result = IsVibrationHandleValid(handle); + } + if (result.IsSuccess() && has_active_aruid) { + device = GetVibrationDevice(handle); + } + if (device != nullptr) { + result = device->SendVibrationValue(value); + } + return result; +} + IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr resource, u64 applet_resource_user_id) : ServiceFramework{system_, "IAppletResource"}, aruid{applet_resource_user_id}, diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h index 179de7edf..f6bc802e1 100644 --- a/src/core/hle/service/hid/resource_manager.h +++ b/src/core/hle/service/hid/resource_manager.h @@ -27,7 +27,7 @@ class Gesture; class Keyboard; class Mouse; class NPad; -class NpadGcVibration; +class NpadGcVibrationDevice; class Palma; class SevenSixAxis; class SixAxis; @@ -88,7 +88,11 @@ public: void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); Result IsVibrationAruidActive(u64 aruid, bool& is_active); - NpadGcVibration* GetGcVibrationDevice(const Core::HID::VibrationDeviceHandle& handle); + NpadN64VibrationDevice* GetN64VibrationDevice(const Core::HID::VibrationDeviceHandle& handle); + NpadVibrationDevice* GetVibrationDevice(const Core::HID::VibrationDeviceHandle& handle); + NpadGcVibrationDevice* GetGcVibrationDevice(const Core::HID::VibrationDeviceHandle& handle); + Result SendVibrationValue(u64 aruid, const Core::HID::VibrationDeviceHandle& handle, + const Core::HID::VibrationValue& value); private: Result CreateAppletResourceImpl(u64 aruid);