mirror of https://github.com/mgba-emu/mgba.git
SDL: Add sensor support for controllers with SDL 2.0.14+
This commit is contained in:
parent
9430913ba3
commit
c1c931c61f
1
CHANGES
1
CHANGES
|
@ -5,6 +5,7 @@ Features:
|
||||||
- Tool for converting scanned pictures of e-Reader cards to raw dotcode data
|
- Tool for converting scanned pictures of e-Reader cards to raw dotcode data
|
||||||
- Options for muting when inactive, minimized, or for different players in multiplayer
|
- Options for muting when inactive, minimized, or for different players in multiplayer
|
||||||
- Cheat code support in homebrew ports
|
- Cheat code support in homebrew ports
|
||||||
|
- Acclerometer and gyro support for controllers on PC
|
||||||
- Support for combo "Super Game Boy Color" SGB + GBC ROM hacks
|
- Support for combo "Super Game Boy Color" SGB + GBC ROM hacks
|
||||||
- Support for 64 kiB SRAM saves used in some bootlegs
|
- Support for 64 kiB SRAM saves used in some bootlegs
|
||||||
- Discord Rich Presence now supports time elapsed
|
- Discord Rich Presence now supports time elapsed
|
||||||
|
|
|
@ -37,6 +37,34 @@ static int32_t _mSDLReadTiltY(struct mRotationSource* rumble);
|
||||||
static int32_t _mSDLReadGyroZ(struct mRotationSource* rumble);
|
static int32_t _mSDLReadGyroZ(struct mRotationSource* rumble);
|
||||||
static void _mSDLRotationSample(struct mRotationSource* source);
|
static void _mSDLRotationSample(struct mRotationSource* source);
|
||||||
|
|
||||||
|
static struct SDL_JoystickCombo* _mSDLOpenJoystick(struct mSDLEvents* events, int i) {
|
||||||
|
SDL_Joystick* sdlJoystick = SDL_JoystickOpen(i);
|
||||||
|
if (!sdlJoystick) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&events->joysticks);
|
||||||
|
joystick->index = SDL_JoystickListSize(&events->joysticks) - 1;
|
||||||
|
joystick->joystick = sdlJoystick;
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
joystick->id = SDL_JoystickInstanceID(joystick->joystick);
|
||||||
|
joystick->haptic = SDL_HapticOpenFromJoystick(joystick->joystick);
|
||||||
|
joystick->controller = SDL_GameControllerOpen(i);
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||||
|
if (joystick->controller) {
|
||||||
|
if (SDL_GameControllerHasSensor(joystick->controller, SDL_SENSOR_GYRO) && !SDL_GameControllerIsSensorEnabled(joystick->controller, SDL_SENSOR_GYRO)) {
|
||||||
|
SDL_GameControllerSetSensorEnabled(joystick->controller, SDL_SENSOR_GYRO, SDL_TRUE);
|
||||||
|
}
|
||||||
|
if (SDL_GameControllerHasSensor(joystick->controller, SDL_SENSOR_ACCEL) && !SDL_GameControllerIsSensorEnabled(joystick->controller, SDL_SENSOR_ACCEL)) {
|
||||||
|
SDL_GameControllerSetSensorEnabled(joystick->controller, SDL_SENSOR_ACCEL, SDL_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
joystick->id = SDL_JoystickIndex(joystick->joystick);
|
||||||
|
#endif
|
||||||
|
return joystick;
|
||||||
|
}
|
||||||
|
|
||||||
bool mSDLInitEvents(struct mSDLEvents* context) {
|
bool mSDLInitEvents(struct mSDLEvents* context) {
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 4)
|
#if SDL_VERSION_ATLEAST(2, 0, 4)
|
||||||
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
|
SDL_SetHint(SDL_HINT_NO_SIGNAL_HANDLERS, "1");
|
||||||
|
@ -50,6 +78,9 @@ bool mSDLInitEvents(struct mSDLEvents* context) {
|
||||||
if (SDL_InitSubSystem(SDL_INIT_HAPTIC) < 0) {
|
if (SDL_InitSubSystem(SDL_INIT_HAPTIC) < 0) {
|
||||||
mLOG(SDL_EVENTS, ERROR, "SDL haptic initialization failed: %s", SDL_GetError());
|
mLOG(SDL_EVENTS, ERROR, "SDL haptic initialization failed: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) < 0) {
|
||||||
|
mLOG(SDL_EVENTS, ERROR, "SDL game controller initialization failed: %s", SDL_GetError());
|
||||||
|
}
|
||||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
|
||||||
mLOG(SDL_EVENTS, ERROR, "SDL video initialization failed: %s", SDL_GetError());
|
mLOG(SDL_EVENTS, ERROR, "SDL video initialization failed: %s", SDL_GetError());
|
||||||
}
|
}
|
||||||
|
@ -64,19 +95,7 @@ bool mSDLInitEvents(struct mSDLEvents* context) {
|
||||||
if (!SDL_JoystickListSize(&context->joysticks)) {
|
if (!SDL_JoystickListSize(&context->joysticks)) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < nJoysticks; ++i) {
|
for (i = 0; i < nJoysticks; ++i) {
|
||||||
SDL_Joystick* sdlJoystick = SDL_JoystickOpen(i);
|
_mSDLOpenJoystick(context, i);
|
||||||
if (!sdlJoystick) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&context->joysticks);
|
|
||||||
joystick->joystick = sdlJoystick;
|
|
||||||
joystick->index = SDL_JoystickListSize(&context->joysticks) - 1;
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
joystick->id = SDL_JoystickInstanceID(joystick->joystick);
|
|
||||||
joystick->haptic = SDL_HapticOpenFromJoystick(joystick->joystick);
|
|
||||||
#else
|
|
||||||
joystick->id = SDL_JoystickIndex(joystick->joystick);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,6 +120,7 @@ void mSDLDeinitEvents(struct mSDLEvents* context) {
|
||||||
for (i = 0; i < SDL_JoystickListSize(&context->joysticks); ++i) {
|
for (i = 0; i < SDL_JoystickListSize(&context->joysticks); ++i) {
|
||||||
struct SDL_JoystickCombo* joystick = SDL_JoystickListGetPointer(&context->joysticks, i);
|
struct SDL_JoystickCombo* joystick = SDL_JoystickListGetPointer(&context->joysticks, i);
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
SDL_GameControllerClose(joystick->controller);
|
||||||
SDL_HapticClose(joystick->haptic);
|
SDL_HapticClose(joystick->haptic);
|
||||||
#endif
|
#endif
|
||||||
SDL_JoystickClose(joystick->joystick);
|
SDL_JoystickClose(joystick->joystick);
|
||||||
|
@ -350,10 +370,6 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED) > 0) {
|
while (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED) > 0) {
|
||||||
if (event.type == SDL_JOYDEVICEADDED) {
|
if (event.type == SDL_JOYDEVICEADDED) {
|
||||||
SDL_Joystick* sdlJoystick = SDL_JoystickOpen(event.jdevice.which);
|
|
||||||
if (!sdlJoystick) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ssize_t joysticks[MAX_PLAYERS];
|
ssize_t joysticks[MAX_PLAYERS];
|
||||||
ssize_t i;
|
ssize_t i;
|
||||||
// Pointers can get invalidated, so we'll need to refresh them
|
// Pointers can get invalidated, so we'll need to refresh them
|
||||||
|
@ -361,38 +377,26 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
||||||
joysticks[i] = events->players[i]->joystick ? (ssize_t) SDL_JoystickListIndex(&events->joysticks, events->players[i]->joystick) : -1;
|
joysticks[i] = events->players[i]->joystick ? (ssize_t) SDL_JoystickListIndex(&events->joysticks, events->players[i]->joystick) : -1;
|
||||||
events->players[i]->joystick = NULL;
|
events->players[i]->joystick = NULL;
|
||||||
}
|
}
|
||||||
struct SDL_JoystickCombo* joystick = SDL_JoystickListAppend(&events->joysticks);
|
struct SDL_JoystickCombo* joystick = _mSDLOpenJoystick(events, event.jdevice.which);
|
||||||
joystick->joystick = sdlJoystick;
|
|
||||||
joystick->id = SDL_JoystickInstanceID(joystick->joystick);
|
|
||||||
joystick->index = SDL_JoystickListSize(&events->joysticks) - 1;
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
joystick->haptic = SDL_HapticOpenFromJoystick(joystick->joystick);
|
|
||||||
#endif
|
|
||||||
for (i = 0; i < events->playersAttached && i < MAX_PLAYERS; ++i) {
|
for (i = 0; i < events->playersAttached && i < MAX_PLAYERS; ++i) {
|
||||||
if (joysticks[i] != -1) {
|
if (joysticks[i] != -1) {
|
||||||
events->players[i]->joystick = SDL_JoystickListGetPointer(&events->joysticks, joysticks[i]);
|
events->players[i]->joystick = SDL_JoystickListGetPointer(&events->joysticks, joysticks[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
char joystickName[34] = {0};
|
char joystickName[34] = {0};
|
||||||
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick->joystick), joystickName, sizeof(joystickName));
|
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick->joystick), joystickName, sizeof(joystickName));
|
||||||
#else
|
for (i = 0; (int) i < events->playersAttached; ++i) {
|
||||||
const char* joystickName = SDL_JoystickName(SDL_JoystickIndex(joystick->joystick));
|
if (events->players[i]->joystick) {
|
||||||
if (joystickName)
|
continue;
|
||||||
#endif
|
}
|
||||||
{
|
if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) {
|
||||||
for (i = 0; (int) i < events->playersAttached; ++i) {
|
events->players[i]->joystick = joystick;
|
||||||
if (events->players[i]->joystick) {
|
if (config) {
|
||||||
continue;
|
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
||||||
}
|
|
||||||
if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) {
|
|
||||||
events->players[i]->joystick = joystick;
|
|
||||||
if (config) {
|
|
||||||
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; (int) i < events->playersAttached; ++i) {
|
for (i = 0; (int) i < events->playersAttached; ++i) {
|
||||||
|
@ -400,11 +404,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
events->players[i]->joystick = joystick;
|
events->players[i]->joystick = joystick;
|
||||||
if (config
|
if (config && joystickName[0]) {
|
||||||
#if !SDL_VERSION_ATLEAST(2, 0, 0)
|
|
||||||
&& joystickName
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -686,11 +686,17 @@ static int32_t _readTilt(struct mSDLPlayer* player, int axis) {
|
||||||
|
|
||||||
static int32_t _mSDLReadTiltX(struct mRotationSource* source) {
|
static int32_t _mSDLReadTiltX(struct mRotationSource* source) {
|
||||||
struct mSDLRotation* rotation = (struct mSDLRotation*) source;
|
struct mSDLRotation* rotation = (struct mSDLRotation*) source;
|
||||||
|
if (rotation->axisX < 0) {
|
||||||
|
return rotation->accelX * -0x2000000;
|
||||||
|
}
|
||||||
return _readTilt(rotation->p, rotation->axisX);
|
return _readTilt(rotation->p, rotation->axisX);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t _mSDLReadTiltY(struct mRotationSource* source) {
|
static int32_t _mSDLReadTiltY(struct mRotationSource* source) {
|
||||||
struct mSDLRotation* rotation = (struct mSDLRotation*) source;
|
struct mSDLRotation* rotation = (struct mSDLRotation*) source;
|
||||||
|
if (rotation->axisY < 0) {
|
||||||
|
return rotation->accelY * -0x2000000;
|
||||||
|
}
|
||||||
return _readTilt(rotation->p, rotation->axisY);
|
return _readTilt(rotation->p, rotation->axisY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,6 +713,30 @@ static void _mSDLRotationSample(struct mRotationSource* source) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if SDL_VERSION_ATLEAST(2, 0, 14)
|
||||||
|
if (rotation->p->joystick->controller) {
|
||||||
|
SDL_GameController* controller = rotation->p->joystick->controller;
|
||||||
|
if (SDL_GameControllerHasSensor(controller, SDL_SENSOR_ACCEL)) {
|
||||||
|
float accel[3];
|
||||||
|
int count = SDL_GameControllerGetSensorData(controller, SDL_SENSOR_ACCEL, accel, 3);
|
||||||
|
if (count >= 0) {
|
||||||
|
rotation->accelX = accel[0];
|
||||||
|
rotation->accelY = accel[2];
|
||||||
|
rotation->axisX = -1;
|
||||||
|
rotation->axisY = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SDL_GameControllerHasSensor(controller, SDL_SENSOR_GYRO)) {
|
||||||
|
float theta[3];
|
||||||
|
int count = SDL_GameControllerGetSensorData(controller, SDL_SENSOR_GYRO, theta, 3);
|
||||||
|
if (count >= 0) {
|
||||||
|
rotation->zDelta = theta[1] / -10.f;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int x = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroX);
|
int x = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroX);
|
||||||
int y = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroY);
|
int y = SDL_JoystickGetAxis(rotation->p->joystick->joystick, rotation->gyroY);
|
||||||
union {
|
union {
|
||||||
|
|
|
@ -38,6 +38,7 @@ struct SDL_JoystickCombo {
|
||||||
size_t index;
|
size_t index;
|
||||||
SDL_Joystick* joystick;
|
SDL_Joystick* joystick;
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
|
SDL_GameController* controller;
|
||||||
SDL_Haptic* haptic;
|
SDL_Haptic* haptic;
|
||||||
SDL_JoystickID id;
|
SDL_JoystickID id;
|
||||||
#else
|
#else
|
||||||
|
@ -88,6 +89,8 @@ struct mSDLPlayer {
|
||||||
// Tilt
|
// Tilt
|
||||||
int axisX;
|
int axisX;
|
||||||
int axisY;
|
int axisY;
|
||||||
|
float accelX;
|
||||||
|
float accelY;
|
||||||
|
|
||||||
// Gyro
|
// Gyro
|
||||||
int gyroX;
|
int gyroX;
|
||||||
|
|
Loading…
Reference in New Issue