SDL: Implement rumble using SDL2 haptic

This commit is contained in:
Jeffrey Pfau 2015-04-16 23:37:27 -07:00
parent 05e04ba76a
commit ee6c9f71c2
5 changed files with 59 additions and 1 deletions

View File

@ -98,6 +98,9 @@ GameController::GameController(QObject* parent)
context->gba->logLevel = GBA_LOG_FATAL; context->gba->logLevel = GBA_LOG_FATAL;
context->gba->luminanceSource = &controller->m_lux; context->gba->luminanceSource = &controller->m_lux;
context->gba->rtcSource = &controller->m_rtc; context->gba->rtcSource = &controller->m_rtc;
#ifdef BUILD_SDL
context->gba->rumble = controller->m_inputController->rumble();
#endif
controller->gameStarted(context); controller->gameStarted(context);
}; };

View File

@ -150,6 +150,10 @@ void InputController::setPreferredGamepad(uint32_t type, const QString& device)
} }
GBAInputSetPreferredDevice(m_config->input(), type, m_sdlPlayer.playerId, device.toLocal8Bit().constData()); GBAInputSetPreferredDevice(m_config->input(), type, m_sdlPlayer.playerId, device.toLocal8Bit().constData());
} }
GBARumble* InputController::rumble() {
return &m_sdlPlayer.rumble.d;
}
#endif #endif
GBAKey InputController::mapKeyboard(int key) const { GBAKey InputController::mapKeyboard(int key) const {

View File

@ -63,6 +63,7 @@ public:
int gamepad(uint32_t type) const { return m_sdlPlayer.joystickIndex; } int gamepad(uint32_t type) const { return m_sdlPlayer.joystickIndex; }
void setGamepad(uint32_t type, int index) { GBASDLPlayerChangeJoystick(&s_sdlEvents, &m_sdlPlayer, index); } void setGamepad(uint32_t type, int index) { GBASDLPlayerChangeJoystick(&s_sdlEvents, &m_sdlPlayer, index); }
void setPreferredGamepad(uint32_t type, const QString& device); void setPreferredGamepad(uint32_t type, const QString& device);
GBARumble* rumble();
#endif #endif
public slots: public slots:

View File

@ -20,8 +20,14 @@
#define GUI_MOD KMOD_CTRL #define GUI_MOD KMOD_CTRL
#endif #endif
static void _GBASDLSetRumble(struct GBARumble* rumble, int enable);
bool GBASDLInitEvents(struct GBASDLEvents* context) { bool GBASDLInitEvents(struct GBASDLEvents* context) {
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0) { int subsystem = SDL_INIT_JOYSTICK;
#if SDL_VERSION_ATLEAST(2, 0, 0)
subsystem |= SDL_INIT_HAPTIC;
#endif
if (SDL_InitSubSystem(subsystem) < 0) {
return false; return false;
} }
@ -30,9 +36,15 @@ bool GBASDLInitEvents(struct GBASDLEvents* context) {
if (nJoysticks > 0) { if (nJoysticks > 0) {
context->nJoysticks = nJoysticks; context->nJoysticks = nJoysticks;
context->joysticks = calloc(context->nJoysticks, sizeof(SDL_Joystick*)); context->joysticks = calloc(context->nJoysticks, sizeof(SDL_Joystick*));
#if SDL_VERSION_ATLEAST(2, 0, 0)
context->haptic = calloc(context->nJoysticks, sizeof(SDL_Haptic*));
#endif
size_t i; size_t i;
for (i = 0; i < context->nJoysticks; ++i) { for (i = 0; i < context->nJoysticks; ++i) {
context->joysticks[i] = SDL_JoystickOpen(i); context->joysticks[i] = SDL_JoystickOpen(i);
#if SDL_VERSION_ATLEAST(2, 0, 0)
context->haptic[i] = SDL_HapticOpenFromJoystick(context->joysticks[i]);
#endif
} }
} else { } else {
context->nJoysticks = 0; context->nJoysticks = 0;
@ -56,6 +68,9 @@ bool GBASDLInitEvents(struct GBASDLEvents* context) {
void GBASDLDeinitEvents(struct GBASDLEvents* context) { void GBASDLDeinitEvents(struct GBASDLEvents* context) {
size_t i; size_t i;
for (i = 0; i < context->nJoysticks; ++i) { for (i = 0; i < context->nJoysticks; ++i) {
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_HapticClose(context->haptic[i]);
#endif
SDL_JoystickClose(context->joysticks[i]); SDL_JoystickClose(context->joysticks[i]);
} }
@ -126,6 +141,11 @@ bool GBASDLAttachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player
player->joystick = 0; player->joystick = 0;
player->joystickIndex = SIZE_MAX; player->joystickIndex = SIZE_MAX;
#if SDL_VERSION_ATLEAST(2, 0, 0)
player->rumble.d.setRumble = _GBASDLSetRumble;
player->rumble.p = player;
#endif
if (events->playersAttached >= MAX_PLAYERS) { if (events->playersAttached >= MAX_PLAYERS) {
return false; return false;
} }
@ -171,6 +191,13 @@ bool GBASDLAttachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player
if (player->joystickIndex != SIZE_MAX) { if (player->joystickIndex != SIZE_MAX) {
player->joystick = events->joysticks[player->joystickIndex]; player->joystick = events->joysticks[player->joystickIndex];
events->joysticksClaimed[player->playerId] = player->joystickIndex; events->joysticksClaimed[player->playerId] = player->joystickIndex;
#if SDL_VERSION_ATLEAST(2, 0, 0)
player->haptic = events->haptic[player->joystickIndex];
if (player->haptic) {
SDL_HapticRumbleInit(player->haptic);
}
#endif
} }
++events->playersAttached; ++events->playersAttached;
@ -403,3 +430,17 @@ void GBASDLHandleEvent(struct GBAThread* context, struct GBASDLPlayer* sdlContex
break; break;
} }
} }
#if SDL_VERSION_ATLEAST(2, 0, 0)
static void _GBASDLSetRumble(struct GBARumble* rumble, int enable) {
struct GBASDLRumble* sdlRumble = (struct GBASDLRumble*) rumble;
if (!sdlRumble->p->haptic || !SDL_HapticRumbleSupported(sdlRumble->p->haptic)) {
return;
}
if (enable) {
SDL_HapticRumblePlay(sdlRumble->p->haptic, 1.0f, 20);
} else {
SDL_HapticRumbleStop(sdlRumble->p->haptic);
}
}
#endif

View File

@ -26,6 +26,9 @@ struct GBASDLEvents {
const char* preferredJoysticks[MAX_PLAYERS]; const char* preferredJoysticks[MAX_PLAYERS];
int playersAttached; int playersAttached;
size_t joysticksClaimed[MAX_PLAYERS]; size_t joysticksClaimed[MAX_PLAYERS];
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Haptic** haptic;
#endif
}; };
struct GBASDLPlayer { struct GBASDLPlayer {
@ -37,6 +40,12 @@ struct GBASDLPlayer {
SDL_Window* window; SDL_Window* window;
int fullscreen; int fullscreen;
int windowUpdated; int windowUpdated;
SDL_Haptic* haptic;
struct GBASDLRumble {
struct GBARumble d;
struct GBASDLPlayer* p;
} rumble;
#endif #endif
}; };