Supermodel/Src/Inputs/MultiInputSource.cpp
Nik Henson 5e247021be Changes relating to input system:
- Fixed bug with mapping of multiple assignments.
- Added new ! operator for input mappings, which lets the user specify that an input must not be active.
- Added option to print info about input system (such as settings and detected keyboards, mice and joysticks) during input configuration.
- Added new trigger input for lightgun games with a configurable option to automatically pull trigger when offscreen input is activated (this makes playing with the mouse easier as the gun can be reloaded with single mouse button, rather than having to press both
 buttons at the same time).
- Added -xinput command line option that switches to using XInput API rather than DirectInput for XBox 360 controllers (this allows the XBox 360 controller's two triggers to be read independently which works better for driving games when they are mapped to accele
rator and brake).
- Added initial version of force feedback implementation to DirectInputSystem (this still needs work).
2011-06-05 20:53:39 +00:00

153 lines
4.1 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(CInputSystem *system) : CInputSource(SourceEmpty), m_system(system), m_isOr(true), m_numSrcs(0), m_srcArray(NULL) { }
CMultiInputSource::CMultiInputSource(CInputSystem *system, bool isOr, vector<CInputSource*> &sources) :
CInputSource(GetCombinedType(sources)), m_system(system), 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)
{
for (int i = 0; i < m_numSrcs; i++)
m_system->ReleaseSource(m_srcArray[i]);
delete m_srcArray;
}
}
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(CInputSystem *system, CInputSource *source) : CInputSource(source->type), m_system(system), m_source(source) { }
CNegInputSource::~CNegInputSource()
{
m_system->ReleaseSource(m_source);
}
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;
}