hid: Replaced various funcs with versions which read from sharedmem.

* Various struct adjustments.
* Removed HidControllerLayoutType/hidSetControllerLayout/hidGetControllerLayout, since these are no longer used.
* Added HidNpadJoyAssignmentMode and hidGetNpadJoyAssignment.
* Replaced hidGetControllerFlags with hidGetNpadSystemProperties/hidGetNpadSystemButtonProperties.
* Added hidGetAppletFooterUiAttributesSet/hidGetAppletFooterUiTypes.
* hidScanInput() now uses hidGetNpadStates*() as determined by the output from hidGetNpadStyleSet().
This commit is contained in:
yellows8 2020-11-16 11:41:18 -05:00 committed by fincs
parent 1e3145f81d
commit db39de34c5
No known key found for this signature in database
GPG Key ID: 62C7609ADA219C60
2 changed files with 299 additions and 238 deletions

View File

@ -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.

View File

@ -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 = &currentLayout->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;
HidNpadJoyAssignmentMode hidGetNpadJoyAssignment(u32 id) {
Result rc = _hidVerifyNpadIdType(id);
HidNpadJoyAssignmentMode 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->header.npad_joy_assignment_mode, memory_order_acquire);
if (tmp != HidNpadJoyAssignmentMode_Dual && tmp != HidNpadJoyAssignmentMode_Single)
rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen);
}
if (id < 0 || id > 9) return;
if (colors == NULL) return;
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 (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; i<count; i++) {
info[i].batteryCharge = atomic_load_explicit(&npad->batteryCharge[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;
hidGetControllerFlags(id, &flags);
for (i=0; i<total_info; i++) {
info[i].isCharging = (flags.powerInfo & BIT(indexbase+i)) != 0;
info[i].powerConnected = (flags.powerInfo & BIT(indexbase+i+3)) != 0;
rwlockReadLock(&g_hidLock);
info[i].batteryCharge = g_controllerMisc[id].batteryCharge[indexbase+i];
rwlockReadUnlock(&g_hidLock);
if (info[i].batteryCharge > 4) info->batteryCharge = 4;
}
}
if (R_FAILED(rc)) diagAbortWithResult(rc);
}
u32 hidGetAppletFooterUiAttributesSet(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_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);