mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 14:15:38 +00:00
Lots of cleaning up to improve user friendliness. Config files are now loaded from the $HOME variable - es_systems.cfg and es_input.cfg.
An example system config file will be created at runtime if one does not exist.
This commit is contained in:
parent
21bd83d5b2
commit
6c5edd3284
|
@ -10,7 +10,7 @@ SDL_Event* InputManager::lastEvent = NULL;
|
||||||
std::map<int, InputManager::InputButton> InputManager::joystickButtonMap, InputManager::joystickAxisPosMap, InputManager::joystickAxisNegMap;
|
std::map<int, InputManager::InputButton> InputManager::joystickButtonMap, InputManager::joystickAxisPosMap, InputManager::joystickAxisNegMap;
|
||||||
std::map<int, int> InputManager::axisState;
|
std::map<int, int> InputManager::axisState;
|
||||||
|
|
||||||
int InputManager::deadzone = 32000;
|
int InputManager::deadzone = 28000;
|
||||||
|
|
||||||
void InputManager::registerComponent(GuiComponent* comp)
|
void InputManager::registerComponent(GuiComponent* comp)
|
||||||
{
|
{
|
||||||
|
@ -138,13 +138,15 @@ void InputManager::processEvent(SDL_Event* event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::loadConfig(std::string path)
|
void InputManager::loadConfig()
|
||||||
{
|
{
|
||||||
//clear any old config
|
//clear any old config
|
||||||
joystickButtonMap.clear();
|
joystickButtonMap.clear();
|
||||||
joystickAxisPosMap.clear();
|
joystickAxisPosMap.clear();
|
||||||
joystickAxisNegMap.clear();
|
joystickAxisNegMap.clear();
|
||||||
|
|
||||||
|
std::string path = getConfigPath();
|
||||||
|
|
||||||
std::ifstream file(path.c_str());
|
std::ifstream file(path.c_str());
|
||||||
|
|
||||||
while(file.good())
|
while(file.good())
|
||||||
|
@ -195,3 +197,16 @@ void InputManager::loadConfig(std::string path)
|
||||||
SDL_JoystickOpen(0);
|
SDL_JoystickOpen(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string InputManager::getConfigPath()
|
||||||
|
{
|
||||||
|
std::string home = getenv("HOME");
|
||||||
|
if(home.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "FATAL ERROR - $HOME environment variable is blank or not defined!\n";
|
||||||
|
exit(1);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return(home + "/.es_input.cfg");
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace InputManager {
|
||||||
void registerComponent(GuiComponent* comp);
|
void registerComponent(GuiComponent* comp);
|
||||||
void unregisterComponent(GuiComponent* comp);
|
void unregisterComponent(GuiComponent* comp);
|
||||||
|
|
||||||
void loadConfig(std::string path);
|
void loadConfig();
|
||||||
|
|
||||||
//enum for identifying input, regardless of configuration
|
//enum for identifying input, regardless of configuration
|
||||||
enum InputButton { UNKNOWN, UP, DOWN, LEFT, RIGHT, BUTTON1, BUTTON2 };
|
enum InputButton { UNKNOWN, UP, DOWN, LEFT, RIGHT, BUTTON1, BUTTON2 };
|
||||||
|
@ -22,6 +22,7 @@ namespace InputManager {
|
||||||
extern std::vector<GuiComponent*> inputVector;
|
extern std::vector<GuiComponent*> inputVector;
|
||||||
extern SDL_Event* lastEvent; //mostly for GuiInputConfig
|
extern SDL_Event* lastEvent; //mostly for GuiInputConfig
|
||||||
extern int deadzone;
|
extern int deadzone;
|
||||||
|
std::string getConfigPath();
|
||||||
|
|
||||||
extern std::map<int, InputButton> joystickButtonMap;
|
extern std::map<int, InputButton> joystickButtonMap;
|
||||||
extern std::map<int, InputButton> joystickAxisPosMap, joystickAxisNegMap;
|
extern std::map<int, InputButton> joystickAxisPosMap, joystickAxisNegMap;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <SDL/SDL_joystick.h>
|
||||||
|
|
||||||
std::vector<SystemData*> SystemData::sSystemVector;
|
std::vector<SystemData*> SystemData::sSystemVector;
|
||||||
|
|
||||||
|
@ -33,6 +34,9 @@ void SystemData::launchGame(unsigned int i)
|
||||||
{
|
{
|
||||||
std::cout << "Attempting to launch game...\n";
|
std::cout << "Attempting to launch game...\n";
|
||||||
|
|
||||||
|
//suspend SDL joystick events (these'll pile up even while something else is running)
|
||||||
|
SDL_JoystickEventState(0);
|
||||||
|
|
||||||
std::string command = mLaunchCommand;
|
std::string command = mLaunchCommand;
|
||||||
GameData* game = mGameVector.at(i);
|
GameData* game = mGameVector.at(i);
|
||||||
|
|
||||||
|
@ -44,6 +48,9 @@ void SystemData::launchGame(unsigned int i)
|
||||||
std::cout << "=====================================================\n";
|
std::cout << "=====================================================\n";
|
||||||
|
|
||||||
std::cout << "...launch terminated!\n";
|
std::cout << "...launch terminated!\n";
|
||||||
|
|
||||||
|
//re-enable SDL joystick events
|
||||||
|
SDL_JoystickEventState(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SystemData::deleteGames()
|
void SystemData::deleteGames()
|
||||||
|
@ -62,6 +69,21 @@ void SystemData::buildGameList()
|
||||||
|
|
||||||
deleteGames();
|
deleteGames();
|
||||||
|
|
||||||
|
//expand home symbol if necessary
|
||||||
|
if(mStartPath[0] == '~')
|
||||||
|
{
|
||||||
|
mStartPath.erase(0, 1);
|
||||||
|
|
||||||
|
std::string home = getenv("HOME");
|
||||||
|
if(home.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR - System start path contains ~ but $HOME is not set!\n";
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
mStartPath.insert(0, home);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!fs::is_directory(mStartPath))
|
if(!fs::is_directory(mStartPath))
|
||||||
{
|
{
|
||||||
std::cout << "Error - system \"" << mName << "\"'s start path does not exist!\n";
|
std::cout << "Error - system \"" << mName << "\"'s start path does not exist!\n";
|
||||||
|
@ -109,10 +131,12 @@ std::string SystemData::getName()
|
||||||
|
|
||||||
|
|
||||||
//creates systems from information located in a config file
|
//creates systems from information located in a config file
|
||||||
void SystemData::loadConfig(std::string path)
|
void SystemData::loadConfig()
|
||||||
{
|
{
|
||||||
deleteSystems();
|
deleteSystems();
|
||||||
|
|
||||||
|
std::string path = getConfigPath();
|
||||||
|
|
||||||
std::cout << "Loading system config file \"" << path << "\"...\n";
|
std::cout << "Loading system config file \"" << path << "\"...\n";
|
||||||
|
|
||||||
std::ifstream file(path.c_str());
|
std::ifstream file(path.c_str());
|
||||||
|
@ -179,6 +203,34 @@ void SystemData::loadConfig(std::string path)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SystemData::writeExampleConfig()
|
||||||
|
{
|
||||||
|
std::string path = getConfigPath();
|
||||||
|
|
||||||
|
std::ofstream file(path.c_str());
|
||||||
|
|
||||||
|
file << "# This is the EmulationStation Systems configuration file." << std::endl;
|
||||||
|
file << "# Lines that begin with a hash (#) are ignored, as are empty lines." << std::endl;
|
||||||
|
file << "# A sample system might look like this:" << std::endl;
|
||||||
|
file << "#NAME=Nintendo Entertainment System" << std::endl;
|
||||||
|
file << "#PATH=~/ROMs/nes/" << std::endl;
|
||||||
|
file << "#EXTENSION=.nes" << std::endl;
|
||||||
|
file << "#COMMAND=retroarch -L ~/cores/libretro-fceumm.so %ROM%" << std::endl << std::endl;
|
||||||
|
|
||||||
|
file << "#NAME is just a name to identify the system." << std::endl;
|
||||||
|
file << "#PATH is the path to start the recursive search for ROMs in. ~ will be expanded into the $HOME variable." << std::endl;
|
||||||
|
file << "#EXTENSION is the exact extension to search for. You MUST include the period, and it must be exact - no regex or wildcard support (sorry!)." << std::endl;
|
||||||
|
file << "#COMMAND is the shell command to execute when a game is selected. %ROM% will be replaced with the path to the ROM." << std::endl << std::endl;
|
||||||
|
|
||||||
|
file << "#Now try your own!" << std::endl;
|
||||||
|
file << "NAME=" << std::endl;
|
||||||
|
file << "PATH=" << std::endl;
|
||||||
|
file << "EXTENSION=" << std::endl;
|
||||||
|
file << "COMMAND=" << std::endl;
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
void SystemData::deleteSystems()
|
void SystemData::deleteSystems()
|
||||||
{
|
{
|
||||||
for(unsigned int i = 0; i < sSystemVector.size(); i++)
|
for(unsigned int i = 0; i < sSystemVector.size(); i++)
|
||||||
|
@ -187,3 +239,16 @@ void SystemData::deleteSystems()
|
||||||
}
|
}
|
||||||
sSystemVector.clear();
|
sSystemVector.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SystemData::getConfigPath()
|
||||||
|
{
|
||||||
|
std::string home = getenv("HOME");
|
||||||
|
if(home.empty())
|
||||||
|
{
|
||||||
|
std::cerr << "FATAL ERROR - $HOME environment variable empty or nonexistant!\n";
|
||||||
|
exit(1);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return(home + "/.es_systems.cfg");
|
||||||
|
}
|
||||||
|
|
|
@ -18,9 +18,10 @@ public:
|
||||||
|
|
||||||
void buildGameList();
|
void buildGameList();
|
||||||
void launchGame(unsigned int i);
|
void launchGame(unsigned int i);
|
||||||
//static std::vector<SystemData*> loadConfig(std::string path);
|
|
||||||
static void deleteSystems();
|
static void deleteSystems();
|
||||||
static void loadConfig(std::string path);
|
static void loadConfig();
|
||||||
|
static void writeExampleConfig();
|
||||||
|
static std::string getConfigPath();
|
||||||
|
|
||||||
static std::vector<SystemData*> sSystemVector;
|
static std::vector<SystemData*> sSystemVector;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -25,6 +25,12 @@ GuiGameList::~GuiGameList()
|
||||||
|
|
||||||
void GuiGameList::setSystemId(int id)
|
void GuiGameList::setSystemId(int id)
|
||||||
{
|
{
|
||||||
|
if(SystemData::sSystemVector.size() == 0)
|
||||||
|
{
|
||||||
|
std::cerr << "Error - no systems found!\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//make sure the id is within range
|
//make sure the id is within range
|
||||||
if(id >= (int)SystemData::sSystemVector.size())
|
if(id >= (int)SystemData::sSystemVector.size())
|
||||||
id -= SystemData::sSystemVector.size();
|
id -= SystemData::sSystemVector.size();
|
||||||
|
@ -48,10 +54,8 @@ void GuiGameList::onInput(InputManager::InputButton button, bool keyDown)
|
||||||
{
|
{
|
||||||
if(button == InputManager::BUTTON1 && mSystem->getGameCount() > 0)
|
if(button == InputManager::BUTTON1 && mSystem->getGameCount() > 0)
|
||||||
{
|
{
|
||||||
//SDL_EnableKeyRepeat(0, 0);
|
|
||||||
if(!keyDown)
|
if(!keyDown)
|
||||||
mSystem->launchGame(mList->getSelection());
|
mSystem->launchGame(mList->getSelection());
|
||||||
//SDL_EnableKeyRepeat(500, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(button == InputManager::RIGHT && keyDown)
|
if(button == InputManager::RIGHT && keyDown)
|
||||||
|
|
|
@ -38,24 +38,29 @@ void GuiInputConfig::onRender()
|
||||||
{
|
{
|
||||||
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFF);
|
Renderer::drawRect(0, 0, Renderer::getScreenWidth(), Renderer::getScreenHeight(), 0xFFFFFF);
|
||||||
|
|
||||||
|
Renderer::drawCenteredText("It looks like you have a joystick plugged in!", 2, 0x000000);
|
||||||
|
Renderer::drawCenteredText("POV hats (some D-Pads) are automatically mapped to directions.", 90, 0x000000);
|
||||||
|
Renderer::drawCenteredText("You can press a keyboard key to skip any input.", 130, 0x000000);
|
||||||
|
Renderer::drawCenteredText("If you want to remap later, just delete ~/.es_input.cfg.", 170, 0x000000);
|
||||||
|
|
||||||
if(mDone)
|
if(mDone)
|
||||||
Renderer::drawCenteredText("All done!", 2, 0x000000);
|
Renderer::drawCenteredText("All done! Press a keyboard key to continue.", 250, 0x00BB00);
|
||||||
else
|
else
|
||||||
Renderer::drawCenteredText("Please press the axis/button for " + sInputs[mInputNum], 2, 0x000000);
|
Renderer::drawCenteredText("Please press the axis/button for " + sInputs[mInputNum], 250, 0x00C000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiInputConfig::onInput(InputManager::InputButton button, bool keyDown)
|
void GuiInputConfig::onInput(InputManager::InputButton button, bool keyDown)
|
||||||
{
|
{
|
||||||
if(mDone)
|
if(mDone)
|
||||||
{
|
{
|
||||||
if(keyDown)
|
if(InputManager::lastEvent->type == SDL_KEYUP)
|
||||||
{
|
{
|
||||||
writeConfig(sConfigPath);
|
writeConfig();
|
||||||
|
|
||||||
if(mJoystick)
|
if(mJoystick)
|
||||||
SDL_JoystickClose(mJoystick);
|
SDL_JoystickClose(mJoystick);
|
||||||
|
|
||||||
InputManager::loadConfig(sConfigPath);
|
InputManager::loadConfig();
|
||||||
delete this;
|
delete this;
|
||||||
new GuiGameList();
|
new GuiGameList();
|
||||||
}
|
}
|
||||||
|
@ -102,8 +107,10 @@ void GuiInputConfig::onInput(InputManager::InputButton button, bool keyDown)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GuiInputConfig::writeConfig(std::string path)
|
void GuiInputConfig::writeConfig()
|
||||||
{
|
{
|
||||||
|
std::string path = InputManager::getConfigPath();
|
||||||
|
|
||||||
std::ofstream file(path.c_str());
|
std::ofstream file(path.c_str());
|
||||||
|
|
||||||
typedef std::map<int, InputManager::InputButton>::iterator it_type;
|
typedef std::map<int, InputManager::InputButton>::iterator it_type;
|
||||||
|
|
|
@ -25,7 +25,7 @@ private:
|
||||||
std::map<int, InputManager::InputButton> mButtonMap;
|
std::map<int, InputManager::InputButton> mButtonMap;
|
||||||
std::map<int, InputManager::InputButton> mAxisPosMap;
|
std::map<int, InputManager::InputButton> mAxisPosMap;
|
||||||
std::map<int, InputManager::InputButton> mAxisNegMap;
|
std::map<int, InputManager::InputButton> mAxisNegMap;
|
||||||
void writeConfig(std::string path);
|
void writeConfig();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
33
src/main.cpp
33
src/main.cpp
|
@ -4,11 +4,13 @@
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "components/GuiGameList.h"
|
#include "components/GuiGameList.h"
|
||||||
#include "SystemData.h"
|
#include "SystemData.h"
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
#include "components/GuiInputConfig.h"
|
#include "components/GuiInputConfig.h"
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
bool running = true;
|
||||||
|
|
||||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0)
|
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0)
|
||||||
{
|
{
|
||||||
std::cerr << "Error - could not initialize SDL!\n";
|
std::cerr << "Error - could not initialize SDL!\n";
|
||||||
|
@ -35,16 +37,31 @@ int main()
|
||||||
SDL_EnableKeyRepeat(500, 100);
|
SDL_EnableKeyRepeat(500, 100);
|
||||||
SDL_JoystickEventState(SDL_ENABLE);
|
SDL_JoystickEventState(SDL_ENABLE);
|
||||||
|
|
||||||
//GuiTitleScreen* testGui = new GuiTitleScreen();
|
if(!boost::filesystem::exists(SystemData::getConfigPath()))
|
||||||
|
{
|
||||||
|
std::cerr << "A system config file in $HOME/.es_systems.cfg was not found. An example will be created.\n";
|
||||||
|
SystemData::writeExampleConfig();
|
||||||
|
std::cerr << "Set it up, then re-run EmulationStation.\n";
|
||||||
|
running = false;
|
||||||
|
}else{
|
||||||
|
SystemData::loadConfig();
|
||||||
|
|
||||||
SystemData::loadConfig("./systems.cfg");
|
if(boost::filesystem::exists(InputManager::getConfigPath()))
|
||||||
|
{
|
||||||
|
InputManager::loadConfig();
|
||||||
|
new GuiGameList();
|
||||||
|
}else{
|
||||||
|
if(SDL_NumJoysticks() > 0)
|
||||||
|
{
|
||||||
|
new GuiInputConfig();
|
||||||
|
}else{
|
||||||
|
std::cout << "Note - it looks like you have no joysticks connected.\n";
|
||||||
|
new GuiGameList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//InputManager::loadConfig("./input.cfg");
|
|
||||||
|
|
||||||
//GuiGameList* testGui = new GuiGameList();
|
|
||||||
GuiInputConfig* testGui = new GuiInputConfig();
|
|
||||||
|
|
||||||
bool running = true;
|
|
||||||
while(running)
|
while(running)
|
||||||
{
|
{
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
15
systems.cfg
15
systems.cfg
|
@ -1,15 +0,0 @@
|
||||||
NAME=Super Nintendo Entertainment System
|
|
||||||
PATH=../ROMs/snes/
|
|
||||||
EXTENSION=.smc
|
|
||||||
COMMAND=retroarch -L ~/cores/libretro-pocketsnes.so %ROM%
|
|
||||||
|
|
||||||
NAME=Nintendo Entertainment System
|
|
||||||
PATH=../ROMs/nes/
|
|
||||||
EXTENSION=.nes
|
|
||||||
COMMAND=retroarch -L ~/cores/libretro-fceumm.so %ROM%
|
|
||||||
|
|
||||||
# This is just a dud to test error handling. Also, comment support! Woo!
|
|
||||||
NAME=Fake System
|
|
||||||
PATH=./fakedir/
|
|
||||||
EXTENSION=.fake
|
|
||||||
COMMAND=this will never be called
|
|
Loading…
Reference in a new issue