mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-02-17 01:45:41 +00:00
![Nik Henson](/assets/img/avatar_default.png)
- 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).
153 lines
4.1 KiB
C++
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;
|
|
} |