/**
** Supermodel
** A Sega Model 3 Arcade Emulator.
** Copyright 2011 Bart Trzynadlowski, Nik Henson
**
** This file is part of Supermodel.
**
** Supermodel is free software: you can redistribute it and/or modify it under
** the terms of the GNU General Public License as published by the Free
** Software Foundation, either version 3 of the License, or (at your option)
** any later version.
**
** Supermodel is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
** FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
** more details.
**
** You should have received a copy of the GNU General Public License along
** with Supermodel. If not, see .
**/
/*
* MultiInputSource.cpp
*
* Implementation of CMultiInputSource.
*/
#include "MultiInputSource.h"
#include "Supermodel.h"
#include "Input.h"
#include
using namespace std;
ESourceType CMultiInputSource::GetCombinedType(vector &sources)
{
// Check if vector is empty
if (sources.empty())
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::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 &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;
}