mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 23:55: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, 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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
33
src/main.cpp
33
src/main.cpp
|
@ -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;
|
||||
|
|
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