Exemple #1
0
Fichier : spfx.c Projet : zid/naev
/**
 * @brief Initializes the rumble effect.
 *
 *    @return 0 on success.
 */
static int spfx_hapticInit (void)
{
#if SDL_VERSION_ATLEAST(1,3,0)
   SDL_HapticEffect *efx;

   /* Haptic must be enabled. */
   if (haptic == NULL)
      return 0;

   efx = &haptic_rumbleEffect;
   memset( efx, 0, sizeof(SDL_HapticEffect) );
   efx->type = SDL_HAPTIC_SINE;
   efx->periodic.direction.type   = SDL_HAPTIC_POLAR;
   efx->periodic.length           = 1000;
   efx->periodic.period           = 200;
   efx->periodic.magnitude        = 0x4000;
   efx->periodic.fade_length      = 1000;
   efx->periodic.fade_level       = 0;

   haptic_rumble = SDL_HapticNewEffect( haptic, efx );
   if (haptic_rumble < 0) {
      WARN("Unable to upload haptic effect: %s.", SDL_GetError());
      return -1;
   }
#endif /* SDL_VERSION_ATLEAST(1,3,0) */

   return 0;
}
Exemple #2
0
bool CSDLPad::SetForceFeedback(IFFParams params)
{
#if defined(SDL_USE_HAPTIC_FEEDBACK)
	if (!m_connected) return false;
	// only submit new one when current has finished
	if (m_supportsFeedback && m_curHapticEffect <0)
	{
		if ( params.strengthA == 0 || params.strengthB == 0)
			return true;
		
		SDL_HapticEffect effect;
		memset(&effect, 0, sizeof(effect));
		effect.type = SDL_HAPTIC_LEFTRIGHT;
		effect.leftright.large_magnitude  = (uint16)(clamp_tpl(params.strengthB,0.0f,1.0f) * 65536.0f);
		effect.leftright.small_magnitude  = (uint16)(clamp_tpl(params.strengthA,0.0f,1.0f) * 65536.0f);
		effect.leftright.length = (params.timeInSeconds == 0.0f) ? 1000 : (Uint32)(params.timeInSeconds * 1000.0f);
		
		
		m_curHapticEffect = SDL_HapticNewEffect(m_pHapticDevice, &effect);
		if (m_curHapticEffect < 0)
		{
			gEnv->pLog->LogError("CSDLPad - Gamepad [%d] failed to create feedback effect: %s", m_deviceNo, SDL_GetError());
			return false;
		}
		gEnv->pLog->Log("CSDLPad - Gamepad [%d] submitting create feedback effect (%d,%d,%d)", m_deviceNo, effect.leftright.large_magnitude, effect.leftright.small_magnitude, effect.leftright.length);
		SDL_HapticRunEffect(m_pHapticDevice, m_curHapticEffect, 1);
		m_vibrateTime=params.timeInSeconds;
	}
#endif
	return true;
}
Exemple #3
0
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);
}
Exemple #4
0
/*
 * Init haptic effects
 */
