void JoyInitHaptic() { #if 0 uint8_t i; unsigned int haptic_query = 0; for (i = 0; i < 2; i++) { if (g.PadState[i].JoyDev && SDL_JoystickIsHaptic(g.PadState[i].JoyDev)) { if (g.PadState[i].haptic != NULL) { SDL_HapticClose(g.PadState[i].haptic); g.PadState[i].haptic = NULL; } g.PadState[i].haptic = SDL_HapticOpenFromJoystick(g.PadState[i].JoyDev); if (g.PadState[i].haptic == NULL) continue; if (SDL_HapticRumbleSupported(g.PadState[i].haptic) == SDL_FALSE) { printf("\nRumble not supported\n"); g.PadState[i].haptic = NULL; continue; } if (SDL_HapticRumbleInit(g.PadState[i].haptic) != 0) { printf("\nFailed to initialize rumble: %s\n", SDL_GetError()); g.PadState[i].haptic = NULL; continue; } } } #endif }
void SDLFrontend::initJoystickAndHaptic () { if (_haptic != nullptr) { SDL_HapticClose(_haptic); _haptic = nullptr; } const int joysticks = SDL_NumJoysticks(); SDL_Haptic *haptic = nullptr; for (int i = 0; i < joysticks; i++) { const char *name; if (SDL_IsGameController(i)) { name = SDL_GameControllerNameForIndex(i); } else { name = SDL_JoystickNameForIndex(i); } SDL_Joystick *joystick = SDL_JoystickOpen(i); info(LOG_CLIENT, String::format("found joystick %s", name ? name : "Unknown Joystick")); info(LOG_CLIENT, String::format("joystick axes: %i", SDL_JoystickNumAxes(joystick))); info(LOG_CLIENT, String::format("joystick hats: %i", SDL_JoystickNumHats(joystick))); info(LOG_CLIENT, String::format("joystick balls: %i", SDL_JoystickNumBalls(joystick))); info(LOG_CLIENT, String::format("joystick buttons: %i", SDL_JoystickNumButtons(joystick))); if (haptic == nullptr) haptic = SDL_HapticOpenFromJoystick(joystick); } if (!joysticks) { info(LOG_CLIENT, "no joysticks found"); } info(LOG_CLIENT, String::format("found %i touch device(s)", SDL_GetNumTouchDevices())); info(LOG_CLIENT, String::format("%i haptic devices", SDL_NumHaptics())); if (haptic == nullptr && SDL_MouseIsHaptic()) { haptic = SDL_HapticOpenFromMouse(); } if (haptic != nullptr) { const bool rumbleSupported = SDL_HapticRumbleSupported(haptic) && SDL_HapticRumbleInit(haptic) == 0; if (rumbleSupported) { info(LOG_CLIENT, "rumble support"); _haptic = haptic; } } if (_haptic == nullptr) { info(LOG_CLIENT, "no rumble support"); } }
C4GamePadOpener::C4GamePadOpener(int iGamepad) { int n = iGamepad; for (int i = 0; i < SDL_NumJoysticks(); i++) if (SDL_IsGameController(i) && n-- == 0) { controller = SDL_GameControllerOpen(i); if (!controller) LogF("SDL: %s", SDL_GetError()); SDL_Joystick *joystick = SDL_GameControllerGetJoystick(controller); haptic = SDL_HapticOpenFromJoystick(joystick); if (haptic && SDL_HapticRumbleSupported(haptic)) SDL_HapticRumbleInit(haptic); else LogF("Gamepad #%d %s does not support rumbling.", SDL_JoystickInstanceID(joystick), SDL_JoystickName(joystick)); break; } if (!controller) LogF("Gamepad %d not available", iGamepad); }
Controller::Controller(){ SDL_InitSubSystem(SDL_INIT_JOYSTICK); SDL_Init(SDL_INIT_HAPTIC); SDL_JoystickEventState(SDL_ENABLE); joystick = SDL_JoystickOpen(0); if (joystick){ joystickAnalogs.resize(SDL_JoystickNumAxes(joystick)); joystickButtonHeld.resize(SDL_JoystickNumButtons(joystick)); joystickButtonPressed.resize(SDL_JoystickNumButtons(joystick)); joystickButtonReleased.resize(SDL_JoystickNumButtons(joystick)); joystickDPad.resize(13); haptic = SDL_HapticOpenFromJoystick(joystick); if (SDL_HapticRumbleSupported(haptic) == SDL_TRUE){ SDL_HapticRumbleInit(haptic); rumbleSupport = true; } else rumbleSupport = false; } }
void test_rumble(int joy_idx) { SDL_Joystick* joy = SDL_JoystickOpen(joy_idx); if (!joy) { fprintf(stderr, "Unable to open joystick %d\n", joy_idx); } else { SDL_Haptic* haptic = SDL_HapticOpenFromJoystick(joy); if (!haptic) { fprintf(stderr, "Unable to open haptic on joystick %d\n", joy_idx); fprintf(stderr, "SDL_Error: %s\n", SDL_GetError()); } else { if (!SDL_HapticRumbleSupported(haptic)) { fprintf(stderr, "rumble not supported on joystick %d\n", joy_idx); } else { if (SDL_HapticRumbleInit(haptic) != 0) { fprintf(stderr, "failed to init rumble\n"); } else { SDL_HapticRumblePlay(haptic, 1.0, 3000); SDL_Delay(3000); } } SDL_HapticClose(haptic); } SDL_JoystickClose(joy); } }
/** * @brief The entry point of this force feedback demo. * @param[in] argc Number of arguments. * @param[in] argv Array of argc arguments. */ int main(int argc, char **argv) { int i; char *name; int index; /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); name = NULL; index = -1; if (argc > 1) { size_t l; name = argv[1]; if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) { SDL_Log("USAGE: %s [device]\n" "If device is a two-digit number it'll use it as an index, otherwise\n" "it'll use it as if it were part of the device's name.\n", argv[0]); return 0; } l = SDL_strlen(name); if ((l < 3) && SDL_isdigit(name[0]) && ((l == 1) || SDL_isdigit(name[1]))) { index = SDL_atoi(name); name = NULL; } } /* Initialize the force feedbackness */ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC); SDL_Log("%d Haptic devices detected.\n", SDL_NumHaptics()); if (SDL_NumHaptics() > 0) { /* We'll just use index or the first force feedback device found */ if (name == NULL) { i = (index != -1) ? index : 0; } /* Try to find matching device */ else { for (i = 0; i < SDL_NumHaptics(); i++) { if (strstr(SDL_HapticName(i), name) != NULL) break; } if (i >= SDL_NumHaptics()) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n", name); return 1; } } haptic = SDL_HapticOpen(i); if (haptic == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n", SDL_GetError()); return 1; } SDL_Log("Device: %s\n", SDL_HapticName(i)); } else { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n"); return 1; } /* We only want force feedback errors. */ SDL_ClearError(); if (SDL_HapticRumbleSupported(haptic) == SDL_FALSE) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Rumble not supported!\n"); return 1; } if (SDL_HapticRumbleInit(haptic) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to initialize rumble: %s\n", SDL_GetError()); return 1; } SDL_Log("Playing 2 second rumble at 0.5 magnitude.\n"); if (SDL_HapticRumblePlay(haptic, 0.5, 5000) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to play rumble: %s\n", SDL_GetError() ); return 1; } SDL_Delay(2000); SDL_Log("Stopping rumble.\n"); SDL_HapticRumbleStop(haptic); SDL_Delay(2000); SDL_Log("Playing 2 second rumble at 0.3 magnitude.\n"); if (SDL_HapticRumblePlay(haptic, 0.3f, 5000) != 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Failed to play rumble: %s\n", SDL_GetError() ); return 1; } SDL_Delay(2000); /* Quit */ if (haptic != NULL) SDL_HapticClose(haptic); SDL_Quit(); return 0; }
void C4GamePadOpener::StopRumble() { if (SDL_HapticRumbleSupported(haptic)) SDL_HapticRumbleStop(haptic); }
void C4GamePadOpener::PlayRumble(float strength, uint32_t length) { if (SDL_HapticRumbleSupported(haptic)) SDL_HapticRumblePlay(haptic, strength, length); }
// First time (lazy) initialization. void gfctrlJoyInit(void) { #ifndef SDL_JOYSTICK gfctrlJoyPresent = GFCTRL_JOY_NONE; for (int index = 0; index < GFCTRL_JOY_NUMBER; index++) { if (!Joysticks[index]) { Joysticks[index] = new jsJoystick(index); } // Don't configure the joystick if it doesn't work if (Joysticks[index]->notWorking()) { delete Joysticks[index]; Joysticks[index] = 0; } else { gfctrlJoyPresent = GFCTRL_JOY_PRESENT; } } #else #if SDL_MAJOR_VERSION >= 2 memset(&cfx, 0, sizeof(cfx)); if (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC) < 0) { #else if (SDL_Init(SDL_INIT_JOYSTICK) < 0) { #endif GfLogError("Couldn't initialize SDL: %s\n", SDL_GetError()); gfctrlJoyPresent = GFCTRL_JOY_UNTESTED; return; } #if SDL_MAJOR_VERSION >= 2 // Ignore the joystick events, we will poll directly as it is faster SDL_JoystickEventState(SDL_IGNORE); #endif gfctrlJoyPresent = SDL_NumJoysticks(); if (gfctrlJoyPresent > GFCTRL_JOY_NUMBER) gfctrlJoyPresent = GFCTRL_JOY_NUMBER; for (int index = 0; index < gfctrlJoyPresent; index++) { if (!Joysticks[index]) { Joysticks[index] = SDL_JoystickOpen(index); } // Don't configure the joystick if it doesn't work if (Joysticks[index] == NULL) { GfLogError("Couldn't open joystick %d: %s\n", index, SDL_GetError()); #if SDL_MAJOR_VERSION >= 2 } else { cfx_timeout[index] = 0; rfx_timeout[index] = 0; // Find which Haptic device relates to this joystick Haptics[index] = SDL_HapticOpenFromJoystick(Joysticks[index]); if (!Haptics[index]) { GfLogInfo("Joystick %d does not support haptic\n", index); break; #if 0 } else { // add an CF effect on startup gfctrlJoyConstantForce(index, 50000, 9000); #endif } // Check for Rumble capability if (SDL_HapticRumbleSupported(Haptics[index]) == SDL_TRUE) { if (SDL_HapticRumbleInit(Haptics[index]) != 0) GfLogError("Couldn't init rumble on joystick %d: %s\n", index, SDL_GetError()); #if 0 else gfctrlJoyRumble(index, 0.5); #endif } #endif } } #endif } #if SDL_JOYSTICK void gfctrlJoyConstantForce(int index, unsigned int level, int dir) { #if SDL_MAJOR_VERSION >= 2 if (!Haptics[index]) return; if ((SDL_HapticQuery(Haptics[index]) & SDL_HAPTIC_CONSTANT) == 0) return; cfx[index].type = SDL_HAPTIC_CONSTANT; cfx[index].constant.direction.type = SDL_HAPTIC_POLAR; cfx[index].constant.direction.dir[0] = dir; cfx[index].constant.length = 1000; cfx[index].constant.level = level; cfx[index].constant.attack_length = 0; cfx[index].constant.fade_length = 1000; #if __WIN32__ if (SDL_HapticGetEffectStatus(Haptics[index], id[index]) == SDL_TRUE) #else // Linux SDL doesn't support checking status at the moment :-( if (cfx_timeout[index] > SDL_GetTicks()) #endif SDL_HapticUpdateEffect(Haptics[index], id[index], &cfx[index]); else { SDL_HapticDestroyEffect(Haptics[index], id[index]); id[index] = SDL_HapticNewEffect(Haptics[index], &cfx[index]); SDL_HapticRunEffect(Haptics[index], id[index], 1); } cfx_timeout[index] = SDL_GetTicks() + cfx[index].constant.length; #endif } void gfctrlJoyRumble(int index, float level) { #if SDL_MAJOR_VERSION >= 2 if (!Haptics[index]) return; if (SDL_HapticRumbleSupported(Haptics[index]) != SDL_TRUE) return; // we have to stop the rumble before updating if (rfx_timeout[index] > SDL_GetTicks()) { if (SDL_HapticRumbleStop(Haptics[index]) != 0) GfLogError("Failed to stop rumble: %s\n", SDL_GetError() ); } if (SDL_HapticRumblePlay(Haptics[index], level, 100) != 0) GfLogError("Failed to play rumble: %s\n", SDL_GetError() ); rfx_timeout[index] = SDL_GetTicks() + 100; #endif } #endif // Shutdown time. void gfctrlJoyShutdown(void) { if (gfctrlJoyPresent != GFCTRL_JOY_UNTESTED) #ifndef SDL_JOYSTICK for (int index = 0; index < GFCTRL_JOY_NUMBER; index++) delete Joysticks[index]; #else for (int index = 0; index < gfctrlJoyPresent; index++) { SDL_JoystickClose(Joysticks[index]); Joysticks[index] = NULL; #if SDL_MAJOR_VERSION >= 2 if (Haptics[index]) { SDL_HapticClose(Haptics[index]); Haptics[index] = NULL; } #endif } #endif gfctrlJoyPresent = GFCTRL_JOY_UNTESTED; } /** Create the joystick control @ingroup ctrl @return pointer on a tCtrlJoyInfo structure <br>0 .. if no joystick present @note call GfctrlJoyRelease to free the tCtrlJoyInfo structure @see GfctrlJoyRelease @see tCtrlJoyInfo */ tCtrlJoyInfo * GfctrlJoyCreate(void) { if (gfctrlJoyPresent == GFCTRL_JOY_UNTESTED) gfctrlJoyInit(); tCtrlJoyInfo* joyInfo = (tCtrlJoyInfo *)calloc(1, sizeof(tCtrlJoyInfo)); #if SDL_JOYSTICK joyInfoCopy = joyInfo; #endif return joyInfo; } /** Release the tCtrlJoyInfo structure @ingroup ctrl @param joyInfo joystick structure @return none */ void GfctrlJoyRelease(tCtrlJoyInfo *joyInfo) { freez(joyInfo); }
void EventosJoysticks::processarEvento(const SDL_Event& evento) { Joystick* joy; switch(evento.type) { case SDL_JOYAXISMOTION: joy = identificarJoystick(evento.jaxis.which); if(joy) { switch(evento.jaxis.axis) { case SDL_CONTROLLER_AXIS_LEFTX: joy->x = evento.caxis.value/32767.0f; filtrarInput(joy->x, joy); break; case SDL_CONTROLLER_AXIS_LEFTY: joy->y = evento.caxis.value/32767.0f; filtrarInput(joy->y, joy); break; case SDL_CONTROLLER_AXIS_RIGHTX: joy->xDir = evento.caxis.value/32767.0f; filtrarInput(joy->xDir, joy); break; case SDL_CONTROLLER_AXIS_RIGHTY: joy->yDir = evento.caxis.value/32767.0f; filtrarInput(joy->yDir, joy); break; case SDL_CONTROLLER_AXIS_TRIGGERLEFT: joy->z = evento.caxis.value/32767.0f; filtrarInput(joy->z, joy); break; case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: joy->zDir = evento.caxis.value/32767.0f; filtrarInput(joy->zDir, joy); break; } } break; case SDL_CONTROLLERBUTTONDOWN: joy = identificarJoystick(evento.cbutton.which); if (joy) { joy->segurando[evento.cbutton.button] = true; if (evento.cbutton.state == SDL_PRESSED) { joy->pressionou[evento.cbutton.button] = true; } } break; case SDL_CONTROLLERBUTTONUP: joy = identificarJoystick(evento.cbutton.which); if (joy) { joy->segurando[evento.cbutton.button] = false; if (evento.cbutton.state == SDL_RELEASED) { joy->soltou[evento.cbutton.button] = true; } } break; case SDL_JOYBUTTONDOWN: joy = identificarJoystick(evento.jbutton.which); if(joy) { if (joy->eControle()) { // para aqui, pois controles são tratados separadamente break; } joy->segurando[evento.jbutton.button] = true; if(evento.jbutton.state == SDL_PRESSED) { joy->pressionou[evento.jbutton.button] = true; } } break; case SDL_JOYBUTTONUP: joy = identificarJoystick(evento.jbutton.which); if(joy) { if (joy->eControle()) { // para aqui, pois controles são tratados separadamente break; } joy->segurando[evento.jbutton.button] = false; if(evento.jbutton.state == SDL_RELEASED) { joy->soltou[evento.jbutton.button] = true; } } break; case SDL_JOYDEVICEADDED: joy = getPrimeiroJoystickLivre(); if(joy) { if (SDL_IsGameController(evento.jdevice.which)) { joy->sdl_controller = SDL_GameControllerOpen(evento.jdevice.which); joy->sdl_joystick = SDL_GameControllerGetJoystick(joy->sdl_controller); } else { joy->sdl_joystick = SDL_JoystickOpen(evento.jdevice.which); joy->sdl_controller = NULL; } joy->id = nextId; joy->sdl_haptic = SDL_HapticOpenFromJoystick(joy->sdl_joystick); if(joy->sdl_haptic) { if(SDL_HapticRumbleSupported(joy->sdl_haptic)) SDL_HapticRumbleInit(joy->sdl_haptic); } nextId++; } break; case SDL_JOYDEVICEREMOVED: joy = identificarJoystick(evento.jdevice.which); if(joy) { if(joy->sdl_haptic) { SDL_HapticClose(joy->sdl_haptic); joy->sdl_haptic = NULL; } if (joy->sdl_controller) { SDL_GameControllerClose(joy->sdl_controller); } else { SDL_JoystickClose(joy->sdl_joystick); } joy->sdl_controller = NULL; joy->sdl_joystick = NULL; joy->id = -1; } break; } }
/** * @brief The entry point of this force feedback demo. * @param[in] argc Number of arguments. * @param[in] argv Array of argc arguments. */ int main(int argc, char **argv) { int i; char *name; int index; SDL_HapticEffect efx[5]; int id[5]; int nefx; unsigned int supported; name = NULL; index = -1; if (argc > 1) { name = argv[1]; if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) { printf("USAGE: %s [device]\n" "If device is a two-digit number it'll use it as an index, otherwise\n" "it'll use it as if it were part of the device's name.\n", argv[0]); return 0; } i = strlen(name); if ((i < 3) && isdigit(name[0]) && ((i == 1) || isdigit(name[1]))) { index = atoi(name); name = NULL; } } /* Initialize the force feedbackness */ SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC); printf("%d Haptic devices detected.\n", SDL_NumHaptics()); if (SDL_NumHaptics() > 0) { /* We'll just use index or the first force feedback device found */ if (name == NULL) { i = (index != -1) ? index : 0; } /* Try to find matching device */ else { for (i = 0; i < SDL_NumHaptics(); i++) { if (strstr(SDL_HapticName(i), name) != NULL) break; } if (i >= SDL_NumHaptics()) { printf("Unable to find device matching '%s', aborting.\n", name); return 1; } } haptic = SDL_HapticOpen(i); if (haptic == NULL) { printf("Unable to create the haptic device: %s\n", SDL_GetError()); return 1; } printf("Device: %s\n", SDL_HapticName(i)); } else { printf("No Haptic devices found!\n"); return 1; } /* We only want force feedback errors. */ SDL_ClearError(); if (SDL_HapticRumbleSupported(haptic) == SDL_FALSE) { printf("\nRumble not supported!\n"); return 1; } if (SDL_HapticRumbleInit(haptic) != 0) { printf("\nFailed to initialize rumble: %s\n", SDL_GetError()); return 1; } printf("Playing 2 second rumble at 0.5 magnitude.\n"); if (SDL_HapticRumblePlay(haptic, 0.5, 5000) != 0) { printf("\nFailed to play rumble: %s\n", SDL_GetError() ); return 1; } SDL_Delay(2000); printf("Stopping rumble.\n"); SDL_HapticRumbleStop(haptic); SDL_Delay(2000); printf("Playing 2 second rumble at 0.3 magnitude.\n"); if (SDL_HapticRumblePlay(haptic, 0.3, 5000) != 0) { printf("\nFailed to play rumble: %s\n", SDL_GetError() ); return 1; } SDL_Delay(2000); /* Quit */ if (haptic != NULL) SDL_HapticClose(haptic); SDL_Quit(); return 0; }