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:
Aloshi 2012-07-23 18:53:33 -05:00
parent 21bd83d5b2
commit 6c5edd3284
9 changed files with 133 additions and 38 deletions

View file

@ -10,7 +10,7 @@ SDL_Event* InputManager::lastEvent = NULL;
std::map<int, InputManager::InputButton> InputManager::joystickButtonMap, InputManager::joystickAxisPosMap, InputManager::joystickAxisNegMap;
std::map<int, int> InputManager::axisState;
int InputManager::deadzone = 32000;
int InputManager::deadzone = 28000;
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
joystickButtonMap.clear();
joystickAxisPosMap.clear();
joystickAxisNegMap.clear();
std::string path = getConfigPath();
std::ifstream file(path.c_str());
while(file.good())
@ -195,3 +197,16 @@ void InputManager::loadConfig(std::string path)
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");
}

View file

@ -12,7 +12,7 @@ namespace InputManager {
void registerComponent(GuiComponent* comp);
void unregisterComponent(GuiComponent* comp);
void loadConfig(std::string path);
void loadConfig();
//enum for identifying input, regardless of configuration
enum InputButton { UNKNOWN, UP, DOWN, LEFT, RIGHT, BUTTON1, BUTTON2 };
@ -22,6 +22,7 @@ namespace InputManager {
extern std::vector<GuiComponent*> inputVector;
extern SDL_Event* lastEvent; //mostly for GuiInputConfig
extern int deadzone;
std::string getConfigPath();
extern std::map<int, InputButton> joystickButtonMap;
extern std::map<int, InputButton> joystickAxisPosMap, joystickAxisNegMap;

View file

@ -3,6 +3,7 @@
#include <boost/filesystem.hpp>
#include <fstream>
#include <stdlib.h>
#include <SDL/SDL_joystick.h>
std::vector<SystemData*> SystemData::sSystemVector;
@ -33,6 +34,9 @@ void SystemData::launchGame(unsigned int i)
{
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;
GameData* game = mGameVector.at(i);
@ -44,6 +48,9 @@ void SystemData::launchGame(unsigned int i)
std::cout << "=====================================================\n";
std::cout << "...launch terminated!\n";
//re-enable SDL joystick events
SDL_JoystickEventState(1);
}
void SystemData::deleteGames()
@ -62,6 +69,21 @@ void SystemData::buildGameList()
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))
{
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
void SystemData::loadConfig(std::string path)
void SystemData::loadConfig()
{
deleteSystems();
std::string path = getConfigPath();
std::cout << "Loading system config file \"" << path << "\"...\n";
std::ifstream file(path.c_str());
@ -179,6 +203,34 @@ void SystemData::loadConfig(std::string path)
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()
{
for(unsigned int i = 0; i < sSystemVector.size(); i++)
@ -187,3 +239,16 @@ void SystemData::deleteSystems()
}
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");
}

View file

@ -18,9 +18,10 @@ public:
void buildGameList();
void launchGame(unsigned int i);
//static std::vector<SystemData*> loadConfig(std::string path);
static void deleteSystems();
static void loadConfig(std::string path);
static void loadConfig();
static void writeExampleConfig();
static std::string getConfigPath();
static std::vector<SystemData*> sSystemVector;
private:

View file

@ -25,6 +25,12 @@ GuiGameList::~GuiGameList()
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
if(id >= (int)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)
{
//SDL_EnableKeyRepeat(0, 0);
if(!keyDown)
mSystem->launchGame(mList->getSelection());
//SDL_EnableKeyRepeat(500, 100);
}
if(button == InputManager::RIGHT && keyDown)

View file

@ -38,24 +38,29 @@ void GuiInputConfig::onRender()
{
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)
Renderer::drawCenteredText("All done!", 2, 0x000000);
Renderer::drawCenteredText("All done! Press a keyboard key to continue.", 250, 0x00BB00);
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)
{
if(mDone)
{
if(keyDown)
if(InputManager::lastEvent->type == SDL_KEYUP)
{
writeConfig(sConfigPath);
writeConfig();
if(mJoystick)
SDL_JoystickClose(mJoystick);
InputManager::loadConfig(sConfigPath);
InputManager::loadConfig();
delete this;
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());
typedef std::map<int, InputManager::InputButton>::iterator it_type;

View file

@ -25,7 +25,7 @@ private:
std::map<int, InputManager::InputButton> mButtonMap;
std::map<int, InputManager::InputButton> mAxisPosMap;
std::map<int, InputManager::InputButton> mAxisNegMap;
void writeConfig(std::string path);
void writeConfig();
};
#endif

View file

@ -4,11 +4,13 @@
#include "Renderer.h"
#include "components/GuiGameList.h"
#include "SystemData.h"
#include <boost/filesystem.hpp>
#include "components/GuiInputConfig.h"
int main()
{
bool running = true;
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) != 0)
{
std::cerr << "Error - could not initialize SDL!\n";
@ -35,16 +37,31 @@ int main()
SDL_EnableKeyRepeat(500, 100);
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)
{
SDL_Event event;

View file

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