Changed the logic for the systems configuration file, it now loads from the resources directory.

Also renamed the file from es_systems.cfg to es_systems.xml
This commit is contained in:
Leon Styhre 2021-06-16 18:54:04 +02:00
parent 1653206b76
commit fa624f9f2c
12 changed files with 95 additions and 105 deletions

View file

@ -564,7 +564,7 @@ std::string CollectionSystemsManager::getValidNewCollectionName(std::string inNa
LOG(LogInfo) << "Had to change name, from: " << inName << " to: " << name; LOG(LogInfo) << "Had to change name, from: " << inName << " to: " << name;
} }
// Get used systems from es_systems.cfg. // Get used systems from es_systems.xml.
std::vector<std::string> systemsInUse = getSystemsFromConfig(); std::vector<std::string> systemsInUse = getSystemsFromConfig();
// Get folders assigned to custom collections. // Get folders assigned to custom collections.
std::vector<std::string> autoSys = getCollectionThemeFolders(false); std::vector<std::string> autoSys = getCollectionThemeFolders(false);
@ -856,7 +856,7 @@ FileData* CollectionSystemsManager::updateCollectionFolderMetadata(SystemData* s
std::vector<std::string> CollectionSystemsManager::getUnusedSystemsFromTheme() std::vector<std::string> CollectionSystemsManager::getUnusedSystemsFromTheme()
{ {
// Get used systems in es_systems.cfg. // Get used systems in es_systems.xml.
std::vector<std::string> systemsInUse = getSystemsFromConfig(); std::vector<std::string> systemsInUse = getSystemsFromConfig();
// Get available folders in theme. // Get available folders in theme.
std::vector<std::string> themeSys = getSystemsFromTheme(); std::vector<std::string> themeSys = getSystemsFromTheme();

View file

@ -810,7 +810,7 @@ void FileData::launchGame(Window* window)
return; return;
} }
// If %EMUPATH% is used in es_systems.cfg for this system, then check that the core file // If %EMUPATH% is used in es_systems.xml for this system, then check that the core file
// actually exists. // actually exists.
auto emuPathPos = command.find("%EMUPATH%"); auto emuPathPos = command.find("%EMUPATH%");
if (emuPathPos != std::string::npos) { if (emuPathPos != std::string::npos) {
@ -856,7 +856,7 @@ void FileData::launchGame(Window* window)
} }
} }
else { else {
LOG(LogError) << "Invalid entry in systems configuration file es_systems.cfg"; LOG(LogError) << "Invalid entry in systems configuration file es_systems.xml";
LOG(LogError) << "Raw emulator launch command:"; LOG(LogError) << "Raw emulator launch command:";
LOG(LogError) << commandRaw; LOG(LogError) << commandRaw;
@ -867,7 +867,7 @@ void FileData::launchGame(Window* window)
} }
} }
// If %COREPATH% is used in es_systems.cfg for this system, try to find the emulator // If %COREPATH% is used in es_systems.xml for this system, try to find the emulator
// core using the core paths defined in the setting EmulatorCorePath. // core using the core paths defined in the setting EmulatorCorePath.
auto corePos = command.find("%COREPATH%"); auto corePos = command.find("%COREPATH%");
if (corePos != std::string::npos && emulatorCorePath.size() > 0) { if (corePos != std::string::npos && emulatorCorePath.size() > 0) {
@ -914,7 +914,7 @@ void FileData::launchGame(Window* window)
} }
} }
else { else {
LOG(LogError) << "Invalid entry in systems configuration file es_systems.cfg"; LOG(LogError) << "Invalid entry in systems configuration file es_systems.xml";
LOG(LogError) << "Raw emulator launch command:"; LOG(LogError) << "Raw emulator launch command:";
LOG(LogError) << commandRaw; LOG(LogError) << commandRaw;
@ -938,7 +938,7 @@ void FileData::launchGame(Window* window)
} }
} }
else if (corePos != std::string::npos) { else if (corePos != std::string::npos) {
LOG(LogError) << "The variable %COREPATH% is used in es_systems.cfg but " \ LOG(LogError) << "The variable %COREPATH% is used in es_systems.xml but " \
"no paths are defined using the setting EmulatorCorePath"; "no paths are defined using the setting EmulatorCorePath";
GuiInfoPopup* s = new GuiInfoPopup(window, "ERROR: NO CORE PATHS CONFIGURED, " \ GuiInfoPopup* s = new GuiInfoPopup(window, "ERROR: NO CORE PATHS CONFIGURED, " \
"CAN'T LOCATE EMULATOR CORE", 6000); "CAN'T LOCATE EMULATOR CORE", 6000);
@ -1033,7 +1033,7 @@ std::string FileData::findEmulatorPath(const std::string& command)
// just the program name, assuming the binary is in the PATH variable of the operating // just the program name, assuming the binary is in the PATH variable of the operating
// system, or it could be an absolute path to the emulator. (In the latter case, if // system, or it could be an absolute path to the emulator. (In the latter case, if
// there is a space in the the path, it needs to be enclosed by quotation marks in // there is a space in the the path, it needs to be enclosed by quotation marks in
// es_systems.cfg.) // es_systems.xml.)
std::string emuExecutable; std::string emuExecutable;
std::string exePath; std::string exePath;

View file

@ -4,7 +4,7 @@
// SystemData.cpp // SystemData.cpp
// //
// Provides data structures for the game systems and populates and indexes them based // Provides data structures for the game systems and populates and indexes them based
// on the configuration in es_systems.cfg as well as the presence of game ROM files. // on the configuration in es_systems.xml as well as the presence of game ROM files.
// Also provides functions to read and write to the gamelist files and to handle theme // Also provides functions to read and write to the gamelist files and to handle theme
// loading. // loading.
// //
@ -106,7 +106,7 @@ void SystemData::setIsGameSystemStatus()
{ {
// We exclude non-game systems from specific operations (i.e. the "RetroPie" system, at least). // We exclude non-game systems from specific operations (i.e. the "RetroPie" system, at least).
// If/when there are more in the future, maybe this can be a more complex method, with a proper // If/when there are more in the future, maybe this can be a more complex method, with a proper
// list but for now a simple string comparison is more performant. // list but for now a simple string comparison is enough.
mIsGameSystem = (mName != "retropie"); mIsGameSystem = (mName != "retropie");
} }
@ -230,16 +230,9 @@ bool SystemData::loadConfig()
{ {
deleteSystems(); deleteSystems();
std::string path = getConfigPath(false); std::string path = getConfigPath(true);
const std::string rompath = FileData::getROMDirectory(); const std::string rompath = FileData::getROMDirectory();
if (!Utils::FileSystem::exists(path)) {
LOG(LogInfo) << "Systems configuration file does not exist";
if (copyConfigTemplate(getConfigPath(true)))
return true;
path = getConfigPath(false);
}
LOG(LogInfo) << "Parsing systems configuration file \"" << path << "\"..."; LOG(LogInfo) << "Parsing systems configuration file \"" << path << "\"...";
pugi::xml_document doc; pugi::xml_document doc;
@ -250,8 +243,7 @@ bool SystemData::loadConfig()
#endif #endif
if (!res) { if (!res) {
LOG(LogError) << "Couldn't parse es_systems.cfg"; LOG(LogError) << "Couldn't parse es_systems.xml: " << res.description();
LOG(LogError) << res.description();
return true; return true;
} }
@ -259,7 +251,7 @@ bool SystemData::loadConfig()
pugi::xml_node systemList = doc.child("systemList"); pugi::xml_node systemList = doc.child("systemList");
if (!systemList) { if (!systemList) {
LOG(LogError) << "es_systems.cfg is missing the <systemList> tag"; LOG(LogError) << "es_systems.xml is missing the <systemList> tag";
return true; return true;
} }
@ -276,7 +268,7 @@ bool SystemData::loadConfig()
path = system.child("path").text().get(); path = system.child("path").text().get();
// If there is a %ROMPATH% variable set for the system, expand it. By doing this // If there is a %ROMPATH% variable set for the system, expand it. By doing this
// it's possible to use either absolute ROM paths in es_systems.cfg or to utilize // it's possible to use either absolute ROM paths in es_systems.xml or to utilize
// the ROM path configured as ROMDirectory in es_settings.cfg. If it's set to "" // the ROM path configured as ROMDirectory in es_settings.cfg. If it's set to ""
// in this configuration file, the default hardcoded path $HOME/ROMs/ will be used. // in this configuration file, the default hardcoded path $HOME/ROMs/ will be used.
path = Utils::String::replace(path, "%ROMPATH%", rompath); path = Utils::String::replace(path, "%ROMPATH%", rompath);
@ -346,7 +338,7 @@ bool SystemData::loadConfig()
if (name.empty()) { if (name.empty()) {
LOG(LogError) << LOG(LogError) <<
"A system in the es_systems.cfg file has no name defined, skipping entry"; "A system in the es_systems.xml file has no name defined, skipping entry";
continue; continue;
} }
else if (fullname.empty() || path.empty() || extensions.empty() || cmd.empty()) { else if (fullname.empty() || path.empty() || extensions.empty() || cmd.empty()) {
@ -413,38 +405,6 @@ bool SystemData::loadConfig()
return false; return false;
} }
bool SystemData::copyConfigTemplate(const std::string& path)
{
std::string systemsTemplateFile;;
LOG(LogInfo) <<
"Attempting to copy template es_systems.cfg file from the resources directory...";
#if defined(_WIN64)
systemsTemplateFile = ResourceManager::getInstance()->
getResourcePath(":/templates/es_systems.cfg_windows", false);
#elif defined(__APPLE__)
systemsTemplateFile = ResourceManager::getInstance()->
getResourcePath(":/templates/es_systems.cfg_macos", false);
#else
systemsTemplateFile = ResourceManager::getInstance()->
getResourcePath(":/templates/es_systems.cfg_unix", false);
#endif
if (systemsTemplateFile == "") {
LOG(LogError) << "Can't find the es_systems.cfg template file";
return true;
}
else if (Utils::FileSystem::copyFile(systemsTemplateFile, path, false)) {
LOG(LogError) << "Copying of es_systems.cfg template file failed";
return true;
}
LOG(LogInfo) << "Template es_systems.cfg file copied successfully";
return false;
}
void SystemData::deleteSystems() void SystemData::deleteSystems()
{ {
for (unsigned int i = 0; i < sSystemVector.size(); i++) for (unsigned int i = 0; i < sSystemVector.size(); i++)
@ -453,13 +413,49 @@ void SystemData::deleteSystems()
sSystemVector.clear(); sSystemVector.clear();
} }
std::string SystemData::getConfigPath(bool forWrite) std::string SystemData::getConfigPath(bool legacyWarning)
{ {
std::string path = Utils::FileSystem::getHomePath() + "/.emulationstation/es_systems.cfg"; if (legacyWarning) {
if (forWrite || Utils::FileSystem::exists(path)) std::string legacyConfigFile = Utils::FileSystem::getHomePath() +
return path; "/.emulationstation/es_systems.cfg";
return ""; if (Utils::FileSystem::exists(legacyConfigFile)) {
LOG(LogInfo) << "Found legacy systems configuration file \"" << legacyConfigFile <<
"\", to retain your customizations move it to "
"\"custom_systems/es_systems.xml\" or otherwise delete the file";
}
}
std::string customSystemsDirectory =
Utils::FileSystem::getHomePath() + "/.emulationstation/custom_systems";
if (!Utils::FileSystem::exists(customSystemsDirectory)) {
LOG(LogInfo) << "Creating custom systems directory \"" << customSystemsDirectory << "\"";
Utils::FileSystem::createDirectory(customSystemsDirectory);
if (!Utils::FileSystem::exists(customSystemsDirectory)) {
LOG(LogError) << "Couldn't create directory, permission problems?";
}
}
std::string path = customSystemsDirectory + "/es_systems.xml";
if (Utils::FileSystem::exists(path)) {
LOG(LogInfo) << "Found custom systems configuration file";
return path;
}
#if defined(_WIN64)
path = ResourceManager::getInstance()->
getResourcePath(":/systems/windows/es_systems.xml", true);
#elif defined(__APPLE__)
path = ResourceManager::getInstance()->
getResourcePath(":/systems/macos/es_systems.xml", true);
#else
path = ResourceManager::getInstance()->
getResourcePath(":/systems/unix/es_systems.xml", true);
#endif
return path;
} }
bool SystemData::createSystemDirectories() bool SystemData::createSystemDirectories()
@ -501,7 +497,7 @@ bool SystemData::createSystemDirectories()
#endif #endif
if (!res) { if (!res) {
LOG(LogError) << "Couldn't parse es_systems.cfg"; LOG(LogError) << "Couldn't parse es_systems.xml";
LOG(LogError) << res.description(); LOG(LogError) << res.description();
return true; return true;
} }
@ -510,7 +506,7 @@ bool SystemData::createSystemDirectories()
pugi::xml_node systemList = doc.child("systemList"); pugi::xml_node systemList = doc.child("systemList");
if (!systemList) { if (!systemList) {
LOG(LogError) << "es_systems.cfg is missing the <systemList> tag"; LOG(LogError) << "es_systems.xml is missing the <systemList> tag";
return true; return true;
} }

View file

@ -4,7 +4,7 @@
// SystemData.h // SystemData.h
// //
// Provides data structures for the game systems and populates and indexes them based // Provides data structures for the game systems and populates and indexes them based
// on the configuration in es_systems.cfg as well as the presence of game ROM files. // on the configuration in es_systems.xml as well as the presence of game ROM files.
// Also provides functions to read and write to the gamelist files and to handle theme // Also provides functions to read and write to the gamelist files and to handle theme
// loading. // loading.
// //
@ -70,11 +70,9 @@ public:
static void deleteSystems(); static void deleteSystems();
// Loads the systems configuration file at getConfigPath() and creates the systems. // Loads the systems configuration file at getConfigPath() and creates the systems.
static bool loadConfig(); static bool loadConfig();
static std::string getConfigPath(bool legacyWarning);
static bool copyConfigTemplate(const std::string& path); // Generates the game system directories and information files based on es_systems.xml.
static std::string getConfigPath(bool forWrite);
// Generates the game system directories and information files based on es_systems.cfg.
static bool createSystemDirectories(); static bool createSystemDirectories();
static std::vector<SystemData*> sSystemVector; static std::vector<SystemData*> sSystemVector;

View file

@ -206,7 +206,7 @@ GuiMetaDataEd::GuiMetaDataEd(
ed->setColor(TEXTCOLOR_USERMARKED); ed->setColor(TEXTCOLOR_USERMARKED);
}; };
std::string staticTextString = "Default value from es_systems.cfg:"; std::string staticTextString = "Default value from es_systems.xml:";
std::string defaultLaunchCommand = scraperParams.system-> std::string defaultLaunchCommand = scraperParams.system->
getSystemEnvData()->mLaunchCommand; getSystemEnvData()->mLaunchCommand;

View file

@ -55,8 +55,8 @@ bool forceInputConfig = false;
bool settingsNeedSaving = false; bool settingsNeedSaving = false;
enum loadSystemsReturnCode { enum loadSystemsReturnCode {
NO_LOADING_ERROR, LOADING_OK,
NO_SYSTEMS_FILE, INVALID_FILE,
NO_ROMS NO_ROMS
}; };
@ -372,10 +372,8 @@ bool verifyHomeFolderExists()
loadSystemsReturnCode loadSystemConfigFile() loadSystemsReturnCode loadSystemConfigFile()
{ {
if (SystemData::loadConfig()) { if (SystemData::loadConfig())
LOG(LogError) << "Could not parse systems configuration file (es_systems.cfg)"; return INVALID_FILE;
return NO_SYSTEMS_FILE;
}
if (SystemData::sSystemVector.size() == 0) { if (SystemData::sSystemVector.size() == 0) {
LOG(LogError) << "No game files were found, make sure that the system directories are " LOG(LogError) << "No game files were found, make sure that the system directories are "
@ -383,7 +381,7 @@ loadSystemsReturnCode loadSystemConfigFile()
return NO_ROMS; return NO_ROMS;
} }
return NO_LOADING_ERROR; return LOADING_OK;
} }
// Called on exit, assuming we get far enough to have the log initialized. // Called on exit, assuming we get far enough to have the log initialized.
@ -516,13 +514,12 @@ int main(int argc, char* argv[])
loadSystemsReturnCode loadSystemsStatus = loadSystemConfigFile(); loadSystemsReturnCode loadSystemsStatus = loadSystemConfigFile();
if (loadSystemsStatus) { if (loadSystemsStatus) {
// If there was an issue with installing the es_systems.cfg file from the // If there was an issue parsing the es_systems.xml file, display an error message.
// template directory, then display an error message and let the user quit. // If there were no game files found, give the option to the user to quit or to
// If there are no game files found, give the option to the user to quit or // configure a different ROM directory as well as to generate the game systems
// to configure a different ROM directory as well as to generate the systems
// directory structure. // directory structure.
if (loadSystemsStatus == NO_SYSTEMS_FILE) { if (loadSystemsStatus == INVALID_FILE) {
ViewController::get()->noSystemsFileDialog(); ViewController::get()->invalidSystemsFileDialog();
} }
else if (loadSystemsStatus == NO_ROMS) { else if (loadSystemsStatus == NO_ROMS) {
ViewController::get()->noGamesDialog(); ViewController::get()->noGamesDialog();

View file

@ -87,15 +87,15 @@ ViewController::~ViewController()
UIModeController::deinit(); UIModeController::deinit();
} }
void ViewController::noSystemsFileDialog() void ViewController::invalidSystemsFileDialog()
{ {
std::string errorMessage = std::string errorMessage =
"COULDN'T FIND THE SYSTEMS CONFIGURATION FILE.\n" "COULDN'T PARSE THE SYSTEMS CONFIGURATION FILE.\n"
"ATTEMPTED TO COPY A TEMPLATE es_systems.cfg FILE\n" "IF YOU HAVE A CUSTOMIZED es_systems.xml FILE, THEN\n"
"FROM THE EMULATIONSTATION RESOURCES DIRECTORY,\n" "SOMETHING IS LIKELY WRONG WITH YOUR XML SYNTAX.\n"
"BUT THIS FAILED. HAS EMULATIONSTATION BEEN PROPERLY\n" "IF YOU DON'T HAVE A CUSTOM SYSTEMS FILE, THEN THE\n"
"INSTALLED AND DO YOU HAVE WRITE PERMISSIONS TO \n" "EMULATIONSTATION INSTALLATION IS BROKEN. SEE THE\n"
"YOUR HOME DIRECTORY?"; "APPLICATION LOG FILE es_log.txt FOR ADDITIONAL INFO.";
mWindow->pushGui(new GuiMsgBox(mWindow, HelpStyle(), mWindow->pushGui(new GuiMsgBox(mWindow, HelpStyle(),
errorMessage.c_str(), errorMessage.c_str(),
@ -109,14 +109,13 @@ void ViewController::noSystemsFileDialog()
void ViewController::noGamesDialog() void ViewController::noGamesDialog()
{ {
mNoGamesErrorMessage = mNoGamesErrorMessage =
"THE SYSTEMS CONFIGURATION FILE EXISTS, BUT NO\n" "NO GAME FILES WERE FOUND. EITHER PLACE YOUR GAMES IN\n"
"GAME FILES WERE FOUND. EITHER PLACE YOUR GAMES\n" "THE CURRENTLY CONFIGURED ROM DIRECTORY OR CHANGE\n"
"IN THE CURRENTLY CONFIGURED ROM DIRECTORY OR\n" "ITS PATH USING THE BUTTON BELOW. OPTIONALLY THE ROM\n"
"CHANGE IT USING THE BUTTON BELOW. OPTIONALLY THE\n" "DIRECTORY STRUCTURE CAN BE GENERATED WHICH WILL\n"
"ROM DIRECTORY STRUCTURE CAN BE GENERATED WHICH\n" "CREATE A TEXT FILE FOR EACH SYSTEM PROVIDING SOME\n"
"WILL CREATE A TEXT FILE FOR EACH SYSTEM PROVIDING\n" "INFORMATION SUCH AS THE SUPPORTED FILE EXTENSIONS.\n"
"SOME INFO SUCH AS THE SUPPORTED FILE EXTENSIONS.\n" "THIS IS THE CURRENTLY CONFIGURED ROM PATH:\n";
"THIS IS THE CURRENTLY CONFIGURED ROM DIRECTORY:\n";
#if defined(_WIN64) #if defined(_WIN64)
mRomDirectory = Utils::String::replace(FileData::getROMDirectory(), "/", "\\"); mRomDirectory = Utils::String::replace(FileData::getROMDirectory(), "/", "\\");
@ -125,7 +124,7 @@ void ViewController::noGamesDialog()
#endif #endif
mNoGamesMessageBox = new GuiMsgBox(mWindow, HelpStyle(), mNoGamesErrorMessage + mRomDirectory, mNoGamesMessageBox = new GuiMsgBox(mWindow, HelpStyle(), mNoGamesErrorMessage + mRomDirectory,
"CHANGE ROM DIRECTORY", [this] { "CHANGE ROM PATH", [this] {
std::string currentROMDirectory; std::string currentROMDirectory;
#if defined(_WIN64) #if defined(_WIN64)
currentROMDirectory = Utils::String::replace(FileData::getROMDirectory(), "/", "\\"); currentROMDirectory = Utils::String::replace(FileData::getROMDirectory(), "/", "\\");
@ -136,8 +135,8 @@ void ViewController::noGamesDialog()
mWindow->pushGui(new GuiComplexTextEditPopup( mWindow->pushGui(new GuiComplexTextEditPopup(
mWindow, mWindow,
HelpStyle(), HelpStyle(),
"ENTER ROM DIRECTORY", "ENTER ROM DIRECTORY PATH",
"Currently configured directory:", "Currently configured path:",
currentROMDirectory, currentROMDirectory,
currentROMDirectory, currentROMDirectory,
[this](const std::string& newROMDirectory) { [this](const std::string& newROMDirectory) {
@ -166,7 +165,7 @@ void ViewController::noGamesDialog()
"CREATE DIRECTORIES", [this] { "CREATE DIRECTORIES", [this] {
mWindow->pushGui(new GuiMsgBox(mWindow, HelpStyle(), mWindow->pushGui(new GuiMsgBox(mWindow, HelpStyle(),
"THIS WILL CREATE DIRECTORIES FOR ALL THE\n" "THIS WILL CREATE DIRECTORIES FOR ALL THE\n"
"GAME SYSTEMS DEFINED IN es_systems.cfg\n\n" "GAME SYSTEMS DEFINED IN es_systems.xml\n\n"
"THIS MAY CREATE A LOT OF FOLDERS SO IT'S\n" "THIS MAY CREATE A LOT OF FOLDERS SO IT'S\n"
"ADVICED TO REMOVE THE ONES YOU DON'T NEED\n\n" "ADVICED TO REMOVE THE ONES YOU DON'T NEED\n\n"
"PROCEED?", "PROCEED?",

View file

@ -36,7 +36,7 @@ public:
virtual ~ViewController(); virtual ~ViewController();
// These functions are called from main(). // These functions are called from main().
void noSystemsFileDialog(); void invalidSystemsFileDialog();
void noGamesDialog(); void noGamesDialog();
// Try to completely populate the GameListView map. // Try to completely populate the GameListView map.

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- This is the EmulationStation-DE game systems configuration file for macOS. --> <!-- This is the ES-DE game systems configuration file for macOS. -->
<systemList> <systemList>
<system> <system>
<name>3do</name> <name>3do</name>

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- This is the EmulationStation-DE game systems configuration file for Unix. --> <!-- This is the ES-DE game systems configuration file for Unix. -->
<systemList> <systemList>
<system> <system>
<name>3do</name> <name>3do</name>

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- This is the EmulationStation-DE game systems configuration file for Unix, Flatpak specific. --> <!-- This is the ES-DE game systems configuration file for Unix, Flatpak specific. -->
<systemList> <systemList>
<system> <system>
<name>3do</name> <name>3do</name>

View file

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- This is the EmulationStation-DE game systems configuration file for Windows. --> <!-- This is the ES-DE game systems configuration file for Windows. -->
<systemList> <systemList>
<system> <system>
<name>3do</name> <name>3do</name>