mirror of https://github.com/encounter/SDL.git
switch: handle single joycons
This commit is contained in:
parent
c29f5893c8
commit
0705288edd
|
@ -26,88 +26,152 @@
|
|||
|
||||
#include "SDL_events.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "SDL_hints.h"
|
||||
|
||||
#include <switch.h>
|
||||
|
||||
#define JOYSTICK_COUNT 8
|
||||
|
||||
typedef struct SWITCHJoystickState
|
||||
{
|
||||
typedef struct SWITCHJoystickState {
|
||||
PadState pad;
|
||||
HidAnalogStickState sticks_old[2];
|
||||
HidVibrationDeviceHandle vibrationDeviceHandles;
|
||||
HidVibrationValue vibrationValues;
|
||||
HidNpadButton *pad_mapping;
|
||||
u32 pad_type;
|
||||
u32 pad_type_prev;
|
||||
HidNpadStyleTag pad_style;
|
||||
HidNpadStyleTag pad_style_prev;
|
||||
} SWITCHJoystickState;
|
||||
|
||||
static SWITCHJoystickState state[JOYSTICK_COUNT];
|
||||
|
||||
static const HidNpadButton pad_mapping[] = {
|
||||
HidNpadButton_A, HidNpadButton_B, HidNpadButton_X, HidNpadButton_Y,
|
||||
HidNpadButton_StickL, HidNpadButton_StickR,
|
||||
HidNpadButton_L, HidNpadButton_R,
|
||||
HidNpadButton_ZL, HidNpadButton_ZR,
|
||||
HidNpadButton_Plus, HidNpadButton_Minus,
|
||||
HidNpadButton_Left, HidNpadButton_Up, HidNpadButton_Right, HidNpadButton_Down,
|
||||
HidNpadButton_StickLLeft, HidNpadButton_StickLUp, HidNpadButton_StickLRight, HidNpadButton_StickLDown,
|
||||
HidNpadButton_StickRLeft, HidNpadButton_StickRUp, HidNpadButton_StickRRight, HidNpadButton_StickRDown,
|
||||
HidNpadButton_LeftSL, HidNpadButton_LeftSR, HidNpadButton_RightSL, HidNpadButton_RightSR
|
||||
static const HidNpadButton pad_mapping_default[] = {
|
||||
HidNpadButton_A, HidNpadButton_B, HidNpadButton_X, HidNpadButton_Y,
|
||||
HidNpadButton_StickL, HidNpadButton_StickR,
|
||||
HidNpadButton_L, HidNpadButton_R,
|
||||
HidNpadButton_ZL, HidNpadButton_ZR,
|
||||
HidNpadButton_Plus, HidNpadButton_Minus,
|
||||
HidNpadButton_Left, HidNpadButton_Up, HidNpadButton_Right, HidNpadButton_Down,
|
||||
HidNpadButton_StickLLeft, HidNpadButton_StickLUp, HidNpadButton_StickLRight, HidNpadButton_StickLDown,
|
||||
HidNpadButton_StickRLeft, HidNpadButton_StickRUp, HidNpadButton_StickRRight, HidNpadButton_StickRDown,
|
||||
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.
|
||||
* It should return 0, or -1 on an unrecoverable fatal error.
|
||||
*/
|
||||
static int
|
||||
SWITCH_JoystickInit(void)
|
||||
{
|
||||
static int SWITCH_JoystickInit(void) {
|
||||
padConfigureInput(JOYSTICK_COUNT, HidNpadStyleSet_NpadStandard);
|
||||
|
||||
// initialize first pad to defaults
|
||||
padInitializeDefault(&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
|
||||
for (int i = 1; i < JOYSTICK_COUNT; i++) {
|
||||
padInitialize(&state[i].pad, HidNpadIdType_No1 + i);
|
||||
padUpdate(&state[i].pad);
|
||||
hidInitializeVibrationDevices(&state[i].vibrationDeviceHandles,1,
|
||||
HidNpadIdType_No1 + i, padGetStyleSet(&state[i].pad));
|
||||
state[i].pad_mapping = (HidNpadButton *) &pad_mapping_default;
|
||||
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;
|
||||
}
|
||||
|
||||
static int
|
||||
SWITCH_JoystickGetCount(void)
|
||||
{
|
||||
static int SWITCH_JoystickGetCount(void) {
|
||||
return JOYSTICK_COUNT;
|
||||
}
|
||||
|
||||
static void
|
||||
SWITCH_JoystickDetect(void)
|
||||
{
|
||||
static void SWITCH_JoystickDetect(void) {
|
||||
}
|
||||
|
||||
/* Function to get the device-dependent name of a joystick */
|
||||
static const char *
|
||||
SWITCH_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
static const char *SWITCH_JoystickGetDeviceName(int device_index) {
|
||||
return "Switch Controller";
|
||||
}
|
||||
|
||||
static int
|
||||
SWITCH_JoystickGetDevicePlayerIndex(int device_index)
|
||||
{
|
||||
static int SWITCH_JoystickGetDevicePlayerIndex(int device_index) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
SWITCH_JoystickSetDevicePlayerIndex(int device_index, int player_index)
|
||||
{
|
||||
static void SWITCH_JoystickSetDevicePlayerIndex(int device_index, int player_index) {
|
||||
}
|
||||
|
||||
static SDL_JoystickGUID
|
||||
SWITCH_JoystickGetDeviceGUID(int device_index)
|
||||
{
|
||||
static SDL_JoystickGUID SWITCH_JoystickGetDeviceGUID(int device_index) {
|
||||
SDL_JoystickGUID guid;
|
||||
/* the GUID is just the first 16 chars of the name for now */
|
||||
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 */
|
||||
static SDL_JoystickID
|
||||
SWITCH_JoystickGetDeviceInstanceID(int device_index)
|
||||
{
|
||||
static SDL_JoystickID SWITCH_JoystickGetDeviceInstanceID(int 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.
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
static int
|
||||
SWITCH_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
{
|
||||
joystick->nbuttons = sizeof(pad_mapping) / sizeof(*pad_mapping);
|
||||
static int SWITCH_JoystickOpen(SDL_Joystick *joystick, int device_index) {
|
||||
joystick->nbuttons = sizeof(pad_mapping_default) / sizeof(*pad_mapping_default);
|
||||
joystick->naxes = 4;
|
||||
joystick->nhats = 0;
|
||||
joystick->instance_id = device_index;
|
||||
|
@ -139,9 +199,7 @@ SWITCH_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SWITCH_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
static int SWITCH_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble) {
|
||||
int id = joystick->instance_id;
|
||||
|
||||
state[id].vibrationValues.amp_low =
|
||||
|
@ -156,27 +214,19 @@ SWITCH_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SWITCH_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left, Uint16 right)
|
||||
{
|
||||
static int SWITCH_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left, Uint16 right) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
SWITCH_JoystickHasLED(SDL_Joystick * joystick)
|
||||
{
|
||||
static SDL_bool SWITCH_JoystickHasLED(SDL_Joystick *joystick) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
SWITCH_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
static int SWITCH_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SWITCH_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
static int SWITCH_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled) {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
|
@ -185,82 +235,93 @@ SWITCH_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
|||
* but instead should call SDL_PrivateJoystick*() to deliver events
|
||||
* and update joystick device state.
|
||||
*/
|
||||
static void
|
||||
SWITCH_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
static void SWITCH_JoystickUpdate(SDL_Joystick *joystick) {
|
||||
u64 diff;
|
||||
int index = (int) SDL_JoystickInstanceID(joystick);
|
||||
if (index > JOYSTICK_COUNT || SDL_IsTextInputActive()) {
|
||||
if (index >= JOYSTICK_COUNT || SDL_IsTextInputActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
padUpdate(&state[index].pad);
|
||||
if (!padIsConnected(&state[index].pad)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Axes (left)
|
||||
if (state[index].sticks_old[0].x != 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;
|
||||
// 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;
|
||||
}
|
||||
if (state[index].sticks_old[0].y != 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] = padGetStickPos(&state[index].pad, 0);
|
||||
// Axes (right)
|
||||
if (state[index].sticks_old[1].x != 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;
|
||||
}
|
||||
if (state[index].sticks_old[1].y != 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] = padGetStickPos(&state[index].pad, 1);
|
||||
|
||||
// Buttons
|
||||
// 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) {
|
||||
SDL_PrivateJoystickAxis(joystick, 0, (Sint16) 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) {
|
||||
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] = padGetStickPos(&state[index].pad, 0);
|
||||
// axis right
|
||||
if (state[index].sticks_old[1].x != 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;
|
||||
}
|
||||
if (state[index].sticks_old[1].y != 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] = padGetStickPos(&state[index].pad, 1);
|
||||
}
|
||||
|
||||
// handle buttons
|
||||
diff = state[index].pad.buttons_old ^ state[index].pad.buttons_cur;
|
||||
if (diff) {
|
||||
for (int i = 0; i < joystick->nbuttons; i++) {
|
||||
if (diff & pad_mapping[i]) {
|
||||
SDL_PrivateJoystickButton(joystick, i,
|
||||
state[index].pad.buttons_cur & pad_mapping[i] ?
|
||||
SDL_PRESSED : SDL_RELEASED);
|
||||
if (diff & state[index].pad_mapping[i]) {
|
||||
SDL_PrivateJoystickButton(
|
||||
joystick, i,
|
||||
state[index].pad.buttons_cur & state[index].pad_mapping[i] ?
|
||||
SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
static void
|
||||
SWITCH_JoystickClose(SDL_Joystick *joystick)
|
||||
{
|
||||
static void SWITCH_JoystickClose(SDL_Joystick *joystick) {
|
||||
}
|
||||
|
||||
/* Function to perform any system-specific joystick related cleanup */
|
||||
static void
|
||||
SWITCH_JoystickQuit(void)
|
||||
{
|
||||
static void SWITCH_JoystickQuit(void) {
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_SWITCH_JoystickDriver =
|
||||
{
|
||||
SWITCH_JoystickInit,
|
||||
SWITCH_JoystickGetCount,
|
||||
SWITCH_JoystickDetect,
|
||||
SWITCH_JoystickGetDeviceName,
|
||||
SWITCH_JoystickGetDevicePlayerIndex,
|
||||
SWITCH_JoystickSetDevicePlayerIndex,
|
||||
SWITCH_JoystickGetDeviceGUID,
|
||||
SWITCH_JoystickGetDeviceInstanceID,
|
||||
SWITCH_JoystickOpen,
|
||||
SWITCH_JoystickRumble,
|
||||
SWITCH_JoystickRumbleTriggers,
|
||||
SWITCH_JoystickHasLED,
|
||||
SWITCH_JoystickSetLED,
|
||||
SWITCH_JoystickSetSensorsEnabled,
|
||||
SWITCH_JoystickUpdate,
|
||||
SWITCH_JoystickClose,
|
||||
SWITCH_JoystickQuit,
|
||||
SDL_JoystickDriver SDL_SWITCH_JoystickDriver = {
|
||||
SWITCH_JoystickInit,
|
||||
SWITCH_JoystickGetCount,
|
||||
SWITCH_JoystickDetect,
|
||||
SWITCH_JoystickGetDeviceName,
|
||||
SWITCH_JoystickGetDevicePlayerIndex,
|
||||
SWITCH_JoystickSetDevicePlayerIndex,
|
||||
SWITCH_JoystickGetDeviceGUID,
|
||||
SWITCH_JoystickGetDeviceInstanceID,
|
||||
SWITCH_JoystickOpen,
|
||||
SWITCH_JoystickRumble,
|
||||
SWITCH_JoystickRumbleTriggers,
|
||||
SWITCH_JoystickHasLED,
|
||||
SWITCH_JoystickSetLED,
|
||||
SWITCH_JoystickSetSensorsEnabled,
|
||||
SWITCH_JoystickUpdate,
|
||||
SWITCH_JoystickClose,
|
||||
SWITCH_JoystickQuit,
|
||||
};
|
||||
|
||||
#endif /* SDL_JOYSTICK_SWITCH */
|
||||
|
|
Loading…
Reference in New Issue