From 991a262e191a0f6285e2e8a9efda5004e9da10c4 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Sat, 14 Nov 2020 13:06:59 -0500 Subject: [PATCH] hid: Replaced HidControllerType with HidNpadStyleTag. HidNpadStyleTag now includes more controllers. Replaced hidGetControllerType with hidGetNpadStyleSet(). Improved _hidGetDeviceHandles(), more controllers are now supported. --- nx/include/switch/services/hid.h | 55 ++++++------ nx/include/switch/services/hidsys.h | 4 +- nx/source/applets/hid_la.c | 6 +- nx/source/runtime/ringcon.c | 6 +- nx/source/services/hid.c | 129 ++++++++++++++++++---------- nx/source/services/hidsys.c | 4 +- 6 files changed, 123 insertions(+), 81 deletions(-) diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 690f8b53..b7f7e6e2 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -214,17 +214,22 @@ typedef enum { KBD_MEDIA_CALC = 0xfb } HidKeyboardScancode; -/// HID controller type +/// HID controller styles typedef enum { - TYPE_PROCONTROLLER = BIT(0), - TYPE_HANDHELD = BIT(1), - TYPE_JOYCON_PAIR = BIT(2), - TYPE_JOYCON_LEFT = BIT(3), - TYPE_JOYCON_RIGHT = BIT(4), - - TYPE_SYSTEM_EXT = BIT(29), - TYPE_SYSTEM = BIT(30), -} HidControllerType; + HidNpadStyleTag_NpadFullKey = BIT(0), ///< Pro Controller + HidNpadStyleTag_NpadHandheld = BIT(1), ///< Joy-Con controller in handheld mode + HidNpadStyleTag_NpadJoyDual = BIT(2), ///< Joy-Con controller in dual mode + HidNpadStyleTag_NpadJoyLeft = BIT(3), ///< Joy-Con left controller in single mode + HidNpadStyleTag_NpadJoyRight = BIT(4), ///< Joy-Con right controller in single mode + HidNpadStyleTag_NpadGc = BIT(5), ///< GameCube controller + HidNpadStyleTag_NpadPalma = BIT(6), ///< Poké Ball Plus controller + HidNpadStyleTag_NpadLark = BIT(7), ///< NES/Famicom controller + HidNpadStyleTag_NpadHandheldLark = BIT(8), ///< NES/Famicom controller in handheld mode + HidNpadStyleTag_NpadLucia = BIT(9), ///< SNES controller + HidNpadStyleTag_Npad10 = BIT(10), + HidNpadStyleTag_NpadSystemExt = BIT(29), ///< Generic external controller + HidNpadStyleTag_NpadSystem = BIT(30), ///< Generic controller +} HidNpadStyleTag; /// HidControllerLayoutType typedef enum { @@ -320,7 +325,7 @@ typedef enum { CONTROLLER_PLAYER_8 = 7, CONTROLLER_HANDHELD = 8, CONTROLLER_UNKNOWN = 9, - CONTROLLER_P1_AUTO = 10, ///< Not an actual HID-sysmodule ID. Only for hidKeys*()/hidJoystickRead()/hidSixAxisSensorValuesRead()/hidGetControllerType()/hidGetControllerColors()/hidIsControllerConnected(). Automatically uses CONTROLLER_PLAYER_1 when connected, otherwise uses CONTROLLER_HANDHELD. + CONTROLLER_P1_AUTO = 10, ///< Not an actual HID-sysmodule ID. Only for hidKeys*()/hidJoystickRead()/hidSixAxisSensorValuesRead()/hidGetControllerColors()/hidIsControllerConnected(). Automatically uses CONTROLLER_PLAYER_1 when connected, otherwise uses CONTROLLER_HANDHELD. } HidControllerID; /// GyroscopeZeroDriftMode @@ -368,9 +373,9 @@ typedef enum { HidDeviceType_Palma = 12, ///< [9.0.0+] ::HidDeviceTypeBits_Palma HidDeviceType_FullKey13 = 13, ///< ::HidDeviceTypeBits_FullKey HidDeviceType_FullKey15 = 15, ///< ::HidDeviceTypeBits_FullKey - HidDeviceType_System19 = 19, ///< ::HidDeviceTypeBits_System with HidControllerType |= TYPE_PROCONTROLLER. - HidDeviceType_System20 = 20, ///< ::HidDeviceTypeBits_System with HidControllerType |= TYPE_JOYCON_PAIR. - HidDeviceType_System21 = 21, ///< ::HidDeviceTypeBits_System with HidControllerType |= TYPE_JOYCON_PAIR. + HidDeviceType_System19 = 19, ///< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadFullKey. + HidDeviceType_System20 = 20, ///< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadJoyDual. + HidDeviceType_System21 = 21, ///< ::HidDeviceTypeBits_System with \ref HidNpadStyleTag |= ::HidNpadStyleTag_NpadJoyDual. } HidDeviceType; /// NpadInterfaceType @@ -547,7 +552,7 @@ typedef struct HidControllerMAC { /// HidNpadStateHeader typedef struct HidNpadStateHeader { - u32 type; + u32 style_set; u32 isHalf; u32 singleColorsDescriptor; u32 singleColorBody; @@ -783,8 +788,10 @@ void* hidGetSharedmemAddr(void); void hidSetControllerLayout(HidControllerID id, HidControllerLayoutType layoutType); HidControllerLayoutType hidGetControllerLayout(HidControllerID id); -/// Gets the \ref HidControllerType for the specified controller. -HidControllerType hidGetControllerType(HidControllerID id); + +/// Gets a bitmask of \ref HidNpadStyleTag for the specified controller. +u32 hidGetNpadStyleSet(u32 id); + void hidGetControllerColors(HidControllerID id, HidControllerColors *colors); bool hidIsControllerConnected(HidControllerID id); @@ -851,11 +858,11 @@ Result hidGetGyroscopeZeroDriftMode(u32 SixAxisSensorHandle, HidGyroscopeZeroDri /// Resets the ::HidGyroscopeZeroDriftMode for the specified SixAxisSensorHandle to ::HidGyroscopeZeroDriftMode_Standard. Result hidResetGyroscopeZeroDriftMode(u32 SixAxisSensorHandle); -/// Sets which controller types are supported. This is automatically called with all types in \ref hidInitialize. -Result hidSetSupportedNpadStyleSet(HidControllerType type); +/// Sets which controller styles are supported, bitmask of \ref HidNpadStyleTag. This is automatically called with all styles in \ref hidInitialize. +Result hidSetSupportedNpadStyleSet(u32 style_set); -/// Gets which controller types are supported. -Result hidGetSupportedNpadStyleSet(HidControllerType *type); +/// Gets which controller styles are supported, bitmask of \ref HidNpadStyleTag. +Result hidGetSupportedNpadStyleSet(u32 *style_set); /// This is automatically called with CONTROLLER_PLAYER_{1-8} and CONTROLLER_HANDHELD in \ref hidInitialize. /// count must be <=10. Each entry in buf must be CONTROLLER_PLAYER_{1-8} or CONTROLLER_HANDHELD. @@ -888,7 +895,7 @@ Result hidSetNpadJoyAssignmentModeDual(HidControllerID id); /// If successful, the id of the resulting dual controller is set to id0. Result hidMergeSingleJoyAsDualJoy(HidControllerID id0, HidControllerID id1); -Result hidInitializeVibrationDevices(u32 *VibrationDeviceHandles, s32 total_handles, HidControllerID id, HidControllerType type); +Result hidInitializeVibrationDevices(u32 *VibrationDeviceHandles, s32 total_handles, HidControllerID id, HidNpadStyleTag style); /// Gets HidVibrationDeviceInfo for the specified VibrationDeviceHandle. Result hidGetVibrationDeviceInfo(const u32 *VibrationDeviceHandle, HidVibrationDeviceInfo *VibrationDeviceInfo); @@ -911,8 +918,8 @@ Result hidSendVibrationValues(const u32 *VibrationDeviceHandles, HidVibrationVal /// Gets whether vibration is available with the specified device. Only available on [7.0.0+]. Result hidIsVibrationDeviceMounted(const u32 *VibrationDeviceHandle, bool *flag); -/// Gets SixAxisSensorHandles. total_handles==2 can only be used with TYPE_JOYCON_PAIR. -Result hidGetSixAxisSensorHandles(u32 *SixAxisSensorHandles, s32 total_handles, HidControllerID id, HidControllerType type); +/// Gets SixAxisSensorHandles. total_handles==2 can only be used with ::HidNpadStyleTag_NpadJoyDual. +Result hidGetSixAxisSensorHandles(u32 *SixAxisSensorHandles, s32 total_handles, HidControllerID id, HidNpadStyleTag style); /// Starts the SixAxisSensor for the specified handle. Result hidStartSixAxisSensor(u32 SixAxisSensorHandle); diff --git a/nx/include/switch/services/hidsys.h b/nx/include/switch/services/hidsys.h index 14655fbd..b87833cc 100644 --- a/nx/include/switch/services/hidsys.h +++ b/nx/include/switch/services/hidsys.h @@ -158,9 +158,9 @@ Result hidsysActivateCaptureButton(void); /** * @brief Gets the SupportedNpadStyleSet for the CallerApplet. applet must be initialized in order to use this (uses \ref appletGetAppletResourceUserIdOfCallerApplet). * @note Only available on [6.0.0+]. - * @param[out] out \ref HidControllerType + * @param[out] out Bitmask of \ref HidNpadStyleTag. */ -Result hidsysGetSupportedNpadStyleSetOfCallerApplet(HidControllerType *out); +Result hidsysGetSupportedNpadStyleSetOfCallerApplet(u32 *out); /** * @brief Gets the UniquePadIds for the specified controller. diff --git a/nx/source/applets/hid_la.c b/nx/source/applets/hid_la.c index 0167bec9..2d7f52ea 100644 --- a/nx/source/applets/hid_la.c +++ b/nx/source/applets/hid_la.c @@ -92,14 +92,14 @@ static Result _hidLaShowControllerFirmwareUpdateCore(const HidLaControllerFirmwa static Result _hidLaSetupControllerSupportArgPrivate(HidLaControllerSupportArgPrivate *private_arg) { Result rc=0; - HidControllerType type; + u32 style_set; HidJoyHoldType hold_type; - rc = hidGetSupportedNpadStyleSet(&type); + rc = hidGetSupportedNpadStyleSet(&style_set); if (R_SUCCEEDED(rc)) rc = hidGetNpadJoyHoldType(&hold_type); if (R_SUCCEEDED(rc)) { - private_arg->npad_style_set = type; + private_arg->npad_style_set = style_set; private_arg->npad_joy_hold_type = hold_type; } diff --git a/nx/source/runtime/ringcon.c b/nx/source/runtime/ringcon.c index 8a99f92d..206dd645 100644 --- a/nx/source/runtime/ringcon.c +++ b/nx/source/runtime/ringcon.c @@ -56,7 +56,7 @@ Result ringconCreate(RingCon *c, HidControllerID id) { Result rc=0; bool handleflag=0; HidbusBusType bus_type; - u32 type = hidGetControllerType(id); + u32 style_set = hidGetNpadStyleSet(hidControllerIDToOfficial(id)); u32 cmd = 0x00020101; memset(c, 0, sizeof(*c)); @@ -69,9 +69,9 @@ Result ringconCreate(RingCon *c, HidControllerID id) { memset(c->workbuf, 0, c->workbuf_size); if (R_SUCCEEDED(rc)) { - if (type & TYPE_JOYCON_LEFT) + if (style_set & HidNpadStyleTag_NpadJoyLeft) bus_type = HidbusBusType_JoyLeftRail; - else if (type & (TYPE_JOYCON_RIGHT | TYPE_JOYCON_PAIR)) + else if (style_set & (HidNpadStyleTag_NpadJoyRight | HidNpadStyleTag_NpadJoyDual)) bus_type = HidbusBusType_JoyRightRail; else rc = MAKERESULT(Module_Libnx, LibnxError_BadInput); diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index c5043bda..ba451f1c 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -86,7 +86,7 @@ Result _hidInitialize(void) { rc = _hidActivateNpad(); if (R_SUCCEEDED(rc)) - rc = hidSetSupportedNpadStyleSet(TYPE_PROCONTROLLER | TYPE_HANDHELD | TYPE_JOYCON_PAIR | TYPE_JOYCON_LEFT | TYPE_JOYCON_RIGHT | TYPE_SYSTEM_EXT | TYPE_SYSTEM); + rc = hidSetSupportedNpadStyleSet(HidNpadStyleTag_NpadFullKey | HidNpadStyleTag_NpadHandheld | HidNpadStyleTag_NpadJoyDual | HidNpadStyleTag_NpadJoyLeft | HidNpadStyleTag_NpadJoyRight | HidNpadStyleTag_NpadSystemExt | HidNpadStyleTag_NpadSystem); if (R_SUCCEEDED(rc)) rc = hidSetSupportedNpadIdType(idbuf, 9); @@ -255,26 +255,26 @@ void hidScanInput(void) { memcpy(&g_controllerMisc[i], &sharedMem->controllers[i].misc, sizeof(HidControllerMisc)); if (g_sixaxisEnabled[i]) { - u32 type = g_controllerHeaders[i].type; + u32 style_set = g_controllerHeaders[i].style_set; HidControllerSixAxisLayout *sixaxis = NULL; - if (type & TYPE_PROCONTROLLER) { + if (style_set & HidNpadStyleTag_NpadFullKey) { sixaxis = &sharedMem->controllers[i].sixaxis[0]; } - else if (type & TYPE_HANDHELD) { + else if (style_set & HidNpadStyleTag_NpadHandheld) { sixaxis = &sharedMem->controllers[i].sixaxis[1]; } - else if (type & TYPE_JOYCON_PAIR) { - if (type & TYPE_JOYCON_LEFT) { + else if (style_set & HidNpadStyleTag_NpadJoyDual) { + if (style_set & HidNpadStyleTag_NpadJoyLeft) { sixaxis = &sharedMem->controllers[i].sixaxis[2]; } else { sixaxis = &sharedMem->controllers[i].sixaxis[3]; } } - else if (type & TYPE_JOYCON_LEFT) { + else if (style_set & HidNpadStyleTag_NpadJoyLeft) { sixaxis = &sharedMem->controllers[i].sixaxis[4]; } - else if (type & TYPE_JOYCON_RIGHT) { + else if (style_set & HidNpadStyleTag_NpadJoyRight) { sixaxis = &sharedMem->controllers[i].sixaxis[5]; } if (sixaxis) { @@ -290,14 +290,34 @@ void hidScanInput(void) { rwlockWriteUnlock(&g_hidLock); } -HidControllerType hidGetControllerType(HidControllerID id) { - if (id==CONTROLLER_P1_AUTO) return hidGetControllerType(g_controllerP1AutoID); - if (id < 0 || id > 9) return 0; +static Result _hidVerifyNpadIdType(u32 id) { + if (id >= 0x8 && (id!=0x10 && id!=0x20)) + return MAKERESULT(Module_Libnx, LibnxError_BadInput); - rwlockReadLock(&g_hidLock); - u32 tmp = g_controllerHeaders[id].type; - rwlockReadUnlock(&g_hidLock); + return 0; +} +static HidController *_hidNpadSharedmemGetInternalState(u32 id) { + if (id >= 0x8) id = id==0x10 ? 0x9 : 0x8; + + HidSharedMemory *sharedmem = (HidSharedMemory*)hidGetSharedmemAddr(); + if (sharedmem == NULL) return NULL; + return &sharedmem->controllers[id]; +} + +u32 hidGetNpadStyleSet(u32 id) { + Result rc = _hidVerifyNpadIdType(id); + u32 tmp=0; + + if (R_SUCCEEDED(rc)) { + HidController *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else + tmp = atomic_load_explicit(&npad->header.style_set, memory_order_acquire); + } + + if (R_FAILED(rc)) diagAbortWithResult(rc); return tmp; } @@ -395,19 +415,11 @@ void hidGetControllerPowerInfo(HidControllerID id, HidPowerInfo *info, size_t to } } -static HidController *_hidNpadSharedmemGetInternalState(u32 id) { - if (id >= 0x8) id = id==0x10 ? 0x9 : 0x8; - - HidSharedMemory *sharedmem = (HidSharedMemory*)hidGetSharedmemAddr(); - if (sharedmem == NULL) return NULL; - return &sharedmem->controllers[id]; -} - static Result _hidGetNpadStates(u32 id, u32 layout, HidNpadStateEntry *states, size_t count, size_t *total_out) { if (total_out) *total_out = 0; - if (id >= 0x8 && (id!=0x10 && id!=0x20)) - return MAKERESULT(Module_Libnx, LibnxError_BadInput); + Result rc = _hidVerifyNpadIdType(id); + if (R_FAILED(rc)) return rc; HidController *npad = _hidNpadSharedmemGetInternalState(id); if (npad == NULL) @@ -881,14 +893,14 @@ Result hidResetGyroscopeZeroDriftMode(u32 SixAxisSensorHandle) { return _hidCmdWithInputU32(SixAxisSensorHandle, 81); } -Result hidSetSupportedNpadStyleSet(HidControllerType type) { - return _hidCmdWithInputU32(type, 100); +Result hidSetSupportedNpadStyleSet(u32 style_set) { + return _hidCmdWithInputU32(style_set, 100); } -Result hidGetSupportedNpadStyleSet(HidControllerType *type) { +Result hidGetSupportedNpadStyleSet(u32 *style_set) { u32 tmp=0; Result rc = _hidCmdOutU32(&tmp, 101); - if (R_SUCCEEDED(rc) && type) *type = tmp; + if (R_SUCCEEDED(rc) && style_set) *style_set = tmp; return rc; } @@ -1068,38 +1080,61 @@ Result hidIsVibrationDeviceMounted(const u32 *VibrationDeviceHandle, bool *flag) return rc; } -static Result _hidGetDeviceHandles(u32 devicetype, u32 *DeviceHandles, s32 total_handles, HidControllerID id, HidControllerType type) { +static Result _hidGetDeviceHandles(u32 devicetype, u32 *DeviceHandles, s32 total_handles, HidControllerID id, HidNpadStyleTag style) { Result rc=0; - u32 tmp_type = type & 0xff; - u32 tmp_id = id; + u32 tmp_type=0; + u32 tmp_id=0; if (total_handles <= 0 || total_handles > 2 || devicetype > 1) return MAKERESULT(Module_Libnx, LibnxError_BadInput); - if (tmp_id == CONTROLLER_HANDHELD) - tmp_id = 0x20; + tmp_id = hidControllerIDToOfficial(id); - if (tmp_type & TYPE_PROCONTROLLER) { + if (style & HidNpadStyleTag_NpadFullKey) { tmp_type = 3; } - else if (tmp_type & TYPE_HANDHELD) { + else if (style & HidNpadStyleTag_NpadHandheld) { tmp_type = 4; } - else if (tmp_type & TYPE_JOYCON_PAIR) { + else if (style & HidNpadStyleTag_NpadJoyDual) { tmp_type = 5; } - else if (tmp_type & TYPE_JOYCON_LEFT) { + else if (style & HidNpadStyleTag_NpadJoyLeft) { tmp_type = 6; } - else if (tmp_type & TYPE_JOYCON_RIGHT) { + else if (style & HidNpadStyleTag_NpadJoyRight) { tmp_type = 7; tmp_type |= 0x010000; } - else if (tmp_type & TYPE_SYSTEM_EXT) { + else if (style & HidNpadStyleTag_NpadGc) { + if (devicetype==0) + tmp_type = 8; + else + tmp_type = 3; + } + else if (style & HidNpadStyleTag_Npad10) { + if (devicetype==0) + tmp_type = 0xd; + else + return MAKERESULT(Module_Libnx, LibnxError_BadInput); // sdknso would return 0, and return no handles. + } + else if (style & (HidNpadStyleTag_NpadLark | HidNpadStyleTag_NpadLucia)) { + return MAKERESULT(Module_Libnx, LibnxError_BadInput); // sdknso would return 0, and return no handles. + } + else if (style & HidNpadStyleTag_NpadHandheldLark) { + tmp_type = 4; + } + else if (style & HidNpadStyleTag_NpadSystem) { + if (devicetype==1) return MAKERESULT(Module_Libnx, LibnxError_BadInput); // sdknso would return 0, and return no handles. + tmp_type = 0x21; + } + else if (style & HidNpadStyleTag_NpadSystemExt) { + if (devicetype==1) return MAKERESULT(Module_Libnx, LibnxError_BadInput); // sdknso would return 0, and return no handles. tmp_type = 0x20; } - else if (tmp_type & TYPE_SYSTEM) { - tmp_type = 0x21; + else if (style & HidNpadStyleTag_NpadPalma) { + if (devicetype==0) return MAKERESULT(Module_Libnx, LibnxError_BadInput); // sdknso would return 0, and return no handles. + tmp_type = 3; } else { return MAKERESULT(Module_Libnx, LibnxError_BadInput); @@ -1112,25 +1147,25 @@ static Result _hidGetDeviceHandles(u32 devicetype, u32 *DeviceHandles, s32 total if (total_handles > 1) { tmp_type &= 0xff; - if (devicetype==0 && (tmp_type!=6 && tmp_type!=7)) { + if (devicetype==0 && (tmp_type!=6 && tmp_type!=7 && tmp_type!=8 && tmp_type!=0xd)) { DeviceHandles[1] = DeviceHandles[0] | 0x010000; } else if (devicetype==1 && tmp_type==5) { DeviceHandles[1] = DeviceHandles[0] | 0x010000; } else { - return MAKERESULT(Module_Libnx, LibnxError_BadInput); + return MAKERESULT(Module_Libnx, LibnxError_BadInput); // sdknso would just return 0 here. } } return rc; } -Result hidInitializeVibrationDevices(u32 *VibrationDeviceHandles, s32 total_handles, HidControllerID id, HidControllerType type) { +Result hidInitializeVibrationDevices(u32 *VibrationDeviceHandles, s32 total_handles, HidControllerID id, HidNpadStyleTag style) { Result rc=0; s32 i; - rc = _hidGetDeviceHandles(0, VibrationDeviceHandles, total_handles, id, type); + rc = _hidGetDeviceHandles(0, VibrationDeviceHandles, total_handles, id, style); if (R_FAILED(rc)) return rc; rwlockWriteLock(&g_hidLock); @@ -1150,8 +1185,8 @@ Result hidInitializeVibrationDevices(u32 *VibrationDeviceHandles, s32 total_hand return rc; } -Result hidGetSixAxisSensorHandles(u32 *SixAxisSensorHandles, s32 total_handles, HidControllerID id, HidControllerType type) { - return _hidGetDeviceHandles(1, SixAxisSensorHandles, total_handles, id, type); +Result hidGetSixAxisSensorHandles(u32 *SixAxisSensorHandles, s32 total_handles, HidControllerID id, HidNpadStyleTag style) { + return _hidGetDeviceHandles(1, SixAxisSensorHandles, total_handles, id, style); } Result hidStartSixAxisSensor(u32 SixAxisSensorHandle) { diff --git a/nx/source/services/hidsys.c b/nx/source/services/hidsys.c index c9192a82..f61a1236 100644 --- a/nx/source/services/hidsys.c +++ b/nx/source/services/hidsys.c @@ -161,7 +161,7 @@ Result hidsysActivateCaptureButton(void) { return _hidsysCmdWithResIdAndPid(151); } -static Result _hidsysGetMaskedSupportedNpadStyleSet(u64 AppletResourceUserId, HidControllerType *out) { +static Result _hidsysGetMaskedSupportedNpadStyleSet(u64 AppletResourceUserId, u32 *out) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); @@ -171,7 +171,7 @@ static Result _hidsysGetMaskedSupportedNpadStyleSet(u64 AppletResourceUserId, Hi return rc; } -Result hidsysGetSupportedNpadStyleSetOfCallerApplet(HidControllerType *out) { +Result hidsysGetSupportedNpadStyleSetOfCallerApplet(u32 *out) { u64 AppletResourceUserId=0; Result rc=0;