mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-30 01:25:51 +00:00
Settings: Add UserResources to EmuFolders
Allowing some resources, such as fonts/sounds to be overridden by the user.
This commit is contained in:
parent
e4e7080f98
commit
73cee9f705
|
@ -1022,7 +1022,7 @@ void Achievements::DisplayAchievementSummary()
|
||||||
|
|
||||||
// Technically not going through the resource API, but since we're passing this to something else, we can't.
|
// Technically not going through the resource API, but since we're passing this to something else, we can't.
|
||||||
if (g_settings.achievements_sound_effects)
|
if (g_settings.achievements_sound_effects)
|
||||||
PlatformMisc::PlaySoundAsync(Path::Combine(EmuFolders::Resources, INFO_SOUND_NAME).c_str());
|
PlatformMisc::PlaySoundAsync(EmuFolders::GetOverridableResourcePath(INFO_SOUND_NAME).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Achievements::DisplayHardcoreDeferredMessage()
|
void Achievements::DisplayHardcoreDeferredMessage()
|
||||||
|
@ -1069,7 +1069,7 @@ void Achievements::HandleUnlockEvent(const rc_client_event_t* event)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_settings.achievements_sound_effects)
|
if (g_settings.achievements_sound_effects)
|
||||||
PlatformMisc::PlaySoundAsync(Path::Combine(EmuFolders::Resources, UNLOCK_SOUND_NAME).c_str());
|
PlatformMisc::PlaySoundAsync(EmuFolders::GetOverridableResourcePath(UNLOCK_SOUND_NAME).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
|
void Achievements::HandleGameCompleteEvent(const rc_client_event_t* event)
|
||||||
|
@ -1144,7 +1144,7 @@ void Achievements::HandleLeaderboardSubmittedEvent(const rc_client_event_t* even
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_settings.achievements_sound_effects)
|
if (g_settings.achievements_sound_effects)
|
||||||
PlatformMisc::PlaySoundAsync(Path::Combine(EmuFolders::Resources, LBSUBMIT_SOUND_NAME).c_str());
|
PlatformMisc::PlaySoundAsync(EmuFolders::GetOverridableResourcePath(LBSUBMIT_SOUND_NAME).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* event)
|
void Achievements::HandleLeaderboardScoreboardEvent(const rc_client_event_t* event)
|
||||||
|
|
|
@ -689,7 +689,7 @@ bool CheatList::SaveToPCSXRFile(const char* filename)
|
||||||
|
|
||||||
bool CheatList::LoadFromPackage(const std::string& serial)
|
bool CheatList::LoadFromPackage(const std::string& serial)
|
||||||
{
|
{
|
||||||
const std::optional<std::string> db_string(Host::ReadResourceFileToString("chtdb.txt"));
|
const std::optional<std::string> db_string(Host::ReadResourceFileToString("chtdb.txt", false));
|
||||||
if (!db_string.has_value())
|
if (!db_string.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -580,7 +580,7 @@ bool GameDatabase::LoadFromCache()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u64 gamedb_ts = Host::GetResourceFileTimestamp("gamedb.json").value_or(0);
|
const u64 gamedb_ts = Host::GetResourceFileTimestamp("gamedb.json", false).value_or(0);
|
||||||
|
|
||||||
u32 signature, version, num_entries, num_codes;
|
u32 signature, version, num_entries, num_codes;
|
||||||
u64 file_gamedb_ts;
|
u64 file_gamedb_ts;
|
||||||
|
@ -674,7 +674,7 @@ bool GameDatabase::LoadFromCache()
|
||||||
|
|
||||||
bool GameDatabase::SaveToCache()
|
bool GameDatabase::SaveToCache()
|
||||||
{
|
{
|
||||||
const u64 gamedb_ts = Host::GetResourceFileTimestamp("gamedb.json").value_or(0);
|
const u64 gamedb_ts = Host::GetResourceFileTimestamp("gamedb.json", false).value_or(0);
|
||||||
|
|
||||||
std::unique_ptr<ByteStream> stream(
|
std::unique_ptr<ByteStream> stream(
|
||||||
ByteStream::OpenFile(GetCacheFile().c_str(), BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE |
|
ByteStream::OpenFile(GetCacheFile().c_str(), BYTESTREAM_OPEN_CREATE | BYTESTREAM_OPEN_WRITE |
|
||||||
|
@ -830,7 +830,7 @@ static std::optional<float> GetOptionalFloatFromObject(const rapidjson::Value& o
|
||||||
|
|
||||||
bool GameDatabase::LoadGameDBJson()
|
bool GameDatabase::LoadGameDBJson()
|
||||||
{
|
{
|
||||||
std::optional<std::string> gamedb_data(Host::ReadResourceFileToString("gamedb.json"));
|
std::optional<std::string> gamedb_data(Host::ReadResourceFileToString("gamedb.json", false));
|
||||||
if (!gamedb_data.has_value())
|
if (!gamedb_data.has_value())
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed to read game database");
|
Log_ErrorPrintf("Failed to read game database");
|
||||||
|
@ -1082,7 +1082,7 @@ void GameDatabase::EnsureTrackHashesMapLoaded()
|
||||||
|
|
||||||
bool GameDatabase::LoadTrackHashes()
|
bool GameDatabase::LoadTrackHashes()
|
||||||
{
|
{
|
||||||
std::optional<std::string> gamedb_data(Host::ReadResourceFileToString("gamedb.json"));
|
std::optional<std::string> gamedb_data(Host::ReadResourceFileToString("gamedb.json", false));
|
||||||
if (!gamedb_data.has_value())
|
if (!gamedb_data.has_value())
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed to read game database");
|
Log_ErrorPrintf("Failed to read game database");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
@ -1504,6 +1504,7 @@ std::string EmuFolders::SaveStates;
|
||||||
std::string EmuFolders::Screenshots;
|
std::string EmuFolders::Screenshots;
|
||||||
std::string EmuFolders::Shaders;
|
std::string EmuFolders::Shaders;
|
||||||
std::string EmuFolders::Textures;
|
std::string EmuFolders::Textures;
|
||||||
|
std::string EmuFolders::UserResources;
|
||||||
|
|
||||||
void EmuFolders::SetDefaults()
|
void EmuFolders::SetDefaults()
|
||||||
{
|
{
|
||||||
|
@ -1519,6 +1520,7 @@ void EmuFolders::SetDefaults()
|
||||||
Screenshots = Path::Combine(DataRoot, "screenshots");
|
Screenshots = Path::Combine(DataRoot, "screenshots");
|
||||||
Shaders = Path::Combine(DataRoot, "shaders");
|
Shaders = Path::Combine(DataRoot, "shaders");
|
||||||
Textures = Path::Combine(DataRoot, "textures");
|
Textures = Path::Combine(DataRoot, "textures");
|
||||||
|
UserResources = Path::Combine(DataRoot, "resources");
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string LoadPathFromSettings(SettingsInterface& si, const std::string& root, const char* section,
|
static std::string LoadPathFromSettings(SettingsInterface& si, const std::string& root, const char* section,
|
||||||
|
@ -1546,19 +1548,22 @@ void EmuFolders::LoadConfig(SettingsInterface& si)
|
||||||
Screenshots = LoadPathFromSettings(si, DataRoot, "Folders", "Screenshots", "screenshots");
|
Screenshots = LoadPathFromSettings(si, DataRoot, "Folders", "Screenshots", "screenshots");
|
||||||
Shaders = LoadPathFromSettings(si, DataRoot, "Folders", "Shaders", "shaders");
|
Shaders = LoadPathFromSettings(si, DataRoot, "Folders", "Shaders", "shaders");
|
||||||
Textures = LoadPathFromSettings(si, DataRoot, "Folders", "Textures", "textures");
|
Textures = LoadPathFromSettings(si, DataRoot, "Folders", "Textures", "textures");
|
||||||
|
UserResources = LoadPathFromSettings(si, DataRoot, "Folders", "UserResources", "resources");
|
||||||
|
|
||||||
Log_DevPrintf("BIOS Directory: %s", Bios.c_str());
|
Log_DevFmt("BIOS Directory: {}", Bios);
|
||||||
Log_DevPrintf("Cache Directory: %s", Cache.c_str());
|
Log_DevFmt("Cache Directory: {}", Cache);
|
||||||
Log_DevPrintf("Cheats Directory: %s", Cheats.c_str());
|
Log_DevFmt("Cheats Directory: {}", Cheats);
|
||||||
Log_DevPrintf("Covers Directory: %s", Covers.c_str());
|
Log_DevFmt("Covers Directory: {}", Covers);
|
||||||
Log_DevPrintf("Dumps Directory: %s", Dumps.c_str());
|
Log_DevFmt("Dumps Directory: {}", Dumps);
|
||||||
Log_DevPrintf("Game Settings Directory: %s", GameSettings.c_str());
|
Log_DevFmt("Game Settings Directory: {}", GameSettings);
|
||||||
Log_DevPrintf("Input Profile Directory: %s", InputProfiles.c_str());
|
Log_DevFmt("Input Profile Directory: {}", InputProfiles);
|
||||||
Log_DevPrintf("MemoryCards Directory: %s", MemoryCards.c_str());
|
Log_DevFmt("MemoryCards Directory: {}", MemoryCards);
|
||||||
Log_DevPrintf("SaveStates Directory: %s", SaveStates.c_str());
|
Log_DevFmt("Resources Directory: {}", Resources);
|
||||||
Log_DevPrintf("Screenshots Directory: %s", Screenshots.c_str());
|
Log_DevFmt("SaveStates Directory: {}", SaveStates);
|
||||||
Log_DevPrintf("Shaders Directory: %s", Shaders.c_str());
|
Log_DevFmt("Screenshots Directory: {}", Screenshots);
|
||||||
Log_DevPrintf("Textures Directory: %s", Textures.c_str());
|
Log_DevFmt("Shaders Directory: {}", Shaders);
|
||||||
|
Log_DevFmt("Textures Directory: {}", Textures);
|
||||||
|
Log_DevFmt("User Resources Directory: {}", UserResources);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuFolders::Save(SettingsInterface& si)
|
void EmuFolders::Save(SettingsInterface& si)
|
||||||
|
@ -1576,6 +1581,7 @@ void EmuFolders::Save(SettingsInterface& si)
|
||||||
si.SetStringValue("Folders", "Screenshots", Path::MakeRelative(Screenshots, DataRoot).c_str());
|
si.SetStringValue("Folders", "Screenshots", Path::MakeRelative(Screenshots, DataRoot).c_str());
|
||||||
si.SetStringValue("Folders", "Shaders", Path::MakeRelative(Shaders, DataRoot).c_str());
|
si.SetStringValue("Folders", "Shaders", Path::MakeRelative(Shaders, DataRoot).c_str());
|
||||||
si.SetStringValue("Folders", "Textures", Path::MakeRelative(Textures, DataRoot).c_str());
|
si.SetStringValue("Folders", "Textures", Path::MakeRelative(Textures, DataRoot).c_str());
|
||||||
|
si.SetStringValue("Folders", "UserResources", Path::MakeRelative(UserResources, DataRoot).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuFolders::Update()
|
void EmuFolders::Update()
|
||||||
|
@ -1623,9 +1629,26 @@ bool EmuFolders::EnsureFoldersExist()
|
||||||
Path::Combine(Shaders, "reshade" FS_OSPATH_SEPARATOR_STR "Textures").c_str(), false) &&
|
Path::Combine(Shaders, "reshade" FS_OSPATH_SEPARATOR_STR "Textures").c_str(), false) &&
|
||||||
result;
|
result;
|
||||||
result = FileSystem::EnsureDirectoryExists(Textures.c_str(), false) && result;
|
result = FileSystem::EnsureDirectoryExists(Textures.c_str(), false) && result;
|
||||||
|
result = FileSystem::EnsureDirectoryExists(UserResources.c_str(), false) && result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string EmuFolders::GetOverridableResourcePath(std::string_view name)
|
||||||
|
{
|
||||||
|
std::string upath = Path::Combine(UserResources, name);
|
||||||
|
if (FileSystem::FileExists(upath.c_str()))
|
||||||
|
{
|
||||||
|
if (UserResources != Resources)
|
||||||
|
Log_WarningFmt("Using user-provided resource file {}", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
upath = Path::Combine(Resources, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return upath;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* s_log_filters[] = {
|
static const char* s_log_filters[] = {
|
||||||
"Achievements",
|
"Achievements",
|
||||||
"AnalogController",
|
"AnalogController",
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
|
||||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#include "util/audio_stream.h"
|
||||||
|
|
||||||
#include "common/log.h"
|
#include "common/log.h"
|
||||||
#include "common/settings_interface.h"
|
#include "common/settings_interface.h"
|
||||||
#include "common/small_string.h"
|
#include "common/small_string.h"
|
||||||
#include "types.h"
|
|
||||||
#include "util/audio_stream.h"
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
enum class RenderAPI : u32;
|
enum class RenderAPI : u32;
|
||||||
|
@ -525,6 +530,7 @@ extern std::string SaveStates;
|
||||||
extern std::string Screenshots;
|
extern std::string Screenshots;
|
||||||
extern std::string Shaders;
|
extern std::string Shaders;
|
||||||
extern std::string Textures;
|
extern std::string Textures;
|
||||||
|
extern std::string UserResources;
|
||||||
|
|
||||||
// Assumes that AppRoot and DataRoot have been initialized.
|
// Assumes that AppRoot and DataRoot have been initialized.
|
||||||
void SetDefaults();
|
void SetDefaults();
|
||||||
|
@ -534,4 +540,7 @@ void Save(SettingsInterface& si);
|
||||||
|
|
||||||
/// Updates the variables in the EmuFolders namespace, reloading subsystems if needed.
|
/// Updates the variables in the EmuFolders namespace, reloading subsystems if needed.
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
/// Returns the path to a resource file, allowing the user to override it.
|
||||||
|
std::string GetOverridableResourcePath(std::string_view name);
|
||||||
} // namespace EmuFolders
|
} // namespace EmuFolders
|
||||||
|
|
|
@ -75,6 +75,7 @@ static void SetResourcesDirectory();
|
||||||
static void SetDataDirectory();
|
static void SetDataDirectory();
|
||||||
static bool SetCriticalFolders();
|
static bool SetCriticalFolders();
|
||||||
static void SetDefaultSettings(SettingsInterface& si, bool system, bool controller);
|
static void SetDefaultSettings(SettingsInterface& si, bool system, bool controller);
|
||||||
|
static std::string GetResourcePath(std::string_view name, bool allow_override);
|
||||||
static void StartCPUThread();
|
static void StartCPUThread();
|
||||||
static void StopCPUThread();
|
static void StopCPUThread();
|
||||||
static void ProcessCPUThreadEvents(bool block);
|
static void ProcessCPUThreadEvents(bool block);
|
||||||
|
@ -360,33 +361,39 @@ s32 Host::Internal::GetTranslatedStringImpl(const std::string_view& context, con
|
||||||
return static_cast<s32>(msg.size());
|
return static_cast<s32>(msg.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host::ResourceFileExists(const char* filename)
|
ALWAYS_INLINE std::string NoGUIHost::GetResourcePath(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
return allow_override ? EmuFolders::GetOverridableResourcePath(filename) :
|
||||||
|
Path::Combine(EmuFolders::Resources, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Host::ResourceFileExists(std::string_view filename, bool allow_override)
|
||||||
|
{
|
||||||
|
const std::string path = NoGUIHost::GetResourcePath(filename, allow_override);
|
||||||
return FileSystem::FileExists(path.c_str());
|
return FileSystem::FileExists(path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::vector<u8>> Host::ReadResourceFile(const char* filename)
|
std::optional<std::vector<u8>> Host::ReadResourceFile(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path = NoGUIHost::GetResourcePath(filename, allow_override);
|
||||||
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(path.c_str()));
|
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(path.c_str()));
|
||||||
if (!ret.has_value())
|
if (!ret.has_value())
|
||||||
Log_ErrorPrintf("Failed to read resource file '%s'", filename);
|
Log_ErrorPrintf("Failed to read resource file '%s'", filename);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> Host::ReadResourceFileToString(const char* filename)
|
std::optional<std::string> Host::ReadResourceFileToString(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path = NoGUIHost::GetResourcePath(filename, allow_override);
|
||||||
std::optional<std::string> ret(FileSystem::ReadFileToString(path.c_str()));
|
std::optional<std::string> ret(FileSystem::ReadFileToString(path.c_str()));
|
||||||
if (!ret.has_value())
|
if (!ret.has_value())
|
||||||
Log_ErrorPrintf("Failed to read resource file to string '%s'", filename);
|
Log_ErrorPrintf("Failed to read resource file to string '%s'", filename);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::time_t> Host::GetResourceFileTimestamp(const char* filename)
|
std::optional<std::time_t> Host::GetResourceFileTimestamp(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path = NoGUIHost::GetResourcePath(filename, allow_override);
|
||||||
FILESYSTEM_STAT_DATA sd;
|
FILESYSTEM_STAT_DATA sd;
|
||||||
if (!FileSystem::StatFile(path.c_str(), &sd))
|
if (!FileSystem::StatFile(path.c_str(), &sd))
|
||||||
{
|
{
|
||||||
|
|
|
@ -90,6 +90,7 @@ static bool SetCriticalFolders();
|
||||||
static void SetDefaultSettings(SettingsInterface& si, bool system, bool controller);
|
static void SetDefaultSettings(SettingsInterface& si, bool system, bool controller);
|
||||||
static void SaveSettings();
|
static void SaveSettings();
|
||||||
static bool RunSetupWizard();
|
static bool RunSetupWizard();
|
||||||
|
static std::string GetResourcePath(std::string_view name, bool allow_override);
|
||||||
static void InitializeEarlyConsole();
|
static void InitializeEarlyConsole();
|
||||||
static void HookSignals();
|
static void HookSignals();
|
||||||
static void PrintCommandLineVersion();
|
static void PrintCommandLineVersion();
|
||||||
|
@ -1442,33 +1443,39 @@ void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
|
||||||
identifier.empty() ? QString() : QString::fromUtf8(identifier.data(), identifier.size()));
|
identifier.empty() ? QString() : QString::fromUtf8(identifier.data(), identifier.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host::ResourceFileExists(const char* filename)
|
ALWAYS_INLINE std::string QtHost::GetResourcePath(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
return allow_override ? EmuFolders::GetOverridableResourcePath(filename) : Path::Combine(EmuFolders::Resources, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Host::ResourceFileExists(std::string_view filename, bool allow_override)
|
||||||
|
{
|
||||||
|
const std::string path = QtHost::GetResourcePath(filename, allow_override);
|
||||||
return FileSystem::FileExists(path.c_str());
|
return FileSystem::FileExists(path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::vector<u8>> Host::ReadResourceFile(const char* filename)
|
std::optional<std::vector<u8>> Host::ReadResourceFile(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path = QtHost::GetResourcePath(filename, allow_override);
|
||||||
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(path.c_str()));
|
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(path.c_str()));
|
||||||
if (!ret.has_value())
|
if (!ret.has_value())
|
||||||
Log_ErrorPrintf("Failed to read resource file '%s'", filename);
|
Log_ErrorPrintf("Failed to read resource file '%s'", filename);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> Host::ReadResourceFileToString(const char* filename)
|
std::optional<std::string> Host::ReadResourceFileToString(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path = QtHost::GetResourcePath(filename, allow_override);
|
||||||
std::optional<std::string> ret(FileSystem::ReadFileToString(path.c_str()));
|
std::optional<std::string> ret(FileSystem::ReadFileToString(path.c_str()));
|
||||||
if (!ret.has_value())
|
if (!ret.has_value())
|
||||||
Log_ErrorPrintf("Failed to read resource file to string '%s'", filename);
|
Log_ErrorPrintf("Failed to read resource file to string '%s'", filename);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::time_t> Host::GetResourceFileTimestamp(const char* filename)
|
std::optional<std::time_t> Host::GetResourceFileTimestamp(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path = QtHost::GetResourcePath(filename, allow_override);
|
||||||
|
|
||||||
FILESYSTEM_STAT_DATA sd;
|
FILESYSTEM_STAT_DATA sd;
|
||||||
if (!FileSystem::StatFile(path.c_str(), &sd))
|
if (!FileSystem::StatFile(path.c_str(), &sd))
|
||||||
{
|
{
|
||||||
|
|
|
@ -181,13 +181,13 @@ void Host::CommitBaseSettingChanges()
|
||||||
// noop, in memory
|
// noop, in memory
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Host::ResourceFileExists(const char* filename)
|
bool Host::ResourceFileExists(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
||||||
return FileSystem::FileExists(path.c_str());
|
return FileSystem::FileExists(path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::vector<u8>> Host::ReadResourceFile(const char* filename)
|
std::optional<std::vector<u8>> Host::ReadResourceFile(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
||||||
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(path.c_str()));
|
std::optional<std::vector<u8>> ret(FileSystem::ReadBinaryFile(path.c_str()));
|
||||||
|
@ -196,7 +196,7 @@ std::optional<std::vector<u8>> Host::ReadResourceFile(const char* filename)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> Host::ReadResourceFileToString(const char* filename)
|
std::optional<std::string> Host::ReadResourceFileToString(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
||||||
std::optional<std::string> ret(FileSystem::ReadFileToString(path.c_str()));
|
std::optional<std::string> ret(FileSystem::ReadFileToString(path.c_str()));
|
||||||
|
@ -205,7 +205,7 @@ std::optional<std::string> Host::ReadResourceFileToString(const char* filename)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::time_t> Host::GetResourceFileTimestamp(const char* filename)
|
std::optional<std::time_t> Host::GetResourceFileTimestamp(std::string_view filename, bool allow_override)
|
||||||
{
|
{
|
||||||
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
const std::string path(Path::Combine(EmuFolders::Resources, filename));
|
||||||
FILESYSTEM_STAT_DATA sd;
|
FILESYSTEM_STAT_DATA sd;
|
||||||
|
|
|
@ -13,17 +13,17 @@
|
||||||
|
|
||||||
namespace Host {
|
namespace Host {
|
||||||
/// Returns true if the specified resource file exists.
|
/// 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.
|
/// Reads a file from the resources directory of the application.
|
||||||
/// This may be outside of the "normal" filesystem on platforms such as Mac.
|
/// 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.
|
/// 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.
|
/// 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.
|
/// 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);
|
void ReportErrorAsync(const std::string_view& title, const std::string_view& message);
|
||||||
|
|
|
@ -274,7 +274,7 @@ std::optional<Common::RGBA8Image> ImGuiFullscreen::LoadTextureImage(const char*
|
||||||
if (Path::IsAbsolute(path))
|
if (Path::IsAbsolute(path))
|
||||||
data = FileSystem::ReadBinaryFile(path);
|
data = FileSystem::ReadBinaryFile(path);
|
||||||
else
|
else
|
||||||
data = Host::ReadResourceFile(path);
|
data = Host::ReadResourceFile(path, true);
|
||||||
if (data.has_value())
|
if (data.has_value())
|
||||||
{
|
{
|
||||||
image = Common::RGBA8Image();
|
image = Common::RGBA8Image();
|
||||||
|
|
|
@ -477,7 +477,7 @@ bool ImGuiManager::LoadFontData()
|
||||||
if (s_standard_font_data.empty())
|
if (s_standard_font_data.empty())
|
||||||
{
|
{
|
||||||
std::optional<std::vector<u8>> font_data = s_font_path.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());
|
FileSystem::ReadBinaryFile(s_font_path.c_str());
|
||||||
if (!font_data.has_value())
|
if (!font_data.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
@ -487,7 +487,7 @@ bool ImGuiManager::LoadFontData()
|
||||||
|
|
||||||
if (s_fixed_font_data.empty())
|
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())
|
if (!font_data.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -496,7 +496,7 @@ bool ImGuiManager::LoadFontData()
|
||||||
|
|
||||||
if (s_icon_fa_font_data.empty())
|
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())
|
if (!font_data.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -505,7 +505,7 @@ bool ImGuiManager::LoadFontData()
|
||||||
|
|
||||||
if (s_icon_pf_font_data.empty())
|
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())
|
if (!font_data.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -402,7 +402,7 @@ std::unique_ptr<PostProcessing::Shader> PostProcessing::TryLoadingShader(const s
|
||||||
|
|
||||||
filename =
|
filename =
|
||||||
fmt::format("shaders/reshade" FS_OSPATH_SEPARATOR_STR "Shaders" FS_OSPATH_SEPARATOR_STR "{}.fx", shader_name);
|
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())
|
if (resource_str.has_value())
|
||||||
{
|
{
|
||||||
std::unique_ptr<ReShadeFXShader> shader = std::make_unique<ReShadeFXShader>();
|
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);
|
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())
|
if (resource_str.has_value())
|
||||||
{
|
{
|
||||||
std::unique_ptr<GLSLShader> shader = std::make_unique<GLSLShader>();
|
std::unique_ptr<GLSLShader> shader = std::make_unique<GLSLShader>();
|
||||||
|
|
|
@ -45,7 +45,7 @@ static bool PreprocessorFileExistsCallback(const std::string& path)
|
||||||
if (Path::IsAbsolute(path))
|
if (Path::IsAbsolute(path))
|
||||||
return FileSystem::FileExists(path.c_str());
|
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)
|
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))
|
if (Path::IsAbsolute(path))
|
||||||
rdata = FileSystem::ReadFileToString(path.c_str());
|
rdata = FileSystem::ReadFileToString(path.c_str());
|
||||||
else
|
else
|
||||||
rdata = Host::ReadResourceFileToString(path.c_str());
|
rdata = Host::ReadResourceFileToString(path.c_str(), true);
|
||||||
if (!rdata.has_value())
|
if (!rdata.has_value())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -935,7 +935,7 @@ bool PostProcessing::ReShadeFXShader::CreatePasses(GPUTexture::Format backbuffer
|
||||||
{
|
{
|
||||||
// Might be a base file/resource instead.
|
// Might be a base file/resource instead.
|
||||||
const std::string resource_name = Path::Combine("shaders/reshade/Textures", source);
|
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()))
|
!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());
|
Error::SetString(error, fmt::format("Failed to load image '{}' (from '{}')", source, image_path).c_str());
|
||||||
|
|
|
@ -243,7 +243,7 @@ void SDLInputSource::SetHints()
|
||||||
Log_InfoFmt("Using Controller DB from user directory: '{}'", upath);
|
Log_InfoFmt("Using Controller DB from user directory: '{}'", upath);
|
||||||
SDL_SetHint(SDL_HINT_GAMECONTROLLERCONFIG_FILE, upath.c_str());
|
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()))
|
FileSystem::FileExists(rpath.c_str()))
|
||||||
{
|
{
|
||||||
Log_InfoPrint("Using Controller DB from resources.");
|
Log_InfoPrint("Using Controller DB from resources.");
|
||||||
|
|
Loading…
Reference in a new issue