From b5dac5f525e8d5884506ebd98a530e237b518480 Mon Sep 17 00:00:00 2001 From: german77 Date: Sun, 7 Jan 2024 09:05:12 -0600 Subject: service: hid: Create abstracted pad structure --- .../resources/vibration/gc_vibration_device.cpp | 106 +++++++++++++++++++++ .../resources/vibration/gc_vibration_device.h | 31 ++++++ .../resources/vibration/n64_vibration_device.cpp | 80 ++++++++++++++++ .../resources/vibration/n64_vibration_device.h | 29 ++++++ .../resources/vibration/vibration_base.cpp | 30 ++++++ src/hid_core/resources/vibration/vibration_base.h | 28 ++++++ .../resources/vibration/vibration_device.cpp | 84 ++++++++++++++++ .../resources/vibration/vibration_device.h | 35 +++++++ 8 files changed, 423 insertions(+) create mode 100644 src/hid_core/resources/vibration/gc_vibration_device.cpp create mode 100644 src/hid_core/resources/vibration/gc_vibration_device.h create mode 100644 src/hid_core/resources/vibration/n64_vibration_device.cpp create mode 100644 src/hid_core/resources/vibration/n64_vibration_device.h create mode 100644 src/hid_core/resources/vibration/vibration_base.cpp create mode 100644 src/hid_core/resources/vibration/vibration_base.h create mode 100644 src/hid_core/resources/vibration/vibration_device.cpp create mode 100644 src/hid_core/resources/vibration/vibration_device.h (limited to 'src/hid_core/resources/vibration') diff --git a/src/hid_core/resources/vibration/gc_vibration_device.cpp b/src/hid_core/resources/vibration/gc_vibration_device.cpp new file mode 100644 index 000000000..f01f81b9a --- /dev/null +++ b/src/hid_core/resources/vibration/gc_vibration_device.cpp @@ -0,0 +1,106 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "hid_core/hid_result.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/npad/npad_vibration.h" +#include "hid_core/resources/vibration/gc_vibration_device.h" + +namespace Service::HID { + +NpadGcVibrationDevice::NpadGcVibrationDevice() {} + +Result NpadGcVibrationDevice::IncrementRefCounter() { + if (ref_counter == 0 && is_mounted) { + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsSuccess()) { + // TODO: SendVibrationGcErmCommand + } + } + ref_counter++; + return ResultSuccess; +} + +Result NpadGcVibrationDevice::DecrementRefCounter() { + if (ref_counter == 1 && !is_mounted) { + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsSuccess()) { + // TODO: SendVibrationGcErmCommand + } + } + + if (ref_counter > 0) { + ref_counter--; + } + + return ResultSuccess; +} + +Result NpadGcVibrationDevice::SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command) { + if (!is_mounted) { + return ResultSuccess; + } + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { + return result; + } + if (volume == 0.0) { + command = Core::HID::VibrationGcErmCommand::Stop; + } else { + if (command > Core::HID::VibrationGcErmCommand::StopHard) { + // Abort + return ResultSuccess; + } + } + // TODO: SendVibrationGcErmCommand + return ResultSuccess; +} + +Result NpadGcVibrationDevice::GetActualVibrationGcErmCommand( + Core::HID::VibrationGcErmCommand& out_command) { + if (!is_mounted) { + out_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) { + out_command = Core::HID::VibrationGcErmCommand::Stop; + return ResultSuccess; + } + + // TODO: GetActualVibrationGcErmCommand + return ResultSuccess; +} + +Result NpadGcVibrationDevice::SendVibrationNotificationPattern( + Core::HID::VibrationGcErmCommand command) { + if (!is_mounted) { + 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; + } + + // TODO: SendVibrationNotificationPattern + return ResultSuccess; +} + +} // namespace Service::HID diff --git a/src/hid_core/resources/vibration/gc_vibration_device.h b/src/hid_core/resources/vibration/gc_vibration_device.h new file mode 100644 index 000000000..87abca57d --- /dev/null +++ b/src/hid_core/resources/vibration/gc_vibration_device.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include + +#include "common/common_types.h" +#include "core/hle/result.h" +#include "hid_core/hid_types.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/vibration/vibration_base.h" + +namespace Service::HID { +class NpadVibration; + +/// Handles Npad request from HID interfaces +class NpadGcVibrationDevice final : public NpadVibrationBase { +public: + explicit NpadGcVibrationDevice(); + + Result IncrementRefCounter() override; + Result DecrementRefCounter() override; + + Result SendVibrationGcErmCommand(Core::HID::VibrationGcErmCommand command); + + Result GetActualVibrationGcErmCommand(Core::HID::VibrationGcErmCommand& out_command); + Result SendVibrationNotificationPattern(Core::HID::VibrationGcErmCommand command); +}; +} // namespace Service::HID diff --git a/src/hid_core/resources/vibration/n64_vibration_device.cpp b/src/hid_core/resources/vibration/n64_vibration_device.cpp new file mode 100644 index 000000000..639f87abf --- /dev/null +++ b/src/hid_core/resources/vibration/n64_vibration_device.cpp @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "hid_core/hid_result.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/npad/npad_vibration.h" +#include "hid_core/resources/vibration/n64_vibration_device.h" + +namespace Service::HID { + +NpadN64VibrationDevice::NpadN64VibrationDevice() {} + +Result NpadN64VibrationDevice::IncrementRefCounter() { + if (ref_counter == 0 && is_mounted) { + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsSuccess()) { + // TODO: SendVibrationInBool + } + } + + ref_counter++; + return ResultSuccess; +} + +Result NpadN64VibrationDevice::DecrementRefCounter() { + if (ref_counter == 1) { + if (!is_mounted) { + ref_counter = 0; + if (is_mounted != false) { + // TODO: SendVibrationInBool + } + return ResultSuccess; + } + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsSuccess()) { + // TODO + } + } + + if (ref_counter > 0) { + ref_counter--; + } + + return ResultSuccess; +} + +Result NpadN64VibrationDevice::SendValueInBool(bool is_vibrating) { + if (ref_counter < 1) { + return ResultVibrationNotInitialized; + } + if (is_mounted) { + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { + return result; + } + // TODO: SendVibrationInBool + } + return ResultSuccess; +} + +Result NpadN64VibrationDevice::SendVibrationNotificationPattern([[maybe_unused]] u32 pattern) { + if (!is_mounted) { + return ResultSuccess; + } + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { + return result; + } + if (volume <= 0.0) { + pattern = 0; + } + // TODO: SendVibrationNotificationPattern + return ResultSuccess; +} + +} // namespace Service::HID diff --git a/src/hid_core/resources/vibration/n64_vibration_device.h b/src/hid_core/resources/vibration/n64_vibration_device.h new file mode 100644 index 000000000..54e6efc1a --- /dev/null +++ b/src/hid_core/resources/vibration/n64_vibration_device.h @@ -0,0 +1,29 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include + +#include "common/common_types.h" +#include "core/hle/result.h" +#include "hid_core/hid_types.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/vibration/vibration_base.h" + +namespace Service::HID { +class NpadVibration; + +/// Handles Npad request from HID interfaces +class NpadN64VibrationDevice final : public NpadVibrationBase { +public: + explicit NpadN64VibrationDevice(); + + Result IncrementRefCounter() override; + Result DecrementRefCounter() override; + + Result SendValueInBool(bool is_vibrating); + Result SendVibrationNotificationPattern(u32 pattern); +}; +} // namespace Service::HID diff --git a/src/hid_core/resources/vibration/vibration_base.cpp b/src/hid_core/resources/vibration/vibration_base.cpp new file mode 100644 index 000000000..350f349c2 --- /dev/null +++ b/src/hid_core/resources/vibration/vibration_base.cpp @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "hid_core/hid_result.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/npad/npad_vibration.h" +#include "hid_core/resources/vibration/vibration_base.h" + +namespace Service::HID { + +NpadVibrationBase::NpadVibrationBase() {} + +Result NpadVibrationBase::IncrementRefCounter() { + ref_counter++; + return ResultSuccess; +} + +Result NpadVibrationBase::DecrementRefCounter() { + if (ref_counter > 0) { + ref_counter--; + } + + return ResultSuccess; +} + +bool NpadVibrationBase::IsVibrationMounted() const { + return is_mounted; +} + +} // namespace Service::HID diff --git a/src/hid_core/resources/vibration/vibration_base.h b/src/hid_core/resources/vibration/vibration_base.h new file mode 100644 index 000000000..c6c5fc4d9 --- /dev/null +++ b/src/hid_core/resources/vibration/vibration_base.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include "common/common_types.h" +#include "core/hle/result.h" + +namespace Service::HID { +class NpadVibration; + +/// Handles Npad request from HID interfaces +class NpadVibrationBase { +public: + explicit NpadVibrationBase(); + + virtual Result IncrementRefCounter(); + virtual Result DecrementRefCounter(); + + bool IsVibrationMounted() const; + +protected: + u64 xcd_handle{}; + s32 ref_counter{}; + bool is_mounted{}; + NpadVibration* vibration_handler{nullptr}; +}; +} // namespace Service::HID diff --git a/src/hid_core/resources/vibration/vibration_device.cpp b/src/hid_core/resources/vibration/vibration_device.cpp new file mode 100644 index 000000000..888c3a7ed --- /dev/null +++ b/src/hid_core/resources/vibration/vibration_device.cpp @@ -0,0 +1,84 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include "hid_core/hid_result.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/npad/npad_vibration.h" +#include "hid_core/resources/vibration/vibration_device.h" + +namespace Service::HID { + +NpadVibrationDevice::NpadVibrationDevice() {} + +Result NpadVibrationDevice::IncrementRefCounter() { + ref_counter++; + return ResultSuccess; +} + +Result NpadVibrationDevice::DecrementRefCounter() { + if (ref_counter > 0) { + ref_counter--; + } + + return ResultSuccess; +} + +Result NpadVibrationDevice::SendVibrationValue(const Core::HID::VibrationValue& value) { + if (ref_counter == 0) { + return ResultVibrationNotInitialized; + } + if (!is_mounted) { + return ResultSuccess; + } + + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { + return result; + } + if (volume <= 0.0f) { + // TODO: SendVibrationValue + return ResultSuccess; + } + + Core::HID::VibrationValue vibration_value = value; + vibration_value.high_amplitude *= volume; + vibration_value.low_amplitude *= volume; + + // TODO: SendVibrationValue + return ResultSuccess; +} + +Result NpadVibrationDevice::SendVibrationNotificationPattern([[maybe_unused]] u32 pattern) { + if (!is_mounted) { + return ResultSuccess; + } + + f32 volume = 1.0f; + const auto result = vibration_handler->GetVibrationVolume(volume); + if (result.IsError()) { + return result; + } + if (volume <= 0.0) { + pattern = 0; + } + + // return xcd_handle->SendVibrationNotificationPattern(pattern); + return ResultSuccess; +} + +Result NpadVibrationDevice::GetActualVibrationValue(Core::HID::VibrationValue& out_value) { + if (ref_counter < 1) { + return ResultVibrationNotInitialized; + } + + out_value = Core::HID::DEFAULT_VIBRATION_VALUE; + if (!is_mounted) { + return ResultSuccess; + } + + // TODO: SendVibrationValue + return ResultSuccess; +} + +} // namespace Service::HID diff --git a/src/hid_core/resources/vibration/vibration_device.h b/src/hid_core/resources/vibration/vibration_device.h new file mode 100644 index 000000000..3574ad60b --- /dev/null +++ b/src/hid_core/resources/vibration/vibration_device.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include +#include + +#include "common/common_types.h" +#include "core/hle/result.h" +#include "hid_core/hid_types.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/vibration/vibration_base.h" + +namespace Service::HID { +class NpadVibration; + +/// Handles Npad request from HID interfaces +class NpadVibrationDevice final : public NpadVibrationBase { +public: + explicit NpadVibrationDevice(); + + Result IncrementRefCounter(); + Result DecrementRefCounter(); + + Result SendVibrationValue(const Core::HID::VibrationValue& value); + Result SendVibrationNotificationPattern(u32 pattern); + + Result GetActualVibrationValue(Core::HID::VibrationValue& out_value); + +private: + u32 device_index{}; +}; + +} // namespace Service::HID -- cgit v1.2.3