From 4de51d5174ca5a725d3889a14adab4acb8471657 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Wed, 31 May 2023 19:31:21 -0600 Subject: [PATCH] hidbus --- src/core/hle/service/hid/errors.h | 25 ++++++++ src/core/hle/service/hid/hidbus.cpp | 96 ++++++++++++++++++----------- src/core/hle/service/hid/hidbus.h | 3 + 3 files changed, 88 insertions(+), 36 deletions(-) diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index 9585bdaf0..0352d3f1c 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h @@ -14,11 +14,22 @@ constexpr Result VibrationInvalidStyleIndex{ErrorModule::HID, 122}; constexpr Result VibrationInvalidNpadId{ErrorModule::HID, 123}; constexpr Result VibrationDeviceIndexOutOfRange{ErrorModule::HID, 124}; constexpr Result InvalidSixAxisFusionRange{ErrorModule::HID, 423}; + +constexpr Result ResultMcuInvalidHandle{ErrorModule::HID, 541}; +constexpr Result ResultMcuNotEnabled{ErrorModule::HID, 542}; +constexpr Result ResultMcuNoDeviceConnected{ErrorModule::HID, 543}; +constexpr Result ResultMcuUnknown544{ErrorModule::HID, 544}; +constexpr Result ResultMcuUnknown546{ErrorModule::HID, 546}; +constexpr Result ResultMcuUnknown548{ErrorModule::HID, 548}; + constexpr Result NpadIsDualJoycon{ErrorModule::HID, 601}; constexpr Result NpadIsSameType{ErrorModule::HID, 602}; constexpr Result InvalidNpadId{ErrorModule::HID, 709}; constexpr Result NpadNotConnected{ErrorModule::HID, 710}; constexpr Result InvalidArraySize{ErrorModule::HID, 715}; + +constexpr Result ResultControllerUpdateFailed{ErrorModule::HID, 3201}; + constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302}; } // namespace Service::HID @@ -29,3 +40,17 @@ constexpr Result InvalidProcessorState{ErrorModule::Irsensor, 78}; constexpr Result InvalidIrCameraHandle{ErrorModule::Irsensor, 204}; } // namespace Service::IRS + +namespace Service::HIDBUS { + +constexpr Result ResultNotEnabled{ErrorModule::HIDBUS, 1}; +constexpr Result ResultControllerUpdateFailed{ErrorModule::HIDBUS, 3}; +constexpr Result ResultInvalidBusHandle{ErrorModule::HIDBUS, 4}; +constexpr Result ResultNoDeviceConnected{ErrorModule::HIDBUS, 5}; +constexpr Result ResultUknown6{ErrorModule::HIDBUS, 6}; +constexpr Result ResultPollingRecieveDataNotAvailable{ErrorModule::HIDBUS, 7}; +constexpr Result ResultDeviceEnabledNotSet{ErrorModule::HIDBUS, 8}; +constexpr Result ResultBusHandleAlreadyInitialized{ErrorModule::HIDBUS, 10}; +constexpr Result ResultInvalidBusType{ErrorModule::HIDBUS, 11}; + +} // namespace Service::HID \ No newline at end of file diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp index 5604a6fda..961189b98 100644 --- a/src/core/hle/service/hid/hidbus.cpp +++ b/src/core/hle/service/hid/hidbus.cpp @@ -12,6 +12,8 @@ #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/errors.h" +#include "core/hle/service/hid/controllers/npad.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" @@ -114,38 +116,9 @@ void HidBus::GetBusHandle(HLERequestContext& ctx) { LOG_INFO(Service_HID, "called, npad_id={}, bus_type={}, applet_resource_user_id={}", parameters.npad_id, parameters.bus_type, parameters.applet_resource_user_id); - bool is_handle_found = 0; - std::size_t handle_index = 0; - - for (std::size_t i = 0; i < devices.size(); i++) { - const auto& handle = devices[i].handle; - if (!handle.is_valid) { - continue; - } - if (static_cast(handle.player_number) == parameters.npad_id && - handle.bus_type_id == static_cast(parameters.bus_type)) { - is_handle_found = true; - handle_index = i; - break; - } - } - - // Handle not found. Create a new one - if (!is_handle_found) { - for (std::size_t i = 0; i < devices.size(); i++) { - if (devices[i].handle.is_valid) { - continue; - } - devices[i].handle = { - .abstracted_pad_id = static_cast(i), - .internal_index = static_cast(i), - .player_number = static_cast(parameters.npad_id), - .bus_type_id = static_cast(parameters.bus_type), - .is_valid = true, - }; - handle_index = i; - break; - } + if (parameters.bus_type >= BusType::MaxBusType) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultInvalidBusType); } struct OutData { @@ -155,10 +128,8 @@ void HidBus::GetBusHandle(HLERequestContext& ctx) { }; static_assert(sizeof(OutData) == 0x10, "OutData has incorrect size."); - const OutData out_data{ - .is_valid = true, - .handle = devices[handle_index].handle, - }; + OutData out_data{}; + out_data.is_valid = GetBusHandleImpl(out_data.handle, parameters.npad_id, parameters.bus_type); IPC::ResponseBuilder rb{ctx, 6}; rb.Push(ResultSuccess); @@ -521,4 +492,57 @@ void HidBus::SetStatusManagerType(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); }; + + +bool HidBus::GetBusHandleImpl(BusHandle& handle, Core::HID::NpadIdType npad_id, BusType bus_type) { + ASSERT_MSG(&handle != nullptr, "Handle is null"); + + if (!Controller_NPad::IsNpadIdValid(npad_id)) { + return false; + } + + if (bus_type == BusType::LeftJoyRail || bus_type == BusType::RightJoyRail) { + return true; + } + + if (bus_type == BusType::InternalBus) { + return true; + } + + return false; +} + + +Result TranslateHidErrorToHidBusError(Result result) { + if (result.IsSuccess()) { + return result; + } + if (result.module != ErrorModule::HID) { + return result; + } + if (result == ResultMcuNotEnabled) { + return HIDBUS::ResultNotEnabled; + } + if (result == ResultMcuNoDeviceConnected) { + return HIDBUS::ResultNoDeviceConnected; + } + if ((result.description & 0x1FFB) == 0x221) { + return HIDBUS::ResultPollingRecieveDataNotAvailable; + } + if (result == ResultMcuInvalidHandle) { + return HIDBUS::ResultInvalidBusHandle; + } + if (result == ResultMcuUnknown546) { + return HIDBUS::ResultDeviceEnabledNotSet; + } + if (result == ResultMcuUnknown548) { + return HIDBUS::ResultInvalidBusHandle; + } + if (result == ResultControllerUpdateFailed) { + return HIDBUS::ResultControllerUpdateFailed; + } + return result; +} + + } // namespace Service::HID diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h index c29b5e882..8a65d2872 100644 --- a/src/core/hle/service/hid/hidbus.h +++ b/src/core/hle/service/hid/hidbus.h @@ -108,6 +108,9 @@ private: void DisableJoyPollingReceiveMode(HLERequestContext& ctx); void SetStatusManagerType(HLERequestContext& ctx); + bool GetBusHandleImpl(BusHandle& handle, Core::HID::NpadIdType npad_id, BusType bus_type); + Result TranslateHidErrorToHidBusError(Result result); + void UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); std::optional GetDeviceIndexFromHandle(BusHandle handle) const;