Added InputConfig saving/loading.

This commit is contained in:
Aloshi 2013-04-11 17:27:27 -05:00
parent 14a05d4943
commit a5f4749d5d
7 changed files with 168 additions and 14 deletions

View file

@ -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()

View file

@ -4,6 +4,38 @@
#include <SDL.h>
#include <iostream>
//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<std::string> 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<std::string, Input>::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; }

View file

@ -6,6 +6,7 @@
#include <string>
#include <SDL.h>
#include <sstream>
#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<std::string> getMappedTo(Input input);
void loadFromXML(pugi::xml_node root, int playerNum);
void writeToXML(pugi::xml_node parent);
private:
std::map<std::string, Input> mNameMap;
const int mDeviceId;

View file

@ -2,6 +2,11 @@
#include "InputConfig.h"
#include "Window.h"
#include <iostream>
#include "Log.h"
#include "pugiXML/pugixml.hpp"
#include <boost/filesystem.hpp>
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;
}

View file

@ -17,6 +17,7 @@ public:
~InputManager();
void loadConfig();
void writeConfig();
static std::string getConfigPath();
void init();

View file

@ -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;

View file

@ -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));