diff options
Diffstat (limited to 'src/core/hle')
95 files changed, 60 insertions, 9717 deletions
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 97eb56ff0..9e05bdafa 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -13,7 +13,6 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/savedata_factory.h" -#include "core/hid/hid_types.h" #include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/result.h" @@ -37,7 +36,6 @@ #include "core/hle/service/caps/caps_su.h" #include "core/hle/service/caps/caps_types.h" #include "core/hle/service/filesystem/filesystem.h" -#include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ns/ns.h" #include "core/hle/service/nvnflinger/fb_share_buffer_manager.h" @@ -48,6 +46,8 @@ #include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi_results.h" #include "core/memory.h" +#include "hid_core/hid_types.h" +#include "hid_core/resources/npad/npad.h" namespace Service::AM { diff --git a/src/core/hle/service/am/applets/applet_cabinet.cpp b/src/core/hle/service/am/applets/applet_cabinet.cpp index 3906c0fa4..c2ff444a6 100644 --- a/src/core/hle/service/am/applets/applet_cabinet.cpp +++ b/src/core/hle/service/am/applets/applet_cabinet.cpp @@ -5,13 +5,13 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/frontend/applets/cabinet.h" -#include "core/hid/hid_core.h" #include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/applet_cabinet.h" #include "core/hle/service/mii/mii_manager.h" #include "core/hle/service/nfc/common/device.h" +#include "hid_core/hid_core.h" namespace Service::AM::Applets { diff --git a/src/core/hle/service/am/applets/applet_controller.cpp b/src/core/hle/service/am/applets/applet_controller.cpp index 9840d2547..0e4d9cc39 100644 --- a/src/core/hle/service/am/applets/applet_controller.cpp +++ b/src/core/hle/service/am/applets/applet_controller.cpp @@ -9,13 +9,13 @@ #include "common/string_util.h" #include "core/core.h" #include "core/frontend/applets/controller.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hid/hid_types.h" #include "core/hle/result.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/applet_controller.h" -#include "core/hle/service/hid/controllers/npad.h" +#include "hid_core/frontend/emulated_controller.h" +#include "hid_core/hid_core.h" +#include "hid_core/hid_types.h" +#include "hid_core/resources/npad/npad.h" namespace Service::AM::Applets { diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/core/hle/service/hid/controllers/applet_resource.cpp deleted file mode 100644 index b4ff663c2..000000000 --- a/src/core/hle/service/hid/controllers/applet_resource.cpp +++ /dev/null @@ -1,329 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/core.h" -#include "core/hle/kernel/k_shared_memory.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" -#include "core/hle/service/hid/errors.h" - -namespace Service::HID { - -AppletResource::AppletResource(Core::System& system_) : system{system_} {} - -AppletResource::~AppletResource() = default; - -Result AppletResource::CreateAppletResource(u64 aruid) { - const u64 index = GetIndexFromAruid(aruid); - - if (index >= AruidIndexMax) { - return ResultAruidNotRegistered; - } - - if (data[index].flag.is_assigned) { - return ResultAruidAlreadyRegistered; - } - - auto& shared_memory = shared_memory_holder[index]; - if (!shared_memory.IsMapped()) { - const Result result = shared_memory.Initialize(system); - if (result.IsError()) { - return result; - } - if (shared_memory.GetAddress() == nullptr) { - shared_memory.Finalize(); - return ResultSharedMemoryNotInitialized; - } - } - - auto* shared_memory_format = shared_memory.GetAddress(); - if (shared_memory_format != nullptr) { - shared_memory_format->Initialize(); - } - - data[index].shared_memory_format = shared_memory_format; - data[index].flag.is_assigned.Assign(true); - // TODO: InitializeSixAxisControllerConfig(false); - active_aruid = aruid; - return ResultSuccess; -} - -Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input) { - const u64 index = GetIndexFromAruid(aruid); - - if (index < AruidIndexMax) { - return ResultAruidAlreadyRegistered; - } - - std::size_t data_index = AruidIndexMax; - for (std::size_t i = 0; i < AruidIndexMax; i++) { - if (!data[i].flag.is_initialized) { - data_index = i; - break; - } - } - - if (data_index == AruidIndexMax) { - return ResultAruidNoAvailableEntries; - } - - AruidData& aruid_data = data[data_index]; - - aruid_data.aruid = aruid; - aruid_data.flag.is_initialized.Assign(true); - if (enable_input) { - aruid_data.flag.enable_pad_input.Assign(true); - aruid_data.flag.enable_six_axis_sensor.Assign(true); - aruid_data.flag.bit_18.Assign(true); - aruid_data.flag.enable_touchscreen.Assign(true); - } - - data_index = AruidIndexMax; - for (std::size_t i = 0; i < AruidIndexMax; i++) { - if (registration_list.flag[i] == RegistrationStatus::Initialized) { - if (registration_list.aruid[i] != aruid) { - continue; - } - data_index = i; - break; - } - if (registration_list.flag[i] == RegistrationStatus::None) { - data_index = i; - break; - } - } - - if (data_index == AruidIndexMax) { - return ResultSuccess; - } - - registration_list.flag[data_index] = RegistrationStatus::Initialized; - registration_list.aruid[data_index] = aruid; - - return ResultSuccess; -} - -void AppletResource::UnregisterAppletResourceUserId(u64 aruid) { - u64 index = GetIndexFromAruid(aruid); - - if (index < AruidIndexMax) { - if (data[index].flag.is_assigned) { - data[index].shared_memory_format = nullptr; - data[index].flag.is_assigned.Assign(false); - } - } - - index = GetIndexFromAruid(aruid); - if (index < AruidIndexMax) { - DestroySevenSixAxisTransferMemory(); - data[index].flag.raw = 0; - data[index].aruid = 0; - - index = GetIndexFromAruid(aruid); - if (index < AruidIndexMax) { - registration_list.flag[index] = RegistrationStatus::PendingDelete; - } - } -} - -void AppletResource::FreeAppletResourceId(u64 aruid) { - u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return; - } - - auto& aruid_data = data[index]; - if (aruid_data.flag.is_assigned) { - aruid_data.shared_memory_format = nullptr; - aruid_data.flag.is_assigned.Assign(false); - } -} - -u64 AppletResource::GetActiveAruid() { - return active_aruid; -} - -Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) { - u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return ResultAruidNotRegistered; - } - - *out_handle = shared_memory_holder[index].GetHandle(); - return ResultSuccess; -} - -Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, - u64 aruid) { - u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return ResultAruidNotRegistered; - } - - *out_shared_memory_format = data[index].shared_memory_format; - return ResultSuccess; -} - -AruidData* AppletResource::GetAruidData(u64 aruid) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index == AruidIndexMax) { - return nullptr; - } - return &data[aruid_index]; -} - -AruidData* AppletResource::GetAruidDataByIndex(std::size_t aruid_index) { - return &data[aruid_index]; -} - -bool AppletResource::IsVibrationAruidActive(u64 aruid) const { - return aruid == 0 || aruid == active_vibration_aruid; -} - -u64 AppletResource::GetIndexFromAruid(u64 aruid) { - for (std::size_t i = 0; i < AruidIndexMax; i++) { - if (registration_list.flag[i] == RegistrationStatus::Initialized && - registration_list.aruid[i] == aruid) { - return i; - } - } - return AruidIndexMax; -} - -Result AppletResource::DestroySevenSixAxisTransferMemory() { - // TODO - return ResultSuccess; -} - -void AppletResource::EnableInput(u64 aruid, bool is_enabled) { - const u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return; - } - - data[index].flag.enable_pad_input.Assign(is_enabled); - data[index].flag.enable_touchscreen.Assign(is_enabled); -} - -void AppletResource::EnableSixAxisSensor(u64 aruid, bool is_enabled) { - const u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return; - } - - data[index].flag.enable_six_axis_sensor.Assign(is_enabled); -} - -void AppletResource::EnablePadInput(u64 aruid, bool is_enabled) { - const u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return; - } - - data[index].flag.enable_pad_input.Assign(is_enabled); -} - -void AppletResource::EnableTouchScreen(u64 aruid, bool is_enabled) { - const u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return; - } - - data[index].flag.enable_touchscreen.Assign(is_enabled); -} - -void AppletResource::SetIsPalmaConnectable(u64 aruid, bool is_connectable) { - const u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return; - } - - data[index].flag.is_palma_connectable.Assign(is_connectable); -} - -void AppletResource::EnablePalmaBoostMode(u64 aruid, bool is_enabled) { - const u64 index = GetIndexFromAruid(aruid); - if (index >= AruidIndexMax) { - return; - } - - data[index].flag.enable_palma_boost_mode.Assign(is_enabled); -} - -Result AppletResource::RegisterCoreAppletResource() { - if (ref_counter == std::numeric_limits<s32>::max() - 1) { - return ResultAppletResourceOverflow; - } - if (ref_counter == 0) { - const u64 index = GetIndexFromAruid(0); - if (index < AruidIndexMax) { - return ResultAruidAlreadyRegistered; - } - - std::size_t data_index = AruidIndexMax; - for (std::size_t i = 0; i < AruidIndexMax; i++) { - if (!data[i].flag.is_initialized) { - data_index = i; - break; - } - } - - if (data_index == AruidIndexMax) { - return ResultAruidNoAvailableEntries; - } - - AruidData& aruid_data = data[data_index]; - - aruid_data.aruid = 0; - aruid_data.flag.is_initialized.Assign(true); - aruid_data.flag.enable_pad_input.Assign(true); - aruid_data.flag.enable_six_axis_sensor.Assign(true); - aruid_data.flag.bit_18.Assign(true); - aruid_data.flag.enable_touchscreen.Assign(true); - - data_index = AruidIndexMax; - for (std::size_t i = 0; i < AruidIndexMax; i++) { - if (registration_list.flag[i] == RegistrationStatus::Initialized) { - if (registration_list.aruid[i] != 0) { - continue; - } - data_index = i; - break; - } - if (registration_list.flag[i] == RegistrationStatus::None) { - data_index = i; - break; - } - } - - Result result = ResultSuccess; - - if (data_index == AruidIndexMax) { - result = CreateAppletResource(0); - } else { - registration_list.flag[data_index] = RegistrationStatus::Initialized; - registration_list.aruid[data_index] = 0; - } - - if (result.IsError()) { - UnregisterAppletResourceUserId(0); - return result; - } - } - ref_counter++; - return ResultSuccess; -} - -Result AppletResource::UnregisterCoreAppletResource() { - if (ref_counter == 0) { - return ResultAppletResourceNotInitialized; - } - - if (--ref_counter == 0) { - UnregisterAppletResourceUserId(0); - } - - return ResultSuccess; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/applet_resource.h b/src/core/hle/service/hid/controllers/applet_resource.h deleted file mode 100644 index 0862fdc2f..000000000 --- a/src/core/hle/service/hid/controllers/applet_resource.h +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <array> -#include <mutex> - -#include "common/bit_field.h" -#include "common/common_types.h" -#include "core/hle/result.h" -#include "core/hle/service/hid/controllers/shared_memory_holder.h" - -namespace Core { -class System; -} - -namespace Kernel { -class KSharedMemory; -} - -namespace Service::HID { -struct SharedMemoryFormat; -class AppletResource; -class NPadResource; - -static constexpr std::size_t AruidIndexMax = 0x20; -static constexpr u64 SystemAruid = 0; - -enum class RegistrationStatus : u32 { - None, - Initialized, - PendingDelete, -}; - -struct DataStatusFlag { - union { - u32 raw{}; - - BitField<0, 1, u32> is_initialized; - BitField<1, 1, u32> is_assigned; - BitField<16, 1, u32> enable_pad_input; - BitField<17, 1, u32> enable_six_axis_sensor; - BitField<18, 1, u32> bit_18; - BitField<19, 1, u32> is_palma_connectable; - BitField<20, 1, u32> enable_palma_boost_mode; - BitField<21, 1, u32> enable_touchscreen; - }; -}; - -struct AruidRegisterList { - std::array<RegistrationStatus, AruidIndexMax> flag{}; - std::array<u64, AruidIndexMax> aruid{}; -}; -static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size"); - -struct AruidData { - DataStatusFlag flag{}; - u64 aruid{}; - SharedMemoryFormat* shared_memory_format{nullptr}; -}; - -struct HandheldConfig { - bool is_handheld_hid_enabled; - bool is_force_handheld; - bool is_joycon_rail_enabled; - bool is_force_handheld_style_vibration; -}; -static_assert(sizeof(HandheldConfig) == 0x4, "HandheldConfig is an invalid size"); - -struct AppletResourceHolder { - std::shared_ptr<AppletResource> applet_resource{nullptr}; - std::recursive_mutex* shared_mutex{nullptr}; - NPadResource* shared_npad_resource{nullptr}; - std::shared_ptr<HandheldConfig> handheld_config{nullptr}; - long* handle_1; -}; - -class AppletResource { -public: - explicit AppletResource(Core::System& system_); - ~AppletResource(); - - Result CreateAppletResource(u64 aruid); - - Result RegisterAppletResourceUserId(u64 aruid, bool enable_input); - void UnregisterAppletResourceUserId(u64 aruid); - - void FreeAppletResourceId(u64 aruid); - - u64 GetActiveAruid(); - Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); - Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid); - AruidData* GetAruidData(u64 aruid); - AruidData* GetAruidDataByIndex(std::size_t aruid_index); - - bool IsVibrationAruidActive(u64 aruid) const; - - u64 GetIndexFromAruid(u64 aruid); - - Result DestroySevenSixAxisTransferMemory(); - - void EnableInput(u64 aruid, bool is_enabled); - void EnableSixAxisSensor(u64 aruid, bool is_enabled); - void EnablePadInput(u64 aruid, bool is_enabled); - void EnableTouchScreen(u64 aruid, bool is_enabled); - void SetIsPalmaConnectable(u64 aruid, bool is_connectable); - void EnablePalmaBoostMode(u64 aruid, bool is_enabled); - - Result RegisterCoreAppletResource(); - Result UnregisterCoreAppletResource(); - -private: - u64 active_aruid{}; - AruidRegisterList registration_list{}; - std::array<AruidData, AruidIndexMax> data{}; - std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{}; - s32 ref_counter{}; - u64 active_vibration_aruid; - - Core::System& system; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/capture_button.cpp b/src/core/hle/service/hid/controllers/capture_button.cpp deleted file mode 100644 index 7847c080e..000000000 --- a/src/core/hle/service/hid/controllers/capture_button.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/capture_button.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -CaptureButton::CaptureButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} - -CaptureButton::~CaptureButton() = default; - -void CaptureButton::OnInit() {} - -void CaptureButton::OnRelease() {} - -void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (!smart_update) { - return; - } - - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - auto& header = data->shared_memory_format->capture_button.header; - header.timestamp = core_timing.GetGlobalTimeNs().count(); - header.total_entry_count = 17; - header.entry_count = 0; - header.last_entry_index = 0; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/capture_button.h b/src/core/hle/service/hid/controllers/capture_button.h deleted file mode 100644 index dcc4715c5..000000000 --- a/src/core/hle/service/hid/controllers/capture_button.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Service::HID { - -class CaptureButton final : public ControllerBase { -public: - explicit CaptureButton(Core::HID::HIDCore& hid_core_); - ~CaptureButton() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - bool smart_update{}; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp deleted file mode 100644 index 4b574c2e5..000000000 --- a/src/core/hle/service/hid/controllers/console_six_axis.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/hid/emulated_console.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/console_six_axis.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} { - console = hid_core.GetEmulatedConsole(); -} - -ConsoleSixAxis::~ConsoleSixAxis() = default; - -void ConsoleSixAxis::OnInit() {} - -void ConsoleSixAxis::OnRelease() {} - -void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - ConsoleSixAxisSensorSharedMemoryFormat& shared_memory = data->shared_memory_format->console; - - if (!IsControllerActivated()) { - return; - } - - const auto motion_status = console->GetMotion(); - - shared_memory.sampling_number++; - shared_memory.is_seven_six_axis_sensor_at_rest = motion_status.is_at_rest; - shared_memory.verticalization_error = motion_status.verticalization_error; - shared_memory.gyro_bias = motion_status.gyro_bias; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h deleted file mode 100644 index e3351f83c..000000000 --- a/src/core/hle/service/hid/controllers/console_six_axis.h +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Core::HID { -class EmulatedConsole; -} // namespace Core::HID - -namespace Service::HID { -class ConsoleSixAxis final : public ControllerBase { -public: - explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_); - ~ConsoleSixAxis() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - Core::HID::EmulatedConsole* console = nullptr; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp deleted file mode 100644 index afca7154c..000000000 --- a/src/core/hle/service/hid/controllers/controller_base.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Service::HID { - -ControllerBase::ControllerBase(Core::HID::HIDCore& hid_core_) : hid_core(hid_core_) {} -ControllerBase::~ControllerBase() = default; - -Result ControllerBase::Activate() { - if (is_activated) { - return ResultSuccess; - } - is_activated = true; - OnInit(); - return ResultSuccess; -} - -Result ControllerBase::Activate(u64 aruid) { - return Activate(); -} - -void ControllerBase::DeactivateController() { - if (is_activated) { - OnRelease(); - } - is_activated = false; -} - -bool ControllerBase::IsControllerActivated() const { - return is_activated; -} - -void ControllerBase::SetAppletResource(std::shared_ptr<AppletResource> resource, - std::recursive_mutex* resource_mutex) { - applet_resource = resource; - shared_mutex = resource_mutex; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h deleted file mode 100644 index b34b85ece..000000000 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <memory> - -#include "common/common_types.h" -#include "core/hle/result.h" -#include "core/hle/service/hid/controllers/applet_resource.h" - -namespace Core::Timing { -class CoreTiming; -} - -namespace Core::HID { -class HIDCore; -} // namespace Core::HID - -namespace Service::HID { -class ControllerBase { -public: - explicit ControllerBase(Core::HID::HIDCore& hid_core_); - virtual ~ControllerBase(); - - // Called when the controller is initialized - virtual void OnInit() = 0; - - // When the controller is released - virtual void OnRelease() = 0; - - // When the controller is requesting an update for the shared memory - virtual void OnUpdate(const Core::Timing::CoreTiming& core_timing) = 0; - - // When the controller is requesting a motion update for the shared memory - virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {} - - Result Activate(); - Result Activate(u64 aruid); - - void DeactivateController(); - - bool IsControllerActivated() const; - - void SetAppletResource(std::shared_ptr<AppletResource> resource, - std::recursive_mutex* resource_mutex); - -protected: - bool is_activated{false}; - std::shared_ptr<AppletResource> applet_resource{nullptr}; - std::recursive_mutex* shared_mutex{nullptr}; - - Core::HID::HIDCore& hid_core; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/debug_mouse.cpp b/src/core/hle/service/hid/controllers/debug_mouse.cpp deleted file mode 100644 index ceeb78d36..000000000 --- a/src/core/hle/service/hid/controllers/debug_mouse.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/frontend/emu_window.h" -#include "core/hid/emulated_devices.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/debug_mouse.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -DebugMouse::DebugMouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} { - emulated_devices = hid_core.GetEmulatedDevices(); -} - -DebugMouse::~DebugMouse() = default; - -void DebugMouse::OnInit() {} -void DebugMouse::OnRelease() {} - -void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - MouseSharedMemoryFormat& shared_memory = data->shared_memory_format->debug_mouse; - - if (!IsControllerActivated()) { - shared_memory.mouse_lifo.buffer_count = 0; - shared_memory.mouse_lifo.buffer_tail = 0; - return; - } - - next_state = {}; - - const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state; - next_state.sampling_number = last_entry.sampling_number + 1; - - if (Settings::values.mouse_enabled) { - const auto& mouse_button_state = emulated_devices->GetMouseButtons(); - const auto& mouse_position_state = emulated_devices->GetMousePosition(); - const auto& mouse_wheel_state = emulated_devices->GetMouseWheel(); - next_state.attribute.is_connected.Assign(1); - next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width); - next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height); - next_state.delta_x = next_state.x - last_entry.x; - next_state.delta_y = next_state.y - last_entry.y; - next_state.delta_wheel_x = mouse_wheel_state.x - last_mouse_wheel_state.x; - next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y; - - last_mouse_wheel_state = mouse_wheel_state; - next_state.button = mouse_button_state; - } - - shared_memory.mouse_lifo.WriteNextEntry(next_state); -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/debug_mouse.h b/src/core/hle/service/hid/controllers/debug_mouse.h deleted file mode 100644 index ec939fa9f..000000000 --- a/src/core/hle/service/hid/controllers/debug_mouse.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Core::HID { -class EmulatedDevices; -struct MouseState; -struct AnalogStickState; -} // namespace Core::HID - -namespace Service::HID { -class DebugMouse final : public ControllerBase { -public: - explicit DebugMouse(Core::HID::HIDCore& hid_core_); - ~DebugMouse() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - Core::HID::MouseState next_state{}; - Core::HID::AnalogStickState last_mouse_wheel_state{}; - Core::HID::EmulatedDevices* emulated_devices = nullptr; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp deleted file mode 100644 index dc83f90f3..000000000 --- a/src/core/hle/service/hid/controllers/debug_pad.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/settings.h" -#include "core/core_timing.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hid/hid_types.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/debug_pad.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -DebugPad::DebugPad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} { - controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); -} - -DebugPad::~DebugPad() = default; - -void DebugPad::OnInit() {} - -void DebugPad::OnRelease() {} - -void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - DebugPadSharedMemoryFormat& shared_memory = data->shared_memory_format->debug_pad; - - if (!IsControllerActivated()) { - shared_memory.debug_pad_lifo.buffer_count = 0; - shared_memory.debug_pad_lifo.buffer_tail = 0; - return; - } - - const auto& last_entry = shared_memory.debug_pad_lifo.ReadCurrentEntry().state; - next_state.sampling_number = last_entry.sampling_number + 1; - - if (Settings::values.debug_pad_enabled) { - next_state.attribute.connected.Assign(1); - - const auto& button_state = controller->GetDebugPadButtons(); - const auto& stick_state = controller->GetSticks(); - - next_state.pad_state = button_state; - next_state.l_stick = stick_state.left; - next_state.r_stick = stick_state.right; - } - - shared_memory.debug_pad_lifo.WriteNextEntry(next_state); -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h deleted file mode 100644 index dd00b2402..000000000 --- a/src/core/hle/service/hid/controllers/debug_pad.h +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/controllers/types/debug_pad_types.h" - -namespace Core::HID { -class HIDCore; -} - -namespace Core::Timing { -class CoreTiming; -} - -namespace Service::HID { -class DebugPad final : public ControllerBase { -public: - explicit DebugPad(Core::HID::HIDCore& hid_core_); - ~DebugPad() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - DebugPadState next_state{}; - Core::HID::EmulatedController* controller = nullptr; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/digitizer.cpp b/src/core/hle/service/hid/controllers/digitizer.cpp deleted file mode 100644 index d5514c965..000000000 --- a/src/core/hle/service/hid/controllers/digitizer.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/digitizer.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -Digitizer::Digitizer(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} - -Digitizer::~Digitizer() = default; - -void Digitizer::OnInit() {} - -void Digitizer::OnRelease() {} - -void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (!smart_update) { - return; - } - - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - auto& header = data->shared_memory_format->digitizer.header; - header.timestamp = core_timing.GetGlobalTimeNs().count(); - header.total_entry_count = 17; - header.entry_count = 0; - header.last_entry_index = 0; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/digitizer.h b/src/core/hle/service/hid/controllers/digitizer.h deleted file mode 100644 index d81f814c3..000000000 --- a/src/core/hle/service/hid/controllers/digitizer.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Service::HID { - -class Digitizer final : public ControllerBase { -public: - explicit Digitizer(Core::HID::HIDCore& hid_core_); - ~Digitizer() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - bool smart_update{}; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp deleted file mode 100644 index c73da13ee..000000000 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ /dev/null @@ -1,366 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/math_util.h" -#include "common/settings.h" -#include "core/frontend/emu_window.h" -#include "core/hid/emulated_console.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/gesture.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { -// HW is around 700, value is set to 400 to make it easier to trigger with mouse -constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s -constexpr f32 angle_threshold = 0.015f; // Threshold in radians -constexpr f32 pinch_threshold = 0.5f; // Threshold in pixels -constexpr f32 press_delay = 0.5f; // Time in seconds -constexpr f32 double_tap_delay = 0.35f; // Time in seconds - -constexpr f32 Square(s32 num) { - return static_cast<f32>(num * num); -} - -Gesture::Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) { - console = hid_core.GetEmulatedConsole(); -} -Gesture::~Gesture() = default; - -void Gesture::OnInit() { - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - shared_memory = &data->shared_memory_format->gesture; - shared_memory->gesture_lifo.buffer_count = 0; - shared_memory->gesture_lifo.buffer_tail = 0; - force_update = true; -} - -void Gesture::OnRelease() {} - -void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - shared_memory = &data->shared_memory_format->gesture; - - if (!IsControllerActivated()) { - shared_memory->gesture_lifo.buffer_count = 0; - shared_memory->gesture_lifo.buffer_tail = 0; - return; - } - - ReadTouchInput(); - - GestureProperties gesture = GetGestureProperties(); - f32 time_difference = - static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) / - (1000 * 1000 * 1000); - - // Only update if necessary - if (!ShouldUpdateGesture(gesture, time_difference)) { - return; - } - - last_update_timestamp = shared_memory->gesture_lifo.timestamp; - UpdateGestureSharedMemory(gesture, time_difference); -} - -void Gesture::ReadTouchInput() { - if (!Settings::values.touchscreen.enabled) { - fingers = {}; - return; - } - - const auto touch_status = console->GetTouch(); - for (std::size_t id = 0; id < fingers.size(); ++id) { - fingers[id] = touch_status[id]; - } -} - -bool Gesture::ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference) { - const auto& last_entry = GetLastGestureEntry(); - if (force_update) { - force_update = false; - return true; - } - - // Update if coordinates change - for (size_t id = 0; id < MAX_POINTS; id++) { - if (gesture.points[id] != last_gesture.points[id]) { - return true; - } - } - - // Update on press and hold event after 0.5 seconds - if (last_entry.type == GestureType::Touch && last_entry.point_count == 1 && - time_difference > press_delay) { - return enable_press_and_tap; - } - - return false; -} - -void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference) { - GestureType type = GestureType::Idle; - GestureAttribute attributes{}; - - const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state; - - // Reset next state to default - next_state.sampling_number = last_entry.sampling_number + 1; - next_state.delta = {}; - next_state.vel_x = 0; - next_state.vel_y = 0; - next_state.direction = GestureDirection::None; - next_state.rotation_angle = 0; - next_state.scale = 0; - - if (gesture.active_points > 0) { - if (last_gesture.active_points == 0) { - NewGesture(gesture, type, attributes); - } else { - UpdateExistingGesture(gesture, type, time_difference); - } - } else { - EndGesture(gesture, last_gesture, type, attributes, time_difference); - } - - // Apply attributes - next_state.detection_count = gesture.detection_count; - next_state.type = type; - next_state.attributes = attributes; - next_state.pos = gesture.mid_point; - next_state.point_count = static_cast<s32>(gesture.active_points); - next_state.points = gesture.points; - last_gesture = gesture; - - shared_memory->gesture_lifo.WriteNextEntry(next_state); -} - -void Gesture::NewGesture(GestureProperties& gesture, GestureType& type, - GestureAttribute& attributes) { - const auto& last_entry = GetLastGestureEntry(); - - gesture.detection_count++; - type = GestureType::Touch; - - // New touch after cancel is not considered new - if (last_entry.type != GestureType::Cancel) { - attributes.is_new_touch.Assign(1); - enable_press_and_tap = true; - } -} - -void Gesture::UpdateExistingGesture(GestureProperties& gesture, GestureType& type, - f32 time_difference) { - const auto& last_entry = GetLastGestureEntry(); - - // Promote to pan type if touch moved - for (size_t id = 0; id < MAX_POINTS; id++) { - if (gesture.points[id] != last_gesture.points[id]) { - type = GestureType::Pan; - break; - } - } - - // Number of fingers changed cancel the last event and clear data - if (gesture.active_points != last_gesture.active_points) { - type = GestureType::Cancel; - enable_press_and_tap = false; - gesture.active_points = 0; - gesture.mid_point = {}; - gesture.points.fill({}); - return; - } - - // Calculate extra parameters of panning - if (type == GestureType::Pan) { - UpdatePanEvent(gesture, last_gesture, type, time_difference); - return; - } - - // Promote to press type - if (last_entry.type == GestureType::Touch) { - type = GestureType::Press; - } -} - -void Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type, GestureAttribute& attributes, f32 time_difference) { - const auto& last_entry = GetLastGestureEntry(); - - if (last_gesture_props.active_points != 0) { - switch (last_entry.type) { - case GestureType::Touch: - if (enable_press_and_tap) { - SetTapEvent(gesture, last_gesture_props, type, attributes); - return; - } - type = GestureType::Cancel; - force_update = true; - break; - case GestureType::Press: - case GestureType::Tap: - case GestureType::Swipe: - case GestureType::Pinch: - case GestureType::Rotate: - type = GestureType::Complete; - force_update = true; - break; - case GestureType::Pan: - EndPanEvent(gesture, last_gesture_props, type, time_difference); - break; - default: - break; - } - return; - } - if (last_entry.type == GestureType::Complete || last_entry.type == GestureType::Cancel) { - gesture.detection_count++; - } -} - -void Gesture::SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type, GestureAttribute& attributes) { - type = GestureType::Tap; - gesture = last_gesture_props; - force_update = true; - f32 tap_time_difference = - static_cast<f32>(last_update_timestamp - last_tap_timestamp) / (1000 * 1000 * 1000); - last_tap_timestamp = last_update_timestamp; - if (tap_time_difference < double_tap_delay) { - attributes.is_double_tap.Assign(1); - } -} - -void Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type, f32 time_difference) { - const auto& last_entry = GetLastGestureEntry(); - - next_state.delta = gesture.mid_point - last_entry.pos; - next_state.vel_x = static_cast<f32>(next_state.delta.x) / time_difference; - next_state.vel_y = static_cast<f32>(next_state.delta.y) / time_difference; - last_pan_time_difference = time_difference; - - // Promote to pinch type - if (std::abs(gesture.average_distance - last_gesture_props.average_distance) > - pinch_threshold) { - type = GestureType::Pinch; - next_state.scale = gesture.average_distance / last_gesture_props.average_distance; - } - - const f32 angle_between_two_lines = std::atan((gesture.angle - last_gesture_props.angle) / - (1 + (gesture.angle * last_gesture_props.angle))); - // Promote to rotate type - if (std::abs(angle_between_two_lines) > angle_threshold) { - type = GestureType::Rotate; - next_state.scale = 0; - next_state.rotation_angle = angle_between_two_lines * 180.0f / Common::PI; - } -} - -void Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type, f32 time_difference) { - const auto& last_entry = GetLastGestureEntry(); - next_state.vel_x = - static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference); - next_state.vel_y = - static_cast<f32>(last_entry.delta.y) / (last_pan_time_difference + time_difference); - const f32 curr_vel = - std::sqrt((next_state.vel_x * next_state.vel_x) + (next_state.vel_y * next_state.vel_y)); - - // Set swipe event with parameters - if (curr_vel > swipe_threshold) { - SetSwipeEvent(gesture, last_gesture_props, type); - return; - } - - // End panning without swipe - type = GestureType::Complete; - next_state.vel_x = 0; - next_state.vel_y = 0; - force_update = true; -} - -void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type) { - const auto& last_entry = GetLastGestureEntry(); - - type = GestureType::Swipe; - gesture = last_gesture_props; - force_update = true; - next_state.delta = last_entry.delta; - - if (std::abs(next_state.delta.x) > std::abs(next_state.delta.y)) { - if (next_state.delta.x > 0) { - next_state.direction = GestureDirection::Right; - return; - } - next_state.direction = GestureDirection::Left; - return; - } - if (next_state.delta.y > 0) { - next_state.direction = GestureDirection::Down; - return; - } - next_state.direction = GestureDirection::Up; -} - -const GestureState& Gesture::GetLastGestureEntry() const { - return shared_memory->gesture_lifo.ReadCurrentEntry().state; -} - -GestureProperties Gesture::GetGestureProperties() { - GestureProperties gesture; - std::array<Core::HID::TouchFinger, MAX_POINTS> active_fingers; - const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), - [](const auto& finger) { return finger.pressed; }); - gesture.active_points = - static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); - - for (size_t id = 0; id < gesture.active_points; ++id) { - const auto& [active_x, active_y] = active_fingers[id].position; - gesture.points[id] = { - .x = static_cast<s32>(active_x * Layout::ScreenUndocked::Width), - .y = static_cast<s32>(active_y * Layout::ScreenUndocked::Height), - }; - - // Hack: There is no touch in docked but games still allow it - if (Settings::IsDockedMode()) { - gesture.points[id] = { - .x = static_cast<s32>(active_x * Layout::ScreenDocked::Width), - .y = static_cast<s32>(active_y * Layout::ScreenDocked::Height), - }; - } - - gesture.mid_point.x += static_cast<s32>(gesture.points[id].x / gesture.active_points); - gesture.mid_point.y += static_cast<s32>(gesture.points[id].y / gesture.active_points); - } - - for (size_t id = 0; id < gesture.active_points; ++id) { - const f32 distance = std::sqrt(Square(gesture.mid_point.x - gesture.points[id].x) + - Square(gesture.mid_point.y - gesture.points[id].y)); - gesture.average_distance += distance / static_cast<f32>(gesture.active_points); - } - - gesture.angle = std::atan2(static_cast<f32>(gesture.mid_point.y - gesture.points[0].y), - static_cast<f32>(gesture.mid_point.x - gesture.points[0].x)); - - gesture.detection_count = last_gesture.detection_count; - - return gesture; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h deleted file mode 100644 index 78da1552a..000000000 --- a/src/core/hle/service/hid/controllers/gesture.h +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> - -#include "common/common_types.h" -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/controllers/types/touch_types.h" - -namespace Core::HID { -class EmulatedConsole; -} - -namespace Service::HID { -struct GestureSharedMemoryFormat; - -class Gesture final : public ControllerBase { -public: - explicit Gesture(Core::HID::HIDCore& hid_core_); - ~Gesture() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - // Reads input from all available input engines - void ReadTouchInput(); - - // Returns true if gesture state needs to be updated - bool ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference); - - // Updates the shared memory to the next state - void UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_difference); - - // Initializes new gesture - void NewGesture(GestureProperties& gesture, GestureType& type, GestureAttribute& attributes); - - // Updates existing gesture state - void UpdateExistingGesture(GestureProperties& gesture, GestureType& type, f32 time_difference); - - // Terminates exiting gesture - void EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type, GestureAttribute& attributes, f32 time_difference); - - // Set current event to a tap event - void SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type, GestureAttribute& attributes); - - // Calculates and set the extra parameters related to a pan event - void UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type, f32 time_difference); - - // Terminates the pan event - void EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type, f32 time_difference); - - // Set current event to a swipe event - void SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, - GestureType& type); - - // Retrieves the last gesture entry, as indicated by shared memory indices. - [[nodiscard]] const GestureState& GetLastGestureEntry() const; - - // Returns the average distance, angle and middle point of the active fingers - GestureProperties GetGestureProperties(); - - GestureState next_state{}; - GestureSharedMemoryFormat* shared_memory; - Core::HID::EmulatedConsole* console = nullptr; - - std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{}; - GestureProperties last_gesture{}; - s64 last_update_timestamp{}; - s64 last_tap_timestamp{}; - f32 last_pan_time_difference{}; - bool force_update{false}; - bool enable_press_and_tap{false}; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/home_button.cpp b/src/core/hle/service/hid/controllers/home_button.cpp deleted file mode 100644 index 1397379f3..000000000 --- a/src/core/hle/service/hid/controllers/home_button.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/home_button.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -HomeButton::HomeButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} - -HomeButton::~HomeButton() = default; - -void HomeButton::OnInit() {} - -void HomeButton::OnRelease() {} - -void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (!smart_update) { - return; - } - - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - auto& header = data->shared_memory_format->home_button.header; - header.timestamp = core_timing.GetGlobalTimeNs().count(); - header.total_entry_count = 17; - header.entry_count = 0; - header.last_entry_index = 0; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/home_button.h b/src/core/hle/service/hid/controllers/home_button.h deleted file mode 100644 index e91c2aa5d..000000000 --- a/src/core/hle/service/hid/controllers/home_button.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Service::HID { - -class HomeButton final : public ControllerBase { -public: - explicit HomeButton(Core::HID::HIDCore& hid_core_); - ~HomeButton() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - bool smart_update{}; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp deleted file mode 100644 index c069bcbb2..000000000 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/settings.h" -#include "core/core_timing.h" -#include "core/hid/emulated_devices.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/keyboard.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -Keyboard::Keyboard(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} { - emulated_devices = hid_core.GetEmulatedDevices(); -} - -Keyboard::~Keyboard() = default; - -void Keyboard::OnInit() {} - -void Keyboard::OnRelease() {} - -void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - KeyboardSharedMemoryFormat& shared_memory = data->shared_memory_format->keyboard; - - if (!IsControllerActivated()) { - shared_memory.keyboard_lifo.buffer_count = 0; - shared_memory.keyboard_lifo.buffer_tail = 0; - return; - } - - const auto& last_entry = shared_memory.keyboard_lifo.ReadCurrentEntry().state; - next_state.sampling_number = last_entry.sampling_number + 1; - - if (Settings::values.keyboard_enabled) { - const auto& keyboard_state = emulated_devices->GetKeyboard(); - const auto& keyboard_modifier_state = emulated_devices->GetKeyboardModifier(); - - next_state.key = keyboard_state; - next_state.modifier = keyboard_modifier_state; - next_state.attribute.is_connected.Assign(1); - } - - shared_memory.keyboard_lifo.WriteNextEntry(next_state); -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h deleted file mode 100644 index e8ca326c6..000000000 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/controllers/types/keyboard_types.h" - -namespace Service::HID { -class Keyboard final : public ControllerBase { -public: - explicit Keyboard(Core::HID::HIDCore& hid_core_); - ~Keyboard() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - KeyboardState next_state{}; - Core::HID::EmulatedDevices* emulated_devices = nullptr; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp deleted file mode 100644 index 3a8d1751b..000000000 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/frontend/emu_window.h" -#include "core/hid/emulated_devices.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/mouse.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -Mouse::Mouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} { - emulated_devices = hid_core.GetEmulatedDevices(); -} - -Mouse::~Mouse() = default; - -void Mouse::OnInit() {} -void Mouse::OnRelease() {} - -void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - MouseSharedMemoryFormat& shared_memory = data->shared_memory_format->mouse; - - if (!IsControllerActivated()) { - shared_memory.mouse_lifo.buffer_count = 0; - shared_memory.mouse_lifo.buffer_tail = 0; - return; - } - - next_state = {}; - - const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state; - next_state.sampling_number = last_entry.sampling_number + 1; - - if (Settings::values.mouse_enabled) { - const auto& mouse_button_state = emulated_devices->GetMouseButtons(); - const auto& mouse_position_state = emulated_devices->GetMousePosition(); - const auto& mouse_wheel_state = emulated_devices->GetMouseWheel(); - next_state.attribute.is_connected.Assign(1); - next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width); - next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height); - next_state.delta_x = next_state.x - last_entry.x; - next_state.delta_y = next_state.y - last_entry.y; - next_state.delta_wheel_x = mouse_wheel_state.x - last_mouse_wheel_state.x; - next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y; - - last_mouse_wheel_state = mouse_wheel_state; - next_state.button = mouse_button_state; - } - - shared_memory.mouse_lifo.WriteNextEntry(next_state); -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h deleted file mode 100644 index cefad956c..000000000 --- a/src/core/hle/service/hid/controllers/mouse.h +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Core::HID { -class EmulatedDevices; -struct MouseState; -struct AnalogStickState; -} // namespace Core::HID - -namespace Service::HID { -class Mouse final : public ControllerBase { -public: - explicit Mouse(Core::HID::HIDCore& hid_core_); - ~Mouse() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - Core::HID::MouseState next_state{}; - Core::HID::AnalogStickState last_mouse_wheel_state{}; - Core::HID::EmulatedDevices* emulated_devices = nullptr; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp deleted file mode 100644 index 17cd0d7a0..000000000 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ /dev/null @@ -1,1342 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <algorithm> -#include <array> -#include <chrono> -#include <cstring> - -#include "common/assert.h" -#include "common/bit_field.h" -#include "common/common_types.h" -#include "common/logging/log.h" -#include "common/settings.h" -#include "core/core_timing.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_readable_event.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/npad.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" -#include "core/hle/service/hid/errors.h" -#include "core/hle/service/hid/hid_util.h" -#include "core/hle/service/kernel_helpers.h" - -namespace Service::HID { - -NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_) - : hid_core{hid_core_}, service_context{service_context_}, npad_resource{service_context} { - for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) { - for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) { - auto& controller = controller_data[aruid_index][i]; - controller.device = hid_core.GetEmulatedControllerByIndex(i); - controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value = - Core::HID::DEFAULT_VIBRATION_VALUE; - controller.vibration[Core::HID::EmulatedDeviceIndex::RightIndex] - .latest_vibration_value = Core::HID::DEFAULT_VIBRATION_VALUE; - Core::HID::ControllerUpdateCallback engine_callback{ - .on_change = - [this, i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }, - .is_npad_service = true, - }; - controller.callback_key = controller.device->SetCallback(engine_callback); - } - } -} - -NPad::~NPad() { - for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) { - for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) { - auto& controller = controller_data[aruid_index][i]; - controller.device->DeleteCallback(controller.callback_key); - } - } -} - -Result NPad::Activate() { - if (ref_counter == std::numeric_limits<s32>::max() - 1) { - return ResultNpadResourceOverflow; - } - - if (ref_counter == 0) { - std::scoped_lock lock{mutex}; - - // TODO: Activate handlers and AbstractedPad - } - - ref_counter++; - return ResultSuccess; -} - -Result NPad::Activate(u64 aruid) { - std::scoped_lock lock{mutex}; - std::scoped_lock shared_lock{*applet_resource_holder.shared_mutex}; - - auto* data = applet_resource_holder.applet_resource->GetAruidData(aruid); - const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return ResultSuccess; - } - - for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) { - auto& controller = controller_data[aruid_index][i]; - controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state; - } - - // Prefill controller buffers - for (auto& controller : controller_data[aruid_index]) { - auto* npad = controller.shared_memory; - npad->fullkey_color = { - .attribute = ColorAttribute::NoController, - .fullkey = {}, - }; - npad->joycon_color = { - .attribute = ColorAttribute::NoController, - .left = {}, - .right = {}, - }; - // HW seems to initialize the first 19 entries - for (std::size_t i = 0; i < 19; ++i) { - WriteEmptyEntry(npad); - } - } - - return ResultSuccess; -} - -Result NPad::ActivateNpadResource() { - return npad_resource.Activate(); -} - -Result NPad::ActivateNpadResource(u64 aruid) { - return npad_resource.Activate(aruid); -} - -void NPad::ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx) { - if (type == Core::HID::ControllerTriggerType::All) { - ControllerUpdate(Core::HID::ControllerTriggerType::Connected, controller_idx); - ControllerUpdate(Core::HID::ControllerTriggerType::Battery, controller_idx); - return; - } - - for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) { - if (controller_idx >= controller_data[aruid_index].size()) { - return; - } - - auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index); - - if (!data->flag.is_assigned) { - continue; - } - - auto& controller = controller_data[aruid_index][controller_idx]; - const auto is_connected = controller.device->IsConnected(); - const auto npad_type = controller.device->GetNpadStyleIndex(); - const auto npad_id = controller.device->GetNpadIdType(); - switch (type) { - case Core::HID::ControllerTriggerType::Connected: - case Core::HID::ControllerTriggerType::Disconnected: - if (is_connected == controller.is_connected) { - return; - } - UpdateControllerAt(data->aruid, npad_type, npad_id, is_connected); - break; - case Core::HID::ControllerTriggerType::Battery: { - if (!controller.device->IsConnected()) { - return; - } - auto* shared_memory = controller.shared_memory; - const auto& battery_level = controller.device->GetBattery(); - shared_memory->battery_level_dual = battery_level.dual.battery_level; - shared_memory->battery_level_left = battery_level.left.battery_level; - shared_memory->battery_level_right = battery_level.right.battery_level; - break; - } - default: - break; - } - } -} - -void NPad::InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id) { - auto& controller = GetControllerFromNpadIdType(aruid, npad_id); - if (!npad_resource.IsControllerSupported(aruid, controller.device->GetNpadStyleIndex())) { - return; - } - LOG_DEBUG(Service_HID, "Npad connected {}", npad_id); - const auto controller_type = controller.device->GetNpadStyleIndex(); - const auto& body_colors = controller.device->GetColors(); - const auto& battery_level = controller.device->GetBattery(); - auto* shared_memory = controller.shared_memory; - if (controller_type == Core::HID::NpadStyleIndex::None) { - npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id); - return; - } - - // Reset memory values - shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; - shared_memory->device_type.raw = 0; - shared_memory->system_properties.raw = 0; - shared_memory->joycon_color.attribute = ColorAttribute::NoController; - shared_memory->joycon_color.attribute = ColorAttribute::NoController; - shared_memory->fullkey_color = {}; - shared_memory->joycon_color.left = {}; - shared_memory->joycon_color.right = {}; - shared_memory->battery_level_dual = {}; - shared_memory->battery_level_left = {}; - shared_memory->battery_level_right = {}; - - switch (controller_type) { - case Core::HID::NpadStyleIndex::None: - ASSERT(false); - break; - case Core::HID::NpadStyleIndex::ProController: - shared_memory->fullkey_color.attribute = ColorAttribute::Ok; - shared_memory->fullkey_color.fullkey = body_colors.fullkey; - shared_memory->battery_level_dual = battery_level.dual.battery_level; - shared_memory->style_tag.fullkey.Assign(1); - shared_memory->device_type.fullkey.Assign(1); - shared_memory->system_properties.is_vertical.Assign(1); - shared_memory->system_properties.use_plus.Assign(1); - shared_memory->system_properties.use_minus.Assign(1); - shared_memory->system_properties.is_charging_joy_dual.Assign( - battery_level.dual.is_charging); - shared_memory->applet_footer_type = AppletFooterUiType::SwitchProController; - shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1); - break; - case Core::HID::NpadStyleIndex::Handheld: - shared_memory->fullkey_color.attribute = ColorAttribute::Ok; - shared_memory->joycon_color.attribute = ColorAttribute::Ok; - shared_memory->fullkey_color.fullkey = body_colors.fullkey; - shared_memory->joycon_color.left = body_colors.left; - shared_memory->joycon_color.right = body_colors.right; - shared_memory->style_tag.handheld.Assign(1); - shared_memory->device_type.handheld_left.Assign(1); - shared_memory->device_type.handheld_right.Assign(1); - shared_memory->system_properties.is_vertical.Assign(1); - shared_memory->system_properties.use_plus.Assign(1); - shared_memory->system_properties.use_minus.Assign(1); - shared_memory->system_properties.use_directional_buttons.Assign(1); - shared_memory->system_properties.is_charging_joy_dual.Assign( - battery_level.left.is_charging); - shared_memory->system_properties.is_charging_joy_left.Assign( - battery_level.left.is_charging); - shared_memory->system_properties.is_charging_joy_right.Assign( - battery_level.right.is_charging); - shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; - shared_memory->applet_footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight; - shared_memory->sixaxis_handheld_properties.is_newly_assigned.Assign(1); - break; - case Core::HID::NpadStyleIndex::JoyconDual: - shared_memory->fullkey_color.attribute = ColorAttribute::Ok; - shared_memory->joycon_color.attribute = ColorAttribute::Ok; - shared_memory->style_tag.joycon_dual.Assign(1); - if (controller.is_dual_left_connected) { - shared_memory->joycon_color.left = body_colors.left; - shared_memory->battery_level_left = battery_level.left.battery_level; - shared_memory->device_type.joycon_left.Assign(1); - shared_memory->system_properties.use_minus.Assign(1); - shared_memory->system_properties.is_charging_joy_left.Assign( - battery_level.left.is_charging); - shared_memory->sixaxis_dual_left_properties.is_newly_assigned.Assign(1); - } - if (controller.is_dual_right_connected) { - shared_memory->joycon_color.right = body_colors.right; - shared_memory->battery_level_right = battery_level.right.battery_level; - shared_memory->device_type.joycon_right.Assign(1); - shared_memory->system_properties.use_plus.Assign(1); - shared_memory->system_properties.is_charging_joy_right.Assign( - battery_level.right.is_charging); - shared_memory->sixaxis_dual_right_properties.is_newly_assigned.Assign(1); - } - shared_memory->system_properties.use_directional_buttons.Assign(1); - shared_memory->system_properties.is_vertical.Assign(1); - shared_memory->assignment_mode = NpadJoyAssignmentMode::Dual; - - if (controller.is_dual_left_connected && controller.is_dual_right_connected) { - shared_memory->applet_footer_type = AppletFooterUiType::JoyDual; - shared_memory->fullkey_color.fullkey = body_colors.left; - shared_memory->battery_level_dual = battery_level.left.battery_level; - shared_memory->system_properties.is_charging_joy_dual.Assign( - battery_level.left.is_charging); - } else if (controller.is_dual_left_connected) { - shared_memory->applet_footer_type = AppletFooterUiType::JoyDualLeftOnly; - shared_memory->fullkey_color.fullkey = body_colors.left; - shared_memory->battery_level_dual = battery_level.left.battery_level; - shared_memory->system_properties.is_charging_joy_dual.Assign( - battery_level.left.is_charging); - } else { - shared_memory->applet_footer_type = AppletFooterUiType::JoyDualRightOnly; - shared_memory->fullkey_color.fullkey = body_colors.right; - shared_memory->battery_level_dual = battery_level.right.battery_level; - shared_memory->system_properties.is_charging_joy_dual.Assign( - battery_level.right.is_charging); - } - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - shared_memory->fullkey_color.attribute = ColorAttribute::Ok; - shared_memory->fullkey_color.fullkey = body_colors.left; - shared_memory->joycon_color.attribute = ColorAttribute::Ok; - shared_memory->joycon_color.left = body_colors.left; - shared_memory->battery_level_dual = battery_level.left.battery_level; - shared_memory->style_tag.joycon_left.Assign(1); - shared_memory->device_type.joycon_left.Assign(1); - shared_memory->system_properties.is_horizontal.Assign(1); - shared_memory->system_properties.use_minus.Assign(1); - shared_memory->system_properties.is_charging_joy_left.Assign( - battery_level.left.is_charging); - shared_memory->applet_footer_type = AppletFooterUiType::JoyLeftHorizontal; - shared_memory->sixaxis_left_properties.is_newly_assigned.Assign(1); - break; - case Core::HID::NpadStyleIndex::JoyconRight: - shared_memory->fullkey_color.attribute = ColorAttribute::Ok; - shared_memory->fullkey_color.fullkey = body_colors.right; - shared_memory->joycon_color.attribute = ColorAttribute::Ok; - shared_memory->joycon_color.right = body_colors.right; - shared_memory->battery_level_right = battery_level.right.battery_level; - shared_memory->style_tag.joycon_right.Assign(1); - shared_memory->device_type.joycon_right.Assign(1); - shared_memory->system_properties.is_horizontal.Assign(1); - shared_memory->system_properties.use_plus.Assign(1); - shared_memory->system_properties.is_charging_joy_right.Assign( - battery_level.right.is_charging); - shared_memory->applet_footer_type = AppletFooterUiType::JoyRightHorizontal; - shared_memory->sixaxis_right_properties.is_newly_assigned.Assign(1); - break; - case Core::HID::NpadStyleIndex::GameCube: - shared_memory->style_tag.gamecube.Assign(1); - shared_memory->device_type.fullkey.Assign(1); - shared_memory->system_properties.is_vertical.Assign(1); - shared_memory->system_properties.use_plus.Assign(1); - break; - case Core::HID::NpadStyleIndex::Pokeball: - shared_memory->style_tag.palma.Assign(1); - shared_memory->device_type.palma.Assign(1); - shared_memory->sixaxis_fullkey_properties.is_newly_assigned.Assign(1); - break; - case Core::HID::NpadStyleIndex::NES: - shared_memory->style_tag.lark.Assign(1); - shared_memory->device_type.fullkey.Assign(1); - break; - case Core::HID::NpadStyleIndex::SNES: - shared_memory->style_tag.lucia.Assign(1); - shared_memory->device_type.fullkey.Assign(1); - shared_memory->applet_footer_type = AppletFooterUiType::Lucia; - break; - case Core::HID::NpadStyleIndex::N64: - shared_memory->style_tag.lagoon.Assign(1); - shared_memory->device_type.fullkey.Assign(1); - shared_memory->applet_footer_type = AppletFooterUiType::Lagon; - break; - case Core::HID::NpadStyleIndex::SegaGenesis: - shared_memory->style_tag.lager.Assign(1); - shared_memory->device_type.fullkey.Assign(1); - break; - default: - break; - } - - controller.is_connected = true; - controller.device->Connect(); - controller.device->SetLedPattern(); - if (controller_type == Core::HID::NpadStyleIndex::JoyconDual) { - if (controller.is_dual_left_connected) { - controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::LeftIndex, - Common::Input::PollingMode::Active); - } - if (controller.is_dual_right_connected) { - controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, - Common::Input::PollingMode::Active); - } - } else { - controller.device->SetPollingMode(Core::HID::EmulatedDeviceIndex::AllDevices, - Common::Input::PollingMode::Active); - } - - npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id); - WriteEmptyEntry(controller.shared_memory); - hid_core.SetLastActiveController(npad_id); -} - -void NPad::WriteEmptyEntry(NpadInternalState* npad) { - NPadGenericState dummy_pad_state{}; - NpadGcTriggerState dummy_gc_state{}; - dummy_pad_state.sampling_number = npad->fullkey_lifo.ReadCurrentEntry().sampling_number + 1; - npad->fullkey_lifo.WriteNextEntry(dummy_pad_state); - dummy_pad_state.sampling_number = npad->handheld_lifo.ReadCurrentEntry().sampling_number + 1; - npad->handheld_lifo.WriteNextEntry(dummy_pad_state); - dummy_pad_state.sampling_number = npad->joy_dual_lifo.ReadCurrentEntry().sampling_number + 1; - npad->joy_dual_lifo.WriteNextEntry(dummy_pad_state); - dummy_pad_state.sampling_number = npad->joy_left_lifo.ReadCurrentEntry().sampling_number + 1; - npad->joy_left_lifo.WriteNextEntry(dummy_pad_state); - dummy_pad_state.sampling_number = npad->joy_right_lifo.ReadCurrentEntry().sampling_number + 1; - npad->joy_right_lifo.WriteNextEntry(dummy_pad_state); - dummy_pad_state.sampling_number = npad->palma_lifo.ReadCurrentEntry().sampling_number + 1; - npad->palma_lifo.WriteNextEntry(dummy_pad_state); - dummy_pad_state.sampling_number = npad->system_ext_lifo.ReadCurrentEntry().sampling_number + 1; - npad->system_ext_lifo.WriteNextEntry(dummy_pad_state); - dummy_gc_state.sampling_number = npad->gc_trigger_lifo.ReadCurrentEntry().sampling_number + 1; - npad->gc_trigger_lifo.WriteNextEntry(dummy_gc_state); -} - -void NPad::RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id) { - std::scoped_lock lock{*applet_resource_holder.shared_mutex}; - auto& controller = GetControllerFromNpadIdType(aruid, npad_id); - const auto controller_type = controller.device->GetNpadStyleIndex(); - - if (!controller.device->IsConnected() && controller.is_connected) { - DisconnectNpad(aruid, npad_id); - return; - } - if (!controller.device->IsConnected()) { - return; - } - if (controller.device->IsConnected() && !controller.is_connected) { - InitNewlyAddedController(aruid, npad_id); - } - - // This function is unique to yuzu for the turbo buttons and motion to work properly - controller.device->StatusUpdate(); - - auto& pad_entry = controller.npad_pad_state; - auto& trigger_entry = controller.npad_trigger_state; - const auto button_state = controller.device->GetNpadButtons(); - const auto stick_state = controller.device->GetSticks(); - - using btn = Core::HID::NpadButton; - pad_entry.npad_buttons.raw = btn::None; - if (controller_type != Core::HID::NpadStyleIndex::JoyconLeft) { - constexpr btn right_button_mask = btn::A | btn::B | btn::X | btn::Y | btn::StickR | btn::R | - btn::ZR | btn::Plus | btn::StickRLeft | btn::StickRUp | - btn::StickRRight | btn::StickRDown; - pad_entry.npad_buttons.raw = button_state.raw & right_button_mask; - pad_entry.r_stick = stick_state.right; - } - - if (controller_type != Core::HID::NpadStyleIndex::JoyconRight) { - constexpr btn left_button_mask = - btn::Left | btn::Up | btn::Right | btn::Down | btn::StickL | btn::L | btn::ZL | - btn::Minus | btn::StickLLeft | btn::StickLUp | btn::StickLRight | btn::StickLDown; - pad_entry.npad_buttons.raw |= button_state.raw & left_button_mask; - pad_entry.l_stick = stick_state.left; - } - - if (controller_type == Core::HID::NpadStyleIndex::JoyconLeft || - controller_type == Core::HID::NpadStyleIndex::JoyconDual) { - pad_entry.npad_buttons.left_sl.Assign(button_state.left_sl); - pad_entry.npad_buttons.left_sr.Assign(button_state.left_sr); - } - - if (controller_type == Core::HID::NpadStyleIndex::JoyconRight || - controller_type == Core::HID::NpadStyleIndex::JoyconDual) { - pad_entry.npad_buttons.right_sl.Assign(button_state.right_sl); - pad_entry.npad_buttons.right_sr.Assign(button_state.right_sr); - } - - if (controller_type == Core::HID::NpadStyleIndex::GameCube) { - const auto& trigger_state = controller.device->GetTriggers(); - trigger_entry.l_analog = trigger_state.left; - trigger_entry.r_analog = trigger_state.right; - pad_entry.npad_buttons.zl.Assign(false); - pad_entry.npad_buttons.zr.Assign(button_state.r); - pad_entry.npad_buttons.l.Assign(button_state.zl); - pad_entry.npad_buttons.r.Assign(button_state.zr); - } - - if (pad_entry.npad_buttons.raw != Core::HID::NpadButton::None) { - hid_core.SetLastActiveController(npad_id); - } -} - -void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (ref_counter == 0) { - return; - } - - std::scoped_lock lock{*applet_resource_holder.shared_mutex}; - for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) { - const auto* data = applet_resource_holder.applet_resource->GetAruidDataByIndex(aruid_index); - const auto aruid = data->aruid; - - if (!data->flag.is_assigned) { - continue; - } - - for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) { - auto& controller = controller_data[aruid_index][i]; - controller.shared_memory = - &data->shared_memory_format->npad.npad_entry[i].internal_state; - auto* npad = controller.shared_memory; - - const auto& controller_type = controller.device->GetNpadStyleIndex(); - - if (controller_type == Core::HID::NpadStyleIndex::None || - !controller.device->IsConnected()) { - continue; - } - - RequestPadStateUpdate(aruid, controller.device->GetNpadIdType()); - auto& pad_state = controller.npad_pad_state; - auto& libnx_state = controller.npad_libnx_state; - auto& trigger_state = controller.npad_trigger_state; - - // LibNX exclusively uses this section, so we always update it since LibNX doesn't - // activate any controllers. - libnx_state.connection_status.raw = 0; - libnx_state.connection_status.is_connected.Assign(1); - switch (controller_type) { - case Core::HID::NpadStyleIndex::None: - ASSERT(false); - break; - case Core::HID::NpadStyleIndex::ProController: - case Core::HID::NpadStyleIndex::NES: - case Core::HID::NpadStyleIndex::SNES: - case Core::HID::NpadStyleIndex::N64: - case Core::HID::NpadStyleIndex::SegaGenesis: - pad_state.connection_status.raw = 0; - pad_state.connection_status.is_connected.Assign(1); - pad_state.connection_status.is_wired.Assign(1); - - libnx_state.connection_status.is_wired.Assign(1); - pad_state.sampling_number = - npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; - npad->fullkey_lifo.WriteNextEntry(pad_state); - break; - case Core::HID::NpadStyleIndex::Handheld: - pad_state.connection_status.raw = 0; - pad_state.connection_status.is_connected.Assign(1); - pad_state.connection_status.is_wired.Assign(1); - pad_state.connection_status.is_left_connected.Assign(1); - pad_state.connection_status.is_right_connected.Assign(1); - pad_state.connection_status.is_left_wired.Assign(1); - pad_state.connection_status.is_right_wired.Assign(1); - - libnx_state.connection_status.is_wired.Assign(1); - libnx_state.connection_status.is_left_connected.Assign(1); - libnx_state.connection_status.is_right_connected.Assign(1); - libnx_state.connection_status.is_left_wired.Assign(1); - libnx_state.connection_status.is_right_wired.Assign(1); - pad_state.sampling_number = - npad->handheld_lifo.ReadCurrentEntry().state.sampling_number + 1; - npad->handheld_lifo.WriteNextEntry(pad_state); - break; - case Core::HID::NpadStyleIndex::JoyconDual: - pad_state.connection_status.raw = 0; - pad_state.connection_status.is_connected.Assign(1); - if (controller.is_dual_left_connected) { - pad_state.connection_status.is_left_connected.Assign(1); - libnx_state.connection_status.is_left_connected.Assign(1); - } - if (controller.is_dual_right_connected) { - pad_state.connection_status.is_right_connected.Assign(1); - libnx_state.connection_status.is_right_connected.Assign(1); - } - - pad_state.sampling_number = - npad->joy_dual_lifo.ReadCurrentEntry().state.sampling_number + 1; - npad->joy_dual_lifo.WriteNextEntry(pad_state); - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - pad_state.connection_status.raw = 0; - pad_state.connection_status.is_connected.Assign(1); - pad_state.connection_status.is_left_connected.Assign(1); - - libnx_state.connection_status.is_left_connected.Assign(1); - pad_state.sampling_number = - npad->joy_left_lifo.ReadCurrentEntry().state.sampling_number + 1; - npad->joy_left_lifo.WriteNextEntry(pad_state); - break; - case Core::HID::NpadStyleIndex::JoyconRight: - pad_state.connection_status.raw = 0; - pad_state.connection_status.is_connected.Assign(1); - pad_state.connection_status.is_right_connected.Assign(1); - - libnx_state.connection_status.is_right_connected.Assign(1); - pad_state.sampling_number = - npad->joy_right_lifo.ReadCurrentEntry().state.sampling_number + 1; - npad->joy_right_lifo.WriteNextEntry(pad_state); - break; - case Core::HID::NpadStyleIndex::GameCube: - pad_state.connection_status.raw = 0; - pad_state.connection_status.is_connected.Assign(1); - pad_state.connection_status.is_wired.Assign(1); - - libnx_state.connection_status.is_wired.Assign(1); - pad_state.sampling_number = - npad->fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1; - trigger_state.sampling_number = - npad->gc_trigger_lifo.ReadCurrentEntry().state.sampling_number + 1; - npad->fullkey_lifo.WriteNextEntry(pad_state); - npad->gc_trigger_lifo.WriteNextEntry(trigger_state); - break; - case Core::HID::NpadStyleIndex::Pokeball: - pad_state.connection_status.raw = 0; - pad_state.connection_status.is_connected.Assign(1); - pad_state.sampling_number = - npad->palma_lifo.ReadCurrentEntry().state.sampling_number + 1; - npad->palma_lifo.WriteNextEntry(pad_state); - break; - default: - break; - } - - libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw; - libnx_state.l_stick = pad_state.l_stick; - libnx_state.r_stick = pad_state.r_stick; - npad->system_ext_lifo.WriteNextEntry(pad_state); - - press_state |= static_cast<u64>(pad_state.npad_buttons.raw); - } - } -} - -Result NPad::SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet supported_style_set) { - std::scoped_lock lock{mutex}; - hid_core.SetSupportedStyleTag({supported_style_set}); - const Result result = npad_resource.SetSupportedNpadStyleSet(aruid, supported_style_set); - if (result.IsSuccess()) { - OnUpdate({}); - } - return result; -} - -Result NPad::GetSupportedNpadStyleSet(u64 aruid, - Core::HID::NpadStyleSet& out_supported_style_set) const { - std::scoped_lock lock{mutex}; - const Result result = npad_resource.GetSupportedNpadStyleSet(out_supported_style_set, aruid); - - if (result == ResultUndefinedStyleset) { - out_supported_style_set = Core::HID::NpadStyleSet::None; - return ResultSuccess; - } - - return result; -} - -Result NPad::GetMaskedSupportedNpadStyleSet( - u64 aruid, Core::HID::NpadStyleSet& out_supported_style_set) const { - std::scoped_lock lock{mutex}; - const Result result = - npad_resource.GetMaskedSupportedNpadStyleSet(out_supported_style_set, aruid); - - if (result == ResultUndefinedStyleset) { - out_supported_style_set = Core::HID::NpadStyleSet::None; - return ResultSuccess; - } - - return result; -} - -Result NPad::SetSupportedNpadIdType(u64 aruid, - std::span<const Core::HID::NpadIdType> supported_npad_list) { - std::scoped_lock lock{mutex}; - if (supported_npad_list.size() > MaxSupportedNpadIdTypes) { - return ResultInvalidArraySize; - } - - Result result = npad_resource.SetSupportedNpadIdType(aruid, supported_npad_list); - - if (result.IsSuccess()) { - OnUpdate({}); - } - - return result; -} - -Result NPad::SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type) { - std::scoped_lock lock{mutex}; - return npad_resource.SetNpadJoyHoldType(aruid, hold_type); -} - -Result NPad::GetNpadJoyHoldType(u64 aruid, NpadJoyHoldType& out_hold_type) const { - std::scoped_lock lock{mutex}; - return npad_resource.GetNpadJoyHoldType(out_hold_type, aruid); -} - -Result NPad::SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode mode) { - std::scoped_lock lock{mutex}; - Result result = npad_resource.SetNpadHandheldActivationMode(aruid, mode); - if (result.IsSuccess()) { - OnUpdate({}); - } - return result; -} - -Result NPad::GetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode& out_mode) const { - std::scoped_lock lock{mutex}; - return npad_resource.GetNpadHandheldActivationMode(out_mode, aruid); -} - -bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, - NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode) { - if (!IsNpadIdValid(npad_id)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - return false; - } - - auto& controller = GetControllerFromNpadIdType(aruid, npad_id); - if (controller.shared_memory->assignment_mode != assignment_mode) { - controller.shared_memory->assignment_mode = assignment_mode; - } - - if (!controller.device->IsConnected()) { - return false; - } - - if (assignment_mode == NpadJoyAssignmentMode::Dual) { - if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft) { - DisconnectNpad(aruid, npad_id); - controller.is_dual_left_connected = true; - controller.is_dual_right_connected = false; - UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); - return false; - } - if (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight) { - DisconnectNpad(aruid, npad_id); - controller.is_dual_left_connected = false; - controller.is_dual_right_connected = true; - UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id, true); - return false; - } - return false; - } - - // This is for NpadJoyAssignmentMode::Single - - // Only JoyconDual get affected by this function - if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::JoyconDual) { - return false; - } - - if (controller.is_dual_left_connected && !controller.is_dual_right_connected) { - DisconnectNpad(aruid, npad_id); - UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); - return false; - } - if (!controller.is_dual_left_connected && controller.is_dual_right_connected) { - DisconnectNpad(aruid, npad_id); - UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); - return false; - } - - // We have two controllers connected to the same npad_id we need to split them - new_npad_id = hid_core.GetFirstDisconnectedNpadId(); - auto& controller_2 = GetControllerFromNpadIdType(aruid, new_npad_id); - DisconnectNpad(aruid, npad_id); - if (npad_device_type == NpadJoyDeviceType::Left) { - UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconLeft, npad_id, true); - controller_2.is_dual_left_connected = false; - controller_2.is_dual_right_connected = true; - UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true); - } else { - UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconRight, npad_id, true); - controller_2.is_dual_left_connected = true; - controller_2.is_dual_right_connected = false; - UpdateControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, new_npad_id, true); - } - return true; -} - -bool NPad::VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id, - std::size_t device_index, - const Core::HID::VibrationValue& vibration_value) { - auto& controller = GetControllerFromNpadIdType(aruid, npad_id); - if (!controller.device->IsConnected()) { - return false; - } - - if (!controller.device->IsVibrationEnabled(device_index)) { - if (controller.vibration[device_index].latest_vibration_value.low_amplitude != 0.0f || - controller.vibration[device_index].latest_vibration_value.high_amplitude != 0.0f) { - // Send an empty vibration to stop any vibrations. - Core::HID::VibrationValue vibration{0.0f, 160.0f, 0.0f, 320.0f}; - controller.device->SetVibration(device_index, vibration); - // Then reset the vibration value to its default value. - controller.vibration[device_index].latest_vibration_value = - Core::HID::DEFAULT_VIBRATION_VALUE; - } - - return false; - } - - if (!Settings::values.enable_accurate_vibrations.GetValue()) { - using std::chrono::duration_cast; - using std::chrono::milliseconds; - using std::chrono::steady_clock; - - const auto now = steady_clock::now(); - - // Filter out non-zero vibrations that are within 15ms of each other. - if ((vibration_value.low_amplitude != 0.0f || vibration_value.high_amplitude != 0.0f) && - duration_cast<milliseconds>( - now - controller.vibration[device_index].last_vibration_timepoint) < - milliseconds(15)) { - return false; - } - - controller.vibration[device_index].last_vibration_timepoint = now; - } - - Core::HID::VibrationValue vibration{ - vibration_value.low_amplitude, vibration_value.low_frequency, - vibration_value.high_amplitude, vibration_value.high_frequency}; - return controller.device->SetVibration(device_index, vibration); -} - -void NPad::VibrateController(u64 aruid, - const Core::HID::VibrationDeviceHandle& vibration_device_handle, - const Core::HID::VibrationValue& vibration_value) { - if (IsVibrationHandleValid(vibration_device_handle).IsError()) { - return; - } - - if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { - return; - } - - auto& controller = GetControllerFromHandle(aruid, vibration_device_handle); - const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); - - if (!controller.vibration[device_index].device_mounted || !controller.device->IsConnected()) { - return; - } - - if (vibration_device_handle.device_index == Core::HID::DeviceIndex::None) { - ASSERT_MSG(false, "DeviceIndex should never be None!"); - return; - } - - // Some games try to send mismatched parameters in the device handle, block these. - if ((controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconLeft && - (vibration_device_handle.npad_type == Core::HID::NpadStyleIndex::JoyconRight || - vibration_device_handle.device_index == Core::HID::DeviceIndex::Right)) || - (controller.device->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::JoyconRight && - (vibration_device_handle.npad_type == Core::HID::NpadStyleIndex::JoyconLeft || - vibration_device_handle.device_index == Core::HID::DeviceIndex::Left))) { - return; - } - - // Filter out vibrations with equivalent values to reduce unnecessary state changes. - if (vibration_value.low_amplitude == - controller.vibration[device_index].latest_vibration_value.low_amplitude && - vibration_value.high_amplitude == - controller.vibration[device_index].latest_vibration_value.high_amplitude) { - return; - } - - if (VibrateControllerAtIndex(aruid, controller.device->GetNpadIdType(), device_index, - vibration_value)) { - controller.vibration[device_index].latest_vibration_value = vibration_value; - } -} - -void NPad::VibrateControllers( - u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, - std::span<const Core::HID::VibrationValue> vibration_values) { - if (!Settings::values.vibration_enabled.GetValue() && !permit_vibration_session_enabled) { - return; - } - - ASSERT_OR_EXECUTE_MSG( - vibration_device_handles.size() == vibration_values.size(), { return; }, - "The amount of device handles does not match with the amount of vibration values," - "this is undefined behavior!"); - - for (std::size_t i = 0; i < vibration_device_handles.size(); ++i) { - VibrateController(aruid, vibration_device_handles[i], vibration_values[i]); - } -} - -Core::HID::VibrationValue NPad::GetLastVibration( - u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { - if (IsVibrationHandleValid(vibration_device_handle).IsError()) { - return {}; - } - - const auto& controller = GetControllerFromHandle(aruid, vibration_device_handle); - const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); - return controller.vibration[device_index].latest_vibration_value; -} - -void NPad::InitializeVibrationDevice( - const Core::HID::VibrationDeviceHandle& vibration_device_handle) { - if (IsVibrationHandleValid(vibration_device_handle).IsError()) { - return; - } - - const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid(); - const auto npad_index = static_cast<Core::HID::NpadIdType>(vibration_device_handle.npad_id); - const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); - InitializeVibrationDeviceAtIndex(aruid, npad_index, device_index); -} - -void NPad::InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id, - std::size_t device_index) { - auto& controller = GetControllerFromNpadIdType(aruid, npad_id); - if (!Settings::values.vibration_enabled.GetValue()) { - controller.vibration[device_index].device_mounted = false; - return; - } - - controller.vibration[device_index].device_mounted = - controller.device->IsVibrationEnabled(device_index); -} - -void NPad::SetPermitVibrationSession(bool permit_vibration_session) { - permit_vibration_session_enabled = permit_vibration_session; -} - -bool NPad::IsVibrationDeviceMounted( - u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const { - if (IsVibrationHandleValid(vibration_device_handle).IsError()) { - return false; - } - - const auto& controller = GetControllerFromHandle(aruid, vibration_device_handle); - const auto device_index = static_cast<std::size_t>(vibration_device_handle.device_index); - return controller.vibration[device_index].device_mounted; -} - -Result NPad::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event, - Core::HID::NpadIdType npad_id) { - std::scoped_lock lock{mutex}; - return npad_resource.AcquireNpadStyleSetUpdateEventHandle(aruid, out_event, npad_id); -} - -void NPad::AddNewControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller, - Core::HID::NpadIdType npad_id) { - UpdateControllerAt(aruid, controller, npad_id, true); -} - -void NPad::UpdateControllerAt(u64 aruid, Core::HID::NpadStyleIndex type, - Core::HID::NpadIdType npad_id, bool connected) { - auto& controller = GetControllerFromNpadIdType(aruid, npad_id); - if (!connected) { - DisconnectNpad(aruid, npad_id); - return; - } - - controller.device->SetNpadStyleIndex(type); - InitNewlyAddedController(aruid, npad_id); -} - -Result NPad::DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id) { - if (!IsNpadIdValid(npad_id)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - return ResultInvalidNpadId; - } - - LOG_DEBUG(Service_HID, "Npad disconnected {}", npad_id); - auto& controller = GetControllerFromNpadIdType(aruid, npad_id); - for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) { - // Send an empty vibration to stop any vibrations. - VibrateControllerAtIndex(aruid, npad_id, device_idx, {}); - controller.vibration[device_idx].device_mounted = false; - } - - auto* shared_memory = controller.shared_memory; - // Don't reset shared_memory->assignment_mode this value is persistent - shared_memory->style_tag.raw = Core::HID::NpadStyleSet::None; // Zero out - shared_memory->device_type.raw = 0; - shared_memory->system_properties.raw = 0; - shared_memory->button_properties.raw = 0; - shared_memory->sixaxis_fullkey_properties.raw = 0; - shared_memory->sixaxis_handheld_properties.raw = 0; - shared_memory->sixaxis_dual_left_properties.raw = 0; - shared_memory->sixaxis_dual_right_properties.raw = 0; - shared_memory->sixaxis_left_properties.raw = 0; - shared_memory->sixaxis_right_properties.raw = 0; - shared_memory->battery_level_dual = Core::HID::NpadBatteryLevel::Empty; - shared_memory->battery_level_left = Core::HID::NpadBatteryLevel::Empty; - shared_memory->battery_level_right = Core::HID::NpadBatteryLevel::Empty; - shared_memory->fullkey_color = { - .attribute = ColorAttribute::NoController, - .fullkey = {}, - }; - shared_memory->joycon_color = { - .attribute = ColorAttribute::NoController, - .left = {}, - .right = {}, - }; - shared_memory->applet_footer_type = AppletFooterUiType::None; - - controller.is_dual_left_connected = true; - controller.is_dual_right_connected = true; - controller.is_connected = false; - controller.device->Disconnect(); - npad_resource.SignalStyleSetUpdateEvent(aruid, npad_id); - WriteEmptyEntry(shared_memory); - return ResultSuccess; -} - -Result NPad::IsFirmwareUpdateAvailableForSixAxisSensor( - u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool& is_firmware_available) const { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - const auto& sixaxis_properties = GetSixaxisProperties(aruid, sixaxis_handle); - is_firmware_available = sixaxis_properties.is_firmware_update_available != 0; - return ResultSuccess; -} - -Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned( - u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - auto& sixaxis_properties = GetSixaxisProperties(aruid, sixaxis_handle); - sixaxis_properties.is_newly_assigned.Assign(0); - - return ResultSuccess; -} - -Result NPad::MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1, - Core::HID::NpadIdType npad_id_2) { - if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, - npad_id_2); - return ResultInvalidNpadId; - } - auto& controller_1 = GetControllerFromNpadIdType(aruid, npad_id_1); - auto& controller_2 = GetControllerFromNpadIdType(aruid, npad_id_2); - auto controller_style_1 = controller_1.device->GetNpadStyleIndex(); - auto controller_style_2 = controller_2.device->GetNpadStyleIndex(); - - // Simplify this code by converting dualjoycon with only a side connected to single joycons - if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual) { - if (controller_1.is_dual_left_connected && !controller_1.is_dual_right_connected) { - controller_style_1 = Core::HID::NpadStyleIndex::JoyconLeft; - } - if (!controller_1.is_dual_left_connected && controller_1.is_dual_right_connected) { - controller_style_1 = Core::HID::NpadStyleIndex::JoyconRight; - } - } - if (controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) { - if (controller_2.is_dual_left_connected && !controller_2.is_dual_right_connected) { - controller_style_2 = Core::HID::NpadStyleIndex::JoyconLeft; - } - if (!controller_2.is_dual_left_connected && controller_2.is_dual_right_connected) { - controller_style_2 = Core::HID::NpadStyleIndex::JoyconRight; - } - } - - // Invalid merge errors - if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconDual || - controller_style_2 == Core::HID::NpadStyleIndex::JoyconDual) { - return NpadIsDualJoycon; - } - if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconLeft && - controller_style_2 == Core::HID::NpadStyleIndex::JoyconLeft) { - return NpadIsSameType; - } - if (controller_style_1 == Core::HID::NpadStyleIndex::JoyconRight && - controller_style_2 == Core::HID::NpadStyleIndex::JoyconRight) { - return NpadIsSameType; - } - - // These exceptions are handled as if they where dual joycon - if (controller_style_1 != Core::HID::NpadStyleIndex::JoyconLeft && - controller_style_1 != Core::HID::NpadStyleIndex::JoyconRight) { - return NpadIsDualJoycon; - } - if (controller_style_2 != Core::HID::NpadStyleIndex::JoyconLeft && - controller_style_2 != Core::HID::NpadStyleIndex::JoyconRight) { - return NpadIsDualJoycon; - } - - // Disconnect the joycons and connect them as dual joycon at the first index. - DisconnectNpad(aruid, npad_id_1); - DisconnectNpad(aruid, npad_id_2); - controller_1.is_dual_left_connected = true; - controller_1.is_dual_right_connected = true; - AddNewControllerAt(aruid, Core::HID::NpadStyleIndex::JoyconDual, npad_id_1); - return ResultSuccess; -} - -Result NPad::StartLrAssignmentMode(u64 aruid) { - std::scoped_lock lock{mutex}; - bool is_enabled{}; - Result result = npad_resource.GetLrAssignmentMode(is_enabled, aruid); - if (result.IsSuccess() && is_enabled == false) { - result = npad_resource.SetLrAssignmentMode(aruid, true); - } - return result; -} - -Result NPad::StopLrAssignmentMode(u64 aruid) { - std::scoped_lock lock{mutex}; - bool is_enabled{}; - Result result = npad_resource.GetLrAssignmentMode(is_enabled, aruid); - if (result.IsSuccess() && is_enabled == true) { - result = npad_resource.SetLrAssignmentMode(aruid, false); - } - return result; -} - -Result NPad::SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1, - Core::HID::NpadIdType npad_id_2) { - if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id_1:{}, npad_id_2:{}", npad_id_1, - npad_id_2); - return ResultInvalidNpadId; - } - if (npad_id_1 == Core::HID::NpadIdType::Handheld || - npad_id_2 == Core::HID::NpadIdType::Handheld || npad_id_1 == Core::HID::NpadIdType::Other || - npad_id_2 == Core::HID::NpadIdType::Other) { - return ResultSuccess; - } - const auto& controller_1 = GetControllerFromNpadIdType(aruid, npad_id_1).device; - const auto& controller_2 = GetControllerFromNpadIdType(aruid, npad_id_2).device; - const auto type_index_1 = controller_1->GetNpadStyleIndex(); - const auto type_index_2 = controller_2->GetNpadStyleIndex(); - const auto is_connected_1 = controller_1->IsConnected(); - const auto is_connected_2 = controller_2->IsConnected(); - - if (!npad_resource.IsControllerSupported(aruid, type_index_1) && is_connected_1) { - return ResultNpadNotConnected; - } - if (!npad_resource.IsControllerSupported(aruid, type_index_2) && is_connected_2) { - return ResultNpadNotConnected; - } - - UpdateControllerAt(aruid, type_index_2, npad_id_1, is_connected_2); - UpdateControllerAt(aruid, type_index_1, npad_id_2, is_connected_1); - - return ResultSuccess; -} - -Result NPad::GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const { - if (!IsNpadIdValid(npad_id)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - return ResultInvalidNpadId; - } - const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid(); - const auto& controller = GetControllerFromNpadIdType(aruid, npad_id).device; - pattern = controller->GetLedPattern(); - return ResultSuccess; -} - -Result NPad::IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid, - Core::HID::NpadIdType npad_id) const { - std::scoped_lock lock{mutex}; - return npad_resource.GetHomeProtectionEnabled(out_is_enabled, aruid, npad_id); -} - -Result NPad::EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id, - bool is_enabled) { - std::scoped_lock lock{mutex}; - return npad_resource.SetHomeProtectionEnabled(aruid, npad_id, is_enabled); -} - -void NPad::SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled) { - std::scoped_lock lock{mutex}; - npad_resource.SetNpadAnalogStickUseCenterClamp(aruid, is_enabled); -} - -void NPad::ClearAllConnectedControllers() { - for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) { - for (auto& controller : controller_data[aruid_index]) { - if (controller.device->IsConnected() && - controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None) { - controller.device->Disconnect(); - controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None); - } - } - } -} - -void NPad::DisconnectAllConnectedControllers() { - for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) { - for (auto& controller : controller_data[aruid_index]) { - controller.device->Disconnect(); - } - } -} - -void NPad::ConnectAllDisconnectedControllers() { - for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) { - for (auto& controller : controller_data[aruid_index]) { - if (controller.device->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::None && - !controller.device->IsConnected()) { - controller.device->Connect(); - } - } - } -} - -void NPad::ClearAllControllers() { - for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; aruid_index++) { - for (auto& controller : controller_data[aruid_index]) { - controller.device->Disconnect(); - controller.device->SetNpadStyleIndex(Core::HID::NpadStyleIndex::None); - } - } -} - -Core::HID::NpadButton NPad::GetAndResetPressState() { - return static_cast<Core::HID::NpadButton>(press_state.exchange(0)); -} - -Result NPad::ApplyNpadSystemCommonPolicy(u64 aruid) { - std::scoped_lock lock{mutex}; - const Result result = npad_resource.ApplyNpadSystemCommonPolicy(aruid, false); - if (result.IsSuccess()) { - OnUpdate({}); - } - return result; -} - -Result NPad::ApplyNpadSystemCommonPolicyFull(u64 aruid) { - std::scoped_lock lock{mutex}; - const Result result = npad_resource.ApplyNpadSystemCommonPolicy(aruid, true); - if (result.IsSuccess()) { - OnUpdate({}); - } - return result; -} - -Result NPad::ClearNpadSystemCommonPolicy(u64 aruid) { - std::scoped_lock lock{mutex}; - const Result result = npad_resource.ClearNpadSystemCommonPolicy(aruid); - if (result.IsSuccess()) { - OnUpdate({}); - } - return result; -} - -void NPad::SetRevision(u64 aruid, NpadRevision revision) { - npad_resource.SetNpadRevision(aruid, revision); -} - -NpadRevision NPad::GetRevision(u64 aruid) { - return npad_resource.GetNpadRevision(aruid); -} - -Result NPad::RegisterAppletResourceUserId(u64 aruid) { - return npad_resource.RegisterAppletResourceUserId(aruid); -} - -void NPad::UnregisterAppletResourceUserId(u64 aruid) { - npad_resource.UnregisterAppletResourceUserId(aruid); -} - -void NPad::SetNpadExternals(std::shared_ptr<AppletResource> resource, - std::recursive_mutex* shared_mutex) { - applet_resource_holder.applet_resource = resource; - applet_resource_holder.shared_mutex = shared_mutex; - applet_resource_holder.shared_npad_resource = &npad_resource; -} - -NPad::NpadControllerData& NPad::GetControllerFromHandle( - u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) { - const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); - return GetControllerFromNpadIdType(aruid, npad_id); -} - -const NPad::NpadControllerData& NPad::GetControllerFromHandle( - u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const { - const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); - return GetControllerFromNpadIdType(aruid, npad_id); -} - -NPad::NpadControllerData& NPad::GetControllerFromHandle( - u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) { - const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); - return GetControllerFromNpadIdType(aruid, npad_id); -} - -const NPad::NpadControllerData& NPad::GetControllerFromHandle( - u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const { - const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); - return GetControllerFromNpadIdType(aruid, npad_id); -} - -NPad::NpadControllerData& NPad::GetControllerFromNpadIdType(u64 aruid, - Core::HID::NpadIdType npad_id) { - if (!IsNpadIdValid(npad_id)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - npad_id = Core::HID::NpadIdType::Player1; - } - const auto npad_index = NpadIdTypeToIndex(npad_id); - const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid); - return controller_data[aruid_index][npad_index]; -} - -const NPad::NpadControllerData& NPad::GetControllerFromNpadIdType( - u64 aruid, Core::HID::NpadIdType npad_id) const { - if (!IsNpadIdValid(npad_id)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - npad_id = Core::HID::NpadIdType::Player1; - } - const auto npad_index = NpadIdTypeToIndex(npad_id); - const auto aruid_index = applet_resource_holder.applet_resource->GetIndexFromAruid(aruid); - return controller_data[aruid_index][npad_index]; -} - -Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( - u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) { - auto& controller = GetControllerFromHandle(aruid, sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - case Core::HID::NpadStyleIndex::Pokeball: - return controller.shared_memory->sixaxis_fullkey_properties; - case Core::HID::NpadStyleIndex::Handheld: - return controller.shared_memory->sixaxis_handheld_properties; - case Core::HID::NpadStyleIndex::JoyconDual: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - return controller.shared_memory->sixaxis_dual_left_properties; - } - return controller.shared_memory->sixaxis_dual_right_properties; - case Core::HID::NpadStyleIndex::JoyconLeft: - return controller.shared_memory->sixaxis_left_properties; - case Core::HID::NpadStyleIndex::JoyconRight: - return controller.shared_memory->sixaxis_right_properties; - default: - return controller.shared_memory->sixaxis_fullkey_properties; - } -} - -const Core::HID::SixAxisSensorProperties& NPad::GetSixaxisProperties( - u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { - const auto& controller = GetControllerFromHandle(aruid, sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - case Core::HID::NpadStyleIndex::Pokeball: - return controller.shared_memory->sixaxis_fullkey_properties; - case Core::HID::NpadStyleIndex::Handheld: - return controller.shared_memory->sixaxis_handheld_properties; - case Core::HID::NpadStyleIndex::JoyconDual: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - return controller.shared_memory->sixaxis_dual_left_properties; - } - return controller.shared_memory->sixaxis_dual_right_properties; - case Core::HID::NpadStyleIndex::JoyconLeft: - return controller.shared_memory->sixaxis_left_properties; - case Core::HID::NpadStyleIndex::JoyconRight: - return controller.shared_memory->sixaxis_right_properties; - default: - return controller.shared_memory->sixaxis_fullkey_properties; - } -} - -AppletDetailedUiType NPad::GetAppletDetailedUiType(Core::HID::NpadIdType npad_id) { - const auto aruid = applet_resource_holder.applet_resource->GetActiveAruid(); - const auto& shared_memory = GetControllerFromNpadIdType(aruid, npad_id).shared_memory; - - return { - .ui_variant = 0, - .footer = shared_memory->applet_footer_type, - }; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h deleted file mode 100644 index 8ab333064..000000000 --- a/src/core/hle/service/hid/controllers/npad.h +++ /dev/null @@ -1,214 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> -#include <atomic> -#include <mutex> -#include <span> - -#include "common/common_types.h" -#include "core/hid/hid_types.h" -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/controllers/npad/npad_resource.h" -#include "core/hle/service/hid/controllers/types/npad_types.h" - -namespace Core::HID { -class EmulatedController; -enum class ControllerTriggerType; -} // namespace Core::HID - -namespace Kernel { -class KEvent; -class KReadableEvent; -} // namespace Kernel - -namespace Service::KernelHelpers { -class ServiceContext; -} // namespace Service::KernelHelpers - -union Result; - -namespace Service::HID { -class AppletResource; -struct NpadInternalState; -struct NpadSixAxisSensorLifo; -struct NpadSharedMemoryFormat; - -class NPad final { -public: - explicit NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_); - ~NPad(); - - Result Activate(); - Result Activate(u64 aruid); - - Result ActivateNpadResource(); - Result ActivateNpadResource(u64 aruid); - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing); - - Result SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet supported_style_set); - Result GetSupportedNpadStyleSet(u64 aruid, - Core::HID::NpadStyleSet& out_supported_style_set) const; - Result GetMaskedSupportedNpadStyleSet(u64 aruid, - Core::HID::NpadStyleSet& out_supported_style_set) const; - - Result SetSupportedNpadIdType(u64 aruid, - std::span<const Core::HID::NpadIdType> supported_npad_list); - - Result SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type); - Result GetNpadJoyHoldType(u64 aruid, NpadJoyHoldType& out_hold_type) const; - - Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode mode); - Result GetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode& out_mode) const; - - bool SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID::NpadIdType npad_id, - NpadJoyDeviceType npad_device_type, NpadJoyAssignmentMode assignment_mode); - - bool VibrateControllerAtIndex(u64 aruid, Core::HID::NpadIdType npad_id, - std::size_t device_index, - const Core::HID::VibrationValue& vibration_value); - - void VibrateController(u64 aruid, - const Core::HID::VibrationDeviceHandle& vibration_device_handle, - const Core::HID::VibrationValue& vibration_value); - - void VibrateControllers( - u64 aruid, std::span<const Core::HID::VibrationDeviceHandle> vibration_device_handles, - std::span<const Core::HID::VibrationValue> vibration_values); - - Core::HID::VibrationValue GetLastVibration( - u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const; - - void InitializeVibrationDevice(const Core::HID::VibrationDeviceHandle& vibration_device_handle); - - void InitializeVibrationDeviceAtIndex(u64 aruid, Core::HID::NpadIdType npad_id, - std::size_t device_index); - - void SetPermitVibrationSession(bool permit_vibration_session); - - bool IsVibrationDeviceMounted( - u64 aruid, const Core::HID::VibrationDeviceHandle& vibration_device_handle) const; - - Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event, - Core::HID::NpadIdType npad_id); - - // Adds a new controller at an index. - void AddNewControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller, - Core::HID::NpadIdType npad_id); - // Adds a new controller at an index with connection status. - void UpdateControllerAt(u64 aruid, Core::HID::NpadStyleIndex controller, - Core::HID::NpadIdType npad_id, bool connected); - - Result DisconnectNpad(u64 aruid, Core::HID::NpadIdType npad_id); - - Result IsFirmwareUpdateAvailableForSixAxisSensor( - u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool& is_firmware_available) const; - Result ResetIsSixAxisSensorDeviceNewlyAssigned( - u64 aruid, const Core::HID::SixAxisSensorHandle& sixaxis_handle); - - Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const; - - Result IsUnintendedHomeButtonInputProtectionEnabled(bool& out_is_enabled, u64 aruid, - Core::HID::NpadIdType npad_id) const; - Result EnableUnintendedHomeButtonInputProtection(u64 aruid, Core::HID::NpadIdType npad_id, - bool is_enabled); - - void SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled); - void ClearAllConnectedControllers(); - void DisconnectAllConnectedControllers(); - void ConnectAllDisconnectedControllers(); - void ClearAllControllers(); - - Result MergeSingleJoyAsDualJoy(u64 aruid, Core::HID::NpadIdType npad_id_1, - Core::HID::NpadIdType npad_id_2); - Result StartLrAssignmentMode(u64 aruid); - Result StopLrAssignmentMode(u64 aruid); - Result SwapNpadAssignment(u64 aruid, Core::HID::NpadIdType npad_id_1, - Core::HID::NpadIdType npad_id_2); - - // Logical OR for all buttons presses on all controllers - // Specifically for cheat engine and other features. - Core::HID::NpadButton GetAndResetPressState(); - - Result ApplyNpadSystemCommonPolicy(u64 aruid); - Result ApplyNpadSystemCommonPolicyFull(u64 aruid); - Result ClearNpadSystemCommonPolicy(u64 aruid); - - void SetRevision(u64 aruid, NpadRevision revision); - NpadRevision GetRevision(u64 aruid); - - Result RegisterAppletResourceUserId(u64 aruid); - void UnregisterAppletResourceUserId(u64 aruid); - void SetNpadExternals(std::shared_ptr<AppletResource> resource, - std::recursive_mutex* shared_mutex); - - AppletDetailedUiType GetAppletDetailedUiType(Core::HID::NpadIdType npad_id); - -private: - struct VibrationData { - bool device_mounted{}; - Core::HID::VibrationValue latest_vibration_value{}; - std::chrono::steady_clock::time_point last_vibration_timepoint{}; - }; - - struct NpadControllerData { - NpadInternalState* shared_memory = nullptr; - Core::HID::EmulatedController* device = nullptr; - - std::array<VibrationData, 2> vibration{}; - bool is_connected{}; - - // Dual joycons can have only one side connected - bool is_dual_left_connected{true}; - bool is_dual_right_connected{true}; - - // Current pad state - NPadGenericState npad_pad_state{}; - NPadGenericState npad_libnx_state{}; - NpadGcTriggerState npad_trigger_state{}; - int callback_key{}; - }; - - void ControllerUpdate(Core::HID::ControllerTriggerType type, std::size_t controller_idx); - void InitNewlyAddedController(u64 aruid, Core::HID::NpadIdType npad_id); - void RequestPadStateUpdate(u64 aruid, Core::HID::NpadIdType npad_id); - void WriteEmptyEntry(NpadInternalState* npad); - - NpadControllerData& GetControllerFromHandle( - u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle); - const NpadControllerData& GetControllerFromHandle( - u64 aruid, const Core::HID::VibrationDeviceHandle& device_handle) const; - NpadControllerData& GetControllerFromHandle( - u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle); - const NpadControllerData& GetControllerFromHandle( - u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const; - NpadControllerData& GetControllerFromNpadIdType(u64 aruid, Core::HID::NpadIdType npad_id); - const NpadControllerData& GetControllerFromNpadIdType(u64 aruid, - Core::HID::NpadIdType npad_id) const; - - Core::HID::SixAxisSensorProperties& GetSixaxisProperties( - u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle); - const Core::HID::SixAxisSensorProperties& GetSixaxisProperties( - u64 aruid, const Core::HID::SixAxisSensorHandle& device_handle) const; - - Core::HID::HIDCore& hid_core; - KernelHelpers::ServiceContext& service_context; - - s32 ref_counter{}; - mutable std::mutex mutex; - NPadResource npad_resource; - AppletResourceHolder applet_resource_holder{}; - Kernel::KEvent* input_event{nullptr}; - std::mutex* input_mutex{nullptr}; - - std::atomic<u64> press_state{}; - bool permit_vibration_session_enabled; - std::array<std::array<NpadControllerData, MaxSupportedNpadIdTypes>, AruidIndexMax> - controller_data{}; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad/npad_data.cpp b/src/core/hle/service/hid/controllers/npad/npad_data.cpp deleted file mode 100644 index d2423b6d3..000000000 --- a/src/core/hle/service/hid/controllers/npad/npad_data.cpp +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/hle/service/hid/controllers/npad/npad_data.h" -#include "core/hle/service/hid/hid_util.h" - -namespace Service::HID { - -NPadData::NPadData() { - ClearNpadSystemCommonPolicy(); -} - -NPadData::~NPadData() = default; - -NpadStatus NPadData::GetNpadStatus() const { - return status; -} - -void NPadData::SetNpadAnalogStickUseCenterClamp(bool is_enabled) { - status.use_center_clamp.Assign(is_enabled); -} - -bool NPadData::GetNpadAnalogStickUseCenterClamp() const { - return status.use_center_clamp.As<bool>(); -} - -void NPadData::SetNpadSystemExtStateEnabled(bool is_enabled) { - status.system_ext_state.Assign(is_enabled); -} - -bool NPadData::GetNpadSystemExtState() const { - return status.system_ext_state.As<bool>(); -} - -Result NPadData::SetSupportedNpadIdType(std::span<const Core::HID::NpadIdType> list) { - // Note: Real limit is 11. But array size is 10. N's bug? - if (list.size() > MaxSupportedNpadIdTypes) { - return ResultInvalidArraySize; - } - - supported_npad_id_types_count = list.size(); - memcpy(supported_npad_id_types.data(), list.data(), - list.size() * sizeof(Core::HID::NpadIdType)); - - return ResultSuccess; -} - -std::size_t NPadData::GetSupportedNpadIdType(std::span<Core::HID::NpadIdType> out_list) const { - std::size_t out_size = std::min(supported_npad_id_types_count, out_list.size()); - - memcpy(out_list.data(), supported_npad_id_types.data(), - out_size * sizeof(Core::HID::NpadIdType)); - - return out_size; -} - -bool NPadData::IsNpadIdTypeSupported(Core::HID::NpadIdType npad_id) const { - for (std::size_t i = 0; i < supported_npad_id_types_count; i++) { - if (supported_npad_id_types[i] == npad_id) { - return true; - } - } - - return false; -} - -void NPadData::SetNpadSystemCommonPolicy(bool is_full_policy) { - supported_npad_style_set = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::JoyDual | - Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; - handheld_activation_mode = NpadHandheldActivationMode::Dual; - - status.is_supported_styleset_set.Assign(true); - status.is_hold_type_set.Assign(true); - status.lr_assignment_mode.Assign(false); - status.is_policy.Assign(true); - if (is_full_policy) { - status.is_full_policy.Assign(true); - } - - supported_npad_id_types_count = 10; - supported_npad_id_types[0] = Core::HID::NpadIdType::Player1; - supported_npad_id_types[1] = Core::HID::NpadIdType::Player2; - supported_npad_id_types[2] = Core::HID::NpadIdType::Player3; - supported_npad_id_types[3] = Core::HID::NpadIdType::Player4; - supported_npad_id_types[4] = Core::HID::NpadIdType::Player5; - supported_npad_id_types[5] = Core::HID::NpadIdType::Player6; - supported_npad_id_types[6] = Core::HID::NpadIdType::Player7; - supported_npad_id_types[7] = Core::HID::NpadIdType::Player8; - supported_npad_id_types[8] = Core::HID::NpadIdType::Other; - supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld; - - for (auto& input_protection : is_unintended_home_button_input_protection) { - input_protection = true; - } -} - -void NPadData::ClearNpadSystemCommonPolicy() { - status.raw = 0; - supported_npad_style_set = Core::HID::NpadStyleSet::All; - npad_hold_type = NpadJoyHoldType::Vertical; - handheld_activation_mode = NpadHandheldActivationMode::Dual; - - for (auto& button_assignment : npad_button_assignment) { - button_assignment = Core::HID::NpadButton::None; - } - - supported_npad_id_types_count = 10; - supported_npad_id_types[0] = Core::HID::NpadIdType::Player1; - supported_npad_id_types[1] = Core::HID::NpadIdType::Player2; - supported_npad_id_types[2] = Core::HID::NpadIdType::Player3; - supported_npad_id_types[3] = Core::HID::NpadIdType::Player4; - supported_npad_id_types[4] = Core::HID::NpadIdType::Player5; - supported_npad_id_types[5] = Core::HID::NpadIdType::Player6; - supported_npad_id_types[6] = Core::HID::NpadIdType::Player7; - supported_npad_id_types[7] = Core::HID::NpadIdType::Player8; - supported_npad_id_types[8] = Core::HID::NpadIdType::Other; - supported_npad_id_types[9] = Core::HID::NpadIdType::Handheld; - - for (auto& input_protection : is_unintended_home_button_input_protection) { - input_protection = true; - } -} - -void NPadData::SetNpadJoyHoldType(NpadJoyHoldType hold_type) { - npad_hold_type = hold_type; - status.is_hold_type_set.Assign(true); -} - -NpadJoyHoldType NPadData::GetNpadJoyHoldType() const { - return npad_hold_type; -} - -void NPadData::SetHandheldActivationMode(NpadHandheldActivationMode activation_mode) { - handheld_activation_mode = activation_mode; -} - -NpadHandheldActivationMode NPadData::GetHandheldActivationMode() const { - return handheld_activation_mode; -} - -void NPadData::SetSupportedNpadStyleSet(Core::HID::NpadStyleSet style_set) { - supported_npad_style_set = style_set; - status.is_supported_styleset_set.Assign(true); - status.is_hold_type_set.Assign(true); -} - -Core::HID::NpadStyleSet NPadData::GetSupportedNpadStyleSet() const { - return supported_npad_style_set; -} - -bool NPadData::IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index) const { - Core::HID::NpadStyleTag style = {supported_npad_style_set}; - switch (style_index) { - case Core::HID::NpadStyleIndex::ProController: - return style.fullkey.As<bool>(); - case Core::HID::NpadStyleIndex::Handheld: - return style.handheld.As<bool>(); - case Core::HID::NpadStyleIndex::JoyconDual: - return style.joycon_dual.As<bool>(); - case Core::HID::NpadStyleIndex::JoyconLeft: - return style.joycon_left.As<bool>(); - case Core::HID::NpadStyleIndex::JoyconRight: - return style.joycon_right.As<bool>(); - case Core::HID::NpadStyleIndex::GameCube: - return style.gamecube.As<bool>(); - case Core::HID::NpadStyleIndex::Pokeball: - return style.palma.As<bool>(); - case Core::HID::NpadStyleIndex::NES: - return style.lark.As<bool>(); - case Core::HID::NpadStyleIndex::SNES: - return style.lucia.As<bool>(); - case Core::HID::NpadStyleIndex::N64: - return style.lagoon.As<bool>(); - case Core::HID::NpadStyleIndex::SegaGenesis: - return style.lager.As<bool>(); - default: - return false; - } -} - -void NPadData::SetLrAssignmentMode(bool is_enabled) { - status.lr_assignment_mode.Assign(is_enabled); -} - -bool NPadData::GetLrAssignmentMode() const { - return status.lr_assignment_mode.As<bool>(); -} - -void NPadData::SetAssigningSingleOnSlSrPress(bool is_enabled) { - status.assigning_single_on_sl_sr_press.Assign(is_enabled); -} - -bool NPadData::GetAssigningSingleOnSlSrPress() const { - return status.assigning_single_on_sl_sr_press.As<bool>(); -} - -void NPadData::SetHomeProtectionEnabled(bool is_enabled, Core::HID::NpadIdType npad_id) { - is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)] = is_enabled; -} - -bool NPadData::GetHomeProtectionEnabled(Core::HID::NpadIdType npad_id) const { - return is_unintended_home_button_input_protection[NpadIdTypeToIndex(npad_id)]; -} - -void NPadData::SetCaptureButtonAssignment(Core::HID::NpadButton button_assignment, - std::size_t style_index) { - npad_button_assignment[style_index] = button_assignment; -} - -Core::HID::NpadButton NPadData::GetCaptureButtonAssignment(std::size_t style_index) const { - return npad_button_assignment[style_index]; -} - -std::size_t NPadData::GetNpadCaptureButtonAssignmentList( - std::span<Core::HID::NpadButton> out_list) const { - for (std::size_t i = 0; i < out_list.size(); i++) { - Core::HID::NpadStyleSet style_set = GetStylesetByIndex(i); - if ((style_set & supported_npad_style_set) == Core::HID::NpadStyleSet::None || - npad_button_assignment[i] == Core::HID::NpadButton::None) { - return i; - } - out_list[i] = npad_button_assignment[i]; - } - - return out_list.size(); -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad/npad_data.h b/src/core/hle/service/hid/controllers/npad/npad_data.h deleted file mode 100644 index f799a9f9c..000000000 --- a/src/core/hle/service/hid/controllers/npad/npad_data.h +++ /dev/null @@ -1,88 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <array> -#include <span> - -#include "common/common_types.h" -#include "core/hid/hid_types.h" -#include "core/hle/result.h" -#include "core/hle/service/hid/controllers/types/npad_types.h" - -namespace Service::HID { - -struct NpadStatus { - union { - u32 raw{}; - - BitField<0, 1, u32> is_supported_styleset_set; - BitField<1, 1, u32> is_hold_type_set; - BitField<2, 1, u32> lr_assignment_mode; - BitField<3, 1, u32> assigning_single_on_sl_sr_press; - BitField<4, 1, u32> is_full_policy; - BitField<5, 1, u32> is_policy; - BitField<6, 1, u32> use_center_clamp; - BitField<7, 1, u32> system_ext_state; - }; -}; -static_assert(sizeof(NpadStatus) == 4, "NpadStatus is an invalid size"); - -/// Handles Npad request from HID interfaces -class NPadData final { -public: - explicit NPadData(); - ~NPadData(); - - NpadStatus GetNpadStatus() const; - - void SetNpadAnalogStickUseCenterClamp(bool is_enabled); - bool GetNpadAnalogStickUseCenterClamp() const; - - void SetNpadSystemExtStateEnabled(bool is_enabled); - bool GetNpadSystemExtState() const; - - Result SetSupportedNpadIdType(std::span<const Core::HID::NpadIdType> list); - std::size_t GetSupportedNpadIdType(std::span<Core::HID::NpadIdType> out_list) const; - bool IsNpadIdTypeSupported(Core::HID::NpadIdType npad_id) const; - - void SetNpadSystemCommonPolicy(bool is_full_policy); - void ClearNpadSystemCommonPolicy(); - - void SetNpadJoyHoldType(NpadJoyHoldType hold_type); - NpadJoyHoldType GetNpadJoyHoldType() const; - - void SetHandheldActivationMode(NpadHandheldActivationMode activation_mode); - NpadHandheldActivationMode GetHandheldActivationMode() const; - - void SetSupportedNpadStyleSet(Core::HID::NpadStyleSet style_set); - Core::HID::NpadStyleSet GetSupportedNpadStyleSet() const; - bool IsNpadStyleIndexSupported(Core::HID::NpadStyleIndex style_index) const; - - void SetLrAssignmentMode(bool is_enabled); - bool GetLrAssignmentMode() const; - - void SetAssigningSingleOnSlSrPress(bool is_enabled); - bool GetAssigningSingleOnSlSrPress() const; - - void SetHomeProtectionEnabled(bool is_enabled, Core::HID::NpadIdType npad_id); - bool GetHomeProtectionEnabled(Core::HID::NpadIdType npad_id) const; - - void SetCaptureButtonAssignment(Core::HID::NpadButton button_assignment, - std::size_t style_index); - Core::HID::NpadButton GetCaptureButtonAssignment(std::size_t style_index) const; - std::size_t GetNpadCaptureButtonAssignmentList(std::span<Core::HID::NpadButton> out_list) const; - -private: - NpadStatus status{}; - Core::HID::NpadStyleSet supported_npad_style_set{Core::HID::NpadStyleSet::All}; - NpadJoyHoldType npad_hold_type{NpadJoyHoldType::Vertical}; - NpadHandheldActivationMode handheld_activation_mode{}; - std::array<Core::HID::NpadIdType, MaxSupportedNpadIdTypes> supported_npad_id_types{}; - std::array<Core::HID::NpadButton, StyleIndexCount> npad_button_assignment{}; - std::size_t supported_npad_id_types_count{}; - std::array<bool, MaxSupportedNpadIdTypes> is_unintended_home_button_input_protection{}; -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad/npad_resource.cpp b/src/core/hle/service/hid/controllers/npad/npad_resource.cpp deleted file mode 100644 index 0a9341a39..000000000 --- a/src/core/hle/service/hid/controllers/npad/npad_resource.cpp +++ /dev/null @@ -1,685 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_readable_event.h" -#include "core/hle/service/hid/controllers/npad/npad_resource.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" - -namespace Service::HID { - -NPadResource::NPadResource(KernelHelpers::ServiceContext& context) : service_context{context} {} - -NPadResource::~NPadResource() = default; - -Result NPadResource::RegisterAppletResourceUserId(u64 aruid) { - const auto aruid_index = GetIndexFromAruid(aruid); - if (aruid_index < AruidIndexMax) { - return ResultAruidAlreadyRegistered; - } - - std::size_t data_index = AruidIndexMax; - for (std::size_t i = 0; i < AruidIndexMax; i++) { - if (!state[i].flag.is_initialized) { - data_index = i; - break; - } - } - - if (data_index == AruidIndexMax) { - return ResultAruidNoAvailableEntries; - } - - auto& aruid_data = state[data_index]; - - aruid_data.aruid = aruid; - aruid_data.flag.is_initialized.Assign(true); - - data_index = AruidIndexMax; - for (std::size_t i = 0; i < AruidIndexMax; i++) { - if (registration_list.flag[i] == RegistrationStatus::Initialized) { - if (registration_list.aruid[i] != aruid) { - continue; - } - data_index = i; - break; - } - if (registration_list.flag[i] == RegistrationStatus::None) { - data_index = i; - break; - } - } - - if (data_index == AruidIndexMax) { - return ResultSuccess; - } - - registration_list.flag[data_index] = RegistrationStatus::Initialized; - registration_list.aruid[data_index] = aruid; - - return ResultSuccess; -} - -void NPadResource::UnregisterAppletResourceUserId(u64 aruid) { - const u64 aruid_index = GetIndexFromAruid(aruid); - - DestroyStyleSetUpdateEvents(aruid); - if (aruid_index < AruidIndexMax) { - state[aruid_index] = {}; - registration_list.flag[aruid_index] = RegistrationStatus::PendingDelete; - } -} - -void NPadResource::DestroyStyleSetUpdateEvents(u64 aruid) { - const u64 aruid_index = GetIndexFromAruid(aruid); - - if (aruid_index >= AruidIndexMax) { - return; - } - - for (auto& controller_state : state[aruid_index].controller_state) { - if (!controller_state.is_styleset_update_event_initialized) { - continue; - } - service_context.CloseEvent(controller_state.style_set_update_event); - controller_state.is_styleset_update_event_initialized = false; - } -} - -Result NPadResource::Activate(u64 aruid) { - const u64 aruid_index = GetIndexFromAruid(aruid); - - if (aruid_index >= AruidIndexMax) { - return ResultSuccess; - } - - auto& state_data = state[aruid_index]; - - if (state_data.flag.is_assigned) { - return ResultAruidAlreadyRegistered; - } - - state_data.flag.is_assigned.Assign(true); - state_data.data.ClearNpadSystemCommonPolicy(); - state_data.npad_revision = NpadRevision::Revision0; - state_data.button_config = {}; - - if (active_data_aruid == aruid) { - default_hold_type = active_data.GetNpadJoyHoldType(); - active_data.SetNpadJoyHoldType(default_hold_type); - } - return ResultSuccess; -} - -Result NPadResource::Activate() { - if (ref_counter == std::numeric_limits<s32>::max() - 1) { - return ResultAppletResourceOverflow; - } - if (ref_counter == 0) { - RegisterAppletResourceUserId(SystemAruid); - Activate(SystemAruid); - } - ref_counter++; - return ResultSuccess; -} - -Result NPadResource::Deactivate() { - if (ref_counter == 0) { - return ResultAppletResourceNotInitialized; - } - - UnregisterAppletResourceUserId(SystemAruid); - ref_counter--; - return ResultSuccess; -} - -NPadData* NPadResource::GetActiveData() { - return &active_data; -} - -u64 NPadResource::GetActiveDataAruid() { - return active_data_aruid; -} - -void NPadResource::SetAppletResourceUserId(u64 aruid) { - if (active_data_aruid == aruid) { - return; - } - - active_data_aruid = aruid; - default_hold_type = active_data.GetNpadJoyHoldType(); - const u64 aruid_index = GetIndexFromAruid(aruid); - - if (aruid_index >= AruidIndexMax) { - return; - } - - auto& data = state[aruid_index].data; - if (data.GetNpadStatus().is_policy || data.GetNpadStatus().is_full_policy) { - data.SetNpadJoyHoldType(default_hold_type); - } - - active_data = data; - if (data.GetNpadStatus().is_hold_type_set) { - active_data.SetNpadJoyHoldType(default_hold_type); - } -} - -std::size_t NPadResource::GetIndexFromAruid(u64 aruid) const { - for (std::size_t i = 0; i < AruidIndexMax; i++) { - if (registration_list.flag[i] == RegistrationStatus::Initialized && - registration_list.aruid[i] == aruid) { - return i; - } - } - return AruidIndexMax; -} - -Result NPadResource::ApplyNpadSystemCommonPolicy(u64 aruid, bool is_full_policy) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - auto& data = state[aruid_index].data; - data.SetNpadSystemCommonPolicy(is_full_policy); - data.SetNpadJoyHoldType(default_hold_type); - if (active_data_aruid == aruid) { - active_data.SetNpadSystemCommonPolicy(is_full_policy); - active_data.SetNpadJoyHoldType(default_hold_type); - } - return ResultSuccess; -} - -Result NPadResource::ClearNpadSystemCommonPolicy(u64 aruid) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].data.ClearNpadSystemCommonPolicy(); - if (active_data_aruid == aruid) { - active_data.ClearNpadSystemCommonPolicy(); - } - return ResultSuccess; -} - -Result NPadResource::SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet style_set) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - auto& data = state[aruid_index].data; - data.SetSupportedNpadStyleSet(style_set); - if (active_data_aruid == aruid) { - active_data.SetSupportedNpadStyleSet(style_set); - active_data.SetNpadJoyHoldType(data.GetNpadJoyHoldType()); - } - return ResultSuccess; -} - -Result NPadResource::GetSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_Set, - u64 aruid) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - auto& data = state[aruid_index].data; - if (!data.GetNpadStatus().is_supported_styleset_set) { - return ResultUndefinedStyleset; - } - - out_style_Set = data.GetSupportedNpadStyleSet(); - return ResultSuccess; -} - -Result NPadResource::GetMaskedSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_set, - u64 aruid) const { - if (aruid == SystemAruid) { - out_style_set = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Palma | - Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; - return ResultSuccess; - } - - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - auto& data = state[aruid_index].data; - if (!data.GetNpadStatus().is_supported_styleset_set) { - return ResultUndefinedStyleset; - } - - Core::HID::NpadStyleSet mask{Core::HID::NpadStyleSet::None}; - out_style_set = data.GetSupportedNpadStyleSet(); - - switch (state[aruid_index].npad_revision) { - case NpadRevision::Revision1: - mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | - Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::SystemExt | - Core::HID::NpadStyleSet::System; - break; - case NpadRevision::Revision2: - mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | - Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark | - Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; - break; - case NpadRevision::Revision3: - mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | - Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark | - Core::HID::NpadStyleSet::HandheldLark | Core::HID::NpadStyleSet::Lucia | - Core::HID::NpadStyleSet::Lagoon | Core::HID::NpadStyleSet::Lager | - Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; - break; - default: - mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::SystemExt | - Core::HID::NpadStyleSet::System; - break; - } - - out_style_set = out_style_set & mask; - return ResultSuccess; -} - -Result NPadResource::GetAvailableStyleset(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - auto& data = state[aruid_index].data; - if (!data.GetNpadStatus().is_supported_styleset_set) { - return ResultUndefinedStyleset; - } - - Core::HID::NpadStyleSet mask{Core::HID::NpadStyleSet::None}; - out_style_set = data.GetSupportedNpadStyleSet(); - - switch (state[aruid_index].npad_revision) { - case NpadRevision::Revision1: - mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | - Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::SystemExt | - Core::HID::NpadStyleSet::System; - break; - case NpadRevision::Revision2: - mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | - Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark | - Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; - break; - case NpadRevision::Revision3: - mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::Gc | - Core::HID::NpadStyleSet::Palma | Core::HID::NpadStyleSet::Lark | - Core::HID::NpadStyleSet::HandheldLark | Core::HID::NpadStyleSet::Lucia | - Core::HID::NpadStyleSet::Lagoon | Core::HID::NpadStyleSet::Lager | - Core::HID::NpadStyleSet::SystemExt | Core::HID::NpadStyleSet::System; - break; - default: - mask = Core::HID::NpadStyleSet::Fullkey | Core::HID::NpadStyleSet::Handheld | - Core::HID::NpadStyleSet::JoyDual | Core::HID::NpadStyleSet::JoyLeft | - Core::HID::NpadStyleSet::JoyRight | Core::HID::NpadStyleSet::SystemExt | - Core::HID::NpadStyleSet::System; - break; - } - - out_style_set = out_style_set & mask; - return ResultSuccess; -} - -NpadRevision NPadResource::GetNpadRevision(u64 aruid) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return NpadRevision::Revision0; - } - - return state[aruid_index].npad_revision; -} - -Result NPadResource::IsSupportedNpadStyleSet(bool& is_set, u64 aruid) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - is_set = state[aruid_index].data.GetNpadStatus().is_supported_styleset_set.Value() != 0; - return ResultSuccess; -} - -Result NPadResource::SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].data.SetNpadJoyHoldType(hold_type); - if (active_data_aruid == aruid) { - active_data.SetNpadJoyHoldType(hold_type); - } - return ResultSuccess; -} - -Result NPadResource::GetNpadJoyHoldType(NpadJoyHoldType& hold_type, u64 aruid) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - auto& data = state[aruid_index].data; - if (data.GetNpadStatus().is_policy || data.GetNpadStatus().is_full_policy) { - hold_type = active_data.GetNpadJoyHoldType(); - return ResultSuccess; - } - hold_type = data.GetNpadJoyHoldType(); - return ResultSuccess; -} - -Result NPadResource::SetNpadHandheldActivationMode(u64 aruid, - NpadHandheldActivationMode activation_mode) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].data.SetHandheldActivationMode(activation_mode); - if (active_data_aruid == aruid) { - active_data.SetHandheldActivationMode(activation_mode); - } - return ResultSuccess; -} - -Result NPadResource::GetNpadHandheldActivationMode(NpadHandheldActivationMode& activation_mode, - u64 aruid) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - activation_mode = state[aruid_index].data.GetHandheldActivationMode(); - return ResultSuccess; -} - -Result NPadResource::SetSupportedNpadIdType( - u64 aruid, std::span<const Core::HID::NpadIdType> supported_npad_list) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - if (supported_npad_list.size() > MaxSupportedNpadIdTypes) { - return ResultInvalidArraySize; - } - - Result result = state[aruid_index].data.SetSupportedNpadIdType(supported_npad_list); - if (result.IsSuccess() && active_data_aruid == aruid) { - result = active_data.SetSupportedNpadIdType(supported_npad_list); - } - - return result; -} - -bool NPadResource::IsControllerSupported(u64 aruid, Core::HID::NpadStyleIndex style_index) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return false; - } - return state[aruid_index].data.IsNpadStyleIndexSupported(style_index); -} - -Result NPadResource::SetLrAssignmentMode(u64 aruid, bool is_enabled) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].data.SetLrAssignmentMode(is_enabled); - if (active_data_aruid == aruid) { - active_data.SetLrAssignmentMode(is_enabled); - } - return ResultSuccess; -} - -Result NPadResource::GetLrAssignmentMode(bool& is_enabled, u64 aruid) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - is_enabled = state[aruid_index].data.GetLrAssignmentMode(); - return ResultSuccess; -} - -Result NPadResource::SetAssigningSingleOnSlSrPress(u64 aruid, bool is_enabled) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].data.SetAssigningSingleOnSlSrPress(is_enabled); - if (active_data_aruid == aruid) { - active_data.SetAssigningSingleOnSlSrPress(is_enabled); - } - return ResultSuccess; -} - -Result NPadResource::IsAssigningSingleOnSlSrPressEnabled(bool& is_enabled, u64 aruid) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - is_enabled = state[aruid_index].data.GetAssigningSingleOnSlSrPress(); - return ResultSuccess; -} - -Result NPadResource::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, - Kernel::KReadableEvent** out_event, - Core::HID::NpadIdType npad_id) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - auto& controller_state = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)]; - if (!controller_state.is_styleset_update_event_initialized) { - // Auto clear = true - controller_state.style_set_update_event = - service_context.CreateEvent("NpadResource:StylesetUpdateEvent"); - - // Assume creating the event succeeds otherwise crash the system here - controller_state.is_styleset_update_event_initialized = true; - } - - *out_event = &controller_state.style_set_update_event->GetReadableEvent(); - - if (controller_state.is_styleset_update_event_initialized) { - controller_state.style_set_update_event->Signal(); - } - - return ResultSuccess; -} - -Result NPadResource::SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType npad_id) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - auto controller = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)]; - if (controller.is_styleset_update_event_initialized) { - controller.style_set_update_event->Signal(); - } - return ResultSuccess; -} - -Result NPadResource::GetHomeProtectionEnabled(bool& is_enabled, u64 aruid, - Core::HID::NpadIdType npad_id) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - is_enabled = state[aruid_index].data.GetHomeProtectionEnabled(npad_id); - return ResultSuccess; -} - -Result NPadResource::SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id, - bool is_enabled) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].data.SetHomeProtectionEnabled(is_enabled, npad_id); - if (active_data_aruid == aruid) { - active_data.SetHomeProtectionEnabled(is_enabled, npad_id); - } - return ResultSuccess; -} - -Result NPadResource::SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].data.SetNpadAnalogStickUseCenterClamp(is_enabled); - if (active_data_aruid == aruid) { - active_data.SetNpadAnalogStickUseCenterClamp(is_enabled); - } - return ResultSuccess; -} - -Result NPadResource::SetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index, - Core::HID::NpadButton button_config) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].button_config[NpadIdTypeToIndex(npad_id)][index] = button_config; - return ResultSuccess; -} - -Core::HID::NpadButton NPadResource::GetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, - std::size_t index, Core::HID::NpadButton mask, - bool is_enabled) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return Core::HID::NpadButton::None; - } - - auto& button_config = state[aruid_index].button_config[NpadIdTypeToIndex(npad_id)][index]; - if (is_enabled) { - button_config = button_config | mask; - return button_config; - } - - button_config = Core::HID::NpadButton::None; - return Core::HID::NpadButton::None; -} - -void NPadResource::ResetButtonConfig() { - for (auto& selected_state : state) { - selected_state.button_config = {}; - } -} - -Result NPadResource::SetNpadCaptureButtonAssignment(u64 aruid, - Core::HID::NpadStyleSet npad_style_set, - Core::HID::NpadButton button_assignment) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - // Must be a power of two - const auto raw_styleset = static_cast<u32>(npad_style_set); - if (raw_styleset == 0 && (raw_styleset & (raw_styleset - 1)) != 0) { - return ResultMultipleStyleSetSelected; - } - - std::size_t style_index{}; - Core::HID::NpadStyleSet style_selected{}; - for (style_index = 0; style_index < StyleIndexCount; ++style_index) { - style_selected = GetStylesetByIndex(style_index); - if (npad_style_set == style_selected) { - break; - } - } - - if (style_selected == Core::HID::NpadStyleSet::None) { - return ResultMultipleStyleSetSelected; - } - - state[aruid_index].data.SetCaptureButtonAssignment(button_assignment, style_index); - if (active_data_aruid == aruid) { - active_data.SetCaptureButtonAssignment(button_assignment, style_index); - } - return ResultSuccess; -} - -Result NPadResource::ClearNpadCaptureButtonAssignment(u64 aruid) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - for (std::size_t i = 0; i < StyleIndexCount; i++) { - state[aruid_index].data.SetCaptureButtonAssignment(Core::HID::NpadButton::None, i); - if (active_data_aruid == aruid) { - active_data.SetCaptureButtonAssignment(Core::HID::NpadButton::None, i); - } - } - return ResultSuccess; -} - -std::size_t NPadResource::GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list, - u64 aruid) const { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return 0; - } - return state[aruid_index].data.GetNpadCaptureButtonAssignmentList(out_list); -} - -void NPadResource::SetNpadRevision(u64 aruid, NpadRevision revision) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return; - } - - state[aruid_index].npad_revision = revision; -} - -Result NPadResource::SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled) { - const u64 aruid_index = GetIndexFromAruid(aruid); - if (aruid_index >= AruidIndexMax) { - return ResultNpadNotConnected; - } - - state[aruid_index].data.SetNpadAnalogStickUseCenterClamp(is_enabled); - if (active_data_aruid == aruid) { - active_data.SetNpadAnalogStickUseCenterClamp(is_enabled); - } - return ResultSuccess; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad/npad_resource.h b/src/core/hle/service/hid/controllers/npad/npad_resource.h deleted file mode 100644 index 4c7e6ab0e..000000000 --- a/src/core/hle/service/hid/controllers/npad/npad_resource.h +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <array> -#include <mutex> -#include <span> - -#include "common/common_types.h" -#include "core/hid/hid_types.h" -#include "core/hle/result.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/npad/npad_data.h" -#include "core/hle/service/hid/controllers/types/npad_types.h" -#include "core/hle/service/kernel_helpers.h" - -namespace Core { -class System; -} - -namespace Kernel { -class KReadableEvent; -} - -namespace Service::HID { -struct DataStatusFlag; - -struct NpadControllerState { - bool is_styleset_update_event_initialized{}; - INSERT_PADDING_BYTES(0x7); - Kernel::KEvent* style_set_update_event{nullptr}; - INSERT_PADDING_BYTES(0x27); -}; - -struct NpadState { - DataStatusFlag flag{}; - u64 aruid{}; - NPadData data{}; - std::array<std::array<Core::HID::NpadButton, StyleIndexCount>, MaxSupportedNpadIdTypes> - button_config; - std::array<NpadControllerState, MaxSupportedNpadIdTypes> controller_state; - NpadRevision npad_revision; -}; - -/// Handles Npad request from HID interfaces -class NPadResource final { -public: - explicit NPadResource(KernelHelpers::ServiceContext& context); - ~NPadResource(); - - NPadData* GetActiveData(); - u64 GetActiveDataAruid(); - - Result RegisterAppletResourceUserId(u64 aruid); - void UnregisterAppletResourceUserId(u64 aruid); - - void DestroyStyleSetUpdateEvents(u64 aruid); - - Result Activate(u64 aruid); - Result Activate(); - Result Deactivate(); - - void SetAppletResourceUserId(u64 aruid); - std::size_t GetIndexFromAruid(u64 aruid) const; - - Result ApplyNpadSystemCommonPolicy(u64 aruid, bool is_full_policy); - Result ClearNpadSystemCommonPolicy(u64 aruid); - - Result SetSupportedNpadStyleSet(u64 aruid, Core::HID::NpadStyleSet style_set); - Result GetSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_Set, u64 aruid) const; - Result GetMaskedSupportedNpadStyleSet(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const; - Result GetAvailableStyleset(Core::HID::NpadStyleSet& out_style_set, u64 aruid) const; - - NpadRevision GetNpadRevision(u64 aruid) const; - void SetNpadRevision(u64 aruid, NpadRevision revision); - - Result IsSupportedNpadStyleSet(bool& is_set, u64 aruid); - - Result SetNpadJoyHoldType(u64 aruid, NpadJoyHoldType hold_type); - Result GetNpadJoyHoldType(NpadJoyHoldType& hold_type, u64 aruid) const; - - Result SetNpadHandheldActivationMode(u64 aruid, NpadHandheldActivationMode activation_mode); - Result GetNpadHandheldActivationMode(NpadHandheldActivationMode& activation_mode, - u64 aruid) const; - - Result SetSupportedNpadIdType(u64 aruid, - std::span<const Core::HID::NpadIdType> supported_npad_list); - bool IsControllerSupported(u64 aruid, Core::HID::NpadStyleIndex style_index) const; - - Result SetLrAssignmentMode(u64 aruid, bool is_enabled); - Result GetLrAssignmentMode(bool& is_enabled, u64 aruid) const; - - Result SetAssigningSingleOnSlSrPress(u64 aruid, bool is_enabled); - Result IsAssigningSingleOnSlSrPressEnabled(bool& is_enabled, u64 aruid) const; - - Result AcquireNpadStyleSetUpdateEventHandle(u64 aruid, Kernel::KReadableEvent** out_event, - Core::HID::NpadIdType npad_id); - Result SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType npad_id); - - Result GetHomeProtectionEnabled(bool& is_enabled, u64 aruid, - Core::HID::NpadIdType npad_id) const; - Result SetHomeProtectionEnabled(u64 aruid, Core::HID::NpadIdType npad_id, bool is_enabled); - - Result SetNpadAnalogStickUseCenterClamp(u64 aruid, bool is_enabled); - - Result SetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, std::size_t index, - Core::HID::NpadButton button_config); - Core::HID::NpadButton GetButtonConfig(u64 aruid, Core::HID::NpadIdType npad_id, - std::size_t index, Core::HID::NpadButton mask, - bool is_enabled); - void ResetButtonConfig(); - - Result SetNpadCaptureButtonAssignment(u64 aruid, Core::HID::NpadStyleSet npad_style_set, - Core::HID::NpadButton button_assignment); - Result ClearNpadCaptureButtonAssignment(u64 aruid); - std::size_t GetNpadCaptureButtonAssignment(std::span<Core::HID::NpadButton> out_list, - u64 aruid) const; - - Result SetNpadSystemExtStateEnabled(u64 aruid, bool is_enabled); - -private: - NPadData active_data{}; - AruidRegisterList registration_list{}; - std::array<NpadState, AruidIndexMax> state{}; - u64 active_data_aruid{}; - NpadJoyHoldType default_hold_type{}; - s32 ref_counter{}; - - KernelHelpers::ServiceContext& service_context; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp deleted file mode 100644 index aa0454b5e..000000000 --- a/src/core/hle/service/hid/controllers/palma.cpp +++ /dev/null @@ -1,226 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hid/hid_types.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_readable_event.h" -#include "core/hle/service/hid/controllers/palma.h" -#include "core/hle/service/kernel_helpers.h" - -namespace Service::HID { - -Palma::Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_) - : ControllerBase{hid_core_}, service_context{service_context_} { - controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); - operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); -} - -Palma::~Palma() { - service_context.CloseEvent(operation_complete_event); -}; - -void Palma::OnInit() {} - -void Palma::OnRelease() {} - -void Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (!IsControllerActivated()) { - return; - } -} - -Result Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, - PalmaConnectionHandle& handle) { - active_handle.npad_id = npad_id; - handle = active_handle; - return ResultSuccess; -} - -Result Palma::InitializePalma(const PalmaConnectionHandle& handle) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - Activate(); - return ResultSuccess; -} - -Kernel::KReadableEvent& Palma::AcquirePalmaOperationCompleteEvent( - const PalmaConnectionHandle& handle) const { - if (handle.npad_id != active_handle.npad_id) { - LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id); - } - return operation_complete_event->GetReadableEvent(); -} - -Result Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle, - PalmaOperationType& operation_type, - PalmaOperationData& data) const { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - operation_type = operation.operation; - data = operation.data; - return ResultSuccess; -} - -Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - operation.operation = PalmaOperationType::PlayActivity; - operation.result = PalmaResultSuccess; - operation.data = {}; - operation_complete_event->Signal(); - return ResultSuccess; -} - -Result Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - fr_mode = fr_mode_; - return ResultSuccess; -} - -Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - operation.operation = PalmaOperationType::ReadStep; - operation.result = PalmaResultSuccess; - operation.data = {}; - operation_complete_event->Signal(); - return ResultSuccess; -} - -Result Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - return ResultSuccess; -} - -Result Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - return ResultSuccess; -} - -void Palma::ReadPalmaApplicationSection() {} - -void Palma::WritePalmaApplicationSection() {} - -Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - operation.operation = PalmaOperationType::ReadUniqueCode; - operation.result = PalmaResultSuccess; - operation.data = {}; - operation_complete_event->Signal(); - return ResultSuccess; -} - -Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - operation.operation = PalmaOperationType::SetUniqueCodeInvalid; - operation.result = PalmaResultSuccess; - operation.data = {}; - operation_complete_event->Signal(); - return ResultSuccess; -} - -void Palma::WritePalmaActivityEntry() {} - -Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - operation.operation = PalmaOperationType::WriteRgbLedPatternEntry; - operation.result = PalmaResultSuccess; - operation.data = {}; - operation_complete_event->Signal(); - return ResultSuccess; -} - -Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, - Common::ProcessAddress t_mem, u64 size) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - operation.operation = PalmaOperationType::WriteWaveEntry; - operation.result = PalmaResultSuccess; - operation.data = {}; - operation_complete_event->Signal(); - return ResultSuccess; -} - -Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, - s32 database_id_version_) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - database_id_version = database_id_version_; - operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion; - operation.result = PalmaResultSuccess; - operation.data[0] = {}; - operation_complete_event->Signal(); - return ResultSuccess; -} - -Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion; - operation.result = PalmaResultSuccess; - operation.data = {}; - operation.data[0] = static_cast<u8>(database_id_version); - operation_complete_event->Signal(); - return ResultSuccess; -} - -void Palma::SuspendPalmaFeature() {} - -Result Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - return operation.result; -} -void Palma::ReadPalmaPlayLog() {} - -void Palma::ResetPalmaPlayLog() {} - -void Palma::SetIsPalmaAllConnectable(bool is_all_connectable) { - // If true controllers are able to be paired - is_connectable = is_all_connectable; -} - -void Palma::SetIsPalmaPairedConnectable() {} - -Result Palma::PairPalma(const PalmaConnectionHandle& handle) { - if (handle.npad_id != active_handle.npad_id) { - return InvalidPalmaHandle; - } - // TODO: Do something - return ResultSuccess; -} - -void Palma::SetPalmaBoostMode(bool boost_mode) {} - -void Palma::CancelWritePalmaWaveEntry() {} - -void Palma::EnablePalmaBoostMode() {} - -void Palma::GetPalmaBluetoothAddress() {} - -void Palma::SetDisallowedPalmaConnection() {} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/palma.h b/src/core/hle/service/hid/controllers/palma.h deleted file mode 100644 index 73884230d..000000000 --- a/src/core/hle/service/hid/controllers/palma.h +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> -#include "common/common_funcs.h" -#include "common/typed_address.h" -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/errors.h" - -namespace Kernel { -class KEvent; -class KReadableEvent; -} // namespace Kernel - -namespace Service::KernelHelpers { -class ServiceContext; -} - -namespace Core::HID { -class EmulatedController; -} // namespace Core::HID - -namespace Service::HID { -class Palma final : public ControllerBase { -public: - using PalmaOperationData = std::array<u8, 0x140>; - - // This is nn::hid::PalmaOperationType - enum class PalmaOperationType { - PlayActivity, - SetFrModeType, - ReadStep, - EnableStep, - ResetStep, - ReadApplicationSection, - WriteApplicationSection, - ReadUniqueCode, - SetUniqueCodeInvalid, - WriteActivityEntry, - WriteRgbLedPatternEntry, - WriteWaveEntry, - ReadDataBaseIdentificationVersion, - WriteDataBaseIdentificationVersion, - SuspendFeature, - ReadPlayLog, - ResetPlayLog, - }; - - // This is nn::hid::PalmaWaveSet - enum class PalmaWaveSet : u64 { - Small, - Medium, - Large, - }; - - // This is nn::hid::PalmaFrModeType - enum class PalmaFrModeType : u64 { - Off, - B01, - B02, - B03, - Downloaded, - }; - - // This is nn::hid::PalmaFeature - enum class PalmaFeature : u64 { - FrMode, - RumbleFeedback, - Step, - MuteSwitch, - }; - - // This is nn::hid::PalmaOperationInfo - struct PalmaOperationInfo { - PalmaOperationType operation{}; - Result result{PalmaResultSuccess}; - PalmaOperationData data{}; - }; - static_assert(sizeof(PalmaOperationInfo) == 0x148, "PalmaOperationInfo is an invalid size"); - - // This is nn::hid::PalmaActivityEntry - struct PalmaActivityEntry { - u32 rgb_led_pattern_index; - INSERT_PADDING_BYTES(2); - PalmaWaveSet wave_set; - u32 wave_index; - INSERT_PADDING_BYTES(12); - }; - static_assert(sizeof(PalmaActivityEntry) == 0x20, "PalmaActivityEntry is an invalid size"); - - struct PalmaConnectionHandle { - Core::HID::NpadIdType npad_id; - INSERT_PADDING_BYTES(4); // Unknown - }; - static_assert(sizeof(PalmaConnectionHandle) == 0x8, - "PalmaConnectionHandle has incorrect size."); - - explicit Palma(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_); - ~Palma() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - - Result GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, PalmaConnectionHandle& handle); - Result InitializePalma(const PalmaConnectionHandle& handle); - Kernel::KReadableEvent& AcquirePalmaOperationCompleteEvent( - const PalmaConnectionHandle& handle) const; - Result GetPalmaOperationInfo(const PalmaConnectionHandle& handle, - PalmaOperationType& operation_type, - PalmaOperationData& data) const; - Result PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity); - Result SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_); - Result ReadPalmaStep(const PalmaConnectionHandle& handle); - Result EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled); - Result ResetPalmaStep(const PalmaConnectionHandle& handle); - Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle); - Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle); - Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown); - Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, - Common::ProcessAddress t_mem, u64 size); - Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, - s32 database_id_version_); - Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle); - Result GetPalmaOperationResult(const PalmaConnectionHandle& handle) const; - void SetIsPalmaAllConnectable(bool is_all_connectable); - Result PairPalma(const PalmaConnectionHandle& handle); - void SetPalmaBoostMode(bool boost_mode); - -private: - void ReadPalmaApplicationSection(); - void WritePalmaApplicationSection(); - void WritePalmaActivityEntry(); - void SuspendPalmaFeature(); - void ReadPalmaPlayLog(); - void ResetPalmaPlayLog(); - void SetIsPalmaPairedConnectable(); - void CancelWritePalmaWaveEntry(); - void EnablePalmaBoostMode(); - void GetPalmaBluetoothAddress(); - void SetDisallowedPalmaConnection(); - - bool is_connectable{}; - s32 database_id_version{}; - PalmaOperationInfo operation{}; - PalmaFrModeType fr_mode{}; - PalmaConnectionHandle active_handle{}; - - Core::HID::EmulatedController* controller; - - Kernel::KEvent* operation_complete_event; - KernelHelpers::ServiceContext& service_context; -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/seven_six_axis.cpp b/src/core/hle/service/hid/controllers/seven_six_axis.cpp deleted file mode 100644 index 495568484..000000000 --- a/src/core/hle/service/hid/controllers/seven_six_axis.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include <cstring> -#include "common/common_types.h" -#include "core/core.h" -#include "core/core_timing.h" -#include "core/frontend/emu_window.h" -#include "core/hid/emulated_console.h" -#include "core/hid/emulated_devices.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/seven_six_axis.h" -#include "core/memory.h" - -namespace Service::HID { -SevenSixAxis::SevenSixAxis(Core::System& system_) - : ControllerBase{system_.HIDCore()}, system{system_} { - console = hid_core.GetEmulatedConsole(); -} - -SevenSixAxis::~SevenSixAxis() = default; - -void SevenSixAxis::OnInit() {} -void SevenSixAxis::OnRelease() {} - -void SevenSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (!IsControllerActivated() || transfer_memory == 0) { - seven_sixaxis_lifo.buffer_count = 0; - seven_sixaxis_lifo.buffer_tail = 0; - return; - } - - const auto& last_entry = seven_sixaxis_lifo.ReadCurrentEntry().state; - next_seven_sixaxis_state.sampling_number = last_entry.sampling_number + 1; - - const auto motion_status = console->GetMotion(); - last_global_timestamp = core_timing.GetGlobalTimeNs().count(); - - // This value increments every time the switch goes to sleep - next_seven_sixaxis_state.unknown = 1; - next_seven_sixaxis_state.timestamp = last_global_timestamp - last_saved_timestamp; - next_seven_sixaxis_state.accel = motion_status.accel; - next_seven_sixaxis_state.gyro = motion_status.gyro; - next_seven_sixaxis_state.quaternion = { - { - motion_status.quaternion.xyz.y, - motion_status.quaternion.xyz.x, - -motion_status.quaternion.w, - }, - -motion_status.quaternion.xyz.z, - }; - - seven_sixaxis_lifo.WriteNextEntry(next_seven_sixaxis_state); - system.ApplicationMemory().WriteBlock(transfer_memory, &seven_sixaxis_lifo, - sizeof(seven_sixaxis_lifo)); -} - -void SevenSixAxis::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { - transfer_memory = t_mem; -} - -void SevenSixAxis::ResetTimestamp() { - last_saved_timestamp = last_global_timestamp; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/seven_six_axis.h b/src/core/hle/service/hid/controllers/seven_six_axis.h deleted file mode 100644 index 40e3f5d12..000000000 --- a/src/core/hle/service/hid/controllers/seven_six_axis.h +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "common/quaternion.h" -#include "common/typed_address.h" -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/ring_lifo.h" - -namespace Core { -class System; -} // namespace Core - -namespace Core::HID { -class EmulatedConsole; -} // namespace Core::HID - -namespace Service::HID { -class SevenSixAxis final : public ControllerBase { -public: - explicit SevenSixAxis(Core::System& system_); - ~SevenSixAxis() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - - // Called on InitializeSevenSixAxisSensor - void SetTransferMemoryAddress(Common::ProcessAddress t_mem); - - // Called on ResetSevenSixAxisSensorTimestamp - void ResetTimestamp(); - -private: - struct SevenSixAxisState { - INSERT_PADDING_WORDS(2); // unused - u64 timestamp{}; - u64 sampling_number{}; - u64 unknown{}; - Common::Vec3f accel{}; - Common::Vec3f gyro{}; - Common::Quaternion<f32> quaternion{}; - }; - static_assert(sizeof(SevenSixAxisState) == 0x48, "SevenSixAxisState is an invalid size"); - - Lifo<SevenSixAxisState, 0x21> seven_sixaxis_lifo{}; - static_assert(sizeof(seven_sixaxis_lifo) == 0xA70, "SevenSixAxisState is an invalid size"); - - u64 last_saved_timestamp{}; - u64 last_global_timestamp{}; - - SevenSixAxisState next_seven_sixaxis_state{}; - Common::ProcessAddress transfer_memory{}; - Core::HID::EmulatedConsole* console = nullptr; - - Core::System& system; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp deleted file mode 100644 index 0bc5169c6..000000000 --- a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/core.h" -#include "core/hle/kernel/k_shared_memory.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/shared_memory_holder.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" -#include "core/hle/service/hid/errors.h" - -namespace Service::HID { -SharedMemoryHolder::SharedMemoryHolder() {} - -SharedMemoryHolder::~SharedMemoryHolder() { - Finalize(); -} - -Result SharedMemoryHolder::Initialize(Core::System& system) { - shared_memory = Kernel::KSharedMemory::Create(system.Kernel()); - const Result result = shared_memory->Initialize( - system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None, - Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat)); - if (result.IsError()) { - return result; - } - Kernel::KSharedMemory::Register(system.Kernel(), shared_memory); - - is_created = true; - is_mapped = true; - address = std::construct_at(reinterpret_cast<SharedMemoryFormat*>(shared_memory->GetPointer())); - return ResultSuccess; -} - -void SharedMemoryHolder::Finalize() { - if (address != nullptr) { - shared_memory->Close(); - } - is_created = false; - is_mapped = false; - address = nullptr; -} - -bool SharedMemoryHolder::IsMapped() { - return is_mapped; -} - -SharedMemoryFormat* SharedMemoryHolder::GetAddress() { - return address; -} - -Kernel::KSharedMemory* SharedMemoryHolder::GetHandle() { - return shared_memory; -} -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.h b/src/core/hle/service/hid/controllers/shared_memory_holder.h deleted file mode 100644 index 943407c00..000000000 --- a/src/core/hle/service/hid/controllers/shared_memory_holder.h +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "core/hle/result.h" - -namespace Core { -class System; -} - -namespace Kernel { -class KSharedMemory; -} - -namespace Service::HID { -struct SharedMemoryFormat; - -// This is nn::hid::detail::SharedMemoryHolder -class SharedMemoryHolder { -public: - SharedMemoryHolder(); - ~SharedMemoryHolder(); - - Result Initialize(Core::System& system); - void Finalize(); - - bool IsMapped(); - SharedMemoryFormat* GetAddress(); - Kernel::KSharedMemory* GetHandle(); - -private: - bool is_owner{}; - bool is_created{}; - bool is_mapped{}; - INSERT_PADDING_BYTES(0x5); - Kernel::KSharedMemory* shared_memory; - INSERT_PADDING_BYTES(0x38); - SharedMemoryFormat* address = nullptr; -}; -// Correct size is 0x50 bytes -static_assert(sizeof(SharedMemoryHolder) == 0x50, "SharedMemoryHolder is an invalid size"); - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp deleted file mode 100644 index adab60911..000000000 --- a/src/core/hle/service/hid/controllers/six_axis.cpp +++ /dev/null @@ -1,421 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "common/common_types.h" -#include "core/core_timing.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/npad.h" -#include "core/hle/service/hid/controllers/six_axis.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" -#include "core/hle/service/hid/errors.h" -#include "core/hle/service/hid/hid_util.h" - -namespace Service::HID { - -SixAxis::SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_) - : ControllerBase{hid_core_}, npad{npad_} { - for (std::size_t i = 0; i < controller_data.size(); ++i) { - auto& controller = controller_data[i]; - controller.device = hid_core.GetEmulatedControllerByIndex(i); - } -} - -SixAxis::~SixAxis() = default; - -void SixAxis::OnInit() {} -void SixAxis::OnRelease() {} - -void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - if (!IsControllerActivated()) { - return; - } - - for (std::size_t i = 0; i < controller_data.size(); ++i) { - NpadSharedMemoryEntry& shared_memory = data->shared_memory_format->npad.npad_entry[i]; - auto& controller = controller_data[i]; - const auto& controller_type = controller.device->GetNpadStyleIndex(); - - if (controller_type == Core::HID::NpadStyleIndex::None || - !controller.device->IsConnected()) { - continue; - } - - const auto& motion_state = controller.device->GetMotions(); - auto& sixaxis_fullkey_state = controller.sixaxis_fullkey_state; - auto& sixaxis_handheld_state = controller.sixaxis_handheld_state; - auto& sixaxis_dual_left_state = controller.sixaxis_dual_left_state; - auto& sixaxis_dual_right_state = controller.sixaxis_dual_right_state; - auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state; - auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state; - - auto& sixaxis_fullkey_lifo = shared_memory.internal_state.sixaxis_fullkey_lifo; - auto& sixaxis_handheld_lifo = shared_memory.internal_state.sixaxis_handheld_lifo; - auto& sixaxis_dual_left_lifo = shared_memory.internal_state.sixaxis_dual_left_lifo; - auto& sixaxis_dual_right_lifo = shared_memory.internal_state.sixaxis_dual_right_lifo; - auto& sixaxis_left_lifo = shared_memory.internal_state.sixaxis_left_lifo; - auto& sixaxis_right_lifo = shared_memory.internal_state.sixaxis_right_lifo; - - // Clear previous state - sixaxis_fullkey_state = {}; - sixaxis_handheld_state = {}; - sixaxis_dual_left_state = {}; - sixaxis_dual_right_state = {}; - sixaxis_left_lifo_state = {}; - sixaxis_right_lifo_state = {}; - - if (controller.sixaxis_sensor_enabled && Settings::values.motion_enabled.GetValue()) { - controller.sixaxis_at_rest = true; - for (std::size_t e = 0; e < motion_state.size(); ++e) { - controller.sixaxis_at_rest = - controller.sixaxis_at_rest && motion_state[e].is_at_rest; - } - } - - const auto set_motion_state = [&](Core::HID::SixAxisSensorState& state, - const Core::HID::ControllerMotion& hid_state) { - using namespace std::literals::chrono_literals; - static constexpr Core::HID::SixAxisSensorState default_motion_state = { - .delta_time = std::chrono::nanoseconds(5ms).count(), - .accel = {0, 0, -1.0f}, - .orientation = - { - Common::Vec3f{1.0f, 0, 0}, - Common::Vec3f{0, 1.0f, 0}, - Common::Vec3f{0, 0, 1.0f}, - }, - .attribute = {1}, - }; - if (!controller.sixaxis_sensor_enabled) { - state = default_motion_state; - return; - } - if (!Settings::values.motion_enabled.GetValue()) { - state = default_motion_state; - return; - } - state.attribute.is_connected.Assign(1); - state.delta_time = std::chrono::nanoseconds(5ms).count(); - state.accel = hid_state.accel; - state.gyro = hid_state.gyro; - state.rotation = hid_state.rotation; - state.orientation = hid_state.orientation; - }; - - switch (controller_type) { - case Core::HID::NpadStyleIndex::None: - ASSERT(false); - break; - case Core::HID::NpadStyleIndex::ProController: - set_motion_state(sixaxis_fullkey_state, motion_state[0]); - break; - case Core::HID::NpadStyleIndex::Handheld: - set_motion_state(sixaxis_handheld_state, motion_state[0]); - break; - case Core::HID::NpadStyleIndex::JoyconDual: - set_motion_state(sixaxis_dual_left_state, motion_state[0]); - set_motion_state(sixaxis_dual_right_state, motion_state[1]); - break; - case Core::HID::NpadStyleIndex::JoyconLeft: - set_motion_state(sixaxis_left_lifo_state, motion_state[0]); - break; - case Core::HID::NpadStyleIndex::JoyconRight: - set_motion_state(sixaxis_right_lifo_state, motion_state[1]); - break; - case Core::HID::NpadStyleIndex::Pokeball: - using namespace std::literals::chrono_literals; - set_motion_state(sixaxis_fullkey_state, motion_state[0]); - sixaxis_fullkey_state.delta_time = std::chrono::nanoseconds(15ms).count(); - break; - default: - break; - } - - sixaxis_fullkey_state.sampling_number = - sixaxis_fullkey_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; - sixaxis_handheld_state.sampling_number = - sixaxis_handheld_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; - sixaxis_dual_left_state.sampling_number = - sixaxis_dual_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; - sixaxis_dual_right_state.sampling_number = - sixaxis_dual_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; - sixaxis_left_lifo_state.sampling_number = - sixaxis_left_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; - sixaxis_right_lifo_state.sampling_number = - sixaxis_right_lifo.lifo.ReadCurrentEntry().state.sampling_number + 1; - - if (IndexToNpadIdType(i) == Core::HID::NpadIdType::Handheld) { - // This buffer only is updated on handheld on HW - sixaxis_handheld_lifo.lifo.WriteNextEntry(sixaxis_handheld_state); - } else { - // Handheld doesn't update this buffer on HW - sixaxis_fullkey_lifo.lifo.WriteNextEntry(sixaxis_fullkey_state); - } - - sixaxis_dual_left_lifo.lifo.WriteNextEntry(sixaxis_dual_left_state); - sixaxis_dual_right_lifo.lifo.WriteNextEntry(sixaxis_dual_right_state); - sixaxis_left_lifo.lifo.WriteNextEntry(sixaxis_left_lifo_state); - sixaxis_right_lifo.lifo.WriteNextEntry(sixaxis_right_lifo_state); - } -} - -Result SixAxis::SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::GyroscopeZeroDriftMode drift_mode) { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - auto& sixaxis = GetSixaxisState(sixaxis_handle); - auto& controller = GetControllerFromHandle(sixaxis_handle); - sixaxis.gyroscope_zero_drift_mode = drift_mode; - controller.device->SetGyroscopeZeroDriftMode(drift_mode); - - return ResultSuccess; -} - -Result SixAxis::GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::GyroscopeZeroDriftMode& drift_mode) const { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - const auto& sixaxis = GetSixaxisState(sixaxis_handle); - drift_mode = sixaxis.gyroscope_zero_drift_mode; - - return ResultSuccess; -} - -Result SixAxis::IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool& is_at_rest) const { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - const auto& controller = GetControllerFromHandle(sixaxis_handle); - is_at_rest = controller.sixaxis_at_rest; - return ResultSuccess; -} - -Result SixAxis::LoadSixAxisSensorCalibrationParameter( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::SixAxisSensorCalibrationParameter& calibration) const { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - // TODO: Request this data to the controller. On error return 0xd8ca - const auto& sixaxis = GetSixaxisState(sixaxis_handle); - calibration = sixaxis.calibration; - return ResultSuccess; -} - -Result SixAxis::GetSixAxisSensorIcInformation( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::SixAxisSensorIcInformation& ic_information) const { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - // TODO: Request this data to the controller. On error return 0xd8ca - const auto& sixaxis = GetSixaxisState(sixaxis_handle); - ic_information = sixaxis.ic_information; - return ResultSuccess; -} - -Result SixAxis::EnableSixAxisSensorUnalteredPassthrough( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled) { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - auto& sixaxis = GetSixaxisState(sixaxis_handle); - sixaxis.unaltered_passtrough = is_enabled; - return ResultSuccess; -} - -Result SixAxis::IsSixAxisSensorUnalteredPassthroughEnabled( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - const auto& sixaxis = GetSixaxisState(sixaxis_handle); - is_enabled = sixaxis.unaltered_passtrough; - return ResultSuccess; -} - -Result SixAxis::SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool sixaxis_status) { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - auto& controller = GetControllerFromHandle(sixaxis_handle); - controller.sixaxis_sensor_enabled = sixaxis_status; - return ResultSuccess; -} - -Result SixAxis::IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool& is_fusion_enabled) const { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - const auto& sixaxis = GetSixaxisState(sixaxis_handle); - is_fusion_enabled = sixaxis.is_fusion_enabled; - - return ResultSuccess; -} -Result SixAxis::SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool is_fusion_enabled) { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - auto& sixaxis = GetSixaxisState(sixaxis_handle); - sixaxis.is_fusion_enabled = is_fusion_enabled; - - return ResultSuccess; -} - -Result SixAxis::SetSixAxisFusionParameters( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters) { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - const auto param1 = sixaxis_fusion_parameters.parameter1; - if (param1 < 0.0f || param1 > 1.0f) { - return InvalidSixAxisFusionRange; - } - - auto& sixaxis = GetSixaxisState(sixaxis_handle); - sixaxis.fusion = sixaxis_fusion_parameters; - - return ResultSuccess; -} - -Result SixAxis::GetSixAxisFusionParameters( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::SixAxisSensorFusionParameters& parameters) const { - const auto is_valid = IsSixaxisHandleValid(sixaxis_handle); - if (is_valid.IsError()) { - LOG_ERROR(Service_HID, "Invalid handle, error_code={}", is_valid.raw); - return is_valid; - } - - const auto& sixaxis = GetSixaxisState(sixaxis_handle); - parameters = sixaxis.fusion; - - return ResultSuccess; -} - -SixAxis::SixaxisParameters& SixAxis::GetSixaxisState( - const Core::HID::SixAxisSensorHandle& sixaxis_handle) { - auto& controller = GetControllerFromHandle(sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - case Core::HID::NpadStyleIndex::Pokeball: - return controller.sixaxis_fullkey; - case Core::HID::NpadStyleIndex::Handheld: - return controller.sixaxis_handheld; - case Core::HID::NpadStyleIndex::JoyconDual: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - return controller.sixaxis_dual_left; - } - return controller.sixaxis_dual_right; - case Core::HID::NpadStyleIndex::JoyconLeft: - return controller.sixaxis_left; - case Core::HID::NpadStyleIndex::JoyconRight: - return controller.sixaxis_right; - default: - return controller.sixaxis_unknown; - } -} - -const SixAxis::SixaxisParameters& SixAxis::GetSixaxisState( - const Core::HID::SixAxisSensorHandle& sixaxis_handle) const { - const auto& controller = GetControllerFromHandle(sixaxis_handle); - switch (sixaxis_handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - case Core::HID::NpadStyleIndex::Pokeball: - return controller.sixaxis_fullkey; - case Core::HID::NpadStyleIndex::Handheld: - return controller.sixaxis_handheld; - case Core::HID::NpadStyleIndex::JoyconDual: - if (sixaxis_handle.device_index == Core::HID::DeviceIndex::Left) { - return controller.sixaxis_dual_left; - } - return controller.sixaxis_dual_right; - case Core::HID::NpadStyleIndex::JoyconLeft: - return controller.sixaxis_left; - case Core::HID::NpadStyleIndex::JoyconRight: - return controller.sixaxis_right; - default: - return controller.sixaxis_unknown; - } -} - -SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle( - const Core::HID::SixAxisSensorHandle& device_handle) { - const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); - return GetControllerFromNpadIdType(npad_id); -} - -const SixAxis::NpadControllerData& SixAxis::GetControllerFromHandle( - const Core::HID::SixAxisSensorHandle& device_handle) const { - const auto npad_id = static_cast<Core::HID::NpadIdType>(device_handle.npad_id); - return GetControllerFromNpadIdType(npad_id); -} - -SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) { - if (!IsNpadIdValid(npad_id)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - npad_id = Core::HID::NpadIdType::Player1; - } - const auto npad_index = NpadIdTypeToIndex(npad_id); - return controller_data[npad_index]; -} - -const SixAxis::NpadControllerData& SixAxis::GetControllerFromNpadIdType( - Core::HID::NpadIdType npad_id) const { - if (!IsNpadIdValid(npad_id)) { - LOG_ERROR(Service_HID, "Invalid NpadIdType npad_id:{}", npad_id); - npad_id = Core::HID::NpadIdType::Player1; - } - const auto npad_index = NpadIdTypeToIndex(npad_id); - return controller_data[npad_index]; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/six_axis.h b/src/core/hle/service/hid/controllers/six_axis.h deleted file mode 100644 index 4c4f5dc7b..000000000 --- a/src/core/hle/service/hid/controllers/six_axis.h +++ /dev/null @@ -1,111 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "core/hid/hid_types.h" -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/ring_lifo.h" - -namespace Core::HID { -class EmulatedController; -} // namespace Core::HID - -namespace Service::HID { -class NPad; - -class SixAxis final : public ControllerBase { -public: - explicit SixAxis(Core::HID::HIDCore& hid_core_, std::shared_ptr<NPad> npad_); - ~SixAxis() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - - Result SetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::GyroscopeZeroDriftMode drift_mode); - Result GetGyroscopeZeroDriftMode(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::GyroscopeZeroDriftMode& drift_mode) const; - Result IsSixAxisSensorAtRest(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool& is_at_rest) const; - Result EnableSixAxisSensorUnalteredPassthrough( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool is_enabled); - Result IsSixAxisSensorUnalteredPassthroughEnabled( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, bool& is_enabled) const; - Result LoadSixAxisSensorCalibrationParameter( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::SixAxisSensorCalibrationParameter& calibration) const; - Result GetSixAxisSensorIcInformation( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::SixAxisSensorIcInformation& ic_information) const; - Result SetSixAxisEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool sixaxis_status); - Result IsSixAxisSensorFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool& is_fusion_enabled) const; - Result SetSixAxisFusionEnabled(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - bool is_fusion_enabled); - Result SetSixAxisFusionParameters( - const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::SixAxisSensorFusionParameters sixaxis_fusion_parameters); - Result GetSixAxisFusionParameters(const Core::HID::SixAxisSensorHandle& sixaxis_handle, - Core::HID::SixAxisSensorFusionParameters& parameters) const; - -private: - static constexpr std::size_t NPAD_COUNT = 10; - - struct SixaxisParameters { - bool is_fusion_enabled{true}; - bool unaltered_passtrough{false}; - Core::HID::SixAxisSensorFusionParameters fusion{}; - Core::HID::SixAxisSensorCalibrationParameter calibration{}; - Core::HID::SixAxisSensorIcInformation ic_information{}; - Core::HID::GyroscopeZeroDriftMode gyroscope_zero_drift_mode{ - Core::HID::GyroscopeZeroDriftMode::Standard}; - }; - - struct NpadControllerData { - Core::HID::EmulatedController* device = nullptr; - - // Motion parameters - bool sixaxis_at_rest{true}; - bool sixaxis_sensor_enabled{true}; - SixaxisParameters sixaxis_fullkey{}; - SixaxisParameters sixaxis_handheld{}; - SixaxisParameters sixaxis_dual_left{}; - SixaxisParameters sixaxis_dual_right{}; - SixaxisParameters sixaxis_left{}; - SixaxisParameters sixaxis_right{}; - SixaxisParameters sixaxis_unknown{}; - - // Current pad state - Core::HID::SixAxisSensorState sixaxis_fullkey_state{}; - Core::HID::SixAxisSensorState sixaxis_handheld_state{}; - Core::HID::SixAxisSensorState sixaxis_dual_left_state{}; - Core::HID::SixAxisSensorState sixaxis_dual_right_state{}; - Core::HID::SixAxisSensorState sixaxis_left_lifo_state{}; - Core::HID::SixAxisSensorState sixaxis_right_lifo_state{}; - int callback_key{}; - }; - - SixaxisParameters& GetSixaxisState(const Core::HID::SixAxisSensorHandle& device_handle); - const SixaxisParameters& GetSixaxisState( - const Core::HID::SixAxisSensorHandle& device_handle) const; - - NpadControllerData& GetControllerFromHandle( - const Core::HID::SixAxisSensorHandle& device_handle); - const NpadControllerData& GetControllerFromHandle( - const Core::HID::SixAxisSensorHandle& device_handle) const; - NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id); - const NpadControllerData& GetControllerFromNpadIdType(Core::HID::NpadIdType npad_id) const; - - std::shared_ptr<NPad> npad; - std::array<NpadControllerData, NPAD_COUNT> controller_data{}; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/sleep_button.cpp b/src/core/hle/service/hid/controllers/sleep_button.cpp deleted file mode 100644 index d44b1f4cc..000000000 --- a/src/core/hle/service/hid/controllers/sleep_button.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/sleep_button.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -SleepButton::SleepButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} - -SleepButton::~SleepButton() = default; - -void SleepButton::OnInit() {} - -void SleepButton::OnRelease() {} - -void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (!smart_update) { - return; - } - - std::scoped_lock shared_lock{*shared_mutex}; - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - auto& header = data->shared_memory_format->capture_button.header; - header.timestamp = core_timing.GetGlobalTimeNs().count(); - header.total_entry_count = 17; - header.entry_count = 0; - header.last_entry_index = 0; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/sleep_button.h b/src/core/hle/service/hid/controllers/sleep_button.h deleted file mode 100644 index 59964bf63..000000000 --- a/src/core/hle/service/hid/controllers/sleep_button.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Service::HID { - -class SleepButton final : public ControllerBase { -public: - explicit SleepButton(Core::HID::HIDCore& hid_core_); - ~SleepButton() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - bool smart_update{}; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp deleted file mode 100644 index b585a5829..000000000 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <algorithm> -#include "common/common_types.h" -#include "common/settings.h" -#include "core/core_timing.h" -#include "core/frontend/emu_window.h" -#include "core/hid/emulated_console.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/touchscreen.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" - -namespace Service::HID { - -TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_) - : ControllerBase{hid_core_}, touchscreen_width(Layout::ScreenUndocked::Width), - touchscreen_height(Layout::ScreenUndocked::Height) { - console = hid_core.GetEmulatedConsole(); -} - -TouchScreen::~TouchScreen() = default; - -void TouchScreen::OnInit() {} - -void TouchScreen::OnRelease() {} - -void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - TouchScreenSharedMemoryFormat& shared_memory = data->shared_memory_format->touch_screen; - shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count(); - - if (!IsControllerActivated()) { - shared_memory.touch_screen_lifo.buffer_count = 0; - shared_memory.touch_screen_lifo.buffer_tail = 0; - return; - } - - const auto touch_status = console->GetTouch(); - for (std::size_t id = 0; id < MAX_FINGERS; id++) { - const auto& current_touch = touch_status[id]; - auto& finger = fingers[id]; - finger.id = current_touch.id; - - if (finger.attribute.start_touch) { - finger.attribute.raw = 0; - continue; - } - - if (finger.attribute.end_touch) { - finger.attribute.raw = 0; - finger.pressed = false; - continue; - } - - if (!finger.pressed && current_touch.pressed) { - // Ignore all touch fingers if disabled - if (!Settings::values.touchscreen.enabled) { - continue; - } - - finger.attribute.start_touch.Assign(1); - finger.pressed = true; - finger.position = current_touch.position; - continue; - } - - if (finger.pressed && !current_touch.pressed) { - finger.attribute.raw = 0; - finger.attribute.end_touch.Assign(1); - continue; - } - - // Only update position if touch is not on a special frame - finger.position = current_touch.position; - } - - std::array<Core::HID::TouchFinger, MAX_FINGERS> active_fingers; - const auto end_iter = std::copy_if(fingers.begin(), fingers.end(), active_fingers.begin(), - [](const auto& finger) { return finger.pressed; }); - const auto active_fingers_count = - static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); - - const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count()); - const auto& last_entry = shared_memory.touch_screen_lifo.ReadCurrentEntry().state; - - next_state.sampling_number = last_entry.sampling_number + 1; - next_state.entry_count = static_cast<s32>(active_fingers_count); - - for (std::size_t id = 0; id < MAX_FINGERS; ++id) { - auto& touch_entry = next_state.states[id]; - if (id < active_fingers_count) { - const auto& [active_x, active_y] = active_fingers[id].position; - touch_entry.position = { - .x = static_cast<u16>(active_x * static_cast<float>(touchscreen_width)), - .y = static_cast<u16>(active_y * static_cast<float>(touchscreen_height)), - }; - touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; - touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; - touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; - touch_entry.delta_time = timestamp - active_fingers[id].last_touch; - fingers[active_fingers[id].id].last_touch = timestamp; - touch_entry.finger = active_fingers[id].id; - touch_entry.attribute.raw = active_fingers[id].attribute.raw; - } else { - // Clear touch entry - touch_entry.attribute.raw = 0; - touch_entry.position = {}; - touch_entry.diameter_x = 0; - touch_entry.diameter_y = 0; - touch_entry.rotation_angle = 0; - touch_entry.delta_time = 0; - touch_entry.finger = 0; - } - } - - shared_memory.touch_screen_lifo.WriteNextEntry(next_state); -} - -void TouchScreen::SetTouchscreenDimensions(u32 width, u32 height) { - touchscreen_width = width; - touchscreen_height = height; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h deleted file mode 100644 index 945d359be..000000000 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> - -#include "core/hid/hid_types.h" -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/controllers/types/touch_types.h" - -namespace Core::HID { -class EmulatedConsole; -} // namespace Core::HID - -namespace Service::HID { -struct TouchScreenSharedMemoryFormat; - -class TouchScreen final : public ControllerBase { -public: - explicit TouchScreen(Core::HID::HIDCore& hid_core_); - ~TouchScreen() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - - void SetTouchscreenDimensions(u32 width, u32 height); - -private: - TouchScreenState next_state{}; - Core::HID::EmulatedConsole* console = nullptr; - - std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{}; - u32 touchscreen_width; - u32 touchscreen_height; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/debug_pad_types.h b/src/core/hle/service/hid/controllers/types/debug_pad_types.h deleted file mode 100644 index a96171b62..000000000 --- a/src/core/hle/service/hid/controllers/types/debug_pad_types.h +++ /dev/null @@ -1,31 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/bit_field.h" -#include "common/common_types.h" -#include "core/hid/hid_types.h" - -namespace Service::HID { - -// This is nn::hid::DebugPadAttribute -struct DebugPadAttribute { - union { - u32 raw{}; - BitField<0, 1, u32> connected; - }; -}; -static_assert(sizeof(DebugPadAttribute) == 0x4, "DebugPadAttribute is an invalid size"); - -// This is nn::hid::DebugPadState -struct DebugPadState { - s64 sampling_number{}; - DebugPadAttribute attribute{}; - Core::HID::DebugPadButton pad_state{}; - Core::HID::AnalogStickState r_stick{}; - Core::HID::AnalogStickState l_stick{}; -}; -static_assert(sizeof(DebugPadState) == 0x20, "DebugPadState is an invalid state"); - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/gesture_types.h b/src/core/hle/service/hid/controllers/types/gesture_types.h deleted file mode 100644 index b4f034cd3..000000000 --- a/src/core/hle/service/hid/controllers/types/gesture_types.h +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <array> -#include "common/bit_field.h" -#include "common/common_types.h" -#include "common/point.h" - -namespace Service::HID { -static constexpr size_t MAX_FINGERS = 16; -static constexpr size_t MAX_POINTS = 4; - -// This is nn::hid::GestureType -enum class GestureType : u32 { - Idle, // Nothing touching the screen - Complete, // Set at the end of a touch event - Cancel, // Set when the number of fingers change - Touch, // A finger just touched the screen - Press, // Set if last type is touch and the finger hasn't moved - Tap, // Fast press then release - Pan, // All points moving together across the screen - Swipe, // Fast press movement and release of a single point - Pinch, // All points moving away/closer to the midpoint - Rotate, // All points rotating from the midpoint -}; - -// This is nn::hid::GestureDirection -enum class GestureDirection : u32 { - None, - Left, - Up, - Right, - Down, -}; - -// This is nn::hid::GestureAttribute -struct GestureAttribute { - union { - u32 raw{}; - - BitField<4, 1, u32> is_new_touch; - BitField<8, 1, u32> is_double_tap; - }; -}; -static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); - -// This is nn::hid::GestureState -struct GestureState { - s64 sampling_number{}; - s64 detection_count{}; - GestureType type{GestureType::Idle}; - GestureDirection direction{GestureDirection::None}; - Common::Point<s32> pos{}; - Common::Point<s32> delta{}; - f32 vel_x{}; - f32 vel_y{}; - GestureAttribute attributes{}; - f32 scale{}; - f32 rotation_angle{}; - s32 point_count{}; - std::array<Common::Point<s32>, 4> points{}; -}; -static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); - -struct GestureProperties { - std::array<Common::Point<s32>, MAX_POINTS> points{}; - std::size_t active_points{}; - Common::Point<s32> mid_point{}; - s64 detection_count{}; - u64 delta_time{}; - f32 average_distance{}; - f32 angle{}; -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/keyboard_types.h b/src/core/hle/service/hid/controllers/types/keyboard_types.h deleted file mode 100644 index f44a536b9..000000000 --- a/src/core/hle/service/hid/controllers/types/keyboard_types.h +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "core/hid/hid_types.h" - -namespace Service::HID { - -// This is nn::hid::detail::KeyboardState -struct KeyboardState { - s64 sampling_number{}; - Core::HID::KeyboardModifier modifier{}; - Core::HID::KeyboardAttribute attribute{}; - Core::HID::KeyboardKey key{}; -}; -static_assert(sizeof(KeyboardState) == 0x30, "KeyboardState is an invalid size"); - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/mouse_types.h b/src/core/hle/service/hid/controllers/types/mouse_types.h deleted file mode 100644 index 8bd6e167c..000000000 --- a/src/core/hle/service/hid/controllers/types/mouse_types.h +++ /dev/null @@ -1,8 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_types.h" - -namespace Service::HID {} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/npad_types.h b/src/core/hle/service/hid/controllers/types/npad_types.h deleted file mode 100644 index 419c33a8c..000000000 --- a/src/core/hle/service/hid/controllers/types/npad_types.h +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/bit_field.h" -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "core/hid/hid_types.h" - -namespace Service::HID { -static constexpr std::size_t MaxSupportedNpadIdTypes = 10; -static constexpr std::size_t StyleIndexCount = 7; - -// This is nn::hid::NpadJoyHoldType -enum class NpadJoyHoldType : u64 { - Vertical = 0, - Horizontal = 1, -}; - -// This is nn::hid::NpadJoyAssignmentMode -enum class NpadJoyAssignmentMode : u32 { - Dual = 0, - Single = 1, -}; - -// This is nn::hid::NpadJoyDeviceType -enum class NpadJoyDeviceType : s64 { - Left = 0, - Right = 1, -}; - -// This is nn::hid::NpadHandheldActivationMode -enum class NpadHandheldActivationMode : u64 { - Dual = 0, - Single = 1, - None = 2, - MaxActivationMode = 3, -}; - -// This is nn::hid::system::AppletFooterUiAttributesSet -struct AppletFooterUiAttributes { - INSERT_PADDING_BYTES(0x4); -}; - -// This is nn::hid::system::AppletFooterUiType -enum class AppletFooterUiType : u8 { - None = 0, - HandheldNone = 1, - HandheldJoyConLeftOnly = 2, - HandheldJoyConRightOnly = 3, - HandheldJoyConLeftJoyConRight = 4, - JoyDual = 5, - JoyDualLeftOnly = 6, - JoyDualRightOnly = 7, - JoyLeftHorizontal = 8, - JoyLeftVertical = 9, - JoyRightHorizontal = 10, - JoyRightVertical = 11, - SwitchProController = 12, - CompatibleProController = 13, - CompatibleJoyCon = 14, - LarkHvc1 = 15, - LarkHvc2 = 16, - LarkNesLeft = 17, - LarkNesRight = 18, - Lucia = 19, - Verification = 20, - Lagon = 21, -}; - -using AppletFooterUiVariant = u8; - -// This is "nn::hid::system::AppletDetailedUiType". -struct AppletDetailedUiType { - AppletFooterUiVariant ui_variant; - INSERT_PADDING_BYTES(0x2); - AppletFooterUiType footer; -}; -static_assert(sizeof(AppletDetailedUiType) == 0x4, "AppletDetailedUiType is an invalid size"); -// This is nn::hid::NpadCommunicationMode -enum class NpadCommunicationMode : u64 { - Mode_5ms = 0, - Mode_10ms = 1, - Mode_15ms = 2, - Default = 3, -}; - -enum class NpadRevision : u32 { - Revision0 = 0, - Revision1 = 1, - Revision2 = 2, - Revision3 = 3, -}; - -// This is nn::hid::detail::ColorAttribute -enum class ColorAttribute : u32 { - Ok = 0, - ReadError = 1, - NoController = 2, -}; -static_assert(sizeof(ColorAttribute) == 4, "ColorAttribute is an invalid size"); - -// This is nn::hid::detail::NpadFullKeyColorState -struct NpadFullKeyColorState { - ColorAttribute attribute{ColorAttribute::NoController}; - Core::HID::NpadControllerColor fullkey{}; -}; -static_assert(sizeof(NpadFullKeyColorState) == 0xC, "NpadFullKeyColorState is an invalid size"); - -// This is nn::hid::detail::NpadJoyColorState -struct NpadJoyColorState { - ColorAttribute attribute{ColorAttribute::NoController}; - Core::HID::NpadControllerColor left{}; - Core::HID::NpadControllerColor right{}; -}; -static_assert(sizeof(NpadJoyColorState) == 0x14, "NpadJoyColorState is an invalid size"); - -// This is nn::hid::NpadAttribute -struct NpadAttribute { - union { - u32 raw{}; - BitField<0, 1, u32> is_connected; - BitField<1, 1, u32> is_wired; - BitField<2, 1, u32> is_left_connected; - BitField<3, 1, u32> is_left_wired; - BitField<4, 1, u32> is_right_connected; - BitField<5, 1, u32> is_right_wired; - }; -}; -static_assert(sizeof(NpadAttribute) == 4, "NpadAttribute is an invalid size"); - -// This is nn::hid::NpadFullKeyState -// This is nn::hid::NpadHandheldState -// This is nn::hid::NpadJoyDualState -// This is nn::hid::NpadJoyLeftState -// This is nn::hid::NpadJoyRightState -// This is nn::hid::NpadPalmaState -// This is nn::hid::NpadSystemExtState -struct NPadGenericState { - s64_le sampling_number{}; - Core::HID::NpadButtonState npad_buttons{}; - Core::HID::AnalogStickState l_stick{}; - Core::HID::AnalogStickState r_stick{}; - NpadAttribute connection_status{}; - INSERT_PADDING_BYTES(4); // Reserved -}; -static_assert(sizeof(NPadGenericState) == 0x28, "NPadGenericState is an invalid size"); - -// This is nn::hid::server::NpadGcTriggerState -struct NpadGcTriggerState { - s64 sampling_number{}; - s32 l_analog{}; - s32 r_analog{}; -}; -static_assert(sizeof(NpadGcTriggerState) == 0x10, "NpadGcTriggerState is an invalid size"); - -// This is nn::hid::NpadSystemProperties -struct NPadSystemProperties { - union { - s64 raw{}; - BitField<0, 1, s64> is_charging_joy_dual; - BitField<1, 1, s64> is_charging_joy_left; - BitField<2, 1, s64> is_charging_joy_right; - BitField<3, 1, s64> is_powered_joy_dual; - BitField<4, 1, s64> is_powered_joy_left; - BitField<5, 1, s64> is_powered_joy_right; - BitField<9, 1, s64> is_system_unsupported_button; - BitField<10, 1, s64> is_system_ext_unsupported_button; - BitField<11, 1, s64> is_vertical; - BitField<12, 1, s64> is_horizontal; - BitField<13, 1, s64> use_plus; - BitField<14, 1, s64> use_minus; - BitField<15, 1, s64> use_directional_buttons; - }; -}; -static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); - -// This is nn::hid::NpadSystemButtonProperties -struct NpadSystemButtonProperties { - union { - s32 raw{}; - BitField<0, 1, s32> is_home_button_protection_enabled; - }; -}; -static_assert(sizeof(NpadSystemButtonProperties) == 0x4, "NPadButtonProperties is an invalid size"); - -// This is nn::hid::system::DeviceType -struct DeviceType { - union { - u32 raw{}; - BitField<0, 1, s32> fullkey; - BitField<1, 1, s32> debug_pad; - BitField<2, 1, s32> handheld_left; - BitField<3, 1, s32> handheld_right; - BitField<4, 1, s32> joycon_left; - BitField<5, 1, s32> joycon_right; - BitField<6, 1, s32> palma; - BitField<7, 1, s32> lark_hvc_left; - BitField<8, 1, s32> lark_hvc_right; - BitField<9, 1, s32> lark_nes_left; - BitField<10, 1, s32> lark_nes_right; - BitField<11, 1, s32> handheld_lark_hvc_left; - BitField<12, 1, s32> handheld_lark_hvc_right; - BitField<13, 1, s32> handheld_lark_nes_left; - BitField<14, 1, s32> handheld_lark_nes_right; - BitField<15, 1, s32> lucia; - BitField<16, 1, s32> lagon; - BitField<17, 1, s32> lager; - BitField<31, 1, s32> system; - }; -}; - -// This is nn::hid::detail::NfcXcdDeviceHandleStateImpl -struct NfcXcdDeviceHandleStateImpl { - u64 handle{}; - bool is_available{}; - bool is_activated{}; - INSERT_PADDING_BYTES(0x6); // Reserved - u64 sampling_number{}; -}; -static_assert(sizeof(NfcXcdDeviceHandleStateImpl) == 0x18, - "NfcXcdDeviceHandleStateImpl is an invalid size"); - -// This is nn::hid::NpadLarkType -enum class NpadLarkType : u32 { - Invalid, - H1, - H2, - NL, - NR, -}; - -// This is nn::hid::NpadLuciaType -enum class NpadLuciaType : u32 { - Invalid, - J, - E, - U, -}; - -// This is nn::hid::NpadLagonType -enum class NpadLagonType : u32 { - Invalid, -}; - -// This is nn::hid::NpadLagerType -enum class NpadLagerType : u32 { - Invalid, - J, - E, - U, -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/shared_memory_format.h b/src/core/hle/service/hid/controllers/types/shared_memory_format.h deleted file mode 100644 index 976043b9c..000000000 --- a/src/core/hle/service/hid/controllers/types/shared_memory_format.h +++ /dev/null @@ -1,240 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "common/vector_math.h" -#include "core/hid/hid_types.h" -#include "core/hle/service/hid//controllers/types/debug_pad_types.h" -#include "core/hle/service/hid//controllers/types/keyboard_types.h" -#include "core/hle/service/hid//controllers/types/mouse_types.h" -#include "core/hle/service/hid//controllers/types/npad_types.h" -#include "core/hle/service/hid//controllers/types/touch_types.h" -#include "core/hle/service/hid/ring_lifo.h" - -namespace Service::HID { -static const std::size_t HidEntryCount = 17; - -struct CommonHeader { - s64 timestamp{}; - s64 total_entry_count{}; - s64 last_entry_index{}; - s64 entry_count{}; -}; -static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); - -// This is nn::hid::detail::DebugPadSharedMemoryFormat -struct DebugPadSharedMemoryFormat { - // This is nn::hid::detail::DebugPadLifo - Lifo<DebugPadState, HidEntryCount> debug_pad_lifo{}; - static_assert(sizeof(debug_pad_lifo) == 0x2C8, "debug_pad_lifo is an invalid size"); - INSERT_PADDING_WORDS(0x4E); -}; -static_assert(sizeof(DebugPadSharedMemoryFormat) == 0x400, - "DebugPadSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::TouchScreenSharedMemoryFormat -struct TouchScreenSharedMemoryFormat { - // This is nn::hid::detail::TouchScreenLifo - Lifo<TouchScreenState, HidEntryCount> touch_screen_lifo{}; - static_assert(sizeof(touch_screen_lifo) == 0x2C38, "touch_screen_lifo is an invalid size"); - INSERT_PADDING_WORDS(0xF2); -}; -static_assert(sizeof(TouchScreenSharedMemoryFormat) == 0x3000, - "TouchScreenSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::MouseSharedMemoryFormat -struct MouseSharedMemoryFormat { - // This is nn::hid::detail::MouseLifo - Lifo<Core::HID::MouseState, HidEntryCount> mouse_lifo{}; - static_assert(sizeof(mouse_lifo) == 0x350, "mouse_lifo is an invalid size"); - INSERT_PADDING_WORDS(0x2C); -}; -static_assert(sizeof(MouseSharedMemoryFormat) == 0x400, - "MouseSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::KeyboardSharedMemoryFormat -struct KeyboardSharedMemoryFormat { - // This is nn::hid::detail::KeyboardLifo - Lifo<KeyboardState, HidEntryCount> keyboard_lifo{}; - static_assert(sizeof(keyboard_lifo) == 0x3D8, "keyboard_lifo is an invalid size"); - INSERT_PADDING_WORDS(0xA); -}; -static_assert(sizeof(KeyboardSharedMemoryFormat) == 0x400, - "KeyboardSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::DigitizerSharedMemoryFormat -struct DigitizerSharedMemoryFormat { - CommonHeader header; - INSERT_PADDING_BYTES(0xFE0); -}; -static_assert(sizeof(DigitizerSharedMemoryFormat) == 0x1000, - "DigitizerSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::HomeButtonSharedMemoryFormat -struct HomeButtonSharedMemoryFormat { - CommonHeader header; - INSERT_PADDING_BYTES(0x1E0); -}; -static_assert(sizeof(HomeButtonSharedMemoryFormat) == 0x200, - "HomeButtonSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::SleepButtonSharedMemoryFormat -struct SleepButtonSharedMemoryFormat { - CommonHeader header; - INSERT_PADDING_BYTES(0x1E0); -}; -static_assert(sizeof(SleepButtonSharedMemoryFormat) == 0x200, - "SleepButtonSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::CaptureButtonSharedMemoryFormat -struct CaptureButtonSharedMemoryFormat { - CommonHeader header; - INSERT_PADDING_BYTES(0x1E0); -}; -static_assert(sizeof(CaptureButtonSharedMemoryFormat) == 0x200, - "CaptureButtonSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::InputDetectorSharedMemoryFormat -struct InputDetectorSharedMemoryFormat { - CommonHeader header; - INSERT_PADDING_BYTES(0x7E0); -}; -static_assert(sizeof(InputDetectorSharedMemoryFormat) == 0x800, - "InputDetectorSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::UniquePadSharedMemoryFormat -struct UniquePadSharedMemoryFormat { - CommonHeader header; - INSERT_PADDING_BYTES(0x3FE0); -}; -static_assert(sizeof(UniquePadSharedMemoryFormat) == 0x4000, - "UniquePadSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::NpadSixAxisSensorLifo -struct NpadSixAxisSensorLifo { - Lifo<Core::HID::SixAxisSensorState, HidEntryCount> lifo; -}; - -// This is nn::hid::detail::NpadInternalState -struct NpadInternalState { - Core::HID::NpadStyleTag style_tag{Core::HID::NpadStyleSet::None}; - NpadJoyAssignmentMode assignment_mode{NpadJoyAssignmentMode::Dual}; - NpadFullKeyColorState fullkey_color{}; - NpadJoyColorState joycon_color{}; - Lifo<NPadGenericState, HidEntryCount> fullkey_lifo{}; - Lifo<NPadGenericState, HidEntryCount> handheld_lifo{}; - Lifo<NPadGenericState, HidEntryCount> joy_dual_lifo{}; - Lifo<NPadGenericState, HidEntryCount> joy_left_lifo{}; - Lifo<NPadGenericState, HidEntryCount> joy_right_lifo{}; - Lifo<NPadGenericState, HidEntryCount> palma_lifo{}; - Lifo<NPadGenericState, HidEntryCount> system_ext_lifo{}; - NpadSixAxisSensorLifo sixaxis_fullkey_lifo{}; - NpadSixAxisSensorLifo sixaxis_handheld_lifo{}; - NpadSixAxisSensorLifo sixaxis_dual_left_lifo{}; - NpadSixAxisSensorLifo sixaxis_dual_right_lifo{}; - NpadSixAxisSensorLifo sixaxis_left_lifo{}; - NpadSixAxisSensorLifo sixaxis_right_lifo{}; - DeviceType device_type{}; - INSERT_PADDING_BYTES(0x4); // Reserved - NPadSystemProperties system_properties{}; - NpadSystemButtonProperties button_properties{}; - Core::HID::NpadBatteryLevel battery_level_dual{}; - Core::HID::NpadBatteryLevel battery_level_left{}; - Core::HID::NpadBatteryLevel battery_level_right{}; - AppletFooterUiAttributes applet_footer_attributes{}; - AppletFooterUiType applet_footer_type{AppletFooterUiType::None}; - INSERT_PADDING_BYTES(0x5B); // Reserved - INSERT_PADDING_BYTES(0x20); // Unknown - Lifo<NpadGcTriggerState, HidEntryCount> gc_trigger_lifo{}; - NpadLarkType lark_type_l_and_main{}; - NpadLarkType lark_type_r{}; - NpadLuciaType lucia_type{}; - NpadLagerType lager_type{}; - Core::HID::SixAxisSensorProperties sixaxis_fullkey_properties; - Core::HID::SixAxisSensorProperties sixaxis_handheld_properties; - Core::HID::SixAxisSensorProperties sixaxis_dual_left_properties; - Core::HID::SixAxisSensorProperties sixaxis_dual_right_properties; - Core::HID::SixAxisSensorProperties sixaxis_left_properties; - Core::HID::SixAxisSensorProperties sixaxis_right_properties; -}; -static_assert(sizeof(NpadInternalState) == 0x43F8, "NpadInternalState is an invalid size"); - -// This is nn::hid::detail::NpadSharedMemoryEntry -struct NpadSharedMemoryEntry { - NpadInternalState internal_state; - INSERT_PADDING_BYTES(0xC08); -}; -static_assert(sizeof(NpadSharedMemoryEntry) == 0x5000, "NpadSharedMemoryEntry is an invalid size"); - -// This is nn::hid::detail::NpadSharedMemoryFormat -struct NpadSharedMemoryFormat { - std::array<NpadSharedMemoryEntry, MaxSupportedNpadIdTypes> npad_entry; -}; -static_assert(sizeof(NpadSharedMemoryFormat) == 0x32000, - "NpadSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::GestureSharedMemoryFormat -struct GestureSharedMemoryFormat { - // This is nn::hid::detail::GestureLifo - Lifo<GestureState, HidEntryCount> gesture_lifo{}; - static_assert(sizeof(gesture_lifo) == 0x708, "gesture_lifo is an invalid size"); - INSERT_PADDING_WORDS(0x3E); -}; -static_assert(sizeof(GestureSharedMemoryFormat) == 0x800, - "GestureSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::ConsoleSixAxisSensorSharedMemoryFormat -struct ConsoleSixAxisSensorSharedMemoryFormat { - u64 sampling_number{}; - bool is_seven_six_axis_sensor_at_rest{}; - INSERT_PADDING_BYTES(3); // padding - f32 verticalization_error{}; - Common::Vec3f gyro_bias{}; - INSERT_PADDING_BYTES(4); // padding -}; -static_assert(sizeof(ConsoleSixAxisSensorSharedMemoryFormat) == 0x20, - "ConsoleSixAxisSensorSharedMemoryFormat is an invalid size"); - -// This is nn::hid::detail::SharedMemoryFormat -struct SharedMemoryFormat { - void Initialize() {} - - DebugPadSharedMemoryFormat debug_pad; - TouchScreenSharedMemoryFormat touch_screen; - MouseSharedMemoryFormat mouse; - KeyboardSharedMemoryFormat keyboard; - DigitizerSharedMemoryFormat digitizer; - HomeButtonSharedMemoryFormat home_button; - SleepButtonSharedMemoryFormat sleep_button; - CaptureButtonSharedMemoryFormat capture_button; - InputDetectorSharedMemoryFormat input_detector; - UniquePadSharedMemoryFormat unique_pad; - NpadSharedMemoryFormat npad; - GestureSharedMemoryFormat gesture; - ConsoleSixAxisSensorSharedMemoryFormat console; - INSERT_PADDING_BYTES(0x19E0); - MouseSharedMemoryFormat debug_mouse; - INSERT_PADDING_BYTES(0x2000); -}; -static_assert(offsetof(SharedMemoryFormat, debug_pad) == 0x0, "debug_pad has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, touch_screen) == 0x400, "touch_screen has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, mouse) == 0x3400, "mouse has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, keyboard) == 0x3800, "keyboard has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, digitizer) == 0x3C00, "digitizer has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, home_button) == 0x4C00, "home_button has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, sleep_button) == 0x4E00, - "sleep_button has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, capture_button) == 0x5000, - "capture_button has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, input_detector) == 0x5200, - "input_detector has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, npad) == 0x9A00, "npad has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, gesture) == 0x3BA00, "gesture has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, console) == 0x3C200, "console has wrong offset"); -static_assert(offsetof(SharedMemoryFormat, debug_mouse) == 0x3DC00, "debug_mouse has wrong offset"); -static_assert(sizeof(SharedMemoryFormat) == 0x40000, "SharedMemoryFormat is an invalid size"); - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/types/touch_types.h b/src/core/hle/service/hid/controllers/types/touch_types.h deleted file mode 100644 index efeaa796d..000000000 --- a/src/core/hle/service/hid/controllers/types/touch_types.h +++ /dev/null @@ -1,90 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <array> - -#include <array> -#include "common/bit_field.h" -#include "common/common_funcs.h" -#include "common/common_types.h" -#include "common/point.h" -#include "core/hid/hid_types.h" - -namespace Service::HID { -static constexpr std::size_t MAX_FINGERS = 16; -static constexpr size_t MAX_POINTS = 4; - -// This is nn::hid::GestureType -enum class GestureType : u32 { - Idle, // Nothing touching the screen - Complete, // Set at the end of a touch event - Cancel, // Set when the number of fingers change - Touch, // A finger just touched the screen - Press, // Set if last type is touch and the finger hasn't moved - Tap, // Fast press then release - Pan, // All points moving together across the screen - Swipe, // Fast press movement and release of a single point - Pinch, // All points moving away/closer to the midpoint - Rotate, // All points rotating from the midpoint -}; - -// This is nn::hid::GestureDirection -enum class GestureDirection : u32 { - None, - Left, - Up, - Right, - Down, -}; - -// This is nn::hid::GestureAttribute -struct GestureAttribute { - union { - u32 raw{}; - - BitField<4, 1, u32> is_new_touch; - BitField<8, 1, u32> is_double_tap; - }; -}; -static_assert(sizeof(GestureAttribute) == 4, "GestureAttribute is an invalid size"); - -// This is nn::hid::GestureState -struct GestureState { - s64 sampling_number{}; - s64 detection_count{}; - GestureType type{GestureType::Idle}; - GestureDirection direction{GestureDirection::None}; - Common::Point<s32> pos{}; - Common::Point<s32> delta{}; - f32 vel_x{}; - f32 vel_y{}; - GestureAttribute attributes{}; - f32 scale{}; - f32 rotation_angle{}; - s32 point_count{}; - std::array<Common::Point<s32>, 4> points{}; -}; -static_assert(sizeof(GestureState) == 0x60, "GestureState is an invalid size"); - -struct GestureProperties { - std::array<Common::Point<s32>, MAX_POINTS> points{}; - std::size_t active_points{}; - Common::Point<s32> mid_point{}; - s64 detection_count{}; - u64 delta_time{}; - f32 average_distance{}; - f32 angle{}; -}; - -// This is nn::hid::TouchScreenState -struct TouchScreenState { - s64 sampling_number{}; - s32 entry_count{}; - INSERT_PADDING_BYTES(4); // Reserved - std::array<Core::HID::TouchState, MAX_FINGERS> states{}; -}; -static_assert(sizeof(TouchScreenState) == 0x290, "TouchScreenState is an invalid size"); - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/unique_pad.cpp b/src/core/hle/service/hid/controllers/unique_pad.cpp deleted file mode 100644 index 6c543031d..000000000 --- a/src/core/hle/service/hid/controllers/unique_pad.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core_timing.h" -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" -#include "core/hle/service/hid/controllers/unique_pad.h" - -namespace Service::HID { - -UniquePad::UniquePad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {} - -UniquePad::~UniquePad() = default; - -void UniquePad::OnInit() {} - -void UniquePad::OnRelease() {} - -void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { - if (!smart_update) { - return; - } - - const u64 aruid = applet_resource->GetActiveAruid(); - auto* data = applet_resource->GetAruidData(aruid); - - if (data == nullptr || !data->flag.is_assigned) { - return; - } - - auto& header = data->shared_memory_format->capture_button.header; - header.timestamp = core_timing.GetGlobalTimeNs().count(); - header.total_entry_count = 17; - header.entry_count = 0; - header.last_entry_index = 0; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/unique_pad.h b/src/core/hle/service/hid/controllers/unique_pad.h deleted file mode 100644 index 966368264..000000000 --- a/src/core/hle/service/hid/controllers/unique_pad.h +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/hid/controllers/controller_base.h" - -namespace Service::HID { - -class UniquePad final : public ControllerBase { -public: - explicit UniquePad(Core::HID::HIDCore& hid_core_); - ~UniquePad() override; - - // Called when the controller is initialized - void OnInit() override; - - // When the controller is released - void OnRelease() override; - - // When the controller is requesting an update for the shared memory - void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; - -private: - bool smart_update{}; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h deleted file mode 100644 index bb14aa61e..000000000 --- a/src/core/hle/service/hid/errors.h +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/result.h" - -namespace Service::HID { - -constexpr Result PalmaResultSuccess{ErrorModule::HID, 0}; -constexpr Result NpadInvalidHandle{ErrorModule::HID, 100}; -constexpr Result NpadDeviceIndexOutOfRange{ErrorModule::HID, 107}; - -constexpr Result ResultVibrationNotInitialized{ErrorModule::HID, 121}; -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}; - -constexpr Result ResultNfcIsNotReady{ErrorModule::HID, 461}; -constexpr Result ResultNfcXcdHandleIsNotInitialized{ErrorModule::HID, 464}; -constexpr Result ResultIrSensorIsNotReady{ErrorModule::HID, 501}; -constexpr Result ResultMcuIsNotReady{ErrorModule::HID, 541}; - -constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601}; -constexpr Result NpadIsSameType{ErrorModule::HID, 602}; -constexpr Result ResultNpadIsNotProController{ErrorModule::HID, 604}; - -constexpr Result ResultInvalidNpadId{ErrorModule::HID, 709}; -constexpr Result ResultNpadNotConnected{ErrorModule::HID, 710}; -constexpr Result ResultNpadHandlerOverflow{ErrorModule::HID, 711}; -constexpr Result ResultNpadHandlerNotInitialized{ErrorModule::HID, 712}; -constexpr Result ResultInvalidArraySize{ErrorModule::HID, 715}; -constexpr Result ResultUndefinedStyleset{ErrorModule::HID, 716}; -constexpr Result ResultMultipleStyleSetSelected{ErrorModule::HID, 717}; - -constexpr Result ResultAppletResourceOverflow{ErrorModule::HID, 1041}; -constexpr Result ResultAppletResourceNotInitialized{ErrorModule::HID, 1042}; -constexpr Result ResultSharedMemoryNotInitialized{ErrorModule::HID, 1043}; -constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044}; -constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046}; -constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047}; - -constexpr Result ResultNpadResourceOverflow{ErrorModule::HID, 2001}; -constexpr Result ResultNpadResourceNotInitialized{ErrorModule::HID, 2002}; - -constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302}; - -} // namespace Service::HID - -namespace Service::IRS { - -constexpr Result InvalidProcessorState{ErrorModule::Irsensor, 78}; -constexpr Result InvalidIrCameraHandle{ErrorModule::Irsensor, 204}; - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index bd2873181..fc8a3ab66 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -5,14 +5,14 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid_debug_server.h" -#include "core/hle/service/hid/hid_firmware_settings.h" #include "core/hle/service/hid/hid_server.h" #include "core/hle/service/hid/hid_system_server.h" #include "core/hle/service/hid/hidbus.h" #include "core/hle/service/hid/irs.h" -#include "core/hle/service/hid/resource_manager.h" #include "core/hle/service/hid/xcd.h" #include "core/hle/service/server_manager.h" +#include "hid_core/resource_manager.h" +#include "hid_core/resources/hid_firmware_settings.h" namespace Service::HID { diff --git a/src/core/hle/service/hid/hid_debug_server.cpp b/src/core/hle/service/hid/hid_debug_server.cpp index 6294f3dfb..f2a767d37 100644 --- a/src/core/hle/service/hid/hid_debug_server.cpp +++ b/src/core/hle/service/hid/hid_debug_server.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "core/hle/service/hid/hid_debug_server.h" -#include "core/hle/service/hid/resource_manager.h" #include "core/hle/service/ipc_helpers.h" +#include "hid_core/resource_manager.h" namespace Service::HID { diff --git a/src/core/hle/service/hid/hid_firmware_settings.cpp b/src/core/hle/service/hid/hid_firmware_settings.cpp deleted file mode 100644 index 59bd6825c..000000000 --- a/src/core/hle/service/hid/hid_firmware_settings.cpp +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/hle/service/hid/hid_firmware_settings.h" - -namespace Service::HID { - -HidFirmwareSettings::HidFirmwareSettings() { - LoadSettings(true); -} - -void HidFirmwareSettings::Reload() { - LoadSettings(true); -} - -void HidFirmwareSettings::LoadSettings(bool reload_config) { - if (is_initalized && !reload_config) { - return; - } - - // TODO: Use nn::settings::fwdbg::GetSettingsItemValue to load config values - - is_debug_pad_enabled = true; - is_device_managed = true; - is_touch_i2c_managed = is_device_managed; - is_future_devices_emulated = false; - is_mcu_hardware_error_emulated = false; - is_rail_enabled = true; - is_firmware_update_failure_emulated = false; - is_firmware_update_failure = {}; - is_ble_disabled = false; - is_dscale_disabled = false; - is_handheld_forced = true; - features_per_id_disabled = {}; - is_touch_firmware_auto_update_disabled = false; - is_initalized = true; -} - -bool HidFirmwareSettings::IsDebugPadEnabled() { - LoadSettings(false); - return is_debug_pad_enabled; -} - -bool HidFirmwareSettings::IsDeviceManaged() { - LoadSettings(false); - return is_device_managed; -} - -bool HidFirmwareSettings::IsEmulateFutureDevice() { - LoadSettings(false); - return is_future_devices_emulated; -} - -bool HidFirmwareSettings::IsTouchI2cManaged() { - LoadSettings(false); - return is_touch_i2c_managed; -} - -bool HidFirmwareSettings::IsHandheldForced() { - LoadSettings(false); - return is_handheld_forced; -} - -bool HidFirmwareSettings::IsRailEnabled() { - LoadSettings(false); - return is_rail_enabled; -} - -bool HidFirmwareSettings::IsHardwareErrorEmulated() { - LoadSettings(false); - return is_mcu_hardware_error_emulated; -} - -bool HidFirmwareSettings::IsBleDisabled() { - LoadSettings(false); - return is_ble_disabled; -} - -bool HidFirmwareSettings::IsDscaleDisabled() { - LoadSettings(false); - return is_dscale_disabled; -} - -bool HidFirmwareSettings::IsTouchAutoUpdateDisabled() { - LoadSettings(false); - return is_touch_firmware_auto_update_disabled; -} - -HidFirmwareSettings::FirmwareSetting HidFirmwareSettings::GetFirmwareUpdateFailure() { - LoadSettings(false); - return is_firmware_update_failure; -} - -HidFirmwareSettings::FeaturesPerId HidFirmwareSettings::FeaturesDisabledPerId() { - LoadSettings(false); - return features_per_id_disabled; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hid_firmware_settings.h b/src/core/hle/service/hid/hid_firmware_settings.h deleted file mode 100644 index 6c10c440b..000000000 --- a/src/core/hle/service/hid/hid_firmware_settings.h +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_types.h" - -namespace Service::HID { - -/// Loads firmware config from nn::settings::fwdbg -class HidFirmwareSettings { -public: - using FirmwareSetting = std::array<u8, 4>; - using FeaturesPerId = std::array<bool, 0xA8>; - - HidFirmwareSettings(); - - void Reload(); - void LoadSettings(bool reload_config); - - bool IsDebugPadEnabled(); - bool IsDeviceManaged(); - bool IsEmulateFutureDevice(); - bool IsTouchI2cManaged(); - bool IsHandheldForced(); - bool IsRailEnabled(); - bool IsHardwareErrorEmulated(); - bool IsBleDisabled(); - bool IsDscaleDisabled(); - bool IsTouchAutoUpdateDisabled(); - - FirmwareSetting GetFirmwareUpdateFailure(); - FeaturesPerId FeaturesDisabledPerId(); - -private: - bool is_initalized{}; - - // Debug settings - bool is_debug_pad_enabled{}; - bool is_device_managed{}; - bool is_touch_i2c_managed{}; - bool is_future_devices_emulated{}; - bool is_mcu_hardware_error_emulated{}; - bool is_rail_enabled{}; - bool is_firmware_update_failure_emulated{}; - bool is_ble_disabled{}; - bool is_dscale_disabled{}; - bool is_handheld_forced{}; - bool is_touch_firmware_auto_update_disabled{}; - FirmwareSetting is_firmware_update_failure{}; - FeaturesPerId features_per_id_disabled{}; -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index a953c92b3..2ff00d30d 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -5,30 +5,29 @@ #include "common/common_types.h" #include "common/logging/log.h" #include "common/settings.h" -#include "core/hid/hid_core.h" #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/service/hid/errors.h" -#include "core/hle/service/hid/hid_firmware_settings.h" #include "core/hle/service/hid/hid_server.h" -#include "core/hle/service/hid/hid_util.h" -#include "core/hle/service/hid/resource_manager.h" #include "core/hle/service/ipc_helpers.h" #include "core/memory.h" - -#include "core/hle/service/hid/controllers/console_six_axis.h" -#include "core/hle/service/hid/controllers/controller_base.h" -#include "core/hle/service/hid/controllers/debug_pad.h" -#include "core/hle/service/hid/controllers/gesture.h" -#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/palma.h" -#include "core/hle/service/hid/controllers/seven_six_axis.h" -#include "core/hle/service/hid/controllers/six_axis.h" -#include "core/hle/service/hid/controllers/touchscreen.h" -#include "core/hle/service/hid/controllers/types/npad_types.h" +#include "hid_core/hid_result.h" +#include "hid_core/hid_util.h" +#include "hid_core/resource_manager.h" +#include "hid_core/resources/hid_firmware_settings.h" + +#include "hid_core/resources/controller_base.h" +#include "hid_core/resources/debug_pad/debug_pad.h" +#include "hid_core/resources/keyboard/keyboard.h" +#include "hid_core/resources/mouse/mouse.h" +#include "hid_core/resources/npad/npad.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/palma/palma.h" +#include "hid_core/resources/six_axis/console_six_axis.h" +#include "hid_core/resources/six_axis/seven_six_axis.h" +#include "hid_core/resources/six_axis/six_axis.h" +#include "hid_core/resources/touch_screen/gesture.h" +#include "hid_core/resources/touch_screen/touch_screen.h" namespace Service::HID { diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index 4823de743..027c56025 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp @@ -1,15 +1,14 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/controllers/npad.h" -#include "core/hle/service/hid/controllers/palma.h" -#include "core/hle/service/hid/controllers/touchscreen.h" -#include "core/hle/service/hid/controllers/types/npad_types.h" -#include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hid_system_server.h" -#include "core/hle/service/hid/resource_manager.h" #include "core/hle/service/ipc_helpers.h" +#include "hid_core/hid_result.h" +#include "hid_core/resource_manager.h" +#include "hid_core/resources/npad/npad.h" +#include "hid_core/resources/npad/npad_types.h" +#include "hid_core/resources/palma/palma.h" +#include "hid_core/resources/touch_screen/touch_screen.h" namespace Service::HID { @@ -270,7 +269,7 @@ void IHidSystemServer::GetLastActiveNpad(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.PushEnum(system.HIDCore().GetLastActiveController()); + rb.Push(0); // Dont forget to fix this } void IHidSystemServer::ApplyNpadSystemCommonPolicyFull(HLERequestContext& ctx) { diff --git a/src/core/hle/service/hid/hid_util.h b/src/core/hle/service/hid/hid_util.h deleted file mode 100644 index 6a2ed287a..000000000 --- a/src/core/hle/service/hid/hid_util.h +++ /dev/null @@ -1,146 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "core/hid/hid_types.h" -#include "core/hle/service/hid/errors.h" - -namespace Service::HID { - -constexpr bool IsNpadIdValid(const Core::HID::NpadIdType npad_id) { - switch (npad_id) { - case Core::HID::NpadIdType::Player1: - case Core::HID::NpadIdType::Player2: - case Core::HID::NpadIdType::Player3: - case Core::HID::NpadIdType::Player4: - case Core::HID::NpadIdType::Player5: - case Core::HID::NpadIdType::Player6: - case Core::HID::NpadIdType::Player7: - case Core::HID::NpadIdType::Player8: - case Core::HID::NpadIdType::Other: - case Core::HID::NpadIdType::Handheld: - return true; - default: - return false; - } -} - -constexpr Result IsSixaxisHandleValid(const Core::HID::SixAxisSensorHandle& handle) { - const auto npad_id = IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id)); - const bool device_index = handle.device_index < Core::HID::DeviceIndex::MaxDeviceIndex; - - if (!npad_id) { - return ResultInvalidNpadId; - } - if (!device_index) { - return NpadDeviceIndexOutOfRange; - } - - return ResultSuccess; -} - -constexpr Result IsVibrationHandleValid(const Core::HID::VibrationDeviceHandle& handle) { - switch (handle.npad_type) { - case Core::HID::NpadStyleIndex::ProController: - case Core::HID::NpadStyleIndex::Handheld: - case Core::HID::NpadStyleIndex::JoyconDual: - case Core::HID::NpadStyleIndex::JoyconLeft: - case Core::HID::NpadStyleIndex::JoyconRight: - case Core::HID::NpadStyleIndex::GameCube: - case Core::HID::NpadStyleIndex::N64: - case Core::HID::NpadStyleIndex::SystemExt: - case Core::HID::NpadStyleIndex::System: - // These support vibration - break; - default: - return ResultVibrationInvalidStyleIndex; - } - - if (!IsNpadIdValid(static_cast<Core::HID::NpadIdType>(handle.npad_id))) { - return ResultVibrationInvalidNpadId; - } - - if (handle.device_index >= Core::HID::DeviceIndex::MaxDeviceIndex) { - return ResultVibrationDeviceIndexOutOfRange; - } - - return ResultSuccess; -} - -/// Converts a Core::HID::NpadIdType to an array index. -constexpr size_t NpadIdTypeToIndex(Core::HID::NpadIdType npad_id_type) { - switch (npad_id_type) { - case Core::HID::NpadIdType::Player1: - return 0; - case Core::HID::NpadIdType::Player2: - return 1; - case Core::HID::NpadIdType::Player3: - return 2; - case Core::HID::NpadIdType::Player4: - return 3; - case Core::HID::NpadIdType::Player5: - return 4; - case Core::HID::NpadIdType::Player6: - return 5; - case Core::HID::NpadIdType::Player7: - return 6; - case Core::HID::NpadIdType::Player8: - return 7; - case Core::HID::NpadIdType::Handheld: - return 8; - case Core::HID::NpadIdType::Other: - return 9; - default: - return 8; - } -} - -/// Converts an array index to a Core::HID::NpadIdType -constexpr Core::HID::NpadIdType IndexToNpadIdType(size_t index) { - switch (index) { - case 0: - return Core::HID::NpadIdType::Player1; - case 1: - return Core::HID::NpadIdType::Player2; - case 2: - return Core::HID::NpadIdType::Player3; - case 3: - return Core::HID::NpadIdType::Player4; - case 4: - return Core::HID::NpadIdType::Player5; - case 5: - return Core::HID::NpadIdType::Player6; - case 6: - return Core::HID::NpadIdType::Player7; - case 7: - return Core::HID::NpadIdType::Player8; - case 8: - return Core::HID::NpadIdType::Handheld; - case 9: - return Core::HID::NpadIdType::Other; - default: - return Core::HID::NpadIdType::Invalid; - } -} - -constexpr Core::HID::NpadStyleSet GetStylesetByIndex(std::size_t index) { - switch (index) { - case 0: - return Core::HID::NpadStyleSet::Fullkey; - case 1: - return Core::HID::NpadStyleSet::Handheld; - case 2: - return Core::HID::NpadStyleSet::JoyDual; - case 3: - return Core::HID::NpadStyleSet::JoyLeft; - case 4: - return Core::HID::NpadStyleSet::JoyRight; - case 5: - return Core::HID::NpadStyleSet::Palma; - default: - return Core::HID::NpadStyleSet::None; - } -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp index ffa7e144d..46f503d38 100644 --- a/src/core/hle/service/hid/hidbus.cpp +++ b/src/core/hle/service/hid/hidbus.cpp @@ -5,18 +5,18 @@ #include "common/settings.h" #include "core/core.h" #include "core/core_timing.h" -#include "core/hid/hid_types.h" #include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/service/hid/hidbus.h" -#include "core/hle/service/hid/hidbus/ringcon.h" -#include "core/hle/service/hid/hidbus/starlink.h" -#include "core/hle/service/hid/hidbus/stubbed.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/service.h" #include "core/memory.h" +#include "hid_core/hid_types.h" +#include "hid_core/hidbus/ringcon.h" +#include "hid_core/hidbus/starlink.h" +#include "hid_core/hidbus/stubbed.h" namespace Service::HID { // (15ms, 66Hz) diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h index 85a1df133..05f62f634 100644 --- a/src/core/hle/service/hid/hidbus.h +++ b/src/core/hle/service/hid/hidbus.h @@ -5,9 +5,9 @@ #include <functional> -#include "core/hle/service/hid/hidbus/hidbus_base.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/service.h" +#include "hid_core/hidbus/hidbus_base.h" namespace Core::Timing { struct EventType; diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.cpp b/src/core/hle/service/hid/hidbus/hidbus_base.cpp deleted file mode 100644 index 8c44f93e8..000000000 --- a/src/core/hle/service/hid/hidbus/hidbus_base.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hid/hid_core.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_readable_event.h" -#include "core/hle/service/hid/hidbus/hidbus_base.h" -#include "core/hle/service/kernel_helpers.h" - -namespace Service::HID { - -HidbusBase::HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_) - : system(system_), service_context(service_context_) { - send_command_async_event = service_context.CreateEvent("hidbus:SendCommandAsyncEvent"); -} - -HidbusBase::~HidbusBase() { - service_context.CloseEvent(send_command_async_event); -}; - -void HidbusBase::ActivateDevice() { - if (is_activated) { - return; - } - is_activated = true; - OnInit(); -} - -void HidbusBase::DeactivateDevice() { - if (is_activated) { - OnRelease(); - } - is_activated = false; -} - -bool HidbusBase::IsDeviceActivated() const { - return is_activated; -} - -void HidbusBase::Enable(bool enable) { - device_enabled = enable; -} - -bool HidbusBase::IsEnabled() const { - return device_enabled; -} - -bool HidbusBase::IsPollingMode() const { - return polling_mode_enabled; -} - -JoyPollingMode HidbusBase::GetPollingMode() const { - return polling_mode; -} - -void HidbusBase::SetPollingMode(JoyPollingMode mode) { - polling_mode = mode; - polling_mode_enabled = true; -} - -void HidbusBase::DisablePollingMode() { - polling_mode_enabled = false; -} - -void HidbusBase::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { - transfer_memory = t_mem; -} - -Kernel::KReadableEvent& HidbusBase::GetSendCommandAsycEvent() const { - return send_command_async_event->GetReadableEvent(); -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus/hidbus_base.h b/src/core/hle/service/hid/hidbus/hidbus_base.h deleted file mode 100644 index ec41684e1..000000000 --- a/src/core/hle/service/hid/hidbus/hidbus_base.h +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> -#include <span> -#include "common/typed_address.h" -#include "core/hle/result.h" - -namespace Core { -class System; -} - -namespace Kernel { -class KEvent; -class KReadableEvent; -} // namespace Kernel - -namespace Service::KernelHelpers { -class ServiceContext; -} - -namespace Service::HID { - -// This is nn::hidbus::JoyPollingMode -enum class JoyPollingMode : u32 { - SixAxisSensorDisable, - SixAxisSensorEnable, - ButtonOnly, -}; - -struct DataAccessorHeader { - Result result{ResultUnknown}; - INSERT_PADDING_WORDS(0x1); - std::array<u8, 0x18> unused{}; - u64 latest_entry{}; - u64 total_entries{}; -}; -static_assert(sizeof(DataAccessorHeader) == 0x30, "DataAccessorHeader is an invalid size"); - -struct JoyDisableSixAxisPollingData { - std::array<u8, 0x26> data; - u8 out_size; - INSERT_PADDING_BYTES(0x1); - u64 sampling_number; -}; -static_assert(sizeof(JoyDisableSixAxisPollingData) == 0x30, - "JoyDisableSixAxisPollingData is an invalid size"); - -struct JoyEnableSixAxisPollingData { - std::array<u8, 0x8> data; - u8 out_size; - INSERT_PADDING_BYTES(0x7); - u64 sampling_number; -}; -static_assert(sizeof(JoyEnableSixAxisPollingData) == 0x18, - "JoyEnableSixAxisPollingData is an invalid size"); - -struct JoyButtonOnlyPollingData { - std::array<u8, 0x2c> data; - u8 out_size; - INSERT_PADDING_BYTES(0x3); - u64 sampling_number; -}; -static_assert(sizeof(JoyButtonOnlyPollingData) == 0x38, - "JoyButtonOnlyPollingData is an invalid size"); - -struct JoyDisableSixAxisPollingEntry { - u64 sampling_number; - JoyDisableSixAxisPollingData polling_data; -}; -static_assert(sizeof(JoyDisableSixAxisPollingEntry) == 0x38, - "JoyDisableSixAxisPollingEntry is an invalid size"); - -struct JoyEnableSixAxisPollingEntry { - u64 sampling_number; - JoyEnableSixAxisPollingData polling_data; -}; -static_assert(sizeof(JoyEnableSixAxisPollingEntry) == 0x20, - "JoyEnableSixAxisPollingEntry is an invalid size"); - -struct JoyButtonOnlyPollingEntry { - u64 sampling_number; - JoyButtonOnlyPollingData polling_data; -}; -static_assert(sizeof(JoyButtonOnlyPollingEntry) == 0x40, - "JoyButtonOnlyPollingEntry is an invalid size"); - -struct JoyDisableSixAxisDataAccessor { - DataAccessorHeader header{}; - std::array<JoyDisableSixAxisPollingEntry, 0xb> entries{}; -}; -static_assert(sizeof(JoyDisableSixAxisDataAccessor) == 0x298, - "JoyDisableSixAxisDataAccessor is an invalid size"); - -struct JoyEnableSixAxisDataAccessor { - DataAccessorHeader header{}; - std::array<JoyEnableSixAxisPollingEntry, 0xb> entries{}; -}; -static_assert(sizeof(JoyEnableSixAxisDataAccessor) == 0x190, - "JoyEnableSixAxisDataAccessor is an invalid size"); - -struct ButtonOnlyPollingDataAccessor { - DataAccessorHeader header; - std::array<JoyButtonOnlyPollingEntry, 0xb> entries; -}; -static_assert(sizeof(ButtonOnlyPollingDataAccessor) == 0x2F0, - "ButtonOnlyPollingDataAccessor is an invalid size"); - -class HidbusBase { -public: - explicit HidbusBase(Core::System& system_, KernelHelpers::ServiceContext& service_context_); - virtual ~HidbusBase(); - - void ActivateDevice(); - - void DeactivateDevice(); - - bool IsDeviceActivated() const; - - // Enables/disables the device - void Enable(bool enable); - - // returns true if device is enabled - bool IsEnabled() const; - - // returns true if polling mode is enabled - bool IsPollingMode() const; - - // returns polling mode - JoyPollingMode GetPollingMode() const; - - // Sets and enables JoyPollingMode - void SetPollingMode(JoyPollingMode mode); - - // Disables JoyPollingMode - void DisablePollingMode(); - - // Called on EnableJoyPollingReceiveMode - void SetTransferMemoryAddress(Common::ProcessAddress t_mem); - - Kernel::KReadableEvent& GetSendCommandAsycEvent() const; - - virtual void OnInit() {} - - virtual void OnRelease() {} - - // Updates device transfer memory - virtual void OnUpdate() {} - - // Returns the device ID of the joycon - virtual u8 GetDeviceId() const { - return {}; - } - - // Assigns a command from data - virtual bool SetCommand(std::span<const u8> data) { - return {}; - } - - // Returns a reply from a command - virtual std::vector<u8> GetReply() const { - return {}; - } - -protected: - bool is_activated{}; - bool device_enabled{}; - bool polling_mode_enabled{}; - JoyPollingMode polling_mode = {}; - // TODO(German77): All data accessors need to be replaced with a ring lifo object - JoyDisableSixAxisDataAccessor disable_sixaxis_data{}; - JoyEnableSixAxisDataAccessor enable_sixaxis_data{}; - ButtonOnlyPollingDataAccessor button_only_data{}; - - Common::ProcessAddress transfer_memory{}; - - Core::System& system; - Kernel::KEvent* send_command_async_event; - KernelHelpers::ServiceContext& service_context; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp deleted file mode 100644 index 378108012..000000000 --- a/src/core/hle/service/hid/hidbus/ringcon.cpp +++ /dev/null @@ -1,292 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/core.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_readable_event.h" -#include "core/hle/service/hid/hidbus/ringcon.h" -#include "core/memory.h" - -namespace Service::HID { - -RingController::RingController(Core::System& system_, - KernelHelpers::ServiceContext& service_context_) - : HidbusBase(system_, service_context_) { - input = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); -} - -RingController::~RingController() = default; - -void RingController::OnInit() { - input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, - Common::Input::PollingMode::Ring); - return; -} - -void RingController::OnRelease() { - input->SetPollingMode(Core::HID::EmulatedDeviceIndex::RightIndex, - Common::Input::PollingMode::Active); - return; -}; - -void RingController::OnUpdate() { - if (!is_activated) { - return; - } - - if (!device_enabled) { - return; - } - - if (!polling_mode_enabled || transfer_memory == 0) { - return; - } - - // TODO: Increment multitasking counters from motion and sensor data - - switch (polling_mode) { - case JoyPollingMode::SixAxisSensorEnable: { - enable_sixaxis_data.header.total_entries = 10; - enable_sixaxis_data.header.result = ResultSuccess; - const auto& last_entry = - enable_sixaxis_data.entries[enable_sixaxis_data.header.latest_entry]; - - enable_sixaxis_data.header.latest_entry = - (enable_sixaxis_data.header.latest_entry + 1) % 10; - auto& curr_entry = enable_sixaxis_data.entries[enable_sixaxis_data.header.latest_entry]; - - curr_entry.sampling_number = last_entry.sampling_number + 1; - curr_entry.polling_data.sampling_number = curr_entry.sampling_number; - - const RingConData ringcon_value = GetSensorValue(); - curr_entry.polling_data.out_size = sizeof(ringcon_value); - std::memcpy(curr_entry.polling_data.data.data(), &ringcon_value, sizeof(ringcon_value)); - - system.ApplicationMemory().WriteBlock(transfer_memory, &enable_sixaxis_data, - sizeof(enable_sixaxis_data)); - break; - } - default: - LOG_ERROR(Service_HID, "Polling mode not supported {}", polling_mode); - break; - } -} - -RingController::RingConData RingController::GetSensorValue() const { - RingConData ringcon_sensor_value{ - .status = DataValid::Valid, - .data = 0, - }; - - const f32 force_value = input->GetRingSensorForce().force * range; - ringcon_sensor_value.data = static_cast<s16>(force_value) + idle_value; - - return ringcon_sensor_value; -} - -u8 RingController::GetDeviceId() const { - return device_id; -} - -std::vector<u8> RingController::GetReply() const { - const RingConCommands current_command = command; - - switch (current_command) { - case RingConCommands::GetFirmwareVersion: - return GetFirmwareVersionReply(); - case RingConCommands::ReadId: - return GetReadIdReply(); - case RingConCommands::c20105: - return GetC020105Reply(); - case RingConCommands::ReadUnkCal: - return GetReadUnkCalReply(); - case RingConCommands::ReadFactoryCal: - return GetReadFactoryCalReply(); - case RingConCommands::ReadUserCal: - return GetReadUserCalReply(); - case RingConCommands::ReadRepCount: - return GetReadRepCountReply(); - case RingConCommands::ReadTotalPushCount: - return GetReadTotalPushCountReply(); - case RingConCommands::ResetRepCount: - return GetResetRepCountReply(); - case RingConCommands::SaveCalData: - return GetSaveDataReply(); - default: - return GetErrorReply(); - } -} - -bool RingController::SetCommand(std::span<const u8> data) { - if (data.size() < 4) { - LOG_ERROR(Service_HID, "Command size not supported {}", data.size()); - command = RingConCommands::Error; - return false; - } - - std::memcpy(&command, data.data(), sizeof(RingConCommands)); - - switch (command) { - case RingConCommands::GetFirmwareVersion: - case RingConCommands::ReadId: - case RingConCommands::c20105: - case RingConCommands::ReadUnkCal: - case RingConCommands::ReadFactoryCal: - case RingConCommands::ReadUserCal: - case RingConCommands::ReadRepCount: - case RingConCommands::ReadTotalPushCount: - ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes"); - send_command_async_event->Signal(); - return true; - case RingConCommands::ResetRepCount: - ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes"); - total_rep_count = 0; - send_command_async_event->Signal(); - return true; - case RingConCommands::SaveCalData: { - ASSERT_MSG(data.size() == 0x14, "data.size is not 0x14 bytes"); - - SaveCalData save_info{}; - std::memcpy(&save_info, data.data(), sizeof(SaveCalData)); - user_calibration = save_info.calibration; - send_command_async_event->Signal(); - return true; - } - default: - LOG_ERROR(Service_HID, "Command not implemented {}", command); - command = RingConCommands::Error; - // Signal a reply to avoid softlocking the game - send_command_async_event->Signal(); - return false; - } -} - -std::vector<u8> RingController::GetFirmwareVersionReply() const { - const FirmwareVersionReply reply{ - .status = DataValid::Valid, - .firmware = version, - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetReadIdReply() const { - // The values are hardcoded from a real joycon - const ReadIdReply reply{ - .status = DataValid::Valid, - .id_l_x0 = 8, - .id_l_x0_2 = 41, - .id_l_x4 = 22294, - .id_h_x0 = 19777, - .id_h_x0_2 = 13621, - .id_h_x4 = 8245, - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetC020105Reply() const { - const Cmd020105Reply reply{ - .status = DataValid::Valid, - .data = 1, - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetReadUnkCalReply() const { - const ReadUnkCalReply reply{ - .status = DataValid::Valid, - .data = 0, - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetReadFactoryCalReply() const { - const ReadFactoryCalReply reply{ - .status = DataValid::Valid, - .calibration = factory_calibration, - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetReadUserCalReply() const { - const ReadUserCalReply reply{ - .status = DataValid::Valid, - .calibration = user_calibration, - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetReadRepCountReply() const { - const GetThreeByteReply reply{ - .status = DataValid::Valid, - .data = {total_rep_count, 0, 0}, - .crc = GetCrcValue({total_rep_count, 0, 0, 0}), - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetReadTotalPushCountReply() const { - const GetThreeByteReply reply{ - .status = DataValid::Valid, - .data = {total_push_count, 0, 0}, - .crc = GetCrcValue({total_push_count, 0, 0, 0}), - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetResetRepCountReply() const { - return GetReadRepCountReply(); -} - -std::vector<u8> RingController::GetSaveDataReply() const { - const StatusReply reply{ - .status = DataValid::Valid, - }; - - return GetDataVector(reply); -} - -std::vector<u8> RingController::GetErrorReply() const { - const ErrorReply reply{ - .status = DataValid::BadCRC, - }; - - return GetDataVector(reply); -} - -u8 RingController::GetCrcValue(const std::vector<u8>& data) const { - u8 crc = 0; - for (std::size_t index = 0; index < data.size(); index++) { - for (u8 i = 0x80; i > 0; i >>= 1) { - bool bit = (crc & 0x80) != 0; - if ((data[index] & i) != 0) { - bit = !bit; - } - crc <<= 1; - if (bit) { - crc ^= 0x8d; - } - } - } - return crc; -} - -template <typename T> -std::vector<u8> RingController::GetDataVector(const T& reply) const { - static_assert(std::is_trivially_copyable_v<T>); - std::vector<u8> data; - data.resize(sizeof(reply)); - std::memcpy(data.data(), &reply, sizeof(reply)); - return data; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus/ringcon.h b/src/core/hle/service/hid/hidbus/ringcon.h deleted file mode 100644 index f42f3ea41..000000000 --- a/src/core/hle/service/hid/hidbus/ringcon.h +++ /dev/null @@ -1,253 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> -#include <span> - -#include "common/common_types.h" -#include "core/hle/service/hid/hidbus/hidbus_base.h" - -namespace Core::HID { -class EmulatedController; -} // namespace Core::HID - -namespace Service::HID { - -class RingController final : public HidbusBase { -public: - explicit RingController(Core::System& system_, KernelHelpers::ServiceContext& service_context_); - ~RingController() override; - - void OnInit() override; - - void OnRelease() override; - - // Updates ringcon transfer memory - void OnUpdate() override; - - // Returns the device ID of the joycon - u8 GetDeviceId() const override; - - // Assigns a command from data - bool SetCommand(std::span<const u8> data) override; - - // Returns a reply from a command - std::vector<u8> GetReply() const override; - -private: - // These values are obtained from a real ring controller - static constexpr s16 idle_value = 2280; - static constexpr s16 idle_deadzone = 120; - static constexpr s16 range = 2500; - - // Most missing command names are leftovers from other firmware versions - enum class RingConCommands : u32 { - GetFirmwareVersion = 0x00020000, - ReadId = 0x00020100, - JoyPolling = 0x00020101, - Unknown1 = 0x00020104, - c20105 = 0x00020105, - Unknown2 = 0x00020204, - Unknown3 = 0x00020304, - Unknown4 = 0x00020404, - ReadUnkCal = 0x00020504, - ReadFactoryCal = 0x00020A04, - Unknown5 = 0x00021104, - Unknown6 = 0x00021204, - Unknown7 = 0x00021304, - ReadUserCal = 0x00021A04, - ReadRepCount = 0x00023104, - ReadTotalPushCount = 0x00023204, - ResetRepCount = 0x04013104, - Unknown8 = 0x04011104, - Unknown9 = 0x04011204, - Unknown10 = 0x04011304, - SaveCalData = 0x10011A04, - Error = 0xFFFFFFFF, - }; - - enum class DataValid : u32 { - Valid, - BadCRC, - Cal, - }; - - struct FirmwareVersion { - u8 sub; - u8 main; - }; - static_assert(sizeof(FirmwareVersion) == 0x2, "FirmwareVersion is an invalid size"); - - struct FactoryCalibration { - s32_le os_max; - s32_le hk_max; - s32_le zero_min; - s32_le zero_max; - }; - static_assert(sizeof(FactoryCalibration) == 0x10, "FactoryCalibration is an invalid size"); - - struct CalibrationValue { - s16 value; - u16 crc; - }; - static_assert(sizeof(CalibrationValue) == 0x4, "CalibrationValue is an invalid size"); - - struct UserCalibration { - CalibrationValue os_max; - CalibrationValue hk_max; - CalibrationValue zero; - }; - static_assert(sizeof(UserCalibration) == 0xC, "UserCalibration is an invalid size"); - - struct SaveCalData { - RingConCommands command; - UserCalibration calibration; - INSERT_PADDING_BYTES_NOINIT(4); - }; - static_assert(sizeof(SaveCalData) == 0x14, "SaveCalData is an invalid size"); - static_assert(std::is_trivially_copyable_v<SaveCalData>, - "SaveCalData must be trivially copyable"); - - struct FirmwareVersionReply { - DataValid status; - FirmwareVersion firmware; - INSERT_PADDING_BYTES(0x2); - }; - static_assert(sizeof(FirmwareVersionReply) == 0x8, "FirmwareVersionReply is an invalid size"); - - struct Cmd020105Reply { - DataValid status; - u8 data; - INSERT_PADDING_BYTES(0x3); - }; - static_assert(sizeof(Cmd020105Reply) == 0x8, "Cmd020105Reply is an invalid size"); - - struct StatusReply { - DataValid status; - }; - static_assert(sizeof(StatusReply) == 0x4, "StatusReply is an invalid size"); - - struct GetThreeByteReply { - DataValid status; - std::array<u8, 3> data; - u8 crc; - }; - static_assert(sizeof(GetThreeByteReply) == 0x8, "GetThreeByteReply is an invalid size"); - - struct ReadUnkCalReply { - DataValid status; - u16 data; - INSERT_PADDING_BYTES(0x2); - }; - static_assert(sizeof(ReadUnkCalReply) == 0x8, "ReadUnkCalReply is an invalid size"); - - struct ReadFactoryCalReply { - DataValid status; - FactoryCalibration calibration; - }; - static_assert(sizeof(ReadFactoryCalReply) == 0x14, "ReadFactoryCalReply is an invalid size"); - - struct ReadUserCalReply { - DataValid status; - UserCalibration calibration; - INSERT_PADDING_BYTES(0x4); - }; - static_assert(sizeof(ReadUserCalReply) == 0x14, "ReadUserCalReply is an invalid size"); - - struct ReadIdReply { - DataValid status; - u16 id_l_x0; - u16 id_l_x0_2; - u16 id_l_x4; - u16 id_h_x0; - u16 id_h_x0_2; - u16 id_h_x4; - }; - static_assert(sizeof(ReadIdReply) == 0x10, "ReadIdReply is an invalid size"); - - struct ErrorReply { - DataValid status; - INSERT_PADDING_BYTES(0x3); - }; - static_assert(sizeof(ErrorReply) == 0x8, "ErrorReply is an invalid size"); - - struct RingConData { - DataValid status; - s16_le data; - INSERT_PADDING_BYTES(0x2); - }; - static_assert(sizeof(RingConData) == 0x8, "RingConData is an invalid size"); - - // Returns RingConData struct with pressure sensor values - RingConData GetSensorValue() const; - - // Returns 8 byte reply with firmware version - std::vector<u8> GetFirmwareVersionReply() const; - - // Returns 16 byte reply with ID values - std::vector<u8> GetReadIdReply() const; - - // (STUBBED) Returns 8 byte reply - std::vector<u8> GetC020105Reply() const; - - // (STUBBED) Returns 8 byte empty reply - std::vector<u8> GetReadUnkCalReply() const; - - // Returns 20 byte reply with factory calibration values - std::vector<u8> GetReadFactoryCalReply() const; - - // Returns 20 byte reply with user calibration values - std::vector<u8> GetReadUserCalReply() const; - - // Returns 8 byte reply - std::vector<u8> GetReadRepCountReply() const; - - // Returns 8 byte reply - std::vector<u8> GetReadTotalPushCountReply() const; - - // Returns 8 byte reply - std::vector<u8> GetResetRepCountReply() const; - - // Returns 4 byte save data reply - std::vector<u8> GetSaveDataReply() const; - - // Returns 8 byte error reply - std::vector<u8> GetErrorReply() const; - - // Returns 8 bit redundancy check from provided data - u8 GetCrcValue(const std::vector<u8>& data) const; - - // Converts structs to an u8 vector equivalent - template <typename T> - std::vector<u8> GetDataVector(const T& reply) const; - - RingConCommands command{RingConCommands::Error}; - - // These counters are used in multitasking mode while the switch is sleeping - // Total steps taken - u8 total_rep_count = 0; - // Total times the ring was pushed - u8 total_push_count = 0; - - const u8 device_id = 0x20; - const FirmwareVersion version = { - .sub = 0x0, - .main = 0x2c, - }; - const FactoryCalibration factory_calibration = { - .os_max = idle_value + range + idle_deadzone, - .hk_max = idle_value - range - idle_deadzone, - .zero_min = idle_value - idle_deadzone, - .zero_max = idle_value + idle_deadzone, - }; - UserCalibration user_calibration = { - .os_max = {.value = range, .crc = 228}, - .hk_max = {.value = -range, .crc = 239}, - .zero = {.value = idle_value, .crc = 225}, - }; - - Core::HID::EmulatedController* input; -}; -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus/starlink.cpp b/src/core/hle/service/hid/hidbus/starlink.cpp deleted file mode 100644 index 36573274e..000000000 --- a/src/core/hle/service/hid/hidbus/starlink.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/hidbus/starlink.h" - -namespace Service::HID { -constexpr u8 DEVICE_ID = 0x28; - -Starlink::Starlink(Core::System& system_, KernelHelpers::ServiceContext& service_context_) - : HidbusBase(system_, service_context_) {} -Starlink::~Starlink() = default; - -void Starlink::OnInit() { - return; -} - -void Starlink::OnRelease() { - return; -}; - -void Starlink::OnUpdate() { - if (!is_activated) { - return; - } - if (!device_enabled) { - return; - } - if (!polling_mode_enabled || transfer_memory == 0) { - return; - } - - LOG_ERROR(Service_HID, "Polling mode not supported {}", polling_mode); -} - -u8 Starlink::GetDeviceId() const { - return DEVICE_ID; -} - -std::vector<u8> Starlink::GetReply() const { - return {}; -} - -bool Starlink::SetCommand(std::span<const u8> data) { - LOG_ERROR(Service_HID, "Command not implemented"); - return false; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus/starlink.h b/src/core/hle/service/hid/hidbus/starlink.h deleted file mode 100644 index a276aa88f..000000000 --- a/src/core/hle/service/hid/hidbus/starlink.h +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "core/hle/service/hid/hidbus/hidbus_base.h" - -namespace Core::HID { -class EmulatedController; -} // namespace Core::HID - -namespace Service::HID { - -class Starlink final : public HidbusBase { -public: - explicit Starlink(Core::System& system_, KernelHelpers::ServiceContext& service_context_); - ~Starlink() override; - - void OnInit() override; - - void OnRelease() override; - - // Updates ringcon transfer memory - void OnUpdate() override; - - // Returns the device ID of the joycon - u8 GetDeviceId() const override; - - // Assigns a command from data - bool SetCommand(std::span<const u8> data) override; - - // Returns a reply from a command - std::vector<u8> GetReply() const override; -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus/stubbed.cpp b/src/core/hle/service/hid/hidbus/stubbed.cpp deleted file mode 100644 index 8160b7218..000000000 --- a/src/core/hle/service/hid/hidbus/stubbed.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/hidbus/stubbed.h" - -namespace Service::HID { -constexpr u8 DEVICE_ID = 0xFF; - -HidbusStubbed::HidbusStubbed(Core::System& system_, KernelHelpers::ServiceContext& service_context_) - : HidbusBase(system_, service_context_) {} -HidbusStubbed::~HidbusStubbed() = default; - -void HidbusStubbed::OnInit() { - return; -} - -void HidbusStubbed::OnRelease() { - return; -}; - -void HidbusStubbed::OnUpdate() { - if (!is_activated) { - return; - } - if (!device_enabled) { - return; - } - if (!polling_mode_enabled || transfer_memory == 0) { - return; - } - - LOG_ERROR(Service_HID, "Polling mode not supported {}", polling_mode); -} - -u8 HidbusStubbed::GetDeviceId() const { - return DEVICE_ID; -} - -std::vector<u8> HidbusStubbed::GetReply() const { - return {}; -} - -bool HidbusStubbed::SetCommand(std::span<const u8> data) { - LOG_ERROR(Service_HID, "Command not implemented"); - return false; -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus/stubbed.h b/src/core/hle/service/hid/hidbus/stubbed.h deleted file mode 100644 index 2e58d42fc..000000000 --- a/src/core/hle/service/hid/hidbus/stubbed.h +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "core/hle/service/hid/hidbus/hidbus_base.h" - -namespace Core::HID { -class EmulatedController; -} // namespace Core::HID - -namespace Service::HID { - -class HidbusStubbed final : public HidbusBase { -public: - explicit HidbusStubbed(Core::System& system_, KernelHelpers::ServiceContext& service_context_); - ~HidbusStubbed() override; - - void OnInit() override; - - void OnRelease() override; - - // Updates ringcon transfer memory - void OnUpdate() override; - - // Returns the device ID of the joycon - u8 GetDeviceId() const override; - - // Assigns a command from data - bool SetCommand(std::span<const u8> data) override; - - // Returns a reply from a command - std::vector<u8> GetReply() const override; -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 05ed31273..18e544f2f 100644 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp @@ -6,22 +6,22 @@ #include "core/core.h" #include "core/core_timing.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/service/hid/errors.h" -#include "core/hle/service/hid/hid_util.h" #include "core/hle/service/hid/irs.h" -#include "core/hle/service/hid/irsensor/clustering_processor.h" -#include "core/hle/service/hid/irsensor/image_transfer_processor.h" -#include "core/hle/service/hid/irsensor/ir_led_processor.h" -#include "core/hle/service/hid/irsensor/moment_processor.h" -#include "core/hle/service/hid/irsensor/pointing_processor.h" -#include "core/hle/service/hid/irsensor/tera_plugin_processor.h" #include "core/hle/service/ipc_helpers.h" #include "core/memory.h" +#include "hid_core/frontend/emulated_controller.h" +#include "hid_core/hid_core.h" +#include "hid_core/hid_result.h" +#include "hid_core/hid_util.h" +#include "hid_core/irsensor/clustering_processor.h" +#include "hid_core/irsensor/image_transfer_processor.h" +#include "hid_core/irsensor/ir_led_processor.h" +#include "hid_core/irsensor/moment_processor.h" +#include "hid_core/irsensor/pointing_processor.h" +#include "hid_core/irsensor/tera_plugin_processor.h" namespace Service::IRS { diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index c8e6dab17..06b7279ee 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h @@ -4,10 +4,10 @@ #pragma once #include "core/core.h" -#include "core/hid/hid_types.h" -#include "core/hid/irs_types.h" -#include "core/hle/service/hid/irsensor/processor_base.h" #include "core/hle/service/service.h" +#include "hid_core/hid_types.h" +#include "hid_core/irsensor/irs_types.h" +#include "hid_core/irsensor/processor_base.h" namespace Core::HID { class EmulatedController; diff --git a/src/core/hle/service/hid/irs_ring_lifo.h b/src/core/hle/service/hid/irs_ring_lifo.h deleted file mode 100644 index 255d1d296..000000000 --- a/src/core/hle/service/hid/irs_ring_lifo.h +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include <array> - -#include "common/common_types.h" - -namespace Service::IRS { - -template <typename State, std::size_t max_buffer_size> -struct Lifo { - s64 sampling_number{}; - s64 buffer_count{}; - std::array<State, max_buffer_size> entries{}; - - const State& ReadCurrentEntry() const { - return entries[GetBufferTail()]; - } - - const State& ReadPreviousEntry() const { - return entries[GetPreviousEntryIndex()]; - } - - s64 GetBufferTail() const { - return sampling_number % max_buffer_size; - } - - std::size_t GetPreviousEntryIndex() const { - return static_cast<size_t>((GetBufferTail() + max_buffer_size - 1) % max_buffer_size); - } - - std::size_t GetNextEntryIndex() const { - return static_cast<size_t>((GetBufferTail() + 1) % max_buffer_size); - } - - void WriteNextEntry(const State& new_state) { - if (buffer_count < static_cast<s64>(max_buffer_size)) { - buffer_count++; - } - sampling_number++; - entries[GetBufferTail()] = new_state; - } -}; - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.cpp b/src/core/hle/service/hid/irsensor/clustering_processor.cpp deleted file mode 100644 index c559eb0d5..000000000 --- a/src/core/hle/service/hid/irsensor/clustering_processor.cpp +++ /dev/null @@ -1,267 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include <queue> - -#include "core/core.h" -#include "core/core_timing.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/irsensor/clustering_processor.h" - -namespace Service::IRS { -ClusteringProcessor::ClusteringProcessor(Core::System& system_, - Core::IrSensor::DeviceFormat& device_format, - std::size_t npad_index) - : device{device_format}, system{system_} { - npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index); - - device.mode = Core::IrSensor::IrSensorMode::ClusteringProcessor; - device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped; - SetDefaultConfig(); - - shared_memory = std::construct_at( - reinterpret_cast<ClusteringSharedMemory*>(&device_format.state.processor_raw_data)); - - Core::HID::ControllerUpdateCallback engine_callback{ - .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); }, - .is_npad_service = true, - }; - callback_key = npad_device->SetCallback(engine_callback); -} - -ClusteringProcessor::~ClusteringProcessor() { - npad_device->DeleteCallback(callback_key); -}; - -void ClusteringProcessor::StartProcessor() { - device.camera_status = Core::IrSensor::IrCameraStatus::Available; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready; -} - -void ClusteringProcessor::SuspendProcessor() {} - -void ClusteringProcessor::StopProcessor() {} - -void ClusteringProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) { - if (type != Core::HID::ControllerTriggerType::IrSensor) { - return; - } - - next_state = {}; - const auto& camera_data = npad_device->GetCamera(); - auto filtered_image = camera_data.data; - - RemoveLowIntensityData(filtered_image); - - const auto window_start_x = static_cast<std::size_t>(current_config.window_of_interest.x); - const auto window_start_y = static_cast<std::size_t>(current_config.window_of_interest.y); - const auto window_end_x = - window_start_x + static_cast<std::size_t>(current_config.window_of_interest.width); - const auto window_end_y = - window_start_y + static_cast<std::size_t>(current_config.window_of_interest.height); - - for (std::size_t y = window_start_y; y < window_end_y; y++) { - for (std::size_t x = window_start_x; x < window_end_x; x++) { - u8 pixel = GetPixel(filtered_image, x, y); - if (pixel == 0) { - continue; - } - const auto cluster = GetClusterProperties(filtered_image, x, y); - if (cluster.pixel_count > current_config.pixel_count_max) { - continue; - } - if (cluster.pixel_count < current_config.pixel_count_min) { - continue; - } - // Cluster object limit reached - if (next_state.object_count >= next_state.data.size()) { - continue; - } - next_state.data[next_state.object_count] = cluster; - next_state.object_count++; - } - } - - next_state.sampling_number = camera_data.sample; - next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count(); - next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; - shared_memory->clustering_lifo.WriteNextEntry(next_state); - - if (!IsProcessorActive()) { - StartProcessor(); - } -} - -void ClusteringProcessor::RemoveLowIntensityData(std::vector<u8>& data) { - for (u8& pixel : data) { - if (pixel < current_config.pixel_count_min) { - pixel = 0; - } - } -} - -ClusteringProcessor::ClusteringData ClusteringProcessor::GetClusterProperties(std::vector<u8>& data, - std::size_t x, - std::size_t y) { - using DataPoint = Common::Point<std::size_t>; - std::queue<DataPoint> search_points{}; - ClusteringData current_cluster = GetPixelProperties(data, x, y); - SetPixel(data, x, y, 0); - search_points.emplace<DataPoint>({x, y}); - - while (!search_points.empty()) { - const auto point = search_points.front(); - search_points.pop(); - - // Avoid negative numbers - if (point.x == 0 || point.y == 0) { - continue; - } - - std::array<DataPoint, 4> new_points{ - DataPoint{point.x - 1, point.y}, - {point.x, point.y - 1}, - {point.x + 1, point.y}, - {point.x, point.y + 1}, - }; - - for (const auto new_point : new_points) { - if (new_point.x >= width) { - continue; - } - if (new_point.y >= height) { - continue; - } - if (GetPixel(data, new_point.x, new_point.y) < current_config.object_intensity_min) { - continue; - } - const ClusteringData cluster = GetPixelProperties(data, new_point.x, new_point.y); - current_cluster = MergeCluster(current_cluster, cluster); - SetPixel(data, new_point.x, new_point.y, 0); - search_points.emplace<DataPoint>({new_point.x, new_point.y}); - } - } - - return current_cluster; -} - -ClusteringProcessor::ClusteringData ClusteringProcessor::GetPixelProperties( - const std::vector<u8>& data, std::size_t x, std::size_t y) const { - return { - .average_intensity = GetPixel(data, x, y) / 255.0f, - .centroid = - { - .x = static_cast<f32>(x), - .y = static_cast<f32>(y), - - }, - .pixel_count = 1, - .bound = - { - .x = static_cast<s16>(x), - .y = static_cast<s16>(y), - .width = 1, - .height = 1, - }, - }; -} - -ClusteringProcessor::ClusteringData ClusteringProcessor::MergeCluster( - const ClusteringData a, const ClusteringData b) const { - const f32 a_pixel_count = static_cast<f32>(a.pixel_count); - const f32 b_pixel_count = static_cast<f32>(b.pixel_count); - const f32 pixel_count = a_pixel_count + b_pixel_count; - const f32 average_intensity = - (a.average_intensity * a_pixel_count + b.average_intensity * b_pixel_count) / pixel_count; - const Core::IrSensor::IrsCentroid centroid = { - .x = (a.centroid.x * a_pixel_count + b.centroid.x * b_pixel_count) / pixel_count, - .y = (a.centroid.y * a_pixel_count + b.centroid.y * b_pixel_count) / pixel_count, - }; - s16 bound_start_x = a.bound.x < b.bound.x ? a.bound.x : b.bound.x; - s16 bound_start_y = a.bound.y < b.bound.y ? a.bound.y : b.bound.y; - s16 a_bound_end_x = a.bound.x + a.bound.width; - s16 a_bound_end_y = a.bound.y + a.bound.height; - s16 b_bound_end_x = b.bound.x + b.bound.width; - s16 b_bound_end_y = b.bound.y + b.bound.height; - - const Core::IrSensor::IrsRect bound = { - .x = bound_start_x, - .y = bound_start_y, - .width = a_bound_end_x > b_bound_end_x ? static_cast<s16>(a_bound_end_x - bound_start_x) - : static_cast<s16>(b_bound_end_x - bound_start_x), - .height = a_bound_end_y > b_bound_end_y ? static_cast<s16>(a_bound_end_y - bound_start_y) - : static_cast<s16>(b_bound_end_y - bound_start_y), - }; - - return { - .average_intensity = average_intensity, - .centroid = centroid, - .pixel_count = static_cast<u32>(pixel_count), - .bound = bound, - }; -} - -u8 ClusteringProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const { - if ((y * width) + x >= data.size()) { - return 0; - } - return data[(y * width) + x]; -} - -void ClusteringProcessor::SetPixel(std::vector<u8>& data, std::size_t x, std::size_t y, u8 value) { - if ((y * width) + x >= data.size()) { - return; - } - data[(y * width) + x] = value; -} - -void ClusteringProcessor::SetDefaultConfig() { - using namespace std::literals::chrono_literals; - current_config.camera_config.exposure_time = std::chrono::microseconds(200ms).count(); - current_config.camera_config.gain = 2; - current_config.camera_config.is_negative_used = false; - current_config.camera_config.light_target = Core::IrSensor::CameraLightTarget::BrightLeds; - current_config.window_of_interest = { - .x = 0, - .y = 0, - .width = width, - .height = height, - }; - current_config.pixel_count_min = 3; - current_config.pixel_count_max = static_cast<u32>(GetDataSize(format)); - current_config.is_external_light_filter_enabled = true; - current_config.object_intensity_min = 150; - - npad_device->SetCameraFormat(format); -} - -void ClusteringProcessor::SetConfig(Core::IrSensor::PackedClusteringProcessorConfig config) { - current_config.camera_config.exposure_time = config.camera_config.exposure_time; - current_config.camera_config.gain = config.camera_config.gain; - current_config.camera_config.is_negative_used = config.camera_config.is_negative_used; - current_config.camera_config.light_target = - static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target); - current_config.window_of_interest = config.window_of_interest; - current_config.pixel_count_min = config.pixel_count_min; - current_config.pixel_count_max = config.pixel_count_max; - current_config.is_external_light_filter_enabled = config.is_external_light_filter_enabled; - current_config.object_intensity_min = config.object_intensity_min; - - LOG_INFO(Service_IRS, - "Processor config, exposure_time={}, gain={}, is_negative_used={}, " - "light_target={}, window_of_interest=({}, {}, {}, {}), pixel_count_min={}, " - "pixel_count_max={}, is_external_light_filter_enabled={}, object_intensity_min={}", - current_config.camera_config.exposure_time, current_config.camera_config.gain, - current_config.camera_config.is_negative_used, - current_config.camera_config.light_target, current_config.window_of_interest.x, - current_config.window_of_interest.y, current_config.window_of_interest.width, - current_config.window_of_interest.height, current_config.pixel_count_min, - current_config.pixel_count_max, current_config.is_external_light_filter_enabled, - current_config.object_intensity_min); - - npad_device->SetCameraFormat(format); -} - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/clustering_processor.h b/src/core/hle/service/hid/irsensor/clustering_processor.h deleted file mode 100644 index 83f34734a..000000000 --- a/src/core/hle/service/hid/irsensor/clustering_processor.h +++ /dev/null @@ -1,115 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "core/hid/irs_types.h" -#include "core/hle/service/hid/irs_ring_lifo.h" -#include "core/hle/service/hid/irsensor/processor_base.h" - -namespace Core { -class System; -} - -namespace Core::HID { -class EmulatedController; -} // namespace Core::HID - -namespace Service::IRS { -class ClusteringProcessor final : public ProcessorBase { -public: - explicit ClusteringProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format, - std::size_t npad_index); - ~ClusteringProcessor() override; - - // Called when the processor is initialized - void StartProcessor() override; - - // Called when the processor is suspended - void SuspendProcessor() override; - - // Called when the processor is stopped - void StopProcessor() override; - - // Sets config parameters of the camera - void SetConfig(Core::IrSensor::PackedClusteringProcessorConfig config); - -private: - static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Size320x240; - static constexpr std::size_t width = 320; - static constexpr std::size_t height = 240; - - // This is nn::irsensor::ClusteringProcessorConfig - struct ClusteringProcessorConfig { - Core::IrSensor::CameraConfig camera_config; - Core::IrSensor::IrsRect window_of_interest; - u32 pixel_count_min; - u32 pixel_count_max; - u32 object_intensity_min; - bool is_external_light_filter_enabled; - INSERT_PADDING_BYTES(3); - }; - static_assert(sizeof(ClusteringProcessorConfig) == 0x30, - "ClusteringProcessorConfig is an invalid size"); - - // This is nn::irsensor::AdaptiveClusteringProcessorConfig - struct AdaptiveClusteringProcessorConfig { - Core::IrSensor::AdaptiveClusteringMode mode; - Core::IrSensor::AdaptiveClusteringTargetDistance target_distance; - }; - static_assert(sizeof(AdaptiveClusteringProcessorConfig) == 0x8, - "AdaptiveClusteringProcessorConfig is an invalid size"); - - // This is nn::irsensor::ClusteringData - struct ClusteringData { - f32 average_intensity; - Core::IrSensor::IrsCentroid centroid; - u32 pixel_count; - Core::IrSensor::IrsRect bound; - }; - static_assert(sizeof(ClusteringData) == 0x18, "ClusteringData is an invalid size"); - - // This is nn::irsensor::ClusteringProcessorState - struct ClusteringProcessorState { - s64 sampling_number; - u64 timestamp; - u8 object_count; - INSERT_PADDING_BYTES(3); - Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level; - std::array<ClusteringData, 0x10> data; - }; - static_assert(sizeof(ClusteringProcessorState) == 0x198, - "ClusteringProcessorState is an invalid size"); - - struct ClusteringSharedMemory { - Service::IRS::Lifo<ClusteringProcessorState, 6> clustering_lifo; - static_assert(sizeof(clustering_lifo) == 0x9A0, "clustering_lifo is an invalid size"); - INSERT_PADDING_WORDS(0x11F); - }; - static_assert(sizeof(ClusteringSharedMemory) == 0xE20, - "ClusteringSharedMemory is an invalid size"); - - void OnControllerUpdate(Core::HID::ControllerTriggerType type); - void RemoveLowIntensityData(std::vector<u8>& data); - ClusteringData GetClusterProperties(std::vector<u8>& data, std::size_t x, std::size_t y); - ClusteringData GetPixelProperties(const std::vector<u8>& data, std::size_t x, - std::size_t y) const; - ClusteringData MergeCluster(const ClusteringData a, const ClusteringData b) const; - u8 GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const; - void SetPixel(std::vector<u8>& data, std::size_t x, std::size_t y, u8 value); - - // Sets config parameters of the camera - void SetDefaultConfig(); - - ClusteringSharedMemory* shared_memory = nullptr; - ClusteringProcessorState next_state{}; - - ClusteringProcessorConfig current_config{}; - Core::IrSensor::DeviceFormat& device; - Core::HID::EmulatedController* npad_device; - int callback_key{}; - - Core::System& system; -}; -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp b/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp deleted file mode 100644 index 22067a591..000000000 --- a/src/core/hle/service/hid/irsensor/image_transfer_processor.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/core.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/irsensor/image_transfer_processor.h" -#include "core/memory.h" - -namespace Service::IRS { -ImageTransferProcessor::ImageTransferProcessor(Core::System& system_, - Core::IrSensor::DeviceFormat& device_format, - std::size_t npad_index) - : device{device_format}, system{system_} { - npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index); - - Core::HID::ControllerUpdateCallback engine_callback{ - .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); }, - .is_npad_service = true, - }; - callback_key = npad_device->SetCallback(engine_callback); - - device.mode = Core::IrSensor::IrSensorMode::ImageTransferProcessor; - device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped; -} - -ImageTransferProcessor::~ImageTransferProcessor() { - npad_device->DeleteCallback(callback_key); -}; - -void ImageTransferProcessor::StartProcessor() { - is_active = true; - device.camera_status = Core::IrSensor::IrCameraStatus::Available; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready; - processor_state.sampling_number = 0; - processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; -} - -void ImageTransferProcessor::SuspendProcessor() {} - -void ImageTransferProcessor::StopProcessor() {} - -void ImageTransferProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) { - if (type != Core::HID::ControllerTriggerType::IrSensor) { - return; - } - if (transfer_memory == 0) { - return; - } - - const auto& camera_data = npad_device->GetCamera(); - - // This indicates how much ambient light is present - processor_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; - processor_state.sampling_number = camera_data.sample; - - if (camera_data.format != current_config.origin_format) { - LOG_WARNING(Service_IRS, "Wrong Input format {} expected {}", camera_data.format, - current_config.origin_format); - system.ApplicationMemory().ZeroBlock(transfer_memory, - GetDataSize(current_config.trimming_format)); - return; - } - - if (current_config.origin_format > current_config.trimming_format) { - LOG_WARNING(Service_IRS, "Origin format {} is smaller than trimming format {}", - current_config.origin_format, current_config.trimming_format); - system.ApplicationMemory().ZeroBlock(transfer_memory, - GetDataSize(current_config.trimming_format)); - return; - } - - std::vector<u8> window_data{}; - const auto origin_width = GetDataWidth(current_config.origin_format); - const auto origin_height = GetDataHeight(current_config.origin_format); - const auto trimming_width = GetDataWidth(current_config.trimming_format); - const auto trimming_height = GetDataHeight(current_config.trimming_format); - window_data.resize(GetDataSize(current_config.trimming_format)); - - if (trimming_width + current_config.trimming_start_x > origin_width || - trimming_height + current_config.trimming_start_y > origin_height) { - LOG_WARNING(Service_IRS, - "Trimming area ({}, {}, {}, {}) is outside of origin area ({}, {})", - current_config.trimming_start_x, current_config.trimming_start_y, - trimming_width, trimming_height, origin_width, origin_height); - system.ApplicationMemory().ZeroBlock(transfer_memory, - GetDataSize(current_config.trimming_format)); - return; - } - - for (std::size_t y = 0; y < trimming_height; y++) { - for (std::size_t x = 0; x < trimming_width; x++) { - const std::size_t window_index = (y * trimming_width) + x; - const std::size_t origin_index = - ((y + current_config.trimming_start_y) * origin_width) + x + - current_config.trimming_start_x; - window_data[window_index] = camera_data.data[origin_index]; - } - } - - system.ApplicationMemory().WriteBlock(transfer_memory, window_data.data(), - GetDataSize(current_config.trimming_format)); - - if (!IsProcessorActive()) { - StartProcessor(); - } -} - -void ImageTransferProcessor::SetConfig(Core::IrSensor::PackedImageTransferProcessorConfig config) { - current_config.camera_config.exposure_time = config.camera_config.exposure_time; - current_config.camera_config.gain = config.camera_config.gain; - current_config.camera_config.is_negative_used = config.camera_config.is_negative_used; - current_config.camera_config.light_target = - static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target); - current_config.origin_format = - static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.format); - current_config.trimming_format = - static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.format); - current_config.trimming_start_x = 0; - current_config.trimming_start_y = 0; - - npad_device->SetCameraFormat(current_config.origin_format); -} - -void ImageTransferProcessor::SetConfig( - Core::IrSensor::PackedImageTransferProcessorExConfig config) { - current_config.camera_config.exposure_time = config.camera_config.exposure_time; - current_config.camera_config.gain = config.camera_config.gain; - current_config.camera_config.is_negative_used = config.camera_config.is_negative_used; - current_config.camera_config.light_target = - static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target); - current_config.origin_format = - static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.origin_format); - current_config.trimming_format = - static_cast<Core::IrSensor::ImageTransferProcessorFormat>(config.trimming_format); - current_config.trimming_start_x = config.trimming_start_x; - current_config.trimming_start_y = config.trimming_start_y; - - npad_device->SetCameraFormat(current_config.origin_format); -} - -void ImageTransferProcessor::SetTransferMemoryAddress(Common::ProcessAddress t_mem) { - transfer_memory = t_mem; -} - -Core::IrSensor::ImageTransferProcessorState ImageTransferProcessor::GetState( - std::vector<u8>& data) const { - const auto size = GetDataSize(current_config.trimming_format); - data.resize(size); - system.ApplicationMemory().ReadBlock(transfer_memory, data.data(), size); - return processor_state; -} - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/image_transfer_processor.h b/src/core/hle/service/hid/irsensor/image_transfer_processor.h deleted file mode 100644 index 7f42d8453..000000000 --- a/src/core/hle/service/hid/irsensor/image_transfer_processor.h +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/typed_address.h" -#include "core/hid/irs_types.h" -#include "core/hle/service/hid/irsensor/processor_base.h" - -namespace Core { -class System; -} - -namespace Core::HID { -class EmulatedController; -} // namespace Core::HID - -namespace Service::IRS { -class ImageTransferProcessor final : public ProcessorBase { -public: - explicit ImageTransferProcessor(Core::System& system_, - Core::IrSensor::DeviceFormat& device_format, - std::size_t npad_index); - ~ImageTransferProcessor() override; - - // Called when the processor is initialized - void StartProcessor() override; - - // Called when the processor is suspended - void SuspendProcessor() override; - - // Called when the processor is stopped - void StopProcessor() override; - - // Sets config parameters of the camera - void SetConfig(Core::IrSensor::PackedImageTransferProcessorConfig config); - void SetConfig(Core::IrSensor::PackedImageTransferProcessorExConfig config); - - // Transfer memory where the image data will be stored - void SetTransferMemoryAddress(Common::ProcessAddress t_mem); - - Core::IrSensor::ImageTransferProcessorState GetState(std::vector<u8>& data) const; - -private: - // This is nn::irsensor::ImageTransferProcessorConfig - struct ImageTransferProcessorConfig { - Core::IrSensor::CameraConfig camera_config; - Core::IrSensor::ImageTransferProcessorFormat format; - }; - static_assert(sizeof(ImageTransferProcessorConfig) == 0x20, - "ImageTransferProcessorConfig is an invalid size"); - - // This is nn::irsensor::ImageTransferProcessorExConfig - struct ImageTransferProcessorExConfig { - Core::IrSensor::CameraConfig camera_config; - Core::IrSensor::ImageTransferProcessorFormat origin_format; - Core::IrSensor::ImageTransferProcessorFormat trimming_format; - u16 trimming_start_x; - u16 trimming_start_y; - bool is_external_light_filter_enabled; - INSERT_PADDING_BYTES(3); - }; - static_assert(sizeof(ImageTransferProcessorExConfig) == 0x28, - "ImageTransferProcessorExConfig is an invalid size"); - - void OnControllerUpdate(Core::HID::ControllerTriggerType type); - - ImageTransferProcessorExConfig current_config{}; - Core::IrSensor::ImageTransferProcessorState processor_state{}; - Core::IrSensor::DeviceFormat& device; - Core::HID::EmulatedController* npad_device; - int callback_key{}; - - Core::System& system; - Common::ProcessAddress transfer_memory{}; -}; -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/ir_led_processor.cpp b/src/core/hle/service/hid/irsensor/ir_led_processor.cpp deleted file mode 100644 index 8e6dd99e4..000000000 --- a/src/core/hle/service/hid/irsensor/ir_led_processor.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/hle/service/hid/irsensor/ir_led_processor.h" - -namespace Service::IRS { -IrLedProcessor::IrLedProcessor(Core::IrSensor::DeviceFormat& device_format) - : device(device_format) { - device.mode = Core::IrSensor::IrSensorMode::IrLedProcessor; - device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped; -} - -IrLedProcessor::~IrLedProcessor() = default; - -void IrLedProcessor::StartProcessor() {} - -void IrLedProcessor::SuspendProcessor() {} - -void IrLedProcessor::StopProcessor() {} - -void IrLedProcessor::SetConfig(Core::IrSensor::PackedIrLedProcessorConfig config) { - current_config.light_target = - static_cast<Core::IrSensor::CameraLightTarget>(config.light_target); -} - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/ir_led_processor.h b/src/core/hle/service/hid/irsensor/ir_led_processor.h deleted file mode 100644 index c3d8693c9..000000000 --- a/src/core/hle/service/hid/irsensor/ir_led_processor.h +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/bit_field.h" -#include "common/common_types.h" -#include "core/hid/irs_types.h" -#include "core/hle/service/hid/irsensor/processor_base.h" - -namespace Service::IRS { -class IrLedProcessor final : public ProcessorBase { -public: - explicit IrLedProcessor(Core::IrSensor::DeviceFormat& device_format); - ~IrLedProcessor() override; - - // Called when the processor is initialized - void StartProcessor() override; - - // Called when the processor is suspended - void SuspendProcessor() override; - - // Called when the processor is stopped - void StopProcessor() override; - - // Sets config parameters of the camera - void SetConfig(Core::IrSensor::PackedIrLedProcessorConfig config); - -private: - // This is nn::irsensor::IrLedProcessorConfig - struct IrLedProcessorConfig { - Core::IrSensor::CameraLightTarget light_target; - }; - static_assert(sizeof(IrLedProcessorConfig) == 0x4, "IrLedProcessorConfig is an invalid size"); - - struct IrLedProcessorState { - s64 sampling_number; - u64 timestamp; - std::array<u8, 0x8> data; - }; - static_assert(sizeof(IrLedProcessorState) == 0x18, "IrLedProcessorState is an invalid size"); - - IrLedProcessorConfig current_config{}; - Core::IrSensor::DeviceFormat& device; -}; - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/moment_processor.cpp b/src/core/hle/service/hid/irsensor/moment_processor.cpp deleted file mode 100644 index cf045bda7..000000000 --- a/src/core/hle/service/hid/irsensor/moment_processor.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/core.h" -#include "core/core_timing.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hle/service/hid/irsensor/moment_processor.h" - -namespace Service::IRS { -static constexpr auto format = Core::IrSensor::ImageTransferProcessorFormat::Size40x30; -static constexpr std::size_t ImageWidth = 40; -static constexpr std::size_t ImageHeight = 30; - -MomentProcessor::MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format, - std::size_t npad_index) - : device(device_format), system{system_} { - npad_device = system.HIDCore().GetEmulatedControllerByIndex(npad_index); - - device.mode = Core::IrSensor::IrSensorMode::MomentProcessor; - device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped; - - shared_memory = std::construct_at( - reinterpret_cast<MomentSharedMemory*>(&device_format.state.processor_raw_data)); - - Core::HID::ControllerUpdateCallback engine_callback{ - .on_change = [this](Core::HID::ControllerTriggerType type) { OnControllerUpdate(type); }, - .is_npad_service = true, - }; - callback_key = npad_device->SetCallback(engine_callback); -} - -MomentProcessor::~MomentProcessor() { - npad_device->DeleteCallback(callback_key); -}; - -void MomentProcessor::StartProcessor() { - device.camera_status = Core::IrSensor::IrCameraStatus::Available; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Ready; -} - -void MomentProcessor::SuspendProcessor() {} - -void MomentProcessor::StopProcessor() {} - -void MomentProcessor::OnControllerUpdate(Core::HID::ControllerTriggerType type) { - if (type != Core::HID::ControllerTriggerType::IrSensor) { - return; - } - - next_state = {}; - const auto& camera_data = npad_device->GetCamera(); - - const auto window_width = static_cast<std::size_t>(current_config.window_of_interest.width); - const auto window_height = static_cast<std::size_t>(current_config.window_of_interest.height); - const auto window_start_x = static_cast<std::size_t>(current_config.window_of_interest.x); - const auto window_start_y = static_cast<std::size_t>(current_config.window_of_interest.y); - - const std::size_t block_width = window_width / Columns; - const std::size_t block_height = window_height / Rows; - - for (std::size_t row = 0; row < Rows; row++) { - for (std::size_t column = 0; column < Columns; column++) { - const size_t x_pos = (column * block_width) + window_start_x; - const size_t y_pos = (row * block_height) + window_start_y; - auto& statistic = next_state.statistic[column + (row * Columns)]; - statistic = GetStatistic(camera_data.data, x_pos, y_pos, block_width, block_height); - } - } - - next_state.sampling_number = camera_data.sample; - next_state.timestamp = system.CoreTiming().GetGlobalTimeNs().count(); - next_state.ambient_noise_level = Core::IrSensor::CameraAmbientNoiseLevel::Low; - shared_memory->moment_lifo.WriteNextEntry(next_state); - - if (!IsProcessorActive()) { - StartProcessor(); - } -} - -u8 MomentProcessor::GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const { - if ((y * ImageWidth) + x >= data.size()) { - return 0; - } - return data[(y * ImageWidth) + x]; -} - -MomentProcessor::MomentStatistic MomentProcessor::GetStatistic(const std::vector<u8>& data, - std::size_t start_x, - std::size_t start_y, - std::size_t width, - std::size_t height) const { - // The actual implementation is always 320x240 - static constexpr std::size_t RealWidth = 320; - static constexpr std::size_t RealHeight = 240; - static constexpr std::size_t Threshold = 30; - MomentStatistic statistic{}; - std::size_t active_points{}; - - // Sum all data points on the block that meet with the threshold - for (std::size_t y = 0; y < width; y++) { - for (std::size_t x = 0; x < height; x++) { - const size_t x_pos = x + start_x; - const size_t y_pos = y + start_y; - const auto pixel = - GetPixel(data, x_pos * ImageWidth / RealWidth, y_pos * ImageHeight / RealHeight); - - if (pixel < Threshold) { - continue; - } - - statistic.average_intensity += pixel; - - statistic.centroid.x += static_cast<float>(x_pos); - statistic.centroid.y += static_cast<float>(y_pos); - - active_points++; - } - } - - // Return an empty field if no points were available - if (active_points == 0) { - return {}; - } - - // Finally calculate the actual centroid and average intensity - statistic.centroid.x /= static_cast<float>(active_points); - statistic.centroid.y /= static_cast<float>(active_points); - statistic.average_intensity /= static_cast<f32>(width * height); - - return statistic; -} - -void MomentProcessor::SetConfig(Core::IrSensor::PackedMomentProcessorConfig config) { - current_config.camera_config.exposure_time = config.camera_config.exposure_time; - current_config.camera_config.gain = config.camera_config.gain; - current_config.camera_config.is_negative_used = config.camera_config.is_negative_used; - current_config.camera_config.light_target = - static_cast<Core::IrSensor::CameraLightTarget>(config.camera_config.light_target); - current_config.window_of_interest = config.window_of_interest; - current_config.preprocess = - static_cast<Core::IrSensor::MomentProcessorPreprocess>(config.preprocess); - current_config.preprocess_intensity_threshold = config.preprocess_intensity_threshold; - - npad_device->SetCameraFormat(format); -} - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/moment_processor.h b/src/core/hle/service/hid/irsensor/moment_processor.h deleted file mode 100644 index 398cfbdc1..000000000 --- a/src/core/hle/service/hid/irsensor/moment_processor.h +++ /dev/null @@ -1,91 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/bit_field.h" -#include "common/common_types.h" -#include "core/hid/irs_types.h" -#include "core/hle/service/hid/irs_ring_lifo.h" -#include "core/hle/service/hid/irsensor/processor_base.h" - -namespace Core { -class System; -} - -namespace Core::HID { -class EmulatedController; -} // namespace Core::HID - -namespace Service::IRS { -class MomentProcessor final : public ProcessorBase { -public: - explicit MomentProcessor(Core::System& system_, Core::IrSensor::DeviceFormat& device_format, - std::size_t npad_index); - ~MomentProcessor() override; - - // Called when the processor is initialized - void StartProcessor() override; - - // Called when the processor is suspended - void SuspendProcessor() override; - - // Called when the processor is stopped - void StopProcessor() override; - - // Sets config parameters of the camera - void SetConfig(Core::IrSensor::PackedMomentProcessorConfig config); - -private: - static constexpr std::size_t Columns = 8; - static constexpr std::size_t Rows = 6; - - // This is nn::irsensor::MomentProcessorConfig - struct MomentProcessorConfig { - Core::IrSensor::CameraConfig camera_config; - Core::IrSensor::IrsRect window_of_interest; - Core::IrSensor::MomentProcessorPreprocess preprocess; - u32 preprocess_intensity_threshold; - }; - static_assert(sizeof(MomentProcessorConfig) == 0x28, - "MomentProcessorConfig is an invalid size"); - - // This is nn::irsensor::MomentStatistic - struct MomentStatistic { - f32 average_intensity; - Core::IrSensor::IrsCentroid centroid; - }; - static_assert(sizeof(MomentStatistic) == 0xC, "MomentStatistic is an invalid size"); - - // This is nn::irsensor::MomentProcessorState - struct MomentProcessorState { - s64 sampling_number; - u64 timestamp; - Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level; - INSERT_PADDING_BYTES(4); - std::array<MomentStatistic, Columns * Rows> statistic; - }; - static_assert(sizeof(MomentProcessorState) == 0x258, "MomentProcessorState is an invalid size"); - - struct MomentSharedMemory { - Service::IRS::Lifo<MomentProcessorState, 6> moment_lifo; - }; - static_assert(sizeof(MomentSharedMemory) == 0xE20, "MomentSharedMemory is an invalid size"); - - void OnControllerUpdate(Core::HID::ControllerTriggerType type); - u8 GetPixel(const std::vector<u8>& data, std::size_t x, std::size_t y) const; - MomentStatistic GetStatistic(const std::vector<u8>& data, std::size_t start_x, - std::size_t start_y, std::size_t width, std::size_t height) const; - - MomentSharedMemory* shared_memory = nullptr; - MomentProcessorState next_state{}; - - MomentProcessorConfig current_config{}; - Core::IrSensor::DeviceFormat& device; - Core::HID::EmulatedController* npad_device; - int callback_key{}; - - Core::System& system; -}; - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.cpp b/src/core/hle/service/hid/irsensor/pointing_processor.cpp deleted file mode 100644 index 929f177fc..000000000 --- a/src/core/hle/service/hid/irsensor/pointing_processor.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/hle/service/hid/irsensor/pointing_processor.h" - -namespace Service::IRS { -PointingProcessor::PointingProcessor(Core::IrSensor::DeviceFormat& device_format) - : device(device_format) { - device.mode = Core::IrSensor::IrSensorMode::PointingProcessorMarker; - device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped; -} - -PointingProcessor::~PointingProcessor() = default; - -void PointingProcessor::StartProcessor() {} - -void PointingProcessor::SuspendProcessor() {} - -void PointingProcessor::StopProcessor() {} - -void PointingProcessor::SetConfig(Core::IrSensor::PackedPointingProcessorConfig config) { - current_config.window_of_interest = config.window_of_interest; -} - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.h b/src/core/hle/service/hid/irsensor/pointing_processor.h deleted file mode 100644 index d63423aff..000000000 --- a/src/core/hle/service/hid/irsensor/pointing_processor.h +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "core/hid/irs_types.h" -#include "core/hle/service/hid/irsensor/processor_base.h" - -namespace Service::IRS { -class PointingProcessor final : public ProcessorBase { -public: - explicit PointingProcessor(Core::IrSensor::DeviceFormat& device_format); - ~PointingProcessor() override; - - // Called when the processor is initialized - void StartProcessor() override; - - // Called when the processor is suspended - void SuspendProcessor() override; - - // Called when the processor is stopped - void StopProcessor() override; - - // Sets config parameters of the camera - void SetConfig(Core::IrSensor::PackedPointingProcessorConfig config); - -private: - // This is nn::irsensor::PointingProcessorConfig - struct PointingProcessorConfig { - Core::IrSensor::IrsRect window_of_interest; - }; - static_assert(sizeof(PointingProcessorConfig) == 0x8, - "PointingProcessorConfig is an invalid size"); - - struct PointingProcessorMarkerData { - u8 pointing_status; - INSERT_PADDING_BYTES(3); - u32 unknown; - float unknown_float1; - float position_x; - float position_y; - float unknown_float2; - Core::IrSensor::IrsRect window_of_interest; - }; - static_assert(sizeof(PointingProcessorMarkerData) == 0x20, - "PointingProcessorMarkerData is an invalid size"); - - struct PointingProcessorMarkerState { - s64 sampling_number; - u64 timestamp; - std::array<PointingProcessorMarkerData, 0x3> data; - }; - static_assert(sizeof(PointingProcessorMarkerState) == 0x70, - "PointingProcessorMarkerState is an invalid size"); - - PointingProcessorConfig current_config{}; - Core::IrSensor::DeviceFormat& device; -}; - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/processor_base.cpp b/src/core/hle/service/hid/irsensor/processor_base.cpp deleted file mode 100644 index 4d43ca17a..000000000 --- a/src/core/hle/service/hid/irsensor/processor_base.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/hle/service/hid/irsensor/processor_base.h" - -namespace Service::IRS { - -ProcessorBase::ProcessorBase() {} -ProcessorBase::~ProcessorBase() = default; - -bool ProcessorBase::IsProcessorActive() const { - return is_active; -} - -std::size_t ProcessorBase::GetDataSize(Core::IrSensor::ImageTransferProcessorFormat format) const { - switch (format) { - case Core::IrSensor::ImageTransferProcessorFormat::Size320x240: - return 320 * 240; - case Core::IrSensor::ImageTransferProcessorFormat::Size160x120: - return 160 * 120; - case Core::IrSensor::ImageTransferProcessorFormat::Size80x60: - return 80 * 60; - case Core::IrSensor::ImageTransferProcessorFormat::Size40x30: - return 40 * 30; - case Core::IrSensor::ImageTransferProcessorFormat::Size20x15: - return 20 * 15; - default: - return 0; - } -} - -std::size_t ProcessorBase::GetDataWidth(Core::IrSensor::ImageTransferProcessorFormat format) const { - switch (format) { - case Core::IrSensor::ImageTransferProcessorFormat::Size320x240: - return 320; - case Core::IrSensor::ImageTransferProcessorFormat::Size160x120: - return 160; - case Core::IrSensor::ImageTransferProcessorFormat::Size80x60: - return 80; - case Core::IrSensor::ImageTransferProcessorFormat::Size40x30: - return 40; - case Core::IrSensor::ImageTransferProcessorFormat::Size20x15: - return 20; - default: - return 0; - } -} - -std::size_t ProcessorBase::GetDataHeight( - Core::IrSensor::ImageTransferProcessorFormat format) const { - switch (format) { - case Core::IrSensor::ImageTransferProcessorFormat::Size320x240: - return 240; - case Core::IrSensor::ImageTransferProcessorFormat::Size160x120: - return 120; - case Core::IrSensor::ImageTransferProcessorFormat::Size80x60: - return 60; - case Core::IrSensor::ImageTransferProcessorFormat::Size40x30: - return 30; - case Core::IrSensor::ImageTransferProcessorFormat::Size20x15: - return 15; - default: - return 0; - } -} - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/processor_base.h b/src/core/hle/service/hid/irsensor/processor_base.h deleted file mode 100644 index bc0d2977b..000000000 --- a/src/core/hle/service/hid/irsensor/processor_base.h +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/common_types.h" -#include "core/hid/irs_types.h" - -namespace Service::IRS { -class ProcessorBase { -public: - explicit ProcessorBase(); - virtual ~ProcessorBase(); - - virtual void StartProcessor() = 0; - virtual void SuspendProcessor() = 0; - virtual void StopProcessor() = 0; - - bool IsProcessorActive() const; - -protected: - /// Returns the number of bytes the image uses - std::size_t GetDataSize(Core::IrSensor::ImageTransferProcessorFormat format) const; - - /// Returns the width of the image - std::size_t GetDataWidth(Core::IrSensor::ImageTransferProcessorFormat format) const; - - /// Returns the height of the image - std::size_t GetDataHeight(Core::IrSensor::ImageTransferProcessorFormat format) const; - - bool is_active{false}; -}; -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp b/src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp deleted file mode 100644 index e691c840a..000000000 --- a/src/core/hle/service/hid/irsensor/tera_plugin_processor.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "core/hle/service/hid/irsensor/tera_plugin_processor.h" - -namespace Service::IRS { -TeraPluginProcessor::TeraPluginProcessor(Core::IrSensor::DeviceFormat& device_format) - : device(device_format) { - device.mode = Core::IrSensor::IrSensorMode::TeraPluginProcessor; - device.camera_status = Core::IrSensor::IrCameraStatus::Unconnected; - device.camera_internal_status = Core::IrSensor::IrCameraInternalStatus::Stopped; -} - -TeraPluginProcessor::~TeraPluginProcessor() = default; - -void TeraPluginProcessor::StartProcessor() {} - -void TeraPluginProcessor::SuspendProcessor() {} - -void TeraPluginProcessor::StopProcessor() {} - -void TeraPluginProcessor::SetConfig(Core::IrSensor::PackedTeraPluginProcessorConfig config) { - current_config.mode = config.mode; - current_config.unknown_1 = config.unknown_1; - current_config.unknown_2 = config.unknown_2; - current_config.unknown_3 = config.unknown_3; -} - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/irsensor/tera_plugin_processor.h b/src/core/hle/service/hid/irsensor/tera_plugin_processor.h deleted file mode 100644 index bbea7ed0b..000000000 --- a/src/core/hle/service/hid/irsensor/tera_plugin_processor.h +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "common/bit_field.h" -#include "common/common_types.h" -#include "core/hid/irs_types.h" -#include "core/hle/service/hid/irsensor/processor_base.h" - -namespace Service::IRS { -class TeraPluginProcessor final : public ProcessorBase { -public: - explicit TeraPluginProcessor(Core::IrSensor::DeviceFormat& device_format); - ~TeraPluginProcessor() override; - - // Called when the processor is initialized - void StartProcessor() override; - - // Called when the processor is suspended - void SuspendProcessor() override; - - // Called when the processor is stopped - void StopProcessor() override; - - // Sets config parameters of the camera - void SetConfig(Core::IrSensor::PackedTeraPluginProcessorConfig config); - -private: - // This is nn::irsensor::TeraPluginProcessorConfig - struct TeraPluginProcessorConfig { - u8 mode; - u8 unknown_1; - u8 unknown_2; - u8 unknown_3; - }; - static_assert(sizeof(TeraPluginProcessorConfig) == 0x4, - "TeraPluginProcessorConfig is an invalid size"); - - struct TeraPluginProcessorState { - s64 sampling_number; - u64 timestamp; - Core::IrSensor::CameraAmbientNoiseLevel ambient_noise_level; - std::array<u8, 0x12c> data; - }; - static_assert(sizeof(TeraPluginProcessorState) == 0x140, - "TeraPluginProcessorState is an invalid size"); - - TeraPluginProcessorConfig current_config{}; - Core::IrSensor::DeviceFormat& device; -}; - -} // namespace Service::IRS diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp deleted file mode 100644 index 1f41e645d..000000000 --- a/src/core/hle/service/hid/resource_manager.cpp +++ /dev/null @@ -1,362 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#include "common/logging/log.h" -#include "core/core.h" -#include "core/core_timing.h" -#include "core/hid/hid_core.h" -#include "core/hle/kernel/k_shared_memory.h" -#include "core/hle/service/hid/resource_manager.h" -#include "core/hle/service/ipc_helpers.h" - -#include "core/hle/service/hid/controllers/applet_resource.h" -#include "core/hle/service/hid/controllers/capture_button.h" -#include "core/hle/service/hid/controllers/console_six_axis.h" -#include "core/hle/service/hid/controllers/debug_mouse.h" -#include "core/hle/service/hid/controllers/debug_pad.h" -#include "core/hle/service/hid/controllers/digitizer.h" -#include "core/hle/service/hid/controllers/gesture.h" -#include "core/hle/service/hid/controllers/home_button.h" -#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/palma.h" -#include "core/hle/service/hid/controllers/seven_six_axis.h" -#include "core/hle/service/hid/controllers/six_axis.h" -#include "core/hle/service/hid/controllers/sleep_button.h" -#include "core/hle/service/hid/controllers/touchscreen.h" -#include "core/hle/service/hid/controllers/types/shared_memory_format.h" -#include "core/hle/service/hid/controllers/unique_pad.h" - -namespace Service::HID { - -// Updating period for each HID device. -// Period time is obtained by measuring the number of samples in a second on HW using a homebrew -// Correct npad_update_ns is 4ms this is overclocked to lower input lag -constexpr auto npad_update_ns = std::chrono::nanoseconds{1 * 1000 * 1000}; // (1ms, 1000Hz) -constexpr auto default_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 1000Hz) -constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 1000}; // (8ms, 125Hz) -constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) - -ResourceManager::ResourceManager(Core::System& system_) - : system{system_}, service_context{system_, "hid"} { - applet_resource = std::make_shared<AppletResource>(system); -} - -ResourceManager::~ResourceManager() = default; - -void ResourceManager::Initialize() { - if (is_initialized) { - return; - } - - system.HIDCore().ReloadInputDevices(); - - InitializeHidCommonSampler(); - InitializeTouchScreenSampler(); - InitializeConsoleSixAxisSampler(); - InitializeAHidSampler(); - - is_initialized = true; -} - -std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const { - return applet_resource; -} - -std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const { - return capture_button; -} - -std::shared_ptr<ConsoleSixAxis> ResourceManager::GetConsoleSixAxis() const { - return console_six_axis; -} - -std::shared_ptr<DebugMouse> ResourceManager::GetDebugMouse() const { - return debug_mouse; -} - -std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() const { - return debug_pad; -} - -std::shared_ptr<Digitizer> ResourceManager::GetDigitizer() const { - return digitizer; -} - -std::shared_ptr<Gesture> ResourceManager::GetGesture() const { - return gesture; -} - -std::shared_ptr<HomeButton> ResourceManager::GetHomeButton() const { - return home_button; -} - -std::shared_ptr<Keyboard> ResourceManager::GetKeyboard() const { - return keyboard; -} - -std::shared_ptr<Mouse> ResourceManager::GetMouse() const { - return mouse; -} - -std::shared_ptr<NPad> ResourceManager::GetNpad() const { - return npad; -} - -std::shared_ptr<Palma> ResourceManager::GetPalma() const { - return palma; -} - -std::shared_ptr<SevenSixAxis> ResourceManager::GetSevenSixAxis() const { - return seven_six_axis; -} - -std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() const { - return six_axis; -} - -std::shared_ptr<SleepButton> ResourceManager::GetSleepButton() const { - return sleep_button; -} - -std::shared_ptr<TouchScreen> ResourceManager::GetTouchScreen() const { - return touch_screen; -} - -std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const { - return unique_pad; -} - -Result ResourceManager::CreateAppletResource(u64 aruid) { - if (aruid == SystemAruid) { - const auto result = RegisterCoreAppletResource(); - if (result.IsError()) { - return result; - } - return GetNpad()->ActivateNpadResource(); - } - - const auto result = CreateAppletResourceImpl(aruid); - if (result.IsError()) { - return result; - } - - // Homebrew doesn't try to activate some controllers, so we activate them by default - npad->Activate(); - six_axis->Activate(); - touch_screen->Activate(); - - return GetNpad()->ActivateNpadResource(aruid); -} - -Result ResourceManager::CreateAppletResourceImpl(u64 aruid) { - std::scoped_lock lock{shared_mutex}; - return applet_resource->CreateAppletResource(aruid); -} - -void ResourceManager::InitializeHidCommonSampler() { - debug_pad = std::make_shared<DebugPad>(system.HIDCore()); - mouse = std::make_shared<Mouse>(system.HIDCore()); - debug_mouse = std::make_shared<DebugMouse>(system.HIDCore()); - keyboard = std::make_shared<Keyboard>(system.HIDCore()); - unique_pad = std::make_shared<UniquePad>(system.HIDCore()); - npad = std::make_shared<NPad>(system.HIDCore(), service_context); - gesture = std::make_shared<Gesture>(system.HIDCore()); - home_button = std::make_shared<HomeButton>(system.HIDCore()); - sleep_button = std::make_shared<SleepButton>(system.HIDCore()); - capture_button = std::make_shared<CaptureButton>(system.HIDCore()); - digitizer = std::make_shared<Digitizer>(system.HIDCore()); - - palma = std::make_shared<Palma>(system.HIDCore(), service_context); - six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad); - - debug_pad->SetAppletResource(applet_resource, &shared_mutex); - digitizer->SetAppletResource(applet_resource, &shared_mutex); - keyboard->SetAppletResource(applet_resource, &shared_mutex); - npad->SetNpadExternals(applet_resource, &shared_mutex); - six_axis->SetAppletResource(applet_resource, &shared_mutex); - mouse->SetAppletResource(applet_resource, &shared_mutex); - debug_mouse->SetAppletResource(applet_resource, &shared_mutex); - home_button->SetAppletResource(applet_resource, &shared_mutex); - sleep_button->SetAppletResource(applet_resource, &shared_mutex); - capture_button->SetAppletResource(applet_resource, &shared_mutex); -} - -void ResourceManager::InitializeTouchScreenSampler() { - gesture = std::make_shared<Gesture>(system.HIDCore()); - touch_screen = std::make_shared<TouchScreen>(system.HIDCore()); - - touch_screen->SetAppletResource(applet_resource, &shared_mutex); - gesture->SetAppletResource(applet_resource, &shared_mutex); -} - -void ResourceManager::InitializeConsoleSixAxisSampler() { - console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore()); - seven_six_axis = std::make_shared<SevenSixAxis>(system); - - console_six_axis->SetAppletResource(applet_resource, &shared_mutex); -} - -void ResourceManager::InitializeAHidSampler() { - // TODO -} - -Result ResourceManager::RegisterCoreAppletResource() { - std::scoped_lock lock{shared_mutex}; - return applet_resource->RegisterCoreAppletResource(); -} - -Result ResourceManager::UnregisterCoreAppletResource() { - std::scoped_lock lock{shared_mutex}; - return applet_resource->UnregisterCoreAppletResource(); -} - -Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) { - std::scoped_lock lock{shared_mutex}; - auto result = applet_resource->RegisterAppletResourceUserId(aruid, bool_value); - if (result.IsSuccess()) { - result = npad->RegisterAppletResourceUserId(aruid); - } - return result; -} - -void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) { - std::scoped_lock lock{shared_mutex}; - applet_resource->UnregisterAppletResourceUserId(aruid); -} - -Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) { - std::scoped_lock lock{shared_mutex}; - return applet_resource->GetSharedMemoryHandle(out_handle, aruid); -} - -void ResourceManager::FreeAppletResourceId(u64 aruid) { - std::scoped_lock lock{shared_mutex}; - applet_resource->FreeAppletResourceId(aruid); -} - -void ResourceManager::EnableInput(u64 aruid, bool is_enabled) { - std::scoped_lock lock{shared_mutex}; - applet_resource->EnableInput(aruid, is_enabled); -} - -void ResourceManager::EnableSixAxisSensor(u64 aruid, bool is_enabled) { - std::scoped_lock lock{shared_mutex}; - applet_resource->EnableSixAxisSensor(aruid, is_enabled); -} - -void ResourceManager::EnablePadInput(u64 aruid, bool is_enabled) { - std::scoped_lock lock{shared_mutex}; - applet_resource->EnablePadInput(aruid, is_enabled); -} - -void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) { - std::scoped_lock lock{shared_mutex}; - applet_resource->EnableTouchScreen(aruid, is_enabled); -} - -void ResourceManager::UpdateControllers(std::chrono::nanoseconds ns_late) { - auto& core_timing = system.CoreTiming(); - debug_pad->OnUpdate(core_timing); - digitizer->OnUpdate(core_timing); - unique_pad->OnUpdate(core_timing); - gesture->OnUpdate(core_timing); - touch_screen->OnUpdate(core_timing); - palma->OnUpdate(core_timing); - home_button->OnUpdate(core_timing); - sleep_button->OnUpdate(core_timing); - capture_button->OnUpdate(core_timing); -} - -void ResourceManager::UpdateNpad(std::chrono::nanoseconds ns_late) { - auto& core_timing = system.CoreTiming(); - npad->OnUpdate(core_timing); -} - -void ResourceManager::UpdateMouseKeyboard(std::chrono::nanoseconds ns_late) { - auto& core_timing = system.CoreTiming(); - mouse->OnUpdate(core_timing); - debug_mouse->OnUpdate(core_timing); - keyboard->OnUpdate(core_timing); -} - -void ResourceManager::UpdateMotion(std::chrono::nanoseconds ns_late) { - auto& core_timing = system.CoreTiming(); - six_axis->OnUpdate(core_timing); - seven_six_axis->OnUpdate(core_timing); - console_six_axis->OnUpdate(core_timing); -} - -IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource, - u64 applet_resource_user_id) - : ServiceFramework{system_, "IAppletResource"}, aruid{applet_resource_user_id}, - resource_manager{resource} { - static const FunctionInfo functions[] = { - {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, - }; - RegisterHandlers(functions); - - // Register update callbacks - npad_update_event = Core::Timing::CreateEvent( - "HID::UpdatePadCallback", - [this, resource]( - s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { - const auto guard = LockService(); - resource->UpdateNpad(ns_late); - return std::nullopt; - }); - default_update_event = Core::Timing::CreateEvent( - "HID::UpdateDefaultCallback", - [this, resource]( - s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { - const auto guard = LockService(); - resource->UpdateControllers(ns_late); - return std::nullopt; - }); - mouse_keyboard_update_event = Core::Timing::CreateEvent( - "HID::UpdateMouseKeyboardCallback", - [this, resource]( - s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { - const auto guard = LockService(); - resource->UpdateMouseKeyboard(ns_late); - return std::nullopt; - }); - motion_update_event = Core::Timing::CreateEvent( - "HID::UpdateMotionCallback", - [this, resource]( - s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { - const auto guard = LockService(); - resource->UpdateMotion(ns_late); - return std::nullopt; - }); - - system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event); - system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns, - default_update_event); - system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns, - mouse_keyboard_update_event); - system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns, - motion_update_event); -} - -IAppletResource::~IAppletResource() { - system.CoreTiming().UnscheduleEvent(npad_update_event); - system.CoreTiming().UnscheduleEvent(default_update_event); - system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event); - system.CoreTiming().UnscheduleEvent(motion_update_event); - resource_manager->FreeAppletResourceId(aruid); -} - -void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { - Kernel::KSharedMemory* handle; - const auto result = resource_manager->GetSharedMemoryHandle(&handle, aruid); - - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, result=0x{:X}", aruid, result.raw); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(result); - rb.PushCopyObjects(handle); -} - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h deleted file mode 100644 index 7a21d8eb8..000000000 --- a/src/core/hle/service/hid/resource_manager.h +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-3.0-or-later - -#pragma once - -#include "core/hle/service/kernel_helpers.h" -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Core::Timing { -struct EventType; -} - -namespace Kernel { -class KSharedMemory; -} - -namespace Service::HID { -class AppletResource; -class CaptureButton; -class Controller_Stubbed; -class ConsoleSixAxis; -class DebugMouse; -class DebugPad; -class Digitizer; -class Gesture; -class HomeButton; -class Keyboard; -class Mouse; -class NPad; -class Palma; -class SevenSixAxis; -class SixAxis; -class SleepButton; -class TouchScreen; -class UniquePad; - -class ResourceManager { - -public: - explicit ResourceManager(Core::System& system_); - ~ResourceManager(); - - void Initialize(); - - std::shared_ptr<AppletResource> GetAppletResource() const; - std::shared_ptr<CaptureButton> GetCaptureButton() const; - std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; - std::shared_ptr<DebugMouse> GetDebugMouse() const; - std::shared_ptr<DebugPad> GetDebugPad() const; - std::shared_ptr<Digitizer> GetDigitizer() const; - std::shared_ptr<Gesture> GetGesture() const; - std::shared_ptr<HomeButton> GetHomeButton() const; - std::shared_ptr<Keyboard> GetKeyboard() const; - std::shared_ptr<Mouse> GetMouse() const; - std::shared_ptr<NPad> GetNpad() const; - std::shared_ptr<Palma> GetPalma() const; - std::shared_ptr<SevenSixAxis> GetSevenSixAxis() const; - std::shared_ptr<SixAxis> GetSixAxis() const; - std::shared_ptr<SleepButton> GetSleepButton() const; - std::shared_ptr<TouchScreen> GetTouchScreen() const; - std::shared_ptr<UniquePad> GetUniquePad() const; - - Result CreateAppletResource(u64 aruid); - - Result RegisterCoreAppletResource(); - Result UnregisterCoreAppletResource(); - Result RegisterAppletResourceUserId(u64 aruid, bool bool_value); - void UnregisterAppletResourceUserId(u64 aruid); - - Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid); - void FreeAppletResourceId(u64 aruid); - - void EnableInput(u64 aruid, bool is_enabled); - void EnableSixAxisSensor(u64 aruid, bool is_enabled); - void EnablePadInput(u64 aruid, bool is_enabled); - void EnableTouchScreen(u64 aruid, bool is_enabled); - - void UpdateControllers(std::chrono::nanoseconds ns_late); - void UpdateNpad(std::chrono::nanoseconds ns_late); - void UpdateMouseKeyboard(std::chrono::nanoseconds ns_late); - void UpdateMotion(std::chrono::nanoseconds ns_late); - -private: - Result CreateAppletResourceImpl(u64 aruid); - void InitializeHidCommonSampler(); - void InitializeTouchScreenSampler(); - void InitializeConsoleSixAxisSampler(); - void InitializeAHidSampler(); - - bool is_initialized{false}; - - mutable std::recursive_mutex shared_mutex; - std::shared_ptr<AppletResource> applet_resource = nullptr; - - std::shared_ptr<CaptureButton> capture_button = nullptr; - std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; - std::shared_ptr<DebugMouse> debug_mouse = nullptr; - std::shared_ptr<DebugPad> debug_pad = nullptr; - std::shared_ptr<Digitizer> digitizer = nullptr; - std::shared_ptr<Gesture> gesture = nullptr; - std::shared_ptr<HomeButton> home_button = nullptr; - std::shared_ptr<Keyboard> keyboard = nullptr; - std::shared_ptr<Mouse> mouse = nullptr; - std::shared_ptr<NPad> npad = nullptr; - std::shared_ptr<Palma> palma = nullptr; - std::shared_ptr<SevenSixAxis> seven_six_axis = nullptr; - std::shared_ptr<SixAxis> six_axis = nullptr; - std::shared_ptr<SleepButton> sleep_button = nullptr; - std::shared_ptr<TouchScreen> touch_screen = nullptr; - std::shared_ptr<UniquePad> unique_pad = nullptr; - - // TODO: Create these resources - // std::shared_ptr<AudioControl> audio_control = nullptr; - // std::shared_ptr<ButtonConfig> button_config = nullptr; - // std::shared_ptr<Config> config = nullptr; - // std::shared_ptr<Connection> connection = nullptr; - // std::shared_ptr<CustomConfig> custom_config = nullptr; - // std::shared_ptr<Digitizer> digitizer = nullptr; - // std::shared_ptr<Hdls> hdls = nullptr; - // std::shared_ptr<PlayReport> play_report = nullptr; - // std::shared_ptr<Rail> rail = nullptr; - - Core::System& system; - KernelHelpers::ServiceContext service_context; -}; - -class IAppletResource final : public ServiceFramework<IAppletResource> { -public: - explicit IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource, - u64 applet_resource_user_id); - ~IAppletResource() override; - -private: - void GetSharedMemoryHandle(HLERequestContext& ctx); - - std::shared_ptr<Core::Timing::EventType> npad_update_event; - std::shared_ptr<Core::Timing::EventType> default_update_event; - std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; - std::shared_ptr<Core::Timing::EventType> motion_update_event; - - u64 aruid; - std::shared_ptr<ResourceManager> resource_manager; -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/hid/ring_lifo.h b/src/core/hle/service/hid/ring_lifo.h deleted file mode 100644 index 0816784e0..000000000 --- a/src/core/hle/service/hid/ring_lifo.h +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <array> - -#include "common/common_types.h" - -namespace Service::HID { - -template <typename State> -struct AtomicStorage { - s64 sampling_number; - State state; -}; - -template <typename State, std::size_t max_buffer_size> -struct Lifo { - s64 timestamp{}; - s64 total_buffer_count = static_cast<s64>(max_buffer_size); - s64 buffer_tail{}; - s64 buffer_count{}; - std::array<AtomicStorage<State>, max_buffer_size> entries{}; - - const AtomicStorage<State>& ReadCurrentEntry() const { - return entries[buffer_tail]; - } - - const AtomicStorage<State>& ReadPreviousEntry() const { - return entries[GetPreviousEntryIndex()]; - } - - std::size_t GetPreviousEntryIndex() const { - return static_cast<size_t>((buffer_tail + max_buffer_size - 1) % max_buffer_size); - } - - std::size_t GetNextEntryIndex() const { - return static_cast<size_t>((buffer_tail + 1) % max_buffer_size); - } - - void WriteNextEntry(const State& new_state) { - if (buffer_count < static_cast<s64>(max_buffer_size) - 1) { - buffer_count++; - } - buffer_tail = GetNextEntryIndex(); - const auto& previous_entry = ReadPreviousEntry(); - entries[buffer_tail].sampling_number = previous_entry.sampling_number + 1; - entries[buffer_tail].state = new_state; - } -}; - -} // namespace Service::HID diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index f97e5b44c..b37fb6da3 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -22,9 +22,6 @@ #include "common/string_util.h" #include "common/tiny_mt.h" #include "core/core.h" -#include "core/hid/emulated_controller.h" -#include "core/hid/hid_core.h" -#include "core/hid/hid_types.h" #include "core/hle/kernel/k_event.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/mii/mii_manager.h" @@ -33,6 +30,9 @@ #include "core/hle/service/nfc/mifare_result.h" #include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/time/time_manager.h" +#include "hid_core/frontend/emulated_controller.h" +#include "hid_core/hid_core.h" +#include "hid_core/hid_types.h" namespace Service::NFC { NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index ad534177d..44f651b87 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp @@ -5,15 +5,15 @@ #include "common/logging/log.h" #include "core/core.h" -#include "core/hid/hid_types.h" #include "core/hle/kernel/k_event.h" -#include "core/hle/service/hid/hid_util.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/nfc/common/device.h" #include "core/hle/service/nfc/common/device_manager.h" #include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/time/clock_types.h" #include "core/hle/service/time/time_manager.h" +#include "hid_core/hid_types.h" +#include "hid_core/hid_util.h" namespace Service::NFC { diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h index c9f038e32..f02bdccf5 100644 --- a/src/core/hle/service/nfc/common/device_manager.h +++ b/src/core/hle/service/nfc/common/device_manager.h @@ -8,13 +8,13 @@ #include <optional> #include <span> -#include "core/hid/hid_types.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/nfc/mifare_types.h" #include "core/hle/service/nfc/nfc_types.h" #include "core/hle/service/nfp/nfp_types.h" #include "core/hle/service/service.h" #include "core/hle/service/time/clock_types.h" +#include "hid_core/hid_types.h" namespace Service::NFC { class NfcDevice; diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp index 179c7ba2c..a71cf74b8 100644 --- a/src/core/hle/service/nfc/nfc_interface.cpp +++ b/src/core/hle/service/nfc/nfc_interface.cpp @@ -3,7 +3,6 @@ #include "common/logging/log.h" #include "core/core.h" -#include "core/hid/hid_types.h" #include "core/hle/kernel/k_event.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/nfc/common/device.h" @@ -15,6 +14,7 @@ #include "core/hle/service/nfc/nfc_types.h" #include "core/hle/service/nfp/nfp_result.h" #include "core/hle/service/time/clock_types.h" +#include "hid_core/hid_types.h" namespace Service::NFC { diff --git a/src/core/hle/service/nfp/nfp_interface.cpp b/src/core/hle/service/nfp/nfp_interface.cpp index 34ef9d82d..5ba6d1742 100644 --- a/src/core/hle/service/nfp/nfp_interface.cpp +++ b/src/core/hle/service/nfp/nfp_interface.cpp @@ -3,7 +3,6 @@ #include "common/logging/log.h" #include "core/core.h" -#include "core/hid/hid_types.h" #include "core/hle/kernel/k_event.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/nfc/common/device.h" @@ -12,6 +11,7 @@ #include "core/hle/service/nfp/nfp_interface.h" #include "core/hle/service/nfp/nfp_result.h" #include "core/hle/service/nfp/nfp_types.h" +#include "hid_core/hid_types.h" namespace Service::NFP { |