Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/joystick/SDL_gamepad_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -865,16 +865,16 @@ static const char *s_GamepadMappings[] = {
"default,*,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
#endif
#ifdef SDL_JOYSTICK_PS2
"0000000050533220436f6e74726f6c00,PS2 Controller,crc:ed87,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
"0000000050533220436f6e74726f6c00,PS2 Controller,crc:ed87,a:b10,b:b9,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b1,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b2,righttrigger:b5,rightx:a2,righty:a3,start:b3,x:b11,y:b8,",
#endif
#ifdef SDL_JOYSTICK_PSP
"00000000505350206275696c74696e00,PSP builtin joypad,crc:bb86,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
"00000000505350206275696c74696e00,PSP builtin joypad,crc:bb86,a:b2,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,rightx:a2,righty:a3,start:b7,x:b3,y:b0,",
#endif
#ifdef SDL_JOYSTICK_VITA
"0000000050535669746120436f6e7400,PSVita Controller,crc:d598,a:b2,b:b1,back:b10,dpdown:b6,dpleft:b7,dpright:b9,dpup:b8,leftshoulder:b4,leftstick:b14,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b15,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,",
"0000000050535669746120436f6e7400,PSVita Controller,crc:d598,a:b2,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b3,y:b0,",
#endif
#ifdef SDL_JOYSTICK_N3DS
"000000004e696e74656e646f20334400,Nintendo 3DS,crc:3210,a:b1,b:b0,back:b2,dpdown:b7,dpleft:b5,dpright:b4,dpup:b6,leftshoulder:b9,lefttrigger:b14,leftx:a0,lefty:a1,rightshoulder:b8,righttrigger:b15,rightx:a2,righty:a3,start:b3,x:b11,y:b10,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
"000000004e696e74656e646f20334400,Nintendo 3DS,crc:3210,a:b1,b:b0,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,lefttrigger:b10,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b11,rightx:a2,righty:a3,start:b3,x:b7,y:b6,hint:!SDL_GAMECONTROLLER_USE_BUTTON_LABELS:=1,",
#endif
NULL
};
117 changes: 79 additions & 38 deletions src/joystick/n3ds/SDL_sysjoystick.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@

#include "../SDL_sysjoystick.h"

#define NB_BUTTONS 23
#define NB_BUTTONS 23 // physical buttons on the device (although we treat four of these, the dpad, as a hat switch).
#define N3DS_HAT_MASK 0xF0 // 0xF0==d-pad bits, which we handle elsewhere, so mask them out here.

