mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-03-06 14:27:43 +00:00
Added InputConfig saving/loading.
This commit is contained in:
parent
14a05d4943
commit
a5f4749d5d
|
@ -69,16 +69,12 @@ void Font::init()
|
||||||
buildAtlas();
|
buildAtlas();
|
||||||
|
|
||||||
FT_Done_Face(face);
|
FT_Done_Face(face);
|
||||||
|
|
||||||
std::cout << "initialized font\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::deinit()
|
void Font::deinit()
|
||||||
{
|
{
|
||||||
if(textureID)
|
if(textureID)
|
||||||
glDeleteTextures(1, &textureID);
|
glDeleteTextures(1, &textureID);
|
||||||
|
|
||||||
std::cout << "deinitialized font\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::buildAtlas()
|
void Font::buildAtlas()
|
||||||
|
|
|
@ -4,6 +4,38 @@
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <iostream>
|
#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)
|
std::string toLower(std::string str)
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < str.length(); i++)
|
for(unsigned int i = 0; i < str.length(); i++)
|
||||||
|
@ -13,6 +45,7 @@ std::string toLower(std::string str)
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
//end util functions
|
||||||
|
|
||||||
InputConfig::InputConfig(int deviceId) : mDeviceId(deviceId)
|
InputConfig::InputConfig(int deviceId) : mDeviceId(deviceId)
|
||||||
{
|
{
|
||||||
|
@ -91,6 +124,53 @@ std::vector<std::string> InputConfig::getMappedTo(Input input)
|
||||||
return maps;
|
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; }
|
void InputConfig::setPlayerNum(int num) { mPlayerNum = num; }
|
||||||
int InputConfig::getPlayerNum() { return mPlayerNum; }
|
int InputConfig::getPlayerNum() { return mPlayerNum; }
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include "pugiXML/pugixml.hpp"
|
||||||
|
|
||||||
#define DEVICE_KEYBOARD -1
|
#define DEVICE_KEYBOARD -1
|
||||||
|
|
||||||
|
@ -103,6 +104,8 @@ public:
|
||||||
//Returns a list of names this input is mapped to.
|
//Returns a list of names this input is mapped to.
|
||||||
std::vector<std::string> getMappedTo(Input input);
|
std::vector<std::string> getMappedTo(Input input);
|
||||||
|
|
||||||
|
void loadFromXML(pugi::xml_node root, int playerNum);
|
||||||
|
void writeToXML(pugi::xml_node parent);
|
||||||
private:
|
private:
|
||||||
std::map<std::string, Input> mNameMap;
|
std::map<std::string, Input> mNameMap;
|
||||||
const int mDeviceId;
|
const int mDeviceId;
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
#include "InputConfig.h"
|
#include "InputConfig.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "Log.h"
|
||||||
|
#include "pugiXML/pugixml.hpp"
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
InputManager::InputManager(Window* window) : mWindow(window)
|
InputManager::InputManager(Window* window) : mWindow(window)
|
||||||
{
|
{
|
||||||
|
@ -21,8 +26,6 @@ void InputManager::init()
|
||||||
if(mJoysticks != NULL)
|
if(mJoysticks != NULL)
|
||||||
deinit();
|
deinit();
|
||||||
|
|
||||||
std::cout << "initializing InputManager...";
|
|
||||||
|
|
||||||
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
SDL_InitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
|
||||||
mNumJoysticks = SDL_NumJoysticks();
|
mNumJoysticks = SDL_NumJoysticks();
|
||||||
|
@ -45,13 +48,11 @@ void InputManager::init()
|
||||||
|
|
||||||
SDL_JoystickEventState(SDL_ENABLE);
|
SDL_JoystickEventState(SDL_ENABLE);
|
||||||
|
|
||||||
std::cout << "done\n";
|
loadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::deinit()
|
void InputManager::deinit()
|
||||||
{
|
{
|
||||||
std::cout << "deinitializing InputManager...";
|
|
||||||
|
|
||||||
SDL_JoystickEventState(SDL_DISABLE);
|
SDL_JoystickEventState(SDL_DISABLE);
|
||||||
|
|
||||||
if(!SDL_WasInit(SDL_INIT_JOYSTICK))
|
if(!SDL_WasInit(SDL_INIT_JOYSTICK))
|
||||||
|
@ -76,8 +77,6 @@ void InputManager::deinit()
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||||
|
|
||||||
std::cout << "done\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int InputManager::getNumJoysticks() { return mNumJoysticks; }
|
int InputManager::getNumJoysticks() { return mNumJoysticks; }
|
||||||
|
@ -164,7 +163,83 @@ bool InputManager::parseEvent(const SDL_Event& ev)
|
||||||
|
|
||||||
void InputManager::loadConfig()
|
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()
|
std::string InputManager::getConfigPath()
|
||||||
|
@ -173,4 +248,3 @@ std::string InputManager::getConfigPath()
|
||||||
path += "/.emulationstation/es_input.cfg";
|
path += "/.emulationstation/es_input.cfg";
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ public:
|
||||||
~InputManager();
|
~InputManager();
|
||||||
|
|
||||||
void loadConfig();
|
void loadConfig();
|
||||||
|
void writeConfig();
|
||||||
static std::string getConfigPath();
|
static std::string getConfigPath();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
|
@ -32,6 +32,7 @@ void GuiInputConfig::input(InputConfig* config, Input input)
|
||||||
{
|
{
|
||||||
mWindow->pushGui(new GuiInputConfig(mWindow, mWindow->getInputManager()->getInputConfigByPlayer(mTargetConfig->getPlayerNum() + 1)));
|
mWindow->pushGui(new GuiInputConfig(mWindow, mWindow->getInputManager()->getInputConfigByPlayer(mTargetConfig->getPlayerNum() + 1)));
|
||||||
}else{
|
}else{
|
||||||
|
mWindow->getInputManager()->writeConfig();
|
||||||
GuiGameList::create(mWindow);
|
GuiGameList::create(mWindow);
|
||||||
}
|
}
|
||||||
delete this;
|
delete this;
|
||||||
|
|
|
@ -136,8 +136,7 @@ int main(int argc, char* argv[])
|
||||||
//choose which GUI to open depending on Input configuration
|
//choose which GUI to open depending on Input configuration
|
||||||
if(fs::exists(InputManager::getConfigPath()))
|
if(fs::exists(InputManager::getConfigPath()))
|
||||||
{
|
{
|
||||||
//an input config already exists - load it and proceed to the gamelist as usual.
|
//an input config already exists - we have input, proceed to the gamelist as usual.
|
||||||
window.getInputManager()->loadConfig();
|
|
||||||
GuiGameList::create(&window);
|
GuiGameList::create(&window);
|
||||||
}else{
|
}else{
|
||||||
window.pushGui(new GuiDetectDevice(&window));
|
window.pushGui(new GuiDetectDevice(&window));
|
||||||
|
|
Loading…
Reference in a new issue