void SdlManager::SdlController::RunHapticLeftRight(float left, float right) { CriticalCode criticalCode(criticalSection); if(!haptic) return; hapticEffect.leftright.length = SDL_HAPTIC_INFINITY; hapticEffect.leftright.large_magnitude = uint16_t(left * 0xffff); hapticEffect.leftright.small_magnitude = uint16_t(right * 0xffff); if(hapticEffectIndex >= 0 && hapticEffect.type == SDL_HAPTIC_LEFTRIGHT) { SDL_HapticStopEffect(haptic, hapticEffectIndex); SDL_HapticUpdateEffect(haptic, hapticEffectIndex, &hapticEffect); } else { if(hapticEffectIndex >= 0) { SDL_HapticStopEffect(haptic, hapticEffectIndex); SDL_HapticDestroyEffect(haptic, hapticEffectIndex); } hapticEffect.type = SDL_HAPTIC_LEFTRIGHT; hapticEffectIndex = SDL_HapticNewEffect(haptic, &hapticEffect); } SDL_HapticRunEffect(haptic, hapticEffectIndex, 1); }
bool Joystick::UpdateOutput() { #ifdef USE_SDL_HAPTIC std::list<EffectIDState>::iterator i = m_state_out.begin(), e = m_state_out.end(); for ( ; i != e; ++i) { if (i->changed) // if SetState was called on this output { if (-1 == i->id) // effect isn't currently uploaded { if (i->effect.type) // if outputstate is >0 this would be true if ((i->id = SDL_HapticNewEffect( m_haptic, &i->effect )) > -1) // upload the effect SDL_HapticRunEffect(m_haptic, i->id, 1); // run the effect } else // effect is already uploaded { if (i->effect.type) // if ouputstate >0 SDL_HapticUpdateEffect(m_haptic, i->id, &i->effect); // update the effect else { SDL_HapticStopEffect(m_haptic, i->id); // else, stop and remove the effect SDL_HapticDestroyEffect(m_haptic, i->id); i->id = -1; // mark it as not uploaded } } i->changed = false; } } #endif return true; }
void destructor(State & state, HapticEffect_pack * hapticEffect){ if (hapticEffect->effect.type == SDL_HAPTIC_CUSTOM && hapticEffect->effect.custom.data){ SDL_free(hapticEffect->effect.custom.data); } if (hapticEffect->id >= 0 && hapticEffect->haptic){ SDL_HapticDestroyEffect(hapticEffect->haptic, hapticEffect->id); } delete hapticEffect; }
/* * Shuts the backend down */ static void IN_Haptic_Effect_Shutdown(int * effect_id) { if (!effect_id) return; if (*effect_id >= 0) SDL_HapticDestroyEffect(joystick_haptic, *effect_id); *effect_id = -1; }
bool SdlRumbleEffect::unload() { if (isActive()) { SDL_HapticDestroyEffect(mHaptic, mId); mId = -1; return true; } return false; }
void CSDLPad::Update(bool bFocus) { if (m_supportsFeedback && m_vibrateTime>0.0f) { m_vibrateTime-=gEnv->pTimer->GetFrameTime(); if (m_vibrateTime<=0.0f) { SDL_HapticDestroyEffect(m_pHapticDevice, m_curHapticEffect); m_curHapticEffect = -1; } } }
/* * Closes a SDL_Haptic device. */ void SDL_HapticClose(SDL_Haptic * haptic) { int i; SDL_Haptic *hapticlist; SDL_Haptic *hapticlistprev; /* Must be valid */ if (!ValidHaptic(haptic)) { return; } /* Check if it's still in use */ if (--haptic->ref_count < 0) { return; } /* Close it, properly removing effects if needed */ for (i = 0; i < haptic->neffects; i++) { if (haptic->effects[i].hweffect != NULL) { SDL_HapticDestroyEffect(haptic, i); } } SDL_SYS_HapticClose(haptic); /* Remove from the list */ hapticlist = SDL_haptics; hapticlistprev = NULL; while ( hapticlist ) { if (haptic == hapticlist) { if ( hapticlistprev ) { /* unlink this entry */ hapticlistprev->next = hapticlist->next; } else { SDL_haptics = haptic->next; } break; } hapticlistprev = hapticlist; hapticlist = hapticlist->next; } /* Free */ SDL_free(haptic); }
bool SDL2FFBDevice::removeEffect(const int idx) { std::shared_ptr<SDL2FFBEffect> sdlEff; CHECK_EFFECT_IDX(idx); if (!stopEffect(idx)) return false; if (m_effects[idx]->type() == FFBEffectTypes::NONE) return true; sdlEff = std::static_pointer_cast<SDL2FFBEffect>(m_effects[idx]); SDL_HapticDestroyEffect(c_haptic, sdlEff->internalIdx()); return true; }
void Joystick::HapticEffect::Update() { if (m_id == -1 && m_effect.type > 0) { m_id = SDL_HapticNewEffect(m_haptic, &m_effect); if (m_id > -1) SDL_HapticRunEffect(m_haptic, m_id, 1); } else if (m_id > -1 && m_effect.type == 0) { SDL_HapticStopEffect(m_haptic, m_id); SDL_HapticDestroyEffect(m_haptic, m_id); m_id = -1; } else if (m_id > -1) { SDL_HapticUpdateEffect(m_haptic, m_id, &m_effect); } }
Joystick::~Joystick() { #ifdef USE_SDL_HAPTIC if (m_haptic) { // stop/destroy all effects SDL_HapticStopAll(m_haptic); std::list<EffectIDState>::iterator i = m_state_out.begin(), e = m_state_out.end(); for ( ; i != e; ++i) if (i->id != -1) SDL_HapticDestroyEffect(m_haptic, i->id); // close haptic first SDL_HapticClose(m_haptic); } #endif // close joystick SDL_JoystickClose(m_joystick); }
Joystick::~Joystick() { #ifdef USE_SDL_HAPTIC if (m_haptic) { // stop/destroy all effects SDL_HapticStopAll(m_haptic); for (auto &i : m_state_out) { if (i.id != -1) { SDL_HapticDestroyEffect(m_haptic, i.id); } } // close haptic first SDL_HapticClose(m_haptic); } #endif // close joystick SDL_JoystickClose(m_joystick); }
bool Joystick::runVibrationEffect() { if (vibration.id != -1) { if (SDL_HapticUpdateEffect(haptic, vibration.id, &vibration.effect) == 0) { if (SDL_HapticRunEffect(haptic, vibration.id, 1) == 0) return true; } // If the effect fails to update, we should destroy and re-create it. SDL_HapticDestroyEffect(haptic, vibration.id); vibration.id = -1; } vibration.id = SDL_HapticNewEffect(haptic, &vibration.effect); if (vibration.id != -1 && SDL_HapticRunEffect(haptic, vibration.id, 1) == 0) return true; return false; }
void SdlManager::SdlController::Close() { CriticalCode criticalCode(criticalSection); if(hapticEffectIndex >= 0) { SDL_HapticStopEffect(haptic, hapticEffectIndex); SDL_HapticDestroyEffect(haptic, hapticEffectIndex); hapticEffectIndex = -1; } if(haptic) { SDL_HapticClose(haptic); haptic = nullptr; } if(controller) { SDL_GameControllerClose(controller); controller = nullptr; } }
bool Joystick::UpdateOutput() { #ifdef USE_SDL_HAPTIC for (auto &i : m_state_out) { if (i.changed) // if SetState was called on this output { if (-1 == i.id) // effect isn't currently uploaded { if (i.effect.type) // if outputstate is >0 this would be true { if ((i.id = SDL_HapticNewEffect(m_haptic, &i.effect)) > -1) // upload the effect { SDL_HapticRunEffect(m_haptic, i.id, 1); // run the effect } } } else // effect is already uploaded { if (i.effect.type) // if ouputstate >0 { SDL_HapticUpdateEffect(m_haptic, i.id, &i.effect); // update the effect } else { SDL_HapticStopEffect(m_haptic, i.id); // else, stop and remove the effect SDL_HapticDestroyEffect(m_haptic, i.id); i.id = -1; // mark it as not uploaded } } i.changed = false; } } #endif return true; }
/* * Closes a SDL_Haptic device. */ void SDL_HapticClose(SDL_Haptic * haptic) { int i; /* Must be valid */ if (!ValidHaptic(haptic)) { return; } /* Check if it's still in use */ if (--haptic->ref_count < 0) { return; } /* Close it, properly removing effects if needed */ for (i = 0; i < haptic->neffects; i++) { if (haptic->effects[i].hweffect != NULL) { SDL_HapticDestroyEffect(haptic, i); } } SDL_SYS_HapticClose(haptic); /* Remove from the list */ for (i = 0; SDL_haptics[i]; ++i) { if (haptic == SDL_haptics[i]) { SDL_haptics[i] = NULL; SDL_memcpy(&SDL_haptics[i], &SDL_haptics[i + 1], (SDL_numhaptics - i) * sizeof(haptic)); break; } } /* Free */ SDL_free(haptic); }
// 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); }
JNIEXPORT void JNICALL Java_at_wisch_joystick_FFJoystick_destroyAllNative (JNIEnv *env, jclass, jint hapticDeviceIndex) { for (int i = SDL_HapticNumEffects(ffjoysticks[hapticDeviceIndex]); i >= 0; i--) { SDL_HapticDestroyEffect(ffjoysticks[hapticDeviceIndex], i); } }
JNIEXPORT void JNICALL Java_at_wisch_joystick_FFJoystick_destroyEffectNative (JNIEnv *env, jclass, jint hapticDeviceIndex, jint effectIndex) { SDL_HapticDestroyEffect(ffjoysticks[hapticDeviceIndex], effectIndex); }