mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-11-04 03:56:39 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			716 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			716 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -------------------------------------------------------
 | 
						|
Copyright (c) 2011 Alberto G. Salguero (alberto.salguero (at) uca.es)
 | 
						|
 | 
						|
Permission is hereby granted, free of charge, to any
 | 
						|
person obtaining a copy of this software and associated
 | 
						|
documentation files (the "Software"), to deal in the
 | 
						|
Software without restriction, including without limitation
 | 
						|
the rights to use, copy, modify, merge, publish,
 | 
						|
distribute, sublicense, and/or sell copies of the
 | 
						|
Software, and to permit persons to whom the Software is
 | 
						|
furnished to do so, subject to the following conditions:
 | 
						|
 | 
						|
The above copyright notice and this permission notice
 | 
						|
shall be included in all copies or substantial portions of
 | 
						|
the Software.
 | 
						|
 | 
						|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
 | 
						|
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 | 
						|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 | 
						|
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
 | 
						|
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 | 
						|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 | 
						|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 | 
						|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
						|
------------------------------------------------------- */
 | 
						|
 | 
						|
#include "ICSInputControlSystem.h"
 | 
						|
 | 
						|
namespace ICS
 | 
						|
{
 | 
						|
	InputControlSystem::InputControlSystem(std::string file, bool active
 | 
						|
		, DetectingBindingListener* detectingBindingListener
 | 
						|
		, InputControlSystemLog* log, size_t channelCount)
 | 
						|
		: mFileName(file)
 | 
						|
		, mLog(log)
 | 
						|
		, mDetectingBindingListener(detectingBindingListener)
 | 
						|
		, mDetectingBindingControl(NULL)
 | 
						|
        , mDetectingBindingDirection(Control::STOP)
 | 
						|
        , mXmouseAxisBinded(false), mYmouseAxisBinded(false)
 | 
						|
        , mClientWidth(1)
 | 
						|
        , mClientHeight(1)
 | 
						|
	{
 | 
						|
		ICS_LOG(" - Creating InputControlSystem - ");
 | 
						|
 | 
						|
		this->mActive = active;
 | 
						|
 | 
						|
		ICS_LOG("Channel count = " + ToString<size_t>(channelCount) );
 | 
						|
		for(size_t i=0;i<channelCount;i++)
 | 
						|
		{
 | 
						|
			mChannels.push_back(new Channel((int)i));
 | 
						|
		}
 | 
						|
 | 
						|
		if(file != "")
 | 
						|
		{
 | 
						|
			TiXmlDocument* xmlDoc;
 | 
						|
			TiXmlElement* xmlRoot;
 | 
						|
 | 
						|
			ICS_LOG("Loading file \""+file+"\"");
 | 
						|
 | 
						|
			xmlDoc = new TiXmlDocument(file.c_str());
 | 
						|
			xmlDoc->LoadFile();
 | 
						|
 | 
						|
			if(xmlDoc->Error())
 | 
						|
			{
 | 
						|
				std::ostringstream message;
 | 
						|
				message << "TinyXml reported an error reading \""+ file + "\". Row " <<
 | 
						|
					(int)xmlDoc->ErrorRow() << ", Col " << (int)xmlDoc->ErrorCol() << ": " <<
 | 
						|
					xmlDoc->ErrorDesc() ;
 | 
						|
				ICS_LOG(message.str());
 | 
						|
 | 
						|
				delete xmlDoc;
 | 
						|
				return;
 | 
						|
			}
 | 
						|
 | 
						|
			xmlRoot = xmlDoc->RootElement();
 | 
						|
			if(std::string(xmlRoot->Value()) != "Controller") {
 | 
						|
				ICS_LOG("Error: Invalid Controller file. Missing <Controller> element.");
 | 
						|
				delete xmlDoc;
 | 
						|
				return;
 | 
						|
			}
 | 
						|
 | 
						|
			TiXmlElement* xmlControl = xmlRoot->FirstChildElement("Control");
 | 
						|
 | 
						|
	        size_t controlChannelCount = 0;
 | 
						|
			while(xmlControl)
 | 
						|
	        {
 | 
						|
	            TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel");
 | 
						|
				while(xmlChannel)
 | 
						|
				{
 | 
						|
					controlChannelCount = std::max(channelCount, FromString<size_t>(xmlChannel->Attribute("number"))+1);
 | 
						|
 | 
						|
					xmlChannel = xmlChannel->NextSiblingElement("Channel");
 | 
						|
				}
 | 
						|
 | 
						|
	            xmlControl = xmlControl->NextSiblingElement("Control");
 | 
						|
	        }
 | 
						|
 | 
						|
			if(controlChannelCount > channelCount)
 | 
						|
			{
 | 
						|
				size_t dif = controlChannelCount - channelCount;
 | 
						|
				ICS_LOG("Warning: default channel count exceeded. Adding " + ToString<size_t>(dif) + " channels" );
 | 
						|
				for(size_t i = channelCount ; i < controlChannelCount ; i++)
 | 
						|
				{
 | 
						|
					mChannels.push_back(new Channel((int)i));
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			ICS_LOG("Applying filters to channels");
 | 
						|
			//<ChannelFilter number="0">
 | 
						|
			//	<interval type="bezier" startX="0.0" startY="0.0" midX="0.25" midY="0.5" endX="0.5" endY="0.5" step="0.1" />
 | 
						|
			//	<interval type="bezier" startX="0.5" startY="0.5" midX="0.75" midY="0.5" endX="1.0" endY="1.0" step="0.1" />
 | 
						|
			//</ChannelFilter>
 | 
						|
 | 
						|
			TiXmlElement* xmlChannelFilter = xmlRoot->FirstChildElement("ChannelFilter");
 | 
						|
			while(xmlChannelFilter)
 | 
						|
			{
 | 
						|
				int ch = FromString<int>(xmlChannelFilter->Attribute("number"));
 | 
						|
 | 
						|
				TiXmlElement* xmlInterval = xmlChannelFilter->FirstChildElement("Interval");
 | 
						|
				while(xmlInterval)
 | 
						|
				{
 | 
						|
					std::string type = xmlInterval->Attribute("type");
 | 
						|
 | 
						|
					if(type == "bezier")
 | 
						|
					{
 | 
						|
						float startX = FromString<float>(xmlInterval->Attribute("startX"));
 | 
						|
						float startY = FromString<float>(xmlInterval->Attribute("startY"));
 | 
						|
						float midX = FromString<float>(xmlInterval->Attribute("midX"));
 | 
						|
						float midY = FromString<float>(xmlInterval->Attribute("midY"));
 | 
						|
						float endX = FromString<float>(xmlInterval->Attribute("endX"));
 | 
						|
						float endY = FromString<float>(xmlInterval->Attribute("endY"));
 | 
						|
 | 
						|
                        float step = FromString<float>(xmlInterval->Attribute("step"));
 | 
						|
 | 
						|
						ICS_LOG("Applying Bezier filter to channel [number="
 | 
						|
							+ ToString<int>(ch) + ", startX="
 | 
						|
							+ ToString<float>(startX) + ", startY="
 | 
						|
							+ ToString<float>(startY) + ", midX="
 | 
						|
							+ ToString<float>(midX) + ", midY="
 | 
						|
							+ ToString<float>(midY) + ", endX="
 | 
						|
							+ ToString<float>(endX) + ", endY="
 | 
						|
							+ ToString<float>(endY) + ", step="
 | 
						|
							+ ToString<float>(step) + "]");
 | 
						|
 | 
						|
						mChannels.at(ch)->addBezierInterval(startX, startY, midX, midY, endX, endY, step);
 | 
						|
					}
 | 
						|
 | 
						|
					xmlInterval = xmlInterval->NextSiblingElement("Interval");
 | 
						|
				}
 | 
						|
 | 
						|
 | 
						|
				xmlChannelFilter = xmlChannelFilter->NextSiblingElement("ChannelFilter");
 | 
						|
			}
 | 
						|
 | 
						|
			xmlControl = xmlRoot->FirstChildElement("Control");
 | 
						|
			while(xmlControl)
 | 
						|
			{
 | 
						|
				bool axisBindable = true;
 | 
						|
				if(xmlControl->Attribute("axisBindable"))
 | 
						|
				{
 | 
						|
					axisBindable = (std::string( xmlControl->Attribute("axisBindable") ) == "true");
 | 
						|
				}
 | 
						|
 | 
						|
				ICS_LOG("Adding Control [name="
 | 
						|
					+ std::string( xmlControl->Attribute("name") ) + ", autoChangeDirectionOnLimitsAfterStop="
 | 
						|
					+ std::string( xmlControl->Attribute("autoChangeDirectionOnLimitsAfterStop") ) + ", autoReverseToInitialValue="
 | 
						|
					+ std::string( xmlControl->Attribute("autoReverseToInitialValue") ) + ", initialValue="
 | 
						|
					+ std::string( xmlControl->Attribute("initialValue") ) + ", stepSize="
 | 
						|
					+ std::string( xmlControl->Attribute("stepSize") ) + ", stepsPerSeconds="
 | 
						|
					+ std::string( xmlControl->Attribute("stepsPerSeconds") ) + ", axisBindable="
 | 
						|
					+ std::string( (axisBindable)? "true" : "false" ) + "]");
 | 
						|
 | 
						|
				float _stepSize = 0;
 | 
						|
				if(xmlControl->Attribute("stepSize"))
 | 
						|
				{
 | 
						|
					std::string value(xmlControl->Attribute("stepSize"));
 | 
						|
					if(value == "MAX")
 | 
						|
					{
 | 
						|
						_stepSize = ICS_MAX;
 | 
						|
					}
 | 
						|
					else
 | 
						|
					{
 | 
						|
						_stepSize = FromString<float>(value.c_str());
 | 
						|
					}
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					ICS_LOG("Warning: no stepSize value found. Default value is 0.");
 | 
						|
				}
 | 
						|
 | 
						|
				float _stepsPerSeconds = 0;
 | 
						|
				if(xmlControl->Attribute("stepsPerSeconds"))
 | 
						|
				{
 | 
						|
					std::string value(xmlControl->Attribute("stepsPerSeconds"));
 | 
						|
					if(value == "MAX")
 | 
						|
					{
 | 
						|
						_stepsPerSeconds = ICS_MAX;
 | 
						|
					}
 | 
						|
					else
 | 
						|
					{
 | 
						|
						_stepsPerSeconds = FromString<float>(value.c_str());
 | 
						|
					}
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					ICS_LOG("Warning: no stepSize value found. Default value is 0.");
 | 
						|
				}
 | 
						|
 | 
						|
				addControl( new Control(xmlControl->Attribute("name")
 | 
						|
					, std::string( xmlControl->Attribute("autoChangeDirectionOnLimitsAfterStop") ) == "true"
 | 
						|
					, std::string( xmlControl->Attribute("autoReverseToInitialValue") ) == "true"
 | 
						|
					, FromString<float>(xmlControl->Attribute("initialValue"))
 | 
						|
					, _stepSize
 | 
						|
					, _stepsPerSeconds
 | 
						|
					, axisBindable) );
 | 
						|
 | 
						|
				loadKeyBinders(xmlControl);
 | 
						|
 | 
						|
				loadMouseAxisBinders(xmlControl);
 | 
						|
 | 
						|
				loadMouseButtonBinders(xmlControl);
 | 
						|
 | 
						|
				loadJoystickAxisBinders(xmlControl);
 | 
						|
 | 
						|
				loadJoystickButtonBinders(xmlControl);
 | 
						|
 | 
						|
				// Attach controls to channels
 | 
						|
				TiXmlElement* xmlChannel = xmlControl->FirstChildElement("Channel");
 | 
						|
				while(xmlChannel)
 | 
						|
				{
 | 
						|
					ICS_LOG("\tAttaching control to channel [number="
 | 
						|
						+ std::string( xmlChannel->Attribute("number") ) + ", direction="
 | 
						|
						+ std::string( xmlChannel->Attribute("direction") ) + "]");
 | 
						|
 | 
						|
					float percentage = 1;
 | 
						|
					if(xmlChannel->Attribute("percentage"))
 | 
						|
					{
 | 
						|
						if(StringIsNumber<float>(xmlChannel->Attribute("percentage")))
 | 
						|
						{
 | 
						|
							float val = FromString<float>(xmlChannel->Attribute("percentage"));
 | 
						|
							if(val > 1 || val < 0)
 | 
						|
							{
 | 
						|
								ICS_LOG("ERROR: attaching percentage value range is [0,1]");
 | 
						|
							}
 | 
						|
							else
 | 
						|
							{
 | 
						|
								percentage = val;
 | 
						|
							}
 | 
						|
						}
 | 
						|
						else
 | 
						|
						{
 | 
						|
							ICS_LOG("ERROR: attaching percentage value range is [0,1]");
 | 
						|
						}
 | 
						|
					}
 | 
						|
 | 
						|
					int chNumber = FromString<int>(xmlChannel->Attribute("number"));
 | 
						|
					if(std::string(xmlChannel->Attribute("direction")) == "DIRECT")
 | 
						|
					{
 | 
						|
						mControls.back()->attachChannel(mChannels[ chNumber ],Channel::DIRECT, percentage);
 | 
						|
					}
 | 
						|
					else if(std::string(xmlChannel->Attribute("direction")) == "INVERSE")
 | 
						|
					{
 | 
						|
						mControls.back()->attachChannel(mChannels[ chNumber ],Channel::INVERSE, percentage);
 | 
						|
					}
 | 
						|
 | 
						|
					xmlChannel = xmlChannel->NextSiblingElement("Channel");
 | 
						|
				}
 | 
						|
 | 
						|
				xmlControl = xmlControl->NextSiblingElement("Control");
 | 
						|
			}
 | 
						|
 | 
						|
			std::vector<Channel *>::const_iterator o;
 | 
						|
			for(o = mChannels.begin(); o != mChannels.end(); ++o)
 | 
						|
			{
 | 
						|
				(*o)->update();
 | 
						|
			}
 | 
						|
 | 
						|
			delete xmlDoc;
 | 
						|
		}
 | 
						|
 | 
						|
		ICS_LOG(" - InputControlSystem Created - ");
 | 
						|
	}
 | 
						|
 | 
						|
	InputControlSystem::~InputControlSystem()
 | 
						|
	{
 | 
						|
		ICS_LOG(" - Deleting InputControlSystem (" + mFileName + ") - ");
 | 
						|
 | 
						|
		mJoystickIDList.clear();
 | 
						|
 | 
						|
		std::vector<Channel *>::const_iterator o;
 | 
						|
		for(o = mChannels.begin(); o != mChannels.end(); ++o)
 | 
						|
		{
 | 
						|
			delete (*o);
 | 
						|
		}
 | 
						|
		mChannels.clear();
 | 
						|
 | 
						|
		std::vector<Control *>::const_iterator o2;
 | 
						|
		for(o2 = mControls.begin(); o2 != mControls.end(); ++o2)
 | 
						|
		{
 | 
						|
			delete (*o2);
 | 
						|
		}
 | 
						|
		mControls.clear();
 | 
						|
 | 
						|
		mControlsKeyBinderMap.clear();
 | 
						|
		mControlsMouseButtonBinderMap.clear();
 | 
						|
		mControlsJoystickButtonBinderMap.clear();
 | 
						|
 | 
						|
		ICS_LOG(" - InputControlSystem deleted - ");
 | 
						|
	}
 | 
						|
 | 
						|
	std::string InputControlSystem::getBaseFileName()
 | 
						|
	{
 | 
						|
		size_t found = mFileName.find_last_of("/\\");
 | 
						|
		std::string file = mFileName.substr(found+1);
 | 
						|
 | 
						|
		return file.substr(0, file.find_last_of("."));
 | 
						|
	}
 | 
						|
 | 
						|
	bool InputControlSystem::save(std::string fileName)
 | 
						|
	{
 | 
						|
		if(fileName != "")
 | 
						|
		{
 | 
						|
			mFileName = fileName;
 | 
						|
		}
 | 
						|
 | 
						|
		TiXmlDocument doc(  mFileName.c_str() );
 | 
						|
 | 
						|
		TiXmlDeclaration dec;
 | 
						|
		dec.Parse( "<?xml version='1.0' encoding='utf-8'?>", 0, TIXML_ENCODING_UNKNOWN );
 | 
						|
		doc.InsertEndChild(dec);
 | 
						|
 | 
						|
		TiXmlElement Controller( "Controller" );
 | 
						|
 | 
						|
        for(std::vector<Channel*>::const_iterator o = mChannels.begin() ; o != mChannels.end(); ++o)
 | 
						|
		{
 | 
						|
			ICS::IntervalList intervals = (*o)->getIntervals();
 | 
						|
 | 
						|
			if(intervals.size() > 1) // all channels have a default linear filter
 | 
						|
			{
 | 
						|
				TiXmlElement ChannelFilter( "ChannelFilter" );
 | 
						|
 | 
						|
				ChannelFilter.SetAttribute("number", ToString<int>((*o)->getNumber()).c_str());
 | 
						|
 | 
						|
				ICS::IntervalList::const_iterator interval = intervals.begin();
 | 
						|
				while( interval != intervals.end() )
 | 
						|
				{
 | 
						|
					// if not default linear filter
 | 
						|
					if(!( interval->step == 0.2f
 | 
						|
						&& interval->startX == 0.0f
 | 
						|
						&& interval->startY == 0.0f
 | 
						|
						&& interval->midX == 0.5f
 | 
						|
						&& interval->midY == 0.5f
 | 
						|
						&& interval->endX == 1.0f
 | 
						|
						&& interval->endY == 1.0f ))
 | 
						|
					{
 | 
						|
						TiXmlElement XMLInterval( "Interval" );
 | 
						|
 | 
						|
						XMLInterval.SetAttribute("type", "bezier");
 | 
						|
						XMLInterval.SetAttribute("step", ToString<float>(interval->step).c_str());
 | 
						|
 | 
						|
						XMLInterval.SetAttribute("startX", ToString<float>(interval->startX).c_str());
 | 
						|
						XMLInterval.SetAttribute("startY", ToString<float>(interval->startY).c_str());
 | 
						|
						XMLInterval.SetAttribute("midX", ToString<float>(interval->midX).c_str());
 | 
						|
						XMLInterval.SetAttribute("midY", ToString<float>(interval->midY).c_str());
 | 
						|
						XMLInterval.SetAttribute("endX", ToString<float>(interval->endX).c_str());
 | 
						|
						XMLInterval.SetAttribute("endY", ToString<float>(interval->endY).c_str());
 | 
						|
 | 
						|
						ChannelFilter.InsertEndChild(XMLInterval);
 | 
						|
					}
 | 
						|
 | 
						|
                    ++interval;
 | 
						|
				}
 | 
						|
 | 
						|
				Controller.InsertEndChild(ChannelFilter);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
        for(std::vector<Control*>::const_iterator o = mControls.begin() ; o != mControls.end(); ++o)
 | 
						|
		{
 | 
						|
			TiXmlElement control( "Control" );
 | 
						|
 | 
						|
			control.SetAttribute( "name", (*o)->getName().c_str() );
 | 
						|
			if((*o)->getAutoChangeDirectionOnLimitsAfterStop())
 | 
						|
			{
 | 
						|
				control.SetAttribute( "autoChangeDirectionOnLimitsAfterStop", "true" );
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				control.SetAttribute( "autoChangeDirectionOnLimitsAfterStop", "false" );
 | 
						|
			}
 | 
						|
			if((*o)->getAutoReverse())
 | 
						|
			{
 | 
						|
				control.SetAttribute( "autoReverseToInitialValue", "true" );
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				control.SetAttribute( "autoReverseToInitialValue", "false" );
 | 
						|
			}
 | 
						|
			control.SetAttribute( "initialValue", ToString<float>((*o)->getInitialValue()).c_str() );
 | 
						|
 | 
						|
			if((*o)->getStepSize() == ICS_MAX)
 | 
						|
			{
 | 
						|
				control.SetAttribute( "stepSize", "MAX" );
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				control.SetAttribute( "stepSize", ToString<float>((*o)->getStepSize()).c_str() );
 | 
						|
			}
 | 
						|
 | 
						|
			if((*o)->getStepsPerSeconds() == ICS_MAX)
 | 
						|
			{
 | 
						|
				control.SetAttribute( "stepsPerSeconds", "MAX" );
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				control.SetAttribute( "stepsPerSeconds", ToString<float>((*o)->getStepsPerSeconds()).c_str() );
 | 
						|
			}
 | 
						|
 | 
						|
			if(!(*o)->isAxisBindable())
 | 
						|
			{
 | 
						|
				control.SetAttribute( "axisBindable", "false" );
 | 
						|
			}
 | 
						|
 | 
						|
            if(getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE) != SDL_SCANCODE_UNKNOWN)
 | 
						|
			{
 | 
						|
				TiXmlElement keyBinder( "KeyBinder" );
 | 
						|
 | 
						|
                keyBinder.SetAttribute( "key", ToString<int>(
 | 
						|
					getKeyBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)).c_str() );
 | 
						|
				keyBinder.SetAttribute( "direction", "INCREASE" );
 | 
						|
				control.InsertEndChild(keyBinder);
 | 
						|
			}
 | 
						|
 | 
						|
            if(getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE) != SDL_SCANCODE_UNKNOWN)
 | 
						|
			{
 | 
						|
				TiXmlElement keyBinder( "KeyBinder" );
 | 
						|
 | 
						|
                keyBinder.SetAttribute( "key", ToString<int>(
 | 
						|
					getKeyBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)).c_str() );
 | 
						|
				keyBinder.SetAttribute( "direction", "DECREASE" );
 | 
						|
				control.InsertEndChild(keyBinder);
 | 
						|
			}
 | 
						|
 | 
						|
			if(getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)
 | 
						|
				!= InputControlSystem/*::NamedAxis*/::UNASSIGNED)
 | 
						|
			{
 | 
						|
				TiXmlElement binder( "MouseBinder" );
 | 
						|
 | 
						|
				InputControlSystem::NamedAxis axis =
 | 
						|
					getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::INCREASE);
 | 
						|
				if(axis == InputControlSystem/*::NamedAxis*/::X)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "axis", "X" );
 | 
						|
				}
 | 
						|
				else if(axis == InputControlSystem/*::NamedAxis*/::Y)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "axis", "Y" );
 | 
						|
				}
 | 
						|
				else if(axis == InputControlSystem/*::NamedAxis*/::Z)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "axis", "Z" );
 | 
						|
				}
 | 
						|
 | 
						|
				binder.SetAttribute( "direction", "INCREASE" );
 | 
						|
				control.InsertEndChild(binder);
 | 
						|
			}
 | 
						|
 | 
						|
			if(getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)
 | 
						|
				!= InputControlSystem/*::NamedAxis*/::UNASSIGNED)
 | 
						|
			{
 | 
						|
				TiXmlElement binder( "MouseBinder" );
 | 
						|
 | 
						|
				InputControlSystem::NamedAxis axis =
 | 
						|
					getMouseAxisBinding(*o, Control/*::ControlChangingDirection*/::DECREASE);
 | 
						|
				if(axis == InputControlSystem/*::NamedAxis*/::X)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "axis", "X" );
 | 
						|
				}
 | 
						|
				else if(axis == InputControlSystem/*::NamedAxis*/::Y)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "axis", "Y" );
 | 
						|
				}
 | 
						|
				else if(axis == InputControlSystem/*::NamedAxis*/::Z)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "axis", "Z" );
 | 
						|
				}
 | 
						|
 | 
						|
				binder.SetAttribute( "direction", "DECREASE" );
 | 
						|
				control.InsertEndChild(binder);
 | 
						|
			}
 | 
						|
 | 
						|
			if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE)
 | 
						|
				!= ICS_MAX_DEVICE_BUTTONS)
 | 
						|
			{
 | 
						|
				TiXmlElement binder( "MouseButtonBinder" );
 | 
						|
 | 
						|
				unsigned int button = getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::INCREASE);
 | 
						|
				if(button == SDL_BUTTON_LEFT)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "button", "LEFT" );
 | 
						|
				}
 | 
						|
				else if(button == SDL_BUTTON_MIDDLE)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "button", "MIDDLE" );
 | 
						|
				}
 | 
						|
				else if(button == SDL_BUTTON_RIGHT)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "button", "RIGHT" );
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "button", ToString<unsigned int>(button).c_str() );
 | 
						|
				}
 | 
						|
				binder.SetAttribute( "direction", "INCREASE" );
 | 
						|
				control.InsertEndChild(binder);
 | 
						|
			}
 | 
						|
 | 
						|
			if(getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE)
 | 
						|
				!= ICS_MAX_DEVICE_BUTTONS)
 | 
						|
			{
 | 
						|
				TiXmlElement binder( "MouseButtonBinder" );
 | 
						|
 | 
						|
				unsigned int button = getMouseButtonBinding(*o, Control/*::ControlChangingDirection*/::DECREASE);
 | 
						|
				if(button == SDL_BUTTON_LEFT)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "button", "LEFT" );
 | 
						|
				}
 | 
						|
				else if(button == SDL_BUTTON_MIDDLE)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "button", "MIDDLE" );
 | 
						|
				}
 | 
						|
				else if(button == SDL_BUTTON_RIGHT)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "button", "RIGHT" );
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "button", ToString<unsigned int>(button).c_str() );
 | 
						|
				}
 | 
						|
				binder.SetAttribute( "direction", "DECREASE" );
 | 
						|
				control.InsertEndChild(binder);
 | 
						|
			}
 | 
						|
			JoystickIDList::const_iterator it = mJoystickIDList.begin();
 | 
						|
			while(it!=mJoystickIDList.end())
 | 
						|
			{
 | 
						|
                int deviceID = *it;
 | 
						|
                if(getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)
 | 
						|
                    != /*NamedAxis::*/UNASSIGNED)
 | 
						|
                {
 | 
						|
                    TiXmlElement binder( "JoystickAxisBinder" );
 | 
						|
 | 
						|
                    binder.SetAttribute( "axis", ToString<int>(
 | 
						|
                        getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)).c_str() );
 | 
						|
 | 
						|
                    binder.SetAttribute( "direction", "INCREASE" );
 | 
						|
 | 
						|
                    binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability
 | 
						|
 | 
						|
                    control.InsertEndChild(binder);
 | 
						|
                }
 | 
						|
 | 
						|
                if(getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)
 | 
						|
                    != /*NamedAxis::*/UNASSIGNED)
 | 
						|
                {
 | 
						|
                    TiXmlElement binder( "JoystickAxisBinder" );
 | 
						|
 | 
						|
                    binder.SetAttribute( "axis", ToString<int>(
 | 
						|
                        getJoystickAxisBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)).c_str() );
 | 
						|
 | 
						|
                    binder.SetAttribute( "direction", "DECREASE" );
 | 
						|
 | 
						|
                    binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability
 | 
						|
 | 
						|
                    control.InsertEndChild(binder);
 | 
						|
                }
 | 
						|
 | 
						|
                if(getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)
 | 
						|
                    != ICS_MAX_DEVICE_BUTTONS)
 | 
						|
                {
 | 
						|
                    TiXmlElement binder( "JoystickButtonBinder" );
 | 
						|
 | 
						|
                    binder.SetAttribute( "button", ToString<unsigned int>(
 | 
						|
                        getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::INCREASE)).c_str() );
 | 
						|
 | 
						|
                    binder.SetAttribute( "direction", "INCREASE" );
 | 
						|
 | 
						|
                    binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability
 | 
						|
 | 
						|
                    control.InsertEndChild(binder);
 | 
						|
                }
 | 
						|
 | 
						|
                if(getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)
 | 
						|
                    != ICS_MAX_DEVICE_BUTTONS)
 | 
						|
                {
 | 
						|
                    TiXmlElement binder( "JoystickButtonBinder" );
 | 
						|
 | 
						|
                    binder.SetAttribute( "button", ToString<unsigned int>(
 | 
						|
                        getJoystickButtonBinding(*o, deviceID, Control/*::ControlChangingDirection*/::DECREASE)).c_str() );
 | 
						|
 | 
						|
                    binder.SetAttribute( "direction", "DECREASE" );
 | 
						|
 | 
						|
                    binder.SetAttribute( "deviceId", deviceID ); //completely useless, but required for backwards compatability
 | 
						|
 | 
						|
                    control.InsertEndChild(binder);
 | 
						|
                }
 | 
						|
                it++;
 | 
						|
            }
 | 
						|
 | 
						|
 | 
						|
			std::list<Channel*> channels = (*o)->getAttachedChannels();
 | 
						|
			for(std::list<Channel*>::iterator it = channels.begin() ;
 | 
						|
                it != channels.end() ; ++it)
 | 
						|
			{
 | 
						|
				TiXmlElement binder( "Channel" );
 | 
						|
 | 
						|
				binder.SetAttribute( "number", ToString<int>((*it)->getNumber()).c_str() );
 | 
						|
 | 
						|
				Channel::ChannelDirection direction = (*it)->getAttachedControlBinding(*o).direction;
 | 
						|
				if(direction == Channel/*::ChannelDirection*/::DIRECT)
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "direction", "DIRECT" );
 | 
						|
				}
 | 
						|
				else
 | 
						|
				{
 | 
						|
					binder.SetAttribute( "direction", "INVERSE" );
 | 
						|
				}
 | 
						|
 | 
						|
				float percentage = (*it)->getAttachedControlBinding(*o).percentage;
 | 
						|
				binder.SetAttribute( "percentage", ToString<float>(percentage).c_str() );
 | 
						|
 | 
						|
				control.InsertEndChild(binder);
 | 
						|
			}
 | 
						|
 | 
						|
			Controller.InsertEndChild(control);
 | 
						|
		}
 | 
						|
 | 
						|
		doc.InsertEndChild(Controller);
 | 
						|
		return doc.SaveFile();
 | 
						|
	}
 | 
						|
 | 
						|
	void InputControlSystem::update(float lTimeSinceLastFrame)
 | 
						|
	{
 | 
						|
		if(mActive)
 | 
						|
		{
 | 
						|
			std::vector<Control *>::const_iterator it;
 | 
						|
			for(it=mControls.begin(); it!=mControls.end(); ++it)
 | 
						|
			{
 | 
						|
				(*it)->update(lTimeSinceLastFrame);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		//! @todo Future versions should consider channel exponentials and mixtures, so
 | 
						|
		// after updating Controls, Channels should be updated according to their values
 | 
						|
	}
 | 
						|
 | 
						|
	float InputControlSystem::getChannelValue(int i)
 | 
						|
	{
 | 
						|
		return std::max<float>(0.0,std::min<float>(1.0,mChannels[i]->getValue()));
 | 
						|
	}
 | 
						|
 | 
						|
	float InputControlSystem::getControlValue(int i)
 | 
						|
	{
 | 
						|
		return mControls[i]->getValue();
 | 
						|
	}
 | 
						|
 | 
						|
	Control* InputControlSystem::findControl(std::string name)
 | 
						|
	{
 | 
						|
		if(mActive)
 | 
						|
		{
 | 
						|
			std::vector<Control *>::const_iterator it;
 | 
						|
			for(it = mControls.begin(); it != mControls.end(); ++it)
 | 
						|
			{
 | 
						|
				if( ((Control*)(*it))->getName() == name)
 | 
						|
				{
 | 
						|
					return (Control*)(*it);
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return NULL;
 | 
						|
	}
 | 
						|
 | 
						|
	void InputControlSystem::enableDetectingBindingState(Control* control
 | 
						|
		, Control::ControlChangingDirection direction)
 | 
						|
	{
 | 
						|
		mDetectingBindingControl = control;
 | 
						|
		mDetectingBindingDirection = direction;
 | 
						|
 | 
						|
		mMouseAxisBindingInitialValues[0] = ICS_MOUSE_AXIS_BINDING_NULL_VALUE;
 | 
						|
	}
 | 
						|
 | 
						|
    bool InputControlSystem::detectingBindingState()
 | 
						|
    {
 | 
						|
        return mDetectingBindingControl != NULL;
 | 
						|
    }
 | 
						|
 | 
						|
	void InputControlSystem::cancelDetectingBindingState()
 | 
						|
	{
 | 
						|
		mDetectingBindingControl = NULL;
 | 
						|
	}
 | 
						|
 | 
						|
    std::string InputControlSystem::scancodeToString(SDL_Scancode key)
 | 
						|
	{
 | 
						|
        SDL_Keycode code = SDL_GetKeyFromScancode(key);
 | 
						|
        if (code == SDLK_UNKNOWN)
 | 
						|
            return std::string(SDL_GetScancodeName(key));
 | 
						|
        else
 | 
						|
            return std::string(SDL_GetKeyName(code));
 | 
						|
	}
 | 
						|
 | 
						|
    void InputControlSystem::adjustMouseRegion(Uint16 width, Uint16 height)
 | 
						|
    {
 | 
						|
        mClientWidth = width;
 | 
						|
        mClientHeight = height;
 | 
						|
    }
 | 
						|
}
 |