diff --git a/es-app/src/CollectionSystemsManager.cpp b/es-app/src/CollectionSystemsManager.cpp index 54dcb845f..1ce5f9555 100644 --- a/es-app/src/CollectionSystemsManager.cpp +++ b/es-app/src/CollectionSystemsManager.cpp @@ -564,7 +564,7 @@ std::string CollectionSystemsManager::getValidNewCollectionName(std::string inNa 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 systemsInUse = getSystemsFromConfig(); // Get folders assigned to custom collections. std::vector autoSys = getCollectionThemeFolders(false); @@ -856,7 +856,7 @@ FileData* CollectionSystemsManager::updateCollectionFolderMetadata(SystemData* s std::vector CollectionSystemsManager::getUnusedSystemsFromTheme() { - // Get used systems in es_systems.cfg. + // Get used systems in es_systems.xml. std::vector systemsInUse = getSystemsFromConfig(); // Get available folders in theme. std::vector themeSys = getSystemsFromTheme(); diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 80a2f5a0c..81deec067 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -810,7 +810,7 @@ void FileData::launchGame(Window* window) 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. auto emuPathPos = command.find("%EMUPATH%"); if (emuPathPos != std::string::npos) { @@ -856,7 +856,7 @@ void FileData::launchGame(Window* window) } } 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) << 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. auto corePos = command.find("%COREPATH%"); if (corePos != std::string::npos && emulatorCorePath.size() > 0) { @@ -914,7 +914,7 @@ void FileData::launchGame(Window* window) } } 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) << commandRaw; @@ -938,7 +938,7 @@ void FileData::launchGame(Window* window) } } 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"; GuiInfoPopup* s = new GuiInfoPopup(window, "ERROR: NO CORE PATHS CONFIGURED, " \ "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 // 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 - // es_systems.cfg.) + // es_systems.xml.) std::string emuExecutable; std::string exePath; diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index d199b9c64..d06fe56ff 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -4,7 +4,7 @@ // SystemData.cpp // // 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 // loading. // @@ -106,7 +106,7 @@ void SystemData::setIsGameSystemStatus() { // 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 - // list but for now a simple string comparison is more performant. + // list but for now a simple string comparison is enough. mIsGameSystem = (mName != "retropie"); } @@ -230,16 +230,9 @@ bool SystemData::loadConfig() { deleteSystems(); - std::string path = getConfigPath(false); + std::string path = getConfigPath(true); 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 << "\"..."; pugi::xml_document doc; @@ -250,8 +243,7 @@ bool SystemData::loadConfig() #endif if (!res) { - LOG(LogError) << "Couldn't parse es_systems.cfg"; - LOG(LogError) << res.description(); + LOG(LogError) << "Couldn't parse es_systems.xml: " << res.description(); return true; } @@ -259,7 +251,7 @@ bool SystemData::loadConfig() pugi::xml_node systemList = doc.child("systemList"); if (!systemList) { - LOG(LogError) << "es_systems.cfg is missing the tag"; + LOG(LogError) << "es_systems.xml is missing the tag"; return true; } @@ -276,7 +268,7 @@ bool SystemData::loadConfig() path = system.child("path").text().get(); // 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 "" // in this configuration file, the default hardcoded path $HOME/ROMs/ will be used. path = Utils::String::replace(path, "%ROMPATH%", rompath); @@ -346,7 +338,7 @@ bool SystemData::loadConfig() if (name.empty()) { 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; } else if (fullname.empty() || path.empty() || extensions.empty() || cmd.empty()) { @@ -413,38 +405,6 @@ bool SystemData::loadConfig() 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() { for (unsigned int i = 0; i < sSystemVector.size(); i++) @@ -453,13 +413,49 @@ void SystemData::deleteSystems() 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 (forWrite || Utils::FileSystem::exists(path)) - return path; + if (legacyWarning) { + std::string legacyConfigFile = Utils::FileSystem::getHomePath() + + "/.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() @@ -501,7 +497,7 @@ bool SystemData::createSystemDirectories() #endif if (!res) { - LOG(LogError) << "Couldn't parse es_systems.cfg"; + LOG(LogError) << "Couldn't parse es_systems.xml"; LOG(LogError) << res.description(); return true; } @@ -510,7 +506,7 @@ bool SystemData::createSystemDirectories() pugi::xml_node systemList = doc.child("systemList"); if (!systemList) { - LOG(LogError) << "es_systems.cfg is missing the tag"; + LOG(LogError) << "es_systems.xml is missing the tag"; return true; } diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index 80d4b7a5c..1d5671aa5 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -4,7 +4,7 @@ // SystemData.h // // 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 // loading. // @@ -70,11 +70,9 @@ public: static void deleteSystems(); // Loads the systems configuration file at getConfigPath() and creates the systems. static bool loadConfig(); + static std::string getConfigPath(bool legacyWarning); - static bool copyConfigTemplate(const std::string& path); - static std::string getConfigPath(bool forWrite); - - // Generates the game system directories and information files based on es_systems.cfg. + // Generates the game system directories and information files based on es_systems.xml. static bool createSystemDirectories(); static std::vector sSystemVector; diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 0d160ec92..57af195fa 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -206,7 +206,7 @@ GuiMetaDataEd::GuiMetaDataEd( 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-> getSystemEnvData()->mLaunchCommand; diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index a0d4a864e..4dc5a95e2 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -55,8 +55,8 @@ bool forceInputConfig = false; bool settingsNeedSaving = false; enum loadSystemsReturnCode { - NO_LOADING_ERROR, - NO_SYSTEMS_FILE, + LOADING_OK, + INVALID_FILE, NO_ROMS }; @@ -372,10 +372,8 @@ bool verifyHomeFolderExists() loadSystemsReturnCode loadSystemConfigFile() { - if (SystemData::loadConfig()) { - LOG(LogError) << "Could not parse systems configuration file (es_systems.cfg)"; - return NO_SYSTEMS_FILE; - } + if (SystemData::loadConfig()) + return INVALID_FILE; if (SystemData::sSystemVector.size() == 0) { 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_LOADING_ERROR; + return LOADING_OK; } // 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(); if (loadSystemsStatus) { - // If there was an issue with installing the es_systems.cfg file from the - // template directory, then display an error message and let the user quit. - // If there are no game files found, give the option to the user to quit or - // to configure a different ROM directory as well as to generate the systems + // If there was an issue parsing the es_systems.xml file, display an error message. + // If there were no game files found, give the option to the user to quit or to + // configure a different ROM directory as well as to generate the game systems // directory structure. - if (loadSystemsStatus == NO_SYSTEMS_FILE) { - ViewController::get()->noSystemsFileDialog(); + if (loadSystemsStatus == INVALID_FILE) { + ViewController::get()->invalidSystemsFileDialog(); } else if (loadSystemsStatus == NO_ROMS) { ViewController::get()->noGamesDialog(); diff --git a/es-app/src/views/ViewController.cpp b/es-app/src/views/ViewController.cpp index 29cca419d..0cc196889 100644 --- a/es-app/src/views/ViewController.cpp +++ b/es-app/src/views/ViewController.cpp @@ -87,15 +87,15 @@ ViewController::~ViewController() UIModeController::deinit(); } -void ViewController::noSystemsFileDialog() +void ViewController::invalidSystemsFileDialog() { std::string errorMessage = - "COULDN'T FIND THE SYSTEMS CONFIGURATION FILE.\n" - "ATTEMPTED TO COPY A TEMPLATE es_systems.cfg FILE\n" - "FROM THE EMULATIONSTATION RESOURCES DIRECTORY,\n" - "BUT THIS FAILED. HAS EMULATIONSTATION BEEN PROPERLY\n" - "INSTALLED AND DO YOU HAVE WRITE PERMISSIONS TO \n" - "YOUR HOME DIRECTORY?"; + "COULDN'T PARSE THE SYSTEMS CONFIGURATION FILE.\n" + "IF YOU HAVE A CUSTOMIZED es_systems.xml FILE, THEN\n" + "SOMETHING IS LIKELY WRONG WITH YOUR XML SYNTAX.\n" + "IF YOU DON'T HAVE A CUSTOM SYSTEMS FILE, THEN THE\n" + "EMULATIONSTATION INSTALLATION IS BROKEN. SEE THE\n" + "APPLICATION LOG FILE es_log.txt FOR ADDITIONAL INFO."; mWindow->pushGui(new GuiMsgBox(mWindow, HelpStyle(), errorMessage.c_str(), @@ -109,14 +109,13 @@ void ViewController::noSystemsFileDialog() void ViewController::noGamesDialog() { mNoGamesErrorMessage = - "THE SYSTEMS CONFIGURATION FILE EXISTS, BUT NO\n" - "GAME FILES WERE FOUND. EITHER PLACE YOUR GAMES\n" - "IN THE CURRENTLY CONFIGURED ROM DIRECTORY OR\n" - "CHANGE IT USING THE BUTTON BELOW. OPTIONALLY THE\n" - "ROM DIRECTORY STRUCTURE CAN BE GENERATED WHICH\n" - "WILL CREATE A TEXT FILE FOR EACH SYSTEM PROVIDING\n" - "SOME INFO SUCH AS THE SUPPORTED FILE EXTENSIONS.\n" - "THIS IS THE CURRENTLY CONFIGURED ROM DIRECTORY:\n"; + "NO GAME FILES WERE FOUND. EITHER PLACE YOUR GAMES IN\n" + "THE CURRENTLY CONFIGURED ROM DIRECTORY OR CHANGE\n" + "ITS PATH USING THE BUTTON BELOW. OPTIONALLY THE ROM\n" + "DIRECTORY STRUCTURE CAN BE GENERATED WHICH WILL\n" + "CREATE A TEXT FILE FOR EACH SYSTEM PROVIDING SOME\n" + "INFORMATION SUCH AS THE SUPPORTED FILE EXTENSIONS.\n" + "THIS IS THE CURRENTLY CONFIGURED ROM PATH:\n"; #if defined(_WIN64) mRomDirectory = Utils::String::replace(FileData::getROMDirectory(), "/", "\\"); @@ -125,7 +124,7 @@ void ViewController::noGamesDialog() #endif mNoGamesMessageBox = new GuiMsgBox(mWindow, HelpStyle(), mNoGamesErrorMessage + mRomDirectory, - "CHANGE ROM DIRECTORY", [this] { + "CHANGE ROM PATH", [this] { std::string currentROMDirectory; #if defined(_WIN64) currentROMDirectory = Utils::String::replace(FileData::getROMDirectory(), "/", "\\"); @@ -136,8 +135,8 @@ void ViewController::noGamesDialog() mWindow->pushGui(new GuiComplexTextEditPopup( mWindow, HelpStyle(), - "ENTER ROM DIRECTORY", - "Currently configured directory:", + "ENTER ROM DIRECTORY PATH", + "Currently configured path:", currentROMDirectory, currentROMDirectory, [this](const std::string& newROMDirectory) { @@ -166,7 +165,7 @@ void ViewController::noGamesDialog() "CREATE DIRECTORIES", [this] { mWindow->pushGui(new GuiMsgBox(mWindow, HelpStyle(), "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" "ADVICED TO REMOVE THE ONES YOU DON'T NEED\n\n" "PROCEED?", diff --git a/es-app/src/views/ViewController.h b/es-app/src/views/ViewController.h index 6f3d6475e..ec3e2ade3 100644 --- a/es-app/src/views/ViewController.h +++ b/es-app/src/views/ViewController.h @@ -36,7 +36,7 @@ public: virtual ~ViewController(); // These functions are called from main(). - void noSystemsFileDialog(); + void invalidSystemsFileDialog(); void noGamesDialog(); // Try to completely populate the GameListView map. diff --git a/resources/templates/es_systems.cfg_macos b/resources/systems/macos/es_systems.xml similarity index 99% rename from resources/templates/es_systems.cfg_macos rename to resources/systems/macos/es_systems.xml index 4078cda2a..bd1242553 100644 --- a/resources/templates/es_systems.cfg_macos +++ b/resources/systems/macos/es_systems.xml @@ -1,5 +1,5 @@ - + 3do diff --git a/resources/templates/es_systems.cfg_unix b/resources/systems/unix/es_systems.xml similarity index 99% rename from resources/templates/es_systems.cfg_unix rename to resources/systems/unix/es_systems.xml index 30a19e203..48995b6b6 100644 --- a/resources/templates/es_systems.cfg_unix +++ b/resources/systems/unix/es_systems.xml @@ -1,5 +1,5 @@ - + 3do diff --git a/resources/templates/es_systems.cfg_unix_flatpak b/resources/systems/unix/es_systems_flatpak.xml similarity index 99% rename from resources/templates/es_systems.cfg_unix_flatpak rename to resources/systems/unix/es_systems_flatpak.xml index 503bc40f4..05376083a 100644 --- a/resources/templates/es_systems.cfg_unix_flatpak +++ b/resources/systems/unix/es_systems_flatpak.xml @@ -1,5 +1,5 @@ - + 3do diff --git a/resources/templates/es_systems.cfg_windows b/resources/systems/windows/es_systems.xml similarity index 99% rename from resources/templates/es_systems.cfg_windows rename to resources/systems/windows/es_systems.xml index 3f0b4a299..c9a6c4bb1 100644 --- a/resources/templates/es_systems.cfg_windows +++ b/resources/systems/windows/es_systems.xml @@ -1,5 +1,5 @@ - + 3do