diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 8c020cbd..e1baecd5 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -555,7 +555,8 @@ typedef struct HidNpadStateEntry { u64 timestamp; u64 buttons; JoystickPosition joysticks[JOYSTICK_NUM_STICKS]; - u64 connectionState; + u32 connectionState; + u32 pad; } HidNpadStateEntry; typedef HidNpadStateEntry HidNpadFullKeyState; @@ -563,6 +564,8 @@ typedef HidNpadStateEntry HidNpadHandheldState; typedef HidNpadStateEntry HidNpadJoyDualState; typedef HidNpadStateEntry HidNpadJoyLeftState; typedef HidNpadStateEntry HidNpadJoyRightState; +typedef HidNpadStateEntry HidNpadSystemExtState; +typedef HidNpadStateEntry HidNpadSystemState; ///< Joysticks state are always zero. Only the following button bits are available: KEY_A, KEY_B, KEY_X, KEY_Y, KEY_DLEFT, KEY_DUP, KEY_DRIGHT, KEY_DDOWN, KEY_L, KEY_R. /// HidControllerInputEntry typedef struct HidControllerInputEntry { @@ -797,6 +800,8 @@ void hidGetNpadStatesHandheld(u32 id, HidNpadHandheldState *states, size_t count void hidGetNpadStatesJoyDual(u32 id, HidNpadJoyDualState *states, size_t count, size_t *total_out); 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); +void hidGetNpadStatesSystemExt(u32 id, HidNpadSystemExtState *states, size_t count, size_t *total_out); +void hidGetNpadStatesSystem(u32 id, HidNpadSystemState *states, size_t count, size_t *total_out); bool hidIsControllerConnected(HidControllerID id); diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index 1112e098..18841cd5 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -253,6 +253,22 @@ void hidScanInput(void) { memcpy(&g_controllerEntries[i], &state, sizeof(state)); } } + else if (style_set & HidNpadStyleTag_NpadSystemExt) { + HidNpadSystemExtState state={0}; + hidGetNpadStatesSystemExt(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_NpadSystem) { + HidNpadSystemState state={0}; + hidGetNpadStatesSystem(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]); @@ -545,6 +561,35 @@ void hidGetNpadStatesJoyRight(u32 id, HidNpadJoyRightState *states, size_t count if (R_FAILED(rc)) diagAbortWithResult(rc); } +void hidGetNpadStatesSystemExt(u32 id, HidNpadSystemExtState *states, size_t count, size_t *total_out) { + Result rc = _hidGetNpadStates(id, 6, states, count, total_out); + if (R_FAILED(rc)) diagAbortWithResult(rc); +} + +void hidGetNpadStatesSystem(u32 id, HidNpadSystemState *states, size_t count, size_t *total_out) { + Result rc = _hidGetNpadStates(id, 6, states, count, total_out); + if (R_FAILED(rc)) diagAbortWithResult(rc); + + for (size_t i=0; i<*total_out; i++) { + u64 buttons = states[i].buttons; + u64 new_buttons = 0; + + if (buttons & KEY_LEFT) new_buttons |= KEY_DLEFT; + if (buttons & KEY_UP) new_buttons |= KEY_DUP; + if (buttons & KEY_RIGHT) new_buttons |= KEY_DRIGHT; + if (buttons & KEY_DOWN) new_buttons |= KEY_DDOWN; + if (buttons & (KEY_L|KEY_ZL)) new_buttons |= KEY_L; // sdknso would mask out this button on the else condition for both of these, but it was already clear anyway. + if (buttons & (KEY_R|KEY_ZR)) new_buttons |= KEY_R; + buttons = new_buttons | (buttons & (KEY_A|KEY_B|KEY_X|KEY_Y)); + + // sdknso would handle button-bitmasking with ControlPadRestriction here. + + states[i].buttons = buttons; + + memset(states[i].joysticks, 0, sizeof(states[i].joysticks)); + } +} + bool hidIsControllerConnected(HidControllerID id) { if (id==CONTROLLER_P1_AUTO) return hidIsControllerConnected(g_controllerP1AutoID);