diff --git a/res/layouts/pages/404.xml b/res/layouts/pages/404.xml index 375d4fde..1912fc2f 100644 --- a/res/layouts/pages/404.xml +++ b/res/layouts/pages/404.xml @@ -1,4 +1,4 @@ - + diff --git a/res/layouts/pages/add_packs.xml b/res/layouts/pages/add_packs.xml index defa84d5..e70993a6 100644 --- a/res/layouts/pages/add_packs.xml +++ b/res/layouts/pages/add_packs.xml @@ -2,5 +2,5 @@ - + diff --git a/res/layouts/pages/content.xml b/res/layouts/pages/content.xml index ea1a9e65..82037dfa 100644 --- a/res/layouts/pages/content.xml +++ b/res/layouts/pages/content.xml @@ -2,6 +2,6 @@ - - + + diff --git a/res/layouts/pages/controls.xml b/res/layouts/pages/controls.xml index 62af88b4..3082474c 100644 --- a/res/layouts/pages/controls.xml +++ b/res/layouts/pages/controls.xml @@ -7,5 +7,5 @@ - + diff --git a/res/layouts/pages/main.xml b/res/layouts/pages/main.xml index 08fb5d86..3ff1c23f 100644 --- a/res/layouts/pages/main.xml +++ b/res/layouts/pages/main.xml @@ -1,7 +1,7 @@ - + - - + + diff --git a/res/layouts/pages/main.xml.lua b/res/layouts/pages/main.xml.lua index b2ebddcf..5ad200cc 100644 --- a/res/layouts/pages/main.xml.lua +++ b/res/layouts/pages/main.xml.lua @@ -1,21 +1,6 @@ function on_open() local worlds = core.get_worlds_list() for _, name in ipairs(worlds) do - document.worlds:add( - "".. - "".. - "".. - "" - ) + document.worlds:add(gui.template("world", {name=name})) end end diff --git a/res/layouts/pages/new_world.xml b/res/layouts/pages/new_world.xml index 911ddfb6..d017b382 100644 --- a/res/layouts/pages/new_world.xml +++ b/res/layouts/pages/new_world.xml @@ -7,11 +7,11 @@ - - - + diff --git a/res/layouts/pages/pause.xml b/res/layouts/pages/pause.xml index c75429e6..de076c52 100644 --- a/res/layouts/pages/pause.xml +++ b/res/layouts/pages/pause.xml @@ -1,8 +1,8 @@ - - - - + + + diff --git a/res/layouts/pages/settings.xml b/res/layouts/pages/settings.xml new file mode 100644 index 00000000..b5fb3225 --- /dev/null +++ b/res/layouts/pages/settings.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/res/layouts/pages/settings.xml.lua b/res/layouts/pages/settings.xml.lua new file mode 100644 index 00000000..62f35f01 --- /dev/null +++ b/res/layouts/pages/settings.xml.lua @@ -0,0 +1,31 @@ +function create_setting(id, name, step, track_width, postfix) + local info = core.get_setting_info(id) + if postfix == nil then + postfix = "" + end + document.settings_panel:add(gui.template("track_setting", { + id=id, + name=gui.str(name, "settings"), + value=core.get_setting(id), + min=info.min, + max=info.max, + step=step, + track_width=track_width, + postfix=postfix + })) +end + +function update_setting(x, id, name, postfix) + core.set_setting(id, x) + -- updating label + document[id..".L"].text = string.format( + "%s: %s%s", name, core.str_setting(id), postfix + ) +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, "°") +end diff --git a/res/layouts/pages/settings-audio.xml b/res/layouts/pages/settings_audio.xml similarity index 72% rename from res/layouts/pages/settings-audio.xml rename to res/layouts/pages/settings_audio.xml index 61f3ee89..c47856a3 100644 --- a/res/layouts/pages/settings-audio.xml +++ b/res/layouts/pages/settings_audio.xml @@ -2,5 +2,5 @@ - + diff --git a/res/layouts/pages/settings-audio.xml.lua b/res/layouts/pages/settings_audio.xml.lua similarity index 100% rename from res/layouts/pages/settings-audio.xml.lua rename to res/layouts/pages/settings_audio.xml.lua diff --git a/res/layouts/templates/pack.xml b/res/layouts/templates/pack.xml index 71df1bcf..691c4173 100644 --- a/res/layouts/templates/pack.xml +++ b/res/layouts/templates/pack.xml @@ -11,7 +11,7 @@ %{description} diff --git a/res/layouts/templates/track_setting.xml b/res/layouts/templates/track_setting.xml new file mode 100644 index 00000000..52b79f05 --- /dev/null +++ b/res/layouts/templates/track_setting.xml @@ -0,0 +1,7 @@ + + + + diff --git a/res/layouts/templates/world.xml b/res/layouts/templates/world.xml new file mode 100644 index 00000000..b41e1020 --- /dev/null +++ b/res/layouts/templates/world.xml @@ -0,0 +1,15 @@ + + + + diff --git a/src/coders/toml.cpp b/src/coders/toml.cpp index 648ad574..96ce407f 100644 --- a/src/coders/toml.cpp +++ b/src/coders/toml.cpp @@ -33,6 +33,10 @@ void Section::add(std::string name, uint* ptr) { add(name, {fieldtype::ftuint, ptr}); } +void Section::add(std::string name, int64_t* ptr) { + add(name, {fieldtype::ftint64, ptr}); +} + void Section::add(std::string name, float* ptr) { add(name, {fieldtype::ftfloat, ptr}); } @@ -100,6 +104,7 @@ std::string Wrapper::write() const { break; case fieldtype::ftint: ss << *((int*)field->ptr); break; case fieldtype::ftuint: ss << *((uint*)field->ptr); break; + case fieldtype::ftint64: ss << *((int64_t*)field->ptr); break; case fieldtype::ftfloat: ss << *((float*)field->ptr); break; case fieldtype::ftdouble: ss << *((double*)field->ptr); break; case fieldtype::ftstring: @@ -144,6 +149,7 @@ void Section::set(const std::string& name, double value) { case fieldtype::ftbool: *(bool*)(field->ptr) = fabs(value) > 0.0; break; case fieldtype::ftint: *(int*)(field->ptr) = value; break; case fieldtype::ftuint: *(uint*)(field->ptr) = value; break; + case fieldtype::ftint64: *(int64_t*)(field->ptr) = value; break; case fieldtype::ftfloat: *(float*)(field->ptr) = value; break; case fieldtype::ftdouble: *(double*)(field->ptr) = value; break; case fieldtype::ftstring: *(std::string*)(field->ptr) = std::to_string(value); break; @@ -162,6 +168,7 @@ void Section::set(const std::string& name, bool value) { case fieldtype::ftbool: *(bool*)(field->ptr) = value; break; case fieldtype::ftint: *(int*)(field->ptr) = (int)value; break; case fieldtype::ftuint: *(uint*)(field->ptr) = (uint)value; break; + case fieldtype::ftint64: *(int64_t*)(field->ptr) = (int64_t)value; break; case fieldtype::ftfloat: *(float*)(field->ptr) = (float)value; break; case fieldtype::ftdouble: *(double*)(field->ptr) = (double)value; break; case fieldtype::ftstring: *(std::string*)(field->ptr) = value ? "true" : "false"; break; diff --git a/src/coders/toml.h b/src/coders/toml.h index be3efe5a..31f87e46 100644 --- a/src/coders/toml.h +++ b/src/coders/toml.h @@ -12,6 +12,7 @@ namespace toml { ftbool, ftint, ftuint, + ftint64, ftfloat, ftdouble, ftstring, @@ -31,6 +32,7 @@ namespace toml { Section(std::string name); void add(std::string name, bool* ptr); void add(std::string name, int* ptr); + void add(std::string name, int64_t* ptr); void add(std::string name, uint* ptr); void add(std::string name, float* ptr); void add(std::string name, double* ptr); diff --git a/src/data/setting.cpp b/src/data/setting.cpp index ea68d769..33dddae4 100644 --- a/src/data/setting.cpp +++ b/src/data/setting.cpp @@ -12,3 +12,14 @@ std::string NumberSetting::toString() const { return "invalid format"; } } + +std::string IntegerSetting::toString() const { + switch (getFormat()) { + case setting_format::simple: + return util::to_string(value); + case setting_format::percent: + return std::to_string(value) + "%"; + default: + return "invalid format"; + } +} diff --git a/src/data/setting.h b/src/data/setting.h index 625868ce..59cf372c 100644 --- a/src/data/setting.h +++ b/src/data/setting.h @@ -95,4 +95,65 @@ public: } }; +class IntegerSetting : public Setting { +protected: + integer_t initial; + integer_t value; + integer_t min; + integer_t max; + std::vector> consumers; +public: + IntegerSetting( + integer_t value, + integer_t min=std::numeric_limits::min(), + integer_t max=std::numeric_limits::max(), + setting_format format=setting_format::simple + ) : Setting(format), + initial(value), + value(value), + min(min), + max(max) + {} + + integer_t& operator*() { + return value; + } + + integer_t get() const { + return value; + } + + void set(integer_t value) { + if (value == this->value) { + return; + } + this->value = value; + for (auto& callback : consumers) { + callback(value); + } + } + + integer_t getMin() const { + return min; + } + + integer_t getMax() const { + return max; + } + + integer_t getT() const { + return (value - min) / (max - min); + } + + void observe(consumer callback) { + consumers.push_back(callback); + } + + virtual void resetToDefault() override { + value = initial; + } + + virtual std::string toString() const override; +}; + #endif // DATA_SETTING_H_ diff --git a/src/files/settings_io.cpp b/src/files/settings_io.cpp index 82b6a93d..28c69b90 100644 --- a/src/files/settings_io.cpp +++ b/src/files/settings_io.cpp @@ -10,6 +10,7 @@ #include "../coders/json.h" SettingsHandler::SettingsHandler(EngineSettings& settings) { + // public settings map.emplace("audio.volume-master", &settings.audio.volumeMaster); map.emplace("audio.volume-regular", &settings.audio.volumeRegular); map.emplace("audio.volume-ui", &settings.audio.volumeUI); @@ -17,6 +18,12 @@ SettingsHandler::SettingsHandler(EngineSettings& settings) { map.emplace("audio.volume-music", &settings.audio.volumeMusic); map.emplace("camera.sensitivity", &settings.camera.sensitivity); + map.emplace("camera.fov", &settings.camera.fov); + + map.emplace("chunks.load-distance", &settings.chunks.loadDistance); + map.emplace("chunks.load-speed", &settings.chunks.loadSpeed); + + map.emplace("graphics.fog-curve", &settings.graphics.fogCurve); } dynamic::Value SettingsHandler::getValue(const std::string& name) const { @@ -27,6 +34,8 @@ dynamic::Value SettingsHandler::getValue(const std::string& name) const { auto setting = found->second; if (auto number = dynamic_cast(setting)) { return dynamic::Value::of((number_t)number->get()); + } else if (auto integer = dynamic_cast(setting)) { + return dynamic::Value::of((integer_t)integer->get()); } else { throw std::runtime_error("type is not implemented for '"+name+"'"); } @@ -41,6 +50,14 @@ std::string SettingsHandler::toString(const std::string& name) const { return setting->toString(); } +Setting* SettingsHandler::getSetting(const std::string& name) const { + auto found = map.find(name); + if (found == map.end()) { + throw std::runtime_error("setting '"+name+"' does not exist"); + } + return found->second; +} + void SettingsHandler::setValue(const std::string& name, dynamic::Value value) { auto found = map.find(name); if (found == map.end()) { @@ -58,6 +75,17 @@ void SettingsHandler::setValue(const std::string& name, dynamic::Value value) { default: throw std::runtime_error("type error, numeric value expected"); } + } else if (auto integer = dynamic_cast(setting)) { + switch (value.type) { + case dynamic::valtype::integer: + integer->set(std::get(value.value)); + break; + case dynamic::valtype::number: + integer->set(std::get(value.value)); + break; + default: + throw std::runtime_error("type error, numeric value expected"); + } } else { throw std::runtime_error("type is not implement - setting '"+name+"'"); } @@ -82,19 +110,19 @@ toml::Wrapper* create_wrapper(EngineSettings& settings) { display.add("swap-interval", &settings.display.swapInterval); toml::Section& chunks = wrapper->add("chunks"); - chunks.add("load-distance", &settings.chunks.loadDistance); - chunks.add("load-speed", &settings.chunks.loadSpeed); - chunks.add("padding", &settings.chunks.padding); + chunks.add("load-distance", &*settings.chunks.loadDistance); + chunks.add("load-speed", &*settings.chunks.loadSpeed); + chunks.add("padding", &*settings.chunks.padding); toml::Section& camera = wrapper->add("camera"); camera.add("fov-effects", &settings.camera.fovEvents); - camera.add("fov", &settings.camera.fov); + camera.add("fov", &*settings.camera.fov); 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("fog-curve", &*settings.graphics.fogCurve); graphics.add("backlight", &settings.graphics.backlight); graphics.add("frustum-culling", &settings.graphics.frustumCulling); graphics.add("skybox-resolution", &settings.graphics.skyboxResolution); diff --git a/src/files/settings_io.h b/src/files/settings_io.h index ec0230f6..6a59a554 100644 --- a/src/files/settings_io.h +++ b/src/files/settings_io.h @@ -18,6 +18,7 @@ public: dynamic::Value getValue(const std::string& name) const; void setValue(const std::string& name, dynamic::Value value); std::string toString(const std::string& name) const; + Setting* getSetting(const std::string& name) const; }; extern std::string write_controls(); diff --git a/src/frontend/menu/menu.cpp b/src/frontend/menu/menu.cpp index c472744c..de110739 100644 --- a/src/frontend/menu/menu.cpp +++ b/src/frontend/menu/menu.cpp @@ -211,12 +211,11 @@ void menus::delete_world(std::string name, Engine* engine) { L" ("+util::str2wstr_utf8(folder.u8string())+L")", [=]() { std::cout << "deleting " << folder.u8string() << std::endl; fs::remove_all(folder); - menus::refresh_menus(engine); }); } void menus::create_menus(Engine* engine) { - create_settings_panel(engine); + // create_settings_panel(engine); auto menu = engine->getGUI()->getMenu(); menu->setPageLoader([=](auto name) { @@ -229,6 +228,3 @@ void menus::create_menus(Engine* engine) { return document->getRoot(); }); } - -void menus::refresh_menus(Engine* engine) { -} diff --git a/src/frontend/menu/menu.h b/src/frontend/menu/menu.h index 1573fe25..6896401e 100644 --- a/src/frontend/menu/menu.h +++ b/src/frontend/menu/menu.h @@ -61,7 +61,6 @@ namespace menus { /// @brief Create development version label at the top-right screen corner void create_version_label(Engine* engine); void create_menus(Engine* engine); - void refresh_menus(Engine* engine); } #endif // FRONTEND_MENU_MENU_H_ diff --git a/src/frontend/menu/menu_pause.cpp b/src/frontend/menu/menu_pause.cpp index b22262e7..0b51ac0b 100644 --- a/src/frontend/menu/menu_pause.cpp +++ b/src/frontend/menu/menu_pause.cpp @@ -19,15 +19,6 @@ using namespace gui; -inline uint64_t randU64() { - srand(time(NULL)); - return rand() ^ (rand() << 8) ^ - (rand() << 16) ^ (rand() << 24) ^ - ((uint64_t)rand() << 32) ^ - ((uint64_t)rand() << 40) ^ - ((uint64_t)rand() << 56); -} - inline uint64_t str2seed(const std::string& seedstr) { if (util::is_integer(seedstr)) { try { diff --git a/src/frontend/menu/menu_settings.cpp b/src/frontend/menu/menu_settings.cpp index a4af6b9c..7b317de1 100644 --- a/src/frontend/menu/menu_settings.cpp +++ b/src/frontend/menu/menu_settings.cpp @@ -13,76 +13,9 @@ using namespace gui; void menus::create_settings_panel(Engine* engine) { - //create_controls_panel(engine); - auto menu = engine->getGUI()->getMenu(); auto panel = menus::create_page(engine, "settings", 400, 0.0f, 1); - /* Load Distance setting track bar */{ - panel->add(menus::create_label([=]() { - return langs::get(L"Load Distance", L"settings")+L": " + - std::to_wstring(engine->getSettings().chunks.loadDistance); - })); - - auto trackbar = std::make_shared(3, 66, 10, 1, 3); - trackbar->setSupplier([=]() { - return engine->getSettings().chunks.loadDistance; - }); - trackbar->setConsumer([=](double value) { - engine->getSettings().chunks.loadDistance = static_cast(value); - }); - panel->add(trackbar); - } - - /* Load Speed setting track bar */{ - panel->add(menus::create_label([=]() { - return langs::get(L"Load Speed", L"settings")+L": " + - std::to_wstring(engine->getSettings().chunks.loadSpeed); - })); - - auto trackbar = std::make_shared(1, 32, 10, 1, 1); - trackbar->setSupplier([=]() { - return engine->getSettings().chunks.loadSpeed; - }); - trackbar->setConsumer([=](double value) { - engine->getSettings().chunks.loadSpeed = static_cast(value); - }); - panel->add(trackbar); - } - - /* Fog Curve setting track bar */{ - panel->add(menus::create_label([=]() { - float value = engine->getSettings().graphics.fogCurve; - return langs::get(L"Fog Curve", L"settings")+L": " + - util::to_wstring(value, 1); - })); - - auto trackbar = std::make_shared(1.0, 6.0, 1.0, 0.1, 2); - trackbar->setSupplier([=]() { - return engine->getSettings().graphics.fogCurve; - }); - trackbar->setConsumer([=](double value) { - engine->getSettings().graphics.fogCurve = value; - }); - panel->add(trackbar); - } - - /* Fov setting track bar */{ - panel->add(menus::create_label([=]() { - int fov = (int)engine->getSettings().camera.fov; - return langs::get(L"FOV", L"settings")+L": "+std::to_wstring(fov)+L"°"; - })); - - auto trackbar = std::make_shared(30.0, 120.0, 90, 1, 4); - trackbar->setSupplier([=]() { - return engine->getSettings().camera.fov; - }); - trackbar->setConsumer([=](double value) { - engine->getSettings().camera.fov = value; - }); - panel->add(trackbar); - } - /* V-Sync checkbox */{ auto checkbox = std::make_shared( langs::get(L"V-Sync", L"settings"), glm::vec2(400, 32) @@ -128,7 +61,7 @@ void menus::create_settings_panel(Engine* engine) { util::str2wstr_utf8(langName), "languages", menu)); - panel->add(guiutil::gotoButton(L"Audio", "settings-audio", menu)); + panel->add(guiutil::gotoButton(L"Audio", "settings_audio", menu)); panel->add(guiutil::gotoButton(L"Controls", "controls", menu)); panel->add(guiutil::backButton(menu)); } diff --git a/src/frontend/screens.cpp b/src/frontend/screens.cpp index 61f11ef0..e1720114 100644 --- a/src/frontend/screens.cpp +++ b/src/frontend/screens.cpp @@ -51,7 +51,6 @@ Screen::~Screen() { MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) { auto menu = engine->getGUI()->getMenu(); menu->reset(); - menus::refresh_menus(engine); menu->setPage("main"); uicamera.reset(new Camera(glm::vec3(), Window::height)); @@ -167,7 +166,7 @@ void LevelScreen::update(float delta) { // TODO: subscribe for setting change EngineSettings& settings = engine->getSettings(); - controller->getPlayer()->camera->setFov(glm::radians(settings.camera.fov)); + controller->getPlayer()->camera->setFov(glm::radians(settings.camera.fov.get())); if (settings.graphics.backlight != backlight) { controller->getLevel()->chunks->saveAndClear(); backlight = settings.graphics.backlight; diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 8431bb6a..021679d3 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -150,7 +150,7 @@ void WorldRenderer::renderLevel( Shader* shader = assets->getShader("main"); auto indices = level->content->getIndices(); - float fogFactor = 15.0f / ((float)settings.chunks.loadDistance-2); + float fogFactor = 15.0f / ((float)settings.chunks.loadDistance.get()-2); // Setting up main shader shader->use(); @@ -158,7 +158,7 @@ void WorldRenderer::renderLevel( shader->uniformMatrix("u_view", camera->getView()); shader->uniform1f("u_gamma", settings.graphics.gamma); shader->uniform1f("u_fogFactor", fogFactor); - shader->uniform1f("u_fogCurve", settings.graphics.fogCurve); + shader->uniform1f("u_fogCurve", settings.graphics.fogCurve.get()); shader->uniform1f("u_dayTime", level->getWorld()->daytime); shader->uniform3f("u_cameraPos", camera->position); shader->uniform1i("u_cubemap", 1); diff --git a/src/graphics/ui/elements/controls.cpp b/src/graphics/ui/elements/controls.cpp index 8319736d..61c279e6 100644 --- a/src/graphics/ui/elements/controls.cpp +++ b/src/graphics/ui/elements/controls.cpp @@ -912,7 +912,8 @@ void TrackBar::mouseMove(GUI*, int x, int y) { value += min; value = (value > max) ? max : value; value = (value < min) ? min : value; - value = (int)(value / step) * step; + value = (int64_t)round(value / step) * step; + if (consumer) { consumer(value); } diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index 9b65d632..166f2480 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -228,20 +228,21 @@ static std::shared_ptr readPanel(UiXmlReader& reader, xml::xmlelement el } static std::shared_ptr readButton(UiXmlReader& reader, xml::xmlelement element) { + glm::vec4 padding = element->attr("padding", "10").asVec4(); + std::shared_ptr