Settings: Add UserResources to EmuFolders

Allowing some resources, such as fonts/sounds to be overridden by the
user.
This commit is contained in:
Stenzek
2024-01-10 13:35:06 +10:00
parent e4e7080f98
commit 73cee9f705
14 changed files with 105 additions and 59 deletions

View File

@ -13,17 +13,17 @@
namespace Host {
/// Returns true if the specified resource file exists.
bool ResourceFileExists(const char* filename);
bool ResourceFileExists(std::string_view filename, bool allow_override);
/// Reads a file from the resources directory of the application.
/// This may be outside of the "normal" filesystem on platforms such as Mac.
std::optional<std::vector<u8>> ReadResourceFile(const char* filename);
std::optional<std::vector<u8>> ReadResourceFile(std::string_view filename, bool allow_override);
/// Reads a resource file file from the resources directory as a string.
std::optional<std::string> ReadResourceFileToString(const char* filename);
std::optional<std::string> ReadResourceFileToString(std::string_view filename, bool allow_override);
/// Returns the modified time of a resource.
std::optional<std::time_t> GetResourceFileTimestamp(const char* filename);
std::optional<std::time_t> GetResourceFileTimestamp(std::string_view filename, bool allow_override);
/// Displays an asynchronous error on the UI thread, i.e. doesn't block the caller.
void ReportErrorAsync(const std::string_view& title, const std::string_view& message);

View File

@ -274,7 +274,7 @@ std::optional<Common::RGBA8Image> ImGuiFullscreen::LoadTextureImage(const char*
if (Path::IsAbsolute(path))
data = FileSystem::ReadBinaryFile(path);
else
data = Host::ReadResourceFile(path);
data = Host::ReadResourceFile(path, true);
if (data.has_value())
{
image = Common::RGBA8Image();

View File

@ -477,7 +477,7 @@ bool ImGuiManager::LoadFontData()
if (s_standard_font_data.empty())
{
std::optional<std::vector<u8>> font_data = s_font_path.empty() ?
Host::ReadResourceFile("fonts/Roboto-Regular.ttf") :
Host::ReadResourceFile("fonts/Roboto-Regular.ttf", true) :
FileSystem::ReadBinaryFile(s_font_path.c_str());
if (!font_data.has_value())
return false;
@ -487,7 +487,7 @@ bool ImGuiManager::LoadFontData()
if (s_fixed_font_data.empty())
{
std::optional<std::vector<u8>> font_data = Host::ReadResourceFile("fonts/RobotoMono-Medium.ttf");
std::optional<std::vector<u8>> font_data = Host::ReadResourceFile("fonts/RobotoMono-Medium.ttf", true);
if (!font_data.has_value())
return false;
@ -496,7 +496,7 @@ bool ImGuiManager::LoadFontData()
if (s_icon_fa_font_data.empty())
{
std::optional<std::vector<u8>> font_data = Host::ReadResourceFile("fonts/fa-solid-900.ttf");
std::optional<std::vector<u8>> font_data = Host::ReadResourceFile("fonts/fa-solid-900.ttf", true);
if (!font_data.has_value())
return false;
@ -505,7 +505,7 @@ bool ImGuiManager::LoadFontData()
if (s_icon_pf_font_data.empty())
{
std::optional<std::vector<u8>> font_data = Host::ReadResourceFile("fonts/promptfont.otf");
std::optional<std::vector<u8>> font_data = Host::ReadResourceFile("fonts/promptfont.otf", true);
if (!font_data.has_value())
return false;

View File

@ -402,7 +402,7 @@ std::unique_ptr<PostProcessing::Shader> PostProcessing::TryLoadingShader(const s
filename =
fmt::format("shaders/reshade" FS_OSPATH_SEPARATOR_STR "Shaders" FS_OSPATH_SEPARATOR_STR "{}.fx", shader_name);
resource_str = Host::ReadResourceFileToString(filename.c_str());
resource_str = Host::ReadResourceFileToString(filename.c_str(), true);
if (resource_str.has_value())
{
std::unique_ptr<ReShadeFXShader> shader = std::make_unique<ReShadeFXShader>();
@ -414,7 +414,7 @@ std::unique_ptr<PostProcessing::Shader> PostProcessing::TryLoadingShader(const s
}
filename = fmt::format("shaders" FS_OSPATH_SEPARATOR_STR "{}.glsl", shader_name);
resource_str = Host::ReadResourceFileToString(filename.c_str());
resource_str = Host::ReadResourceFileToString(filename.c_str(), true);
if (resource_str.has_value())
{
std::unique_ptr<GLSLShader> shader = std::make_unique<GLSLShader>();

View File

@ -45,7 +45,7 @@ static bool PreprocessorFileExistsCallback(const std::string& path)
if (Path::IsAbsolute(path))
return FileSystem::FileExists(path.c_str());
return Host::ResourceFileExists(path.c_str());
return Host::ResourceFileExists(path.c_str(), true);
}
static bool PreprocessorReadFileCallback(const std::string& path, std::string& data)
@ -54,7 +54,7 @@ static bool PreprocessorReadFileCallback(const std::string& path, std::string& d
if (Path::IsAbsolute(path))
rdata = FileSystem::ReadFileToString(path.c_str());
else
rdata = Host::ReadResourceFileToString(path.c_str());
rdata = Host::ReadResourceFileToString(path.c_str(), true);
if (!rdata.has_value())
return false;
@ -935,7 +935,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
{
// Might be a base file/resource instead.
const std::string resource_name = Path::Combine("shaders/reshade/Textures", source);
if (std::optional<std::vector<u8>> resdata = Host::ReadResourceFile(resource_name.c_str());
if (std::optional<std::vector<u8>> resdata = Host::ReadResourceFile(resource_name.c_str(), true);
!resdata.has_value() || !image.LoadFromBuffer(resource_name.c_str(), resdata->data(), resdata->size()))
{
Error::SetString(error, fmt::format("Failed to load image '{}' (from '{}')", source, image_path).c_str());

View File

@ -243,7 +243,7 @@ void SDLInputSource::SetHints()
Log_InfoFmt("Using Controller DB from user directory: '{}'", upath);
SDL_SetHint(SDL_HINT_GAMECONTROLLERCONFIG_FILE, upath.c_str());
}
else if (const std::string rpath = Path::Combine(EmuFolders::Resources, CONTROLLER_DB_FILENAME);
else if (const std::string rpath = EmuFolders::GetOverridableResourcePath(CONTROLLER_DB_FILENAME);
FileSystem::FileExists(rpath.c_str()))
{
Log_InfoPrint("Using Controller DB from resources.");