From e8cc760b101349f88a2f0cea5635aeac2a4d34b3 Mon Sep 17 00:00:00 2001 From: kaikecarlos <28846018+kaikecarlos@users.noreply.github.com> Date: Sun, 27 Mar 2022 08:06:14 -0300 Subject: [PATCH] Implement IHidServer Functions Add GetVibrationDeviceInfo and StartSixAxisSensor --- .../main/cpp/skyline/input/npad_device.cpp | 2 +- app/src/main/cpp/skyline/input/npad_device.h | 11 +++++++ .../main/cpp/skyline/input/sections/Npad.h | 21 +++++++++++++ .../cpp/skyline/services/hid/IHidServer.cpp | 30 +++++++++++++++++++ .../cpp/skyline/services/hid/IHidServer.h | 18 +++++++++++ 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/app/src/main/cpp/skyline/input/npad_device.cpp b/app/src/main/cpp/skyline/input/npad_device.cpp index 33584544..fa119282 100644 --- a/app/src/main/cpp/skyline/input/npad_device.cpp +++ b/app/src/main/cpp/skyline/input/npad_device.cpp @@ -134,7 +134,7 @@ namespace skyline::input { section.header.singleColorStatus = NpadColorReadStatus::Success; // Single color is also written for dual controllers section.header.singleColor = section.header.leftColor; // and is set to the color of the left JC break; - + case NpadControllerType::Gamecube: case NpadControllerType::None: break; } diff --git a/app/src/main/cpp/skyline/input/npad_device.h b/app/src/main/cpp/skyline/input/npad_device.h index 74a3b26f..27dac24c 100644 --- a/app/src/main/cpp/skyline/input/npad_device.h +++ b/app/src/main/cpp/skyline/input/npad_device.h @@ -83,12 +83,23 @@ namespace skyline::input { return NpadControllerType::JoyconLeft; case 7: return NpadControllerType::JoyconRight; + case 8: + return NpadControllerType::Gamecube; default: return NpadControllerType::None; } } }; + /** + * @url https://switchbrew.org/wiki/HID_services#VibrationDeviceInfo + */ + struct NpadVibrationDeviceInfo { + NpadVibrationDeviceType deviceType; + NpadVibrationDevicePosition position; + }; + static_assert(sizeof(NpadVibrationDeviceInfo) == 0x8); + /** * @brief The parameters to produce a vibration using an LRA * @note The vibration is broken into a frequency band with the lower and high range supplied diff --git a/app/src/main/cpp/skyline/input/sections/Npad.h b/app/src/main/cpp/skyline/input/sections/Npad.h index 8e610f8d..9007504e 100644 --- a/app/src/main/cpp/skyline/input/sections/Npad.h +++ b/app/src/main/cpp/skyline/input/sections/Npad.h @@ -14,6 +14,7 @@ namespace skyline::input { JoyconDual = 0b100, JoyconLeft = 0b1000, JoyconRight = 0b10000, + Gamecube = 0b100000, }; // @fmt:on @@ -187,6 +188,26 @@ namespace skyline::input { }; static_assert(sizeof(NpadDeviceType) == 0x4); + /** + * @url https://switchbrew.org/wiki/HID_services#VibrationDeviceType + */ + enum class NpadVibrationDeviceType : u32 { + Unknown, + LinearResonantActuator, //!< LRAs are used on devices that support HD Rumble functionality such as Joy-Cons and the Pro Controller + EccentricRotatingMass, //!< ERMs are mainly used in the old GameCube controllers and offer more crude rumble + }; + static_assert(sizeof(NpadVibrationDeviceType) == 0x4); + + /** + * @url https://switchbrew.org/wiki/HID_services#VibrationDevicePosition + */ + enum class NpadVibrationDevicePosition : u32 { + None, + Left, + Right + }; + static_assert(sizeof(NpadVibrationDevicePosition) == 0x4); + /** * @url https://switchbrew.org/wiki/HID_Shared_Memory#NpadSystemProperties */ diff --git a/app/src/main/cpp/skyline/services/hid/IHidServer.cpp b/app/src/main/cpp/skyline/services/hid/IHidServer.cpp index 4c30744d..d9fe27a8 100644 --- a/app/src/main/cpp/skyline/services/hid/IHidServer.cpp +++ b/app/src/main/cpp/skyline/services/hid/IHidServer.cpp @@ -179,4 +179,34 @@ namespace skyline::service::hid { return {}; } + + Result IHidServer::StartSixAxisSensor(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + return {}; + } + + Result IHidServer::GetVibrationDeviceInfo(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { + auto deviceHandle{request.Pop()}; + auto id{deviceHandle.id}; + + if (id > NpadId::Player8 && id != NpadId::Handheld && id != NpadId::Unknown) + return result::InvalidNpadId; + + auto vibrationDeviceType{NpadVibrationDeviceType::Unknown}; + auto vibrationDevicePosition{NpadVibrationDevicePosition::None}; + + if (deviceHandle.GetType() == NpadControllerType::Gamecube) + vibrationDeviceType = NpadVibrationDeviceType::EccentricRotatingMass; + else + vibrationDeviceType = NpadVibrationDeviceType::LinearResonantActuator; + + if (vibrationDeviceType == NpadVibrationDeviceType::LinearResonantActuator) + if (deviceHandle.isRight) + vibrationDevicePosition = NpadVibrationDevicePosition::Right; + else + vibrationDevicePosition = NpadVibrationDevicePosition::Left; + + response.Push(NpadVibrationDeviceInfo{vibrationDeviceType, vibrationDevicePosition}); + + return {}; + } } diff --git a/app/src/main/cpp/skyline/services/hid/IHidServer.h b/app/src/main/cpp/skyline/services/hid/IHidServer.h index 8fecb086..dbd8493f 100644 --- a/app/src/main/cpp/skyline/services/hid/IHidServer.h +++ b/app/src/main/cpp/skyline/services/hid/IHidServer.h @@ -7,6 +7,10 @@ #include "IAppletResource.h" namespace skyline::service::hid { + namespace result { + constexpr Result InvalidNpadId(202, 709); + } + /** * @brief IHidServer or hid service is used to access input devices * @url https://switchbrew.org/wiki/HID_services#hid @@ -31,6 +35,12 @@ namespace skyline::service::hid { */ Result ActivateTouchScreen(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + /** + * @brief Starts the Six Axis Sensor given an PID + * @url https://switchbrew.org/wiki/HID_services#CreateAppletResource + */ + Result StartSixAxisSensor(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + /** * @brief Sets the style of controllers supported * @url https://switchbrew.org/wiki/HID_services#SetSupportedNpadStyleSet @@ -114,6 +124,12 @@ namespace skyline::service::hid { */ Result CreateActiveVibrationDeviceList(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + /** + * @brief Returns the current vibration state of a device + * @url https://switchbrew.org/wiki/HID_services#GetVibrationDeviceInfo + */ + Result GetVibrationDeviceInfo(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response); + /** * @brief Send a single vibration value to a HID device * @url https://switchbrew.org/wiki/HID_services#SendVibrationValue @@ -130,6 +146,7 @@ namespace skyline::service::hid { SFUNC(0x0, IHidServer, CreateAppletResource), SFUNC(0x1, IHidServer, ActivateDebugPad), SFUNC(0xB, IHidServer, ActivateTouchScreen), + SFUNC(0x42, IHidServer, StartSixAxisSensor), SFUNC(0x64, IHidServer, SetSupportedNpadStyleSet), SFUNC(0x65, IHidServer, GetSupportedNpadStyleSet), SFUNC(0x66, IHidServer, SetSupportedNpadIdType), @@ -144,6 +161,7 @@ namespace skyline::service::hid { SFUNC(0x7B, IHidServer, SetNpadJoyAssignmentModeSingle), SFUNC(0x7C, IHidServer, SetNpadJoyAssignmentModeDual), SFUNC(0xCB, IHidServer, CreateActiveVibrationDeviceList), + SFUNC(0xC8, IHidServer, GetVibrationDeviceInfo), SFUNC(0xC9, IHidServer, SendVibrationValue), SFUNC(0xCE, IHidServer, SendVibrationValues) )