From 66476ee64281cfaf22f18587db2067d762beed17 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 20 May 2024 04:06:49 +0300 Subject: [PATCH] bindings.toml, config/bindings.toml file --- res/bindings.toml | 17 ++++++++++++ res/layouts/pages/settings_controls.xml.lua | 1 + src/core_defs.cpp | 29 +++++++-------------- src/core_defs.hpp | 4 +-- src/engine.cpp | 11 ++++++-- src/files/files.cpp | 5 ++++ src/files/files.hpp | 6 ++--- src/frontend/screens/LevelScreen.cpp | 3 ++- src/window/Events.cpp | 27 +++++++++++++++++++ src/window/Events.hpp | 3 ++- src/window/input.cpp | 4 ++- 11 files changed, 79 insertions(+), 31 deletions(-) create mode 100644 res/bindings.toml diff --git a/res/bindings.toml b/res/bindings.toml new file mode 100644 index 00000000..d0a7e1e9 --- /dev/null +++ b/res/bindings.toml @@ -0,0 +1,17 @@ +devtools.console="key:grave-accent" +movement.forward="key:w" +movement.back="key:s" +movement.left="key:a" +movement.right="key:d" +movement.jump="key:space" +movement.sprint="key:left-ctrl" +movement.crouch="key:left-shift" +movement.cheat="key:r" +camera.zoom="key:c" +camera.mode="key:f4" +player.noclip="key:n" +player.flight="key:f" +player.attack="mouse:left" +player.build="mouse:right" +player.pick="mouse:middle" +hud.inventory="key:tab" diff --git a/res/layouts/pages/settings_controls.xml.lua b/res/layouts/pages/settings_controls.xml.lua index a66e17e3..879f21e5 100644 --- a/res/layouts/pages/settings_controls.xml.lua +++ b/res/layouts/pages/settings_controls.xml.lua @@ -17,6 +17,7 @@ function on_open() local panel = document.bindings_panel local bindings = core.get_bindings() + table.sort(bindings, function(a, b) return a > b end) for i,name in ipairs(bindings) do panel:add(gui.template("binding", { id=name, name=gui.str(name) diff --git a/src/core_defs.cpp b/src/core_defs.cpp index e0a4e6b0..39c70991 100644 --- a/src/core_defs.cpp +++ b/src/core_defs.cpp @@ -3,13 +3,15 @@ #include "items/ItemDef.hpp" #include "content/Content.hpp" #include "content/ContentBuilder.hpp" +#include "files/files.hpp" +#include "files/engine_paths.hpp" #include "window/Window.hpp" #include "window/Events.hpp" #include "window/input.hpp" #include "voxels/Block.hpp" // All in-game definitions (blocks, items, etc..) -void corecontent::setup(ContentBuilder* builder) { +void corecontent::setup(EnginePaths* paths, ContentBuilder* builder) { Block& block = builder->createBlock("core:air"); block.replaceable = true; block.drawGroup = 1; @@ -22,24 +24,11 @@ void corecontent::setup(ContentBuilder* builder) { ItemDef& item = builder->createItem("core:empty"); item.iconType = item_icon_type::none; -} -void corecontent::setup_bindings() { - Events::bind(BIND_DEVTOOLS_CONSOLE, inputtype::keyboard, keycode::GRAVE_ACCENT); - Events::bind(BIND_MOVE_FORWARD, inputtype::keyboard, keycode::W); - Events::bind(BIND_MOVE_BACK, inputtype::keyboard, keycode::S); - Events::bind(BIND_MOVE_RIGHT, inputtype::keyboard, keycode::D); - Events::bind(BIND_MOVE_LEFT, inputtype::keyboard, keycode::A); - Events::bind(BIND_MOVE_JUMP, inputtype::keyboard, keycode::SPACE); - Events::bind(BIND_MOVE_SPRINT, inputtype::keyboard, keycode::LEFT_CONTROL); - Events::bind(BIND_MOVE_CROUCH, inputtype::keyboard, keycode::LEFT_SHIFT); - Events::bind(BIND_MOVE_CHEAT, inputtype::keyboard, keycode::R); - Events::bind(BIND_CAM_ZOOM, inputtype::keyboard, keycode::C); - Events::bind(BIND_CAM_MODE, inputtype::keyboard, keycode::F4); - Events::bind(BIND_PLAYER_NOCLIP, inputtype::keyboard, keycode::N); - Events::bind(BIND_PLAYER_FLIGHT, inputtype::keyboard, keycode::F); - Events::bind(BIND_PLAYER_ATTACK, inputtype::mouse, mousecode::BUTTON_1); - Events::bind(BIND_PLAYER_BUILD, inputtype::mouse, mousecode::BUTTON_2); - Events::bind(BIND_PLAYER_PICK, inputtype::mouse, mousecode::BUTTON_3); - Events::bind(BIND_HUD_INVENTORY, inputtype::keyboard, keycode::TAB); + auto bindsFile = paths->getResources()/fs::path("bindings.toml"); + if (fs::is_regular_file(bindsFile)) { + Events::loadBindingsToml( + bindsFile.u8string(), files::read_string(bindsFile) + ); + } } diff --git a/src/core_defs.hpp b/src/core_defs.hpp index 1a2b0a9f..884cda26 100644 --- a/src/core_defs.hpp +++ b/src/core_defs.hpp @@ -27,11 +27,11 @@ inline const std::string BIND_PLAYER_BUILD = "player.build"; inline const std::string BIND_PLAYER_PICK = "player.pick"; inline const std::string BIND_HUD_INVENTORY = "hud.inventory"; +class EnginePaths; class ContentBuilder; namespace corecontent { - void setup_bindings(); - void setup(ContentBuilder* builder); + void setup(EnginePaths* paths, ContentBuilder* builder); } #endif // CORE_DEFS_HPP_ diff --git a/src/engine.cpp b/src/engine.cpp index a4b9f5bf..0810d004 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -64,7 +64,6 @@ Engine::Engine(EngineSettings& settings, SettingsHandler& settingsHandler, Engin : settings(settings), settingsHandler(settingsHandler), paths(paths), interpreter(std::make_unique()) { - corecontent::setup_bindings(); loadSettings(); controller = std::make_unique(this); @@ -255,7 +254,7 @@ void Engine::loadAssets() { void Engine::loadContent() { auto resdir = paths->getResources(); ContentBuilder contentBuilder; - corecontent::setup(&contentBuilder); + corecontent::setup(paths, &contentBuilder); paths->setContentPacks(&contentPacks); std::vector names; @@ -273,6 +272,14 @@ void Engine::loadContent() { ContentLoader loader(&pack); loader.load(contentBuilder); + + auto configFolder = pack.folder/fs::path("config"); + auto bindsFile = configFolder/fs::path("bindings.toml"); + if (fs::is_regular_file(bindsFile)) { + Events::loadBindingsToml( + bindsFile.u8string(), files::read_string(bindsFile) + ); + } } content = contentBuilder.build(); resPaths = std::make_unique(resdir, resRoots); diff --git a/src/files/files.cpp b/src/files/files.cpp index 104f21b5..bd9e1716 100644 --- a/src/files/files.cpp +++ b/src/files/files.cpp @@ -2,6 +2,7 @@ #include "../coders/commons.hpp" #include "../coders/json.hpp" +#include "../coders/toml.hpp" #include "../coders/gzip.hpp" #include "../util/stringutil.hpp" #include "../data/dynamic.hpp" @@ -121,6 +122,10 @@ std::shared_ptr files::read_binary_json(fs::path file) { return json::from_binary(bytes.get(), size); } +std::shared_ptr files::read_toml(fs::path file) { + return toml::parse(file.u8string(), files::read_string(file)); +} + std::vector files::read_list(fs::path filename) { std::ifstream file(filename); if (!file) { diff --git a/src/files/files.hpp b/src/files/files.hpp index 1270d6eb..560d5e1f 100644 --- a/src/files/files.hpp +++ b/src/files/files.hpp @@ -44,10 +44,7 @@ namespace files { /// @brief Write dynamic data to the JSON file /// @param nice if true, human readable format will be used, otherwise minimal - bool write_json( - fs::path filename, - const dynamic::Map* obj, - bool nice=true); + bool write_json(fs::path filename, const dynamic::Map* obj, bool nice=true); /// @brief Write dynamic data to the binary JSON file /// (see src/coders/binary_json_spec.md) @@ -66,6 +63,7 @@ namespace files { /// @param file *.json or *.bjson file std::shared_ptr read_json(fs::path file); std::shared_ptr read_binary_json(fs::path file); + std::shared_ptr read_toml(fs::path file); std::vector read_list(fs::path file); } diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index fea96193..93c60169 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -6,6 +6,7 @@ #include "../../coders/imageio.hpp" #include "../../debug/Logger.hpp" #include "../../engine.hpp" +#include "../../files/files.hpp" #include "../../graphics/core/DrawContext.hpp" #include "../../graphics/core/ImageData.hpp" #include "../../graphics/core/PostProcessing.hpp" @@ -15,6 +16,7 @@ #include "../../graphics/ui/GUI.hpp" #include "../../logic/LevelController.hpp" #include "../../logic/scripting/scripting_hud.hpp" +#include "../../util/stringutil.hpp" #include "../../physics/Hitbox.hpp" #include "../../voxels/Chunks.hpp" #include "../../window/Camera.hpp" @@ -66,7 +68,6 @@ void LevelScreen::initializePack(ContentPackRuntime* pack) { if (fs::is_regular_file(scriptFile)) { scripting::load_hud_script(pack->getEnvironment(), info.id, scriptFile); } - auto configFolder = info.folder/fs::path("config"); } LevelScreen::~LevelScreen() { diff --git a/src/window/Events.cpp b/src/window/Events.cpp index 8ac783fd..76158230 100644 --- a/src/window/Events.cpp +++ b/src/window/Events.cpp @@ -1,6 +1,7 @@ #include "Events.hpp" #include "Window.hpp" #include "../debug/Logger.hpp" +#include "../util/stringutil.hpp" #include #include @@ -148,6 +149,7 @@ void Events::setPosition(float xpos, float ypos) { #include "../data/dynamic.hpp" #include "../coders/json.hpp" +#include "../coders/toml.hpp" std::string Events::writeBindings() { dynamic::Map obj; @@ -189,3 +191,28 @@ void Events::loadBindings(const std::string& filename, const std::string& source jentry->num("code", binding.code); } } + +void Events::loadBindingsToml(const std::string& filename, const std::string& source) { + auto map = toml::parse(filename, source); + for (auto& entry : map->values) { + if (auto value = std::get_if(&entry.second)) { + auto [prefix, codename] = util::split_at(*value, ':'); + inputtype type; + int code; + if (prefix == "key") { + type = inputtype::keyboard; + code = static_cast(input_util::keycode_from(codename)); + } else if (prefix == "mouse") { + type = inputtype::mouse; + code = static_cast(input_util::mousecode_from(codename)); + } else { + logger.error() << "unknown input type: " << prefix + << " (binding " << util::quote(entry.first) << ")"; + continue; + } + Events::bind(entry.first, type, code); + } else { + logger.error() << "invalid binding entry: " << entry.first; + } + } +} diff --git a/src/window/Events.hpp b/src/window/Events.hpp index 36544c2a..c8d354d3 100644 --- a/src/window/Events.hpp +++ b/src/window/Events.hpp @@ -2,11 +2,11 @@ #define WINDOW_EVENTS_HPP_ #include "input.hpp" +#include "../typedefs.hpp" #include #include #include -#include "../typedefs.hpp" inline constexpr short KEYS_BUFFER_SIZE = 1036; @@ -51,6 +51,7 @@ public: static std::string writeBindings(); static void loadBindings(const std::string& filename, const std::string& source); + static void loadBindingsToml(const std::string& filename, const std::string& source); }; #endif // WINDOW_EVENTS_HPP_ diff --git a/src/window/input.cpp b/src/window/input.cpp index 50825047..33621f70 100644 --- a/src/window/input.cpp +++ b/src/window/input.cpp @@ -15,6 +15,7 @@ static std::unordered_map keycodes { {"delete", GLFW_KEY_DELETE}, {"home", GLFW_KEY_HOME}, {"end", GLFW_KEY_END}, + {"tab", GLFW_KEY_TAB}, {"insert", GLFW_KEY_INSERT}, {"page-down", GLFW_KEY_PAGE_DOWN}, {"page-up", GLFW_KEY_PAGE_UP}, @@ -26,6 +27,7 @@ static std::unordered_map keycodes { {"right-alt", GLFW_KEY_RIGHT_ALT}, {"left-super", GLFW_KEY_LEFT_SUPER}, {"right-super", GLFW_KEY_RIGHT_SUPER}, + {"grave-accent", GLFW_KEY_GRAVE_ACCENT}, {"left", GLFW_KEY_LEFT}, {"right", GLFW_KEY_RIGHT}, {"down", GLFW_KEY_DOWN}, @@ -59,7 +61,7 @@ void input_util::initialize() { keycodes["f"+std::to_string(i)] = GLFW_KEY_F1+i; } for (char i = 'a'; i <= 'z'; i++) { - keycodes[std::to_string(i)] = GLFW_KEY_A-'a'+i; + keycodes[std::string({i})] = GLFW_KEY_A-'a'+i; } }