252 lines
11 KiB
C++
252 lines
11 KiB
C++
#pragma once
|
|
|
|
#include "core/utils/toml.hpp"
|
|
#include <glm/vec4.hpp>
|
|
#include <limits.h>
|
|
#include <iomanip>
|
|
#include "world/Universe.hpp"
|
|
#include "render/Renderer.hpp"
|
|
#include "render/Window.hpp"
|
|
#include "contouring/Abstract.hpp"
|
|
#include "control/Camera.hpp"
|
|
|
|
namespace config::client {
|
|
|
|
inline glm::vec4 fromHex(const std::string& str) {
|
|
std::array<int, 3> rgb = {UCHAR_MAX};
|
|
sscanf(str.c_str() + 1, "%02X%02X%02X", (unsigned int *)&rgb[0], (unsigned int *)&rgb[1], (unsigned int *)&rgb[2]);
|
|
return glm::vec4(rgb[0] * 1.f / UCHAR_MAX, rgb[1] * 1.f / UCHAR_MAX, rgb[2] * 1.f / UCHAR_MAX, 1);
|
|
}
|
|
inline std::string toHexa(const glm::vec4& rgb) {
|
|
std::ostringstream sstr;
|
|
sstr << '#' << std::hex << std::setw(2) << std::setfill('0') <<
|
|
static_cast<int>(rgb.x * UCHAR_MAX) << static_cast<int>(rgb.y * UCHAR_MAX) << static_cast<int>(rgb.z * UCHAR_MAX);
|
|
return sstr.str();
|
|
}
|
|
|
|
/// Client side configuration
|
|
struct options {
|
|
public:
|
|
options(toml::node_view<toml::node> config) {
|
|
assert(config["enabled"] && "probably a broken config file");
|
|
|
|
window.targetFPS = config["window"]["target_fps"].value_or(window.targetFPS);
|
|
window.sampling = config["window"]["sampling"].value_or(window.sampling);
|
|
window.fullscreen = config["window"]["fullscreen"].value_or(window.fullscreen);
|
|
renderer.inFlightFrames = config["window"]["parallel_frames"].value_or(renderer.inFlightFrames);
|
|
|
|
preferVulkan = config["render"]["prefer_vulkan"].value_or(preferVulkan);
|
|
renderer.textures = config["render"]["textures"].value_or(renderer.textures);
|
|
renderer.textureQuality = config["render"]["texture_quality"].value_or(renderer.textureQuality);
|
|
renderer.textureSharpness = config["render"]["texture_angular_quality"].value_or(renderer.textureSharpness);
|
|
renderer.voxel.pbr = config["render"]["pbr"].value_or(renderer.voxel.pbr);
|
|
renderer.voxel.planar = static_cast<render::Planar>(config["render"]["planar"].value_or(static_cast<int>(renderer.voxel.planar)));
|
|
renderer.voxel.stochastic = config["render"]["stochastic"].value_or(renderer.voxel.stochastic);
|
|
renderer.voxel.geometry = config["render"]["geometry"].value_or(renderer.voxel.geometry);
|
|
renderer.voxel.blend = config["render"]["blend"].value_or(renderer.voxel.blend);
|
|
renderer.voxel.fog = config["render"]["fog"].value_or(renderer.voxel.fog);
|
|
const std::string fog = config["render"]["fog_color"].value_or(std::string{"#000000"});
|
|
renderer.clear_color = fromHex(fog);
|
|
renderer.skybox = config["render"]["skybox"].value_or(renderer.skybox);
|
|
renderer.voxel.curvature = config["render"]["curvature"].value_or(renderer.voxel.curvature);
|
|
renderer.voxel.curv_depth = config["render"]["curvature_depth"].value_or(renderer.voxel.curv_depth);
|
|
renderer.voxel.transparency = config["render"]["transparency"].value_or(renderer.voxel.transparency);
|
|
culling = config["render"]["culling"].value_or(culling);
|
|
|
|
contouring = config["contouring"].value_or(std::string(""));
|
|
|
|
camera.far_dist = config["camera"]["far"].value_or(camera.far_dist);
|
|
camera.near_dist = config["camera"]["near"].value_or(camera.near_dist);
|
|
camera.fov = config["camera"]["fov"].value_or(camera.fov);
|
|
control.sensibility = config["control"]["sensibility"].value_or(control.sensibility);
|
|
control.speed = config["control"]["speed"].value_or(control.speed);
|
|
control.collide = config["control"]["collide"].value_or(control.collide);
|
|
|
|
world.loadDistance = config["world"]["load_distance"].value_or(world.loadDistance);
|
|
world.keepDistance = config["world"]["keep_distance"].value_or(world.keepDistance);
|
|
world.useAverages = config["world"]["use_averages"].value_or(world.useAverages);
|
|
world.trustMajorant = config["world"]["trust_majorant"].value_or(world.trustMajorant);
|
|
world.editPrediction = config["world"]["edit_prediction"].value_or(world.editPrediction);
|
|
world.editHandling = config["world"]["edit_handling"].value_or(world.editHandling);
|
|
world.movePrediction = config["world"]["move_prediction"].value_or(world.movePrediction);
|
|
world.moveCollision = config["world"]["move_collision"].value_or(world.moveCollision);
|
|
|
|
#ifndef LIGHT_CLIENT
|
|
const auto useLocal = config["connection"]["use_local"].value_or(true);
|
|
#else
|
|
const auto useLocal = false;
|
|
#endif
|
|
|
|
if(!useLocal) {
|
|
world::client::Universe::connection ct;
|
|
ct.host = config["connection"]["host"].value_or(ct.host);
|
|
ct.port = config["connection"]["port"].value_or(ct.port);
|
|
connection = ct;
|
|
}
|
|
|
|
editor.visible = config["editor"]["visible"].value_or(editor.visible);
|
|
editor.tool.shape = static_cast<world::action::Shape>(config["editor"]["tool"]["shape"].value_or(static_cast<int>(editor.tool.shape)));
|
|
editor.tool.radius = config["editor"]["tool"]["radius"].value_or(editor.tool.radius);
|
|
editor.tool.material = config["editor"]["tool"]["material"].value_or(editor.tool.material);
|
|
editor.tool.emptyAir = config["editor"]["tool"]["empty_air"].value_or(editor.tool.emptyAir);
|
|
|
|
console.visible = config["console"]["visible"].value_or(console.visible);
|
|
console.scroll = config["console"]["scroll"].value_or(console.scroll);
|
|
console.opacity = config["console"]["opacity"].value_or(console.opacity);
|
|
|
|
debugMenu.bar = config["debug_menu"]["bar"].value_or(debugMenu.bar);
|
|
debugMenu.render = config["debug_menu"]["render"].value_or(debugMenu.render);
|
|
debugMenu.world = config["debug_menu"]["world"].value_or(debugMenu.world);
|
|
debugMenu.contouring = config["debug_menu"]["contouring"].value_or(debugMenu.contouring);
|
|
debugMenu.controls = config["debug_menu"]["controls"].value_or(debugMenu.controls);
|
|
|
|
overlay.visible = config["overlay"]["visible"].value_or(overlay.visible);
|
|
overlay.corner = config["overlay"]["corner"].value_or(overlay.corner);
|
|
|
|
if (config["keys"].is_table()) {
|
|
for(auto entry: *config["keys"].as_table()) {
|
|
keys.emplace_back(std::stoi(entry.first), entry.second.value_or(-1));
|
|
}
|
|
}
|
|
}
|
|
|
|
toml::table save() {
|
|
auto config = toml::table();
|
|
config.insert_or_assign("enabled", true);
|
|
config.insert_or_assign("window", toml::table({
|
|
{"target_fps", window.targetFPS},
|
|
{"sampling", window.sampling},
|
|
{"fullscreen", window.fullscreen},
|
|
{"parallel_frames", renderer.inFlightFrames}
|
|
}));
|
|
config.insert_or_assign("render", toml::table({
|
|
{"prefer_vulkan", preferVulkan},
|
|
{"textures", renderer.textures},
|
|
{"texture_quality", renderer.textureQuality},
|
|
{"texture_angular_quality", renderer.textureSharpness},
|
|
{"pbr", renderer.voxel.pbr},
|
|
{"planar", static_cast<int>(renderer.voxel.planar)},
|
|
{"stochastic", renderer.voxel.stochastic},
|
|
{"geometry", renderer.voxel.geometry},
|
|
{"blend", renderer.voxel.blend},
|
|
{"fog", renderer.voxel.fog},
|
|
{"fog_color", toHexa(renderer.clear_color)},
|
|
{"skybox", renderer.skybox},
|
|
{"curvature", renderer.voxel.curvature},
|
|
{"curvature_depth", renderer.voxel.curv_depth},
|
|
{"transparency", renderer.voxel.transparency},
|
|
{"culling", culling}
|
|
}));
|
|
config.insert_or_assign("contouring", contouring);
|
|
config.insert_or_assign("camera", toml::table({
|
|
{"far", camera.far_dist},
|
|
{"near", camera.near_dist},
|
|
{"fov", camera.fov}
|
|
}));
|
|
config.insert_or_assign("control", toml::table({
|
|
{"sensibility", control.sensibility},
|
|
{"speed", control.speed},
|
|
{"collide", control.collide}
|
|
}));
|
|
config.insert_or_assign("world", toml::table({
|
|
{"load_distance", world.loadDistance},
|
|
{"keep_distance", world.keepDistance},
|
|
{"use_averages", world.useAverages},
|
|
{"trust_majorant", world.trustMajorant},
|
|
{"edit_prediction", world.editPrediction},
|
|
{"edit_handling", world.editHandling},
|
|
{"move_prediction", world.movePrediction},
|
|
{"move_collision", world.moveCollision}
|
|
}));
|
|
if(connection.has_value()) {
|
|
const auto &ct = connection.value();
|
|
config.insert_or_assign("connection", toml::table({
|
|
#ifndef LIGHT_CLIENT
|
|
{"use_local", false},
|
|
#endif
|
|
{"host", ct.host},
|
|
{"port", ct.port}
|
|
}));
|
|
} else {
|
|
config.insert_or_assign("connection", toml::table({{"use_local", true}}));
|
|
}
|
|
|
|
config.insert_or_assign("editor", toml::table({
|
|
{"visible", editor.visible},
|
|
{"tool", toml::table({
|
|
{"shape", static_cast<int>(editor.tool.shape)},
|
|
{"radius", editor.tool.radius},
|
|
{"material", editor.tool.material},
|
|
{"empty_air", editor.tool.emptyAir}
|
|
})}
|
|
}));
|
|
config.insert_or_assign("console", toml::table({
|
|
{"visible", console.visible},
|
|
{"scroll", console.scroll},
|
|
{"opacity", console.opacity}
|
|
}));
|
|
config.insert_or_assign("debug_menu", toml::table({
|
|
{"bar", debugMenu.bar},
|
|
{"render", debugMenu.render},
|
|
{"world", debugMenu.world},
|
|
{"contouring", debugMenu.contouring},
|
|
{"controls", debugMenu.controls}
|
|
}));
|
|
config.insert_or_assign("overlay", toml::table({
|
|
{"visible", overlay.visible},
|
|
{"corner", overlay.corner}
|
|
}));
|
|
toml::table key_table;
|
|
for (const auto& key: keys)
|
|
key_table.insert_or_assign(std::to_string(key.first), key.second);
|
|
config.insert_or_assign("keys", key_table);
|
|
return config;
|
|
}
|
|
|
|
world::client::Universe::options world;
|
|
|
|
struct {
|
|
bool bar = false;
|
|
bool render = false;
|
|
bool world = false;
|
|
bool contouring = false;
|
|
bool controls = false;
|
|
} debugMenu;
|
|
|
|
windowOptions window;
|
|
|
|
bool preferVulkan = false;
|
|
render::renderOptions renderer;
|
|
int culling = 0;
|
|
|
|
std::string contouring;
|
|
|
|
Controllable::options control;
|
|
Camera::options camera;
|
|
|
|
struct {
|
|
bool visible = false;
|
|
struct {
|
|
world::action::Shape shape = world::action::Shape::Cube;
|
|
int radius = 2;
|
|
unsigned short material = 5;
|
|
bool emptyAir = true;
|
|
} tool;
|
|
} editor;
|
|
|
|
struct {
|
|
bool visible = true;
|
|
bool scroll = true;
|
|
float opacity = .8f;
|
|
} console;
|
|
|
|
struct overlay_t {
|
|
bool visible = true;
|
|
int corner = 3;
|
|
} overlay;
|
|
|
|
std::optional<world::client::Universe::connection> connection = {};
|
|
|
|
std::vector<std::pair<int, int>> keys;
|
|
};
|
|
} |