static int
IN_Haptic_Effect_Init(int effect_x, int effect_y, int effect_z, int period, int magnitude, int length, int attack, int fade)
{
	/*
	 * Direction:
	 * North - 0
	 * East - 9000
	 * South - 18000
	 * West - 27000
	 */
	int effect_id;
	static SDL_HapticEffect haptic_effect;
	SDL_memset(&haptic_effect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default
	haptic_effect.type = SDL_HAPTIC_SINE;
	haptic_effect.periodic.direction.type = SDL_HAPTIC_CARTESIAN; // Cartesian/3d coordinates
	haptic_effect.periodic.direction.dir[0] = effect_x;
	haptic_effect.periodic.direction.dir[1] = effect_y;
	haptic_effect.periodic.direction.dir[2] = effect_z;
	haptic_effect.periodic.period = period;
	haptic_effect.periodic.magnitude = magnitude;
	haptic_effect.periodic.length = length;
	haptic_effect.periodic.attack_length = attack;
	haptic_effect.periodic.fade_length = fade;
	effect_id = SDL_HapticNewEffect(joystick_haptic, &haptic_effect);
	if (effect_id < 0)
	{
		Com_Printf ("SDL_HapticNewEffect failed: %s\n", SDL_GetError());
		Com_Printf ("Please try to rerun game. Effects will be disabled for now.\n");
		IN_Haptic_Shutdown();
	}
	return effect_id;
}
Exemple #5
0
/*
 * Init haptic effects
 */
static int
IN_Haptic_Effect_Init(int dir, int period, int magnitude, int length, int attack, int fade)
{
	/*
	 * Direction:
	 * North - 0
	 * East - 9000
	 * South - 18000
	 * West - 27000
	 */
	int effect_id;
	static SDL_HapticEffect haptic_effect;
	SDL_memset(&haptic_effect, 0, sizeof(SDL_HapticEffect)); // 0 is safe default
	haptic_effect.type = SDL_HAPTIC_SINE;
	haptic_effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
	haptic_effect.periodic.direction.dir[0] = dir;
	haptic_effect.periodic.period = period;
	haptic_effect.periodic.magnitude = magnitude;
	haptic_effect.periodic.length = length;
	haptic_effect.periodic.attack_length = attack;
	haptic_effect.periodic.fade_length = fade;
	effect_id = SDL_HapticNewEffect(joystick_haptic, &haptic_effect);
	if (effect_id < 0)
	{
		Com_Printf ("SDL_HapticNewEffect failed: %s", SDL_GetError());
	}
	return effect_id;
}
Exemple #6
0
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;
}
Exemple #7
0
void JoystickInfo::InitHapticEffect()
{
#if SDL_MAJOR_VERSION >= 2
	if (haptic == NULL) return;

#if 0
	additional field of the effect
    /* Trigger */
    Uint16 button;      /**< Button that triggers the effect. */
    Uint16 interval;    /**< How soon it can be triggered again after button. */

	// periodic parameter
    Sint16 offset;      /**< Mean value of the wave. */
    Uint16 phase;       /**< Horizontal shift given by hundredth of a cycle. */
#endif

	/*******************************************************************/
	/* Effect big & small    										   */
	/*******************************************************************/
	for (int new_effect = 0; new_effect < 2 ; new_effect++) {

		// Direction of the effect SDL_HapticDirection
		haptic_effect_data[new_effect].periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
		haptic_effect_data[new_effect].periodic.direction.dir[0] = 18000; // Force comes from south

		// periodic parameter
		haptic_effect_data[new_effect].periodic.period = 20; // 20 ms
		haptic_effect_data[new_effect].periodic.magnitude = 2000; // 2000/32767 strength

		// Replay
		haptic_effect_data[new_effect].periodic.length = 60; // 60 ms long
		haptic_effect_data[new_effect].periodic.delay  = 0;	   // start 0 second after the upload

		// enveloppe
		haptic_effect_data[new_effect].periodic.attack_length = 5;// Takes 5 ms to get max strength
		haptic_effect_data[new_effect].periodic.attack_level = 0;   // start at 0
		haptic_effect_data[new_effect].periodic.fade_length = 5;	// Takes 5 ms to fade away
		haptic_effect_data[new_effect].periodic.fade_level = 0;    	// finish at 0
	}

	/*******************************************************************/
	/* Effect small													   */
	/*******************************************************************/
	haptic_effect_data[0].type = SDL_HAPTIC_LEFTRIGHT;

	/*******************************************************************/
	/* Effect big													   */
	/*******************************************************************/
	haptic_effect_data[1].type = SDL_HAPTIC_TRIANGLE;

	/*******************************************************************/
	/* Upload effect to the device									   */
	/*******************************************************************/
	for (int i = 0 ; i < 2 ; i++)
		haptic_effect_id[i] = SDL_HapticNewEffect(haptic, &haptic_effect_data[i]);
#endif
}
Exemple #8
0
void JoystickInfo::Rumble(int type, int pad)
{
    if (type > 1) return;
    if ( !(conf->pad_options[pad].forcefeedback) ) return;

#if SDL_MAJOR_VERSION >= 2
    if (haptic == NULL) return;

    if(first)
    {   // If done multiple times, device memory will be filled
        first = 0;
        GenerateDefaultEffect();
        /** Sine and triangle are quite probably the best, don't change that lightly and if you do
         *	keep effects ordered by type
         **/
        /** Effect for small motor **/
        /** Sine seems to be the only effect making little motor from DS3/4 react
         *	Intensity has pretty much no effect either(which is coherent with what is explain in hid_sony driver
         **/
        effects[0].type = SDL_HAPTIC_SINE;
        effects_id[0] = SDL_HapticNewEffect(haptic, &effects[0]);
        if(effects_id[0] < 0)
        {
            fprintf(stderr,"ERROR: Effect is not uploaded! %s, id is %d\n",SDL_GetError(),effects_id[0]);
        }

        /** Effect for big motor **/
        effects[1].type = SDL_HAPTIC_TRIANGLE;
        effects_id[1] = SDL_HapticNewEffect(haptic, &effects[1]);
        if(effects_id[1] < 0)
        {
            fprintf(stderr,"ERROR: Effect is not uploaded! %s, id is %d\n",SDL_GetError(),effects_id[1]);
        }
    }

    int id;
    id = effects_id[type];
    if(SDL_HapticRunEffect(haptic, id, 1) != 0)
    {
        fprintf(stderr,"ERROR: Effect is not working! %s, id is %d\n",SDL_GetError(),id);
    }
#endif
}
Exemple #9
0
JNIEXPORT jint JNICALL Java_at_wisch_joystick_FFJoystick_newEffectNative (JNIEnv *env, jclass, jint hapticDeviceIndex, jobject jEffect, jint effectType){
	SDL_HapticEffect *effect = getEffectFromJavaEffect(env, jEffect, effectType);
	int num = SDL_HapticNewEffect(ffjoysticks[hapticDeviceIndex], effect);
	if (num < 0) {
		throwException(env, SDL_GetError());
		return -21;
	}
	
	if (effect->type == SDL_HAPTIC_CUSTOM){ delete(effect->custom.data); }
	delete(effect);
	return num;
}
static bool sdl_joypad_set_rumble(unsigned pad, enum retro_rumble_effect effect, uint16_t strength)
{
   SDL_HapticEffect efx;
   sdl_joypad_t *joypad = (sdl_joypad_t*)&sdl_pads[pad];

   memset(&efx, 0, sizeof(efx));

   if (!joypad->joypad || !joypad->haptic)
      return false;

   efx.type             = SDL_HAPTIC_LEFTRIGHT;
   efx.leftright.type   = SDL_HAPTIC_LEFTRIGHT;
   efx.leftright.length = 5000;

   switch (effect)
   {
      case RETRO_RUMBLE_STRONG:
         efx.leftright.large_magnitude = strength;
         break;
      case RETRO_RUMBLE_WEAK:
         efx.leftright.small_magnitude = strength;
         break;
      default:
         return false;
   }

   if (joypad->rumble_effect == -1)
   {
      joypad->rumble_effect = SDL_HapticNewEffect(sdl_pads[pad].haptic, &efx);
      if (joypad->rumble_effect < 0)
      {
         RARCH_WARN("[SDL]: Failed to create rumble effect for joypad %u: %s\n",
                    pad, SDL_GetError());
         joypad->rumble_effect = -2;
         return false;
      }
   }
   else if (joypad->rumble_effect >= 0)
      SDL_HapticUpdateEffect(joypad->haptic, joypad->rumble_effect, &efx);

   if (joypad->rumble_effect < 0)
      return false;

   if (SDL_HapticRunEffect(joypad->haptic, joypad->rumble_effect, 1) < 0)
   {
      RARCH_WARN("[SDL]: Failed to set rumble effect on joypad %u: %s\n",
                          pad, SDL_GetError());
      return false;
   }

   return true;
}
Exemple #11
0
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);
	}
}
/*
 * Initializes the haptic device for simple rumble playback.
 */
