mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-21 21:55:38 +00:00
Added proper error handling for resource files and improved overall logging.
This commit is contained in:
parent
04d4658fc9
commit
5a7fb828a6
1
NEWS.md
1
NEWS.md
|
@ -24,6 +24,7 @@ v1.0.0
|
|||
* Moved all resources to a subdirectory structure and enabled the CMake install prefix variable to generate the resources search path
|
||||
* Changed theme directory to the install prefix (e.g. /usr/local/share/emulationstation/themes) with themes in the home directory taking precedence
|
||||
* No more attempts to open files directly under /etc, instead only the install prefix directory and the home directory are used
|
||||
* Added proper error handling for missing resource files and improved overall logging
|
||||
* Refactoring, cleanup and documentation of the source code, removal of deprecated files etc.
|
||||
* All required fonts bundled with the application, no dependencies on the OS to provide them any longer
|
||||
* Made pugixml an external dependency instead of bundling it
|
||||
|
|
|
@ -94,8 +94,14 @@ void SystemData::setIsGameSystemStatus()
|
|||
bool SystemData::populateFolder(FileData* folder)
|
||||
{
|
||||
const std::string& folderPath = folder->getPath();
|
||||
if (!Utils::FileSystem::exists(folderPath)) {
|
||||
LOG(LogInfo) << "Info - Folder with path \"" <<
|
||||
folderPath << "\" does not exist.";
|
||||
return false;
|
||||
}
|
||||
if (!Utils::FileSystem::isDirectory(folderPath)) {
|
||||
LOG(LogWarning) << "Error - folder with path \"" << folderPath << "\" is not a directory!";
|
||||
LOG(LogWarning) << "Warning - Folder with path \"" <<
|
||||
folderPath << "\" is not a directory!";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -104,7 +110,8 @@ bool SystemData::populateFolder(FileData* folder)
|
|||
// If this symlink resolves to somewhere that's at the beginning of our
|
||||
// path, it's going to create a recursive loop. Make sure to avoid this.
|
||||
if (folderPath.find(Utils::FileSystem::getCanonicalPath(folderPath)) == 0) {
|
||||
LOG(LogWarning) << "Skipping infinitely recursive symlink \"" << folderPath << "\"";
|
||||
LOG(LogWarning) << "Warning - Skipping infinitely recursive symlink \"" <<
|
||||
folderPath << "\"";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +218,7 @@ bool SystemData::loadConfig()
|
|||
LOG(LogInfo) << "Loading system config file " << path << "...";
|
||||
|
||||
if (!Utils::FileSystem::exists(path)) {
|
||||
LOG(LogError) << "es_systems.cfg file does not exist!";
|
||||
LOG(LogError) << "Error - es_systems.cfg file does not exist!";
|
||||
writeExampleConfig(getConfigPath(true));
|
||||
return false;
|
||||
}
|
||||
|
@ -220,7 +227,7 @@ bool SystemData::loadConfig()
|
|||
pugi::xml_parse_result res = doc.load_file(path.c_str());
|
||||
|
||||
if (!res) {
|
||||
LOG(LogError) << "Could not parse es_systems.cfg file!";
|
||||
LOG(LogError) << "Error - Could not parse es_systems.cfg file!";
|
||||
LOG(LogError) << res.description();
|
||||
return false;
|
||||
}
|
||||
|
@ -229,7 +236,7 @@ bool SystemData::loadConfig()
|
|||
pugi::xml_node systemList = doc.child("systemList");
|
||||
|
||||
if (!systemList) {
|
||||
LOG(LogError) << "es_systems.cfg is missing the <systemList> tag!";
|
||||
LOG(LogError) << "Error - es_systems.cfg is missing the <systemList> tag!";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -275,8 +282,8 @@ bool SystemData::loadConfig()
|
|||
// If there appears to be an actual platform ID supplied
|
||||
// but it didn't match the list, generate a warning.
|
||||
if (str != nullptr && str[0] != '\0' && platformId == PlatformIds::PLATFORM_UNKNOWN)
|
||||
LOG(LogWarning) << "Unknown platform for system \"" << name << "\" (platform \""
|
||||
<< str << "\" from list \"" << platformList << "\")";
|
||||
LOG(LogWarning) << "Warning - Unknown platform for system \"" << name <<
|
||||
"\" (platform \"" << str << "\" from list \"" << platformList << "\")";
|
||||
else if (platformId != PlatformIds::PLATFORM_UNKNOWN)
|
||||
platformIds.push_back(platformId);
|
||||
}
|
||||
|
@ -286,7 +293,7 @@ bool SystemData::loadConfig()
|
|||
|
||||
// Validate.
|
||||
if (name.empty() || path.empty() || extensions.empty() || cmd.empty()) {
|
||||
LOG(LogError) << "System \"" << name <<
|
||||
LOG(LogError) << "Error - System \"" << name <<
|
||||
"\" is missing name, path, extension, or command!";
|
||||
continue;
|
||||
}
|
||||
|
@ -310,7 +317,7 @@ bool SystemData::loadConfig()
|
|||
|
||||
SystemData* newSys = new SystemData(name, fullname, envData, themeFolder);
|
||||
if (newSys->getRootFolder()->getChildrenByFilename().size() == 0) {
|
||||
LOG(LogWarning) << "System \"" << name << "\" has no games! Ignoring it.";
|
||||
LOG(LogInfo) << "Info - System \"" << name << "\" has no games, ignoring it.";
|
||||
delete newSys;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -416,12 +416,18 @@ int main(int argc, char* argv[])
|
|||
|
||||
bool splashScreen = Settings::getInstance()->getBool("SplashScreen");
|
||||
bool splashScreenProgress = Settings::getInstance()->getBool("SplashScreenProgress");
|
||||
SDL_Event event;
|
||||
|
||||
if (!window.init()) {
|
||||
LOG(LogError) << "Window failed to initialize!";
|
||||
return 1;
|
||||
}
|
||||
|
||||
InputManager::getInstance()->parseEvent(event, &window);
|
||||
if (event.type == SDL_QUIT)
|
||||
return 1;
|
||||
|
||||
|
||||
if (splashScreen) {
|
||||
std::string progressText = "Loading...";
|
||||
if (splashScreenProgress)
|
||||
|
@ -433,8 +439,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
if (loadSystemConfigFile(errorMsg) != NO_ERRORS) {
|
||||
// Something went terribly wrong.
|
||||
if (errorMsg == "")
|
||||
{
|
||||
if (errorMsg == "") {
|
||||
LOG(LogError) << "Unknown error occured while parsing system config file.";
|
||||
Renderer::deinit();
|
||||
return 1;
|
||||
|
|
|
@ -161,8 +161,8 @@ void thegamesdb_generate_json_scraper_requests(
|
|||
first = false;
|
||||
}
|
||||
else {
|
||||
LOG(LogWarning) << "TheGamesDB scraper warning - no support for platform "
|
||||
<< getPlatformName(*platformIt);
|
||||
LOG(LogWarning) << "Warning - TheGamesDB scraper warning - "
|
||||
"no support for platform " << getPlatformName(*platformIt);
|
||||
}
|
||||
}
|
||||
path += platformQueryParam;
|
||||
|
@ -290,6 +290,7 @@ void processGame(const Value& game, std::vector<ScraperSearchResult>& results)
|
|||
result.gameID = std::to_string(getIntOrThrow(game, "id"));
|
||||
|
||||
result.mdl.set("name", getStringOrThrow(game, "game_title"));
|
||||
|
||||
if (game.HasMember("overview") && game["overview"].IsString())
|
||||
result.mdl.set("desc", game["overview"].GetString());
|
||||
|
||||
|
@ -309,6 +310,21 @@ void processGame(const Value& game, std::vector<ScraperSearchResult>& results)
|
|||
if (game.HasMember("players") && game["players"].IsInt())
|
||||
result.mdl.set("players", std::to_string(game["players"].GetInt()));
|
||||
|
||||
LOG(LogDebug) << "GamesDBJSONScraper::processGame(): Name: " <<
|
||||
result.mdl.get("name");
|
||||
LOG(LogDebug) << "GamesDBJSONScraper::processGame(): Release Date (unparsed): " <<
|
||||
game["release_date"].GetString();
|
||||
LOG(LogDebug) << "GamesDBJSONScraper::processGame(): Release Date (parsed): " <<
|
||||
result.mdl.get("releasedate");
|
||||
LOG(LogDebug) << "GamesDBJSONScraper::processGame(): Developer: " <<
|
||||
result.mdl.get("developer");
|
||||
LOG(LogDebug) << "GamesDBJSONScraper::processGame(): Publisher: " <<
|
||||
result.mdl.get("publisher");
|
||||
LOG(LogDebug) << "GamesDBJSONScraper::processGame(): Genre: " <<
|
||||
result.mdl.get("genre");
|
||||
LOG(LogDebug) << "GamesDBJSONScraper::processGame(): Players: " <<
|
||||
result.mdl.get("players");
|
||||
|
||||
result.mediaURLFetch = NOT_STARTED;
|
||||
results.push_back(result);
|
||||
}
|
||||
|
@ -365,7 +381,7 @@ void TheGamesDBJSONRequest::process(const std::unique_ptr<HttpReq>& req,
|
|||
|
||||
if (doc.HasParseError()) {
|
||||
std::string err =
|
||||
std::string("TheGamesDBJSONRequest - Error parsing JSON. \n\t") +
|
||||
std::string("Error - TheGamesDBJSONRequest - Error parsing JSON. \n\t") +
|
||||
GetParseError_En(doc.GetParseError());
|
||||
setError(err);
|
||||
LOG(LogError) << err;
|
||||
|
@ -384,7 +400,7 @@ void TheGamesDBJSONRequest::process(const std::unique_ptr<HttpReq>& req,
|
|||
baseImageUrlLarge = base_url["large"].GetString();
|
||||
}
|
||||
else {
|
||||
std::string warn = "TheGamesDBJSONRequest - No URL path for large images.\n";
|
||||
std::string warn = "Warning - TheGamesDBJSONRequest - No URL path for large images.\n";
|
||||
LOG(LogWarning) << warn;
|
||||
return;
|
||||
}
|
||||
|
@ -393,7 +409,7 @@ void TheGamesDBJSONRequest::process(const std::unique_ptr<HttpReq>& req,
|
|||
processMediaURLs(images, baseImageUrlLarge, results);
|
||||
}
|
||||
catch (std::runtime_error& e) {
|
||||
LOG(LogError) << "Error while processing media URLs: " << e.what();
|
||||
LOG(LogError) << "Error - Error while processing media URLs: " << e.what();
|
||||
}
|
||||
|
||||
// Find how many more requests we can make before the scraper
|
||||
|
@ -412,7 +428,7 @@ void TheGamesDBJSONRequest::process(const std::unique_ptr<HttpReq>& req,
|
|||
// These process steps are for the initial scraping response.
|
||||
if (!doc.HasMember("data") || !doc["data"].HasMember("games") ||
|
||||
!doc["data"]["games"].IsArray()) {
|
||||
std::string warn = "TheGamesDBJSONRequest - Response had no game data.\n";
|
||||
std::string warn = "Warning - TheGamesDBJSONRequest - Response had no game data.\n";
|
||||
LOG(LogWarning) << warn;
|
||||
return;
|
||||
}
|
||||
|
@ -426,7 +442,7 @@ void TheGamesDBJSONRequest::process(const std::unique_ptr<HttpReq>& req,
|
|||
processGame(v, results);
|
||||
}
|
||||
catch (std::runtime_error& e) {
|
||||
LOG(LogError) << "Error while processing game: " << e.what();
|
||||
LOG(LogError) << "Error - Error while processing game: " << e.what();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,8 @@ std::unique_ptr<ScraperSearchHandle> startScraperSearch(const ScraperSearchParam
|
|||
|
||||
// Check if the scraper in the settings still exists as a registered scraping source.
|
||||
if (scraper_request_funcs.find(name) == scraper_request_funcs.end())
|
||||
LOG(LogWarning) << "Configured scraper (" << name << ") unavailable, scraping aborted.";
|
||||
LOG(LogWarning) << "Warning - Configured scraper (" << name <<
|
||||
") unavailable, scraping aborted.";
|
||||
else
|
||||
scraper_request_funcs.at(name)(params, handle->mRequestQueue, handle->mResults);
|
||||
|
||||
|
@ -44,7 +45,8 @@ std::unique_ptr<ScraperSearchHandle> startMediaURLsFetch(const std::string& game
|
|||
ScraperSearchParams params;
|
||||
// Check if the scraper in the settings still exists as a registered scraping source.
|
||||
if (scraper_request_funcs.find(name) == scraper_request_funcs.end())
|
||||
LOG(LogWarning) << "Configured scraper (" << name << ") unavailable, scraping aborted.";
|
||||
LOG(LogWarning) << "Warning - Configured scraper (" << name <<
|
||||
") unavailable, scraping aborted.";
|
||||
else
|
||||
// Specifically use the TheGamesDB function as this type of request
|
||||
// will never occur for ScreenScraper.
|
||||
|
@ -140,7 +142,7 @@ void ScraperHttpRequest::update()
|
|||
return;
|
||||
|
||||
// Everything else is some sort of error.
|
||||
LOG(LogError) << "ScraperHttpRequest network error (status: " << status<< ") - "
|
||||
LOG(LogError) << "Error - ScraperHttpRequest network error (status: " << status<< ") - "
|
||||
<< mReq->getErrorMsg();
|
||||
setError(mReq->getErrorMsg());
|
||||
}
|
||||
|
@ -367,7 +369,7 @@ bool resizeImage(const std::string& path, int maxWidth, int maxHeight)
|
|||
if (format == FIF_UNKNOWN)
|
||||
format = FreeImage_GetFIFFromFilename(path.c_str());
|
||||
if (format == FIF_UNKNOWN) {
|
||||
LOG(LogError) << "Error - could not detect filetype for image \"" << path << "\"!";
|
||||
LOG(LogError) << "Error - Could not detect filetype for image \"" << path << "\"!";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -376,7 +378,7 @@ bool resizeImage(const std::string& path, int maxWidth, int maxHeight)
|
|||
image = FreeImage_Load(format, path.c_str());
|
||||
}
|
||||
else {
|
||||
LOG(LogError) << "Error - file format reading not supported for image \"" << path << "\"!";
|
||||
LOG(LogError) << "Error - File format not supported for image \"" << path << "\"!";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -397,7 +399,7 @@ bool resizeImage(const std::string& path, int maxWidth, int maxHeight)
|
|||
FreeImage_Unload(image);
|
||||
|
||||
if (imageRescaled == nullptr) {
|
||||
LOG(LogError) << "Could not resize image! (not enough memory? invalid bitdepth?)";
|
||||
LOG(LogError) << "Error - Could not resize image! (not enough memory? invalid bitdepth?)";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -405,7 +407,7 @@ bool resizeImage(const std::string& path, int maxWidth, int maxHeight)
|
|||
FreeImage_Unload(imageRescaled);
|
||||
|
||||
if (!saved) {
|
||||
LOG(LogError) << "Failed to save resized image!";
|
||||
LOG(LogError) << "Error - Failed to save resized image!";
|
||||
}
|
||||
|
||||
return saved;
|
||||
|
|
|
@ -149,7 +149,7 @@ void screenscraper_generate_scraper_requests(const ScraperSearchParams& params,
|
|||
p_ids.push_back(mapIt->second);
|
||||
}
|
||||
else {
|
||||
LOG(LogWarning) << "ScreenScraper: no support for platform " <<
|
||||
LOG(LogWarning) << "Warning - ScreenScraper: no support for platform " <<
|
||||
getPlatformName(*platformIt);
|
||||
// Add the scrape request without a platform/system ID.
|
||||
requests.push(std::unique_ptr<ScraperRequest>
|
||||
|
@ -180,8 +180,7 @@ void ScreenScraperRequest::process(const std::unique_ptr<HttpReq>& req,
|
|||
|
||||
if (!parseResult) {
|
||||
std::stringstream ss;
|
||||
ss << "ScreenScraperRequest - Error parsing XML." << std::endl <<
|
||||
parseResult.description() << "";
|
||||
ss << "Error - ScreenScraperRequest - Error parsing XML: " << parseResult.description();
|
||||
|
||||
std::string err = ss.str();
|
||||
setError(err);
|
||||
|
@ -232,14 +231,12 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc,
|
|||
// Genre fallback language: EN. ( Xpath: Data/jeu[0]/genres/genre[*] ).
|
||||
result.mdl.set("genre", find_child_by_attribute_list(game.child("genres"),
|
||||
"genre", "langue", { language, "en" }).text().get());
|
||||
LOG(LogDebug) << "Genre: " << result.mdl.get("genre");
|
||||
|
||||
// Get the date proper. The API returns multiple 'date' children nodes to the 'dates'
|
||||
// main child of 'jeu'.
|
||||
// Date fallback: WOR(LD), US, SS, JP, EU.
|
||||
std::string _date = find_child_by_attribute_list(game.child("dates"), "date", "region",
|
||||
{ region, "wor", "us", "ss", "jp", "eu" }).text().get();
|
||||
LOG(LogDebug) << "Release Date (unparsed): " << _date;
|
||||
|
||||
// Date can be YYYY-MM-DD or just YYYY.
|
||||
if (_date.length() > 4) {
|
||||
|
@ -251,8 +248,6 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc,
|
|||
Utils::Time::stringToTime(_date, "%Y")));
|
||||
}
|
||||
|
||||
LOG(LogDebug) << "Release Date (parsed): " << result.mdl.get("releasedate");
|
||||
|
||||
/// Developer for the game( Xpath: Data/jeu[0]/developpeur ).
|
||||
std::string developer = game.child("developpeur").text().get();
|
||||
if (!developer.empty())
|
||||
|
@ -276,6 +271,21 @@ void ScreenScraperRequest::processGame(const pugi::xml_document& xmldoc,
|
|||
result.mdl.set("rating", ss.str());
|
||||
}
|
||||
|
||||
LOG(LogDebug) << "ScreenScraperRequest::processGame(): Name: " <<
|
||||
result.mdl.get("name");
|
||||
LOG(LogDebug) << "ScreenScraperRequest::processGame(): Release Date (unparsed): " <<
|
||||
_date;
|
||||
LOG(LogDebug) << "ScreenScraperRequest::processGame(): Release Date (parsed): " <<
|
||||
result.mdl.get("releasedate");
|
||||
LOG(LogDebug) << "ScreenScraperRequest::processGame(): Developer: " <<
|
||||
result.mdl.get("developer");
|
||||
LOG(LogDebug) << "ScreenScraperRequest::processGame(): Publisher: " <<
|
||||
result.mdl.get("publisher");
|
||||
LOG(LogDebug) << "ScreenScraperRequest::processGame(): Genre: " <<
|
||||
result.mdl.get("genre");
|
||||
LOG(LogDebug) << "ScreenScraperRequest::processGame(): Players: " <<
|
||||
result.mdl.get("players");
|
||||
|
||||
// Media super-node.
|
||||
pugi::xml_node media_list = game.child("medias");
|
||||
|
||||
|
@ -352,13 +362,13 @@ void ScreenScraperRequest::processList(const pugi::xml_document& xmldoc,
|
|||
{
|
||||
assert(mRequestQueue != nullptr);
|
||||
|
||||
LOG(LogDebug) << "Processing a list of results";
|
||||
LOG(LogDebug) << "ScreenScraper: Processing a list of results";
|
||||
|
||||
pugi::xml_node data = xmldoc.child("Data");
|
||||
pugi::xml_node game = data.child("jeu");
|
||||
|
||||
if (!game) {
|
||||
LOG(LogDebug) << "Found nothing";
|
||||
LOG(LogDebug) << "ScreenScraper: Found nothing";
|
||||
}
|
||||
|
||||
ScreenScraperRequest::ScreenScraperConfig ssConfig;
|
||||
|
|
|
@ -146,8 +146,8 @@ void UIModeController::logInput(InputConfig * config, Input input)
|
|||
mapname += ", ";
|
||||
}
|
||||
|
||||
LOG(LogDebug) << "UIModeController::logInput( " << config->getDeviceName() <<
|
||||
" ):" << input.string() << ", isMappedTo= " << mapname << ", value=" << input.value;
|
||||
LOG(LogDebug) << "UIModeController::logInput(" << config->getDeviceName() <<
|
||||
"): " << input.string() << ", isMappedTo=" << mapname << ", value=" << input.value;
|
||||
}
|
||||
|
||||
bool UIModeController::isValidInput(InputConfig * config, Input input)
|
||||
|
|
|
@ -65,7 +65,8 @@ std::vector<unsigned char> ImageIO::loadFromMemoryRGBA32(const unsigned char * d
|
|||
}
|
||||
}
|
||||
else {
|
||||
LOG(LogError) << "Error - File type " <<
|
||||
LOG(LogError) << "Error - Couldn't load image, file is missing or the file type is " <<
|
||||
// it's not existing or the file type " <<
|
||||
(format == FIF_UNKNOWN ? "unknown" : "unsupported") << "!";
|
||||
}
|
||||
// Free fiMemory again
|
||||
|
|
|
@ -5,7 +5,12 @@
|
|||
//
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#include "renderers/Renderer.h"
|
||||
#include "utils/StringUtil.h"
|
||||
#include "AudioManager.h"
|
||||
#include "Log.h"
|
||||
#include "MameNames.h"
|
||||
|
||||
#if defined(__linux__) || defined(_WIN64)
|
||||
#include <SDL2/SDL_events.h>
|
||||
|
@ -22,8 +27,6 @@
|
|||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
int runRebootCommand()
|
||||
{
|
||||
#ifdef _WIN64 // Windows.
|
||||
|
@ -141,6 +144,19 @@ int quitES(QuitMode mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void emergencyShutdown()
|
||||
{
|
||||
LOG(LogError) << "Critical Error - Performing emergency shutdown...";
|
||||
|
||||
MameNames::deinit();
|
||||
AudioManager::getInstance()->deinit();
|
||||
// Most of the SDL deinitialization is done in Renderer.
|
||||
Renderer::deinit();
|
||||
Log::flush();
|
||||
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void touch(const std::string& filename)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
|
|
|
@ -29,7 +29,10 @@ int runSystemCommand(const std::wstring& cmd_utf16);
|
|||
int launchEmulatorUnix(const std::string& cmd_utf8);
|
||||
int launchEmulatorWindows(const std::wstring& cmd_utf16);
|
||||
|
||||
// Clean, normal shutdown.
|
||||
int quitES(QuitMode mode = QuitMode::QUIT);
|
||||
// Immediately shut down the application as cleanly as possible.
|
||||
void emergencyShutdown();
|
||||
void processQuitMode();
|
||||
|
||||
#endif // ES_CORE_PLATFORM_H
|
||||
|
|
|
@ -37,8 +37,8 @@ namespace Renderer
|
|||
{
|
||||
size_t width = 0;
|
||||
size_t height = 0;
|
||||
ResourceData resData =
|
||||
ResourceManager::getInstance()->getFileData(":/graphics/window_icon_256.png");
|
||||
ResourceData resData = ResourceManager::getInstance()->
|
||||
getFileData(":/graphics/window_icon_256.png");
|
||||
std::vector<unsigned char> rawData =
|
||||
ImageIO::loadFromMemoryRGBA32(resData.ptr.get(), resData.length, width, height);
|
||||
|
||||
|
|
|
@ -213,6 +213,13 @@ std::vector<std::string> getFallbackFontPaths()
|
|||
{
|
||||
std::vector<std::string> fontPaths;
|
||||
|
||||
// Standard fonts, let's include them here for error checking purposes even though that's
|
||||
// not really the correct location. (The application will crash if they are missing.)
|
||||
ResourceManager::getInstance()->
|
||||
getResourcePath(":/fonts/opensans_hebrew_condensed_light.ttf");
|
||||
ResourceManager::getInstance()->
|
||||
getResourcePath(":/fonts/opensans_hebrew_condensed_regular.ttf");
|
||||
|
||||
// Vera sans Unicode:
|
||||
fontPaths.push_back(ResourceManager::getInstance()->
|
||||
getResourcePath(":/fonts/DejaVuSans.ttf"));
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
#include "ResourceManager.h"
|
||||
|
||||
#include "utils/FileSystemUtil.h"
|
||||
#include "Log.h"
|
||||
#include "Platform.h"
|
||||
#include "Scripting.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
auto array_deleter = [](unsigned char* p) { delete[] p; };
|
||||
|
@ -31,23 +35,36 @@ std::string ResourceManager::getResourcePath(const std::string& path) const
|
|||
{
|
||||
// Check if this is a resource file.
|
||||
if ((path[0] == ':') && (path[1] == '/')) {
|
||||
std::string test;
|
||||
std::string testHome;
|
||||
std::string testDataPath;
|
||||
|
||||
// Check under the home directory.
|
||||
test = Utils::FileSystem::getHomePath() + "/.emulationstation/resources/" + &path[2];
|
||||
if (Utils::FileSystem::exists(test))
|
||||
return test;
|
||||
testHome = Utils::FileSystem::getHomePath() + "/.emulationstation/resources/" + &path[2];
|
||||
if (Utils::FileSystem::exists(testHome))
|
||||
return testHome;
|
||||
|
||||
// Check for the resource under the data installation directory for Unix or under
|
||||
// the executable directory for Windows.
|
||||
#ifdef _WIN64
|
||||
test = Utils::FileSystem::getExePath() + "/resources/" + &path[2];
|
||||
testDataPath = Utils::FileSystem::getExePath() + "/resources/" + &path[2];
|
||||
#else
|
||||
test = Utils::FileSystem::getProgramDataPath() + "/resources/" + &path[2];
|
||||
testDataPath = Utils::FileSystem::getProgramDataPath() + "/resources/" + &path[2];
|
||||
#endif
|
||||
|
||||
if (Utils::FileSystem::exists(test))
|
||||
return test;
|
||||
if (Utils::FileSystem::exists(testDataPath)) {
|
||||
return testDataPath;
|
||||
}
|
||||
// For missing resources, log an error and terminate the application. This should
|
||||
// indicate that we have a broken EmulationStation installation.
|
||||
else {
|
||||
LOG(LogError) << "Error - Program resource missing: " << path;
|
||||
LOG(LogError) << "Tried to find the resource in the following locations:";
|
||||
LOG(LogError) << testHome;
|
||||
LOG(LogError) << testDataPath;
|
||||
LOG(LogError) << "Has EmulationStation been properly installed?";
|
||||
Scripting::fireEvent("quit");
|
||||
emergencyShutdown();
|
||||
}
|
||||
}
|
||||
|
||||
// Not a resource, return unmodified path.
|
||||
|
|
|
@ -490,20 +490,19 @@ namespace Utils
|
|||
#if defined(_WIN64)
|
||||
HANDLE hFile = CreateFile(path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
|
||||
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
|
||||
/*
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0,
|
||||
resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0,
|
||||
FILE_NAME_NORMALIZED) + 1);
|
||||
if (GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(),
|
||||
if (GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(),
|
||||
(DWORD)resolved.size(), FILE_NAME_NORMALIZED) > 0) {
|
||||
resolved.resize(resolved.size() - 1);
|
||||
resolved = getGenericPath(resolved);
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
*/
|
||||
// TEMPORARY, will need to fix this later.
|
||||
// if (hFile != INVALID_HANDLE_VALUE) {
|
||||
// resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0,
|
||||
// resolved.resize(GetFinalPathNameByHandle(hFile, nullptr, 0,
|
||||
// FILE_NAME_NORMALIZED) + 1);
|
||||
// if (GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(),
|
||||
// if (GetFinalPathNameByHandle(hFile, (LPSTR)resolved.data(),
|
||||
// (DWORD)resolved.size(), FILE_NAME_NORMALIZED) > 0) {
|
||||
// resolved.resize(resolved.size() - 1);
|
||||
// resolved = getGenericPath(resolved);
|
||||
// }
|
||||
// CloseHandle(hFile);
|
||||
// }
|
||||
#else
|
||||
struct stat info;
|
||||
|
||||
|
|
Loading…
Reference in a new issue