/*
N3DS sticks values are roughly within +/-160
Expand All @@ -54,8 +55,9 @@ static inline int Correct_Axis_Y(int Y) {
return Correct_Axis_X(-Y);
}

static void UpdateN3DSPressedButtons(Uint64 timestamp, SDL_Joystick *joystick);
static void UpdateN3DSReleasedButtons(Uint64 timestamp, SDL_Joystick *joystick);
static void UpdateN3DSPressedButtons(Uint64 timestamp, SDL_Joystick *joystick, u32 previous_state, u32 current_state);
static void UpdateN3DSReleasedButtons(Uint64 timestamp, SDL_Joystick *joystick, u32 previous_state, u32 current_state);
static void UpdateN3DSHat(Uint64 timestamp, SDL_Joystick *joystick, u32 previous_down_state, u32 current_down_state, u32 previous_up_state, u32 current_up_state);
static void UpdateN3DSCircle(Uint64 timestamp, SDL_Joystick *joystick);
static void UpdateN3DSCStick(Uint64 timestamp, SDL_Joystick *joystick);

Expand Down Expand Up @@ -89,9 +91,9 @@ static SDL_JoystickID N3DS_JoystickGetDeviceInstanceID(int device_index)

static bool N3DS_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
joystick->nbuttons = NB_BUTTONS;
joystick->nbuttons = NB_BUTTONS - 4; // -4 for the dpad (which we treat as a hat).
joystick->naxes = 4;
joystick->nhats = 0;
joystick->nhats = 1; // treat the dpad as a hat.

return true;
}
Expand All @@ -103,46 +105,85 @@ static bool N3DS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, bool enabled)

static void N3DS_JoystickUpdate(SDL_Joystick *joystick)
{
Uint64 timestamp = SDL_GetTicksNS();

UpdateN3DSPressedButtons(timestamp, joystick);
UpdateN3DSReleasedButtons(timestamp, joystick);
static u32 previous_down_state = 0;
static u32 previous_up_state = 0;
const Uint64 timestamp = SDL_GetTicksNS();
const u32 current_down_state = hidKeysDown();
const u32 current_up_state = hidKeysUp();

UpdateN3DSPressedButtons(timestamp, joystick, previous_down_state, current_down_state);
UpdateN3DSReleasedButtons(timestamp, joystick, previous_up_state, current_up_state);
UpdateN3DSHat(timestamp, joystick, previous_down_state, current_down_state, previous_up_state, current_up_state);
UpdateN3DSCircle(timestamp, joystick);
UpdateN3DSCStick(timestamp, joystick);

previous_down_state = current_down_state;
previous_up_state = current_up_state;
}

static void UpdateN3DSPressedButtons(Uint64 timestamp, SDL_Joystick *joystick)
static void UpdateN3DSPressedButtons(Uint64 timestamp, SDL_Joystick *joystick, u32 previous_state, u32 current_state)
{
static u32 previous_state = 0;
u32 updated_down;
u32 current_state = hidKeysDown();
updated_down = previous_state ^ current_state;
const u32 updated_down = (previous_state ^ current_state) & ~N3DS_HAT_MASK;
if (updated_down) {
for (Uint8 i = 0; i < joystick->nbuttons; i++) {
if (current_state & BIT(i) & updated_down) {
SDL_SendJoystickButton(timestamp, joystick, i, true);
Uint8 buttonidx = 0;
Uint8 i = 0;
while (i < joystick->nbuttons) {
if ((buttonidx < 4) || (buttonidx > 7)) { // skip dpad (we treat it as a hat).
if (current_state & BIT(buttonidx) & updated_down) {
SDL_SendJoystickButton(timestamp, joystick, i, true);
}
i++;
}
buttonidx++;
}
}
previous_state = current_state;
}

static void UpdateN3DSReleasedButtons(Uint64 timestamp, SDL_Joystick *joystick)
static void UpdateN3DSReleasedButtons(Uint64 timestamp, SDL_Joystick *joystick, u32 previous_state, u32 current_state)
{
static u32 previous_state = 0;
u32 updated_up;
u32 current_state = hidKeysUp();
updated_up = previous_state ^ current_state;
const u32 updated_up = (previous_state ^ current_state) & ~N3DS_HAT_MASK;
if (updated_up) {
for (Uint8 i = 0; i < joystick->nbuttons; i++) {
if (current_state & BIT(i) & updated_up) {
SDL_SendJoystickButton(timestamp, joystick, i, false);
}
Uint8 buttonidx = 0;
Uint8 i = 0;
while (i < joystick->nbuttons) {
if ((buttonidx < 4) || (buttonidx > 7)) { // skip dpad (we treat it as a hat).
if (current_state & BIT(buttonidx) & updated_up) {
SDL_SendJoystickButton(timestamp, joystick, i, false);
}
i++;
}
buttonidx++;
}
}
previous_state = current_state;
}

static void UpdateN3DSHat(Uint64 timestamp, SDL_Joystick *joystick, u32 previous_down_state, u32 current_down_state, u32 previous_up_state, u32 current_up_state)
{
// The 3DS dpad looks like 4 buttons at this level, but we treat it as a hat switch, so apps that are talking to SDL_Joystick can hope to do basic directional things without a configuration step.
// (but they should _really_ be using the gamepad API.)
const u32 updated_hat = (((previous_up_state ^ current_up_state) | (previous_down_state ^ current_down_state)) & N3DS_HAT_MASK); // did bits 4 through 7 change?
if (updated_hat) {
Uint8 hat = SDL_HAT_CENTERED;

#define HATSTATE(n3dsbit, sdlenum) if (current_down_state & BIT(n3dsbit)) { hat |= SDL_HAT_##sdlenum; }
HATSTATE(4, RIGHT);
HATSTATE(5, LEFT);
HATSTATE(6, UP);
HATSTATE(7, DOWN);
#undef HATSTATE

// this is a physical d-pad on the device, so it probably _can't_ send opposing buttons at the same time, but just in case, cancel them out.
if ((hat & (SDL_HAT_UP|SDL_HAT_DOWN)) == (SDL_HAT_UP|SDL_HAT_DOWN)) {
hat &= ~(SDL_HAT_UP|SDL_HAT_DOWN);
}
if ((hat & (SDL_HAT_LEFT|SDL_HAT_RIGHT)) == (SDL_HAT_LEFT|SDL_HAT_RIGHT)) {
hat &= ~(SDL_HAT_LEFT|SDL_HAT_RIGHT);
}
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
}
}


static void UpdateN3DSCircle(Uint64 timestamp, SDL_Joystick *joystick)
{
static circlePosition previous_state = { 0, 0 };
Expand Down Expand Up @@ -194,19 +235,19 @@ static bool N3DS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping
*out = (SDL_GamepadMapping){
.a = { EMappingKind_Button, 0 },
.b = { EMappingKind_Button, 1 },
.x = { EMappingKind_Button, 10 },
.y = { EMappingKind_Button, 11 },
.x = { EMappingKind_Button, 6 },
.y = { EMappingKind_Button, 7 },
.back = { EMappingKind_Button, 2 },
.guide = { EMappingKind_None, 255 },
.start = { EMappingKind_Button, 3 },
.leftstick = { EMappingKind_None, 255 },
.rightstick = { EMappingKind_None, 255 },
.leftshoulder = { EMappingKind_Button, 9 },
.rightshoulder = { EMappingKind_Button, 8 },
.dpup = { EMappingKind_Button, 6 },
.dpdown = { EMappingKind_Button, 7 },
.dpleft = { EMappingKind_Button, 5 },
.dpright = { EMappingKind_Button, 4 },
.leftshoulder = { EMappingKind_Button, 5 },
.rightshoulder = { EMappingKind_Button, 4 },
.dpup = { EMappingKind_Hat, SDL_HAT_UP },
.dpdown = { EMappingKind_Hat, SDL_HAT_DOWN },
.dpleft = { EMappingKind_Hat, SDL_HAT_LEFT },
.dpright = { EMappingKind_Hat, SDL_HAT_RIGHT },
.misc1 = { EMappingKind_None, 255 },
.right_paddle1 = { EMappingKind_None, 255 },
.left_paddle1 = { EMappingKind_None, 255 },
Expand All @@ -216,8 +257,8 @@ static bool N3DS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping
.lefty = { EMappingKind_Axis, 1 },
.rightx = { EMappingKind_Axis, 2 },
.righty = { EMappingKind_Axis, 3 },
.lefttrigger = { EMappingKind_Button, 14 },
.righttrigger = { EMappingKind_Button, 15 },
.lefttrigger = { EMappingKind_Button, 10 },
.righttrigger = { EMappingKind_Button, 11 },
};
return true;
}
Expand Down
57 changes: 44 additions & 13 deletions src/joystick/ps2/SDL_sysjoystick.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
#define MAX_CONTROLLERS (PS2_MAX_PORT * PS2_MAX_SLOT)
#define PS2_ANALOG_STICKS 2
#define PS2_ANALOG_AXIS 2
#define PS2_BUTTONS 16
#define PS2_BUTTONS 16 // this is total physical buttons, but we steal the 4 from the dpad for a hat switch.
#define PS2_TOTAL_AXIS (PS2_ANALOG_STICKS * PS2_ANALOG_AXIS)

#define PS2_HAT_MASK 0xF0 // mask out bits 4-7 (that's the dpad, which we treat as a hat elsewhere).

struct JoyInfo
{
uint8_t padBuf[256];
Expand Down Expand Up @@ -269,9 +271,9 @@ static bool PS2_JoystickOpen(SDL_Joystick *joystick, int device_index)
}
PS2_InitializePad(info->port, info->slot);

joystick->nbuttons = PS2_BUTTONS;
joystick->nbuttons = PS2_BUTTONS - 4; // we steal 4 (the d-pad) for a hat switch.
joystick->naxes = PS2_TOTAL_AXIS;
joystick->nhats = 0;
joystick->nhats = 1; // treat the dpad buttons as a hat.

SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, true);

Expand Down Expand Up @@ -347,19 +349,48 @@ static void PS2_JoystickUpdate(SDL_Joystick *joystick)
int ret = padRead(info->port, info->slot, &buttons); // port, slot, buttons
if (ret != 0) {
// Buttons
int32_t pressed_buttons = 0xffff ^ buttons.btns;
;
if (info->btns != pressed_buttons) {
for (i = 0; i < PS2_BUTTONS; i++) {
mask = (1 << i);
previous = info->btns & mask;
current = pressed_buttons & mask;
if (previous != current) {
SDL_SendJoystickButton(timestamp, joystick, i, (current != 0));
const int32_t current_buttons = (0xffff ^ buttons.btns);
const int32_t previous_buttons = info->btns;
if (previous_buttons != current_buttons) { // did any buttons change?
if ((previous_buttons & ~PS2_HAT_MASK) != (current_buttons & ~PS2_HAT_MASK)) { // did non-dpad buttons change?
uint8_t buttonidx = 0;
i = 0;
while (i < PS2_BUTTONS-4) {
if ((buttonidx < 4) || (buttonidx > 7)) { // skip dpad (we treat it as a hat).
mask = (1 << buttonidx);
previous = previous_buttons & mask;
current = current_buttons & mask;
if (previous != current) {
SDL_SendJoystickButton(timestamp, joystick, i, (current != 0));
}
i++;
}
buttonidx++;
}
}

if ((previous_buttons & PS2_HAT_MASK) != (current_buttons & PS2_HAT_MASK)) { // did dpad buttons change?
// The PS2 dpad looks like 4 buttons at this level, but we treat it as a hat switch, so apps that are talking to SDL_Joystick can hope to do basic directional things without a configuration step.
// (but they should _really_ be using the gamepad API.)
Uint8 hat = SDL_HAT_CENTERED;
#define HATSTATE(ps2bit, sdlenum) if (current_buttons & (1 << ps2bit)) { hat |= SDL_HAT_##sdlenum; }
HATSTATE(4, UP);
HATSTATE(5, RIGHT);
HATSTATE(6, DOWN);
HATSTATE(7, LEFT);
#undef HATSTATE
// this is a physical d-pad on the device, so it probably _can't_ send opposing buttons at the same time, but just in case, cancel them out.
if ((hat & (SDL_HAT_UP|SDL_HAT_DOWN)) == (SDL_HAT_UP|SDL_HAT_DOWN)) {
hat &= ~(SDL_HAT_UP|SDL_HAT_DOWN);
}
if ((hat & (SDL_HAT_LEFT|SDL_HAT_RIGHT)) == (SDL_HAT_LEFT|SDL_HAT_RIGHT)) {
hat &= ~(SDL_HAT_LEFT|SDL_HAT_RIGHT);
}
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
}

info->btns = current_buttons;
}
info->btns = pressed_buttons;

// Analog
all_axis[0] = buttons.ljoy_h;
Expand Down
33 changes: 27 additions & 6 deletions src/joystick/psp/SDL_sysjoystick.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@
#include "../SDL_sysjoystick.h"
#include "../SDL_joystick_c.h"

#define PSP_HAT_MASK (PSP_CTRL_DOWN | PSP_CTRL_LEFT | PSP_CTRL_UP | PSP_CTRL_RIGHT )

// Current pad state
static SceCtrlData pad = { .Lx = 0, .Ly = 0, .Buttons = 0 };
static const enum PspCtrlButtons button_map[] = {
PSP_CTRL_TRIANGLE, PSP_CTRL_CIRCLE, PSP_CTRL_CROSS, PSP_CTRL_SQUARE,
PSP_CTRL_LTRIGGER, PSP_CTRL_RTRIGGER,
PSP_CTRL_DOWN, PSP_CTRL_LEFT, PSP_CTRL_UP, PSP_CTRL_RIGHT,
PSP_CTRL_SELECT, PSP_CTRL_START, PSP_CTRL_HOME, PSP_CTRL_HOLD
};
static int analog_map[256]; // Map analog inputs to -32768 -> 32767
Expand Down Expand Up @@ -159,7 +160,7 @@ static bool PSP_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
joystick->nbuttons = SDL_arraysize(button_map);
joystick->naxes = 2;
joystick->nhats = 0;
joystick->nhats = 1; // we treat the d-pad as a hat.

return true;
}
Expand Down Expand Up @@ -224,15 +225,35 @@ static void PSP_JoystickUpdate(SDL_Joystick *joystick)
// Buttons
changed = old_buttons ^ buttons;
old_buttons = buttons;
if (changed) {
if (changed & ~PSP_HAT_MASK) {
for (i = 0; i < SDL_arraysize(button_map); i++) {
if (changed & button_map[i]) {
bool down = ((buttons & button_map[i]) != 0);
SDL_SendJoystickButton(timestamp,
joystick, i, down);
const bool down = ((buttons & button_map[i]) != 0);
SDL_SendJoystickButton(timestamp, joystick, i, down);
}
}
}

if (changed & PSP_HAT_MASK) {
// The PSP dpad looks like 4 buttons at this level, but we treat it as a hat switch, so apps that are talking to SDL_Joystick can hope to do basic directional things without a configuration step.
// (but they should _really_ be using the gamepad API.)
Uint8 hat = SDL_HAT_CENTERED;
#define HATSTATE(name) if (buttons & PSP_CTRL_##name) { hat |= SDL_HAT_##name; }
HATSTATE(UP);
HATSTATE(RIGHT);
HATSTATE(DOWN);
HATSTATE(LEFT);
#undef HATSTATE

// this is a physical d-pad on the device, so it probably _can't_ send opposing buttons at the same time, but just in case, cancel them out.
if ((hat & (SDL_HAT_UP|SDL_HAT_DOWN)) == (SDL_HAT_UP|SDL_HAT_DOWN)) {
hat &= ~(SDL_HAT_UP|SDL_HAT_DOWN);
}
if ((hat & (SDL_HAT_LEFT|SDL_HAT_RIGHT)) == (SDL_HAT_LEFT|SDL_HAT_RIGHT)) {
hat &= ~(SDL_HAT_LEFT|SDL_HAT_RIGHT);
}
SDL_SendJoystickHat(timestamp, joystick, 0, hat);
}
}

// Function to close a joystick after use
Expand Down
Loading
Loading