diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index d7321696..badb600a 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -565,6 +565,36 @@ typedef HidNpadStateEntry HidNpadJoyDualState; typedef HidNpadStateEntry HidNpadJoyLeftState; typedef HidNpadStateEntry HidNpadJoyRightState; typedef HidNpadStateEntry HidNpadPalmaState; + +/// HidNpadLarkState +typedef struct HidNpadLarkState { + u64 timestamp; + u64 buttons; + JoystickPosition joysticks[JOYSTICK_NUM_STICKS]; ///< Joysticks state are always zero. + u32 connectionState; + u32 unk; +} HidNpadLarkState; + +/// HidNpadHandheldLarkState +typedef struct HidNpadHandheldLarkState { + u64 timestamp; + u64 buttons; + JoystickPosition joysticks[JOYSTICK_NUM_STICKS]; + u32 connectionState; + u32 unk; + u32 unk2; + u32 pad; +} HidNpadHandheldLarkState; + +/// HidNpadLuciaState +typedef struct HidNpadLuciaState { + u64 timestamp; + u64 buttons; + JoystickPosition joysticks[JOYSTICK_NUM_STICKS]; ///< Joysticks state are always zero. + u32 connectionState; + u32 unk; +} HidNpadLuciaState; + 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. @@ -660,10 +690,18 @@ typedef struct HidNpad { struct { u32 applet_footer_ui_attribute; u8 applet_footer_ui_type; - u8 unk_x41AD[0x5B]; + u8 pad2[3]; + u8 unk_x41B0[0x58]; }; }; - u8 unk_2[0xDF8]; + u8 mutex[0x8]; + u8 unk_x4210[0x18]; + u8 npad_gc_trigger_header[0x20]; + u8 npad_gc_trigger_state[0x198]; + u32 unk_x43E0; + u32 unk_x43E4; + u32 unk_x43E8; + u8 unk_x43EC[0xC14]; } HidNpad; // End HidNpad @@ -802,6 +840,9 @@ 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); void hidGetNpadStatesPalma(u32 id, HidNpadPalmaState *states, size_t count, size_t *total_out); +void hidGetNpadStatesLark(u32 id, HidNpadLarkState *states, size_t count, size_t *total_out); +void hidGetNpadStatesHandheldLark(u32 id, HidNpadHandheldLarkState *states, size_t count, size_t *total_out); +void hidGetNpadStatesLucia(u32 id, HidNpadLuciaState *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); diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index c2fc75c9..1528f327 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -568,6 +568,99 @@ void hidGetNpadStatesPalma(u32 id, HidNpadPalmaState *states, size_t count, size // sdknso doesn't handle ControlPadRestriction with this. } +void hidGetNpadStatesLark(u32 id, HidNpadLarkState *states, size_t count, size_t *total_out) { + HidNpadStateEntry tmp_entries[17]={0}; + + if (count > 17) count = 17; + Result rc = _hidGetNpadStates(id, 0, tmp_entries, count, total_out); + if (R_FAILED(rc)) diagAbortWithResult(rc); + + memset(states, 0, sizeof(HidNpadLarkState) * (*total_out)); + + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_NotInitialized)); + + u32 unk = atomic_load_explicit(&npad->unk_x43E0, memory_order_acquire); + if (!(unk>=1 && unk<=4)) unk = 0; + + for (size_t i=0; i<*total_out; i++) { + states[i].timestamp = tmp_entries[i].timestamp; + + // sdknso would handle button-bitmasking with ControlPadRestriction here. + + states[i].buttons = tmp_entries[i].buttons; + + // Leave joysticks state at zeros. + + states[i].connectionState = tmp_entries[i].connectionState; + states[i].unk = unk; + } +} + +void hidGetNpadStatesHandheldLark(u32 id, HidNpadHandheldLarkState *states, size_t count, size_t *total_out) { + HidNpadStateEntry tmp_entries[17]={0}; + + if (count > 17) count = 17; + Result rc = _hidGetNpadStates(id, 1, tmp_entries, count, total_out); + if (R_FAILED(rc)) diagAbortWithResult(rc); + + memset(states, 0, sizeof(HidNpadHandheldLarkState) * (*total_out)); + + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_NotInitialized)); + + u32 unk = atomic_load_explicit(&npad->unk_x43E0, memory_order_acquire); + if (!(unk>=1 && unk<=4)) unk = 0; + + u32 unk2 = atomic_load_explicit(&npad->unk_x43E4, memory_order_acquire); + if (!(unk2>=1 && unk2<=4)) unk2 = 0; + + for (size_t i=0; i<*total_out; i++) { + states[i].timestamp = tmp_entries[i].timestamp; + + // sdknso would handle button-bitmasking with ControlPadRestriction here. + + states[i].buttons = tmp_entries[i].buttons; + + memcpy(states[i].joysticks, tmp_entries[i].joysticks, sizeof(tmp_entries[i].joysticks)); // sdknso uses index 0 for the src here. + states[i].connectionState = tmp_entries[i].connectionState; + states[i].unk = unk; + states[i].unk2 = unk2; + } +} + +void hidGetNpadStatesLucia(u32 id, HidNpadLuciaState *states, size_t count, size_t *total_out) { + HidNpadStateEntry tmp_entries[17]={0}; + + if (count > 17) count = 17; + Result rc = _hidGetNpadStates(id, 0, tmp_entries, count, total_out); + if (R_FAILED(rc)) diagAbortWithResult(rc); + + memset(states, 0, sizeof(HidNpadLuciaState) * (*total_out)); + + HidNpad *npad = _hidNpadSharedmemGetInternalState(id); + if (npad == NULL) + diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_NotInitialized)); + + u32 unk = atomic_load_explicit(&npad->unk_x43E8, memory_order_acquire); + if (!(unk>=1 && unk<=3)) unk = 0; + + for (size_t i=0; i<*total_out; i++) { + states[i].timestamp = tmp_entries[i].timestamp; + + // sdknso would handle button-bitmasking with ControlPadRestriction here. + + states[i].buttons = tmp_entries[i].buttons; + + // Leave joysticks state at zeros. + + states[i].connectionState = tmp_entries[i].connectionState; + states[i].unk = unk; + } +} + 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);