mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-04-27 21:01:41 +00:00
initial config file
This commit is contained in:
parent
455e114aef
commit
a5ea1893ab
8 changed files with 145 additions and 15 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
|
@ -4,3 +4,6 @@
|
||||||
[submodule "thirdparty/dxbc"]
|
[submodule "thirdparty/dxbc"]
|
||||||
path = thirdparty/dxbc
|
path = thirdparty/dxbc
|
||||||
url = https://github.com/PancakeTAS/dxbc.git
|
url = https://github.com/PancakeTAS/dxbc.git
|
||||||
|
[submodule "thirdparty/toml11"]
|
||||||
|
path = thirdparty/toml11
|
||||||
|
url = https://github.com/ToruNiina/toml11
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,10 @@ add_compile_options(-fPIC
|
||||||
|
|
||||||
add_subdirectory(thirdparty/dxbc EXCLUDE_FROM_ALL)
|
add_subdirectory(thirdparty/dxbc EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(thirdparty/pe-parse/pe-parser-library EXCLUDE_FROM_ALL)
|
add_subdirectory(thirdparty/pe-parse/pe-parser-library EXCLUDE_FROM_ALL)
|
||||||
|
add_subdirectory(thirdparty/toml11 EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(framegen)
|
add_subdirectory(framegen)
|
||||||
|
|
||||||
|
|
||||||
# main project
|
# main project
|
||||||
project(lsfg-vk
|
project(lsfg-vk
|
||||||
VERSION 0.0.1
|
VERSION 0.0.1
|
||||||
|
|
@ -41,7 +43,10 @@ set_target_properties(lsfg-vk PROPERTIES
|
||||||
target_include_directories(lsfg-vk
|
target_include_directories(lsfg-vk
|
||||||
PRIVATE include)
|
PRIVATE include)
|
||||||
target_link_libraries(lsfg-vk PRIVATE
|
target_link_libraries(lsfg-vk PRIVATE
|
||||||
lsfg-vk-framegen pe-parse dxbc vulkan)
|
lsfg-vk-framegen pe-parse dxbc toml11 vulkan)
|
||||||
|
|
||||||
|
get_target_property(TOML11_INCLUDE_DIRS toml11 INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
|
target_include_directories(lsfg-vk SYSTEM PRIVATE ${TOML11_INCLUDE_DIRS})
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
set_target_properties(lsfg-vk PROPERTIES
|
set_target_properties(lsfg-vk PROPERTIES
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
@ -31,4 +32,31 @@ namespace LSFG {
|
||||||
VkResult result;
|
VkResult result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Simple exception class for stacking errors.
|
||||||
|
class rethrowable_error : public std::runtime_error {
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// Construct a new rethrowable_error with a message.
|
||||||
|
///
|
||||||
|
/// @param message The error message.
|
||||||
|
/// @param exe The original exception to rethrow.
|
||||||
|
///
|
||||||
|
explicit rethrowable_error(const std::string& message,
|
||||||
|
const std::exception& exe);
|
||||||
|
|
||||||
|
/// Get the exception as a string.
|
||||||
|
[[nodiscard]] const char* what() const noexcept override {
|
||||||
|
return message.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trivially copyable, moveable and destructible
|
||||||
|
rethrowable_error(const rethrowable_error&) = default;
|
||||||
|
rethrowable_error(rethrowable_error&&) = default;
|
||||||
|
rethrowable_error& operator=(const rethrowable_error&) = default;
|
||||||
|
rethrowable_error& operator=(rethrowable_error&&) = default;
|
||||||
|
~rethrowable_error() noexcept override;
|
||||||
|
private:
|
||||||
|
std::string message;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <vulkan/vulkan_core.h>
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <format>
|
#include <format>
|
||||||
|
|
@ -14,3 +15,10 @@ vulkan_error::vulkan_error(VkResult result, const std::string& message)
|
||||||
result(result) {}
|
result(result) {}
|
||||||
|
|
||||||
vulkan_error::~vulkan_error() noexcept = default;
|
vulkan_error::~vulkan_error() noexcept = default;
|
||||||
|
|
||||||
|
rethrowable_error::rethrowable_error(const std::string& message, const std::exception& exe)
|
||||||
|
: std::runtime_error(message) {
|
||||||
|
this->message = std::format("{}\n- {}", message, exe.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
rethrowable_error::~rethrowable_error() noexcept = default;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace Config {
|
namespace Config {
|
||||||
|
|
||||||
/// lsfg-vk configuration.
|
/// lsfg-vk configuration
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
/// Whether lsfg-vk should be loaded in the first place.
|
/// Whether lsfg-vk should be loaded in the first place.
|
||||||
bool enable{false};
|
bool enable{false};
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,99 @@
|
||||||
#include "config/config.hpp"
|
#include "config/config.hpp"
|
||||||
|
#include "common/exception.hpp"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <optional>
|
||||||
|
#include <toml11/find.hpp>
|
||||||
|
#include <toml11/parser.hpp>
|
||||||
|
#include <toml.hpp>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <string_view>
|
||||||
|
#include <exception>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <utility>
|
||||||
|
#include <atomic>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
using namespace Config;
|
using namespace Config;
|
||||||
|
|
||||||
const Configuration defaultConf{
|
namespace {
|
||||||
.enable = false
|
Configuration globalConf{};
|
||||||
};
|
std::optional<std::unordered_map<std::string, Configuration>> gameConfs;
|
||||||
|
}
|
||||||
|
|
||||||
bool Config::loadAndWatchConfig(const std::string& file) {
|
bool Config::loadAndWatchConfig(const std::string& file) {
|
||||||
|
// parse config file
|
||||||
|
toml::value toml{};
|
||||||
|
if (std::filesystem::exists(file)) {
|
||||||
|
try {
|
||||||
|
toml = toml::parse(file);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
throw LSFG::rethrowable_error("Unable to parse configuration file", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse global configuration
|
||||||
|
auto& global = globalConf;
|
||||||
|
const toml::value globalTable = toml::find_or_default<toml::table>(toml, "global");
|
||||||
|
global.enable = toml::find_or(globalTable, "enable", false);
|
||||||
|
global.dll = toml::find_or(globalTable, "dll", std::string());
|
||||||
|
global.multiplier = toml::find_or(globalTable, "multiplier", size_t(2));
|
||||||
|
global.flowScale = toml::find_or(globalTable, "flow_scale", 1.0F);
|
||||||
|
global.performance = toml::find_or(globalTable, "performance_mode", false);
|
||||||
|
global.hdr = toml::find_or(globalTable, "hdr_mode", false);
|
||||||
|
global.valid = std::make_shared<std::atomic_bool>(true);
|
||||||
|
|
||||||
|
// validate global configuration
|
||||||
|
if (global.multiplier < 2)
|
||||||
|
throw std::runtime_error("Multiplier cannot be less than 2");
|
||||||
|
if (global.flowScale < 0.25F || global.flowScale > 1.0F)
|
||||||
|
throw std::runtime_error("Flow scale must be between 0.25 and 1.0");
|
||||||
|
|
||||||
|
// parse game-specific configuration
|
||||||
|
auto& games = gameConfs.emplace();
|
||||||
|
const toml::value gamesList = toml::find_or_default<toml::array>(toml, "game");
|
||||||
|
for (const auto& gameTable : gamesList.as_array()) {
|
||||||
|
if (!gameTable.is_table())
|
||||||
|
throw std::runtime_error("Invalid game configuration entry");
|
||||||
|
if (!gameTable.contains("exe"))
|
||||||
|
throw std::runtime_error("Game override missing 'exe' field");
|
||||||
|
|
||||||
|
const std::string exe = toml::find<std::string>(gameTable, "exe");
|
||||||
|
Configuration game{
|
||||||
|
.enable = toml::find_or(gameTable, "enable", global.enable),
|
||||||
|
.dll = toml::find_or(gameTable, "dll", global.dll),
|
||||||
|
.multiplier = toml::find_or(gameTable, "multiplier", global.multiplier),
|
||||||
|
.flowScale = toml::find_or(gameTable, "flow_scale", global.flowScale),
|
||||||
|
.performance = toml::find_or(gameTable, "performance_mode", global.performance),
|
||||||
|
.hdr = toml::find_or(gameTable, "hdr_mode", global.hdr),
|
||||||
|
.valid = global.valid // only need a single validity flag
|
||||||
|
};
|
||||||
|
|
||||||
|
// validate the configuration
|
||||||
|
if (game.multiplier < 2)
|
||||||
|
throw std::runtime_error("Multiplier cannot be less than 2");
|
||||||
|
if (game.flowScale < 0.25F || game.flowScale > 1.0F)
|
||||||
|
throw std::runtime_error("Flow scale must be between 0.25 and 1.0");
|
||||||
|
games[exe] = std::move(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
// prepare config watcher
|
||||||
|
// (TODO)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Configuration Config::getConfig(std::string_view name) {
|
Configuration Config::getConfig(std::string_view name) {
|
||||||
return defaultConf;
|
if (name.empty() || !gameConfs.has_value())
|
||||||
|
return globalConf;
|
||||||
|
|
||||||
|
const auto& games = *gameConfs;
|
||||||
|
auto it = games.find(std::string(name));
|
||||||
|
if (it != games.end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
return globalConf;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/main.cpp
19
src/main.cpp
|
|
@ -46,8 +46,8 @@ namespace {
|
||||||
return{configFile};
|
return{configFile};
|
||||||
const char* homePath = std::getenv("HOME");
|
const char* homePath = std::getenv("HOME");
|
||||||
if (homePath && *homePath != '\0')
|
if (homePath && *homePath != '\0')
|
||||||
return std::string(homePath) + "/.config/lsfg-vk.conf";
|
return std::string(homePath) + "/.config/lsfg-vk.toml";
|
||||||
return "/etc/lsfg-vk.conf";
|
return "/etc/lsfg-vk.toml";
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((constructor)) void lsfgvk_init() {
|
__attribute__((constructor)) void lsfgvk_init() {
|
||||||
|
|
@ -57,6 +57,7 @@ namespace {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: health check, maybe?
|
||||||
std::cerr << "lsfg-vk: This library is not meant to be preloaded, unless you are running a benchmark.\n";
|
std::cerr << "lsfg-vk: This library is not meant to be preloaded, unless you are running a benchmark.\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
@ -66,8 +67,8 @@ namespace {
|
||||||
try {
|
try {
|
||||||
Config::loadAndWatchConfig(file);
|
Config::loadAndWatchConfig(file);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
std::cerr << "lsfg-vk: Unable to read configuration file, exiting." << '\n';
|
std::cerr << "lsfg-vk: An error occured while trying to parse the configuration, exiting:" << '\n';
|
||||||
std::cerr << e.what() << '\n';
|
std::cerr << "- " << e.what() << '\n';
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,10 +88,10 @@ namespace {
|
||||||
|
|
||||||
// print config
|
// print config
|
||||||
std::cerr << "lsfg-vk: Loaded configuration for " << name << ":\n";
|
std::cerr << "lsfg-vk: Loaded configuration for " << name << ":\n";
|
||||||
std::cerr << "lsfg-vk: Using DLL from: " << conf.dll << '\n';
|
if (!conf.dll.empty()) std::cerr << " Using DLL from: " << conf.dll << '\n';
|
||||||
std::cerr << "lsfg-vk: Multiplier: " << conf.multiplier << '\n';
|
std::cerr << " Multiplier: " << conf.multiplier << '\n';
|
||||||
std::cerr << "lsfg-vk: Flow Scale: " << conf.flowScale << '\n';
|
std::cerr << " Flow Scale: " << conf.flowScale << '\n';
|
||||||
std::cerr << "lsfg-vk: Performance Mode: " << (conf.performance ? "Enabled" : "Disabled") << '\n';
|
std::cerr << " Performance Mode: " << (conf.performance ? "Enabled" : "Disabled") << '\n';
|
||||||
std::cerr << "lsfg-vk: HDR: " << (conf.hdr ? "Enabled" : "Disabled") << '\n';
|
std::cerr << " HDR Mode: " << (conf.hdr ? "Enabled" : "Disabled") << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
thirdparty/toml11
vendored
Submodule
1
thirdparty/toml11
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit be08ba2be2a964edcdb3d3e3ea8d100abc26f286
|
||||||
Loading…
Add table
Reference in a new issue