SDL: Implement rumble using SDL2 haptic
Jeffrey Pfau jeffrey@endrift.com
Thu, 16 Apr 2015 23:37:27 -0700
5 files changed,
59 insertions(+),
1 deletions(-)
M
src/platform/qt/GameController.cpp
→
src/platform/qt/GameController.cpp
@@ -98,6 +98,9 @@ // Override the GBA object's log level to prevent stdout spew
context->gba->logLevel = GBA_LOG_FATAL; context->gba->luminanceSource = &controller->m_lux; context->gba->rtcSource = &controller->m_rtc; +#ifdef BUILD_SDL + context->gba->rumble = controller->m_inputController->rumble(); +#endif controller->gameStarted(context); };
M
src/platform/qt/InputController.cpp
→
src/platform/qt/InputController.cpp
@@ -150,6 +150,10 @@ return;
} GBAInputSetPreferredDevice(m_config->input(), type, m_sdlPlayer.playerId, device.toLocal8Bit().constData()); } + +GBARumble* InputController::rumble() { + return &m_sdlPlayer.rumble.d; +} #endif GBAKey InputController::mapKeyboard(int key) const {
M
src/platform/qt/InputController.h
→
src/platform/qt/InputController.h
@@ -63,6 +63,7 @@ QStringList connectedGamepads(uint32_t type) const;
int gamepad(uint32_t type) const { return m_sdlPlayer.joystickIndex; } void setGamepad(uint32_t type, int index) { GBASDLPlayerChangeJoystick(&s_sdlEvents, &m_sdlPlayer, index); } void setPreferredGamepad(uint32_t type, const QString& device); + GBARumble* rumble(); #endif public slots:
M
src/platform/sdl/sdl-events.c
→
src/platform/sdl/sdl-events.c
@@ -20,8 +20,14 @@ #else
#define GUI_MOD KMOD_CTRL #endif +static void _GBASDLSetRumble(struct GBARumble* rumble, int enable); + 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; }@@ -30,9 +36,15 @@ int nJoysticks = SDL_NumJoysticks();
if (nJoysticks > 0) { context->nJoysticks = nJoysticks; 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; for (i = 0; i < context->nJoysticks; ++i) { context->joysticks[i] = SDL_JoystickOpen(i); +#if SDL_VERSION_ATLEAST(2, 0, 0) + context->haptic[i] = SDL_HapticOpenFromJoystick(context->joysticks[i]); +#endif } } else { context->nJoysticks = 0;@@ -56,6 +68,9 @@
void GBASDLDeinitEvents(struct GBASDLEvents* context) { size_t 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]); }@@ -126,6 +141,11 @@ bool GBASDLAttachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player) {
player->joystick = 0; 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) { return false; }@@ -171,6 +191,13 @@
if (player->joystickIndex != SIZE_MAX) { player->joystick = events->joysticks[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;@@ -403,3 +430,17 @@ _GBASDLHandleJoyAxis(context, sdlContext, &event->jaxis);
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
M
src/platform/sdl/sdl-events.h
→
src/platform/sdl/sdl-events.h
@@ -26,6 +26,9 @@ size_t nJoysticks;
const char* preferredJoysticks[MAX_PLAYERS]; int playersAttached; size_t joysticksClaimed[MAX_PLAYERS]; +#if SDL_VERSION_ATLEAST(2, 0, 0) + SDL_Haptic** haptic; +#endif }; struct GBASDLPlayer {@@ -37,6 +40,12 @@ #if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Window* window; int fullscreen; int windowUpdated; + SDL_Haptic* haptic; + + struct GBASDLRumble { + struct GBARumble d; + struct GBASDLPlayer* p; + } rumble; #endif };