diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 0cc62433..8c020cbd 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -231,17 +231,6 @@ typedef enum { HidNpadStyleTag_NpadSystem = BIT(30), ///< Generic controller } HidNpadStyleTag; -/// HidControllerLayoutType -typedef enum { - LAYOUT_PROCONTROLLER = 0, ///< Pro Controller or Hid gamepad. - LAYOUT_HANDHELD = 1, ///< Two Joy-Con docked to rails. - LAYOUT_SINGLE = 2, ///< Single Joy-Con or pair of Joy-Con, only available in dual-mode with no orientation adjustment. - LAYOUT_LEFT = 3, ///< Only single-mode raw left Joy-Con state, no orientation adjustment. - LAYOUT_RIGHT = 4, ///< Only single-mode raw right Joy-Con state, no orientation adjustment. - LAYOUT_DEFAULT_DIGITAL = 5, ///< Same as next, but sticks have 8-direction values only. - LAYOUT_DEFAULT = 6, ///< Safe default. Single-mode and ::HidJoyHoldType_Horizontal: Joy-Con have buttons/sticks rotated for orientation, where physical Z(L/R) are unavailable and S(L/R) are mapped to L/R (with physical L/R unavailable). -} HidControllerLayoutType; - /// HidControllerColorDescription typedef enum { COLORS_NONEXISTENT = BIT(1), @@ -340,9 +329,15 @@ typedef enum { /// JoyHoldType typedef enum { HidJoyHoldType_Default = 0, ///< Default / Joy-Con held vertically. - HidJoyHoldType_Horizontal = 1, ///< Joy-Con held horizontally with HID state orientation adjustment, see \ref HidControllerLayoutType. + HidJoyHoldType_Horizontal = 1, ///< Joy-Con held horizontally with HID state orientation adjustment. } HidJoyHoldType; +/// NpadJoyAssignmentMode +typedef enum { + HidNpadJoyAssignmentMode_Dual = 0, ///< Dual (Set by \ref hidSetNpadJoyAssignmentModeDual) + HidNpadJoyAssignmentMode_Single = 1, ///< Single (Set by hidSetNpadJoyAssignmentModeSingle*()) +} HidNpadJoyAssignmentMode; + /// DeviceType typedef enum { HidDeviceTypeBits_FullKey = BIT(0), ///< Pro Controller and Gc controller. @@ -442,6 +437,14 @@ typedef struct SixAxisSensorValues { // End enums and output structs +/// HidCommonStateHeader +typedef struct HidCommonStateHeader { + u64 timestamp_ticks; + u64 total_entries; + u64 latest_entry; + u64 max_entry; +} HidCommonStateHeader; + // Begin HidTouchScreen /// HidTouchScreenHeader @@ -490,14 +493,6 @@ typedef struct HidTouchScreen { // Begin HidMouse -/// HidMouseHeader -typedef struct HidMouseHeader { - u64 timestampTicks; - u64 numEntries; - u64 latestEntry; - u64 maxEntryIndex; -} HidMouseHeader; - /// HidMouseEntry typedef struct HidMouseEntry { u64 timestamp; @@ -508,7 +503,7 @@ typedef struct HidMouseEntry { /// HidMouse typedef struct HidMouse { - HidMouseHeader header; + HidCommonStateHeader header; HidMouseEntry entries[17]; u8 padding[0xB0]; } HidMouse; @@ -517,14 +512,6 @@ typedef struct HidMouse { // Begin HidKeyboard -/// HidKeyboardHeader -typedef struct HidKeyboardHeader { - u64 timestampTicks; - u64 numEntries; - u64 latestEntry; - u64 maxEntryIndex; -} HidKeyboardHeader; - /// HidKeyboardEntry typedef struct HidKeyboardEntry { u64 timestamp; @@ -535,7 +522,7 @@ typedef struct HidKeyboardEntry { /// HidKeyboard typedef struct HidKeyboard { - HidKeyboardHeader header; + HidCommonStateHeader header; HidKeyboardEntry entries[17]; u8 padding[0x28]; } HidKeyboard; @@ -544,51 +531,25 @@ typedef struct HidKeyboard { // Begin HidNpad -/// HidControllerMAC -typedef struct HidControllerMAC { - u64 timestamp; - u8 mac[0x8]; - u64 unk; - u64 timestamp_2; -} HidControllerMAC; +/// Npad colors. +/// Color fields are zero when not set. +typedef struct HidNpadControllerColor +{ + u32 color_body; ///< RGBA Body Color + u32 color_buttons; ///< RGBA Buttons Color +} HidNpadControllerColor; /// HidNpadStateHeader typedef struct HidNpadStateHeader { u32 style_set; - u32 isHalf; - u32 singleColorsDescriptor; - u32 singleColorBody; - u32 singleColorButtons; - u32 splitColorsDescriptor; - u32 leftColorBody; - u32 leftColorButtons; - u32 rightColorBody; - u32 rightColorButtons; + u32 npad_joy_assignment_mode; + u32 single_colors_descriptor; + HidNpadControllerColor single_colors; + u32 split_colors_descriptor; + HidNpadControllerColor left_colors; + HidNpadControllerColor right_colors; } HidNpadStateHeader; -/// Info struct extracted from HidNpadStateHeader. -/// Color fields are zero when not set. This can happen even when the *Set fields are set to true. -typedef struct HidNpadControllerColor -{ - bool singleSet; ///< Set to true when the below fields are valid. - u32 singleColorBody; ///< RGBA Single Body Color - u32 singleColorButtons; ///< RGBA Single Buttons Color - - bool splitSet; ///< Set to true when the below fields are valid. - u32 leftColorBody; ///< RGBA Left Body Color - u32 leftColorButtons; ///< RGBA Left Buttons Color - u32 rightColorBody; ///< RGBA Right Body Color - u32 rightColorButtons; ///< RGBA Right Buttons Color -} HidNpadControllerColor; - -/// HidControllerLayoutHeader -typedef struct HidControllerLayoutHeader { - u64 timestamp_ticks; - u64 total_entries; - u64 latest_entry; - u64 max_entry; -} HidControllerLayoutHeader; - /// HidNpadStateEntry typedef struct HidNpadStateEntry { u64 timestamp; @@ -611,18 +572,10 @@ typedef struct HidControllerInputEntry { /// HidControllerLayout typedef struct HidControllerLayout { - HidControllerLayoutHeader header; + HidCommonStateHeader header; HidControllerInputEntry entries[17]; } HidControllerLayout; -/// HidNpadSixAxisSensorHeader -typedef struct HidNpadSixAxisSensorHeader { - u64 timestamp; - u64 numEntries; - u64 latestEntry; - u64 maxEntryIndex; -} HidNpadSixAxisSensorHeader; - /// HidNpadSixAxisSensorState typedef struct HidNpadSixAxisSensorState { u64 timestamp; @@ -634,11 +587,11 @@ typedef struct HidNpadSixAxisSensorState { /// HidControllerSixAxisLayout typedef struct HidControllerSixAxisLayout { - HidNpadSixAxisSensorHeader header; + HidCommonStateHeader header; HidNpadSixAxisSensorState entries[17]; } HidControllerSixAxisLayout; -/// Controller flags. +/// NpadSystemProperties typedef struct { u32 powerInfo : 6; ///< Use \ref hidGetControllerPowerInfo instead of accessing this directly. @@ -655,20 +608,12 @@ typedef struct { u32 directionalButtonsSupported : 1; ///< [8.0.0+] u32 unused; +} HidNpadSystemProperties; - u32 unintendedHomeButtonInputProtectionDisabled : 1; -} HidFlags; - -/// HidControllerMisc +/// NpadSystemButtonProperties typedef struct { - u32 deviceType; - u32 pad; - HidFlags flags; - u32 batteryCharge[3]; - u8 unk_1[0x20]; - HidControllerMAC macLeft; - HidControllerMAC macRight; -} HidControllerMisc; + u32 unintendedHomeButtonInputProtectionDisabled : 1; +} HidNpadSystemButtonProperties; /// HidPowerInfo typedef struct { @@ -677,12 +622,43 @@ typedef struct { u32 batteryCharge; ///< Battery charge, always 0-4. } HidPowerInfo; +/// HidNfcXcdDeviceHandleState +typedef struct HidNfcXcdDeviceHandleState { + u64 handle; + u8 flag0; + u8 flag1; + u8 pad[6]; + u64 timestamp; +} HidNfcXcdDeviceHandleState; + +/// HidNfcXcdDeviceHandleStateEntry +typedef struct HidNfcXcdDeviceHandleStateEntry { + u64 timestamp; + HidNfcXcdDeviceHandleState state; +} HidNfcXcdDeviceHandleStateEntry; + /// HidNpad typedef struct HidNpad { HidNpadStateHeader header; HidControllerLayout layouts[7]; HidControllerSixAxisLayout sixaxis[6]; - HidControllerMisc misc; + u32 deviceType; + u32 pad; + HidNpadSystemProperties system_properties; + HidNpadSystemButtonProperties system_button_properties; + u32 batteryCharge[3]; + union { + struct { // [1.0.0-3.0.2] + u8 nfc_xcd_device_handle_header[0x20]; + HidNfcXcdDeviceHandleStateEntry nfc_xcd_device_handle_state[2]; + }; + + struct { + u32 applet_footer_ui_attribute; + u8 applet_footer_ui_type; + u8 unk_x41AD[0x5B]; + }; + }; u8 unk_2[0xDF8]; } HidNpad; @@ -785,25 +761,36 @@ Service* hidGetServiceSession(void); /// Gets the address of the SharedMemory. void* hidGetSharedmemAddr(void); -void hidSetControllerLayout(HidControllerID id, HidControllerLayoutType layoutType); -HidControllerLayoutType hidGetControllerLayout(HidControllerID id); +void hidScanInput(void); -/// Gets a bitmask of \ref HidNpadStyleTag for the specified controller. +/// Gets a bitfield of \ref HidNpadStyleTag for the specified controller. u32 hidGetNpadStyleSet(u32 id); -void hidGetControllerColors(HidControllerID id, HidNpadControllerColor *colors); -bool hidIsControllerConnected(HidControllerID id); +/// Gets the \ref HidNpadJoyAssignmentMode for the specified controller. +HidNpadJoyAssignmentMode hidGetNpadJoyAssignment(u32 id); + +/// Gets the \ref HidNpadControllerColor for the specified controller. colors is the output array, where count is the number of entries. count must be 1 or 2: former for the main colors, latter for reading left/right colors. +Result hidGetNpadControllerColor(u32 id, HidNpadControllerColor *colors, size_t count); /// Gets the \ref HidDeviceTypeBits for the specified controller. -u32 hidGetControllerDeviceType(HidControllerID id); +u32 hidGetNpadDeviceType(u32 id); -/// Gets the flags for the specified controller. -void hidGetControllerFlags(HidControllerID id, HidFlags *flags); +/// Gets the \ref HidNpadSystemProperties for the specified controller. +void hidGetNpadSystemProperties(u32 id, HidNpadSystemProperties *out); -/// Gets the \ref HidPowerInfo for the specified controller. info is the output array, where total_info is the number of entries. total_info must be 1 or 2: former for the main battery info, latter for reading left/right Joy-Con PowerInfo. -void hidGetControllerPowerInfo(HidControllerID id, HidPowerInfo *info, size_t total_info); +/// Gets the \ref HidNpadSystemButtonProperties for the specified controller. +void hidGetNpadSystemButtonProperties(u32 id, HidNpadSystemButtonProperties *out); -void hidScanInput(void); +/// Gets the \ref HidPowerInfo for the specified controller. info is the output array, where count is the number of entries. count must be 1 or 2: former for the main battery info, latter for reading left/right Joy-Con PowerInfo. +void hidGetNpadPowerInfo(u32 id, HidPowerInfo *info, size_t count); + +/// Gets a bitfield of AppletFooterUiAttributes for the specified Npad. +/// Only available on [9.0.0+]. +u32 hidGetAppletFooterUiAttributesSet(u32 id); + +/// Gets AppletFooterUiTypes for the specified Npad. +/// Only available on [9.0.0+]. +u8 hidGetAppletFooterUiTypes(u32 id); void hidGetNpadStatesFullKey(u32 id, HidNpadFullKeyState *states, size_t count, size_t *total_out); void hidGetNpadStatesHandheld(u32 id, HidNpadHandheldState *states, size_t count, size_t *total_out); @@ -811,6 +798,8 @@ void hidGetNpadStatesJoyDual(u32 id, HidNpadJoyDualState *states, size_t count, void hidGetNpadStatesJoyLeft(u32 id, HidNpadJoyLeftState *states, size_t count, size_t *total_out); void hidGetNpadStatesJoyRight(u32 id, HidNpadJoyRightState *states, size_t count, size_t *total_out); +bool hidIsControllerConnected(HidControllerID id); + u64 hidKeysHeld(HidControllerID id); u64 hidKeysDown(HidControllerID id); u64 hidKeysUp(HidControllerID id); @@ -857,10 +846,10 @@ Result hidGetGyroscopeZeroDriftMode(u32 SixAxisSensorHandle, HidGyroscopeZeroDri /// Resets the ::HidGyroscopeZeroDriftMode for the specified SixAxisSensorHandle to ::HidGyroscopeZeroDriftMode_Standard. Result hidResetGyroscopeZeroDriftMode(u32 SixAxisSensorHandle); -/// Sets which controller styles are supported, bitmask of \ref HidNpadStyleTag. This is automatically called with all styles in \ref hidInitialize. +/// Sets which controller styles are supported, bitfield of \ref HidNpadStyleTag. This is automatically called with all styles in \ref hidInitialize. Result hidSetSupportedNpadStyleSet(u32 style_set); -/// Gets which controller styles are supported, bitmask of \ref HidNpadStyleTag. +/// Gets which controller styles are supported, bitfield of \ref HidNpadStyleTag. Result hidGetSupportedNpadStyleSet(u32 *style_set); /// This is automatically called with CONTROLLER_PLAYER_{1-8} and CONTROLLER_HANDHELD in \ref hidInitialize. diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index d364faa6..1112e098 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -20,10 +20,8 @@ static HidTouchScreenEntry g_touchEntry; static HidMouseEntry *g_mouseEntry; static HidMouse g_mouse; static HidKeyboardEntry g_keyboardEntry; -static HidNpadStateHeader g_controllerHeaders[10]; -static HidControllerInputEntry g_controllerEntries[10]; +static HidNpadStateEntry g_controllerEntries[10]; static HidControllerSixAxisLayout g_sixaxisLayouts[10]; -static HidControllerMisc g_controllerMisc[10]; static u64 g_mouseOld, g_mouseHeld, g_mouseDown, g_mouseUp; static u64 g_keyboardModOld, g_keyboardModHeld, g_keyboardModDown, g_keyboardModUp; @@ -31,8 +29,7 @@ static u32 g_keyboardOld[8], g_keyboardHeld[8], g_keyboardDown[8], g_keyboardUp[ static u64 g_controllerOld[10], g_controllerHeld[10], g_controllerDown[10], g_controllerUp[10]; static bool g_sixaxisEnabled[10]; -static HidControllerLayoutType g_controllerLayout[10]; -static u64 g_touchTimestamp, g_mouseTimestamp, g_keyboardTimestamp, g_controllerTimestamps[10]; +static u64 g_touchTimestamp, g_mouseTimestamp, g_keyboardTimestamp; static HidControllerID g_controllerP1AutoID; @@ -124,9 +121,7 @@ void hidReset(void) { memset(&g_touchEntry, 0, sizeof(HidTouchScreenEntry)); memset(&g_mouse, 0, sizeof(HidMouse)); memset(&g_keyboardEntry, 0, sizeof(HidKeyboardEntry)); - memset(g_controllerHeaders, 0, sizeof(g_controllerHeaders)); memset(g_controllerEntries, 0, sizeof(g_controllerEntries)); - memset(g_controllerMisc, 0, sizeof(g_controllerMisc)); memset(g_sixaxisLayouts, 0, sizeof(g_sixaxisLayouts)); memset(g_sixaxisEnabled, 0, sizeof(g_sixaxisEnabled)); @@ -138,12 +133,7 @@ void hidReset(void) { for (int i = 0; i < 10; i++) g_controllerOld[i] = g_controllerHeld[i] = g_controllerDown[i] = g_controllerUp[i] = 0; - for (int i = 0; i < 10; i++) - g_controllerLayout[i] = LAYOUT_DEFAULT; - g_touchTimestamp = g_mouseTimestamp = g_keyboardTimestamp = 0; - for (int i = 0; i < 10; i++) - g_controllerTimestamps[i] = 0; g_controllerP1AutoID = CONTROLLER_HANDHELD; @@ -158,24 +148,6 @@ void* hidGetSharedmemAddr(void) { return shmemGetAddr(&g_hidSharedmem); } -void hidSetControllerLayout(HidControllerID id, HidControllerLayoutType layoutType) { - if (id < 0 || id > 9) return; - - rwlockWriteLock(&g_hidLock); - g_controllerLayout[id] = layoutType; - rwlockWriteUnlock(&g_hidLock); -} - -HidControllerLayoutType hidGetControllerLayout(HidControllerID id) { - if (id < 0 || id > 9) return LAYOUT_DEFAULT; - - rwlockReadLock(&g_hidLock); - HidControllerLayoutType tmp = g_controllerLayout[id]; - rwlockReadUnlock(&g_hidLock); - - return tmp; -} - void hidScanInput(void) { rwlockWriteLock(&g_hidLock); @@ -194,7 +166,6 @@ void hidScanInput(void) { memset(&g_mouse, 0, sizeof(HidMouse)); memset(&g_keyboardEntry, 0, sizeof(HidKeyboardEntry)); memset(g_controllerEntries, 0, sizeof(g_controllerEntries)); - memset(g_controllerMisc, 0, sizeof(g_controllerMisc)); memset(g_sixaxisLayouts, 0, sizeof(g_sixaxisLayouts)); u64 latestTouchEntry = sharedMem->touchscreen.header.latestEntry; @@ -207,7 +178,7 @@ void hidScanInput(void) { g_controllerHeld[CONTROLLER_HANDHELD] |= KEY_TOUCH; } - u64 latestMouseEntry = sharedMem->mouse.header.latestEntry; + u64 latestMouseEntry = sharedMem->mouse.header.latest_entry; HidMouseEntry *newMouseEntry = &sharedMem->mouse.entries[latestMouseEntry]; memcpy(&g_mouse, &sharedMem->mouse, sizeof(HidMouse)); if ((s64)(newMouseEntry->timestamp - g_mouseTimestamp) >= 0) { @@ -219,43 +190,74 @@ void hidScanInput(void) { g_mouseDown = (~g_mouseOld) & g_mouseHeld; g_mouseUp = g_mouseOld & (~g_mouseHeld); - u64 latestKeyboardEntry = sharedMem->keyboard.header.latestEntry; + u64 latestKeyboardEntry = sharedMem->keyboard.header.latest_entry; HidKeyboardEntry *newKeyboardEntry = &sharedMem->keyboard.entries[latestKeyboardEntry]; if ((s64)(newKeyboardEntry->timestamp - g_keyboardTimestamp) >= 0) { memcpy(&g_keyboardEntry, newKeyboardEntry, sizeof(HidKeyboardEntry)); g_keyboardTimestamp = newKeyboardEntry->timestamp; g_keyboardModHeld = g_keyboardEntry.modifier; - for (int i = 0; i < 8; i++) { + for (u32 i = 0; i < 8; i++) { g_keyboardHeld[i] = g_keyboardEntry.keys[i]; } } g_keyboardModDown = (~g_keyboardModOld) & g_keyboardModHeld; g_keyboardModUp = g_keyboardModOld & (~g_keyboardModHeld); - for (int i = 0; i < 8; i++) { + for (u32 i = 0; i < 8; i++) { g_keyboardDown[i] = (~g_keyboardOld[i]) & g_keyboardHeld[i]; g_keyboardUp[i] = g_keyboardOld[i] & (~g_keyboardHeld[i]); } - for (int i = 0; i < 10; i++) { - HidControllerLayout *currentLayout = &sharedMem->npad[i].layouts[g_controllerLayout[i]]; - memcpy(&g_controllerHeaders[i], &sharedMem->npad[i].header, sizeof(HidNpadStateHeader)); - u64 latestControllerEntry = currentLayout->header.latest_entry; - HidControllerInputEntry *newInputEntry = ¤tLayout->entries[latestControllerEntry]; - if ((s64)(newInputEntry->timestamp - g_controllerTimestamps[i]) >= 0) { - memcpy(&g_controllerEntries[i], newInputEntry, sizeof(HidControllerInputEntry)); - g_controllerTimestamps[i] = newInputEntry->timestamp; + for (u32 i = 0; i < 10; i++) { + u32 id = hidControllerIDToOfficial(i); + u32 style_set = hidGetNpadStyleSet(id); + size_t total_out=0; - g_controllerHeld[i] |= g_controllerEntries[i].state.buttons; + if (style_set & HidNpadStyleTag_NpadFullKey) { + HidNpadFullKeyState state={0}; + hidGetNpadStatesFullKey(id, &state, 1, &total_out); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadHandheld) { + HidNpadHandheldState state={0}; + hidGetNpadStatesHandheld(id, &state, 1, &total_out); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadJoyDual) { + HidNpadJoyDualState state={0}; + hidGetNpadStatesJoyDual(id, &state, 1, &total_out); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadJoyLeft) { + HidNpadJoyLeftState state={0}; + hidGetNpadStatesJoyLeft(id, &state, 1, &total_out); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadJoyRight) { + HidNpadJoyRightState state={0}; + hidGetNpadStatesJoyRight(id, &state, 1, &total_out); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } } g_controllerDown[i] = (~g_controllerOld[i]) & g_controllerHeld[i]; g_controllerUp[i] = g_controllerOld[i] & (~g_controllerHeld[i]); - memcpy(&g_controllerMisc[i], &sharedMem->npad[i].misc, sizeof(HidControllerMisc)); - if (g_sixaxisEnabled[i]) { - u32 style_set = g_controllerHeaders[i].style_set; HidControllerSixAxisLayout *sixaxis = NULL; if (style_set & HidNpadStyleTag_NpadFullKey) { sixaxis = &sharedMem->npad[i].sixaxis[0]; @@ -284,7 +286,7 @@ void hidScanInput(void) { } g_controllerP1AutoID = CONTROLLER_HANDHELD; - if (g_controllerEntries[CONTROLLER_PLAYER_1].state.connectionState & CONTROLLER_STATE_CONNECTED) + if (g_controllerEntries[CONTROLLER_PLAYER_1].connectionState & CONTROLLER_STATE_CONNECTED) g_controllerP1AutoID = CONTROLLER_PLAYER_1; rwlockWriteUnlock(&g_hidLock); @@ -321,98 +323,158 @@ u32 hidGetNpadStyleSet(u32 id) { return tmp; } -void hidGetControllerColors(HidControllerID id, HidNpadControllerColor *colors) { - if (id==CONTROLLER_P1_AUTO) { - hidGetControllerColors(g_controllerP1AutoID, colors); - return; - } - if (id < 0 || id > 9) return; - if (colors == NULL) return; +HidNpadJoyAssignmentMode hidGetNpadJoyAssignment(u32 id) { + Result rc = _hidVerifyNpadIdType(id); + HidNpadJoyAssignmentMode tmp=0; - HidNpadStateHeader *hdr = &g_controllerHeaders[id]; - - memset(colors, 0, sizeof(HidNpadControllerColor)); - - rwlockReadLock(&g_hidLock); - - colors->singleSet = (hdr->singleColorsDescriptor & BIT(1)) == 0; - colors->splitSet = (hdr->splitColorsDescriptor & BIT(1)) == 0; - - if (colors->singleSet) { - colors->singleColorBody = hdr->singleColorBody; - colors->singleColorButtons = hdr->singleColorButtons; + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else { + tmp = atomic_load_explicit(&npad->header.npad_joy_assignment_mode, memory_order_acquire); + if (tmp != HidNpadJoyAssignmentMode_Dual && tmp != HidNpadJoyAssignmentMode_Single) + rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen); + } } - if (colors->splitSet) { - colors->leftColorBody = hdr->leftColorBody; - colors->leftColorButtons = hdr->leftColorButtons; - colors->rightColorBody = hdr->rightColorBody; - colors->rightColorButtons = hdr->rightColorButtons; + if (R_FAILED(rc)) diagAbortWithResult(rc); + return tmp; +} + +Result hidGetNpadControllerColor(u32 id, HidNpadControllerColor *colors, size_t count) { + Result rc = _hidVerifyNpadIdType(id); + u32 tmp=0; + + if (count==0) return rc; + + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else { + tmp = count==1 ? npad->header.single_colors_descriptor : npad->header.split_colors_descriptor; + if (tmp==2) rc = MAKERESULT(202, 604); + else if (tmp==1) rc = MAKERESULT(202, 603); + else if (tmp!=0) diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen)); + + if (R_SUCCEEDED(rc)) { + if (count==1) colors[0] = npad->header.single_colors; + else { + colors[0] = npad->header.left_colors; + colors[1] = npad->header.right_colors; + } + } + } } - rwlockReadUnlock(&g_hidLock); + return rc; } -bool hidIsControllerConnected(HidControllerID id) { - if (id==CONTROLLER_P1_AUTO) - return hidIsControllerConnected(g_controllerP1AutoID); - if (id < 0 || id > 9) return 0; +u32 hidGetNpadDeviceType(u32 id) { + Result rc = _hidVerifyNpadIdType(id); + u32 tmp=0; - rwlockReadLock(&g_hidLock); - bool flag = (g_controllerEntries[id].state.connectionState & CONTROLLER_STATE_CONNECTED) != 0; - rwlockReadUnlock(&g_hidLock); - return flag; -} - -u32 hidGetControllerDeviceType(HidControllerID id) { - if (id==CONTROLLER_P1_AUTO) - return hidGetControllerDeviceType(g_controllerP1AutoID); - if (id < 0 || id > 9) return 0; - - rwlockReadLock(&g_hidLock); - u32 type = g_controllerMisc[id].deviceType; - rwlockReadUnlock(&g_hidLock); - return type; -} - -void hidGetControllerFlags(HidControllerID id, HidFlags *flags) { - if (id==CONTROLLER_P1_AUTO) { - hidGetControllerFlags(g_controllerP1AutoID, flags); - return; + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else + tmp = atomic_load_explicit(&npad->deviceType, memory_order_acquire); } - if (id < 0 || id > 9) return; - rwlockReadLock(&g_hidLock); - *flags = g_controllerMisc[id].flags; - rwlockReadUnlock(&g_hidLock); + if (R_FAILED(rc)) diagAbortWithResult(rc); + return tmp; } -void hidGetControllerPowerInfo(HidControllerID id, HidPowerInfo *info, size_t total_info) { +void hidGetNpadSystemProperties(u32 id, HidNpadSystemProperties *out) { + Result rc = _hidVerifyNpadIdType(id); + + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else + *out = atomic_load_explicit(&npad->system_properties, memory_order_acquire); + } + + if (R_FAILED(rc)) diagAbortWithResult(rc); +} + +void hidGetNpadSystemButtonProperties(u32 id, HidNpadSystemButtonProperties *out) { + Result rc = _hidVerifyNpadIdType(id); + + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else + *out = atomic_load_explicit(&npad->system_button_properties, memory_order_acquire); + } + + if (R_FAILED(rc)) diagAbortWithResult(rc); +} + +void hidGetNpadPowerInfo(u32 id, HidPowerInfo *info, size_t count) { + Result rc = _hidVerifyNpadIdType(id); size_t i; size_t indexbase; - HidFlags flags; + HidNpadSystemProperties properties; - if (id==CONTROLLER_P1_AUTO) { - hidGetControllerPowerInfo(g_controllerP1AutoID, info, total_info); - return; + if (count == 0) return; + if (count > 2) count = 2; + indexbase = count-1; + + hidGetNpadSystemProperties(id, &properties); + + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else { + for (i=0; ibatteryCharge[indexbase+i], memory_order_acquire); + if (info[i].batteryCharge > 4) info->batteryCharge = 4; // sdknso would Abort when this occurs. + + info[i].isCharging = (properties.powerInfo & BIT(indexbase+i)) != 0; + info[i].powerConnected = (properties.powerInfo & BIT(indexbase+i+3)) != 0; + } + } } - if (id < 0 || id > 9) return; - if (total_info == 0) return; - if (total_info > 2) total_info = 2; - indexbase = total_info-1; + if (R_FAILED(rc)) diagAbortWithResult(rc); +} - hidGetControllerFlags(id, &flags); +u32 hidGetAppletFooterUiAttributesSet(u32 id) { + Result rc = _hidVerifyNpadIdType(id); + u32 tmp=0; - for (i=0; i 4) info->batteryCharge = 4; + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else + tmp = atomic_load_explicit(&npad->applet_footer_ui_attribute, memory_order_acquire); } + + if (R_FAILED(rc)) diagAbortWithResult(rc); + return tmp; +} + +u8 hidGetAppletFooterUiTypes(u32 id) { + Result rc = _hidVerifyNpadIdType(id); + u32 tmp=0; + + if (R_SUCCEEDED(rc)) { + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + rc = MAKERESULT(Module_Libnx, LibnxError_NotInitialized); + else + tmp = atomic_load_explicit(&npad->applet_footer_ui_type, memory_order_acquire); + } + + if (R_FAILED(rc)) diagAbortWithResult(rc); + return tmp; } static Result _hidGetNpadStates(u32 id, u32 layout, HidNpadStateEntry *states, size_t count, size_t *total_out) { @@ -483,6 +545,17 @@ void hidGetNpadStatesJoyRight(u32 id, HidNpadJoyRightState *states, size_t count if (R_FAILED(rc)) diagAbortWithResult(rc); } +bool hidIsControllerConnected(HidControllerID id) { + if (id==CONTROLLER_P1_AUTO) + return hidIsControllerConnected(g_controllerP1AutoID); + if (id < 0 || id > 9) return 0; + + rwlockReadLock(&g_hidLock); + bool flag = (g_controllerEntries[id].connectionState & CONTROLLER_STATE_CONNECTED) != 0; + rwlockReadUnlock(&g_hidLock); + return flag; +} + u64 hidKeysHeld(HidControllerID id) { if (id==CONTROLLER_P1_AUTO) return hidKeysHeld(g_controllerP1AutoID); if (id < 0 || id > 9) return 0; @@ -556,12 +629,12 @@ u32 hidMouseMultiRead(MousePosition *entries, u32 num_entries) { rwlockReadLock(&g_hidLock); - if (num_entries > g_mouse.header.maxEntryIndex + 1) - num_entries = g_mouse.header.maxEntryIndex + 1; + if (num_entries > g_mouse.header.max_entry + 1) + num_entries = g_mouse.header.max_entry + 1; - entry = g_mouse.header.latestEntry + 1 - num_entries; + entry = g_mouse.header.latest_entry + 1 - num_entries; if (entry < 0) - entry += g_mouse.header.maxEntryIndex + 1; + entry += g_mouse.header.max_entry + 1; u64 timestamp = 0; for (i = 0; i < num_entries; i++) { @@ -571,7 +644,7 @@ u32 hidMouseMultiRead(MousePosition *entries, u32 num_entries) { timestamp = g_mouse.entries[entry].timestamp; entry++; - if (entry > g_mouse.header.maxEntryIndex) + if (entry > g_mouse.header.max_entry) entry = 0; } @@ -658,8 +731,7 @@ void hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoy } rwlockReadLock(&g_hidLock); - pos->dx = g_controllerEntries[id].state.joysticks[stick].dx; - pos->dy = g_controllerEntries[id].state.joysticks[stick].dy; + *pos = g_controllerEntries[id].joysticks[stick]; rwlockReadUnlock(&g_hidLock); } } @@ -681,12 +753,12 @@ u32 hidSixAxisSensorValuesRead(SixAxisSensorValues *values, HidControllerID id, return 0; } - if (num_entries > g_sixaxisLayouts[id].header.maxEntryIndex + 1) - num_entries = g_sixaxisLayouts[id].header.maxEntryIndex + 1; + if (num_entries > g_sixaxisLayouts[id].header.max_entry + 1) + num_entries = g_sixaxisLayouts[id].header.max_entry + 1; - entry = g_sixaxisLayouts[id].header.latestEntry + 1 - num_entries; + entry = g_sixaxisLayouts[id].header.latest_entry + 1 - num_entries; if (entry < 0) - entry += g_sixaxisLayouts[id].header.maxEntryIndex + 1; + entry += g_sixaxisLayouts[id].header.max_entry + 1; u64 timestamp = 0; for (i = 0; i < num_entries; i++) { @@ -696,7 +768,7 @@ u32 hidSixAxisSensorValuesRead(SixAxisSensorValues *values, HidControllerID id, timestamp = g_sixaxisLayouts[id].entries[entry].timestamp; entry++; - if (entry > g_sixaxisLayouts[id].header.maxEntryIndex) + if (entry > g_sixaxisLayouts[id].header.max_entry) entry = 0; } rwlockReadUnlock(&g_hidLock);