Add periodic effects for haptic devices.

This adds support for drivers supporting sine, square and triangle
periodic haptic effects. This allows rumble to work on devices/drivers
supporting these effects, such as an xbox controller using the xpad
driver under Linux.
This commit is contained in:
Scott Moreau 2012-07-11 14:48:15 -06:00
parent 80c15f21b4
commit d34418100b
2 changed files with 127 additions and 1 deletions

View file

@ -113,6 +113,27 @@ Joystick::Joystick(SDL_Joystick* const joystick, const int sdl_index, const unsi
m_state_out.push_back(EffectIDState());
AddOutput(new RampEffect(m_state_out.back()));
}
// sine effect
if (supported_effects & SDL_HAPTIC_SINE)
{
m_state_out.push_back(EffectIDState());
AddOutput(new SineEffect(m_state_out.back()));
}
// square effect
if (supported_effects & SDL_HAPTIC_SQUARE)
{
m_state_out.push_back(EffectIDState());
AddOutput(new SquareEffect(m_state_out.back()));
}
// triangle effect
if (supported_effects & SDL_HAPTIC_TRIANGLE)
{
m_state_out.push_back(EffectIDState());
AddOutput(new TriangleEffect(m_state_out.back()));
}
}
#endif
@ -151,6 +172,21 @@ std::string Joystick::RampEffect::GetName() const
return "Ramp";
}
std::string Joystick::SineEffect::GetName() const
{
return "Sine";
}
std::string Joystick::SquareEffect::GetName() const
{
return "Square";
}
std::string Joystick::TriangleEffect::GetName() const
{
return "Triangle";
}
void Joystick::ConstantEffect::SetState(const ControlState state)
{
if (state)
@ -176,12 +212,72 @@ void Joystick::RampEffect::SetState(const ControlState state)
}
else
m_effect.effect.type = 0;
const Sint16 old = m_effect.effect.ramp.start;
m_effect.effect.ramp.start = state * 0x7FFF;
if (old != m_effect.effect.ramp.start)
m_effect.changed = true;
}
void Joystick::SineEffect::SetState(const ControlState state)
{
if (state)
{
m_effect.effect.type = SDL_HAPTIC_SINE;
m_effect.effect.periodic.length = 250;
}
else {
m_effect.effect.type = 0;
}
const Sint16 old = m_effect.effect.periodic.magnitude;
m_effect.effect.periodic.period = 5;
m_effect.effect.periodic.magnitude = state * 0x5000;
m_effect.effect.periodic.attack_length = 0;
m_effect.effect.periodic.fade_length = 500;
if (old != m_effect.effect.periodic.magnitude)
m_effect.changed = true;
}
void Joystick::SquareEffect::SetState(const ControlState state)
{
if (state)
{
m_effect.effect.type = SDL_HAPTIC_SQUARE;
m_effect.effect.periodic.length = 250;
}
else {
m_effect.effect.type = 0;
}
const Sint16 old = m_effect.effect.periodic.magnitude;
m_effect.effect.periodic.period = 5;
m_effect.effect.periodic.magnitude = state * 0x5000;
m_effect.effect.periodic.attack_length = 0;
m_effect.effect.periodic.fade_length = 100;
if (old != m_effect.effect.periodic.magnitude)
m_effect.changed = true;
}
void Joystick::TriangleEffect::SetState(const ControlState state)
{
if (state)
{
m_effect.effect.type = SDL_HAPTIC_TRIANGLE;
m_effect.effect.periodic.length = 250;
}
else {
m_effect.effect.type = 0;
}
const Sint16 old = m_effect.effect.periodic.magnitude;
m_effect.effect.periodic.period = 5;
m_effect.effect.periodic.magnitude = state * 0x5000;
m_effect.effect.periodic.attack_length = 0;
m_effect.effect.periodic.fade_length = 100;
if (old != m_effect.effect.periodic.magnitude)
m_effect.changed = true;
}
#endif
bool Joystick::UpdateInput()

View file

@ -95,6 +95,36 @@ private:
private:
EffectIDState& m_effect;
};
class SineEffect : public Output
{
public:
std::string GetName() const;
SineEffect(EffectIDState& effect) : m_effect(effect) {}
void SetState(const ControlState state);
private:
EffectIDState& m_effect;
};
class SquareEffect : public Output
{
public:
std::string GetName() const;
SquareEffect(EffectIDState& effect) : m_effect(effect) {}
void SetState(const ControlState state);
private:
EffectIDState& m_effect;
};
class TriangleEffect : public Output
{
public:
std::string GetName() const;
TriangleEffect(EffectIDState& effect) : m_effect(effect) {}
void SetState(const ControlState state);
private:
EffectIDState& m_effect;
};
#endif
public: