diff --git a/src/Font.cpp b/src/Font.cpp index ddec1df0d..e5395c3f2 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -69,16 +69,12 @@ void Font::init() buildAtlas(); FT_Done_Face(face); - - std::cout << "initialized font\n"; } void Font::deinit() { if(textureID) glDeleteTextures(1, &textureID); - - std::cout << "deinitialized font\n"; } void Font::buildAtlas() diff --git a/src/InputConfig.cpp b/src/InputConfig.cpp index 22bb9f90f..84bb9737a 100644 --- a/src/InputConfig.cpp +++ b/src/InputConfig.cpp @@ -4,6 +4,38 @@ #include #include +//some util functions +std::string inputTypeToString(InputType type) +{ + switch(type) + { + case TYPE_AXIS: + return "axis"; + case TYPE_BUTTON: + return "button"; + case TYPE_HAT: + return "hat"; + case TYPE_KEY: + return "key"; + default: + return "error"; + } +} + +InputType stringToInputType(const std::string& type) +{ + if(type == "axis") + return TYPE_AXIS; + if(type == "button") + return TYPE_BUTTON; + if(type == "hat") + return TYPE_HAT; + if(type == "key") + return TYPE_KEY; + return TYPE_COUNT; +} + + std::string toLower(std::string str) { for(unsigned int i = 0; i < str.length(); i++) @@ -13,6 +45,7 @@ std::string toLower(std::string str) return str; } +//end util functions InputConfig::InputConfig(int deviceId) : mDeviceId(deviceId) { @@ -91,6 +124,53 @@ std::vector InputConfig::getMappedTo(Input input) return maps; } +void InputConfig::loadFromXML(pugi::xml_node node, int playerNum) +{ + this->clear(); + + setPlayerNum(playerNum); + + for(pugi::xml_node input = node.child("input"); input; input = input.next_sibling("input")) + { + std::string name = input.attribute("name").as_string(); + std::string type = input.attribute("type").as_string(); + InputType typeEnum = stringToInputType(type); + + if(typeEnum == TYPE_COUNT) + { + std::cout << "ERROR - input type \"" << type << "\" is invalid! Skipping input \"" << name << "\".\n"; + continue; + } + + int id = input.attribute("id").as_int(); + int value = input.attribute("value").as_int(); + + if(value == 0) + std::cout << "WARNING: InputConfig value is 0 for " << type << " " << id << "!\n"; + + mNameMap[toLower(name)] = Input(mDeviceId, typeEnum, id, value, true); + } +} + +void InputConfig::writeToXML(pugi::xml_node parent) +{ + pugi::xml_node cfg = parent.append_child("inputConfig"); + + if(mDeviceId == DEVICE_KEYBOARD) + cfg.append_attribute("type") = "keyboard"; + else + cfg.append_attribute("type") = "joystick"; + + typedef std::map::iterator it_type; + for(it_type iterator = mNameMap.begin(); iterator != mNameMap.end(); iterator++) + { + pugi::xml_node input = cfg.append_child("input"); + input.append_attribute("name") = iterator->first.c_str(); + input.append_attribute("type") = inputTypeToString(iterator->second.type).c_str(); + input.append_attribute("id").set_value(iterator->second.id); + input.append_attribute("value").set_value(iterator->second.value); + } +} void InputConfig::setPlayerNum(int num) { mPlayerNum = num; } int InputConfig::getPlayerNum() { return mPlayerNum; } diff --git a/src/InputConfig.h b/src/InputConfig.h index f498045ac..99d13e84b 100644 --- a/src/InputConfig.h +++ b/src/InputConfig.h @@ -6,6 +6,7 @@ #include #include #include +#include "pugiXML/pugixml.hpp" #define DEVICE_KEYBOARD -1 @@ -103,6 +104,8 @@ public: //Returns a list of names this input is mapped to. std::vector getMappedTo(Input input); + void loadFromXML(pugi::xml_node root, int playerNum); + void writeToXML(pugi::xml_node parent); private: std::map mNameMap; const int mDeviceId; diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 01e307970..c06156faf 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -2,6 +2,11 @@ #include "InputConfig.h" #include "Window.h" #include +#include "Log.h" +#include "pugiXML/pugixml.hpp" +#include + +namespace fs = boost::filesystem; InputManager::InputManager(Window* window) : mWindow(window) { @@ -21,8 +26,6 @@ void InputManager::init() if(mJoysticks != NULL) deinit(); - std::cout << "initializing InputManager..."; - SDL_InitSubSystem(SDL_INIT_JOYSTICK); mNumJoysticks = SDL_NumJoysticks(); @@ -45,13 +48,11 @@ void InputManager::init() SDL_JoystickEventState(SDL_ENABLE); - std::cout << "done\n"; + loadConfig(); } void InputManager::deinit() { - std::cout << "deinitializing InputManager..."; - SDL_JoystickEventState(SDL_DISABLE); if(!SDL_WasInit(SDL_INIT_JOYSTICK)) @@ -76,8 +77,6 @@ void InputManager::deinit() } SDL_QuitSubSystem(SDL_INIT_JOYSTICK); - - std::cout << "done\n"; } int InputManager::getNumJoysticks() { return mNumJoysticks; } @@ -164,7 +163,83 @@ bool InputManager::parseEvent(const SDL_Event& ev) void InputManager::loadConfig() { + if(!mJoysticks) + { + std::cout << "ERROR - cannot load config without being initialized!\n"; + } + std::string path = getConfigPath(); + if(!fs::exists(path)) + return; + + pugi::xml_document doc; + pugi::xml_parse_result res = doc.load_file(path.c_str()); + + if(!res) + { + LOG(LogError) << "Error loading input config: " << res.description(); + return; + } + + mNumPlayers = 0; + + pugi::xml_node root = doc.child("inputList"); + + for(pugi::xml_node node = root.child("inputConfig"); node; node = node.next_sibling("inputConfig")) + { + std::string type = node.attribute("type").as_string(); + + if(type == "keyboard") + { + getInputConfigByDevice(DEVICE_KEYBOARD)->loadFromXML(node, mNumPlayers); + mNumPlayers++; + }else if(type == "joystick") + { + bool found = false; + std::string devName = node.child("deviceName").text().get(); + for(int i = 0; i < mNumJoysticks; i++) + { + if(SDL_JoystickName(i) == devName) + { + mInputConfigs[i]->loadFromXML(node, mNumPlayers); + mNumPlayers++; + found = true; + break; + } + } + + if(!found) + { + LOG(LogWarning) << "Could not find joystick named \"" << devName << "\"! Skipping it.\n"; + continue; + } + }else{ + LOG(LogWarning) << "Device type \"" << type << "\" unknown!\n"; + } + } +} + +void InputManager::writeConfig() +{ + if(!mJoysticks) + { + std::cout << "ERROR - cannot write config without being initialized!\n"; + return; + } + + std::string path = getConfigPath(); + + pugi::xml_document doc; + + pugi::xml_node root = doc.append_child("inputList"); + + mKeyboardInputConfig->writeToXML(root); + for(int i = 0; i < mNumJoysticks; i++) + { + mInputConfigs[i]->writeToXML(root); + } + + doc.save_file(path.c_str()); } std::string InputManager::getConfigPath() @@ -173,4 +248,3 @@ std::string InputManager::getConfigPath() path += "/.emulationstation/es_input.cfg"; return path; } - diff --git a/src/InputManager.h b/src/InputManager.h index cfb8fb674..ba5121a5c 100644 --- a/src/InputManager.h +++ b/src/InputManager.h @@ -17,6 +17,7 @@ public: ~InputManager(); void loadConfig(); + void writeConfig(); static std::string getConfigPath(); void init(); diff --git a/src/components/GuiInputConfig.cpp b/src/components/GuiInputConfig.cpp index 1f03000d0..04bdaa4ac 100644 --- a/src/components/GuiInputConfig.cpp +++ b/src/components/GuiInputConfig.cpp @@ -32,6 +32,7 @@ void GuiInputConfig::input(InputConfig* config, Input input) { mWindow->pushGui(new GuiInputConfig(mWindow, mWindow->getInputManager()->getInputConfigByPlayer(mTargetConfig->getPlayerNum() + 1))); }else{ + mWindow->getInputManager()->writeConfig(); GuiGameList::create(mWindow); } delete this; diff --git a/src/main.cpp b/src/main.cpp index 977ab6e9d..5e5729bb9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -136,8 +136,7 @@ int main(int argc, char* argv[]) //choose which GUI to open depending on Input configuration if(fs::exists(InputManager::getConfigPath())) { - //an input config already exists - load it and proceed to the gamelist as usual. - window.getInputManager()->loadConfig(); + //an input config already exists - we have input, proceed to the gamelist as usual. GuiGameList::create(&window); }else{ window.pushGui(new GuiDetectDevice(&window));