diff --git a/FEXCore/Source/Interface/Config/Config.cpp b/FEXCore/Source/Interface/Config/Config.cpp index f64136dd3a..339539951d 100644 --- a/FEXCore/Source/Interface/Config/Config.cpp +++ b/FEXCore/Source/Interface/Config/Config.cpp @@ -130,7 +130,7 @@ namespace DefaultValues { static fextl::map> ConfigLayers; static FEXCore::Config::Layer *Meta{}; - constexpr std::array LoadOrder = { + constexpr std::array LoadOrder = { FEXCore::Config::LayerType::LAYER_GLOBAL_MAIN, FEXCore::Config::LayerType::LAYER_MAIN, FEXCore::Config::LayerType::LAYER_GLOBAL_STEAM_APP, @@ -138,6 +138,7 @@ namespace DefaultValues { FEXCore::Config::LayerType::LAYER_LOCAL_STEAM_APP, FEXCore::Config::LayerType::LAYER_LOCAL_APP, FEXCore::Config::LayerType::LAYER_ARGUMENTS, + FEXCore::Config::LayerType::LAYER_USER_OVERRIDE, FEXCore::Config::LayerType::LAYER_ENVIRONMENT, FEXCore::Config::LayerType::LAYER_TOP }; diff --git a/FEXCore/include/FEXCore/Config/Config.h b/FEXCore/include/FEXCore/Config/Config.h index 9aa01f2d13..38c2aa5352 100644 --- a/FEXCore/include/FEXCore/Config/Config.h +++ b/FEXCore/include/FEXCore/Config/Config.h @@ -81,6 +81,7 @@ namespace Handler { LAYER_GLOBAL_APP, LAYER_LOCAL_STEAM_APP, LAYER_LOCAL_APP, + LAYER_USER_OVERRIDE, LAYER_ENVIRONMENT, LAYER_TOP, }; diff --git a/Source/Common/Config.cpp b/Source/Common/Config.cpp index 5a1aaef50e..1430479ed7 100644 --- a/Source/Common/Config.cpp +++ b/Source/Common/Config.cpp @@ -129,6 +129,8 @@ namespace JSON { public: explicit MainLoader(FEXCore::Config::LayerType Type); explicit MainLoader(fextl::string ConfigFile); + explicit MainLoader(FEXCore::Config::LayerType Type, const char* ConfigFile); + void Load() override; private: @@ -188,6 +190,12 @@ namespace JSON { , Config{std::move(ConfigFile)} { } + + MainLoader::MainLoader(FEXCore::Config::LayerType Type, const char* ConfigFile) + : OptionMapper(Type) + , Config{ConfigFile} { + } + void MainLoader::Load() { JSON::LoadJSonConfig(Config, [this](const char *Name, const char *ConfigString) { MapNameToOption(Name, ConfigString); @@ -276,6 +284,10 @@ namespace JSON { } } + fextl::unique_ptr CreateUserOverrideLayer(const char* AppConfig) { + return fextl::make_unique(FEXCore::Config::LayerType::LAYER_USER_OVERRIDE, AppConfig); + } + fextl::unique_ptr CreateAppLayer(const fextl::string& Filename, FEXCore::Config::LayerType Type) { return fextl::make_unique(Filename, Type); } @@ -371,6 +383,11 @@ namespace JSON { FEXCore::Config::AddLayer(fextl::make_unique(argc, argv)); } + const char *AppConfig = getenv("FEX_APP_CONFIG"); + if (AppConfig && FHU::Filesystem::Exists(AppConfig)) { + FEXCore::Config::AddLayer(CreateUserOverrideLayer(AppConfig)); + } + FEXCore::Config::AddLayer(CreateEnvironmentLayer(envp)); FEXCore::Config::Load(); @@ -529,21 +546,7 @@ namespace JSON { } fextl::string GetConfigFileLocation(bool Global) { - fextl::string ConfigFile{}; - if (Global) { - ConfigFile = GetConfigDirectory(true) + "Config.json"; - } - else { - const char *AppConfig = getenv("FEX_APP_CONFIG"); - if (AppConfig) { - // App config environment variable overwrites only the config file - ConfigFile = AppConfig; - } - else { - ConfigFile = GetConfigDirectory(false) + "Config.json"; - } - } - return ConfigFile; + return GetConfigDirectory(Global) + "Config.json"; } void InitializeConfigs() { diff --git a/Source/Common/Config.h b/Source/Common/Config.h index 5e08d1ef7c..5e7bbeb040 100644 --- a/Source/Common/Config.h +++ b/Source/Common/Config.h @@ -73,6 +73,7 @@ namespace FEX::Config { * @return unique_ptr for that layer */ fextl::unique_ptr CreateMainLayer(fextl::string const *File = nullptr); + fextl::unique_ptr CreateUserOverrideLayer(const char* AppConfig); /** * @brief Create an application configuration loader diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp index 4fafd612c9..75941f9e3d 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/FileManagement.cpp @@ -219,6 +219,7 @@ FileManager::FileManager(FEXCore::Context::Context *ctx) // - AppConfig Global // - Steam AppConfig Local // - AppConfig Local + // - AppConfig override // This doesn't support the classic thunks interface. auto AppName = AppConfigName(); @@ -245,6 +246,11 @@ FileManager::FileManager(FEXCore::Context::Context *ctx) ConfigPaths.emplace_back(FEXCore::Config::GetApplicationConfig(AppName, false)); } + const char *AppConfig = getenv("FEX_APP_CONFIG"); + if (AppConfig) { + ConfigPaths.emplace_back(AppConfig); + } + if (!LDPath().empty()) { RootFSFD = open(LDPath().c_str(), O_DIRECTORY | O_PATH | O_CLOEXEC); if (RootFSFD == -1) {