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->luminanceSource = &controller->m_lux;
context->gba->rtcSource = &controller->m_rtc;
#ifdef BUILD_SDL
context->gba->rumble = controller->m_inputController->rumble();
#endif
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());
}
GBARumble* InputController::rumble() {
return &m_sdlPlayer.rumble.d;
}
#endif
GBAKey InputController::mapKeyboard(int key) const {

View File

@ -63,6 +63,7 @@ public:
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:

View File

@ -20,8 +20,14 @@
#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 @@ bool GBASDLInitEvents(struct GBASDLEvents* context) {
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 @@ bool GBASDLInitEvents(struct GBASDLEvents* context) {
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 @@ bool GBASDLAttachPlayer(struct GBASDLEvents* events, struct GBASDLPlayer* player
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 @@ void GBASDLHandleEvent(struct GBAThread* context, struct GBASDLPlayer* sdlContex
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];
int playersAttached;
size_t joysticksClaimed[MAX_PLAYERS];
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Haptic** haptic;
#endif
};
struct GBASDLPlayer {
@ -37,6 +40,12 @@ struct GBASDLPlayer {
SDL_Window* window;
int fullscreen;
int windowUpdated;
SDL_Haptic* haptic;
struct GBASDLRumble {
struct GBARumble d;
struct GBASDLPlayer* p;
} rumble;
#endif
};