mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-24 00:20:01 +00:00
Merge pull request #1959 from netux79/master
Fixed nunchuk controller support, it was not correctly detected.
This commit is contained in:
commit
f2ee781e92
@ -122,7 +122,7 @@ HAVE_7ZIP := 1
|
||||
HAVE_RPNG := 1
|
||||
HAVE_RPNG := 1
|
||||
HAVE_OVERLAY := 1
|
||||
HAVE_LIBSICKSAXIS := 0
|
||||
HAVE_LIBSICKSAXIS := 1
|
||||
HAVE_BUILTIN_AUTOCONFIG := 1
|
||||
else ifeq ($(platform), psp1)
|
||||
CC = psp-gcc$(EXE_EXT)
|
||||
|
@ -22,13 +22,13 @@ DECL_BTN(b, 1) \
|
||||
DECL_BTN(x, 2) \
|
||||
DECL_BTN(y, 3) \
|
||||
DECL_BTN(start, 4) \
|
||||
DECL_BTN(select, 5) \
|
||||
DECL_BTN(up, 8) \
|
||||
DECL_BTN(down, 9) \
|
||||
DECL_BTN(left, 10) \
|
||||
DECL_BTN(right, 11) \
|
||||
DECL_BTN(l, 6) \
|
||||
DECL_BTN(r, 7) \
|
||||
DECL_BTN(select, 6) \
|
||||
DECL_BTN(up, 9) \
|
||||
DECL_BTN(down, 10) \
|
||||
DECL_BTN(left, 11) \
|
||||
DECL_BTN(right, 12) \
|
||||
DECL_BTN(l, 7) \
|
||||
DECL_BTN(r, 8) \
|
||||
DECL_AXIS(l_x_plus, +0) \
|
||||
DECL_AXIS(l_x_minus, -0) \
|
||||
DECL_AXIS(l_y_plus, +1) \
|
||||
@ -39,50 +39,50 @@ DECL_AXIS(r_y_plus, -3) \
|
||||
DECL_AXIS(r_y_minus, +3)
|
||||
|
||||
#define GXINPUT_WIIMOTE_DEFAULT_BINDS \
|
||||
DECL_BTN(a, 46) \
|
||||
DECL_BTN(b, 45) \
|
||||
DECL_BTN(x, 45) \
|
||||
DECL_BTN(y, 43) \
|
||||
DECL_BTN(start, 47) \
|
||||
DECL_BTN(select, 48) \
|
||||
DECL_BTN(up, 50) \
|
||||
DECL_BTN(down, 51) \
|
||||
DECL_BTN(left, 52) \
|
||||
DECL_BTN(right, 53)
|
||||
DECL_BTN(a, 31) \
|
||||
DECL_BTN(b, 30) \
|
||||
DECL_BTN(x, 29) \
|
||||
DECL_BTN(y, 28) \
|
||||
DECL_BTN(start, 32) \
|
||||
DECL_BTN(select, 33) \
|
||||
DECL_BTN(up, 35) \
|
||||
DECL_BTN(down, 36) \
|
||||
DECL_BTN(left, 37) \
|
||||
DECL_BTN(right, 38)
|
||||
|
||||
#define GXINPUT_NUNCHUK_DEFAULT_BINDS \
|
||||
DECL_BTN(a, 43) \
|
||||
DECL_BTN(b, 44) \
|
||||
DECL_BTN(x, 45) \
|
||||
DECL_BTN(y, 46) \
|
||||
DECL_BTN(start, 47) \
|
||||
DECL_BTN(select, 48) \
|
||||
DECL_BTN(up, 50) \
|
||||
DECL_BTN(down, 51) \
|
||||
DECL_BTN(left, 52) \
|
||||
DECL_BTN(right, 53) \
|
||||
DECL_BTN(l, 54) \
|
||||
DECL_BTN(r, 55) \
|
||||
DECL_BTN(a, 28) \
|
||||
DECL_BTN(b, 29) \
|
||||
DECL_BTN(x, 30) \
|
||||
DECL_BTN(y, 31) \
|
||||
DECL_BTN(start, 32) \
|
||||
DECL_BTN(select, 33) \
|
||||
DECL_BTN(up, 35) \
|
||||
DECL_BTN(down, 36) \
|
||||
DECL_BTN(left, 37) \
|
||||
DECL_BTN(right, 38) \
|
||||
DECL_BTN(l, 39) \
|
||||
DECL_BTN(r, 40) \
|
||||
DECL_AXIS(l_x_plus, +0) \
|
||||
DECL_AXIS(l_x_minus, -0) \
|
||||
DECL_AXIS(l_y_plus, +1) \
|
||||
DECL_AXIS(l_y_minus, -1)
|
||||
|
||||
#define GXINPUT_CLASSIC_DEFAULT_BINDS \
|
||||
DECL_BTN(a, 20) \
|
||||
DECL_BTN(b, 21) \
|
||||
DECL_BTN(x, 22) \
|
||||
DECL_BTN(y, 23) \
|
||||
DECL_BTN(start, 24) \
|
||||
DECL_BTN(select, 25) \
|
||||
DECL_BTN(up, 31) \
|
||||
DECL_BTN(down, 32) \
|
||||
DECL_BTN(left, 33) \
|
||||
DECL_BTN(right, 34) \
|
||||
DECL_BTN(l, 27) \
|
||||
DECL_BTN(r, 28) \
|
||||
DECL_BTN(l2, 29) \
|
||||
DECL_BTN(r2, 30) \
|
||||
DECL_BTN(a, 13) \
|
||||
DECL_BTN(b, 14) \
|
||||
DECL_BTN(x, 15) \
|
||||
DECL_BTN(y, 16) \
|
||||
DECL_BTN(start, 17) \
|
||||
DECL_BTN(select, 18) \
|
||||
DECL_BTN(up, 24) \
|
||||
DECL_BTN(down, 25) \
|
||||
DECL_BTN(left, 26) \
|
||||
DECL_BTN(right, 27) \
|
||||
DECL_BTN(l, 20) \
|
||||
DECL_BTN(r, 21) \
|
||||
DECL_BTN(l2, 22) \
|
||||
DECL_BTN(r2, 23) \
|
||||
DECL_AXIS(l_x_plus, +0) \
|
||||
DECL_AXIS(l_x_minus, -0) \
|
||||
DECL_AXIS(l_y_plus, +1) \
|
||||
@ -92,15 +92,44 @@ DECL_AXIS(r_x_minus, -2) \
|
||||
DECL_AXIS(r_y_plus, -3) \
|
||||
DECL_AXIS(r_y_minus, +3)
|
||||
|
||||
/* TODO: missing Libsicksaxis binds */
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
#define GXINPUT_SIXAXIS_DEFAULT_BINDS \
|
||||
DECL_BTN(a, 45) \
|
||||
DECL_BTN(b, 46) \
|
||||
DECL_BTN(x, 47) \
|
||||
DECL_BTN(y, 48) \
|
||||
DECL_BTN(start, 55) \
|
||||
DECL_BTN(select, 56) \
|
||||
DECL_BTN(up, 58) \
|
||||
DECL_BTN(down, 59) \
|
||||
DECL_BTN(left, 60) \
|
||||
DECL_BTN(right, 61) \
|
||||
DECL_BTN(l, 49) \
|
||||
DECL_BTN(r, 50) \
|
||||
DECL_BTN(l2, 51) \
|
||||
DECL_BTN(r2, 52) \
|
||||
DECL_BTN(l3, 53) \
|
||||
DECL_BTN(r3, 54) \
|
||||
DECL_AXIS(l_x_plus, +0) \
|
||||
DECL_AXIS(l_x_minus, -0) \
|
||||
DECL_AXIS(l_y_plus, +1) \
|
||||
DECL_AXIS(l_y_minus, -1) \
|
||||
DECL_AXIS(r_x_plus, +2) \
|
||||
DECL_AXIS(r_x_minus, -2) \
|
||||
DECL_AXIS(r_y_plus, -3) \
|
||||
DECL_AXIS(r_y_minus, +3)
|
||||
#endif
|
||||
|
||||
const char* const input_builtin_autoconfs[] =
|
||||
{
|
||||
DECL_AUTOCONF_DEVICE("GameCube Controller", "gx", GXINPUT_GAMECUBE_DEFAULT_BINDS),
|
||||
#ifdef HW_RVL
|
||||
DECL_AUTOCONF_DEVICE("Wiimote Controller", "gx", GXINPUT_WIIMOTE_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("NunChuk Controller", "gx", GXINPUT_NUNCHUK_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("Nunchuk Controller", "gx", GXINPUT_NUNCHUK_DEFAULT_BINDS),
|
||||
DECL_AUTOCONF_DEVICE("Classic Controller", "gx", GXINPUT_CLASSIC_DEFAULT_BINDS),
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
DECL_AUTOCONF_DEVICE("Sixaxis Controller", "gx", GXINPUT_SIXAXIS_DEFAULT_BINDS),
|
||||
#endif
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
@ -64,51 +64,68 @@ enum
|
||||
GX_GC_X = 2,
|
||||
GX_GC_Y = 3,
|
||||
GX_GC_START = 4,
|
||||
GX_GC_Z_TRIGGER = 5,
|
||||
GX_GC_L_TRIGGER = 6,
|
||||
GX_GC_R_TRIGGER = 7,
|
||||
GX_GC_UP = 8,
|
||||
GX_GC_DOWN = 9,
|
||||
GX_GC_LEFT = 10,
|
||||
GX_GC_RIGHT = 11,
|
||||
GX_GC_HOME = 5,/* needed on GameCube as "fake" menu button. */
|
||||
GX_GC_Z_TRIGGER = 6,
|
||||
GX_GC_L_TRIGGER = 7,
|
||||
GX_GC_R_TRIGGER = 8,
|
||||
GX_GC_UP = 9,
|
||||
GX_GC_DOWN = 10,
|
||||
GX_GC_LEFT = 11,
|
||||
GX_GC_RIGHT = 12,
|
||||
#ifdef HW_RVL
|
||||
GX_CLASSIC_A = 20,
|
||||
GX_CLASSIC_B = 21,
|
||||
GX_CLASSIC_X = 22,
|
||||
GX_CLASSIC_Y = 23,
|
||||
GX_CLASSIC_PLUS = 24,
|
||||
GX_CLASSIC_MINUS = 25,
|
||||
GX_CLASSIC_HOME = 26,
|
||||
GX_CLASSIC_L_TRIGGER = 27,
|
||||
GX_CLASSIC_R_TRIGGER = 28,
|
||||
GX_CLASSIC_ZL_TRIGGER = 29,
|
||||
GX_CLASSIC_ZR_TRIGGER = 30,
|
||||
GX_CLASSIC_UP = 31,
|
||||
GX_CLASSIC_DOWN = 32,
|
||||
GX_CLASSIC_LEFT = 33,
|
||||
GX_CLASSIC_RIGHT = 34,
|
||||
GX_WIIMOTE_A = 43,
|
||||
GX_WIIMOTE_B = 44,
|
||||
GX_WIIMOTE_1 = 45,
|
||||
GX_WIIMOTE_2 = 46,
|
||||
GX_WIIMOTE_PLUS = 47,
|
||||
GX_WIIMOTE_MINUS = 48,
|
||||
#if 0
|
||||
GX_WIIMOTE_HOME = 49,
|
||||
GX_CLASSIC_A = 13,
|
||||
GX_CLASSIC_B = 14,
|
||||
GX_CLASSIC_X = 15,
|
||||
GX_CLASSIC_Y = 16,
|
||||
GX_CLASSIC_PLUS = 17,
|
||||
GX_CLASSIC_MINUS = 18,
|
||||
GX_CLASSIC_HOME = 19,
|
||||
GX_CLASSIC_L_TRIGGER = 20,
|
||||
GX_CLASSIC_R_TRIGGER = 21,
|
||||
GX_CLASSIC_ZL_TRIGGER = 22,
|
||||
GX_CLASSIC_ZR_TRIGGER = 23,
|
||||
GX_CLASSIC_UP = 24,
|
||||
GX_CLASSIC_DOWN = 25,
|
||||
GX_CLASSIC_LEFT = 26,
|
||||
GX_CLASSIC_RIGHT = 27,
|
||||
GX_WIIMOTE_A = 28,
|
||||
GX_WIIMOTE_B = 29,
|
||||
GX_WIIMOTE_1 = 30,
|
||||
GX_WIIMOTE_2 = 31,
|
||||
GX_WIIMOTE_PLUS = 32,
|
||||
GX_WIIMOTE_MINUS = 33,
|
||||
GX_WIIMOTE_HOME = 34,
|
||||
GX_WIIMOTE_UP = 35,
|
||||
GX_WIIMOTE_DOWN = 36,
|
||||
GX_WIIMOTE_LEFT = 37,
|
||||
GX_WIIMOTE_RIGHT = 38,
|
||||
GX_NUNCHUK_Z = 39,
|
||||
GX_NUNCHUK_C = 40,
|
||||
GX_NUNCHUK_UP = 41,
|
||||
GX_NUNCHUK_DOWN = 42,
|
||||
GX_NUNCHUK_LEFT = 43,
|
||||
GX_NUNCHUK_RIGHT = 44,
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
GX_SIXAXIS_CIRCLE = 45,
|
||||
GX_SIXAXIS_CROSS = 46,
|
||||
GX_SIXAXIS_TRIANGLE = 47,
|
||||
GX_SIXAXIS_SQUARE = 48,
|
||||
GX_SIXAXIS_L1 = 49,
|
||||
GX_SIXAXIS_R1 = 50,
|
||||
GX_SIXAXIS_L2 = 51,
|
||||
GX_SIXAXIS_R2 = 52,
|
||||
GX_SIXAXIS_L3 = 53,
|
||||
GX_SIXAXIS_R3 = 54,
|
||||
GX_SIXAXIS_START = 55,
|
||||
GX_SIXAXIS_SELECT = 56,
|
||||
GX_SIXAXIS_PS = 57,
|
||||
GX_SIXAXIS_UP = 58,
|
||||
GX_SIXAXIS_DOWN = 59,
|
||||
GX_SIXAXIS_LEFT = 60,
|
||||
GX_SIXAXIS_RIGHT = 61,
|
||||
#endif
|
||||
GX_WIIMOTE_UP = 50,
|
||||
GX_WIIMOTE_DOWN = 51,
|
||||
GX_WIIMOTE_LEFT = 52,
|
||||
GX_WIIMOTE_RIGHT = 53,
|
||||
GX_NUNCHUK_Z = 54,
|
||||
GX_NUNCHUK_C = 55,
|
||||
GX_NUNCHUK_UP = 56,
|
||||
GX_NUNCHUK_DOWN = 57,
|
||||
GX_NUNCHUK_LEFT = 58,
|
||||
GX_NUNCHUK_RIGHT = 59,
|
||||
#endif
|
||||
GX_WIIMOTE_HOME = 49, /* needed on GameCube as "fake" menu button. */
|
||||
GX_QUIT_KEY = 60,
|
||||
GX_QUIT_KEY = 62,
|
||||
};
|
||||
|
||||
#define GC_JOYSTICK_THRESHOLD (48 * 256)
|
||||
@ -128,19 +145,8 @@ static void power_callback(void)
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
volatile int lol = 0;
|
||||
struct ss_device dev[MAX_PADS];
|
||||
|
||||
int change_cb(int result, void *usrdata)
|
||||
{
|
||||
(*(volatile int*)usrdata)++;
|
||||
return result;
|
||||
}
|
||||
|
||||
void removal_cb(void *usrdata)
|
||||
{
|
||||
input_config_autoconfigure_disconnect((int)usrdata, gx_joypad.ident);
|
||||
}
|
||||
# define USB_SLOTS 1
|
||||
struct ss_device sixaxis[USB_SLOTS];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -260,10 +266,10 @@ static int16_t gx_joypad_axis(unsigned port, uint32_t joyaxis)
|
||||
#define PI 3.14159265f
|
||||
#endif
|
||||
|
||||
static s8 WPAD_StickX(WPADData *data, u8 chan,u8 right)
|
||||
static int16_t WPAD_StickX(WPADData *data, u8 right)
|
||||
{
|
||||
float mag = 0.0;
|
||||
float ang = 0.0;
|
||||
float mag = 0.0f;
|
||||
float ang = 0.0f;
|
||||
|
||||
switch (data->exp.type)
|
||||
{
|
||||
@ -294,19 +300,19 @@ static s8 WPAD_StickX(WPADData *data, u8 chan,u8 right)
|
||||
}
|
||||
|
||||
/* calculate X value (angle need to be converted into radian) */
|
||||
if (mag > 1.0)
|
||||
mag = 1.0;
|
||||
else if (mag < -1.0)
|
||||
mag = -1.0;
|
||||
if (mag > 1.0f)
|
||||
mag = 1.0f;
|
||||
else if (mag < -1.0f)
|
||||
mag = -1.0f;
|
||||
double val = mag * sin(PI * ang/180.0f);
|
||||
|
||||
return (s8)(val * 128.0f);
|
||||
return (int16_t)(val * 32767.0f);
|
||||
}
|
||||
|
||||
static s8 WPAD_StickY(WPADData *data, u8 chan, u8 right)
|
||||
static int16_t WPAD_StickY(WPADData *data, u8 right)
|
||||
{
|
||||
float mag = 0.0;
|
||||
float ang = 0.0;
|
||||
float mag = 0.0f;
|
||||
float ang = 0.0f;
|
||||
|
||||
switch (data->exp.type)
|
||||
{
|
||||
@ -336,14 +342,14 @@ static s8 WPAD_StickY(WPADData *data, u8 chan, u8 right)
|
||||
break;
|
||||
}
|
||||
|
||||
/* calculate X value (angle need to be converted into radian) */
|
||||
if (mag > 1.0)
|
||||
mag = 1.0;
|
||||
else if (mag < -1.0)
|
||||
mag = -1.0;
|
||||
double val = mag * cos(PI * ang/180.0f);
|
||||
/* calculate Y value (angle need to be converted into radian) */
|
||||
if (mag > 1.0f)
|
||||
mag = 1.0f;
|
||||
else if (mag < -1.0f)
|
||||
mag = -1.0f;
|
||||
double val = -mag * cos(PI * ang/180.0f);
|
||||
|
||||
return (s8)(val * 128.0f);
|
||||
return (int16_t)(val * 32767.0f);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -368,16 +374,89 @@ static void gx_joypad_poll(void)
|
||||
uint32_t down = 0, ptype = WPAD_EXP_NOCONTROLLER;
|
||||
uint64_t *state_cur = &pad_state[port];
|
||||
|
||||
if (gcpad & (1 << port))
|
||||
{
|
||||
int16_t ls_x, ls_y, rs_x, rs_y;
|
||||
uint64_t menu_combo = 0;
|
||||
|
||||
down = PAD_ButtonsHeld(port);
|
||||
|
||||
*state_cur |= (down & PAD_BUTTON_A) ? (UINT64_C(1) << GX_GC_A) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_B) ? (UINT64_C(1) << GX_GC_B) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_X) ? (UINT64_C(1) << GX_GC_X) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_Y) ? (UINT64_C(1) << GX_GC_Y) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_UP) ? (UINT64_C(1) << GX_GC_UP) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_GC_DOWN) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_GC_LEFT) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_GC_RIGHT) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_START) ? (UINT64_C(1) << GX_GC_START) : 0;
|
||||
*state_cur |= (down & PAD_TRIGGER_Z) ? (UINT64_C(1) << GX_GC_Z_TRIGGER) : 0;
|
||||
*state_cur |= ((down & PAD_TRIGGER_L) || PAD_TriggerL(port) > 127) ? (UINT64_C(1) << GX_GC_L_TRIGGER) : 0;
|
||||
*state_cur |= ((down & PAD_TRIGGER_R) || PAD_TriggerR(port) > 127) ? (UINT64_C(1) << GX_GC_R_TRIGGER) : 0;
|
||||
|
||||
ls_x = (int16_t)PAD_StickX(port) * 256;
|
||||
ls_y = (int16_t)PAD_StickY(port) * -256;
|
||||
rs_x = (int16_t)PAD_SubStickX(port) * 256;
|
||||
rs_y = (int16_t)PAD_SubStickY(port) * -256;
|
||||
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = ls_x;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = ls_y;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = rs_x;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = rs_y;
|
||||
|
||||
menu_combo = (UINT64_C(1) << GX_GC_START) | (UINT64_C(1) << GX_GC_Z_TRIGGER) |
|
||||
(UINT64_C(1) << GX_GC_L_TRIGGER) | (UINT64_C(1) << GX_GC_R_TRIGGER);
|
||||
|
||||
if ((*state_cur & menu_combo) == menu_combo)
|
||||
*state_cur |= (UINT64_C(1) << GX_GC_HOME);
|
||||
|
||||
ptype = WPAD_EXP_GAMECUBE;
|
||||
}
|
||||
#ifdef HW_RVL
|
||||
if (WPADProbe(port, &ptype) == WPAD_ERR_NONE)
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
else if (port < USB_SLOTS && ss_is_ready(&sixaxis[port]))/* Only defined 1 port for now */
|
||||
{
|
||||
int16_t ls_x, ls_y, rs_x, rs_y;
|
||||
|
||||
ss_read_pad(&sixaxis[port]);
|
||||
|
||||
*state_cur |= (sixaxis[port].pad.buttons.PS) ? (UINT64_C(1) << GX_SIXAXIS_PS) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.cross) ? (UINT64_C(1) << GX_SIXAXIS_CROSS) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.square) ? (UINT64_C(1) << GX_SIXAXIS_SQUARE) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.select) ? (UINT64_C(1) << GX_SIXAXIS_SELECT) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.start) ? (UINT64_C(1) << GX_SIXAXIS_START) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.up) ? (UINT64_C(1) << GX_SIXAXIS_UP) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.down) ? (UINT64_C(1) << GX_SIXAXIS_DOWN) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.left) ? (UINT64_C(1) << GX_SIXAXIS_LEFT) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.right) ? (UINT64_C(1) << GX_SIXAXIS_RIGHT) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.circle) ? (UINT64_C(1) << GX_SIXAXIS_CIRCLE) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.triangle) ? (UINT64_C(1) << GX_SIXAXIS_TRIANGLE) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.L1) ? (UINT64_C(1) << GX_SIXAXIS_L1) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.R1) ? (UINT64_C(1) << GX_SIXAXIS_R1) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.L2) ? (UINT64_C(1) << GX_SIXAXIS_L2) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.R2) ? (UINT64_C(1) << GX_SIXAXIS_R2) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.L3) ? (UINT64_C(1) << GX_SIXAXIS_L3) : 0;
|
||||
*state_cur |= (sixaxis[port].pad.buttons.R3) ? (UINT64_C(1) << GX_SIXAXIS_R3) : 0;
|
||||
|
||||
ls_x = (int16_t)(sixaxis[port].pad.left_analog.x - 128) << 8;
|
||||
ls_y = (int16_t)(sixaxis[port].pad.left_analog.y - 128) << 8;
|
||||
rs_x = (int16_t)(sixaxis[port].pad.right_analog.x - 128) << 8;
|
||||
rs_y = (int16_t)(sixaxis[port].pad.right_analog.y - 128) << 8;
|
||||
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = ls_x;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = ls_y;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = rs_x;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = rs_y;
|
||||
|
||||
ptype = WPAD_EXP_SICKSAXIS;
|
||||
}
|
||||
#endif
|
||||
else if (WPADProbe(port, &ptype) == WPAD_ERR_NONE)
|
||||
{
|
||||
WPADData *wpaddata = (WPADData*)WPAD_Data(port);
|
||||
expansion_t *exp = NULL;
|
||||
|
||||
down = wpaddata->btns_h;
|
||||
|
||||
exp = (expansion_t*)&wpaddata->exp;
|
||||
|
||||
*state_cur |= (down & WPAD_BUTTON_A) ? (UINT64_C(1) << GX_WIIMOTE_A) : 0;
|
||||
*state_cur |= (down & WPAD_BUTTON_B) ? (UINT64_C(1) << GX_WIIMOTE_B) : 0;
|
||||
*state_cur |= (down & WPAD_BUTTON_1) ? (UINT64_C(1) << GX_WIIMOTE_1) : 0;
|
||||
@ -395,7 +474,6 @@ static void gx_joypad_poll(void)
|
||||
*state_cur |= (down & WPAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_WIIMOTE_UP) : 0;
|
||||
}
|
||||
|
||||
|
||||
if (ptype == WPAD_EXP_CLASSIC)
|
||||
{
|
||||
*state_cur |= (down & WPAD_CLASSIC_BUTTON_A) ? (UINT64_C(1) << GX_CLASSIC_A) : 0;
|
||||
@ -414,10 +492,10 @@ static void gx_joypad_poll(void)
|
||||
*state_cur |= (down & WPAD_CLASSIC_BUTTON_ZL) ? (UINT64_C(1) << GX_CLASSIC_ZL_TRIGGER) : 0;
|
||||
*state_cur |= (down & WPAD_CLASSIC_BUTTON_ZR) ? (UINT64_C(1) << GX_CLASSIC_ZR_TRIGGER) : 0;
|
||||
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, port, 0);
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, port, 0);
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, port, 1);
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, port, 1);
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, 0);
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, 0);
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, 1);
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, 1);
|
||||
}
|
||||
else if (ptype == WPAD_EXP_NUNCHUK)
|
||||
{
|
||||
@ -431,104 +509,11 @@ static void gx_joypad_poll(void)
|
||||
*state_cur |= (down & WPAD_NUNCHUK_BUTTON_Z) ? (UINT64_C(1) << GX_NUNCHUK_Z) : 0;
|
||||
*state_cur |= (down & WPAD_NUNCHUK_BUTTON_C) ? (UINT64_C(1) << GX_NUNCHUK_C) : 0;
|
||||
|
||||
float js_mag = exp->nunchuk.js.mag;
|
||||
float js_ang = exp->nunchuk.js.ang;
|
||||
|
||||
if (js_mag > 1.0f)
|
||||
js_mag = 1.0f;
|
||||
else if (js_mag < -1.0f)
|
||||
js_mag = -1.0f;
|
||||
|
||||
double js_val_x = js_mag * sin(M_PI * js_ang / 180.0);
|
||||
double js_val_y = -js_mag * cos(M_PI * js_ang / 180.0);
|
||||
|
||||
int16_t x = (int16_t)(js_val_x * 32767.0f);
|
||||
int16_t y = (int16_t)(js_val_y * 32767.0f);
|
||||
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = x;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = y;
|
||||
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = WPAD_StickX(wpaddata, 0);
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = WPAD_StickY(wpaddata, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (gcpad & (1 << port))
|
||||
{
|
||||
int16_t ls_x, ls_y, rs_x, rs_y;
|
||||
uint64_t menu_combo = 0;
|
||||
|
||||
down = PAD_ButtonsHeld(port);
|
||||
|
||||
*state_cur |= (down & PAD_BUTTON_A) ? (UINT64_C(1) << GX_GC_A) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_B) ? (UINT64_C(1) << GX_GC_B) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_X) ? (UINT64_C(1) << GX_GC_X) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_Y) ? (UINT64_C(1) << GX_GC_Y) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_UP) ? (UINT64_C(1) << GX_GC_UP) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_DOWN) ? (UINT64_C(1) << GX_GC_DOWN) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_LEFT) ? (UINT64_C(1) << GX_GC_LEFT) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_RIGHT) ? (UINT64_C(1) << GX_GC_RIGHT) : 0;
|
||||
*state_cur |= (down & PAD_BUTTON_START) ? (UINT64_C(1) << GX_GC_START) : 0;
|
||||
*state_cur |= (down & PAD_TRIGGER_Z) ? (UINT64_C(1) << GX_GC_Z_TRIGGER) : 0;
|
||||
*state_cur |= ((down & PAD_TRIGGER_L) || PAD_TriggerL(port) > 127) ? (UINT64_C(1) << GX_GC_L_TRIGGER) : 0;
|
||||
*state_cur |= ((down & PAD_TRIGGER_R) || PAD_TriggerR(port) > 127) ? (UINT64_C(1) << GX_GC_R_TRIGGER) : 0;
|
||||
|
||||
ls_x = (int16_t)PAD_StickX(port) * 256;
|
||||
ls_y = (int16_t)PAD_StickY(port) * -256;
|
||||
rs_x = (int16_t)PAD_SubStickX(port) * 256;
|
||||
rs_y = (int16_t)PAD_SubStickY(port) * -256;
|
||||
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_X] = ls_x;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_LEFT][RETRO_DEVICE_ID_ANALOG_Y] = ls_y;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_X] = rs_x;
|
||||
analog_state[port][RETRO_DEVICE_INDEX_ANALOG_RIGHT][RETRO_DEVICE_ID_ANALOG_Y] = rs_y;
|
||||
|
||||
menu_combo = (UINT64_C(1) << GX_GC_START) | (UINT64_C(1) << GX_GC_Z_TRIGGER) |
|
||||
(UINT64_C(1) << GX_GC_L_TRIGGER) | (UINT64_C(1) << GX_GC_R_TRIGGER);
|
||||
|
||||
if ((*state_cur & menu_combo) == menu_combo)
|
||||
*state_cur |= (UINT64_C(1) << GX_WIIMOTE_HOME);
|
||||
|
||||
ptype = WPAD_EXP_GAMECUBE;
|
||||
}
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
else
|
||||
{
|
||||
USB_DeviceChangeNotifyAsync(USB_CLASS_HID, change_cb, (void*)&lol);
|
||||
|
||||
if (ss_is_connected(&dev[port]))
|
||||
{
|
||||
ptype = WPAD_EXP_SICKSAXIS;
|
||||
*state_cur |= (dev[port].pad.buttons.PS) ? (UINT64_C(1) << RARCH_MENU_TOGGLE) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.cross) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_B) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.square) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_Y) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.select) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_SELECT) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.start) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_START) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.up) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_UP) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.down) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_DOWN) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.left) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_LEFT) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.right) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_RIGHT) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.circle) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_A) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.triangle) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_X) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.L1) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.R1) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.L2) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L2) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.R2) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R2) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.L3) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_L3) : 0;
|
||||
*state_cur |= (dev[port].pad.buttons.R3) ? (UINT64_C(1) << RETRO_DEVICE_ID_JOYPAD_R3) : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ss_open(&dev[port]) > 0)
|
||||
{
|
||||
ptype = WPAD_EXP_SICKSAXIS;
|
||||
ss_start_reading(&dev[port]);
|
||||
ss_set_removal_cb(&dev[port], removal_cb, (void*)1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ptype != pad_type[port])
|
||||
handle_hotplug(port, ptype);
|
||||
@ -539,23 +524,27 @@ static void gx_joypad_poll(void)
|
||||
analog_state[port][i][j] = -0x7fff;
|
||||
}
|
||||
|
||||
uint64_t *state_p1 = &pad_state[0];
|
||||
uint64_t *state_p1 = &pad_state[0];
|
||||
|
||||
|
||||
BIT64_CLEAR(lifecycle_state, RARCH_MENU_TOGGLE);
|
||||
|
||||
if (g_menu)
|
||||
{
|
||||
*state_p1 |= (UINT64_C(1) << GX_WIIMOTE_HOME);
|
||||
*state_p1 |= (UINT64_C(1) << GX_GC_HOME);
|
||||
g_menu = false;
|
||||
}
|
||||
|
||||
if (*state_p1 & ((UINT64_C(1) << GX_WIIMOTE_HOME)
|
||||
if (*state_p1 & ((UINT64_C(1) << GX_GC_HOME)
|
||||
#ifdef HW_RVL
|
||||
| (UINT64_C(1) << GX_WIIMOTE_HOME)
|
||||
| (UINT64_C(1) << GX_CLASSIC_HOME)
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
| (UINT64_C(1) << GX_SIXAXIS_PS)
|
||||
#endif
|
||||
#endif
|
||||
))
|
||||
BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
|
||||
|
||||
BIT64_SET(lifecycle_state, RARCH_MENU_TOGGLE);
|
||||
}
|
||||
|
||||
static bool gx_joypad_init(void *data)
|
||||
@ -574,13 +563,9 @@ static bool gx_joypad_init(void *data)
|
||||
PAD_Init();
|
||||
#ifdef HW_RVL
|
||||
WPADInit();
|
||||
#endif
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
int i;
|
||||
USB_Initialize();
|
||||
ss_init();
|
||||
for (i = 0; i < MAX_PADS; i++)
|
||||
ss_initialize(&dev[i]);
|
||||
ss_init(sixaxis, USB_SLOTS);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
gx_joypad_poll();
|
||||
@ -595,20 +580,18 @@ static bool gx_joypad_query_pad(unsigned pad)
|
||||
|
||||
static void gx_joypad_destroy(void)
|
||||
{
|
||||
#ifdef HW_RVL
|
||||
int i;
|
||||
for (i = 0; i < MAX_PADS; i++)
|
||||
{
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
ss_close(&dev[i]);
|
||||
USB_Deinitialize();
|
||||
#endif
|
||||
|
||||
#ifdef HW_RVL
|
||||
// Commenting this out fixes the Wii remote not reconnecting after core load, exit, etc.
|
||||
// WPAD_Flush(i);
|
||||
// WPADDisconnect(i);
|
||||
#endif
|
||||
}
|
||||
#ifdef HAVE_LIBSICKSAXIS
|
||||
ss_shutdown();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
input_device_driver_t gx_joypad = {
|
||||
|
@ -1,366 +1,236 @@
|
||||
#include "gx_sicksaxis.h"
|
||||
#include "sicksaxis.h"
|
||||
#include <gccore.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <retro_inline.h>
|
||||
|
||||
static uint8_t ATTRIBUTE_ALIGN(32) _ss_attributes_payload[] =
|
||||
static uint8_t ATTRIBUTE_ALIGN(32) _ss_attributes[] =
|
||||
{
|
||||
0x52,
|
||||
0x00, 0x00, 0x00, 0x00, //Rumble
|
||||
0xff, 0x80, //Gyro
|
||||
0x00, 0x00,
|
||||
0x00, //* LED_1 = 0x02, LED_2 = 0x04, ... */
|
||||
0xff, 0x27, 0x10, 0x00, 0x32, /* LED_4 */
|
||||
0xff, 0x27, 0x10, 0x00, 0x32, /* LED_3 */
|
||||
0xff, 0x27, 0x10, 0x00, 0x32, /* LED_2 */
|
||||
0xff, 0x27, 0x10, 0x00, 0x32, /* LED_1 */
|
||||
0x00,
|
||||
0x00, 0x00, 0x00, 0x00, //Rumble
|
||||
0x00, 0x00, //Gyro
|
||||
0x00, 0x00,
|
||||
0x00, //* LED_1 = 0x02, LED_2 = 0x04, ... */
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32, /* LED_4 */
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32, /* LED_3 */
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32, /* LED_2 */
|
||||
0xFF, 0x27, 0x10, 0x00, 0x32, /* LED_1 */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const uint8_t _ss_led_pattern[] = {0x0, 0x02, 0x04, 0x08, 0x10, 0x12, 0x14, 0x18};
|
||||
|
||||
static int _ss_heap_id = -1;
|
||||
static int _ss_inited = 0;
|
||||
static int _ss_dev_number = 1;
|
||||
static int _ss_dev_id_list[SS_MAX_DEV] = {0};
|
||||
static int _dev_detected = 0;
|
||||
static int _slots = 0;
|
||||
static int _ss_rem_cb = 0; /* helps to know if it has just removed a device from the usb iface. */
|
||||
struct ss_device *_ss_dev_list = NULL; /* just hold a pointer to the dev list. */
|
||||
|
||||
static int _ss_initialize(struct ss_device *dev);
|
||||
int _ss_open(struct ss_device *dev);
|
||||
int _ss_close(struct ss_device *dev);
|
||||
static int _ss_dev_id_list_exists(int id);
|
||||
static int _ss_dev_id_list_add(int id);
|
||||
static int _ss_dev_id_list_remove(int id);
|
||||
static int _ss_removal_cb(int result, void *usrdata);
|
||||
static int _ss_read_cb(int result, void *usrdata);
|
||||
static int _ss_operational_cb(int result, void *usrdata);
|
||||
static int _ss_read(struct ss_device *dev);
|
||||
static int _ss_set_operational(struct ss_device *dev);
|
||||
static int _ss_build_attributes_payload(struct ss_device *dev);
|
||||
static int _ss_change_cb(int result, void *usrdata);
|
||||
static int _ss_send_attributes_payload(struct ss_device *dev);
|
||||
static int _ss_set_operational(struct ss_device *dev);
|
||||
|
||||
int ss_init(void)
|
||||
{
|
||||
if (!_ss_inited)
|
||||
{
|
||||
_ss_heap_id = iosCreateHeap(SS_HEAP_SIZE);
|
||||
_ss_inited = 1;
|
||||
}
|
||||
return 1;
|
||||
int ss_init(struct ss_device *dev_list, int slots) {
|
||||
if (!_ss_inited) {
|
||||
|
||||
USB_Initialize();
|
||||
_ss_dev_list = dev_list;
|
||||
_slots = slots;
|
||||
|
||||
int i;
|
||||
for (i = 0;i < _slots; i++) {
|
||||
_ss_initialize(&_ss_dev_list[i]);
|
||||
}
|
||||
|
||||
USB_DeviceChangeNotifyAsync(USB_CLASS_HID, _ss_change_cb, NULL);
|
||||
_dev_detected = 1; /* try open any existing sixasis device */
|
||||
_ss_inited = 1;
|
||||
}
|
||||
return _ss_inited;
|
||||
}
|
||||
|
||||
|
||||
int ss_initialize(struct ss_device *dev)
|
||||
{
|
||||
dev->device_id = -1;
|
||||
dev->fd = -1;
|
||||
dev->connected = 0;
|
||||
dev->enabled = 0;
|
||||
dev->reading = 0;
|
||||
dev->removal_callback = NULL;
|
||||
dev->removal_usrdata = NULL;
|
||||
dev->read_callback = NULL;
|
||||
dev->read_usrdata = NULL;
|
||||
memset(&dev->pad, 0x0, sizeof(struct SS_GAMEPAD));
|
||||
memset(&dev->attributes, 0x0, sizeof(struct SS_ATTRIBUTES));
|
||||
return 1;
|
||||
int ss_shutdown() {
|
||||
int i;
|
||||
for (i = 0;i < _slots; i++) {
|
||||
_ss_close(&_ss_dev_list[i]);
|
||||
}
|
||||
|
||||
USB_Deinitialize();
|
||||
_ss_inited = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_open(struct ss_device *dev)
|
||||
{
|
||||
usb_device_entry dev_entry[8];
|
||||
unsigned char dev_count;
|
||||
if (!_ss_inited)
|
||||
return -1;
|
||||
if (dev->connected)
|
||||
ss_close(dev);
|
||||
|
||||
if (USB_GetDeviceList(dev_entry, 8, USB_CLASS_HID, &dev_count) < 0)
|
||||
return -2;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < dev_count; ++i)
|
||||
{
|
||||
if ((dev_entry[i].vid == SS_VENDOR_ID) &&
|
||||
(dev_entry[i].pid == SS_PRODUCT_ID))
|
||||
{
|
||||
if (!_ss_dev_id_list_exists(dev_entry[i].device_id))
|
||||
{
|
||||
if (USB_OpenDevice(dev_entry[i].device_id,
|
||||
SS_VENDOR_ID, SS_PRODUCT_ID, &dev->fd) < 0)
|
||||
return -3;
|
||||
|
||||
dev->device_id = dev_entry[i].device_id;
|
||||
dev->connected = 1;
|
||||
dev->enabled = 0;
|
||||
dev->reading = 0;
|
||||
|
||||
_ss_set_operational(dev);
|
||||
ss_set_led(dev, _ss_dev_number);
|
||||
|
||||
_ss_dev_id_list_add(dev_entry[i].device_id);
|
||||
_ss_dev_number++;
|
||||
|
||||
USB_DeviceRemovalNotifyAsync(dev->fd, &_ss_removal_cb, dev);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -4;
|
||||
}
|
||||
|
||||
int ss_close(struct ss_device *dev)
|
||||
{
|
||||
if (dev && dev->fd > 0)
|
||||
USB_CloseDevice(&dev->fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_is_connected(struct ss_device *dev)
|
||||
{
|
||||
return dev->connected;
|
||||
}
|
||||
|
||||
int ss_set_read_cb(struct ss_device *dev,ss_usb_callback cb,
|
||||
void *userdata)
|
||||
{
|
||||
dev->read_callback = cb;
|
||||
dev->read_usrdata = userdata;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_set_removal_cb(struct ss_device *dev, ss_usb_callback cb,
|
||||
void *usrdata)
|
||||
{
|
||||
dev->removal_callback = cb;
|
||||
dev->removal_usrdata = userdata;
|
||||
static int _ss_initialize(struct ss_device *dev) {
|
||||
dev->device_id = -1;
|
||||
dev->connected = 0;
|
||||
dev->enabled = 0;
|
||||
memset(&dev->pad, 0x0, sizeof(struct SS_GAMEPAD));
|
||||
memset(&dev->attributes, 0x0, sizeof(struct SS_ATTRIBUTES));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_start_reading(struct ss_device *dev)
|
||||
{
|
||||
if (dev)
|
||||
{
|
||||
dev->reading = 1;
|
||||
if (dev->enabled)
|
||||
_ss_read(dev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
static int _ss_change_cb(int result, void *usrdata) {
|
||||
if (!_ss_rem_cb) {
|
||||
/* As it's not coming from the removal callback
|
||||
then we detected a new device being inserted */
|
||||
_dev_detected = 1;
|
||||
}
|
||||
else {
|
||||
_ss_rem_cb = 0;
|
||||
}
|
||||
|
||||
/* Re-apply the callback notification for future connections changes*/
|
||||
USB_DeviceChangeNotifyAsync(USB_CLASS_HID, _ss_change_cb, NULL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ss_stop_reading(struct ss_device *dev)
|
||||
{
|
||||
if (dev)
|
||||
{
|
||||
dev->reading = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
int _ss_open(struct ss_device *dev) {
|
||||
/* always try to close the device first */
|
||||
_ss_close(dev);
|
||||
|
||||
usb_device_entry dev_entry[SS_MAX_DEV];
|
||||
unsigned char dev_count = 0;
|
||||
if (USB_GetDeviceList(dev_entry, SS_MAX_DEV, USB_CLASS_HID, &dev_count) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < dev_count; ++i) {
|
||||
if ((dev_entry[i].vid == SS_VENDOR_ID) && (dev_entry[i].pid == SS_PRODUCT_ID)) {
|
||||
if (!_ss_dev_id_list_exists(dev_entry[i].device_id)) {
|
||||
int fd;
|
||||
if (USB_OpenDevice(dev_entry[i].device_id, SS_VENDOR_ID, SS_PRODUCT_ID, &fd) < 0) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
dev->device_id = dev_entry[i].device_id;
|
||||
dev->connected = 1;
|
||||
dev->fd = fd;
|
||||
|
||||
_ss_set_operational(dev);
|
||||
USB_DeviceRemovalNotifyAsync(dev->fd, &_ss_removal_cb, dev);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -4;
|
||||
}
|
||||
|
||||
static int _ss_build_attributes_payload(struct ss_device *dev)
|
||||
{
|
||||
_ss_attributes_payload[1] = dev->attributes.rumble.duration_right;
|
||||
_ss_attributes_payload[2] = dev->attributes.rumble.power_right;
|
||||
_ss_attributes_payload[3] = dev->attributes.rumble.duration_left;
|
||||
_ss_attributes_payload[4] = dev->attributes.rumble.power_left;
|
||||
_ss_attributes_payload[9] = _ss_led_pattern[dev->attributes.led];
|
||||
return 1;
|
||||
int _ss_close(struct ss_device *dev) {
|
||||
if (dev && dev->fd > 0) {
|
||||
USB_CloseDevice(&dev->fd);
|
||||
dev->fd = -1; /* Clear its descriptor */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _ss_send_attributes_payload(struct ss_device *dev)
|
||||
{
|
||||
if (!dev->connected)
|
||||
return 0;
|
||||
int ss_is_ready(struct ss_device *dev) {
|
||||
|
||||
_ss_build_attributes_payload(dev);
|
||||
/* if a device is detected, try to connect it. */
|
||||
if (_dev_detected) {
|
||||
/* As we are processing the detected device, we turn off the flag. */
|
||||
_dev_detected = 0;
|
||||
int i;
|
||||
for(i = 0; i < _slots; i++) {
|
||||
if (_ss_dev_list[i].device_id < 0) { /* found an empty slot? */
|
||||
if (_ss_open(&_ss_dev_list[i]) > 0) {
|
||||
ss_set_led(&_ss_dev_list[i], i+1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->connected && dev->enabled)
|
||||
return 1;
|
||||
|
||||
return USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_SET,
|
||||
USB_REQ_SETREPORT,
|
||||
(USB_REPTYPE_OUTPUT<<8) | 0x01,
|
||||
0x0,
|
||||
sizeof(_ss_attributes_payload),
|
||||
_ss_attributes_payload,
|
||||
NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INLINE int ss_set_led(struct ss_device *dev, int led)
|
||||
{
|
||||
dev->attributes.led = led;
|
||||
return _ss_send_attributes_payload(dev);
|
||||
static int _ss_send_attributes_payload(struct ss_device *dev) {
|
||||
_ss_attributes[1] = dev->attributes.rumble.duration_right;
|
||||
_ss_attributes[2] = dev->attributes.rumble.power_right;
|
||||
_ss_attributes[3] = dev->attributes.rumble.duration_left;
|
||||
_ss_attributes[4] = dev->attributes.rumble.power_left;
|
||||
_ss_attributes[9] = _ss_led_pattern[dev->attributes.led];
|
||||
|
||||
return USB_WriteCtrlMsg(
|
||||
dev->fd,
|
||||
USB_REQTYPE_INTERFACE_SET,
|
||||
USB_REQ_SETREPORT,
|
||||
(USB_REPTYPE_OUTPUT<<8) | 0x01,
|
||||
0x0,
|
||||
sizeof(_ss_attributes),
|
||||
_ss_attributes
|
||||
);
|
||||
}
|
||||
|
||||
static INLINE int ss_set_rumble(struct ss_device *dev, uint8_t duration_right,
|
||||
uint8_t power_right, uint8_t duration_left, uint8_t power_left)
|
||||
{
|
||||
dev->attributes.rumble.duration_right = duration_right;
|
||||
dev->attributes.rumble.power_right = power_right;
|
||||
dev->attributes.rumble.duration_left = duration_left;
|
||||
dev->attributes.rumble.power_left = power_left;
|
||||
return _ss_send_attributes_payload(dev);
|
||||
int ss_set_led(struct ss_device *dev, int led) {
|
||||
/* Need to clear the data for rumble */
|
||||
dev->attributes.rumble.duration_right = 0;
|
||||
dev->attributes.rumble.power_right = 0;
|
||||
dev->attributes.rumble.duration_left = 0;
|
||||
dev->attributes.rumble.power_left = 0;
|
||||
|
||||
dev->attributes.led = led;
|
||||
|
||||
return _ss_send_attributes_payload(dev);
|
||||
}
|
||||
|
||||
int ss_get_bd_address(struct ss_device *dev, uint8_t *mac)
|
||||
{
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[17];
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf2,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
|
||||
mac[0] = msg[4];
|
||||
mac[1] = msg[5];
|
||||
mac[2] = msg[6];
|
||||
mac[3] = msg[7];
|
||||
mac[4] = msg[8];
|
||||
mac[5] = msg[9];
|
||||
return ret;
|
||||
int ss_set_rumble(struct ss_device *dev, uint8_t duration_right, uint8_t power_right, uint8_t duration_left, uint8_t power_left) {
|
||||
dev->attributes.rumble.duration_right = duration_right;
|
||||
dev->attributes.rumble.power_right = power_right;
|
||||
dev->attributes.rumble.duration_left = duration_left;
|
||||
dev->attributes.rumble.power_left = power_left;
|
||||
return _ss_send_attributes_payload(dev);
|
||||
}
|
||||
|
||||
int ss_get_mac(struct ss_device *dev, uint8_t *mac)
|
||||
{
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[8];
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf5,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
|
||||
mac[0] = msg[2];
|
||||
mac[1] = msg[3];
|
||||
mac[2] = msg[4];
|
||||
mac[3] = msg[5];
|
||||
mac[4] = msg[6];
|
||||
mac[5] = msg[7];
|
||||
return ret;
|
||||
inline int ss_read_pad(struct ss_device *dev) {
|
||||
return USB_ReadIntrMsg(dev->fd, 0x81, SS_PAYLOAD_SIZE, (u8 *)&dev->pad);
|
||||
}
|
||||
|
||||
int ss_set_mac(struct ss_device *dev, const uint8_t *mac)
|
||||
{
|
||||
uint8_t ATTRIBUTE_ALIGN(32) msg[] = {0x01, 0x00, mac[0], mac[1],
|
||||
mac[2], mac[3], mac[4], mac[5]};
|
||||
int ret = USB_WriteCtrlMsgAsync(dev->fd,
|
||||
USB_REQTYPE_INTERFACE_SET,
|
||||
USB_REQ_SETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf5,
|
||||
0,
|
||||
sizeof(msg),
|
||||
msg,
|
||||
NULL, NULL);
|
||||
return ret;
|
||||
static int _ss_removal_cb(int result, void *usrdata) {
|
||||
struct ss_device *dev = (struct ss_device*)usrdata;
|
||||
if (dev->device_id > 0) {
|
||||
_ss_initialize(dev);
|
||||
_ss_rem_cb = 1; /* inform we already pass thru the removal callback */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int _ss_read(struct ss_device *dev)
|
||||
{
|
||||
return USB_WriteCtrlMsgAsync(
|
||||
dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_INPUT<<8) | 0x01,
|
||||
0x0,
|
||||
SS_PAYLOAD_SIZE,
|
||||
&dev->pad,
|
||||
&_ss_read_cb,
|
||||
dev);
|
||||
static int _ss_set_operational(struct ss_device *dev) {
|
||||
int r;
|
||||
uint8_t ATTRIBUTE_ALIGN(32) buf[4] = {0x42, 0x0c, 0x00, 0x00}; /* Special command to enable Sixaxis */
|
||||
/* Sometimes it fails so we should keep trying until success */
|
||||
do {
|
||||
r = USB_WriteCtrlMsg(
|
||||
dev->fd,
|
||||
USB_REQTYPE_INTERFACE_SET,
|
||||
USB_REQ_SETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf4,
|
||||
0x0,
|
||||
sizeof(buf),
|
||||
buf
|
||||
);
|
||||
} while (r < 0);
|
||||
|
||||
dev->enabled = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _ss_removal_cb(int result, void *usrdata)
|
||||
{
|
||||
struct ss_device *dev = (struct ss_device*)usrdata;
|
||||
if (dev->device_id > 0)
|
||||
{
|
||||
_ss_dev_id_list_remove(dev->device_id);
|
||||
_ss_dev_number--;
|
||||
if (dev->removal_callback)
|
||||
dev->removal_callback(dev->removal_usrdata);
|
||||
ss_initialize(dev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ss_set_operational(struct ss_device *dev)
|
||||
{
|
||||
uint8_t ATTRIBUTE_ALIGN(32) buf[17];
|
||||
return USB_WriteCtrlMsgAsync(
|
||||
dev->fd,
|
||||
USB_REQTYPE_INTERFACE_GET,
|
||||
USB_REQ_GETREPORT,
|
||||
(USB_REPTYPE_FEATURE<<8) | 0xf2,
|
||||
0x0,
|
||||
17,
|
||||
buf,
|
||||
&_ss_operational_cb,
|
||||
dev);
|
||||
}
|
||||
|
||||
static int _ss_read_cb(int result, void *userdata)
|
||||
{
|
||||
if (userdata)
|
||||
{
|
||||
struct ss_device *dev = (struct ss_device*)userdata;
|
||||
if (dev->reading)
|
||||
{
|
||||
_ss_read(dev);
|
||||
if (dev->read_callback)
|
||||
dev->read_callback(dev->read_usrdata);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _ss_operational_cb(int result, void *userdata)
|
||||
{
|
||||
struct ss_device *dev = (struct ss_device*)userdata;
|
||||
dev->enabled = 1;
|
||||
if (dev->reading)
|
||||
_ss_read(dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int _ss_dev_id_list_exists(int id)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i)
|
||||
{
|
||||
if (_ss_dev_id_list[i] == id)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ss_dev_id_list_add(int id)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i)
|
||||
{
|
||||
if (_ss_dev_id_list[i] == 0)
|
||||
{
|
||||
_ss_dev_id_list[i] = id;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _ss_dev_id_list_remove(int id)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < SS_MAX_DEV; ++i)
|
||||
{
|
||||
if (_ss_dev_id_list[i] == id)
|
||||
{
|
||||
_ss_dev_id_list[i] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
static int _ss_dev_id_list_exists(int id) {
|
||||
int i;
|
||||
for (i = 0; i < _slots; ++i) {
|
||||
if (_ss_dev_list[i].device_id == id) return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -3,14 +3,13 @@
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
#define SS_HEAP_SIZE 4096
|
||||
|
||||
#define SS_MAX_DEV 8
|
||||
#define SS_VENDOR_ID 0x054C
|
||||
#define SS_PRODUCT_ID 0x0268
|
||||
#define SS_PAYLOAD_SIZE 49
|
||||
|
||||
struct SS_BUTTONS
|
||||
{
|
||||
struct SS_BUTTONS {
|
||||
uint8_t left : 1;
|
||||
uint8_t down : 1;
|
||||
uint8_t right : 1;
|
||||
@ -33,46 +32,40 @@ struct SS_BUTTONS
|
||||
uint8_t PS : 1;
|
||||
};
|
||||
|
||||
struct SS_ANALOG
|
||||
{
|
||||
struct SS_ANALOG {
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
};
|
||||
|
||||
struct SS_DPAD_SENSITIVE
|
||||
{
|
||||
struct SS_DPAD_SENSITIVE {
|
||||
uint8_t up;
|
||||
uint8_t right;
|
||||
uint8_t down;
|
||||
uint8_t left;
|
||||
};
|
||||
|
||||
struct SS_SHOULDER_SENSITIVE
|
||||
{
|
||||
struct SS_SHOULDER_SENSITIVE {
|
||||
uint8_t L2;
|
||||
uint8_t R2;
|
||||
uint8_t L1;
|
||||
uint8_t R1;
|
||||
};
|
||||
|
||||
struct SS_BUTTON_SENSITIVE
|
||||
{
|
||||
struct SS_BUTTON_SENSITIVE {
|
||||
uint8_t triangle;
|
||||
uint8_t circle;
|
||||
uint8_t cross;
|
||||
uint8_t square;
|
||||
};
|
||||
|
||||
struct SS_MOTION
|
||||
{
|
||||
struct SS_MOTION {
|
||||
uint16_t acc_x;
|
||||
uint16_t acc_y;
|
||||
uint16_t acc_z;
|
||||
uint16_t z_gyro;
|
||||
};
|
||||
|
||||
struct SS_GAMEPAD
|
||||
{
|
||||
struct SS_GAMEPAD {
|
||||
uint8_t hid_data;
|
||||
uint8_t unk0;
|
||||
struct SS_BUTTONS buttons;
|
||||
@ -94,63 +87,34 @@ struct SS_GAMEPAD
|
||||
struct SS_MOTION motion;
|
||||
}__attribute__((packed));
|
||||
|
||||
struct SS_ATTRIBUTE_RUMBLE
|
||||
{
|
||||
struct SS_ATTRIBUTE_RUMBLE {
|
||||
uint8_t duration_right;
|
||||
uint8_t power_right;
|
||||
uint8_t duration_left;
|
||||
uint8_t power_left;
|
||||
};
|
||||
|
||||
struct SS_ATTRIBUTES
|
||||
{
|
||||
struct SS_ATTRIBUTES {
|
||||
struct SS_ATTRIBUTE_RUMBLE rumble;
|
||||
int led;
|
||||
};
|
||||
|
||||
typedef void (*ss_usb_callback)(void *usrdata);
|
||||
|
||||
struct ss_device {
|
||||
struct SS_GAMEPAD pad;
|
||||
struct SS_ATTRIBUTES attributes;
|
||||
int device_id, fd;
|
||||
int connected, enabled, reading;
|
||||
ss_usb_callback read_callback;
|
||||
ss_usb_callback removal_callback;
|
||||
void *read_usrdata, *removal_usrdata;
|
||||
int device_id;
|
||||
int fd;
|
||||
int connected;
|
||||
int enabled;
|
||||
}__attribute__((aligned(32)));
|
||||
|
||||
|
||||
int ss_init(void);
|
||||
|
||||
int ss_initialize(struct ss_device *dev);
|
||||
|
||||
int ss_open(struct ss_device *dev);
|
||||
|
||||
int ss_close(struct ss_device *dev);
|
||||
|
||||
int ss_is_connected(struct ss_device *dev);
|
||||
|
||||
int ss_set_read_cb(struct ss_device *dev,
|
||||
ss_usb_callback cb, void *usrdata);
|
||||
|
||||
int ss_set_removal_cb(struct ss_device *dev,
|
||||
ss_usb_callback cb, void *usrdata);
|
||||
|
||||
int ss_start_reading(struct ss_device *dev);
|
||||
|
||||
int ss_stop_reading(struct ss_device *dev);
|
||||
int ss_init(struct ss_device *dev_list, int slots);
|
||||
int ss_shutdown();
|
||||
int ss_is_ready(struct ss_device *dev);
|
||||
|
||||
int ss_read_pad(struct ss_device *dev);
|
||||
int ss_set_led(struct ss_device *dev, int led);
|
||||
|
||||
int ss_set_rumble(struct ss_device *dev, uint8_t duration_right,
|
||||
uint8_t power_right, uint8_t duration_left, uint8_t power_left);
|
||||
|
||||
int ss_get_bd_address(struct ss_device *dev, uint8_t *mac);
|
||||
|
||||
int ss_get_paired_mac(struct ss_device *dev, uint8_t *mac);
|
||||
|
||||
int ss_set_paired_mac(struct ss_device *dev, const uint8_t *mac);
|
||||
|
||||
int ss_set_rumble(struct ss_device *dev, uint8_t duration_right, uint8_t power_right, uint8_t duration_left, uint8_t power_left);
|
||||
|
||||
#endif
|
||||
|
@ -83,7 +83,7 @@ static void print_help(void)
|
||||
puts("-h/--help: This help.");
|
||||
}
|
||||
|
||||
#define MAX_BUTTONS 32
|
||||
#define MAX_BUTTONS 64
|
||||
#define MAX_AXES 32
|
||||
#define MAX_HATS 32
|
||||
struct poll_data
|
||||
|
Loading…
Reference in New Issue
Block a user