From 3e6adf7be48df32cf7b99ff9755f796695fe7d33 Mon Sep 17 00:00:00 2001
From: Aloshi <aloshi@aloshi>
Date: Mon, 8 Apr 2013 09:27:38 -0500
Subject: [PATCH] Backported InputConfig.

---
 Makefile.common     |   2 +-
 src/InputConfig.cpp |  97 ++++++++++++++++++++++++++++++++++++++
 src/InputConfig.h   | 112 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 210 insertions(+), 1 deletion(-)
 create mode 100644 src/InputConfig.cpp
 create mode 100644 src/InputConfig.h

diff --git a/Makefile.common b/Makefile.common
index 862432143..c73a30594 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -2,7 +2,7 @@ CXX=g++
 CXXFLAGS=-Wall -g -O2
 LDFLAGS=
 
-SRC_SOURCES=AudioManager.cpp Log.cpp FolderData.cpp Font.cpp GameData.cpp GuiComponent.cpp InputManager.cpp main.cpp MathExp.cpp Renderer.cpp Renderer_draw_gl.cpp Renderer_init.cpp Sound.cpp SystemData.cpp XMLReader.cpp components/GuiAnimation.cpp components/GuiBox.cpp components/GuiFastSelect.cpp components/GuiGameList.cpp components/GuiImage.cpp components/GuiInputConfig.cpp components/GuiMenu.cpp components/GuiTheme.cpp pugiXML/pugixml.cpp
+SRC_SOURCES=AudioManager.cpp InputConfig.cpp Log.cpp FolderData.cpp Font.cpp GameData.cpp GuiComponent.cpp InputManager.cpp main.cpp MathExp.cpp Renderer.cpp Renderer_draw_gl.cpp Renderer_init.cpp Sound.cpp SystemData.cpp XMLReader.cpp components/GuiAnimation.cpp components/GuiBox.cpp components/GuiFastSelect.cpp components/GuiGameList.cpp components/GuiImage.cpp components/GuiInputConfig.cpp components/GuiMenu.cpp components/GuiTheme.cpp pugiXML/pugixml.cpp
 SOURCES=$(addprefix src/,$(SRC_SOURCES))
 OBJECTS=$(SOURCES:.cpp=.o)
 DEPS=$(SOURCES:.cpp=.d)
