/** ** 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; }