Added hid vibration.

This commit is contained in:
yellows8 2018-03-06 18:08:57 -05:00
parent e7a4eba71c
commit a3933c7a85
2 changed files with 140 additions and 0 deletions

View File

@ -539,6 +539,12 @@ typedef struct HidSharedMemory
} HidSharedMemory;
static_assert(sizeof(HidSharedMemory) == 0x40000, "Hid Shared Memory structure has incorrect size");
typedef struct HidVibrationValue
{
float values[4];
} HidVibrationValue;
static_assert(sizeof(HidVibrationValue) == 0x10, "Hid VibrationValue structure has incorrect size");
Result hidInitialize(void);
void hidExit(void);
void hidReset(void);
@ -580,3 +586,7 @@ Result hidSetNpadJoyAssignmentModeSingleByDefault(HidControllerID id);
/// 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);
Result hidInitializeVibrationDevice(u32 *VibrationDeviceHandle, HidControllerID id, HidControllerLayoutType type);
Result hidSendVibrationValue(u32 *VibrationDeviceHandle, HidVibrationValue *VibrationValue);

View File

@ -540,3 +540,133 @@ Result hidSetNpadJoyAssignmentModeDual(HidControllerID id) {
return rc;
}
static Result _hidCreateActiveVibrationDeviceList(Service* srv_out) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 203;
Result rc = serviceIpcDispatch(&g_hidSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
if (R_SUCCEEDED(rc)) {
serviceCreate(srv_out, r.Handles[0]);
}
}
return rc;
}
static Result _hidActivateVibrationDevice(Service* srv, u32 VibrationDeviceHandle) {
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 VibrationDeviceHandle;
} *raw;
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 0;
raw->VibrationDeviceHandle = VibrationDeviceHandle;
Result rc = serviceIpcDispatch(srv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
ipcParse(&r);
struct {
u64 magic;
u64 result;
} *resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result hidSendVibrationValue(u32 *VibrationDeviceHandle, HidVibrationValue *VibrationValue) {
Result rc;
u64 AppletResourceUserId;
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
if (R_FAILED(rc))
return rc;
IpcCommand c;
ipcInitialize(&c);
struct {
u64 magic;
u64 cmd_id;
u32 VibrationDeviceHandle;
HidVibrationValue VibrationValue;
u64 AppletResourceUserId;
} *raw;
ipcSendPid(&c);
raw = ipcPrepareHeader(&c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 201;
raw->VibrationDeviceHandle = *VibrationDeviceHandle;
raw->AppletResourceUserId = AppletResourceUserId;
memcpy(&raw->VibrationValue, VibrationValue, sizeof(HidVibrationValue));
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 hidInitializeVibrationDevice(u32 *VibrationDeviceHandle, HidControllerID id, HidControllerLayoutType type) {
Result rc=0;
Service srv;
//TODO: Is type correct?
*VibrationDeviceHandle = (type & 0xff) | (id & 0xff)<<8;
rc = _hidCreateActiveVibrationDeviceList(&srv);
if (R_FAILED(rc))
return rc;
rc = _hidActivateVibrationDevice(&srv, *VibrationDeviceHandle);
serviceClose(&srv);
return rc;
}