settings page completely moved to xml

This commit is contained in:
MihailRis 2024-04-20 15:52:55 +03:00
parent 9cdf3ff016
commit b9ea88b988
15 changed files with 111 additions and 107 deletions

View File

@ -1,6 +1,7 @@
<panel size='400' color='0' interval='1' context='menu'>
<panel id='settings_panel' color='0'>
</panel>
<button onclick='menu.page="languages"' id='langs_btn'>-</button>
<button onclick='menu.page="settings_audio"'>@Audio</button>
<button onclick='menu.page="controls"'>@Controls</button>
<button onclick='menu:back()'>@Back</button>

View File

@ -23,9 +23,23 @@ function update_setting(x, id, name, postfix)
)
end
function create_checkbox(id, name)
document.settings_panel:add(string.format(
"<checkbox consumer='function(x) core.set_setting(\"%s\", x) end' checked='%s'>%s</checkbox>",
id, core.str_setting(id), gui.str(name, "settings")
))
end
function on_open()
create_setting("chunks.load-distance", "Load Distance", 1, 3)
create_setting("chunks.load-speed", "Load Speed", 1, 1)
create_setting("graphics.fog-curve", "Fog Curve", 0.1, 2)
create_setting("camera.fov", "FOV", 1, 4, "°")
create_checkbox("display.vsync", "V-Sync")
create_checkbox("graphics.backlight", "Backlight")
create_checkbox("camera.shaking", "Camera Shaking")
document.langs_btn.text = string.format(
"%s: %s", gui.str("Language", "settings"),
gui.get_locales_info()[gui.get_locale()].name
)
end

View File

@ -23,3 +23,12 @@ std::string IntegerSetting::toString() const {
return "invalid format";
}
}
std::string FlagSetting::toString() const {
switch (getFormat()) {
case setting_format::simple:
return value ? "true" : "false";
default:
return "invalid format";
}
}

View File

@ -156,4 +156,47 @@ public:
virtual std::string toString() const override;
};
class FlagSetting : public Setting {
protected:
bool initial;
bool value;
std::vector<consumer<bool>> consumers;
public:
FlagSetting(
bool value,
setting_format format=setting_format::simple
) : Setting(format),
initial(value),
value(value)
{}
bool& operator*() {
return value;
}
bool get() const {
return value;
}
void set(bool value) {
if (value == this->value) {
return;
}
this->value = value;
for (auto& callback : consumers) {
callback(value);
}
}
void observe(consumer<bool> callback) {
consumers.push_back(callback);
}
virtual void resetToDefault() override {
value = initial;
}
virtual std::string toString() const override;
};
#endif // DATA_SETTING_H_

View File

