From e7a4eba71c2aada52182a977c2068667b16b9f2a Mon Sep 17 00:00:00 2001 From: yellows8 Date: Mon, 5 Mar 2018 22:35:54 -0500 Subject: [PATCH] Added hidSetNpadJoyAssignmentModeSingleByDefault() and hidSetNpadJoyAssignmentModeDual(). Check serviceIsActive() in hidExit(). Use hidSetNpadJoyAssignmentModeDual() for all controllers during hidInitialize()/hidExit(). --- nx/include/switch/services/hid.h | 9 +++ nx/source/services/hid.c | 110 +++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) diff --git a/nx/include/switch/services/hid.h b/nx/include/switch/services/hid.h index 2c0edde7..c675bb16 100644 --- a/nx/include/switch/services/hid.h +++ b/nx/include/switch/services/hid.h @@ -571,3 +571,12 @@ u32 hidTouchCount(void); void hidTouchRead(touchPosition *pos, u32 point_id); void hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoystick stick); + +/// 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_*. +Result hidSetNpadJoyAssignmentModeSingleByDefault(HidControllerID id); +/// Used automatically during app startup/exit for all controllers. +/// 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_*. +Result hidSetNpadJoyAssignmentModeDual(HidControllerID id); diff --git a/nx/source/services/hid.c b/nx/source/services/hid.c index c8693322..fb7d2b38 100644 --- a/nx/source/services/hid.c +++ b/nx/source/services/hid.c @@ -32,6 +32,8 @@ static RwLock g_hidLock; static Result _hidCreateAppletResource(Service* srv, Service* srv_out, u64 AppletResourceUserId); static Result _hidGetSharedMemoryHandle(Service* srv, Handle* handle_out); +static Result _hidSetDualModeAll(void); + Result hidInitialize(void) { if (serviceIsActive(&g_hidSrv)) @@ -61,6 +63,9 @@ Result hidInitialize(void) rc = shmemMap(&g_hidSharedmem); } + if (R_SUCCEEDED(rc)) + rc = _hidSetDualModeAll(); + if (R_FAILED(rc)) hidExit(); @@ -70,6 +75,11 @@ Result hidInitialize(void) void hidExit(void) { + if (!serviceIsActive(&g_hidSrv)) + return; + + _hidSetDualModeAll(); + serviceClose(&g_hidIAppletResource); serviceClose(&g_hidSrv); shmemClose(&g_hidSharedmem); @@ -356,6 +366,18 @@ void hidJoystickRead(JoystickPosition *pos, HidControllerID id, HidControllerJoy } } +static Result _hidSetDualModeAll(void) { + Result rc=0; + int i; + + for (i=0; i<8; i++) { + rc = hidSetNpadJoyAssignmentModeDual(i); + if (R_FAILED(rc)) break; + } + + return rc; +} + static Result _hidCreateAppletResource(Service* srv, Service* srv_out, u64 AppletResourceUserId) { IpcCommand c; ipcInitialize(&c); @@ -430,3 +452,91 @@ static Result _hidGetSharedMemoryHandle(Service* srv, Handle* handle_out) { return rc; } +Result hidSetNpadJoyAssignmentModeSingleByDefault(HidControllerID id) { + Result rc; + u64 AppletResourceUserId; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 id; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 122; + raw->id = 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 hidSetNpadJoyAssignmentModeDual(HidControllerID id) { + Result rc; + u64 AppletResourceUserId; + + rc = appletGetAppletResourceUserId(&AppletResourceUserId); + if (R_FAILED(rc)) + return rc; + + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 id; + u64 AppletResourceUserId; + } *raw; + + ipcSendPid(&c); + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 124; + raw->id = 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; +} +