mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 20:42:44 +02:00
255 lines
9.3 KiB
C
255 lines
9.3 KiB
C
#include <string.h>
|
|
#include "libapplet_internal.h"
|
|
#include "applets/hid_la.h"
|
|
#include "runtime/hosversion.h"
|
|
|
|
static Result _hidLaShow(const HidLaControllerSupportArgPrivate *private_arg, const void* arg, size_t arg_size, void* reply, size_t reply_size) {
|
|
Result rc=0;
|
|
LibAppletArgs commonargs;
|
|
AppletHolder holder;
|
|
u32 version=0x3; // [1.0.0+]
|
|
|
|
if (hosversionAtLeast(11,0,0))
|
|
version = 0x8;
|
|
else if (hosversionAtLeast(8,0,0))
|
|
version = 0x7;
|
|
else if (hosversionAtLeast(6,0,0))
|
|
version = 0x5;
|
|
else if (hosversionAtLeast(3,0,0))
|
|
version = 0x4;
|
|
|
|
rc = appletCreateLibraryApplet(&holder, AppletId_LibraryAppletController, LibAppletMode_AllForeground);
|
|
if (R_FAILED(rc)) return rc;
|
|
|
|
libappletArgsCreate(&commonargs, version);
|
|
libappletArgsSetPlayStartupSound(&commonargs, (private_arg->flag1!=0) && (private_arg->flag0!=0));
|
|
|
|
if (R_SUCCEEDED(rc)) rc = libappletArgsPush(&commonargs, &holder);
|
|
if (R_SUCCEEDED(rc)) rc = libappletPushInData(&holder, private_arg, sizeof(*private_arg));
|
|
if (R_SUCCEEDED(rc)) rc = libappletPushInData(&holder, arg, arg_size);
|
|
if (R_SUCCEEDED(rc)) rc = libappletStart(&holder);
|
|
if (R_SUCCEEDED(rc)) libappletPopOutData(&holder, reply, reply_size, NULL); // Official sw ignores the rc/transfer_size.
|
|
appletHolderClose(&holder);
|
|
|
|
return rc;
|
|
}
|
|
|
|
static size_t _hidLaGetControllerSupportArgSize(void) {
|
|
size_t arg_size = sizeof(HidLaControllerSupportArg);
|
|
if (hosversionBefore(8,0,0)) arg_size = sizeof(HidLaControllerSupportArgV3);
|
|
|
|
return arg_size;
|
|
}
|
|
|
|
static Result _hidLaShowControllerSupportCore(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg, const HidLaControllerSupportArgPrivate *private_arg) {
|
|
Result rc=0;
|
|
HidLaControllerSupportResultInfoInternal res={0};
|
|
HidLaControllerSupportArgV3 arg_v3;
|
|
const void* arg_ptr = arg;
|
|
size_t arg_size = _hidLaGetControllerSupportArgSize();
|
|
|
|
if (private_arg->mode == HidLaControllerSupportMode_ShowControllerFirmwareUpdate)
|
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
|
|
|
if (hosversionBefore(8,0,0)) {
|
|
memset(&arg_v3, 0, sizeof(arg_v3));
|
|
arg_ptr = &arg_v3;
|
|
|
|
memcpy(&arg_v3.hdr, &arg->hdr, sizeof(arg->hdr));
|
|
memcpy(arg_v3.identification_color, arg->identification_color, sizeof(arg_v3.identification_color));
|
|
arg_v3.enable_explain_text = arg->enable_explain_text;
|
|
memcpy(arg_v3.explain_text, arg->explain_text, sizeof(arg_v3.explain_text));
|
|
|
|
if (arg_v3.hdr.player_count_min > 4) arg_v3.hdr.player_count_min = 4;
|
|
if (arg_v3.hdr.player_count_max > 4) arg_v3.hdr.player_count_max = 4;
|
|
}
|
|
|
|
rc = _hidLaShow(private_arg, arg_ptr, arg_size, &res, sizeof(res));
|
|
if (R_SUCCEEDED(rc)) {
|
|
if (result_info) {
|
|
*result_info = res.info;
|
|
result_info->selected_id = result_info->selected_id;
|
|
}
|
|
|
|
if (res.res != 0) {
|
|
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); // Official sw would return different values for 2/{other values}, but we won't do so.
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static Result _hidLaShowControllerFirmwareUpdateCore(const HidLaControllerFirmwareUpdateArg *arg, const HidLaControllerSupportArgPrivate *private_arg) {
|
|
Result rc=0;
|
|
HidLaControllerSupportResultInfoInternal res={0};
|
|
|
|
if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
|
|
|
if (private_arg->mode != HidLaControllerSupportMode_ShowControllerFirmwareUpdate)
|
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
|
|
|
rc = _hidLaShow(private_arg, arg, sizeof(*arg), &res, sizeof(res));
|
|
if (R_SUCCEEDED(rc)) {
|
|
if (res.res != 0) {
|
|
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static Result _hidLaShowControllerKeyRemappingCore(const HidLaControllerKeyRemappingArg *arg, const HidLaControllerSupportArgPrivate *private_arg) {
|
|
Result rc=0;
|
|
HidLaControllerSupportResultInfoInternal res={0};
|
|
|
|
if (hosversionBefore(11,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
|
|
|
if (private_arg->mode != HidLaControllerSupportMode_ShowControllerKeyRemappingForSystem)
|
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
|
|
|
rc = _hidLaShow(private_arg, arg, sizeof(*arg), &res, sizeof(res));
|
|
if (R_SUCCEEDED(rc)) {
|
|
if (res.res != 0) {
|
|
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static Result _hidLaSetupControllerSupportArgPrivate(HidLaControllerSupportArgPrivate *private_arg) {
|
|
Result rc=0;
|
|
u32 style_set;
|
|
HidNpadJoyHoldType hold_type;
|
|
|
|
rc = hidGetSupportedNpadStyleSet(&style_set);
|
|
if (R_SUCCEEDED(rc)) rc = hidGetNpadJoyHoldType(&hold_type);
|
|
|
|
if (R_SUCCEEDED(rc)) {
|
|
private_arg->npad_style_set = style_set;
|
|
private_arg->npad_joy_hold_type = hold_type;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
void hidLaCreateControllerSupportArg(HidLaControllerSupportArg *arg) {
|
|
memset(arg, 0, sizeof(*arg));
|
|
arg->hdr.player_count_min = 0;
|
|
arg->hdr.player_count_max = 4;
|
|
arg->hdr.enable_take_over_connection = 1;
|
|
arg->hdr.enable_left_justify = 1;
|
|
arg->hdr.enable_permit_joy_dual = 1;
|
|
}
|
|
|
|
void hidLaCreateControllerFirmwareUpdateArg(HidLaControllerFirmwareUpdateArg *arg) {
|
|
memset(arg, 0, sizeof(*arg));
|
|
}
|
|
|
|
void hidLaCreateControllerKeyRemappingArg(HidLaControllerKeyRemappingArg *arg) {
|
|
memset(arg, 0, sizeof(*arg));
|
|
}
|
|
|
|
Result hidLaSetExplainText(HidLaControllerSupportArg *arg, const char *str, HidNpadIdType id) {
|
|
if (id >= 8)
|
|
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
|
|
|
memset(arg->explain_text[id], 0, sizeof(arg->explain_text[id]));
|
|
strncpy(arg->explain_text[id], str, sizeof(arg->explain_text[id])-1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
Result hidLaShowControllerSupport(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg) {
|
|
Result rc=0;
|
|
HidLaControllerSupportArgPrivate private_arg = {
|
|
.private_size = sizeof(private_arg), .arg_size = _hidLaGetControllerSupportArgSize(), .mode = HidLaControllerSupportMode_ShowControllerSupport
|
|
};
|
|
|
|
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
|
|
|
|
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerSupportCore(result_info, arg, &private_arg);
|
|
|
|
return rc;
|
|
}
|
|
|
|
Result hidLaShowControllerStrapGuide(void) {
|
|
Result rc=0;
|
|
HidLaControllerSupportArg arg;
|
|
HidLaControllerSupportArgPrivate private_arg = {
|
|
.private_size = sizeof(private_arg), .arg_size = _hidLaGetControllerSupportArgSize(), .mode = HidLaControllerSupportMode_ShowControllerStrapGuide
|
|
};
|
|
|
|
if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
|
|
|
hidLaCreateControllerSupportArg(&arg);
|
|
|
|
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
|
|
|
|
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerSupportCore(NULL, &arg, &private_arg);
|
|
|
|
return rc;
|
|
}
|
|
|
|
Result hidLaShowControllerFirmwareUpdate(const HidLaControllerFirmwareUpdateArg *arg) {
|
|
Result rc=0;
|
|
HidLaControllerSupportArgPrivate private_arg = {
|
|
.private_size = sizeof(private_arg), .arg_size = _hidLaGetControllerSupportArgSize(), .mode = HidLaControllerSupportMode_ShowControllerFirmwareUpdate
|
|
};
|
|
|
|
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
|
|
|
|
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerFirmwareUpdateCore(arg, &private_arg);
|
|
|
|
return rc;
|
|
}
|
|
|
|
Result hidLaShowControllerSupportForSystem(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg, bool flag) {
|
|
Result rc=0;
|
|
HidLaControllerSupportArgPrivate private_arg = {
|
|
.private_size = sizeof(private_arg), .arg_size = _hidLaGetControllerSupportArgSize(),
|
|
.flag0 = flag!=0, .flag1 = 1, .mode = HidLaControllerSupportMode_ShowControllerSupport
|
|
};
|
|
|
|
if (hosversionAtLeast(3,0,0)) {
|
|
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
|
|
}
|
|
else {
|
|
private_arg.npad_style_set = 0;
|
|
private_arg.npad_joy_hold_type = HidNpadJoyHoldType_Horizontal;
|
|
}
|
|
|
|
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerSupportCore(result_info, arg, &private_arg);
|
|
|
|
return rc;
|
|
}
|
|
|
|
Result hidLaShowControllerFirmwareUpdateForSystem(const HidLaControllerFirmwareUpdateArg *arg, HidLaControllerSupportCaller caller) {
|
|
Result rc=0;
|
|
HidLaControllerSupportArgPrivate private_arg = {
|
|
.private_size = sizeof(private_arg), .arg_size = _hidLaGetControllerSupportArgSize(),
|
|
.flag1 = 1, .mode = HidLaControllerSupportMode_ShowControllerFirmwareUpdate, .controller_support_caller = caller
|
|
};
|
|
|
|
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
|
|
|
|
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerFirmwareUpdateCore(arg, &private_arg);
|
|
|
|
return rc;
|
|
}
|
|
|
|
Result hidLaShowControllerKeyRemappingForSystem(const HidLaControllerKeyRemappingArg *arg, HidLaControllerSupportCaller caller) {
|
|
Result rc=0;
|
|
HidLaControllerSupportArgPrivate private_arg = {
|
|
.private_size = sizeof(private_arg), .arg_size = _hidLaGetControllerSupportArgSize(),
|
|
.flag1 = 1, .mode = HidLaControllerSupportMode_ShowControllerKeyRemappingForSystem, .controller_support_caller = caller
|
|
};
|
|
|
|
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
|
|
|
|
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerKeyRemappingCore(arg, &private_arg);
|
|
|
|
return rc;
|
|
}
|
|
|