diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 501e224f..1d74ce9d 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -644,6 +644,8 @@ Result hidSetSupportedNpadIdType(HidControllerID *buf, size_t count); /// Sets which controller types are supported. This is automatically called with all types in \ref hidInitialize. Result hidSetSupportedNpadStyleSet(HidControllerType type); +Result hidSetNpadJoyHoldType(u64 type); + /// Use this if you want to use a single joy-con as a dedicated CONTROLLER_PLAYER_*. /// When used, both joy-cons in a pair should be used with this (CONTROLLER_PLAYER_1 and CONTROLLER_PLAYER_2 for example). /// id must be CONTROLLER_PLAYER_*. diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index e9909a0b..3afa7e05 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -37,6 +37,9 @@ static RwLock g_hidLock; static Result _hidCreateAppletResource(Service* srv, Service* srv_out, u64 AppletResourceUserId); static Result _hidGetSharedMemoryHandle(Service* srv, Handle* handle_out); +static Result _hidActivateNpad(void); +static Result _hidDeactivateNpad(void); + static Result _hidSetDualModeAll(void); Result hidInitialize(void) @@ -85,6 +88,9 @@ Result hidInitialize(void) rc = shmemMap(&g_hidSharedmem); } + if (R_SUCCEEDED(rc)) + rc = _hidActivateNpad(); + if (R_SUCCEEDED(rc)) rc = hidSetSupportedNpadStyleSet(TYPE_PROCONTROLLER | TYPE_HANDHELD | TYPE_JOYCON_PAIR | TYPE_JOYCON_LEFT | TYPE_JOYCON_RIGHT); @@ -107,6 +113,8 @@ void hidExit(void) { _hidSetDualModeAll(); + _hidDeactivateNpad(); + serviceClose(&g_hidIAppletResource); serviceClose(&g_hidSrv); shmemClose(&g_hidSharedmem); @@ -677,10 +685,108 @@ static Result _hidCmdWithInputU32(u64 cmd_id, u32 inputval) { return rc; } +static Result _hidCmdWithInputU64(u64 cmd_id, u64 inputval) { + Result rc; + u64 AppletResourceUserId; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + AppletResourceUserId = 0; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 AppletResourceUserId; + u64 val; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = cmd_id; + raw->val = inputval; + raw->AppletResourceUserId = AppletResourceUserId; + + rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + +static Result _hidCmdWithNoInput(u64 cmd_id) { + Result rc; + u64 AppletResourceUserId; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + AppletResourceUserId = 0; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = cmd_id; + raw->AppletResourceUserId = AppletResourceUserId; + + rc = serviceIpcDispatch(&g_hidSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + } *resp = r.Raw; + + rc = resp->result; + } + + return rc; +} + Result hidSetSupportedNpadStyleSet(HidControllerType type) { return _hidCmdWithInputU32(100, type); } +static Result _hidActivateNpad(void) { + return _hidCmdWithNoInput(103); +} + +static Result _hidDeactivateNpad(void) { + return _hidCmdWithNoInput(104); +} + +Result hidSetNpadJoyHoldType(u64 type) { + return _hidCmdWithInputU64(120, type); +} + Result hidSetNpadJoyAssignmentModeSingleByDefault(HidControllerID id) { return _hidCmdWithInputU32(122, id); }