mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 23:55:38 +00:00
Merge pull request #37 from twolife/master
Add a new directory for gamelist.xml & theme.xml for each system
This commit is contained in:
commit
56ae7c1b69
|
@ -111,7 +111,7 @@ An example gamelist.xml:
|
|||
</gameList>
|
||||
```
|
||||
|
||||
The path element should be the absolute path of the ROM. Special characters SHOULD NOT be escaped. The image element is the absolute path to an image to display above the description (like a screenshot or boxart). Most formats can be used (including png, jpg, gif, etc.). Not all elements need to be used.
|
||||
The path element should be the absolute path of the ROM. Special characters SHOULD NOT be escaped. The image element is the path to an image to display above the description (like a screenshot or boxart). Most formats can be used (including png, jpg, gif, etc.). Not all elements need to be used.
|
||||
|
||||
The switch `--gamelist-only` can be used to skip automatic searching, and only display games defined in the system's gamelist.xml.
|
||||
The switch `--ignore-gamelist` can be used to ignore the gamelist and use the non-detailed view.
|
||||
|
|
|
@ -3,7 +3,10 @@ Themes
|
|||
|
||||
EmulationStation allows each system to have its own "theme." A theme is a collection of display settings and images defined in an XML document.
|
||||
|
||||
ES will check two places for a theme: first, the system's search directory for theme.xml. Then, if that's not found, $HOME/.emulationstation/es_theme.xml will be used.
|
||||
ES will check 3 places for a theme, in the following order:
|
||||
- a theme.xml file in the sysytem's %PATH% directory.
|
||||
- $HOME/.emulationstation/%NAME%/theme.xml
|
||||
- $HOME/.emulationstation/es_theme.xml
|
||||
|
||||
Almost all positions, dimensions, origins, etc. work in percentages - that is, they are a decimal between 0 and 1, representing the percentage of the screen on that axis to use. This ensures that themes look similar at every resolution.
|
||||
|
||||
|
|
|
@ -18,9 +18,10 @@ extern bool IGNOREGAMELIST;
|
|||
std::string SystemData::getStartPath() { return mStartPath; }
|
||||
std::string SystemData::getExtension() { return mSearchExtension; }
|
||||
|
||||
SystemData::SystemData(std::string name, std::string startPath, std::string extension, std::string command)
|
||||
SystemData::SystemData(std::string name, std::string desc, std::string startPath, std::string extension, std::string command)
|
||||
{
|
||||
mName = name;
|
||||
mDesc = desc;
|
||||
|
||||
//expand home symbol if the startpath contains it
|
||||
if(startPath[0] == '~')
|
||||
|
@ -41,7 +42,6 @@ SystemData::SystemData(std::string name, std::string startPath, std::string exte
|
|||
mSearchExtension = extension;
|
||||
mLaunchCommand = command;
|
||||
|
||||
|
||||
mRootFolder = new FolderData(this, mStartPath, "Search Root");
|
||||
|
||||
if(!PARSEGAMELISTONLY)
|
||||
|
@ -153,14 +153,15 @@ void SystemData::populateFolder(FolderData* folder)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
std::string SystemData::getName()
|
||||
{
|
||||
return mName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
std::string SystemData::getDesc()
|
||||
{
|
||||
return mDesc;
|
||||
}
|
||||
|
||||
//creates systems from information located in a config file
|
||||
void SystemData::loadConfig()
|
||||
|
@ -175,7 +176,7 @@ void SystemData::loadConfig()
|
|||
if(file.is_open())
|
||||
{
|
||||
std::string line;
|
||||
std::string sysName, sysPath, sysExtension, sysCommand;
|
||||
std::string sysName, sysDesc, sysPath, sysExtension, sysCommand;
|
||||
while(file.good())
|
||||
{
|
||||
std::getline(file, line);
|
||||
|
@ -203,6 +204,8 @@ void SystemData::loadConfig()
|
|||
//map the value to the appropriate variable
|
||||
if(varName == "NAME")
|
||||
sysName = varValue;
|
||||
else if(varName == "DESC")
|
||||
sysDesc = varValue;
|
||||
else if(varName == "PATH")
|
||||
{
|
||||
if(varValue[varValue.length() - 1] == '/')
|
||||
|
@ -215,9 +218,9 @@ void SystemData::loadConfig()
|
|||
sysCommand = varValue;
|
||||
|
||||
//we have all our variables - create the system object
|
||||
if(!sysName.empty() && !sysPath.empty() &&!sysExtension.empty() && !sysCommand.empty())
|
||||
if(!sysName.empty() && !sysDesc.empty() && !sysPath.empty() &&!sysExtension.empty() && !sysCommand.empty())
|
||||
{
|
||||
SystemData* newSystem = new SystemData(sysName, sysPath, sysExtension, sysCommand);
|
||||
SystemData* newSystem = new SystemData(sysName, sysDesc, sysPath, sysExtension, sysCommand);
|
||||
if(newSystem->getRootFolder()->getFileCount() == 0)
|
||||
{
|
||||
std::cout << "System \"" << sysName << "\" has no games! Deleting.\n";
|
||||
|
@ -227,7 +230,7 @@ void SystemData::loadConfig()
|
|||
}
|
||||
|
||||
//reset the variables for the next block (should there be one)
|
||||
sysName = ""; sysPath = ""; sysExtension = ""; sysCommand = "";
|
||||
sysName = ""; sysDesc = ""; sysPath = ""; sysExtension = ""; sysCommand = "" ;
|
||||
}
|
||||
}else{
|
||||
std::cerr << "Error reading config file \"" << path << "\" - no equals sign found on line \"" << line << "\"!\n";
|
||||
|
@ -252,18 +255,21 @@ void SystemData::writeExampleConfig()
|
|||
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 << "#NAME=nes" << std::endl;
|
||||
file << "#DESC=Nintendo Entertainment System" << std::endl;
|
||||
file << "#PATH=~/ROMs/nes/" << std::endl;
|
||||
file << "#EXTENSION=.nes .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 << "#NAME is a short name used internaly." << std::endl;
|
||||
file << "#DESC is just a pretty desciption 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 a list of extensions to search for, separated by spaces. You MUST include the period, and it must be exact - it's case sensitive, and no wildcards." << std::endl;
|
||||
file << "#COMMAND is the shell command to execute when a game is selected. %ROM% will be replaced with the (bash special-character escaped) path to the ROM." << std::endl << std::endl;
|
||||
|
||||
file << "#Now try your own!" << std::endl;
|
||||
file << "NAME=" << std::endl;
|
||||
file << "DESC=" << std::endl;
|
||||
file << "PATH=" << std::endl;
|
||||
file << "EXTENSION=" << std::endl;
|
||||
file << "COMMAND=" << std::endl;
|
||||
|
@ -298,7 +304,26 @@ FolderData* SystemData::getRootFolder()
|
|||
return mRootFolder;
|
||||
}
|
||||
|
||||
std::string SystemData::getGamelistPath(){
|
||||
|
||||
std::string filePath;
|
||||
|
||||
filePath = mRootFolder->getPath() + "/gamelist.xml";
|
||||
if(fs::exists(filePath))
|
||||
return filePath;
|
||||
|
||||
filePath = getenv("HOME");
|
||||
filePath += "/.emulationstation/"+ getName() + "/gamelist.xml";
|
||||
if(fs::exists(filePath))
|
||||
return filePath;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool SystemData::hasGamelist()
|
||||
{
|
||||
return fs::exists(mRootFolder->getPath() + "/gamelist.xml");
|
||||
if(getGamelistPath().empty())
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -10,13 +10,15 @@ class GameData;
|
|||
class SystemData
|
||||
{
|
||||
public:
|
||||
SystemData(std::string name, std::string startPath, std::string extension, std::string command);
|
||||
SystemData(std::string name, std::string desc, std::string startPath, std::string extension, std::string command);
|
||||
~SystemData();
|
||||
|
||||
FolderData* getRootFolder();
|
||||
std::string getName();
|
||||
std::string getDesc();
|
||||
std::string getStartPath();
|
||||
std::string getExtension();
|
||||
std::string getGamelistPath();
|
||||
bool hasGamelist();
|
||||
|
||||
void launchGame(GameData* game);
|
||||
|
@ -29,6 +31,7 @@ public:
|
|||
static std::vector<SystemData*> sSystemVector;
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mDesc;
|
||||
std::string mStartPath;
|
||||
std::string mSearchExtension;
|
||||
std::string mLaunchCommand;
|
||||
|
|
|
@ -102,10 +102,10 @@ GameData* createGameFromPath(std::string gameAbsPath, SystemData* system)
|
|||
|
||||
void parseGamelist(SystemData* system)
|
||||
{
|
||||
if(!system->hasGamelist())
|
||||
return;
|
||||
std::string xmlpath = system->getGamelistPath();
|
||||
|
||||
std::string xmlpath = system->getRootFolder()->getPath() + "/gamelist.xml";
|
||||
if(xmlpath.empty())
|
||||
return;
|
||||
|
||||
std::cout << "Parsing XML file \"" << xmlpath << "\"...";
|
||||
|
||||
|
@ -166,7 +166,8 @@ void parseGamelist(SystemData* system)
|
|||
if(newImage[0] == '.')
|
||||
{
|
||||
newImage.erase(0, 1);
|
||||
newImage.insert(0, system->getRootFolder()->getPath());
|
||||
boost::filesystem::path pathname(xmlpath);
|
||||
newImage.insert(0, pathname.parent_path().string() );
|
||||
}
|
||||
|
||||
//if the image doesn't exist, forget it
|
||||
|
|
|
@ -91,7 +91,7 @@ void GuiGameList::onRender()
|
|||
|
||||
//header
|
||||
if(!mTheme->getBool("hideHeader"))
|
||||
Renderer::drawCenteredText(mSystem->getName(), 0, 1, 0xFF0000FF, Renderer::getDefaultFont(Renderer::LARGE));
|
||||
Renderer::drawCenteredText(mSystem->getDesc(), 0, 1, 0xFF0000FF, Renderer::getDefaultFont(Renderer::LARGE));
|
||||
|
||||
if(mDetailed)
|
||||
{
|
||||
|
@ -204,21 +204,33 @@ void GuiGameList::updateList()
|
|||
}
|
||||
}
|
||||
|
||||
std::string GuiGameList::getThemeFile() {
|
||||
|
||||
std::string themePath;
|
||||
|
||||
themePath = getenv("HOME");
|
||||
themePath += "/.emulationstation/" + mSystem->getName() + "/theme.xml";
|
||||
if(boost::filesystem::exists(themePath))
|
||||
return themePath;
|
||||
|
||||
themePath = mSystem->getStartPath() + "/theme.xml";
|
||||
if(boost::filesystem::exists(themePath))
|
||||
return themePath;
|
||||
|
||||
themePath = getenv("HOME");
|
||||
themePath += "/.emulationstation/es_theme.xml";
|
||||
if(boost::filesystem::exists(themePath))
|
||||
return themePath;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void GuiGameList::updateTheme()
|
||||
{
|
||||
if(!mTheme)
|
||||
return;
|
||||
|
||||
std::string defaultPath = getenv("HOME");
|
||||
defaultPath += "/.emulationstation/es_theme.xml";
|
||||
std::string themePath = mSystem->getStartPath() + "/theme.xml";
|
||||
|
||||
if(boost::filesystem::exists(themePath))
|
||||
mTheme->readXML(themePath);
|
||||
else if(boost::filesystem::exists(defaultPath))
|
||||
mTheme->readXML(defaultPath);
|
||||
else
|
||||
mTheme->readXML(""); //clears any current theme
|
||||
mTheme->readXML( getThemeFile() );
|
||||
|
||||
mList->setSelectorColor(mTheme->getColor("selector"));
|
||||
mList->setSelectedTextColor(mTheme->getColor("selected"));
|
||||
|
@ -296,7 +308,6 @@ void GuiGameList::onInit()
|
|||
mTheme->init();
|
||||
}
|
||||
|
||||
|
||||
extern bool IGNOREGAMELIST; //defined in main.cpp (as a command line argument)
|
||||
GuiGameList* GuiGameList::create()
|
||||
{
|
||||
|
|
|
@ -37,6 +37,7 @@ private:
|
|||
void updateTheme();
|
||||
void updateDetailData();
|
||||
void clearDetailData();
|
||||
std::string getThemeFile();
|
||||
|
||||
SystemData* mSystem;
|
||||
FolderData* mFolder;
|
||||
|
|
|
@ -151,7 +151,7 @@ void GuiTheme::readXML(std::string path)
|
|||
if(path.empty())
|
||||
return;
|
||||
|
||||
//std::cout << "Loading theme \"" << path << "\"...\n";
|
||||
std::cout << "Loading theme \"" << path << "\"...\n";
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_file(path.c_str());
|
||||
|
|
Loading…
Reference in a new issue