diff --git a/src/core/hle/service/hid/controllers/npad/n64_vibration_device.h b/src/core/hle/service/hid/controllers/npad/n64_vibration_device.h index a2854c2d9..1789c7526 100644 --- a/src/core/hle/service/hid/controllers/npad/n64_vibration_device.h +++ b/src/core/hle/service/hid/controllers/npad/n64_vibration_device.h @@ -26,7 +26,7 @@ public: void FUN_71000b6750(); Result FUN_71000b67b0(long* param_2, NpadVibrationHandler* handler); Result FUN_71000b6898(); - Result FUN_71000b6908(undefined4 param_2); + Result FUN_71000b6908(u32 param_2); private: u64 xcd_handle; 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 e8c209883..d71a792ed 100644 --- a/src/core/hle/service/hid/controllers/npad/vibration_device.cpp +++ b/src/core/hle/service/hid/controllers/npad/vibration_device.cpp @@ -9,233 +9,177 @@ namespace Service::HID { Result NpadVibrationDevice::IncrementRefCounter() { - int iVar1; - char local_4[4]; - - iVar1 = field10_0x14; - field10_0x14 = iVar1 + 1; - if (iVar1 == 0) { - FUN_71000b6a1c(param_1); + if (ref_counter == 0) { + FUN_71000b6a1c(); } - 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); + + ref_counter++; + if (is_mounted != false && xcd_handle->FUN_710011a950(local_4, device_index) != '\x01') { + xcd_handle->FUN_710011a8f0(true, device_index); } 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 (ref_counter == 0) { + return; } - if (cVar1 != '\0') { - local_30 = 1.0; - nVar2 = VibrationVolume::GetVibrationVolume(npad_vibration, &local_30); - if (nVar2 == ResultSuccess) { - FUN_710011ab70(field8_0x8, 0); + if (is_mounted) { + f32 volume = 1.0; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsSuccess()) { + xcd_handle->SendVibrationValue(Core::HID::DEFAULT_VIBRATION_VALUE, device_index); + } + } + + if (is_mounted) { + f32 volume = 1.0; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { return; } + xcd_handle->SendVibrationNotificationPattern(0); } - return; } Result NpadVibrationDevice::DecrementRefCounter() { int iVar1; char local_4[4]; - iVar1 = field10_0x14; - if (iVar1 == 1) { - FUN_71000b6a1c(param_1); - iVar1 = field10_0x14; + if (ref_counter == 1) { + FUN_71000b6a1c(); } - 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--; + if (ref_counter > 0) { + return ResultSuccess; } + + ref_counter = 0; + if (is_mounted && FUN_710011a950(local_4, device_index) == 0) { + xcd_handle->FUN_710011a8f0(0, device_index); + } + return ResultSuccess; } 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 ((int)field10_0x14 < 1) { - return Hid_0121_VibrationDisabled; + if (ref_counter == 0) { + return ResultVibrationNotInitialized; } - 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) { + if (!is_mounted) { return ResultSuccess; } - local_24 = 1.0; - nVar1 = VibrationVolume::GetVibrationVolume(npad_vibration, &local_24); - if (nVar1 != ResultSuccess) { - return nVar1; + + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { + return result; } - if (local_24 <= 0.0) { - param_2 = 0; + if (volume <= 0.0f) { + return xcd_handle->FUN_710011a9b0(Core::HID::DEFAULT_VIBRATION_VALUE, device_index); } - nVar1 = FUN_710011ab70(field8_0x8, param_2); - return nVar1; + + Core::HID::VibrationValue vibration_value = value; + vibration_value.high_amplitude *= volume; + vibration_value.low_amplitude *= volume; + + return xcd_handle->FUN_710011a9b0(vibration_value, device_index); } -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; +Result NpadVibrationDevice::SendVibrationNotificationPattern(u32 param_2) { + if (!is_mounted) { + return ResultSuccess; + } - 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; - } - } + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { + return result; + } + if (volume <= 0.0) { + param_2 = 0; + } + + return xcd_handle->SendVibrationNotificationPattern(param_2); +} + +Result NpadVibrationDevice::FUN_71000b6cc0(IAbstractedPad* abstracted_pad, + Core::HID::VibrationDevicePosition position, + NpadVibrationHandler* handler) { + + Result result = abstracted_pad->driver->UpdateState(); + if (result.IsError()) { + return ResultSuccess; + } + + if (!abstracted_pad->internal_flags.is_connected) { + return ResultSuccess; + } + + xcd_handle = abstracted_pad->xcd_handle; + + switch (position) { + case Core::HID::VibrationDevicePosition ::Left: + device_index = 0; + break; + case Core::HID::VibrationDevicePosition ::Right: + device_index = 1; + break; + default: + // Abort + return; + } + + vibration_handler = handler; + is_mounted = true; + + if (ref_counter == 0) { + return ResultSuccess; + } + + result = FUN_710011a950(&local_48); + if (result.IsSuccess() && (local_48._0_1_ != '\x01')) { + xcd_handle->FUN_710011a8f0(1, device_index); + } + if (ref_counter != 0 && is_mounted) { + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsSuccess()) { + xcd_handle->FUN_710011a9b0(Core::HID::DEFAULT_VIBRATION_VALUE, device_index); } } - 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; - } + if (ref_counter == 0 || !is_mounted) { + is_mounted = false; + return ResultSuccess; } + + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { + is_mounted = false; + return ResultSuccess; + } + is_mounted = false; + xcd_handle->FUN_710011a9b0(Core::HID::DEFAULT_VIBRATION_VALUE, device_index); + return ResultSuccess; } -Result NpadVibrationDevice::FUN_71000b6eb8(u64* param_2) { - Result nVar1; - u32 local_30; - u64 local_2c; - u32 local_24; +Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) { + if (ref_counter < 1) { + return ResultVibrationNotInitialized; + } - if ((int)field10_0x14 < 1) { - return Hid_0121_VibrationDisabled; + out_value = Core::HID::DEFAULT_VIBRATION_VALUE; + if (!is_mounted) { + return ResultSuccess; } - *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; - } - return ResultSuccess; + + return xcd_handle->GetActualVibrationValue(out_value, device_index); } bool NpadVibrationDevice::IsVibrationMounted() { 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 5f98fc035..c6b653858 100644 --- a/src/core/hle/service/hid/controllers/npad/vibration_device.h +++ b/src/core/hle/service/hid/controllers/npad/vibration_device.h @@ -12,6 +12,7 @@ #include "core/hle/service/hid/controllers/types/npad_types.h" namespace Service::HID { +class IAbstractedPad; class NpadVibrationHandler; /// Handles Npad request from HID interfaces @@ -26,15 +27,17 @@ public: Result DecrementRefCounter(); Result SendVibrationValue(const Core::HID::VibrationValue& value); - Result FUN_71000b6c40(u32 param_2); + Result SendVibrationNotificationPattern(u32 param_2); - Result FUN_71000b6cc0(long* param_2, int param_3, NpadVibration* param_4); + Result FUN_71000b6cc0(IAbstractedPad* abstracted_pad, Core::HID::VibrationDevicePosition position, + NpadVibrationHandler* handler); Result FUN_71000b6e0c(); - Result FUN_71000b6eb8(u64* param_2); + Result GetActualVibrationValue(Core::HID::VibrationValue& out_value); bool IsVibrationMounted(); private: u64 xcd_handle; + u32 device_index; s32 ref_counter; bool is_mounted; NpadVibrationHandler* vibration_handler;