mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-29 17:15:40 +00:00
e8782b98fa
- Added ability to configure axis min, centre and max values in INI file. This allows some types of steering wheel pedals that use an inverted value range to work properly with the emulator. - Modified CINIFile to read and write signed numbers (needed for above change). - Added check at configuration start for "bad" input sources such as axes that are wrongly calibrated or buttons that are always triggering a value. Otherwise they cause the configuration loop to wait indefinitely for the axis or button to be released. - Removed superfluous check for XInput devices when XInput is not enabled in CDirectInputSystem. - Improved force beedback code in CDirectInputSystem and also added the extra feedback effects needed so far for drive board emulation.
193 lines
4.6 KiB
C++
193 lines
4.6 KiB
C++
#include "Supermodel.h"
|
|
|
|
#include <vector>
|
|
using namespace std;
|
|
|
|
ESourceType CMultiInputSource::GetCombinedType(vector<CInputSource*> &sources)
|
|
{
|
|
// Check if vector is empty
|
|
if (sources.size() == 0)
|
|
return SourceEmpty;
|
|
// Otherwise, see whether all sources are switches, or if have a full- or half-axis present
|
|
bool allSwitches = true;
|
|
bool hasFullAxis = false;
|
|
bool hasHalfAxis = false;
|
|
for (vector<CInputSource*>::iterator it = sources.begin(); it != sources.end(); it++)
|
|
{
|
|
if ((*it)->type == SourceInvalid)
|
|
return SourceInvalid; // An invalid source makes the whole lot invalid
|
|
else if ((*it)->type == SourceSwitch)
|
|
continue;
|
|
allSwitches = false;
|
|
if ((*it)->type == SourceFullAxis)
|
|
{
|
|
if (hasHalfAxis)
|
|
return SourceInvalid; // A half-axis and full-axis combined makes the whole lot invalid
|
|
hasFullAxis = true;
|
|
}
|
|
else if ((*it)->type == SourceHalfAxis)
|
|
{
|
|
if (hasFullAxis)
|
|
return SourceInvalid; // A half-axis and full-axis combined makes the whole lot invalid
|
|
hasHalfAxis = true;
|
|
}
|
|
}
|
|
// Return resulting combined type
|
|
if (allSwitches) return SourceSwitch;
|
|
else if (hasFullAxis) return SourceFullAxis;
|
|
else if (hasHalfAxis) return SourceHalfAxis;
|
|
else return SourceEmpty;
|
|
}
|
|
|
|
CMultiInputSource::CMultiInputSource() : CInputSource(SourceEmpty), m_isOr(true), m_numSrcs(0), m_srcArray(NULL)
|
|
{
|
|
//
|
|
}
|
|
|
|
CMultiInputSource::CMultiInputSource(bool isOr, vector<CInputSource*> &sources) :
|
|
CInputSource(GetCombinedType(sources)), m_isOr(isOr), m_numSrcs(sources.size())
|
|
{
|
|
m_srcArray = new CInputSource*[m_numSrcs];
|
|
copy(sources.begin(), sources.end(), m_srcArray);
|
|
}
|
|
|
|
CMultiInputSource::~CMultiInputSource()
|
|
{
|
|
if (m_srcArray != NULL)
|
|
delete m_srcArray;
|
|
}
|
|
|
|
void CMultiInputSource::Acquire()
|
|
{
|
|
CInputSource::Acquire();
|
|
|
|
if (m_acquired == 1)
|
|
{
|
|
// Acquire all sources
|
|
for (int i = 0; i < m_numSrcs; i++)
|
|
m_srcArray[i]->Acquire();
|
|
}
|
|
}
|
|
|
|
void CMultiInputSource::Release()
|
|
{
|
|
if (m_acquired == 1)
|
|
{
|
|
// Release all sources
|
|
for (int i = 0; i < m_numSrcs; i++)
|
|
m_srcArray[i]->Release();
|
|
}
|
|
|
|
CInputSource::Release();
|
|
}
|
|
|
|
bool CMultiInputSource::GetValueAsSwitch(bool &val)
|
|
{
|
|
if (m_isOr)
|
|
{
|
|
// Return value for first input that is active
|
|
for (int i = 0; i < m_numSrcs; i++)
|
|
{
|
|
if (m_srcArray[i]->GetValueAsSwitch(val))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// Check all inputs are active
|
|
for (int i = 0; i < m_numSrcs; i++)
|
|
{
|
|
if (!m_srcArray[i]->GetValueAsSwitch(val))
|
|
return false;
|
|
}
|
|
return m_numSrcs > 0;
|
|
}
|
|
}
|
|
|
|
bool CMultiInputSource::GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal)
|
|
{
|
|
if (m_isOr)
|
|
{
|
|
// Return value for first input that is active
|
|
for (int i = 0; i < m_numSrcs; i++)
|
|
{
|
|
if (m_srcArray[i]->GetValueAsAnalog(val, minVal, offVal, maxVal))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
// Check all switch inputs are active
|
|
for (int i = 0; i < m_numSrcs; i++)
|
|
{
|
|
if (m_srcArray[i]->type == SourceSwitch && !m_srcArray[i]->GetValueAsAnalog(val, minVal, offVal, maxVal))
|
|
return false;
|
|
}
|
|
// If so, then return value for first non-switch input that is active
|
|
for (int i = 0; i < m_numSrcs; i++)
|
|
{
|
|
if (m_srcArray[i]->type != SourceSwitch && m_srcArray[i]->GetValueAsAnalog(val, minVal, offVal, maxVal))
|
|
return true;
|
|
}
|
|
// If non found, then value is only valid if not empty and all inputs are switches
|
|
return m_numSrcs > 0 && type == SourceSwitch;
|
|
}
|
|
}
|
|
|
|
bool CMultiInputSource::SendForceFeedbackCmd(ForceFeedbackCmd ffCmd)
|
|
{
|
|
bool result = false;
|
|
for (int i = 0; i < m_numSrcs; i++)
|
|
result |= m_srcArray[i]->SendForceFeedbackCmd(ffCmd);
|
|
return result;
|
|
}
|
|
|
|
CNegInputSource::CNegInputSource(CInputSource *source) : CInputSource(source->type), m_source(source)
|
|
{
|
|
// Acquire source
|
|
m_source->Acquire();
|
|
}
|
|
|
|
void CNegInputSource::Acquire()
|
|
{
|
|
CInputSource::Acquire();
|
|
|
|
// Acquire source
|
|
if (m_acquired == 1)
|
|
m_source->Acquire();
|
|
}
|
|
|
|
void CNegInputSource::Release()
|
|
{
|
|
// Release source
|
|
if (m_acquired == 1)
|
|
m_source->Release();
|
|
|
|
CInputSource::Release();
|
|
}
|
|
|
|
bool CNegInputSource::GetValueAsSwitch(bool &val)
|
|
{
|
|
bool oldVal = val;
|
|
if (m_source->GetValueAsSwitch(val))
|
|
{
|
|
val = oldVal;
|
|
return false;
|
|
}
|
|
val = true;
|
|
return true;
|
|
}
|
|
|
|
bool CNegInputSource::GetValueAsAnalog(int &val, int minVal, int offVal, int maxVal)
|
|
{
|
|
int oldVal = val;
|
|
if (m_source->GetValueAsAnalog(val, minVal, offVal, maxVal))
|
|
{
|
|
val = oldVal;
|
|
return false;
|
|
}
|
|
val = maxVal;
|
|
return true;
|
|
} |