service: hid: Fully implement abstract vibration
This commit is contained in:
parent
2c29c2b8dd
commit
2cacb9d48c
31 changed files with 905 additions and 448 deletions
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_result.h"
|
||||
#include "hid_core/resources/npad/npad_types.h"
|
||||
#include "hid_core/resources/npad/npad_vibration.h"
|
||||
|
|
@ -10,24 +11,25 @@ namespace Service::HID {
|
|||
|
||||
NpadGcVibrationDevice::NpadGcVibrationDevice() {}
|
||||
|
||||
Result NpadGcVibrationDevice::IncrementRefCounter() {
|
||||
Result NpadGcVibrationDevice::Activate() {
|
||||
if (ref_counter == 0 && is_mounted) {
|
||||
f32 volume = 1.0f;
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
// TODO: SendVibrationGcErmCommand
|
||||
xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop);
|
||||
}
|
||||
}
|
||||
|
||||
ref_counter++;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadGcVibrationDevice::DecrementRefCounter() {
|
||||
if (ref_counter == 1 && !is_mounted) {
|
||||
Result NpadGcVibrationDevice::Deactivate() {
|
||||
if (ref_counter == 1 && is_mounted) {
|
||||
f32 volume = 1.0f;
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
// TODO: SendVibrationGcErmCommand
|
||||
xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -38,6 +40,48 @@ Result NpadGcVibrationDevice::DecrementRefCounter() {
|
|||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadGcVibrationDevice::Mount(IAbstractedPad& abstracted_pad, u32 slot,
|
||||
NpadVibration* handler) {
|
||||
if (!abstracted_pad.internal_flags.is_connected) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
// TODO: This device doesn't use a xcd handle instead has an GC adapter handle. This is just to
|
||||
// keep compatibility with the front end.
|
||||
xcd_handle = abstracted_pad.xcd_handle;
|
||||
adapter_slot = slot;
|
||||
vibration_handler = handler;
|
||||
is_mounted = true;
|
||||
|
||||
if (ref_counter == 0) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
f32 volume{1.0f};
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop);
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadGcVibrationDevice::Unmount() {
|
||||
if (ref_counter == 0 || !is_mounted) {
|
||||
is_mounted = false;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
f32 volume{1.0f};
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
xcd_handle->SetVibration(adapter_slot, Core::HID::VibrationGcErmCommand::Stop);
|
||||
}
|
||||
|
||||
is_mounted = false;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command) {
|
||||
if (!is_mounted) {
|
||||
return ResultSuccess;
|
||||
|
|
@ -55,7 +99,7 @@ Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcEr
|
|||
return ResultSuccess;
|
||||
}
|
||||
}
|
||||
// TODO: SendVibrationGcErmCommand
|
||||
xcd_handle->SetVibration(adapter_slot, command);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,12 +20,18 @@ class NpadGcVibrationDevice final : public NpadVibrationBase {
|
|||
public:
|
||||
explicit NpadGcVibrationDevice();
|
||||
|
||||
Result IncrementRefCounter() override;
|
||||
Result DecrementRefCounter() override;
|
||||
Result Activate() override;
|
||||
Result Deactivate() override;
|
||||
|
||||
Result Mount(IAbstractedPad& abstracted_pad, u32 slot, NpadVibration* handler);
|
||||
Result Unmount();
|
||||
|
||||
Result SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command);
|
||||
|
||||
Result GetActualVibrationGcErmCommand(Core::HID::VibrationGcErmCommand& out_command);
|
||||
Result SendVibrationNotificationPattern(Core::HID::VibrationGcErmCommand command);
|
||||
|
||||
private:
|
||||
u32 adapter_slot;
|
||||
};
|
||||
} // namespace Service::HID
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_result.h"
|
||||
#include "hid_core/resources/npad/npad_types.h"
|
||||
#include "hid_core/resources/npad/npad_vibration.h"
|
||||
|
|
@ -10,12 +11,12 @@ namespace Service::HID {
|
|||
|
||||
NpadN64VibrationDevice::NpadN64VibrationDevice() {}
|
||||
|
||||
Result NpadN64VibrationDevice::IncrementRefCounter() {
|
||||
Result NpadN64VibrationDevice::Activate() {
|
||||
if (ref_counter == 0 && is_mounted) {
|
||||
f32 volume = 1.0f;
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
// TODO: SendVibrationInBool
|
||||
xcd_handle->SetVibration(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -23,19 +24,12 @@ Result NpadN64VibrationDevice::IncrementRefCounter() {
|
|||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadN64VibrationDevice::DecrementRefCounter() {
|
||||
if (ref_counter == 1) {
|
||||
if (!is_mounted) {
|
||||
ref_counter = 0;
|
||||
if (is_mounted != false) {
|
||||
// TODO: SendVibrationInBool
|
||||
}
|
||||
return ResultSuccess;
|
||||
}
|
||||
Result NpadN64VibrationDevice::Deactivate() {
|
||||
if (ref_counter == 1 && is_mounted) {
|
||||
f32 volume = 1.0f;
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
// TODO
|
||||
xcd_handle->SetVibration(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,6 +40,43 @@ Result NpadN64VibrationDevice::DecrementRefCounter() {
|
|||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadN64VibrationDevice::Mount(IAbstractedPad& abstracted_pad, NpadVibration* handler) {
|
||||
if (!abstracted_pad.internal_flags.is_connected) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
xcd_handle = abstracted_pad.xcd_handle;
|
||||
vibration_handler = handler;
|
||||
is_mounted = true;
|
||||
|
||||
if (ref_counter == 0) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
f32 volume{1.0f};
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
xcd_handle->SetVibration(false);
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadN64VibrationDevice::Unmount() {
|
||||
if (ref_counter == 0 || !is_mounted) {
|
||||
is_mounted = false;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
f32 volume{1.0f};
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
xcd_handle->SetVibration(false);
|
||||
}
|
||||
|
||||
is_mounted = false;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) {
|
||||
if (ref_counter < 1) {
|
||||
return ResultVibrationNotInitialized;
|
||||
|
|
@ -56,7 +87,7 @@ Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) {
|
|||
if (result.IsError()) {
|
||||
return result;
|
||||
}
|
||||
// TODO: SendVibrationInBool
|
||||
xcd_handle->SetVibration(false);
|
||||
}
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,14 +14,18 @@
|
|||
|
||||
namespace Service::HID {
|
||||
class NpadVibration;
|
||||
struct IAbstractedPad;
|
||||
|
||||
/// Handles Npad request from HID interfaces
|
||||
class NpadN64VibrationDevice final : public NpadVibrationBase {
|
||||
public:
|
||||
explicit NpadN64VibrationDevice();
|
||||
|
||||
Result IncrementRefCounter() override;
|
||||
Result DecrementRefCounter() override;
|
||||
Result Activate() override;
|
||||
Result Deactivate() override;
|
||||
|
||||
Result Mount(IAbstractedPad& abstracted_pad, NpadVibration* handler);
|
||||
Result Unmount();
|
||||
|
||||
Result SendValueInBool(bool is_vibrating);
|
||||
Result SendVibrationNotificationPattern(u32 pattern);
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@ namespace Service::HID {
|
|||
|
||||
NpadVibrationBase::NpadVibrationBase() {}
|
||||
|
||||
Result NpadVibrationBase::IncrementRefCounter() {
|
||||
Result NpadVibrationBase::Activate() {
|
||||
ref_counter++;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadVibrationBase::DecrementRefCounter() {
|
||||
Result NpadVibrationBase::Deactivate() {
|
||||
if (ref_counter > 0) {
|
||||
ref_counter--;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@
|
|||
#include "common/common_types.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
namespace Core::HID {
|
||||
class EmulatedController;
|
||||
}
|
||||
|
||||
namespace Service::HID {
|
||||
class NpadVibration;
|
||||
|
||||
|
|
@ -14,13 +18,13 @@ class NpadVibrationBase {
|
|||
public:
|
||||
explicit NpadVibrationBase();
|
||||
|
||||
virtual Result IncrementRefCounter();
|
||||
virtual Result DecrementRefCounter();
|
||||
virtual Result Activate();
|
||||
virtual Result Deactivate();
|
||||
|
||||
bool IsVibrationMounted() const;
|
||||
|
||||
protected:
|
||||
u64 xcd_handle{};
|
||||
Core::HID::EmulatedController* xcd_handle{nullptr};
|
||||
s32 ref_counter{};
|
||||
bool is_mounted{};
|
||||
NpadVibration* vibration_handler{nullptr};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_result.h"
|
||||
#include "hid_core/resources/npad/npad_types.h"
|
||||
#include "hid_core/resources/npad/npad_vibration.h"
|
||||
|
|
@ -10,12 +11,30 @@ namespace Service::HID {
|
|||
|
||||
NpadVibrationDevice::NpadVibrationDevice() {}
|
||||
|
||||
Result NpadVibrationDevice::IncrementRefCounter() {
|
||||
Result NpadVibrationDevice::Activate() {
|
||||
if (ref_counter == 0 && is_mounted) {
|
||||
f32 volume = 1.0f;
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE);
|
||||
// TODO: SendNotificationPattern;
|
||||
}
|
||||
}
|
||||
|
||||
ref_counter++;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadVibrationDevice::DecrementRefCounter() {
|
||||
Result NpadVibrationDevice::Deactivate() {
|
||||
if (ref_counter == 1 && is_mounted) {
|
||||
f32 volume = 1.0f;
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE);
|
||||
// TODO: SendNotificationPattern;
|
||||
}
|
||||
}
|
||||
|
||||
if (ref_counter > 0) {
|
||||
ref_counter--;
|
||||
}
|
||||
|
|
@ -23,6 +42,45 @@ Result NpadVibrationDevice::DecrementRefCounter() {
|
|||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadVibrationDevice::Mount(IAbstractedPad& abstracted_pad, Core::HID::DeviceIndex index,
|
||||
NpadVibration* handler) {
|
||||
if (!abstracted_pad.internal_flags.is_connected) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
xcd_handle = abstracted_pad.xcd_handle;
|
||||
device_index = index;
|
||||
vibration_handler = handler;
|
||||
is_mounted = true;
|
||||
|
||||
if (ref_counter == 0) {
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
f32 volume{1.0f};
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
xcd_handle->SetVibration(false);
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadVibrationDevice::Unmount() {
|
||||
if (ref_counter == 0 || !is_mounted) {
|
||||
is_mounted = false;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
f32 volume{1.0f};
|
||||
const auto result = vibration_handler->GetVibrationVolume(volume);
|
||||
if (result.IsSuccess()) {
|
||||
xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE);
|
||||
}
|
||||
|
||||
is_mounted = false;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& value) {
|
||||
if (ref_counter == 0) {
|
||||
return ResultVibrationNotInitialized;
|
||||
|
|
@ -37,7 +95,7 @@ Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue&
|
|||
return result;
|
||||
}
|
||||
if (volume <= 0.0f) {
|
||||
// TODO: SendVibrationValue
|
||||
xcd_handle->SetVibration(device_index, Core::HID::DEFAULT_VIBRATION_VALUE);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +103,7 @@ Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue&
|
|||
vibration_value.high_amplitude *= volume;
|
||||
vibration_value.low_amplitude *= volume;
|
||||
|
||||
// TODO: SendVibrationValue
|
||||
xcd_handle->SetVibration(device_index, vibration_value);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
|
|
@ -63,11 +121,11 @@ Result NpadVibrationDevice::SendVibrationNotificationPattern([[maybe_unused]] u3
|
|||
pattern = 0;
|
||||
}
|
||||
|
||||
// return xcd_handle->SendVibrationNotificationPattern(pattern);
|
||||
// TODO: SendVibrationNotificationPattern;
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) {
|
||||
Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) const {
|
||||
if (ref_counter < 1) {
|
||||
return ResultVibrationNotInitialized;
|
||||
}
|
||||
|
|
@ -77,7 +135,7 @@ Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& o
|
|||
return ResultSuccess;
|
||||
}
|
||||
|
||||
// TODO: SendVibrationValue
|
||||
out_value = xcd_handle->GetActualVibrationValue(device_index);
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,10 @@
|
|||
#include "hid_core/resources/npad/npad_types.h"
|
||||
#include "hid_core/resources/vibration/vibration_base.h"
|
||||
|
||||
namespace Core::HID {
|
||||
enum class DeviceIndex : u8;
|
||||
}
|
||||
|
||||
namespace Service::HID {
|
||||
class NpadVibration;
|
||||
|
||||
|
|
@ -20,16 +24,20 @@ class NpadVibrationDevice final : public NpadVibrationBase {
|
|||
public:
|
||||
explicit NpadVibrationDevice();
|
||||
|
||||
Result IncrementRefCounter();
|
||||
Result DecrementRefCounter();
|
||||
Result Activate();
|
||||
Result Deactivate();
|
||||
|
||||
Result Mount(IAbstractedPad& abstracted_pad, Core::HID::DeviceIndex index,
|
||||
NpadVibration* handler);
|
||||
Result Unmount();
|
||||
|
||||
Result SendVibrationValue(const Core::HID::VibrationValue& value);
|
||||
Result SendVibrationNotificationPattern(u32 pattern);
|
||||
|
||||
Result GetActualVibrationValue(Core::HID::VibrationValue& out_value);
|
||||
Result GetActualVibrationValue(Core::HID::VibrationValue& out_value) const;
|
||||
|
||||
private:
|
||||
u32 device_index{};
|
||||
Core::HID::DeviceIndex device_index{};
|
||||
};
|
||||
|
||||
} // namespace Service::HID
|
||||
|
|
|
|||
Reference in a new issue