From 34a85b5a1efbe85f699413e17e53bd8d0f7161f2 Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 24 Jul 2023 07:10:34 -0600 Subject: [PATCH] kiske --- src/core/hle/service/hid/errors.h | 24 +++ src/core/hle/service/hid/hidbus.cpp | 211 +++++++++++++++------ src/core/hle/service/hid/hidbus.h | 4 + src/input_common/helpers/joycon_driver.cpp | 14 +- 4 files changed, 187 insertions(+), 66 deletions(-) diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index 9585bdaf0..e4d53cdb3 100644 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h @@ -14,11 +14,21 @@ 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 +39,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::HIDBUS diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp index 80aac221b..d9866c824 100644 --- a/src/core/hle/service/hid/hidbus.cpp +++ b/src/core/hle/service/hid/hidbus.cpp @@ -10,6 +10,8 @@ #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/controllers/npad.h" +#include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hidbus.h" #include "core/hle/service/hid/hidbus/ringcon.h" #include "core/hle/service/hid/hidbus/starlink.h" @@ -64,25 +66,7 @@ HidBus::~HidBus() { system.CoreTiming().UnscheduleEvent(hidbus_update_event, 0); } -void HidBus::UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { - if (is_hidbus_enabled) { - for (std::size_t i = 0; i < devices.size(); ++i) { - if (!devices[i].is_device_initializated) { - continue; - } - auto& device = devices[i].device; - device->OnUpdate(); - auto& cur_entry = hidbus_status.entries[devices[i].handle.internal_index]; - cur_entry.is_polling_mode = device->IsPollingMode(); - cur_entry.polling_mode = device->GetPollingMode(); - cur_entry.is_enabled = device->IsEnabled(); - - u8* shared_memory = system.Kernel().GetHidBusSharedMem().GetPointer(); - std::memcpy(shared_memory + (i * sizeof(HidbusStatusManagerEntry)), &hidbus_status, - sizeof(HidbusStatusManagerEntry)); - } - } -} +void HidBus::UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {} std::optional HidBus::GetDeviceIndexFromHandle(BusHandle handle) const { for (std::size_t i = 0; i < devices.size(); ++i) { @@ -108,45 +92,6 @@ void HidBus::GetBusHandle(HLERequestContext& ctx) { }; static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size."); - const auto parameters{rp.PopRaw()}; - - 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; - } - } - struct OutData { bool is_valid; INSERT_PADDING_BYTES(7); @@ -154,16 +99,158 @@ 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, - }; + const auto parameters{rp.PopRaw()}; + + LOG_INFO(Service_HID, "called, npad_id={}, bus_type={}, applet_resource_user_id={}", + parameters.npad_id, parameters.bus_type, parameters.applet_resource_user_id); + + if (parameters.bus_type >= BusType::MaxBusType) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(HIDBUS::ResultInvalidBusType); + return; + } + + 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); rb.PushRaw(out_data); } +bool HidBus::GetBusHandleImpl(BusHandle& handle, Core::HID::NpadIdType npad_id, + BusType bus_type) const { + if (!Controller_NPad::IsNpadIdValid(npad_id)) { + return false; + } + + if (MakeBusHandle(handle, npad_id, bus_type).IsError()) { + return false; + } + + if (bus_type == BusType::LeftJoyRail || bus_type == BusType::RightJoyRail) { + // TODO: IsBusHandleValid(*npad_id,bus_type) + return true; + } + + if (bus_type == BusType::InternalBus) { + // TODO: IsBusHandleValid(*npad_id,BusType::RightJoyRail) + return true; + } + + return false; +} + +Result HidBus::MakeBusHandle(BusHandle& handle, Core::HID::NpadIdType npad_id, + BusType bus_type) const { + u32 abstracted_pad_id{}; + const Result result = GetAbstractedHidbusPadId(abstracted_pad_id, npad_id, bus_type); + + if (result.IsError()) { + return result; + } + + u8 internal_index = static_cast(npad_id); + if (bus_type < BusType::MaxBusType) { + internal_index = internal_index << 1 | 1; + } + if (bus_type == BusType::LeftJoyRail) { + internal_index = internal_index << 1; + } + if (npad_id == Core::HID::NpadIdType::Handheld) { + switch (bus_type) { + case BusType::LeftJoyRail: + internal_index = 0x10; + break; + case BusType::InternalBus: + internal_index = 0; + break; + default: + internal_index = 0x11; + break; + } + } + + handle = { + .abstracted_pad_id = abstracted_pad_id, + .internal_index = internal_index, + .player_number = static_cast(npad_id) && 0xff, + .bus_type_id = static_cast(bus_type) && 0xff, + .is_valid = true, // This is hardcoded on the sysmodule + }; + return ResultSuccess; +} + +Result HidBus::GetAbstractedHidbusPadId(u32& abstracted_pad_id, Core::HID::NpadIdType npad_id, + BusType bus_type) const { + // This struct is unknown + struct LeftData { + std::array data; + }; + + struct ControllerData { + u32 data_1; + u32 data_2; + u32 is_connected; // ((d + 0x8) >> 1 & 1) + u32 abstracted_pad_id; + u32 data_5; + u32 data_6; + u32 data_7; + u32 data_8; + LeftData left_data; + u32 right_data; + u32 data_11; + u32 data_12; + u32 data_13; + u32 has_battery; // ((d + 0x3a) & 6) ((d + 0x38) & 0x60000) + u32 data_15; + u32 data_16; + }; + static_assert(sizeof(ControllerData) == 0x40, "ControllerData has incorrect size."); + + // auto& controller = GetControllerFromNpadIdType(npad_id); + const std::array data_pointer{}; // controller->GetControllerData(5); + + if (data_pointer.size() == 0) { + return ResultMcuInvalidHandle; + } + + for (const ControllerData& data : data_pointer) { + bool is_valid = false; + switch (bus_type) { + case BusType::LeftJoyRail: + if ((data.left_data.data[3] >> 1 & 1) != 0) { + is_valid = true; + } + break; + case BusType::RightJoyRail: { + if (((data.right_data >> 9 & 1) == 0) && ((data.right_data >> 10 & 1) != 0)) { + is_valid = true; + } + break; + } + case BusType::InternalBus: + if ((data.right_data & 0xe00) == 0x800) { + is_valid = true; + } + break; + default: + break; + } + + if (is_valid) { + abstracted_pad_id = data.abstracted_pad_id; + return ResultSuccess; + } + } + + // STUB this function for now + abstracted_pad_id = static_cast(npad_id); + return ResultSuccess; + + return ResultMcuInvalidHandle; +} + void HidBus::IsExternalDeviceConnected(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto bus_handle_{rp.PopRaw()}; diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h index c29b5e882..2ce7f1251 100644 --- a/src/core/hle/service/hid/hidbus.h +++ b/src/core/hle/service/hid/hidbus.h @@ -95,6 +95,10 @@ private: }; void GetBusHandle(HLERequestContext& ctx); + bool GetBusHandleImpl(BusHandle& handle, Core::HID::NpadIdType npad_id, BusType bus_type) const; + Result MakeBusHandle(BusHandle& handle, Core::HID::NpadIdType npad_id, BusType bus_type) const; + Result GetAbstractedHidbusPadId(u32& abstracted_pad_id, Core::HID::NpadIdType npad_id, + BusType bus_type) const; void IsExternalDeviceConnected(HLERequestContext& ctx); void Initialize(HLERequestContext& ctx); void Finalize(HLERequestContext& ctx); diff --git a/src/input_common/helpers/joycon_driver.cpp b/src/input_common/helpers/joycon_driver.cpp index cf51f3481..4aa5e9451 100644 --- a/src/input_common/helpers/joycon_driver.cpp +++ b/src/input_common/helpers/joycon_driver.cpp @@ -74,7 +74,7 @@ Common::Input::DriverResult JoyconDriver::InitializeDevice() { passive_enabled = false; irs_enabled = false; input_only_device = false; - gyro_sensitivity = Joycon::GyroSensitivity::DPS2000; + gyro_sensitivity = Joycon::GyroSensitivity::DPS250; gyro_performance = Joycon::GyroPerformance::HZ833; accelerometer_sensitivity = Joycon::AccelerometerSensitivity::G8; accelerometer_performance = Joycon::AccelerometerPerformance::HZ100; @@ -173,6 +173,12 @@ void JoyconDriver::InputThread(std::stop_token stop_token) { void JoyconDriver::OnNewData(std::span buffer) { const auto report_mode = static_cast(buffer[0]); + std::string str = ""; + for (u8 dat : buffer) { + str += fmt::format("{:02x} ", dat); + } + + LOG_CRITICAL(Input, "{}", str); // Packages can be a little bit inconsistent. Average the delta time to provide a smoother // motion experience @@ -203,7 +209,7 @@ void JoyconDriver::OnNewData(std::span buffer) { if (ring_connected && report_mode == ReportMode::STANDARD_FULL_60HZ) { InputReportActive data{}; memcpy(&data, buffer.data(), sizeof(InputReportActive)); - calibration_protocol->GetRingCalibration(ring_calibration, data.ring_input); + //calibration_protocol->GetRingCalibration(ring_calibration, data.ring_input); } const RingStatus ring_status{ @@ -264,8 +270,8 @@ Common::Input::DriverResult JoyconDriver::SetPollingMode() { if (motion_enabled && supported_features.motion) { generic_protocol->EnableImu(true); - generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance, - accelerometer_sensitivity, accelerometer_performance); + //generic_protocol->SetImuConfig(gyro_sensitivity, gyro_performance, + // accelerometer_sensitivity, accelerometer_performance); } else { generic_protocol->EnableImu(false); }