diff --git a/src/InputConfig.cpp b/src/InputConfig.cpp
new file mode 100644
index 000000000..22bb9f90f
--- /dev/null
+++ b/src/InputConfig.cpp
@@ -0,0 +1,97 @@
+#include "InputConfig.h"
+#include <string>
+#include <algorithm>
+#include <SDL.h>
+#include <iostream>
+
+std::string toLower(std::string str)
+{
+	for(unsigned int i = 0; i < str.length(); i++)
+	{
+		str[i] = tolower(str[i]);
+	}
+
+	return str;
+}
+
+InputConfig::InputConfig(int deviceId) : mDeviceId(deviceId)
+{
+	mPlayerNum = -1;
+}
+
+void InputConfig::clear()
+{
+	mNameMap.clear();
+}
+
+void InputConfig::mapInput(const std::string& name, Input input)
+{
+	mNameMap[toLower(name)] = input;
+}
+
+Input InputConfig::getInputByName(const std::string& name)
+{
+	return mNameMap[toLower(name)];
+}
+
+bool InputConfig::isMappedTo(const std::string& name, Input input)
+{
+	Input comp = getInputByName(name);
+
+	if(comp.configured && comp.type == input.type && comp.id == input.id)
+	{
+		if(comp.type == TYPE_HAT)
+		{
+			return (input.value == 0 || input.value & comp.value);
+		}
+
+		if(comp.type == TYPE_AXIS)
+		{
+			return input.value == 0 || comp.value == input.value;
+		}else{
+			return true;
+		}
+	}
+	return false;
+}
+
+std::vector<std::string> InputConfig::getMappedTo(Input input)
+{
+	std::vector<std::string> maps;
+
+	typedef std::map<std::string, Input>::iterator it_type;
+	for(it_type iterator = mNameMap.begin(); iterator != mNameMap.end(); iterator++)
+	{
+		Input chk = iterator->second;
+
+		if(!chk.configured)
+			continue;
+
+		if(chk.device == input.device && chk.type == input.type && chk.id == input.id)
+		{
+			if(chk.type == TYPE_HAT)
+			{
+				if(input.value == 0 || input.value & chk.value)
+				{
+					maps.push_back(iterator->first);
+				}
+				continue;
+			}
+
+			if(input.type == TYPE_AXIS)
+			{
+				if(input.value == 0 || chk.value == input.value)
+					maps.push_back(iterator->first);
+			}else{
+				maps.push_back(iterator->first);
+			}
+		}
+	}
+
+	return maps;
+}
+
+
+void InputConfig::setPlayerNum(int num) { mPlayerNum = num; }
+int InputConfig::getPlayerNum() { return mPlayerNum; }
+int InputConfig::getDeviceId() { return mDeviceId; }
diff --git a/src/InputConfig.h b/src/InputConfig.h
new file mode 100644
index 000000000..f498045ac
--- /dev/null
+++ b/src/InputConfig.h
@@ -0,0 +1,112 @@
+#ifndef _INPUTCONFIG_H_
+#define _INPUTCONFIG_H_
+
+#include <map>
+#include <vector>
+#include <string>
+#include <SDL.h>
+#include <sstream>
+
+#define DEVICE_KEYBOARD -1
+
+enum InputType
+{
+	TYPE_AXIS,
+	TYPE_BUTTON,
+	TYPE_HAT,
+	TYPE_KEY,
+	TYPE_COUNT
+};
+
+struct Input
+{
+public:
+	int device;
+	InputType type;
+	int id;
+	int value;
+	bool configured;
+
+	Input()
+	{
+		device = DEVICE_KEYBOARD;
+		configured = false;
+		id = -1;
+		value = -999;
+		type = TYPE_COUNT;
+	}
+
+	Input(int dev, InputType t, int i, int val, bool conf) : device(dev), type(t), id(i), value(val), configured(conf)
+	{
+	}
+
+	std::string getHatDir(int val)
+	{
+		if(val & SDL_HAT_UP)
+			return "up";
+		else if(val & SDL_HAT_DOWN)
+			return "down";
+		else if(val & SDL_HAT_LEFT)
+			return "left";
+		else if(val & SDL_HAT_RIGHT)
+			return "right";
+		return "neutral?";
+	}
+
+	std::string string()
+	{
+		if(!configured)
+			return "";
+
+		std::stringstream stream;
+		switch(type)
+		{
+			case TYPE_BUTTON:
+				stream << "Button " << id;
+				break;
+			case TYPE_AXIS:
+				stream << "Axis " << id << (value > 0 ? "+" : "-");
+				break;
+			case TYPE_HAT:
+				stream << "Hat " << id << " " << getHatDir(value);
+				break;
+			case TYPE_KEY:
+				stream << "Key " << SDL_GetKeyName((SDLKey)id);
+				break;
+			default:
+				stream << "Input to string error";
+				break;
+		}
+
+		return stream.str();
+	}
+};
+
+class InputConfig
+{
+public:
+	InputConfig(int deviceId);
+
+	void clear();
+	void mapInput(const std::string& name, Input input);
+	void setPlayerNum(int num);
+
+	int getPlayerNum();
+	int getDeviceId();
+
+	//Returns the input mapped to this name.
+	Input getInputByName(const std::string& name);
+
+	//Returns true if Input is mapped to this name, false otherwise.
+	bool isMappedTo(const std::string& name, Input input);
+
+	//Returns a list of names this input is mapped to.
+	std::vector<std::string> getMappedTo(Input input);
+
+private:
+	std::map<std::string, Input> mNameMap;
+	const int mDeviceId;
+	int mPlayerNum;
+};
+
+#endif