diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 9577377a5..bbd27e1da 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -11,6 +11,9 @@ #include "../services/btdrv_types.h" #include "../sf/service.h" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + // Begin enums and output structs /// HidDebugPadButton @@ -197,6 +200,184 @@ typedef enum { HidKeyboardModifier_Hiragana = BIT(12), } HidKeyboardModifier; +/// HidKeyboardScancode \deprecated +typedef enum DEPRECATED { + KBD_NONE = 0x00, + KBD_ERR_OVF = 0x01, + + KBD_A = 0x04, + KBD_B = 0x05, + KBD_C = 0x06, + KBD_D = 0x07, + KBD_E = 0x08, + KBD_F = 0x09, + KBD_G = 0x0a, + KBD_H = 0x0b, + KBD_I = 0x0c, + KBD_J = 0x0d, + KBD_K = 0x0e, + KBD_L = 0x0f, + KBD_M = 0x10, + KBD_N = 0x11, + KBD_O = 0x12, + KBD_P = 0x13, + KBD_Q = 0x14, + KBD_R = 0x15, + KBD_S = 0x16, + KBD_T = 0x17, + KBD_U = 0x18, + KBD_V = 0x19, + KBD_W = 0x1a, + KBD_X = 0x1b, + KBD_Y = 0x1c, + KBD_Z = 0x1d, + + KBD_1 = 0x1e, + KBD_2 = 0x1f, + KBD_3 = 0x20, + KBD_4 = 0x21, + KBD_5 = 0x22, + KBD_6 = 0x23, + KBD_7 = 0x24, + KBD_8 = 0x25, + KBD_9 = 0x26, + KBD_0 = 0x27, + + KBD_ENTER = 0x28, + KBD_ESC = 0x29, + KBD_BACKSPACE = 0x2a, + KBD_TAB = 0x2b, + KBD_SPACE = 0x2c, + KBD_MINUS = 0x2d, + KBD_EQUAL = 0x2e, + KBD_LEFTBRACE = 0x2f, + KBD_RIGHTBRACE = 0x30, + KBD_BACKSLASH = 0x31, + KBD_HASHTILDE = 0x32, + KBD_SEMICOLON = 0x33, + KBD_APOSTROPHE = 0x34, + KBD_GRAVE = 0x35, + KBD_COMMA = 0x36, + KBD_DOT = 0x37, + KBD_SLASH = 0x38, + KBD_CAPSLOCK = 0x39, + + KBD_F1 = 0x3a, + KBD_F2 = 0x3b, + KBD_F3 = 0x3c, + KBD_F4 = 0x3d, + KBD_F5 = 0x3e, + KBD_F6 = 0x3f, + KBD_F7 = 0x40, + KBD_F8 = 0x41, + KBD_F9 = 0x42, + KBD_F10 = 0x43, + KBD_F11 = 0x44, + KBD_F12 = 0x45, + + KBD_SYSRQ = 0x46, + KBD_SCROLLLOCK = 0x47, + KBD_PAUSE = 0x48, + KBD_INSERT = 0x49, + KBD_HOME = 0x4a, + KBD_PAGEUP = 0x4b, + KBD_DELETE = 0x4c, + KBD_END = 0x4d, + KBD_PAGEDOWN = 0x4e, + KBD_RIGHT = 0x4f, + KBD_LEFT = 0x50, + KBD_DOWN = 0x51, + KBD_UP = 0x52, + + KBD_NUMLOCK = 0x53, + KBD_KPSLASH = 0x54, + KBD_KPASTERISK = 0x55, + KBD_KPMINUS = 0x56, + KBD_KPPLUS = 0x57, + KBD_KPENTER = 0x58, + KBD_KP1 = 0x59, + KBD_KP2 = 0x5a, + KBD_KP3 = 0x5b, + KBD_KP4 = 0x5c, + KBD_KP5 = 0x5d, + KBD_KP6 = 0x5e, + KBD_KP7 = 0x5f, + KBD_KP8 = 0x60, + KBD_KP9 = 0x61, + KBD_KP0 = 0x62, + KBD_KPDOT = 0x63, + + KBD_102ND = 0x64, + KBD_COMPOSE = 0x65, + KBD_POWER = 0x66, + KBD_KPEQUAL = 0x67, + + KBD_F13 = 0x68, + KBD_F14 = 0x69, + KBD_F15 = 0x6a, + KBD_F16 = 0x6b, + KBD_F17 = 0x6c, + KBD_F18 = 0x6d, + KBD_F19 = 0x6e, + KBD_F20 = 0x6f, + KBD_F21 = 0x70, + KBD_F22 = 0x71, + KBD_F23 = 0x72, + KBD_F24 = 0x73, + + KBD_OPEN = 0x74, + KBD_HELP = 0x75, + KBD_PROPS = 0x76, + KBD_FRONT = 0x77, + KBD_STOP = 0x78, + KBD_AGAIN = 0x79, + KBD_UNDO = 0x7a, + KBD_CUT = 0x7b, + KBD_COPY = 0x7c, + KBD_PASTE = 0x7d, + KBD_FIND = 0x7e, + KBD_MUTE = 0x7f, + KBD_VOLUMEUP = 0x80, + KBD_VOLUMEDOWN = 0x81, + KBD_CAPSLOCK_ACTIVE = 0x82 , + KBD_NUMLOCK_ACTIVE = 0x83 , + KBD_SCROLLLOCK_ACTIVE = 0x84 , + KBD_KPCOMMA = 0x85, + + KBD_KPLEFTPAREN = 0xb6, + KBD_KPRIGHTPAREN = 0xb7, + + KBD_LEFTCTRL = 0xe0, + KBD_LEFTSHIFT = 0xe1, + KBD_LEFTALT = 0xe2, + KBD_LEFTMETA = 0xe3, + KBD_RIGHTCTRL = 0xe4, + KBD_RIGHTSHIFT = 0xe5, + KBD_RIGHTALT = 0xe6, + KBD_RIGHTMETA = 0xe7, + + KBD_MEDIA_PLAYPAUSE = 0xe8, + KBD_MEDIA_STOPCD = 0xe9, + KBD_MEDIA_PREVIOUSSONG = 0xea, + KBD_MEDIA_NEXTSONG = 0xeb, + KBD_MEDIA_EJECTCD = 0xec, + KBD_MEDIA_VOLUMEUP = 0xed, + KBD_MEDIA_VOLUMEDOWN = 0xee, + KBD_MEDIA_MUTE = 0xef, + KBD_MEDIA_WWW = 0xf0, + KBD_MEDIA_BACK = 0xf1, + KBD_MEDIA_FORWARD = 0xf2, + KBD_MEDIA_STOP = 0xf3, + KBD_MEDIA_FIND = 0xf4, + KBD_MEDIA_SCROLLUP = 0xf5, + KBD_MEDIA_SCROLLDOWN = 0xf6, + KBD_MEDIA_EDIT = 0xf7, + KBD_MEDIA_SLEEP = 0xf8, + KBD_MEDIA_COFFEE = 0xf9, + KBD_MEDIA_REFRESH = 0xfa, + KBD_MEDIA_CALC = 0xfb +} HidKeyboardScancode; + /// KeyboardLockKeyEvent typedef enum { HidKeyboardLockKeyEvent_NumLockOn = BIT(0), ///< NumLockOn @@ -293,6 +474,63 @@ typedef enum { HidNpadButton_AnySR = HidNpadButton_LeftSR | HidNpadButton_RightSR, ///< Bitmask containing SR buttons on both Joy-Cons (Left/Right) } HidNpadButton; +/// HidControllerKeys \deprecated +typedef enum DEPRECATED { + KEY_A = HidNpadButton_A, + KEY_B = HidNpadButton_B, + KEY_X = HidNpadButton_X, + KEY_Y = HidNpadButton_Y, + KEY_LSTICK = HidNpadButton_StickL, + KEY_RSTICK = HidNpadButton_StickR, + KEY_L = HidNpadButton_L, + KEY_R = HidNpadButton_R, + KEY_ZL = HidNpadButton_ZL, + KEY_ZR = HidNpadButton_ZR, + KEY_PLUS = HidNpadButton_Plus, + KEY_MINUS = HidNpadButton_Minus, + KEY_DLEFT = HidNpadButton_Left, + KEY_DUP = HidNpadButton_Up, + KEY_DRIGHT = HidNpadButton_Right, + KEY_DDOWN = HidNpadButton_Down, + KEY_LSTICK_LEFT = HidNpadButton_StickLLeft, + KEY_LSTICK_UP = HidNpadButton_StickLUp, + KEY_LSTICK_RIGHT = HidNpadButton_StickLRight, + KEY_LSTICK_DOWN = HidNpadButton_StickLDown, + KEY_RSTICK_LEFT = HidNpadButton_StickRLeft, + KEY_RSTICK_UP = HidNpadButton_StickRUp, + KEY_RSTICK_RIGHT = HidNpadButton_StickRRight, + KEY_RSTICK_DOWN = HidNpadButton_StickRDown, + KEY_SL_LEFT = HidNpadButton_LeftSL, + KEY_SR_LEFT = HidNpadButton_LeftSR, + KEY_SL_RIGHT = HidNpadButton_RightSL, + KEY_SR_RIGHT = HidNpadButton_RightSR, + KEY_NES_HANDHELD_LEFT_B = HidNpadButton_HandheldLeftB, + + KEY_HOME = BIT(18), ///< HOME button, only available for use with HiddbgHdlsState::buttons. + KEY_CAPTURE = BIT(19), ///< Capture button, only available for use with HiddbgHdlsState::buttons. + KEY_TOUCH = BIT(28), ///< Pseudo-key for at least one finger on the touch screen + + KEY_JOYCON_RIGHT = HidNpadButton_A, + KEY_JOYCON_DOWN = HidNpadButton_B, + KEY_JOYCON_UP = HidNpadButton_X, + KEY_JOYCON_LEFT = HidNpadButton_Y, + + KEY_UP = HidNpadButton_AnyUp, + KEY_DOWN = HidNpadButton_AnyDown, + KEY_LEFT = HidNpadButton_AnyLeft, + KEY_RIGHT = HidNpadButton_AnyRight, + KEY_SL = HidNpadButton_AnySL, + KEY_SR = HidNpadButton_AnySR, +} HidControllerKeys; + +/// HidControllerJoystick \deprecated +typedef enum DEPRECATED { + JOYSTICK_LEFT = 0, + JOYSTICK_RIGHT = 1, + + JOYSTICK_NUM_STICKS = 2, +} HidControllerJoystick; + /// HidDebugPadAttribute typedef enum { HidDebugPadAttribute_IsConnected = BIT(0), ///< IsConnected @@ -355,6 +593,21 @@ typedef enum { HidGestureType_Rotate = 9, ///< Rotate } HidGestureType; +/// HidControllerID \deprecated +typedef enum DEPRECATED { + CONTROLLER_PLAYER_1 = 0, + CONTROLLER_PLAYER_2 = 1, + CONTROLLER_PLAYER_3 = 2, + CONTROLLER_PLAYER_4 = 3, + CONTROLLER_PLAYER_5 = 4, + CONTROLLER_PLAYER_6 = 5, + CONTROLLER_PLAYER_7 = 6, + 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()/hidIsControllerConnected(). Automatically uses CONTROLLER_PLAYER_1 when connected, otherwise uses CONTROLLER_HANDHELD. +} HidControllerID; + /// GyroscopeZeroDriftMode typedef enum { HidGyroscopeZeroDriftMode_Loose = 0, ///< Loose @@ -556,12 +809,38 @@ typedef enum { HidPalmaFeature_MuteSwitch = BIT(3), ///< MuteSwitch } HidPalmaFeature; +/// touchPosition \deprecated +typedef struct DEPRECATED touchPosition { + u32 id; + u32 px; + u32 py; + u32 dx; + u32 dy; + u32 angle; +} touchPosition; + /// HidAnalogStickState typedef struct HidAnalogStickState { s32 x; ///< X s32 y; ///< Y } HidAnalogStickState; +/// JoystickPosition \deprecated +typedef struct DEPRECATED JoystickPosition { + s32 dx; + s32 dy; +} JoystickPosition; + +/// MousePosition \deprecated +typedef struct DEPRECATED MousePosition { + s32 x; + s32 y; + s32 velocityX; + s32 velocityY; + s32 scrollVelocityX; + s32 scrollVelocityY; +} MousePosition; + /// HidVector typedef struct HidVector { float x; @@ -574,6 +853,14 @@ typedef struct HidDirectionState { float direction[3][3]; ///< 3x3 matrix } HidDirectionState; +/// SixAxisSensorValues \deprecated DEPRECATED +typedef struct DEPRECATED SixAxisSensorValues { + HidVector accelerometer; + HidVector gyroscope; + HidVector unk; + HidVector orientation[3]; +} SixAxisSensorValues; + #define JOYSTICK_MAX (0x7FFF) #define JOYSTICK_MIN (-0x7FFF) @@ -1149,18 +1436,34 @@ typedef struct HidPalmaActivityEntry { u16 wave_index; ///< WaveIndex } HidPalmaActivityEntry; +static inline HidNpadIdType hidControllerIDToNpadIdType(HidControllerID id) { + if (id <= CONTROLLER_PLAYER_8) return (HidNpadIdType)id; + if (id == CONTROLLER_HANDHELD) return HidNpadIdType_Handheld; + return HidNpadIdType_Other;//For CONTROLLER_UNKNOWN and invalid values return this. +} + +static inline HidControllerID hidControllerIDFromNpadIdType(HidNpadIdType id) { + if (id <= HidNpadIdType_No8) return (HidControllerID)id; + if (id == HidNpadIdType_Handheld) return CONTROLLER_HANDHELD; + return CONTROLLER_UNKNOWN; +} + /// Initialize hid. Called automatically during app startup. Result hidInitialize(void); /// Exit hid. Called automatically during app exit. void hidExit(void); +void DEPRECATED hidReset(void); ///< \deprecated + /// Gets the Service object for the actual hid service session. Service* hidGetServiceSession(void); /// Gets the address of the SharedMemory. void* hidGetSharedmemAddr(void); +void DEPRECATED hidScanInput(void); ///< \deprecated + ///@name TouchScreen ///@{ @@ -1429,6 +1732,39 @@ size_t hidGetGestureStates(HidGestureState *states, size_t count); ///@} +bool DEPRECATED hidIsControllerConnected(HidControllerID id); ///< \deprecated + +u64 DEPRECATED hidKeysHeld(HidControllerID id); ///< \deprecated +u64 DEPRECATED hidKeysDown(HidControllerID id); ///< \deprecated +u64 DEPRECATED hidKeysUp(HidControllerID id); ///< \deprecated + +u64 DEPRECATED hidMouseButtonsHeld(void); ///< \deprecated +u64 DEPRECATED hidMouseButtonsDown(void); ///< \deprecated +u64 DEPRECATED hidMouseButtonsUp(void); ///< \deprecated +void DEPRECATED hidMouseRead(MousePosition *pos); ///< \deprecated +u32 DEPRECATED hidMouseMultiRead(MousePosition *entries, u32 num_entries); ///< \deprecated + +bool DEPRECATED hidKeyboardModifierHeld(HidKeyboardModifier modifier); ///< \deprecated +bool DEPRECATED hidKeyboardModifierDown(HidKeyboardModifier modifier); ///< \deprecated +bool DEPRECATED hidKeyboardModifierUp(HidKeyboardModifier modifier); ///< \deprecated + +bool DEPRECATED hidKeyboardHeld(HidKeyboardScancode key); ///< \deprecated +bool DEPRECATED hidKeyboardDown(HidKeyboardScancode key); ///< \deprecated +bool DEPRECATED hidKeyboardUp(HidKeyboardScancode key); ///< \deprecated + +u32 DEPRECATED hidTouchCount(void); ///< \deprecated +void DEPRECATED hidTouchRead(touchPosition *pos, u32 point_id); ///< \deprecated + +void DEPRECATED hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoystick stick); ///< \deprecated +u32 DEPRECATED hidSixAxisSensorValuesRead(SixAxisSensorValues *values, HidControllerID id, u32 num_entries); ///< \deprecated + +/** + * @brief This can be used to check what CONTROLLER_P1_AUTO uses. + * @return 0 when CONTROLLER_PLAYER_1 is connected, otherwise returns 1 for handheld-mode. + * @deprecated + */ +bool DEPRECATED hidGetHandheldMode(void); + /** * @brief SendKeyboardLockKeyEvent * @note Same as \ref hidsysSendKeyboardLockKeyEvent. @@ -2164,3 +2500,5 @@ Result hidSetTouchScreenConfiguration(const HidTouchScreenConfigurationForNx *co * @param[out] out Output flag. */ Result hidIsFirmwareUpdateNeededForNotification(bool *out); + +#pragma GCC diagnostic pop diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index f0ebc3279..9e19de5ea 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -22,6 +22,21 @@ static u8* g_sevenSixAxisSensorBuffer; static TransferMemory g_sevenSixAxisSensorTmem0; static TransferMemory g_sevenSixAxisSensorTmem1; +static bool g_scanInputInitialized; +static RwLock g_hidLock; + +static HidTouchScreenState g_touchScreenState; +static HidMouseState g_mouseState; +static HidKeyboardState g_keyboardState; +static HidNpadCommonState g_controllerEntries[10]; + +static u64 g_mouseOld, g_mouseHeld, g_mouseDown, g_mouseUp; +static u64 g_keyboardModOld, g_keyboardModHeld, g_keyboardModDown, g_keyboardModUp; +static u64 g_keyboardOld[4], g_keyboardHeld[4], g_keyboardDown[4], g_keyboardUp[4]; +static u64 g_controllerOld[10], g_controllerHeld[10], g_controllerDown[10], g_controllerUp[10]; + +static HidControllerID g_controllerP1AutoID; + static Result _hidCreateAppletResource(Service* srv, Service* srv_out); static Result _hidGetSharedMemoryHandle(Service* srv, Handle* handle_out); @@ -31,6 +46,8 @@ static Result _hidActivateKeyboard(void); static Result _hidActivateNpad(void); static Result _hidActivateGesture(void); +static Result _hidSetDualModeAll(void); + static Result _hidGetVibrationDeviceHandles(HidVibrationDeviceHandle *handles, s32 total_handles, HidNpadIdType id, HidNpadStyleTag style); static Result _hidCreateActiveVibrationDeviceList(Service* srv_out); @@ -69,12 +86,36 @@ void _hidCleanup(void) { if (g_sevenSixAxisSensorBuffer != NULL) diagAbortWithResult(MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen)); + g_scanInputInitialized = false; serviceClose(&g_hidIActiveVibrationDeviceList); shmemClose(&g_hidSharedmem); serviceClose(&g_hidIAppletResource); serviceClose(&g_hidSrv); } +static void _hidReset(void) { + // Reset internal state + memset(&g_touchScreenState, 0, sizeof(HidTouchScreenState)); + memset(&g_mouseState, 0, sizeof(HidMouseState)); + memset(&g_keyboardState, 0, sizeof(HidKeyboardState)); + memset(g_controllerEntries, 0, sizeof(g_controllerEntries)); + + g_mouseOld = g_mouseHeld = g_mouseDown = g_mouseUp = 0; + g_keyboardModOld = g_keyboardModHeld = g_keyboardModDown = g_keyboardModUp = 0; + for (u32 i = 0; i < 4; i++) + g_keyboardOld[i] = g_keyboardHeld[i] = g_keyboardDown[i] = g_keyboardUp[i] = 0; + for (u32 i = 0; i < 10; i++) + g_controllerOld[i] = g_controllerHeld[i] = g_controllerDown[i] = g_controllerUp[i] = 0; + + g_controllerP1AutoID = CONTROLLER_HANDHELD; +} + +void hidReset(void) { + rwlockWriteLock(&g_hidLock); + _hidReset(); + rwlockWriteUnlock(&g_hidLock); +} + Service* hidGetServiceSession(void) { return &g_hidSrv; } @@ -83,6 +124,156 @@ void* hidGetSharedmemAddr(void) { return shmemGetAddr(&g_hidSharedmem); } +void hidScanInput(void) { + rwlockWriteLock(&g_hidLock); + + if (!g_scanInputInitialized) { + Result rc; + + hidInitializeNpad(); + hidInitializeTouchScreen(); + hidInitializeKeyboard(); + hidInitializeMouse(); + _hidReset(); + + rc = hidSetSupportedNpadStyleSet(HidNpadStyleSet_NpadStandard | HidNpadStyleTag_NpadSystemExt | HidNpadStyleTag_NpadSystem); + if (R_FAILED(rc)) diagAbortWithResult(rc); + + static const HidNpadIdType idbuf[] = { + HidNpadIdType_No1, + HidNpadIdType_No2, + HidNpadIdType_No3, + HidNpadIdType_No4, + HidNpadIdType_No5, + HidNpadIdType_No6, + HidNpadIdType_No7, + HidNpadIdType_No8, + HidNpadIdType_Handheld, + }; + + rc = hidSetSupportedNpadIdType(idbuf, sizeof(idbuf)/sizeof(*idbuf)); + if (R_FAILED(rc)) diagAbortWithResult(rc); + + rc = _hidSetDualModeAll(); + if (R_FAILED(rc)) diagAbortWithResult(rc); + + rc = hidSetNpadJoyHoldType(HidNpadJoyHoldType_Vertical); + if (R_FAILED(rc)) diagAbortWithResult(rc); + + g_scanInputInitialized = true; + } + + g_mouseOld = g_mouseHeld; + g_keyboardModOld = g_keyboardModHeld; + memcpy(g_keyboardOld, g_keyboardHeld, sizeof(g_keyboardOld)); + memcpy(g_controllerOld, g_controllerHeld, sizeof(g_controllerOld)); + + g_mouseHeld = 0; + g_keyboardModHeld = 0; + memset(g_keyboardHeld, 0, sizeof(g_keyboardHeld)); + memset(g_controllerHeld, 0, sizeof(g_controllerHeld)); + memset(&g_touchScreenState, 0, sizeof(HidTouchScreenState)); + memset(&g_mouseState, 0, sizeof(HidMouseState)); + memset(&g_keyboardState, 0, sizeof(HidKeyboardState)); + memset(g_controllerEntries, 0, sizeof(g_controllerEntries)); + + if (hidGetTouchScreenStates(&g_touchScreenState, 1)) { + if (g_touchScreenState.count >= 1) + g_controllerHeld[CONTROLLER_HANDHELD] |= KEY_TOUCH; + } + + if (hidGetMouseStates(&g_mouseState, 1)) { + g_mouseHeld = g_mouseState.buttons; + g_mouseDown = (~g_mouseOld) & g_mouseHeld; + g_mouseUp = g_mouseOld & (~g_mouseHeld); + } + + if (hidGetKeyboardStates(&g_keyboardState, 1)) { + g_keyboardModHeld = g_keyboardState.modifiers; + for (u32 i = 0; i < 4; i++) { + g_keyboardHeld[i] = g_keyboardState.keys[i]; + } + g_keyboardModDown = (~g_keyboardModOld) & g_keyboardModHeld; + g_keyboardModUp = g_keyboardModOld & (~g_keyboardModHeld); + for (u32 i = 0; i < 4; i++) { + g_keyboardDown[i] = (~g_keyboardOld[i]) & g_keyboardHeld[i]; + g_keyboardUp[i] = g_keyboardOld[i] & (~g_keyboardHeld[i]); + } + } + + for (u32 i = 0; i < 10; i++) { + HidNpadIdType id = hidControllerIDToNpadIdType(i); + u32 style_set = hidGetNpadStyleSet(id); + size_t total_out=0; + + if (style_set & HidNpadStyleTag_NpadSystemExt) { + HidNpadSystemExtState state={0}; + total_out = hidGetNpadStatesSystemExt(id, &state, 1); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadSystem) { + HidNpadSystemState state={0}; + total_out = hidGetNpadStatesSystem(id, &state, 1); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadFullKey) { + HidNpadFullKeyState state={0}; + total_out = hidGetNpadStatesFullKey(id, &state, 1); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadHandheld) { + HidNpadHandheldState state={0}; + total_out = hidGetNpadStatesHandheld(id, &state, 1); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadJoyDual) { + HidNpadJoyDualState state={0}; + total_out = hidGetNpadStatesJoyDual(id, &state, 1); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadJoyLeft) { + HidNpadJoyLeftState state={0}; + total_out = hidGetNpadStatesJoyLeft(id, &state, 1); + if (total_out) { + g_controllerHeld[i] |= state.buttons; + memcpy(&g_controllerEntries[i], &state, sizeof(state)); + } + } + else if (style_set & HidNpadStyleTag_NpadJoyRight) { + HidNpadJoyRightState state={0}; + total_out = hidGetNpadStatesJoyRight(id, &state, 1); + 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]); + } + + g_controllerP1AutoID = CONTROLLER_HANDHELD; + if (g_controllerEntries[CONTROLLER_PLAYER_1].attributes & HidNpadAttribute_IsConnected) + g_controllerP1AutoID = CONTROLLER_PLAYER_1; + + rwlockWriteUnlock(&g_hidLock); +} + static HidNpadInternalState* _hidGetNpadInternalState(HidNpadIdType id) { HidSharedMemory *sharedmem = (HidSharedMemory*)hidGetSharedmemAddr(); if (sharedmem == NULL) @@ -456,13 +647,13 @@ size_t hidGetNpadStatesSystem(HidNpadIdType id, HidNpadSystemState *states, size u64 buttons = states[i].buttons; u64 new_buttons = 0; - if (buttons & HidNpadButton_AnyLeft) new_buttons |= HidNpadButton_Left; - if (buttons & HidNpadButton_AnyUp) new_buttons |= HidNpadButton_Up; - if (buttons & HidNpadButton_AnyRight) new_buttons |= HidNpadButton_Right; - if (buttons & HidNpadButton_AnyDown) new_buttons |= HidNpadButton_Down; - if (buttons & (HidNpadButton_L|HidNpadButton_ZL)) new_buttons |= HidNpadButton_L; // sdknso would mask out this button on the else condition for both of these, but it was already clear anyway. - if (buttons & (HidNpadButton_R|HidNpadButton_ZR)) new_buttons |= HidNpadButton_R; - buttons = new_buttons | (buttons & (HidNpadButton_A|HidNpadButton_B|HidNpadButton_X|HidNpadButton_Y)); + 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. @@ -528,6 +719,251 @@ size_t hidGetGestureStates(HidGestureState *states, size_t count) { return total; } +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].attributes & HidNpadAttribute_IsConnected) != 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; + + rwlockReadLock(&g_hidLock); + u64 tmp = g_controllerHeld[id]; + rwlockReadUnlock(&g_hidLock); + + return tmp; +} + +u64 hidKeysDown(HidControllerID id) { + if (id==CONTROLLER_P1_AUTO) return hidKeysDown(g_controllerP1AutoID); + if (id < 0 || id > 9) return 0; + + rwlockReadLock(&g_hidLock); + u64 tmp = g_controllerDown[id]; + rwlockReadUnlock(&g_hidLock); + + return tmp; +} + +u64 hidKeysUp(HidControllerID id) { + if (id==CONTROLLER_P1_AUTO) return hidKeysUp(g_controllerP1AutoID); + if (id < 0 || id > 9) return 0; + + rwlockReadLock(&g_hidLock); + u64 tmp = g_controllerUp[id]; + rwlockReadUnlock(&g_hidLock); + + return tmp; +} + +u64 hidMouseButtonsHeld(void) { + rwlockReadLock(&g_hidLock); + u64 tmp = g_mouseHeld; + rwlockReadUnlock(&g_hidLock); + + return tmp; +} + +u64 hidMouseButtonsDown(void) { + rwlockReadLock(&g_hidLock); + u64 tmp = g_mouseDown; + rwlockReadUnlock(&g_hidLock); + + return tmp; +} + +u64 hidMouseButtonsUp(void) { + rwlockReadLock(&g_hidLock); + u64 tmp = g_mouseUp; + rwlockReadUnlock(&g_hidLock); + + return tmp; +} + +void hidMouseRead(MousePosition *pos) { + rwlockReadLock(&g_hidLock); + pos->x = g_mouseState.x; + pos->y = g_mouseState.y; + pos->velocityX = g_mouseState.delta_x; + pos->velocityY = g_mouseState.delta_y; + pos->scrollVelocityX = g_mouseState.wheel_delta_x; + pos->scrollVelocityY = g_mouseState.wheel_delta_y; + rwlockReadUnlock(&g_hidLock); +} + +u32 hidMouseMultiRead(MousePosition *entries, u32 num_entries) { + HidMouseState temp_states[17]; + + if (!entries || !num_entries) return 0; + if (num_entries > 17) num_entries = 17; + + memset(entries, 0, sizeof(MousePosition) * num_entries); + + size_t total = hidGetMouseStates(temp_states, num_entries); + + for (size_t i=0; i= g_touchScreenState.count) { + memset(pos, 0, sizeof(touchPosition)); + return; + } + + pos->id = g_touchScreenState.touches[point_id].finger_id; + pos->px = g_touchScreenState.touches[point_id].x; + pos->py = g_touchScreenState.touches[point_id].y; + pos->dx = g_touchScreenState.touches[point_id].diameter_x; + pos->dy = g_touchScreenState.touches[point_id].diameter_y; + pos->angle = g_touchScreenState.touches[point_id].rotation_angle; + } +} + +void hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoystick stick) { + if (id == CONTROLLER_P1_AUTO) return hidJoystickRead(pos, g_controllerP1AutoID, stick); + + if (pos) { + if (id < 0 || id > 9 || stick >= JOYSTICK_NUM_STICKS) { + memset(pos, 0, sizeof(*pos)); + return; + } + + rwlockReadLock(&g_hidLock); + memcpy(pos, stick==JOYSTICK_LEFT ? &g_controllerEntries[id].analog_stick_l : &g_controllerEntries[id].analog_stick_r, sizeof(HidAnalogStickState)); + rwlockReadUnlock(&g_hidLock); + } +} + +u32 hidSixAxisSensorValuesRead(SixAxisSensorValues *values, HidControllerID id, u32 num_entries) { + HidSixAxisSensorState temp_states[17]; + + if (!values || !num_entries) return 0; + + if (id == CONTROLLER_P1_AUTO) id = g_controllerP1AutoID; + + memset(values, 0, sizeof(SixAxisSensorValues) * num_entries); + if (id < 0 || id > 9) return 0; + if (num_entries > 17) num_entries = 17; + + HidNpadIdType npad_id = hidControllerIDToNpadIdType(id); + u32 style_set = hidGetNpadStyleSet(npad_id); + size_t num_handles = 1; + size_t handle_idx = 0; + style_set &= -style_set; // retrieve least significant set bit + + if (style_set == HidNpadStyleTag_NpadJoyDual) { + u32 device_type = hidGetNpadDeviceType(npad_id); + num_handles = 2; + if (device_type & HidDeviceTypeBits_JoyLeft) + handle_idx = 0; + else if (device_type & HidDeviceTypeBits_JoyRight) + handle_idx = 1; + else + return 0; + } + + HidSixAxisSensorHandle handles[2]; + Result rc = hidGetSixAxisSensorHandles(handles, num_handles, npad_id, style_set); + if (R_FAILED(rc)) + return 0; + + size_t total = hidGetSixAxisSensorStates(handles[handle_idx], temp_states, num_entries); + + for (size_t i=0; i