mirror of https://github.com/encounter/SDL.git
switch: handle single joycons
This commit is contained in:
parent
c29f5893c8
commit
0705288edd
|
@ -26,22 +26,27 @@
|
||||||
|
|
||||||
#include "SDL_events.h"
|
#include "SDL_events.h"
|
||||||
#include "../SDL_sysjoystick.h"
|
#include "../SDL_sysjoystick.h"
|
||||||
|
#include "SDL_hints.h"
|
||||||
|
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
#define JOYSTICK_COUNT 8
|
#define JOYSTICK_COUNT 8
|
||||||
|
|
||||||
typedef struct SWITCHJoystickState
|
typedef struct SWITCHJoystickState {
|
||||||
{
|
|
||||||
PadState pad;
|
PadState pad;
|
||||||
HidAnalogStickState sticks_old[2];
|
HidAnalogStickState sticks_old[2];
|
||||||
HidVibrationDeviceHandle vibrationDeviceHandles;
|
HidVibrationDeviceHandle vibrationDeviceHandles;
|
||||||
HidVibrationValue vibrationValues;
|
HidVibrationValue vibrationValues;
|
||||||
|
HidNpadButton *pad_mapping;
|
||||||
|
u32 pad_type;
|
||||||
|
u32 pad_type_prev;
|
||||||
|
HidNpadStyleTag pad_style;
|
||||||
|
HidNpadStyleTag pad_style_prev;
|
||||||
} SWITCHJoystickState;
|
} SWITCHJoystickState;
|
||||||
|
|
||||||
static SWITCHJoystickState state[JOYSTICK_COUNT];
|
static SWITCHJoystickState state[JOYSTICK_COUNT];
|
||||||
|
|
||||||
static const HidNpadButton pad_mapping[] = {
|
static const HidNpadButton pad_mapping_default[] = {
|
||||||
HidNpadButton_A, HidNpadButton_B, HidNpadButton_X, HidNpadButton_Y,
|
HidNpadButton_A, HidNpadButton_B, HidNpadButton_X, HidNpadButton_Y,
|
||||||
HidNpadButton_StickL, HidNpadButton_StickR,
|
HidNpadButton_StickL, HidNpadButton_StickR,
|
||||||
HidNpadButton_L, HidNpadButton_R,
|
HidNpadButton_L, HidNpadButton_R,
|
||||||
|
@ -53,61 +58,120 @@ static const HidNpadButton pad_mapping[] = {
|
||||||
HidNpadButton_LeftSL, HidNpadButton_LeftSR, HidNpadButton_RightSL, HidNpadButton_RightSR
|
HidNpadButton_LeftSL, HidNpadButton_LeftSR, HidNpadButton_RightSL, HidNpadButton_RightSR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// left single joycon mapping (start = left stick, select = minus)
|
||||||
|
static const HidNpadButton pad_mapping_left_joy[] = {
|
||||||
|
HidNpadButton_Down, HidNpadButton_Left, HidNpadButton_Right, HidNpadButton_Up,
|
||||||
|
BIT(31), BIT(31),
|
||||||
|
BIT(31), BIT(31),
|
||||||
|
HidNpadButton_LeftSL, HidNpadButton_LeftSR,
|
||||||
|
HidNpadButton_StickL, HidNpadButton_Minus,
|
||||||
|
HidNpadButton_StickLUp, HidNpadButton_StickLRight, HidNpadButton_StickLDown, HidNpadButton_StickLLeft,
|
||||||
|
BIT(31), BIT(31), BIT(31), BIT(31),
|
||||||
|
BIT(31), BIT(31), BIT(31), BIT(31),
|
||||||
|
BIT(31), BIT(31), BIT(31), BIT(31)
|
||||||
|
};
|
||||||
|
|
||||||
|
// right single joycon mapping (start = right stick, select = plus)
|
||||||
|
static const HidNpadButton pad_mapping_right_joy[] = {
|
||||||
|
HidNpadButton_X, HidNpadButton_A, HidNpadButton_Y, HidNpadButton_B,
|
||||||
|
BIT(31), BIT(31),
|
||||||
|
BIT(31), BIT(31),
|
||||||
|
HidNpadButton_RightSL, HidNpadButton_RightSR,
|
||||||
|
HidNpadButton_StickR, HidNpadButton_Plus,
|
||||||
|
HidNpadButton_StickRDown, HidNpadButton_StickRLeft, HidNpadButton_StickRUp, HidNpadButton_StickRRight,
|
||||||
|
BIT(31), BIT(31), BIT(31), BIT(31),
|
||||||
|
BIT(31), BIT(31), BIT(31), BIT(31),
|
||||||
|
BIT(31), BIT(31), BIT(31), BIT(31)
|
||||||
|
};
|
||||||
|
|
||||||
|
static void SWITCH_ShowControllerSupport(void) {
|
||||||
|
HidLaControllerSupportResultInfo info;
|
||||||
|
HidLaControllerSupportArg args;
|
||||||
|
hidLaCreateControllerSupportArg(&args);
|
||||||
|
args.hdr.player_count_max = JOYSTICK_COUNT;
|
||||||
|
hidLaShowControllerSupportForSystem(&info, &args, false);
|
||||||
|
|
||||||
|
// update pads states
|
||||||
|
for (int i = 0; i < JOYSTICK_COUNT; i++) {
|
||||||
|
SDL_Joystick *joy = SDL_JoystickFromInstanceID(i);
|
||||||
|
if (joy) {
|
||||||
|
padUpdate(&state[i].pad);
|
||||||
|
state[i].pad_type = state[i].pad_type_prev = hidGetNpadDeviceType((HidNpadIdType) i);
|
||||||
|
state[i].pad_style = state[i].pad_style_prev = hidGetNpadStyleSet((HidNpadIdType) i);
|
||||||
|
// update pad mapping
|
||||||
|
if (!(state[i].pad_style & HidNpadStyleTag_NpadJoyDual) &&
|
||||||
|
(state[i].pad_type & HidDeviceTypeBits_JoyLeft)) {
|
||||||
|
state[i].pad_mapping = (HidNpadButton *) &pad_mapping_left_joy;
|
||||||
|
} else if (!(state[i].pad_style & HidNpadStyleTag_NpadJoyDual) &&
|
||||||
|
(state[i].pad_type & HidDeviceTypeBits_JoyRight)) {
|
||||||
|
state[i].pad_mapping = (HidNpadButton *) &pad_mapping_right_joy;
|
||||||
|
} else {
|
||||||
|
state[i].pad_mapping = (HidNpadButton *) &pad_mapping_default;
|
||||||
|
}
|
||||||
|
// update vibration stuff ?
|
||||||
|
hidInitializeVibrationDevices(&state[i].vibrationDeviceHandles, 1,
|
||||||
|
HidNpadIdType_No1 + i, state[i].pad_style);
|
||||||
|
// reset sdl joysticks states
|
||||||
|
SDL_PrivateJoystickAxis(joy, 0, 0);
|
||||||
|
SDL_PrivateJoystickAxis(joy, 1, 0);
|
||||||
|
SDL_PrivateJoystickAxis(joy, 2, 0);
|
||||||
|
SDL_PrivateJoystickAxis(joy, 3, 0);
|
||||||
|
state[i].pad.buttons_cur = 0;
|
||||||
|
state[i].pad.buttons_old = 0;
|
||||||
|
for (int j = 0; j < joy->nbuttons; j++) {
|
||||||
|
SDL_PrivateJoystickButton(joy, j, SDL_RELEASED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Function to scan the system for joysticks.
|
/* Function to scan the system for joysticks.
|
||||||
* It should return 0, or -1 on an unrecoverable fatal error.
|
* It should return 0, or -1 on an unrecoverable fatal error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int SWITCH_JoystickInit(void) {
|
||||||
SWITCH_JoystickInit(void)
|
|
||||||
{
|
|
||||||
padConfigureInput(JOYSTICK_COUNT, HidNpadStyleSet_NpadStandard);
|
padConfigureInput(JOYSTICK_COUNT, HidNpadStyleSet_NpadStandard);
|
||||||
|
|
||||||
// initialize first pad to defaults
|
// initialize first pad to defaults
|
||||||
padInitializeDefault(&state[0].pad);
|
padInitializeDefault(&state[0].pad);
|
||||||
padUpdate(&state[0].pad);
|
padUpdate(&state[0].pad);
|
||||||
|
state[0].pad_mapping = (HidNpadButton *) &pad_mapping_default;
|
||||||
|
state[0].pad_type = state[0].pad_type_prev = hidGetNpadDeviceType((HidNpadIdType) 0);
|
||||||
|
state[0].pad_style = state[0].pad_style_prev = hidGetNpadStyleSet((HidNpadIdType) 0);
|
||||||
|
|
||||||
// initialize pad and vibrations for pad 1 to 7
|
// initialize pad and vibrations for pad 1 to 7
|
||||||
for (int i = 1; i < JOYSTICK_COUNT; i++) {
|
for (int i = 1; i < JOYSTICK_COUNT; i++) {
|
||||||
padInitialize(&state[i].pad, HidNpadIdType_No1 + i);
|
padInitialize(&state[i].pad, HidNpadIdType_No1 + i);
|
||||||
padUpdate(&state[i].pad);
|
padUpdate(&state[i].pad);
|
||||||
hidInitializeVibrationDevices(&state[i].vibrationDeviceHandles,1,
|
state[i].pad_mapping = (HidNpadButton *) &pad_mapping_default;
|
||||||
HidNpadIdType_No1 + i, padGetStyleSet(&state[i].pad));
|
state[i].pad_type = state[i].pad_type_prev = hidGetNpadDeviceType((HidNpadIdType) i);
|
||||||
|
state[i].pad_style = state[i].pad_style_prev = hidGetNpadStyleSet((HidNpadIdType) i);
|
||||||
|
hidInitializeVibrationDevices(&state[i].vibrationDeviceHandles, 1,
|
||||||
|
HidNpadIdType_No1 + i, state[i].pad_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
return JOYSTICK_COUNT;
|
return JOYSTICK_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int SWITCH_JoystickGetCount(void) {
|
||||||
SWITCH_JoystickGetCount(void)
|
|
||||||
{
|
|
||||||
return JOYSTICK_COUNT;
|
return JOYSTICK_COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void SWITCH_JoystickDetect(void) {
|
||||||
SWITCH_JoystickDetect(void)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to get the device-dependent name of a joystick */
|
/* Function to get the device-dependent name of a joystick */
|
||||||
static const char *
|
static const char *SWITCH_JoystickGetDeviceName(int device_index) {
|
||||||
SWITCH_JoystickGetDeviceName(int device_index)
|
|
||||||
{
|
|
||||||
return "Switch Controller";
|
return "Switch Controller";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int SWITCH_JoystickGetDevicePlayerIndex(int device_index) {
|
||||||
SWITCH_JoystickGetDevicePlayerIndex(int device_index)
|
|
||||||
{
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void SWITCH_JoystickSetDevicePlayerIndex(int device_index, int player_index) {
|
||||||
SWITCH_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_JoystickGUID
|
static SDL_JoystickGUID SWITCH_JoystickGetDeviceGUID(int device_index) {
|
||||||
SWITCH_JoystickGetDeviceGUID(int device_index)
|
|
||||||
{
|
|
||||||
SDL_JoystickGUID guid;
|
SDL_JoystickGUID guid;
|
||||||
/* the GUID is just the first 16 chars of the name for now */
|
/* the GUID is just the first 16 chars of the name for now */
|
||||||
const char *name = SWITCH_JoystickGetDeviceName(device_index);
|
const char *name = SWITCH_JoystickGetDeviceName(device_index);
|
||||||
|
@ -117,9 +181,7 @@ SWITCH_JoystickGetDeviceGUID(int device_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to perform the mapping from device index to the instance id for this index */
|
/* Function to perform the mapping from device index to the instance id for this index */
|
||||||
static SDL_JoystickID
|
static SDL_JoystickID SWITCH_JoystickGetDeviceInstanceID(int device_index) {
|
||||||
SWITCH_JoystickGetDeviceInstanceID(int device_index)
|
|
||||||
{
|
|
||||||
return device_index;
|
return device_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,10 +190,8 @@ SWITCH_JoystickGetDeviceInstanceID(int device_index)
|
||||||
This should fill the nbuttons and naxes fields of the joystick structure.
|
This should fill the nbuttons and naxes fields of the joystick structure.
|
||||||
It returns 0, or -1 if there is an error.
|
It returns 0, or -1 if there is an error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int SWITCH_JoystickOpen(SDL_Joystick *joystick, int device_index) {
|
||||||
SWITCH_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
joystick->nbuttons = sizeof(pad_mapping_default) / sizeof(*pad_mapping_default);
|
||||||
{
|
|
||||||
joystick->nbuttons = sizeof(pad_mapping) / sizeof(*pad_mapping);
|
|
||||||
joystick->naxes = 4;
|
joystick->naxes = 4;
|
||||||
joystick->nhats = 0;
|
joystick->nhats = 0;
|
||||||
joystick->instance_id = device_index;
|
joystick->instance_id = device_index;
|
||||||
|
@ -139,9 +199,7 @@ SWITCH_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int SWITCH_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) {
|
||||||
SWITCH_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
|
||||||
{
|
|
||||||
int id = joystick->instance_id;
|
int id = joystick->instance_id;
|
||||||
|
|
||||||
state[id].vibrationValues.amp_low =
|
state[id].vibrationValues.amp_low =
|
||||||
|
@ -156,27 +214,19 @@ SWITCH_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int SWITCH_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right) {
|
||||||
SWITCH_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left, Uint16 right)
|
|
||||||
{
|
|
||||||
return SDL_Unsupported();
|
return SDL_Unsupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool SWITCH_JoystickHasLED(SDL_Joystick *joystick) {
|
||||||
SWITCH_JoystickHasLED(SDL_Joystick * joystick)
|
|
||||||
{
|
|
||||||
return SDL_FALSE;
|
return SDL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int SWITCH_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) {
|
||||||
SWITCH_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
|
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int SWITCH_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) {
|
||||||
SWITCH_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
|
||||||
{
|
|
||||||
return SDL_Unsupported();
|
return SDL_Unsupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,45 +235,61 @@ SWITCH_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||||
* but instead should call SDL_PrivateJoystick*() to deliver events
|
* but instead should call SDL_PrivateJoystick*() to deliver events
|
||||||
* and update joystick device state.
|
* and update joystick device state.
|
||||||
*/
|
*/
|
||||||
static void
|
static void SWITCH_JoystickUpdate(SDL_Joystick *joystick) {
|
||||||
SWITCH_JoystickUpdate(SDL_Joystick *joystick)
|
|
||||||
{
|
|
||||||
u64 diff;
|
u64 diff;
|
||||||
int index = (int) SDL_JoystickInstanceID(joystick);
|
int index = (int) SDL_JoystickInstanceID(joystick);
|
||||||
if (index > JOYSTICK_COUNT || SDL_IsTextInputActive()) {
|
if (index >= JOYSTICK_COUNT || SDL_IsTextInputActive()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
padUpdate(&state[index].pad);
|
padUpdate(&state[index].pad);
|
||||||
|
if (!padIsConnected(&state[index].pad)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Axes (left)
|
// update pad type and style, open controller support applet if needed
|
||||||
|
state[index].pad_type = hidGetNpadDeviceType((HidNpadIdType) index);
|
||||||
|
state[index].pad_style = hidGetNpadStyleSet((HidNpadIdType) index);
|
||||||
|
if (state[index].pad_type != state[index].pad_type_prev
|
||||||
|
|| state[index].pad_style != state[index].pad_style_prev) {
|
||||||
|
SWITCH_ShowControllerSupport();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only handle axes in non-single joycon mode
|
||||||
|
if (state[index].pad_style & HidNpadStyleTag_NpadJoyDual
|
||||||
|
|| (state[index].pad_type != HidDeviceTypeBits_JoyLeft
|
||||||
|
&& state[index].pad_type != HidDeviceTypeBits_JoyRight)) {
|
||||||
|
// axis left
|
||||||
if (state[index].sticks_old[0].x != state[index].pad.sticks[0].x) {
|
if (state[index].sticks_old[0].x != state[index].pad.sticks[0].x) {
|
||||||
SDL_PrivateJoystickAxis(joystick, 0, (Sint16) state[index].pad.sticks[0].x);
|
SDL_PrivateJoystickAxis(joystick, 0, (Sint16) state[index].pad.sticks[0].x);
|
||||||
state[index].sticks_old[0].x = state[index].pad.sticks[0].x;
|
state[index].sticks_old[0].x = state[index].pad.sticks[0].x;
|
||||||
}
|
}
|
||||||
if (state[index].sticks_old[0].y != state[index].pad.sticks[0].y) {
|
if (state[index].sticks_old[0].y != state[index].pad.sticks[0].y) {
|
||||||
SDL_PrivateJoystickAxis(joystick, 1, (Sint16) -state[index].pad.sticks[0].y);
|
SDL_PrivateJoystickAxis(joystick, 1, (Sint16) - state[index].pad.sticks[0].y);
|
||||||
state[index].sticks_old[0].y = -state[index].pad.sticks[0].y;
|
state[index].sticks_old[0].y = -state[index].pad.sticks[0].y;
|
||||||
}
|
}
|
||||||
state[index].sticks_old[0] = padGetStickPos(&state[index].pad, 0);
|
state[index].sticks_old[0] = padGetStickPos(&state[index].pad, 0);
|
||||||
// Axes (right)
|
// axis right
|
||||||
if (state[index].sticks_old[1].x != state[index].pad.sticks[1].x) {
|
if (state[index].sticks_old[1].x != state[index].pad.sticks[1].x) {
|
||||||
SDL_PrivateJoystickAxis(joystick, 2, (Sint16) state[index].pad.sticks[1].x);
|
SDL_PrivateJoystickAxis(joystick, 2, (Sint16) state[index].pad.sticks[1].x);
|
||||||
state[index].sticks_old[1].x = state[index].pad.sticks[1].x;
|
state[index].sticks_old[1].x = state[index].pad.sticks[1].x;
|
||||||
}
|
}
|
||||||
if (state[index].sticks_old[1].y != state[index].pad.sticks[1].y) {
|
if (state[index].sticks_old[1].y != state[index].pad.sticks[1].y) {
|
||||||
SDL_PrivateJoystickAxis(joystick, 3, (Sint16) -state[index].pad.sticks[1].y);
|
SDL_PrivateJoystickAxis(joystick, 3, (Sint16) - state[index].pad.sticks[1].y);
|
||||||
state[index].sticks_old[1].y = -state[index].pad.sticks[1].y;
|
state[index].sticks_old[1].y = -state[index].pad.sticks[1].y;
|
||||||
}
|
}
|
||||||
state[index].sticks_old[1] = padGetStickPos(&state[index].pad, 1);
|
state[index].sticks_old[1] = padGetStickPos(&state[index].pad, 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Buttons
|
// handle buttons
|
||||||
diff = state[index].pad.buttons_old ^ state[index].pad.buttons_cur;
|
diff = state[index].pad.buttons_old ^ state[index].pad.buttons_cur;
|
||||||
if (diff) {
|
if (diff) {
|
||||||
for (int i = 0; i < joystick->nbuttons; i++) {
|
for (int i = 0; i < joystick->nbuttons; i++) {
|
||||||
if (diff & pad_mapping[i]) {
|
if (diff & state[index].pad_mapping[i]) {
|
||||||
SDL_PrivateJoystickButton(joystick, i,
|
SDL_PrivateJoystickButton(
|
||||||
state[index].pad.buttons_cur & pad_mapping[i] ?
|
joystick, i,
|
||||||
|
state[index].pad.buttons_cur & state[index].pad_mapping[i] ?
|
||||||
SDL_PRESSED : SDL_RELEASED);
|
SDL_PRESSED : SDL_RELEASED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,19 +297,14 @@ SWITCH_JoystickUpdate(SDL_Joystick *joystick)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to close a joystick after use */
|
/* Function to close a joystick after use */
|
||||||
static void
|
static void SWITCH_JoystickClose(SDL_Joystick *joystick) {
|
||||||
SWITCH_JoystickClose(SDL_Joystick *joystick)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function to perform any system-specific joystick related cleanup */
|
/* Function to perform any system-specific joystick related cleanup */
|
||||||
static void
|
static void SWITCH_JoystickQuit(void) {
|
||||||
SWITCH_JoystickQuit(void)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_JoystickDriver SDL_SWITCH_JoystickDriver =
|
SDL_JoystickDriver SDL_SWITCH_JoystickDriver = {
|
||||||
{
|
|
||||||
SWITCH_JoystickInit,
|
SWITCH_JoystickInit,
|
||||||
SWITCH_JoystickGetCount,
|
SWITCH_JoystickGetCount,
|
||||||
SWITCH_JoystickDetect,
|
SWITCH_JoystickDetect,
|
||||||
|
|
Loading…
Reference in New Issue