all repos — mgba @ ee6c9f71c24cbbc3588af9517e226c13bc16e3e8

mGBA Game Boy Advance Emulator

SDL: Implement rumble using SDL2 haptic
Jeffrey Pfau jeffrey@endrift.com
Thu, 16 Apr 2015 23:37:27 -0700
commit

ee6c9f71c24cbbc3588af9517e226c13bc16e3e8

parent

05e04ba76a396c4e54933951bf72f90097865438

M src/platform/qt/GameController.cppsrc/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.cppsrc/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.hsrc/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.csrc/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.hsrc/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 };