@ -149,7 +149,7 @@ void Engine::mainloop() {
if (!Window::isIconified()) {
renderFrame(batch);
}
Window::swapInterval(Window::isIconified() ? 1 : settings.display.swapInterval);
Window::swapInterval(Window::isIconified() ? 1 : settings.display.vsync.get());
processPostRunnables();

View File

@ -17,13 +17,17 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) {
map.emplace("audio.volume-ambient", &settings.audio.volumeAmbient);
map.emplace("audio.volume-music", &settings.audio.volumeMusic);
map.emplace("display.vsync", &settings.display.vsync);
map.emplace("camera.sensitivity", &settings.camera.sensitivity);
map.emplace("camera.fov", &settings.camera.fov);
map.emplace("camera.shaking", &settings.camera.shaking);
map.emplace("chunks.load-distance", &settings.chunks.loadDistance);
map.emplace("chunks.load-speed", &settings.chunks.loadSpeed);
map.emplace("graphics.fog-curve", &settings.graphics.fogCurve);
map.emplace("graphics.backlight", &settings.graphics.backlight);
}
dynamic::Value SettingsHandler::getValue(const std::string& name) const {
@ -36,6 +40,8 @@ dynamic::Value SettingsHandler::getValue(const std::string& name) const {
return dynamic::Value::of((number_t)number->get());
} else if (auto integer = dynamic_cast<IntegerSetting*>(setting)) {
return dynamic::Value::of((integer_t)integer->get());
} else if (auto flag = dynamic_cast<FlagSetting*>(setting)) {
return dynamic::Value::boolean(flag->get());
} else {
throw std::runtime_error("type is not implemented for '"+name+"'");
}
@ -58,6 +64,23 @@ Setting* SettingsHandler::getSetting(const std::string& name) const {
return found->second;
}
template<class T>
static void set_numeric_value(T* setting, dynamic::Value& value) {
switch (value.type) {
case dynamic::valtype::integer:
setting->set(std::get<integer_t>(value.value));
break;
case dynamic::valtype::number:
setting->set(std::get<number_t>(value.value));
break;
case dynamic::valtype::boolean:
setting->set(std::get<bool>(value.value));
break;
default:
throw std::runtime_error("type error, numeric value expected");
}
}
void SettingsHandler::setValue(const std::string& name, dynamic::Value value) {
auto found = map.find(name);
if (found == map.end()) {
@ -65,27 +88,11 @@ void SettingsHandler::setValue(const std::string& name, dynamic::Value value) {
}
auto setting = found->second;
if (auto number = dynamic_cast<NumberSetting*>(setting)) {
switch (value.type) {
case dynamic::valtype::integer:
number->set(std::get<integer_t>(value.value));
break;
case dynamic::valtype::number:
number->set(std::get<number_t>(value.value));
break;
default:
throw std::runtime_error("type error, numeric value expected");
}
set_numeric_value(number, value);
} else if (auto integer = dynamic_cast<IntegerSetting*>(setting)) {
switch (value.type) {
case dynamic::valtype::integer:
integer->set(std::get<integer_t>(value.value));
break;
case dynamic::valtype::number:
integer->set(std::get<number_t>(value.value));
break;
default:
throw std::runtime_error("type error, numeric value expected");
}
set_numeric_value(number, value);
} else if (auto flag = dynamic_cast<FlagSetting*>(setting)) {
set_numeric_value(flag, value);
} else {
throw std::runtime_error("type is not implement - setting '"+name+"'");
}
@ -107,7 +114,7 @@ toml::Wrapper* create_wrapper(EngineSettings& settings) {
display.add("width", &settings.display.width);
display.add("height", &settings.display.height);
display.add("samples", &settings.display.samples);
display.add("swap-interval", &settings.display.swapInterval);
display.add("vsync", &*settings.display.vsync);
toml::Section& chunks = wrapper->add("chunks");
chunks.add("load-distance", &*settings.chunks.loadDistance);
@ -117,13 +124,13 @@ toml::Wrapper* create_wrapper(EngineSettings& settings) {
toml::Section& camera = wrapper->add("camera");
camera.add("fov-effects", &settings.camera.fovEvents);
camera.add("fov", &*settings.camera.fov);
camera.add("shaking", &settings.camera.shaking);
camera.add("shaking", &*settings.camera.shaking);
camera.add("sensitivity", &*settings.camera.sensitivity);
toml::Section& graphics = wrapper->add("graphics");
graphics.add("gamma", &settings.graphics.gamma);
graphics.add("fog-curve", &*settings.graphics.fogCurve);
graphics.add("backlight", &settings.graphics.backlight);
graphics.add("backlight", &*settings.graphics.backlight);
graphics.add("frustum-culling", &settings.graphics.frustumCulling);
graphics.add("skybox-resolution", &settings.graphics.skyboxResolution);

View File

@ -17,9 +17,6 @@ class LevelController;
using packconsumer = std::function<void(const ContentPack& pack)>;
namespace menus {
// implemented in menu_settings.cpp
extern void create_settings_panel(Engine* engine);
extern std::shared_ptr<gui::Panel> create_packs_panel(
const std::vector<ContentPack>& packs,
Engine* engine,

View File

@ -1,67 +0,0 @@
#include "menu.h"
#include "menu_commons.h"
#include "../locale/langs.h"
#include "../../graphics/ui/GUI.h"
#include "../../graphics/ui/gui_util.h"
#include "../../engine.h"
#include "../../util/stringutil.h"
#include "../../window/Events.h"
#include <glm/glm.hpp>
using namespace gui;
void menus::create_settings_panel(Engine* engine) {
auto menu = engine->getGUI()->getMenu();
auto panel = menus::create_page(engine, "settings", 400, 0.0f, 1);
/* V-Sync checkbox */{
auto checkbox = std::make_shared<FullCheckBox>(
langs::get(L"V-Sync", L"settings"), glm::vec2(400, 32)
);
checkbox->setSupplier([=]() {
return engine->getSettings().display.swapInterval != 0;
});
checkbox->setConsumer([=](bool checked) {
engine->getSettings().display.swapInterval = checked;
});
panel->add(checkbox);
}
/* Backlight checkbox */{
auto checkbox = std::make_shared<FullCheckBox>(
langs::get(L"Backlight", L"settings"), glm::vec2(400, 32)
);
checkbox->setSupplier([=]() {
return engine->getSettings().graphics.backlight;
});
checkbox->setConsumer([=](bool checked) {
engine->getSettings().graphics.backlight = checked;
});
panel->add(checkbox);
}
/* Camera shaking checkbox */ {
auto checkbox = std::make_shared<FullCheckBox>(
langs::get(L"Camera Shaking", L"settings"), glm::vec2(400, 32)
);
checkbox->setSupplier([=]() {
return engine->getSettings().camera.shaking;
});
checkbox->setConsumer([=](bool checked) {
engine->getSettings().camera.shaking = checked;
});
panel->add(checkbox);
}
std::string langName = langs::locales_info.at(langs::current->getId()).name;
panel->add(guiutil::gotoButton(
langs::get(L"Language", L"settings")+L": "+
util::str2wstr_utf8(langName),
"languages", menu));
panel->add(guiutil::gotoButton(L"Audio", "settings_audio", menu));
panel->add(guiutil::gotoButton(L"Controls", "controls", menu));
panel->add(guiutil::backButton(menu));
}

View File

@ -102,7 +102,7 @@ LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) {
hud = std::make_unique<Hud>(engine, frontend.get(), controller->getPlayer());
backlight = settings.graphics.backlight;
backlight = settings.graphics.backlight.get();
animator = std::make_unique<TextureAnimator>();
animator->addAnimations(assets->getAnimations());
@ -167,9 +167,9 @@ void LevelScreen::update(float delta) {
// TODO: subscribe for setting change
EngineSettings& settings = engine->getSettings();
controller->getPlayer()->camera->setFov(glm::radians(settings.camera.fov.get()));
if (settings.graphics.backlight != backlight) {
if (settings.graphics.backlight.get() != backlight) {
controller->getLevel()->chunks->saveAndClear();
backlight = settings.graphics.backlight;
backlight = settings.graphics.backlight.get();
}
if (!hud->isPause()) {

View File

@ -449,7 +449,7 @@ void BlocksRenderer::render(const voxel* voxels) {
void BlocksRenderer::build(const Chunk* chunk, const ChunksStorage* chunks) {
this->chunk = chunk;
voxelsBuffer->setPosition(chunk->x * CHUNK_W - 1, 0, chunk->z * CHUNK_D - 1);
chunks->getVoxels(voxelsBuffer, settings.graphics.backlight);
chunks->getVoxels(voxelsBuffer, settings.graphics.backlight.get());
overflow = false;
vertexOffset = 0;
indexOffset = indexSize = 0;

View File

@ -254,7 +254,7 @@ static std::shared_ptr<UINode> readButton(UiXmlReader& reader, xml::xmlelement e
static std::shared_ptr<UINode> readCheckBox(UiXmlReader& reader, xml::xmlelement element) {
auto text = readAndProcessInnerText(element, reader.getContext());
bool checked = element->attr("checked", "false").asBool();
auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(), checked);
auto checkbox = std::make_shared<FullCheckBox>(text, glm::vec2(32), checked);
_readPanel(reader, element, *checkbox);
if (element->has("consumer")) {

View File

@ -139,7 +139,7 @@ void CameraControl::switchCamera() {
void CameraControl::update(PlayerInput& input, float delta, Chunks* chunks) {
offset = glm::vec3(0.0f, 0.7f, 0.0f);
if (settings.shaking && !input.cheat) {
if (settings.shaking.get() && !input.cheat) {
offset += updateCameraShaking(delta);
}
if (settings.fovEvents){

View File

@ -133,8 +133,8 @@ static int l_str_setting(lua_State* L) {
static int l_get_setting_info(lua_State* L) {
auto name = lua_tostring(L, 1);
auto setting = scripting::engine->getSettingsHandler().getSetting(name);
lua_createtable(L, 0, 1);
if (auto number = dynamic_cast<NumberSetting*>(setting)) {
lua_createtable(L, 0, 1);
lua_pushnumber(L, number->getMin());
lua_setfield(L, -2, "min");
lua_pushnumber(L, number->getMax());
@ -142,13 +142,13 @@ static int l_get_setting_info(lua_State* L) {
return 1;
}
if (auto integer = dynamic_cast<IntegerSetting*>(setting)) {
lua_createtable(L, 0, 1);
lua_pushinteger(L, integer->getMin());
lua_setfield(L, -2, "min");
lua_pushinteger(L, integer->getMax());
lua_setfield(L, -2, "max");
return 1;
}
lua_pop(L, 1);
luaL_error(L, "unsupported setting type");
return 0;
}

View File

@ -28,8 +28,8 @@ struct DisplaySettings {
int height = 720;
/// @brief Anti-aliasing samples
int samples = 0;
/// @brief GLFW swap interval value, 0 - unlimited fps, 1 - vsync
int swapInterval = 1;
/// @brief VSync on
FlagSetting vsync = {true};
/// @brief Window title */
std::string title = "VoxelEngine-Cpp v" +
std::to_string(ENGINE_VERSION_MAJOR) + "." +
@ -49,7 +49,7 @@ struct CameraSettings {
/// @brief Camera dynamic field of view effects
bool fovEvents = true;
/// @brief Camera movement shake
bool shaking = true;
FlagSetting shaking = {true};
/// @brief Camera field of view
NumberSetting fov {90.0f, 10, 120};
/// @brief Camera sensitivity
@ -62,7 +62,7 @@ struct GraphicsSettings {
NumberSetting fogCurve {1.6f, 1.0f, 6.0f};
float gamma = 1.0f;
/// @brief Enable blocks backlight to prevent complete darkness
bool backlight = true;
FlagSetting backlight = {true};
/// @brief Enable chunks frustum culling
bool frustumCulling = true;
int skyboxResolution = 64 + 32;

View File

@ -164,7 +164,7 @@ int Window::initialize(DisplaySettings& settings){
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, GLFW_DONT_CARE);
}
glfwSwapInterval(settings.swapInterval);
glfwSwapInterval(settings.vsync.get());
const GLubyte* vendor = glGetString(GL_VENDOR);
const GLubyte* renderer = glGetString(GL_RENDERER);
logger.info() << "GL Vendor: " << (char*)vendor;