int
SDL_HapticRumbleInit(SDL_Haptic * haptic)
{
    if (!ValidHaptic(haptic)) {
        return -1;
    }

    /* Already allocated. */
    if (haptic->rumble_id >= 0) {
        return 0;
    }

    /* Copy over. */
    SDL_HapticRumbleCreate(&haptic->rumble_effect);
    haptic->rumble_id = SDL_HapticNewEffect(haptic, &haptic->rumble_effect);
    if (haptic->rumble_id >= 0) {
        return 0;
    }
    return -1;
}
Exemple #13
0
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;
}
Exemple #14
0
/*
 * Initializes the haptic device for simple rumble playback.
 */
int
SDL_HapticRumbleInit(SDL_Haptic * haptic)
{
    SDL_HapticEffect *efx = &haptic->rumble_effect;

    if (!ValidHaptic(haptic)) {
        return -1;
    }

    /* Already allocated. */
    if (haptic->rumble_id >= 0) {
        return 0;
    }

    SDL_zerop(efx);
    if (haptic->supported & SDL_HAPTIC_SINE) {
        efx->type = SDL_HAPTIC_SINE;
        efx->periodic.period = 1000;
        efx->periodic.magnitude = 0x4000;
        efx->periodic.length = 5000;
        efx->periodic.attack_length = 0;
        efx->periodic.fade_length = 0;
    } else if (haptic->supported & SDL_HAPTIC_LEFTRIGHT) {  /* XInput? */
        efx->type = SDL_HAPTIC_LEFTRIGHT;
        efx->leftright.length = 5000;
        efx->leftright.large_magnitude = 0x4000;
        efx->leftright.small_magnitude = 0x4000;
    } else {
        return SDL_SetError("Device doesn't support rumble");
    }

    haptic->rumble_id = SDL_HapticNewEffect(haptic, &haptic->rumble_effect);
    if (haptic->rumble_id >= 0) {
        return 0;
    }
    return -1;
}
Exemple #15
0
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;
}
Exemple #16
0
/**
 * @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[9];
    int id[9];
    int nefx;
    unsigned int supported;

    /* Enable standard application logging */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    name = NULL;
    index = -1;
    if (argc > 1) {
        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;
        }

        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);
    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));
        HapticPrintSupported(haptic);
    } else {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n");
        return 1;
    }

    /* We only want force feedback errors. */
    SDL_ClearError();

    /* Create effects. */
    memset(&efx, 0, sizeof(efx));
    nefx = 0;
    supported = SDL_HapticQuery(haptic);

    SDL_Log("\nUploading effects\n");
    /* First we'll try a SINE effect. */
    if (supported & SDL_HAPTIC_SINE) {
        SDL_Log("   effect %d: Sine Wave\n", nefx);
        efx[nefx].type = SDL_HAPTIC_SINE;
        efx[nefx].periodic.period = 1000;
        efx[nefx].periodic.magnitude = -0x2000;    /* Negative magnitude and ...                      */
        efx[nefx].periodic.phase = 18000;          /* ... 180 degrees phase shift => cancel eachother */
        efx[nefx].periodic.length = 5000;
        efx[nefx].periodic.attack_length = 1000;
        efx[nefx].periodic.fade_length = 1000;
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    /* Now we'll try a SAWTOOTHUP */
    if (supported & SDL_HAPTIC_SAWTOOTHUP) {
        SDL_Log("   effect %d: Sawtooth Up\n", nefx);
        efx[nefx].type = SDL_HAPTIC_SAWTOOTHUP;
        efx[nefx].periodic.period = 500;
        efx[nefx].periodic.magnitude = 0x5000;
        efx[nefx].periodic.length = 5000;
        efx[nefx].periodic.attack_length = 1000;
        efx[nefx].periodic.fade_length = 1000;
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    
    /* Now the classical constant effect. */
    if (supported & SDL_HAPTIC_CONSTANT) {
        SDL_Log("   effect %d: Constant Force\n", nefx);
        efx[nefx].type = SDL_HAPTIC_CONSTANT;
        efx[nefx].constant.direction.type = SDL_HAPTIC_POLAR;
        efx[nefx].constant.direction.dir[0] = 20000;    /* Force comes from the south-west. */
        efx[nefx].constant.length = 5000;
        efx[nefx].constant.level = 0x6000;
        efx[nefx].constant.attack_length = 1000;
        efx[nefx].constant.fade_length = 1000;
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    
    /* The cute spring effect. */
    if (supported & SDL_HAPTIC_SPRING) {
        SDL_Log("   effect %d: Condition Spring\n", nefx);
        efx[nefx].type = SDL_HAPTIC_SPRING;
        efx[nefx].condition.length = 5000;
        for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
            efx[nefx].condition.right_sat[i] = 0xFFFF;
            efx[nefx].condition.left_sat[i] = 0xFFFF;
            efx[nefx].condition.right_coeff[i] = 0x2000;
            efx[nefx].condition.left_coeff[i] = 0x2000;
            efx[nefx].condition.center[i] = 0x1000;     /* Displace the center for it to move. */
        }
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    /* The interesting damper effect. */
    if (supported & SDL_HAPTIC_DAMPER) {
        SDL_Log("   effect %d: Condition Damper\n", nefx);
        efx[nefx].type = SDL_HAPTIC_DAMPER;
        efx[nefx].condition.length = 5000;
        for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
            efx[nefx].condition.right_sat[i] = 0xFFFF;
            efx[nefx].condition.left_sat[i] = 0xFFFF;
            efx[nefx].condition.right_coeff[i] = 0x2000;
            efx[nefx].condition.left_coeff[i] = 0x2000;
        }
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    /* The pretty awesome inertia effect. */
    if (supported & SDL_HAPTIC_INERTIA) {
        SDL_Log("   effect %d: Condition Inertia\n", nefx);
        efx[nefx].type = SDL_HAPTIC_INERTIA;
        efx[nefx].condition.length = 5000;
        for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
            efx[nefx].condition.right_sat[i] = 0xFFFF;
            efx[nefx].condition.left_sat[i] = 0xFFFF;
            efx[nefx].condition.right_coeff[i] = 0x2000;
            efx[nefx].condition.left_coeff[i] = 0x2000;
            efx[nefx].condition.deadband[i] = 0x1000;    /* 1/16th of axis-range around the center is 'dead'. */
        }
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    /* The hot friction effect. */
    if (supported & SDL_HAPTIC_FRICTION) {
        SDL_Log("   effect %d: Condition Friction\n", nefx);
        efx[nefx].type = SDL_HAPTIC_FRICTION;
        efx[nefx].condition.length = 5000;
        for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
            efx[nefx].condition.right_sat[i] = 0xFFFF;
            efx[nefx].condition.left_sat[i] = 0xFFFF;
            efx[nefx].condition.right_coeff[i] = 0x2000;
            efx[nefx].condition.left_coeff[i] = 0x2000;
        }
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    
    /* Now we'll try a ramp effect */
    if (supported & SDL_HAPTIC_RAMP) {
        SDL_Log("   effect %d: Ramp\n", nefx);
        efx[nefx].type = SDL_HAPTIC_RAMP;
        efx[nefx].ramp.direction.type = SDL_HAPTIC_CARTESIAN;
        efx[nefx].ramp.direction.dir[0] = 1;     /* Force comes from                 */
        efx[nefx].ramp.direction.dir[1] = -1;    /*                  the north-east. */
        efx[nefx].ramp.length = 5000;
        efx[nefx].ramp.start = 0x4000;
        efx[nefx].ramp.end = -0x4000;
        efx[nefx].ramp.attack_length = 1000;
        efx[nefx].ramp.fade_length = 1000;
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }

    /* Finally we'll try a left/right effect. */
    if (supported & SDL_HAPTIC_LEFTRIGHT) {
        SDL_Log("   effect %d: Left/Right\n", nefx);
        efx[nefx].type = SDL_HAPTIC_LEFTRIGHT;
        efx[nefx].leftright.length = 5000;
        efx[nefx].leftright.large_magnitude = 0x3000;
        efx[nefx].leftright.small_magnitude = 0xFFFF;
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }


    SDL_Log
        ("\nNow playing effects for 5 seconds each with 1 second delay between\n");
    for (i = 0; i < nefx; i++) {
        SDL_Log("   Playing effect %d\n", i);
        SDL_HapticRunEffect(haptic, id[i], 1);
        SDL_Delay(6000);        /* Effects only have length 5000 */
    }

    /* Quit */
    if (haptic != NULL)
        SDL_HapticClose(haptic);
    SDL_Quit();

    return 0;
}
Exemple #17
0
// 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);
}
bool Application::OnInit() {
    if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
        return false;
    }

    // Set up graphics

    SDL_Window *screen = SDL_CreateWindow("Psychokinesis",
                          SDL_WINDOWPOS_UNDEFINED,
                          SDL_WINDOWPOS_UNDEFINED,
                          screenw, screenh,
                          SDL_WINDOW_OPENGL);
    if(screen == NULL) {
        Logger::log("SDL_CreateWindow failure");
        return false;
    }

    if((graphics.renderer = SDL_CreateRenderer(screen, -1, 0)) == NULL) {
        Logger::log("SDL_CreateRenderer failure");
        return false;
    }

    graphics.camera = new Camera();
    entities.push_back(new Entity(new CameraControl(graphics.camera),
                                  new NullPhysicsComponent(),
                                  new NullRenderComponent()));

    // Set up joystick controls

    std::stringstream ss;
    ss << SDL_NumJoysticks() << " joysticks were found";
    Logger::log(ss.str());

    SDL_JoystickEventState(SDL_ENABLE);
    joystick = SDL_JoystickOpen(0);

    // Set up rumble effects

    haptic = SDL_HapticOpen( 0 );
    if (haptic == NULL) {
        Logger::log("SDL_HapticOpen failure");
    }

    if (haptic != NULL && SDL_HapticRumbleInit( haptic ) != 0) {
        Logger::log("SDL_HapticRumbleInit failure: " +
                    std::string(SDL_GetError()));
        haptic = NULL;
    }

    SDL_HapticEffect effect;
    memset(&effect, 0, sizeof(SDL_HapticEffect));
    effect.type = SDL_HAPTIC_SINE;
    effect.periodic.direction.type = SDL_HAPTIC_POLAR; // Polar coordinates
    effect.periodic.direction.dir[0] = 18000; // Force comes from south
    effect.periodic.period = 1000; // 1000 ms
    effect.periodic.magnitude = 20000; // 20000/32767 strength
    effect.periodic.length = 1000; // .1 seconds long
    effect.periodic.attack_length = 0; // Takes 0 seconds to get max strength
    effect.periodic.fade_length = 0; // Takes 0 seconds to fade away

    effect_id = SDL_HapticNewEffect(haptic, &effect);


    Logger::log("Creating player");

    Create(Entity::PLAYER, 4, 20);

    // Test blocks to shove around

    // Create(Entity::LITTLE_MAN, 26, 25);
    // Create(Entity::LITTLE_MAN, 21, 25);
    // Create(Entity::BIG_MAN, 17, 25);
    // Create(Entity::LITTLE_MAN, 26, 20);
    // Create(Entity::LITTLE_MAN, 11, 20);
    // Create(Entity::LITTLE_MAN, 7, 20);
    // Create(Entity::LITTLE_MAN, 26, 35);
    Create(Entity::LITTLE_MAN, 21, 35);
    Create(Entity::BIG_MAN, 17, 35);
    Create(Entity::LITTLE_MAN, 26, 30);
    Create(Entity::LITTLE_MAN, 11, 30);
    Create(Entity::LITTLE_MAN, 7, 30);
 
    /// \todo Make the bullet factory manage its own list

    entities.push_back(Bullet::Create(&Level::p_level->world, graphics,
                                      20, 30, 20, 0));


    mainhud.Hud_Load_Hit_Pts_Texture("art_assets/hit_pts_meter.png",
                                     graphics.renderer,
                                     Player::player->hit_pts);

    if(level.LoadAssets(graphics.renderer, "art_assets/sky2.png",
                        "art_assets/lanscape.png") == NULL) {
        Logger::log("Level loading failure: " + std::string(SDL_GetError()));
    }

    Level::p_level->world.SetContactListener(&contactListen);

    oldtime = SDL_GetTicks();
    return true;
}
Exemple #19
0
/**
 * @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));
        HapticPrintSupported(haptic);
    } else {
        printf("No Haptic devices found!\n");
        return 1;
    }

    /* We only want force feedback errors. */
    SDL_ClearError();

    /* Create effects. */
    memset(&efx, 0, sizeof(efx));
    nefx = 0;
    supported = SDL_HapticQuery(haptic);

    printf("\nUploading effects\n");
    /* First we'll try a SINE effect. */
    if (supported & SDL_HAPTIC_SINE) {
        printf("   effect %d: Sine Wave\n", nefx);
        efx[nefx].type = SDL_HAPTIC_SINE;
        efx[nefx].periodic.period = 1000;
        efx[nefx].periodic.magnitude = 0x4000;
        efx[nefx].periodic.length = 5000;
        efx[nefx].periodic.attack_length = 1000;
        efx[nefx].periodic.fade_length = 1000;
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    /* Now we'll try a SAWTOOTHUP */
    if (supported & SDL_HAPTIC_SAWTOOTHUP) {
        printf("   effect %d: Sawtooth Up\n", nefx);
        efx[nefx].type = SDL_HAPTIC_SQUARE;
        efx[nefx].periodic.period = 500;
        efx[nefx].periodic.magnitude = 0x5000;
        efx[nefx].periodic.length = 5000;
        efx[nefx].periodic.attack_length = 1000;
        efx[nefx].periodic.fade_length = 1000;
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    /* Now the classical constant effect. */
    if (supported & SDL_HAPTIC_CONSTANT) {
        printf("   effect %d: Constant Force\n", nefx);
        efx[nefx].type = SDL_HAPTIC_CONSTANT;
        efx[nefx].constant.direction.type = SDL_HAPTIC_POLAR;
        efx[nefx].constant.direction.dir[0] = 20000;    /* Force comes from the south-west. */
        efx[nefx].constant.length = 5000;
        efx[nefx].constant.level = 0x6000;
        efx[nefx].constant.attack_length = 1000;
        efx[nefx].constant.fade_length = 1000;
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    /* The cute spring effect. */
    if (supported & SDL_HAPTIC_SPRING) {
        printf("   effect %d: Condition Spring\n", nefx);
        efx[nefx].type = SDL_HAPTIC_SPRING;
        efx[nefx].condition.length = 5000;
        for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
            efx[nefx].condition.right_sat[i] = 0x7FFF;
            efx[nefx].condition.left_sat[i] = 0x7FFF;
            efx[nefx].condition.right_coeff[i] = 0x2000;
            efx[nefx].condition.left_coeff[i] = 0x2000;
            efx[nefx].condition.center[i] = 0x1000;     /* Displace the center for it to move. */
        }
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }
    /* The pretty awesome inertia effect. */
    if (supported & SDL_HAPTIC_INERTIA) {
        printf("   effect %d: Condition Inertia\n", nefx);
        efx[nefx].type = SDL_HAPTIC_SPRING;
        efx[nefx].condition.length = 5000;
        for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
            efx[nefx].condition.right_sat[i] = 0x7FFF;
            efx[nefx].condition.left_sat[i] = 0x7FFF;
            efx[nefx].condition.right_coeff[i] = 0x2000;
            efx[nefx].condition.left_coeff[i] = 0x2000;
        }
        id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
        if (id[nefx] < 0) {
            printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
            abort_execution();
        }
        nefx++;
    }

    printf
        ("\nNow playing effects for 5 seconds each with 1 second delay between\n");
    for (i = 0; i < nefx; i++) {
        printf("   Playing effect %d\n", i);
        SDL_HapticRunEffect(haptic, id[i], 1);
        SDL_Delay(6000);        /* Effects only have length 5000 */
    }

    /* Quit */
    if (haptic != NULL)
        SDL_HapticClose(haptic);
    SDL_Quit();

    return 0;
}
Exemple #20
0
bool SDL2FFBDevice::uploadEffect(const int idx, const FFBEffectTypes type, std::shared_ptr<FFBEffectParameters> parameters)
{
  SDL_HapticEffect* underlEff;
  int intIdx;
  std::shared_ptr<FFBEffect> effect = SDL2FFBEffectFactory::createEffect(type);
  std::shared_ptr<SDL2FFBEffect> sdlEff;

  CHECK_EFFECT_IDX(idx);

  if (type != FFBEffectTypes::NONE)
    sdlEff = std::static_pointer_cast<SDL2FFBEffect>(effect);
  else
    return false;

  if (sdlEff == nullptr)
    return false;

  if (!sdlEff->setParameters(parameters))
    return false;

  /* There is no effect in the selected slot */
  if (m_effects[idx]->type() != FFBEffectTypes::NONE) {
    /* Effects are not of the same type, delete the previous effect and create a new one */
    if (*m_effects[idx] != *sdlEff) {
      if (!removeEffect(idx)) {
        return false;
      }
    } else {
      /* Effects are of the same type, update it */

      underlEff = sdlEff->createFFstruct();
      if (underlEff == nullptr)
        return false;

      intIdx = SDL_HapticUpdateEffect(c_haptic, std::static_pointer_cast<SDL2FFBEffect>(m_effects[idx])->internalIdx(), underlEff);
      if (intIdx < 0) {
        QMessageBox::critical(nullptr, SDL2DEV_ERR_CAPTION, QString("Unable to update the effect:\n%1").arg(SDL_GetError()));
        m_effects[idx]->setStatus(FFBEffect::FFBEffectStatus::UPLOADED);
        return true;
      }
      sdlEff->setStatus(m_effects[idx]->status());

      goto out;
    }
  }

  underlEff = sdlEff->createFFstruct();
  if (underlEff == nullptr)
    return false;

  intIdx = SDL_HapticNewEffect(c_haptic, underlEff);
  if (intIdx < 0) {
    QMessageBox::critical(nullptr, SDL2DEV_ERR_CAPTION, QString("Unable to create effect:\n%1").arg(SDL_GetError()));
    return false;
  }
  sdlEff->setStatus(FFBEffect::FFBEffectStatus::UPLOADED);

out:
  sdlEff->setInternalIdx(intIdx);
  delete underlEff;
  m_effects[idx] = sdlEff;

  return true;
}
Exemple #21
0
ForceFeedback::ForceFeedback(
	const std::string & device,
	std::ostream & error_output,
	std::ostream & info_output) :
	device_name(device),
	enabled(true),
	lastforce(0),
	haptic(0),
	effect_id(-1)
{
	// Close haptic if already open.
	if (haptic)
	{
		SDL_HapticClose(haptic);
		haptic = NULL;
	}

	// Do we have force feedback devices?
	int haptic_num = SDL_NumHaptics();
	if (haptic_num == 0)
	{
		info_output << "No force feedback devices found." << std::endl;
		return;
	}
	info_output << "Number of force feedback devices: " << haptic_num << std::endl;

	// Try to create haptic device.
	int haptic_id = 0;
	haptic = SDL_HapticOpen(haptic_id);
	if (!haptic)
	{
		error_output << "Failed to initialize force feedback device: " << SDL_GetError();
		return;
	}

	// Check for constant force support.
	unsigned int haptic_query = SDL_HapticQuery(haptic);
	if (!(haptic_query & SDL_HAPTIC_CONSTANT))
	{
		error_output << "Constant force feedback not supported: " << SDL_GetError();
		return;
	}

	// Create the effect.
	memset(&effect, 0, sizeof(SDL_HapticEffect) ); // 0 is safe default
	effect.type = SDL_HAPTIC_CONSTANT;
	effect.constant.direction.type = SDL_HAPTIC_CARTESIAN; // Using cartesian direction encoding.
	effect.constant.direction.dir[0] = 1; // X position
	effect.constant.direction.dir[1] = 0; // Y position
	effect.constant.length = 0xffff;
	effect.constant.delay = 0;
	effect.constant.button = 0;
	effect.constant.interval = 0;
	effect.constant.level = 0;
	effect.constant.attack_length = 0;
	effect.constant.attack_level = 0;
	effect.constant.fade_length = 0;
	effect.constant.fade_level = 0;

	// Upload the effect.
	effect_id = SDL_HapticNewEffect(haptic, &effect);
	if (effect_id == -1)
	{
		error_output << "Failed to initialize force feedback effect: " << SDL_GetError();
		return;
	}

	info_output << "Force feedback enabled." << std::endl;
}
bool SdlRumbleEffect::load()
{
   mId = SDL_HapticNewEffect(mHaptic, &mEffect);
   return isActive();
}