ForceFeedback: Apply immediately as well
This commit is contained in:
parent
1958a10b6f
commit
86e4da2c07
|
@ -38,17 +38,6 @@ static const ForceType force_type_names[] =
|
||||||
//{GUID_Friction, "Friction"},
|
//{GUID_Friction, "Friction"},
|
||||||
};
|
};
|
||||||
|
|
||||||
ForceFeedbackDevice::~ForceFeedbackDevice()
|
|
||||||
{
|
|
||||||
// release the ff effect iface's
|
|
||||||
for (EffectState& state : m_state_out)
|
|
||||||
{
|
|
||||||
state.iface->Stop();
|
|
||||||
state.iface->Unload();
|
|
||||||
state.iface->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, int cAxes)
|
bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, int cAxes)
|
||||||
{
|
{
|
||||||
if (cAxes == 0)
|
if (cAxes == 0)
|
||||||
|
@ -107,14 +96,12 @@ bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, i
|
||||||
LPDIRECTINPUTEFFECT pEffect;
|
LPDIRECTINPUTEFFECT pEffect;
|
||||||
if (SUCCEEDED(device->CreateEffect(f.guid, &eff, &pEffect, nullptr)))
|
if (SUCCEEDED(device->CreateEffect(f.guid, &eff, &pEffect, nullptr)))
|
||||||
{
|
{
|
||||||
m_state_out.push_back(EffectState(pEffect));
|
|
||||||
|
|
||||||
if (f.guid == GUID_ConstantForce)
|
if (f.guid == GUID_ConstantForce)
|
||||||
AddOutput(new ForceConstant(f.name, m_state_out.back()));
|
AddOutput(new ForceConstant(f.name, pEffect));
|
||||||
else if (f.guid == GUID_RampForce)
|
else if (f.guid == GUID_RampForce)
|
||||||
AddOutput(new ForceRamp(f.name, m_state_out.back()));
|
AddOutput(new ForceRamp(f.name, pEffect));
|
||||||
else
|
else
|
||||||
AddOutput(new ForcePeriodic(f.name, m_state_out.back()));
|
AddOutput(new ForcePeriodic(f.name, pEffect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,32 +120,32 @@ bool ForceFeedbackDevice::InitForceFeedback(const LPDIRECTINPUTDEVICE8 device, i
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForceFeedbackDevice::UpdateOutput()
|
template<typename P>
|
||||||
|
ForceFeedbackDevice::Force<P>::~Force()
|
||||||
{
|
{
|
||||||
DIEFFECT eff;
|
m_iface->Stop();
|
||||||
memset(&eff, 0, sizeof(eff));
|
m_iface->Unload();
|
||||||
|
m_iface->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename P>
|
||||||
|
void ForceFeedbackDevice::Force<P>::Update()
|
||||||
|
{
|
||||||
|
DIEFFECT eff = {};
|
||||||
eff.dwSize = sizeof(DIEFFECT);
|
eff.dwSize = sizeof(DIEFFECT);
|
||||||
eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
|
eff.dwFlags = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
|
||||||
|
|
||||||
for (EffectState& state : m_state_out)
|
eff.cbTypeSpecificParams = sizeof(P);
|
||||||
{
|
eff.lpvTypeSpecificParams = ¶ms;
|
||||||
if (state.params)
|
|
||||||
{
|
|
||||||
if (state.size)
|
|
||||||
{
|
|
||||||
eff.cbTypeSpecificParams = state.size;
|
|
||||||
eff.lpvTypeSpecificParams = state.params;
|
|
||||||
// set params and start effect
|
|
||||||
state.iface->SetParameters(&eff, DIEP_TYPESPECIFICPARAMS | DIEP_START);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
state.iface->Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
state.params = nullptr;
|
// set params and start effect
|
||||||
}
|
m_iface->SetParameters(&eff, DIEP_TYPESPECIFICPARAMS | DIEP_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename P>
|
||||||
|
void ForceFeedbackDevice::Force<P>::Stop()
|
||||||
|
{
|
||||||
|
m_iface->Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -166,15 +153,14 @@ void ForceFeedbackDevice::ForceConstant::SetState(const ControlState state)
|
||||||
{
|
{
|
||||||
const LONG new_val = LONG(10000 * state);
|
const LONG new_val = LONG(10000 * state);
|
||||||
|
|
||||||
LONG &val = params.lMagnitude;
|
if (params.lMagnitude == new_val)
|
||||||
if (val != new_val)
|
return;
|
||||||
{
|
|
||||||
val = new_val;
|
|
||||||
m_state.params = ¶ms; // tells UpdateOutput the state has changed
|
|
||||||
|
|
||||||
// tells UpdateOutput to either start or stop the force
|
params.lMagnitude = new_val;
|
||||||
m_state.size = new_val ? sizeof(params) : 0;
|
if (new_val)
|
||||||
}
|
Update();
|
||||||
|
else
|
||||||
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -182,14 +168,14 @@ void ForceFeedbackDevice::ForceRamp::SetState(const ControlState state)
|
||||||
{
|
{
|
||||||
const LONG new_val = LONG(10000 * state);
|
const LONG new_val = LONG(10000 * state);
|
||||||
|
|
||||||
if (params.lStart != new_val)
|
if (params.lStart == new_val)
|
||||||
{
|
return;
|
||||||
params.lStart = params.lEnd = new_val;
|
|
||||||
m_state.params = ¶ms; // tells UpdateOutput the state has changed
|
|
||||||
|
|
||||||
// tells UpdateOutput to either start or stop the force
|
params.lStart = params.lEnd = new_val;
|
||||||
m_state.size = new_val ? sizeof(params) : 0;
|
if (new_val)
|
||||||
}
|
Update();
|
||||||
|
else
|
||||||
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
@ -197,22 +183,19 @@ void ForceFeedbackDevice::ForcePeriodic::SetState(const ControlState state)
|
||||||
{
|
{
|
||||||
const DWORD new_val = DWORD(10000 * state);
|
const DWORD new_val = DWORD(10000 * state);
|
||||||
|
|
||||||
DWORD &val = params.dwMagnitude;
|
if (params.dwMagnitude == new_val)
|
||||||
if (val != new_val)
|
return;
|
||||||
{
|
|
||||||
val = new_val;
|
|
||||||
//params.dwPeriod = 0;//DWORD(0.05 * DI_SECONDS); // zero is working fine for me
|
|
||||||
|
|
||||||
m_state.params = ¶ms; // tells UpdateOutput the state has changed
|
params.dwMagnitude = new_val;
|
||||||
|
if (new_val)
|
||||||
// tells UpdateOutput to either start or stop the force
|
Update();
|
||||||
m_state.size = new_val ? sizeof(params) : 0;
|
else
|
||||||
}
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename P>
|
template <typename P>
|
||||||
ForceFeedbackDevice::Force<P>::Force(const std::string& name, EffectState& state)
|
ForceFeedbackDevice::Force<P>::Force(const std::string& name, LPDIRECTINPUTEFFECT iface)
|
||||||
: m_name(name), m_state(state)
|
: m_name(name), m_iface(iface)
|
||||||
{
|
{
|
||||||
memset(¶ms, 0, sizeof(params));
|
memset(¶ms, 0, sizeof(params));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,25 +25,19 @@ namespace ForceFeedback
|
||||||
class ForceFeedbackDevice : public Core::Device
|
class ForceFeedbackDevice : public Core::Device
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
struct EffectState
|
|
||||||
{
|
|
||||||
EffectState(LPDIRECTINPUTEFFECT eff) : iface(eff), params(nullptr), size(0) {}
|
|
||||||
|
|
||||||
LPDIRECTINPUTEFFECT iface;
|
|
||||||
void* params; // null when force hasn't changed
|
|
||||||
u8 size; // zero when force should stop
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename P>
|
template <typename P>
|
||||||
class Force : public Output
|
class Force : public Output
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string GetName() const;
|
std::string GetName() const;
|
||||||
Force(const std::string& name, EffectState& state);
|
Force(const std::string& name, LPDIRECTINPUTEFFECT iface);
|
||||||
|
~Force();
|
||||||
void SetState(ControlState state);
|
void SetState(ControlState state);
|
||||||
|
void Update();
|
||||||
|
void Stop();
|
||||||
private:
|
private:
|
||||||
const std::string m_name;
|
const std::string m_name;
|
||||||
EffectState& m_state;
|
LPDIRECTINPUTEFFECT m_iface;
|
||||||
P params;
|
P params;
|
||||||
};
|
};
|
||||||
typedef Force<DICONSTANTFORCE> ForceConstant;
|
typedef Force<DICONSTANTFORCE> ForceConstant;
|
||||||
|
@ -52,11 +46,6 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool InitForceFeedback(const LPDIRECTINPUTDEVICE8, int cAxes);
|
bool InitForceFeedback(const LPDIRECTINPUTDEVICE8, int cAxes);
|
||||||
void UpdateOutput() override;
|
|
||||||
|
|
||||||
virtual ~ForceFeedbackDevice();
|
|
||||||
private:
|
|
||||||
std::list<EffectState> m_state_out;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue