diff --git a/es-app/CMakeLists.txt b/es-app/CMakeLists.txt index 48a33fcff..ea5bfc162 100644 --- a/es-app/CMakeLists.txt +++ b/es-app/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT # -# EmulationStation Desktop Edition +# ES-DE # CMakeLists.txt (es-app) # # CMake configuration for es-app diff --git a/es-app/src/ApplicationUpdater.cpp b/es-app/src/ApplicationUpdater.cpp index 49e2f77d9..eade0ca9b 100644 --- a/es-app/src/ApplicationUpdater.cpp +++ b/es-app/src/ApplicationUpdater.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ApplicationUpdater.cpp // // Checks for application updates. @@ -211,14 +211,14 @@ void ApplicationUpdater::parseFile() #if (LOCAL_TESTING_FILE) LOG(LogWarning) << "ApplicationUpdater: Using local \"latest_release.json\" testing file"; - const std::string localReleaseFile {Utils::FileSystem::getHomePath() + - "/.emulationstation/latest_release.json"}; + const std::filesystem::path localReleaseFile { + Utils::FileSystem::getAppDataDirectory().append("latest_release.json")}; - if (!Utils::FileSystem::exists(localReleaseFile)) + if (!Utils::FileSystem::existsSTD(localReleaseFile)) throw std::runtime_error("Local testing file not found"); const ResourceData& localReleaseFileData { - ResourceManager::getInstance().getFileData(localReleaseFile)}; + ResourceManager::getInstance().getFileData(localReleaseFile.string())}; doc.Parse(reinterpret_cast(localReleaseFileData.ptr.get()), localReleaseFileData.length); #else diff --git a/es-app/src/ApplicationUpdater.h b/es-app/src/ApplicationUpdater.h index 23b1bb48b..17e2ebd8a 100644 --- a/es-app/src/ApplicationUpdater.h +++ b/es-app/src/ApplicationUpdater.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ApplicationUpdater.h // // Checks for application updates. diff --git a/es-app/src/CollectionSystemsManager.cpp b/es-app/src/CollectionSystemsManager.cpp index 0f9491a15..ce98c16b9 100644 --- a/es-app/src/CollectionSystemsManager.cpp +++ b/es-app/src/CollectionSystemsManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CollectionSystemsManager.cpp // // Manages collections of the following two types: @@ -1437,7 +1437,7 @@ std::vector CollectionSystemsManager::getSystemsFromConfig() std::vector configPaths {SystemData::getConfigPath()}; // Here we don't honor the tag which may be present in the custom es_systems.xml - // file under ~/.emulationstation/custom_systems as we really want to include all the themes + // file under /custom_systems as we really want to include all the themes // supported by ES-DE. Otherwise a user may accidentally create a custom collection that // corresponds to a supported theme. for (auto path : configPaths) { @@ -1625,6 +1625,5 @@ std::string CollectionSystemsManager::getCustomCollectionConfigPath( std::string CollectionSystemsManager::getCollectionsFolder() { - return Utils::FileSystem::getGenericPath(Utils::FileSystem::getHomePath() + - "/.emulationstation/collections"); + return Utils::FileSystem::getAppDataDirectory().append("collections").string(); } diff --git a/es-app/src/CollectionSystemsManager.h b/es-app/src/CollectionSystemsManager.h index 344fb969b..35162271e 100644 --- a/es-app/src/CollectionSystemsManager.h +++ b/es-app/src/CollectionSystemsManager.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // CollectionSystemsManager.h // // Manages collections of the following two types: diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 889b26b7e..57233f33a 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -152,6 +152,10 @@ const std::vector FileData::getChildrenRecursive() const const std::string FileData::getROMDirectory() { +#if defined(__ANDROID__) + return AndroidVariables::sROMDirectory.string(); +#endif + const std::string& romDirSetting {Settings::getInstance()->getString("ROMDirectory")}; std::string romDirPath; @@ -184,8 +188,9 @@ const std::string FileData::getMediaDirectory() const std::string& mediaDirSetting {Settings::getInstance()->getString("MediaDirectory")}; std::string mediaDirPath; - if (mediaDirSetting == "") { - mediaDirPath = Utils::FileSystem::getHomePath() + "/.emulationstation/downloaded_media/"; + if (mediaDirSetting.empty()) { + mediaDirPath = + Utils::FileSystem::getAppDataDirectory().append("downloaded_media").string() + "/"; } else { mediaDirPath = mediaDirSetting; diff --git a/es-app/src/SystemData.cpp b/es-app/src/SystemData.cpp index 12f1c390a..43f419555 100644 --- a/es-app/src/SystemData.cpp +++ b/es-app/src/SystemData.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SystemData.cpp // // Provides data structures for the game systems and populates and indexes them based @@ -41,11 +41,11 @@ FindRules::FindRules() void FindRules::loadFindRules() { - std::vector paths; - std::string filePath {Utils::FileSystem::getHomePath() + "/.emulationstation/custom_systems" + - "/es_find_rules.xml"}; - - if (Utils::FileSystem::exists(filePath)) { + std::vector paths; + std::filesystem::path filePath {Utils::FileSystem::getAppDataDirectory() + .append("custom_systems") + .append("es_find_rules.xml")}; + if (Utils::FileSystem::existsSTD(filePath)) { paths.emplace_back(filePath); LOG(LogInfo) << "Found custom find rules configuration file"; } @@ -64,28 +64,28 @@ void FindRules::loadFindRules() ResourceManager::getInstance().getResourcePath(":/systems/unix/es_find_rules.xml", false); #endif - if (filePath == "" && paths.empty()) { + if (filePath.empty() && paths.empty()) { LOG(LogWarning) << "No find rules configuration file found"; return; } - if (filePath != "") + if (!filePath.empty()) paths.emplace_back(filePath); for (auto& path : paths) { #if defined(_WIN64) LOG(LogInfo) << "Parsing find rules configuration file \"" - << Utils::String::replace(path, "/", "\\") << "\"..."; + << Utils::String::replace(path.string(), "/", "\\") << "\"..."; #else - LOG(LogInfo) << "Parsing find rules configuration file \"" << path << "\"..."; + LOG(LogInfo) << "Parsing find rules configuration file \"" << path.string() << "\"..."; #endif pugi::xml_document doc; #if defined(_WIN64) const pugi::xml_parse_result& res { - doc.load_file(Utils::String::stringToWideString(path).c_str())}; + doc.load_file(Utils::String::stringToWideString(path.string()).c_str())}; #else - const pugi::xml_parse_result& res {doc.load_file(path.c_str())}; + const pugi::xml_parse_result& res {doc.load_file(path.string().c_str())}; #endif if (!res) { LOG(LogError) << "Couldn't parse es_find_rules.xml: " << res.description(); @@ -848,10 +848,10 @@ bool SystemData::loadConfig() void SystemData::loadSortingConfig() { const std::string sortSetting {Settings::getInstance()->getString("SystemsSorting")}; - const std::string customFilePath {Utils::FileSystem::getHomePath() + - "/.emulationstation/custom_systems" + - "/es_systems_sorting.xml"}; - const bool customFileExists {Utils::FileSystem::exists(customFilePath)}; + const std::filesystem::path customFilePath {Utils::FileSystem::getAppDataDirectory() + .append("custom_systems") + .append("es_systems_sorting.xml")}; + const bool customFileExists {Utils::FileSystem::existsSTD(customFilePath)}; std::string path; bool bundledFile {false}; @@ -882,10 +882,10 @@ void SystemData::loadSortingConfig() "bundled file has been selected"; } else if (!bundledFile && customFileExists) { - path = customFilePath; + path = customFilePath.string(); } - if (path == "") { + if (path.empty()) { LOG(LogDebug) << "No systems sorting file loaded"; return; } @@ -957,18 +957,19 @@ std::vector SystemData::getConfigPath() { std::vector paths; - const std::string& customSystemsDirectory {Utils::FileSystem::getHomePath() + - "/.emulationstation/custom_systems"}; + const std::filesystem::path customSystemsDirectory { + Utils::FileSystem::getAppDataDirectory().append("custom_systems")}; - if (!Utils::FileSystem::exists(customSystemsDirectory)) { - LOG(LogInfo) << "Creating custom systems directory \"" << customSystemsDirectory << "\"..."; - Utils::FileSystem::createDirectory(customSystemsDirectory); - if (!Utils::FileSystem::exists(customSystemsDirectory)) { + if (!Utils::FileSystem::existsSTD(customSystemsDirectory)) { + LOG(LogInfo) << "Creating custom systems directory \"" << customSystemsDirectory.string() + << "\"..."; + Utils::FileSystem::createDirectory(customSystemsDirectory.string()); + if (!Utils::FileSystem::existsSTD(customSystemsDirectory)) { LOG(LogError) << "Couldn't create directory, permission problems?"; } } - std::string path {customSystemsDirectory + "/es_systems.xml"}; + std::string path {customSystemsDirectory.string() + "/es_systems.xml"}; if (Utils::FileSystem::exists(path)) { LOG(LogInfo) << "Found custom systems configuration file"; @@ -1307,36 +1308,36 @@ SystemData* SystemData::getPrev() const std::string SystemData::getGamelistPath(bool forWrite) const { - std::string filePath {mRootFolder->getPath() + "/gamelist.xml"}; - const std::string gamelistPath {Utils::FileSystem::getHomePath() + - "/.emulationstation/gamelists/" + mName}; + std::filesystem::path filePath {mRootFolder->getPath() + "/gamelist.xml"}; + const std::filesystem::path gamelistPath { + Utils::FileSystem::getAppDataDirectory().append("gamelists").append(mName)}; - if (Utils::FileSystem::exists(filePath)) { + if (Utils::FileSystem::existsSTD(filePath)) { if (Settings::getInstance()->getBool("LegacyGamelistFileLocation")) { - return filePath; + return filePath.string(); } else { #if defined(_WIN64) LOG(LogWarning) << "Found a gamelist.xml file in \"" << Utils::String::replace(mRootFolder->getPath(), "/", "\\") << "\\\" which will not get loaded, move it to \"" - << Utils::String::replace(gamelistPath, "/", "\\") - << "\\\" or otherwise delete it"; + << gamelistPath.string() << "\\\" or otherwise delete it"; #else LOG(LogWarning) << "Found a gamelist.xml file in \"" << mRootFolder->getPath() - << "/\" which will not get loaded, move it to \"" << gamelistPath - << "/\" or otherwise delete it"; + << "/\" which will not get loaded, move it to \"" + << gamelistPath.string() << "/\" or otherwise delete it"; #endif } } - filePath = gamelistPath + "/gamelist.xml"; + filePath = gamelistPath; + filePath.append("gamelist.xml"); // Make sure the directory exists if we're going to write to it, or crashes will happen. if (forWrite) - Utils::FileSystem::createDirectory(Utils::FileSystem::getParent(filePath)); - if (forWrite || Utils::FileSystem::exists(filePath)) - return filePath; + Utils::FileSystem::createDirectory(Utils::FileSystem::getParent(filePath.string())); + if (forWrite || Utils::FileSystem::existsSTD(filePath)) + return filePath.string(); return ""; } diff --git a/es-app/src/SystemData.h b/es-app/src/SystemData.h index d352b27d8..53b636213 100644 --- a/es-app/src/SystemData.h +++ b/es-app/src/SystemData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // SystemData.h // // Provides data structures for the game systems and populates and indexes them based diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 8eff03a15..09a6806d5 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMenu.cpp // // Main menu. @@ -1183,7 +1183,8 @@ void GuiMenu::openOtherOptions() rowMediaDir.addElement(bracketMediaDirectory, false); std::string titleMediaDir {"ENTER GAME MEDIA DIRECTORY"}; std::string mediaDirectoryStaticText {"Default directory:"}; - std::string defaultDirectoryText {"~/.emulationstation/downloaded_media/"}; + std::string defaultDirectoryText { + Utils::FileSystem::getAppDataDirectory().append("downloaded_media").string()}; std::string initValueMediaDir {Settings::getInstance()->getString("MediaDirectory")}; bool multiLineMediaDir {false}; auto updateValMediaDir = [this](const std::string& newVal) { diff --git a/es-app/src/guis/GuiMenu.h b/es-app/src/guis/GuiMenu.h index 924f92137..1c2db4d7c 100644 --- a/es-app/src/guis/GuiMenu.h +++ b/es-app/src/guis/GuiMenu.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiMenu.h // // Main menu. diff --git a/es-app/src/guis/GuiThemeDownloader.cpp b/es-app/src/guis/GuiThemeDownloader.cpp index 018d4ac52..c734b638c 100644 --- a/es-app/src/guis/GuiThemeDownloader.cpp +++ b/es-app/src/guis/GuiThemeDownloader.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiThemeDownloader.cpp // // Theme downloader. @@ -174,28 +174,33 @@ GuiThemeDownloader::GuiThemeDownloader(std::function updateCallback) std::promise().swap(mPromise); mFuture = mPromise.get_future(); - const std::string defaultUserThemeDir {Utils::FileSystem::getHomePath() + - "/.emulationstation/themes"}; - std::string userThemeDirSetting {Utils::FileSystem::expandHomePath( +#if defined(__ANDROID__) + mThemeDirectory = Utils::FileSystem::getInternalAppDataDirectory().append("themes").string(); +#else + const std::filesystem::path defaultUserThemeDir { + Utils::FileSystem::getAppDataDirectory().append("themes")}; + const std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath( Settings::getInstance()->getString("UserThemeDirectory"))}; + #if defined(_WIN64) mThemeDirectory = Utils::String::replace(mThemeDirectory, "\\", "/"); #endif - if (userThemeDirSetting == "") { - mThemeDirectory = defaultUserThemeDir; + if (userThemeDirSetting.empty()) { + mThemeDirectory = defaultUserThemeDir.string(); } - else if (Utils::FileSystem::isDirectory(userThemeDirSetting) || - Utils::FileSystem::isSymlink(userThemeDirSetting)) { - mThemeDirectory = userThemeDirSetting; + else if (Utils::FileSystem::isDirectorySTD(userThemeDirSetting) || + Utils::FileSystem::isSymlinkSTD(userThemeDirSetting)) { + mThemeDirectory = userThemeDirSetting.string(); } else { LOG(LogWarning) << "GuiThemeDownloader: Requested user theme directory \"" - << userThemeDirSetting + << userThemeDirSetting.string() << "\" does not exist or is not a directory, reverting to \"" - << defaultUserThemeDir << "\""; - mThemeDirectory = defaultUserThemeDir; + << defaultUserThemeDir.string() << "\""; + mThemeDirectory = defaultUserThemeDir.string(); } +#endif // __ANDROID__ if (mThemeDirectory.back() != '/') mThemeDirectory.append("/"); @@ -588,8 +593,8 @@ void GuiThemeDownloader::parseThemesList() #if (LOCAL_TESTING_FILE) LOG(LogWarning) << "GuiThemeDownloader: Using local \"themes.json\" testing file"; - const std::string themesFile {Utils::FileSystem::getHomePath() + - "/.emulationstation/themes.json"}; + const std::string themesFile { + Utils::FileSystem::getAppDataDirectory().append("themes.json").string()}; #else const std::string themesFile {mThemeDirectory + "themes-list/themes.json"}; #endif diff --git a/es-app/src/guis/GuiThemeDownloader.h b/es-app/src/guis/GuiThemeDownloader.h index c8bbec35e..ce1e8dd18 100644 --- a/es-app/src/guis/GuiThemeDownloader.h +++ b/es-app/src/guis/GuiThemeDownloader.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GuiThemeDownloader.h // // Theme downloader. diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 7681547de..446d66c6f 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -441,25 +441,21 @@ bool parseArguments(const std::vector& arguments) return true; } -bool checkApplicationHomeDirectory() +bool checkApplicationDataDirectory() { - // Check that the application home directory exists, otherwise create it. - std::string home {Utils::FileSystem::getHomePath()}; - std::string applicationHome {home + "/.emulationstation"}; - if (!Utils::FileSystem::exists(applicationHome)) { -#if defined(_WIN64) - std::cout << "First startup, creating application home directory \"" - << Utils::String::replace(applicationHome, "/", "\\") << "\"\n"; -#elif defined(__ANDROID__) + // Check that the application data directory exists, otherwise create it. + const std::filesystem::path applicationData {Utils::FileSystem::getAppDataDirectory()}; + if (!Utils::FileSystem::existsSTD(applicationData)) { +#if defined(__ANDROID__) __android_log_print(ANDROID_LOG_VERBOSE, ANDROID_APPLICATION_ID, - "First startup, creating application home directory \"%s\"", - applicationHome.c_str()); + "First startup, creating application data directory \"%s\"", + applicationData.string().c_str()); #else - std::cout << "First startup, creating application home directory \"" << applicationHome - << "\"\n"; + std::cout << "First startup, creating application data directory \"" + << applicationData.string() << "\"\n"; #endif - Utils::FileSystem::createDirectory(applicationHome); - if (!Utils::FileSystem::exists(applicationHome)) { + Utils::FileSystem::createDirectory(applicationData.string()); + if (!Utils::FileSystem::existsSTD(applicationData)) { #if defined(__ANDROID__) __android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID, "Error: Couldn't create directory, permission problems?"); @@ -535,6 +531,10 @@ int main(int argc, char* argv[]) std::locale::global(std::locale("C")); +#if defined(__ANDROID__) + Utils::Platform::Android::setDataDirectories(); +#endif + #if defined(__APPLE__) // This is a workaround to disable the incredibly annoying save state functionality in // macOS which forces a restore of the previous window state. The problem is that this @@ -590,8 +590,8 @@ int main(int argc, char* argv[]) FreeImage_Initialise(); #endif - // If ~/.emulationstation doesn't exist and cannot be created, bail. - if (!checkApplicationHomeDirectory()) + // If the application data directory doesn't exist and can't be created, then exit. + if (!checkApplicationDataDirectory()) return 1; // Start the logger. @@ -632,8 +632,8 @@ int main(int argc, char* argv[]) // Check if the configuration file exists, and if not, create it. // This should only happen on first application startup. - if (!Utils::FileSystem::exists(Utils::FileSystem::getHomePath() + - "/.emulationstation/es_settings.xml")) { + if (!Utils::FileSystem::existsSTD( + Utils::FileSystem::getAppDataDirectory().append("es_settings.xml"))) { LOG(LogInfo) << "Settings file es_settings.xml does not exist, creating it..."; Settings::getInstance()->saveFile(); } @@ -659,63 +659,60 @@ int main(int argc, char* argv[]) Settings::getInstance()->saveFile(); } - // Create the gamelists directory in the application home folder. - const std::string gamelistsDir {Utils::FileSystem::getHomePath() + - "/.emulationstation/gamelists"}; - if (!Utils::FileSystem::exists(gamelistsDir)) { -#if defined(_WIN64) - LOG(LogInfo) << "Creating gamelists directory \"" - << Utils::String::replace(gamelistsDir, "/", "\\") << "\"..."; -#else - LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir << "\"..."; -#endif - Utils::FileSystem::createDirectory(gamelistsDir); - if (!Utils::FileSystem::exists(gamelistsDir)) { + // Create the gamelists folder in the application data directory. + const std::filesystem::path gamelistsDir { + Utils::FileSystem::getAppDataDirectory().append("gamelists")}; + if (!Utils::FileSystem::existsSTD(gamelistsDir)) { + LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir.string() << "\"..."; + Utils::FileSystem::createDirectory(gamelistsDir.string()); + if (!Utils::FileSystem::existsSTD(gamelistsDir)) { LOG(LogWarning) << "Couldn't create directory, permission problems?\n"; } } - // Create the themes directory in the application home directory (or elsewhere if the - // UserThemeDirectory setting has been defined). - const std::string defaultUserThemeDir {Utils::FileSystem::getHomePath() + - "/.emulationstation/themes"}; - std::string userThemeDirSetting {Utils::FileSystem::expandHomePath( - Settings::getInstance()->getString("UserThemeDirectory"))}; -#if defined(_WIN64) - userThemeDirSetting = Utils::String::replace(userThemeDirSetting, "\\", "/"); -#endif - std::string userThemeDirectory; +#if defined(__ANDROID__) + const std::filesystem::path themeDir { + Utils::FileSystem::getAppDataDirectory().append("themes")}; + if (!Utils::FileSystem::existsSTD(themeDir)) { + LOG(LogInfo) << "Creating themes directory \"" << themeDir.string() << "\"..."; - if (userThemeDirSetting == "") + Utils::FileSystem::createDirectory(themeDir.string()); + if (!Utils::FileSystem::existsSTD(themeDir)) { + LOG(LogWarning) << "Couldn't create directory, permission problems?"; + } + } +#else + // Create the themes folder in the application data directory (or elsewhere if the + // UserThemeDirectory setting has been defined). + const std::filesystem::path defaultUserThemeDir { + Utils::FileSystem::getAppDataDirectory().append("themes")}; + std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath( + Settings::getInstance()->getString("UserThemeDirectory"))}; + std::filesystem::path userThemeDirectory; + + if (userThemeDirSetting.empty()) userThemeDirectory = defaultUserThemeDir; else userThemeDirectory = userThemeDirSetting; - if (!Utils::FileSystem::exists(userThemeDirectory)) { -#if defined(_WIN64) - LOG(LogInfo) << "Creating user theme directory \"" - << Utils::String::replace(userThemeDirectory, "/", "\\") << "\"..."; -#else - LOG(LogInfo) << "Creating themes directory \"" << userThemeDirectory << "\"..."; -#endif - Utils::FileSystem::createDirectory(userThemeDirectory); - if (!Utils::FileSystem::exists(userThemeDirectory)) { + if (!Utils::FileSystem::existsSTD(userThemeDirectory)) { + LOG(LogInfo) << "Creating themes directory \"" << userThemeDirectory.string() << "\"..."; + + Utils::FileSystem::createDirectory(userThemeDirectory.string()); + if (!Utils::FileSystem::existsSTD(userThemeDirectory)) { LOG(LogWarning) << "Couldn't create directory, permission problems?"; } } - - // Create the scripts directory in the application home folder. This is only required - // for custom event scripts so it's also created as a convenience. - const std::string scriptsDir {Utils::FileSystem::getHomePath() + "/.emulationstation/scripts"}; - if (!Utils::FileSystem::exists(scriptsDir)) { -#if defined(_WIN64) - LOG(LogInfo) << "Creating scripts directory \"" - << Utils::String::replace(scriptsDir, "/", "\\") << "\"..."; -#else - LOG(LogInfo) << "Creating scripts directory \"" << scriptsDir << "\"..."; #endif - Utils::FileSystem::createDirectory(scriptsDir); - if (!Utils::FileSystem::exists(scriptsDir)) { + + // Create the scripts folder in the application data directory. This is only required + // for custom event scripts so it's also created as a convenience. + const std::filesystem::path scriptsDir { + Utils::FileSystem::getAppDataDirectory().append("scripts")}; + if (!Utils::FileSystem::existsSTD(scriptsDir)) { + LOG(LogInfo) << "Creating scripts directory \"" << scriptsDir.string() << "\"..."; + Utils::FileSystem::createDirectory(scriptsDir.string()); + if (!Utils::FileSystem::existsSTD(scriptsDir)) { LOG(LogWarning) << "Couldn't create directory, permission problems?\n"; } } @@ -740,7 +737,6 @@ int main(int argc, char* argv[]) LOG(LogDebug) << "Android storage state: " << SDL_AndroidGetExternalStorageState(); LOG(LogDebug) << "Android internal path: " << SDL_AndroidGetInternalStoragePath(); LOG(LogDebug) << "Android external path: " << SDL_AndroidGetExternalStoragePath(); - Utils::Platform::Android::setPrivateDataDirectory(); { std::string buildIdentifier {PROGRAM_VERSION_STRING}; buildIdentifier.append(" (r") @@ -801,14 +797,7 @@ int main(int argc, char* argv[]) #if defined(__ANDROID__) Utils::Platform::Android::requestStoragePermission(); - - const std::string storageDir {"/sdcard/ES-DE"}; - if (!Utils::FileSystem::exists(storageDir)) { - LOG(LogInfo) << "Creating data directory \"" << storageDir << "\"..."; - if (!Utils::FileSystem::createDirectory(storageDir)) { - LOG(LogError) << "Couldn't create directory, permission problems?"; - } - } + Utils::Platform::Android::setROMDirectory(); #endif MameNames::getInstance(); diff --git a/es-app/src/scrapers/GamesDBJSONScraper.cpp b/es-app/src/scrapers/GamesDBJSONScraper.cpp index 2e6257c51..31525bd3b 100644 --- a/es-app/src/scrapers/GamesDBJSONScraper.cpp +++ b/es-app/src/scrapers/GamesDBJSONScraper.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamesDBJSONScraper.cpp // // Functions specifically for scraping from thegamesdb.net diff --git a/es-app/src/scrapers/GamesDBJSONScraper.h b/es-app/src/scrapers/GamesDBJSONScraper.h index fedba2ecd..e5c952077 100644 --- a/es-app/src/scrapers/GamesDBJSONScraper.h +++ b/es-app/src/scrapers/GamesDBJSONScraper.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamesDBJSONScraper.h // // Functions specifically for scraping from thegamesdb.net diff --git a/es-app/src/scrapers/GamesDBJSONScraperResources.cpp b/es-app/src/scrapers/GamesDBJSONScraperResources.cpp index 161c30cd9..e68198344 100644 --- a/es-app/src/scrapers/GamesDBJSONScraperResources.cpp +++ b/es-app/src/scrapers/GamesDBJSONScraperResources.cpp @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamesDBJSONScraperResources.cpp // // Functions specifically for scraping from thegamesdb.net // Called from GamesDBJSONScraper. // -// Downloads these resource files to ~/.emulationstation/scrapers: +// Downloads these resource files to the scrapers folder in the application data directory: // gamesdb_developers.json // gamesdb_genres.json // gamesdb_publishers.json @@ -64,8 +64,7 @@ namespace std::string getScrapersResouceDir() { - return Utils::FileSystem::getGenericPath(Utils::FileSystem::getHomePath() + - "/.emulationstation/" + SCRAPER_RESOURCES_DIR); + return Utils::FileSystem::getAppDataDirectory().append(SCRAPER_RESOURCES_DIR).string(); } std::string TheGamesDBJSONRequestResources::getApiKey() const { return GamesDBAPIKey; } diff --git a/es-app/src/scrapers/GamesDBJSONScraperResources.h b/es-app/src/scrapers/GamesDBJSONScraperResources.h index 631b85cc6..e567aa364 100644 --- a/es-app/src/scrapers/GamesDBJSONScraperResources.h +++ b/es-app/src/scrapers/GamesDBJSONScraperResources.h @@ -1,12 +1,12 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // GamesDBJSONScraperResources.h // // Functions specifically for scraping from thegamesdb.net // Called from GamesDBJSONScraper. // -// Downloads these resource files to ~/.emulationstation/scrapers: +// Downloads these resource files to the scrapers folder in the application data directory: // gamesdb_developers.json // gamesdb_genres.json // gamesdb_publishers.json diff --git a/es-app/src/scrapers/Scraper.h b/es-app/src/scrapers/Scraper.h index d0e105877..660f4bd9b 100644 --- a/es-app/src/scrapers/Scraper.h +++ b/es-app/src/scrapers/Scraper.h @@ -212,8 +212,8 @@ private: bool* mSavedNewMediaPtr; }; -// Downloads to the home directory, using this subdirectory structure: -// ".emulationstation/downloaded_media/[system_name]/[media_type]/[game_name].[file_extension]". +// Downloads media using this subdirectory structure: +// /downloaded_media///. // The subdirectories are automatically created if they do not exist. std::string getSaveAsPath(const ScraperSearchParams& params, const std::string& filetypeSubdirectory, diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index 9f60146f7..09a3852dd 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT # -# EmulationStation Desktop Edition +# ES-DE # CMakeLists.txt (es-core) # # CMake configuration for es-core diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index ef18b33dc..a9c38f176 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // InputManager.cpp // // Low-level input handling. @@ -86,14 +86,14 @@ void InputManager::init() // the bundled mapping is incorrect, or the SDL version is a bit older, it makes sense to be // able to customize this. If a controller GUID is present in the mappings file that is // already present inside SDL, the custom mapping will overwrite the bundled one. - std::string mappingsFile {Utils::FileSystem::getHomePath() + "/.emulationstation/" + - "es_controller_mappings.cfg"}; + std::filesystem::path mappingsFile { + Utils::FileSystem::getAppDataDirectory().append("es_controller_mappings.cfg")}; - if (!Utils::FileSystem::exists(mappingsFile)) + if (!Utils::FileSystem::existsSTD(mappingsFile)) mappingsFile = ResourceManager::getInstance().getResourcePath( ":/controllers/es_controller_mappings.cfg"); - int controllerMappings {SDL_GameControllerAddMappingsFromFile(mappingsFile.c_str())}; + int controllerMappings {SDL_GameControllerAddMappingsFromFile(mappingsFile.string().c_str())}; if (controllerMappings != -1 && controllerMappings != 0) { LOG(LogInfo) << "Loaded " << controllerMappings << " controller " @@ -255,16 +255,12 @@ void InputManager::doOnFinish() std::string InputManager::getConfigPath() { - std::string path {Utils::FileSystem::getHomePath()}; - path.append("/.emulationstation/es_input.xml"); - return path; + return Utils::FileSystem::getAppDataDirectory().append("es_input.xml").string(); } std::string InputManager::getTemporaryConfigPath() { - std::string path {Utils::FileSystem::getHomePath()}; - path.append("/.emulationstation/es_temporaryinput.xml"); - return path; + return Utils::FileSystem::getAppDataDirectory().append("es_temporaryinput.xml").string(); } int InputManager::getNumConfiguredDevices() diff --git a/es-core/src/InputManager.h b/es-core/src/InputManager.h index d68fa0b53..0814e5136 100644 --- a/es-core/src/InputManager.h +++ b/es-core/src/InputManager.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // InputManager.h // // Low-level input handling. diff --git a/es-core/src/MameNames.cpp b/es-core/src/MameNames.cpp index 39e9a2725..6c1683a60 100644 --- a/es-core/src/MameNames.cpp +++ b/es-core/src/MameNames.cpp @@ -1,12 +1,11 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MameNames.cpp // // Provides expanded game names based on short MAME name arguments. Also contains // functions to check whether a passed argument is a MAME BIOS or a MAME device. -// The data sources are stored in the .emulationstation/resources directory -// as the files mamebioses.xml, mamedevices.xml and mamenames.xml. +// The data sources are stored as the files mamebioses.xml, mamedevices.xml and mamenames.xml. // #include "MameNames.h" diff --git a/es-core/src/MameNames.h b/es-core/src/MameNames.h index 144017010..051de283e 100644 --- a/es-core/src/MameNames.h +++ b/es-core/src/MameNames.h @@ -1,12 +1,11 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // MameNames.h // // Provides expanded game names based on short MAME name arguments. Also contains // functions to check whether a passed argument is a MAME BIOS or a MAME device. -// The data sources are stored in the .emulationstation/resources directory -// as the files mamebioses.xml, mamedevices.xml and mamenames.xml. +// The data sources are stored as the files mamebioses.xml, mamedevices.xml and mamenames.xml. // #ifndef ES_CORE_MAMENAMES_H diff --git a/es-core/src/Scripting.cpp b/es-core/src/Scripting.cpp index a34eab10a..4c32ff35f 100644 --- a/es-core/src/Scripting.cpp +++ b/es-core/src/Scripting.cpp @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Scripting.cpp // // Executes custom scripts for various events. // By calling fireEvent() the scripts inside the directory corresponding to the // argument "eventName" will be executed with arg1, arg2, arg3 and arg4 as arguments. // -// The scripts are searched for in ~/.emulationstation/scripts/ +// The scripts are searched for in /scripts/ // For example, if the event is called "game-start", all scripts inside the directory -// ~/.emulationstation/scripts/game-start/ will be executed. +// /scripts/game-start/ will be executed. // #include "Scripting.h" @@ -37,12 +37,12 @@ namespace Scripting << "\" \"" << arg3 << "\" \"" << arg4 << "\""; std::list scriptDirList; - std::string scriptDir; + std::filesystem::path scriptDir; - // Check in homepath. - scriptDir = Utils::FileSystem::getHomePath() + "/.emulationstation/scripts/" + eventName; - if (Utils::FileSystem::exists(scriptDir)) - scriptDirList.push_back(scriptDir); + // Check in application data directory. + scriptDir = Utils::FileSystem::getAppDataDirectory().append("scripts").append(eventName); + if (Utils::FileSystem::existsSTD(scriptDir)) + scriptDirList.push_back(scriptDir.string()); for (auto dirIt = scriptDirList.cbegin(); dirIt != scriptDirList.cend(); ++dirIt) { std::list scripts {Utils::FileSystem::getDirContent(*dirIt)}; diff --git a/es-core/src/Scripting.h b/es-core/src/Scripting.h index 30f5c6e21..ff88be1c2 100644 --- a/es-core/src/Scripting.h +++ b/es-core/src/Scripting.h @@ -1,15 +1,15 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Scripting.h // // Executes custom scripts for various events. // By calling fireEvent() the scripts inside the directory corresponding to the // argument "eventName" will be executed with arg1, arg2, arg3 and arg4 as arguments. // -// The scripts are searched for in ~/.emulationstation/scripts/ +// The scripts are searched for in /scripts/ // For example, if the event is called "game-start", all scripts inside the directory -// ~/.emulationstation/scripts/game-start/ will be executed. +// /scripts/game-start/ will be executed. // #ifndef ES_CORE_SCRIPTING_H diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 2ee7f741e..0874f607d 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Settings.cpp // // Functions to read from and write to the configuration file es_settings.xml. @@ -326,7 +326,9 @@ void Settings::setDefaults() mBoolMap["DebugSkipMissingThemeFilesCustomCollections"] = {true, true}; mBoolMap["LegacyGamelistFileLocation"] = {false, false}; mStringMap["OpenGLVersion"] = {"", ""}; +#if !defined(__ANDROID__) mStringMap["ROMDirectory"] = {"", ""}; +#endif mStringMap["UIMode_passkey"] = {"uuddlrlrba", "uuddlrlrba"}; mStringMap["UserThemeDirectory"] = {"", ""}; mIntMap["LottieMaxFileCache"] = {150, 150}; @@ -364,7 +366,7 @@ void Settings::saveFile() { LOG(LogDebug) << "Settings::saveFile(): Saving settings to es_settings.xml"; const std::filesystem::path path { - Utils::FileSystem::getESDataDirectory().append("es_settings.xml")}; + Utils::FileSystem::getAppDataDirectory().append("es_settings.xml")}; pugi::xml_document doc; @@ -395,7 +397,7 @@ void Settings::saveFile() void Settings::loadFile() { std::filesystem::path configFile { - Utils::FileSystem::getESDataDirectory().append("es_settings.xml")}; + Utils::FileSystem::getAppDataDirectory().append("es_settings.xml")}; if (!Utils::FileSystem::existsSTD(configFile)) return; diff --git a/es-core/src/Settings.h b/es-core/src/Settings.h index c35d871a2..90b175f2c 100644 --- a/es-core/src/Settings.h +++ b/es-core/src/Settings.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // Settings.h // // Functions to read from and write to the configuration file es_settings.xml. diff --git a/es-core/src/ThemeData.cpp b/es-core/src/ThemeData.cpp index 23f55aa6c..52a1f99af 100644 --- a/es-core/src/ThemeData.cpp +++ b/es-core/src/ThemeData.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ThemeData.cpp // // Finds available themes on the file system and loads and parses these. @@ -667,8 +667,12 @@ void ThemeData::populateThemes() // Check for themes first under the user theme directory (which is in the ES-DE home directory // by default), then under the data installation directory (Unix only) and last under the ES-DE // binary directory. +#if defined(__ANDROID__) + const std::filesystem::path userThemeDirectory { + Utils::FileSystem::getInternalAppDataDirectory().append("themes")}; +#else const std::filesystem::path defaultUserThemeDir { - Utils::FileSystem::getESDataDirectory().append("themes")}; + Utils::FileSystem::getAppDataDirectory().append("themes")}; const std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath( Settings::getInstance()->getString("UserThemeDirectory"))}; std::filesystem::path userThemeDirectory; @@ -687,10 +691,12 @@ void ThemeData::populateThemes() << defaultUserThemeDir.string() << "\""; userThemeDirectory = defaultUserThemeDir; } +#endif #if defined(__ANDROID__) const std::vector themePaths { - Utils::FileSystem::getProgramDataPath().append("themes"), userThemeDirectory}; + Utils::FileSystem::getProgramDataPath().append("themes"), userThemeDirectory, + Utils::FileSystem::getAppDataDirectory().append("themes")}; #elif defined(__APPLE__) const std::vector themePaths { Utils::FileSystem::getExePathSTD().append("themes"), diff --git a/es-core/src/ThemeData.h b/es-core/src/ThemeData.h index 7574b0712..3a9ff783e 100644 --- a/es-core/src/ThemeData.h +++ b/es-core/src/ThemeData.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ThemeData.h // // Finds available themes on the file system and loads and parses these. diff --git a/es-core/src/resources/ResourceManager.cpp b/es-core/src/resources/ResourceManager.cpp index 7c8b86eac..941e89c1e 100644 --- a/es-core/src/resources/ResourceManager.cpp +++ b/es-core/src/resources/ResourceManager.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // ResourceManager.cpp // // Handles the application resources (fonts, graphics, sounds etc.). @@ -28,8 +28,8 @@ std::string ResourceManager::getResourcePath(const std::string& path, bool termi if ((path[0] == ':') && (path[1] == '/')) { // Check under the home directory. - std::string testHome {Utils::FileSystem::getHomePath() + "/.emulationstation/resources/" + - &path[2]}; + std::string testHome { + Utils::FileSystem::getAppDataDirectory().append("resources").string() + "/" + &path[2]}; if (Utils::FileSystem::exists(testHome)) return testHome; diff --git a/es-core/src/utils/FileSystemUtil.cpp b/es-core/src/utils/FileSystemUtil.cpp index 7f62ebed5..2f305df31 100644 --- a/es-core/src/utils/FileSystemUtil.cpp +++ b/es-core/src/utils/FileSystemUtil.cpp @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileSystemUtil.cpp // // Low-level filesystem functions. @@ -198,6 +198,11 @@ namespace Utils if (homePath.length()) return homePath; +#if defined(__ANDROID__) + homePath = AndroidVariables::sAppDataDirectory; + return homePath; +#endif + #if defined(_WIN64) // On Windows we need to check HOMEDRIVE and HOMEPATH. if (!homePath.length()) { @@ -241,6 +246,11 @@ namespace Utils if (!homePathSTD.empty()) return homePathSTD; +#if defined(__ANDROID__) + homePathSTD = + std::filesystem::path {getGenericPath(AndroidVariables::sAppDataDirectory)}; + return homePathSTD; +#endif #if defined(_WIN64) // On Windows we need to check HOMEDRIVE and HOMEPATH. std::wstring envHomeDrive; @@ -261,7 +271,6 @@ namespace Utils } #else - std::string envHome; if (getenv("HOME") != nullptr) envHome = getenv("HOME"); @@ -304,15 +313,24 @@ namespace Utils return ""; } - std::filesystem::path getESDataDirectory() + std::filesystem::path getAppDataDirectory() { #if defined(__ANDROID__) - return getHomePathSTD().append(".emulationstation"); + return getHomePathSTD(); #else return getHomePathSTD().append(".emulationstation"); #endif } + std::filesystem::path getInternalAppDataDirectory() + { +#if defined(__ANDROID__) + return AndroidVariables::sExternalDataDirectory; +#else + return std::filesystem::path {}; +#endif + } + std::string getPathToBinary(const std::string& executable) { #if defined(_WIN64) @@ -332,8 +350,8 @@ namespace Utils // Using a temporary file is the only viable solution I've found to communicate // between the sandbox and the outside world. - const std::string& tempFile {Utils::FileSystem::getHomePath() + "/.emulationstation/" + - ".flatpak_emulator_binary_path.tmp"}; + const std::string tempFile {Utils::FileSystem::getAppDataDirectory().string() + + ".flatpak_emulator_binary_path.tmp"}; std::string emulatorPath; @@ -440,7 +458,7 @@ namespace Utils std::filesystem::path getProgramDataPath() { #if defined(__ANDROID__) - return AndroidVariables::sPrivateDataDirectory; + return AndroidVariables::sInternalDataDirectory; #elif defined(__unix__) return std::filesystem::path {installPrefix}.append("share").append("emulationstation"); #else diff --git a/es-core/src/utils/FileSystemUtil.h b/es-core/src/utils/FileSystemUtil.h index 89152f589..eb382c6d6 100644 --- a/es-core/src/utils/FileSystemUtil.h +++ b/es-core/src/utils/FileSystemUtil.h @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// EmulationStation Desktop Edition +// ES-DE // FileSystemUtil.h // // Low-level filesystem functions. @@ -30,7 +30,8 @@ namespace Utils std::string getHomePath(); std::filesystem::path getHomePathSTD(); std::string getSystemHomeDirectory(); - std::filesystem::path getESDataDirectory(); + std::filesystem::path getAppDataDirectory(); + std::filesystem::path getInternalAppDataDirectory(); std::string getPathToBinary(const std::string& executable); void setExePath(const std::string& path); std::string getExePath();