bindings, controls.json file

This commit is contained in:
MihailRis 2023-11-19 22:37:15 +03:00
parent e3743b8463
commit 9051db3526
11 changed files with 186 additions and 22 deletions

View File

@ -15,6 +15,7 @@ else()
# additional warnings
-Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wundef
-Wswitch-enum
-Wwrite-strings -Wno-unused-parameter)
endif()

View File

@ -258,6 +258,10 @@ JObject& JObject::put(string key, string value){
return *this;
}
JObject& JObject::put(std::string key, const char* value) {
return put(key, string(value));
}
JObject& JObject::put(string key, JObject* value){
auto found = map.find(key);
if (found != map.end()) delete found->second;

View File

@ -81,6 +81,7 @@ namespace json {
JObject& put(std::string key, int value);
JObject& put(std::string key, float value);
JObject& put(std::string key, double value);
JObject& put(std::string key, const char* value);
JObject& put(std::string key, std::string value);
JObject& put(std::string key, JObject* value);
JObject& put(std::string key, JArray* value);

View File

@ -1,6 +1,8 @@
#include "definitions.h"
#include "window/Window.h"
#include "window/Events.h"
#include "window/input.h"
#include "voxels/Block.h"
// All in-game definitions (blocks, items, etc..)
@ -91,3 +93,17 @@ void setup_definitions() {
block = new Block(BLOCK_RUST, 19);
Block::blocks[block->id] = block;
}
void setup_bindings() {
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_PLAYER_NOCLIP, inputtype::keyboard, keycode::N);
Events::bind(BIND_PLAYER_FLIGHT, inputtype::keyboard, keycode::F);
}

View File

@ -21,7 +21,20 @@
#define BLOCK_METAL 15
#define BLOCK_RUST 16
void setup_definitions();
#define BIND_MOVE_FORWARD "movement.forward"
#define BIND_MOVE_BACK "movement.back"
#define BIND_MOVE_LEFT "movement.left"
#define BIND_MOVE_RIGHT "movement.right"
#define BIND_MOVE_JUMP "movement.jump"
#define BIND_MOVE_SPRINT "movement.sprint"
#define BIND_MOVE_CROUCH "movement.crouch"
#define BIND_MOVE_CHEAT "movement.cheat"
#define BIND_CAM_ZOOM "camera.zoom"
#define BIND_PLAYER_NOCLIP "player.noclip"
#define BIND_PLAYER_FLIGHT "player.flight"
extern void setup_bindings();
extern void setup_definitions();
#endif // DECLARATIONS_H

View File

@ -38,18 +38,18 @@ void PlayerController::refreshCamera() {
}
void PlayerController::updateKeyboard() {
input.zoom = Events::pressed(keycode::C);
input.moveForward = Events::pressed(keycode::W);
input.moveBack = Events::pressed(keycode::S);
input.moveLeft = Events::pressed(keycode::A);
input.moveRight = Events::pressed(keycode::D);
input.sprint = Events::pressed(keycode::LEFT_CONTROL);
input.shift = Events::pressed(keycode::LEFT_SHIFT);
input.cheat = Events::pressed(keycode::R);
input.jump = Events::pressed(keycode::SPACE);
input.moveForward = Events::active("movement.forward");
input.moveBack = Events::active("movement.back");
input.moveLeft = Events::active("movement.left");
input.moveRight = Events::active("movement.right");
input.sprint = Events::active("movement.sprint");
input.shift = Events::active("movement.crouch");
input.cheat = Events::active("movement.cheat");
input.jump = Events::active("movement.jump");
input.zoom = Events::active("camera.zoom");
input.noclip = Events::jpressed(keycode::N);
input.flight = Events::jpressed(keycode::F);
input.noclip = Events::jactive("player.noclip");
input.flight = Events::jactive("player.flight");
// block choice
for (int i = 1; i < 10; i++){

View File

@ -1,19 +1,23 @@
#include "platform.h"
#include <sstream>
#include <filesystem>
#include <iomanip>
#include <time.h>
#include "../typedefs.h"
#define SETTINGS_FILE "settings.toml"
#define CONTROLS_FILE "controls.json"
using std::string;
using std::filesystem::path;
string platform::get_settings_file() {
return SETTINGS_FILE;
path platform::get_settings_file() {
return path(SETTINGS_FILE);
}
path platform::get_controls_file() {
return path(CONTROLS_FILE);
}
#ifdef WIN32

View File

@ -2,10 +2,12 @@
#define UTIL_PLATFORM_H_
#include <string>
#include <filesystem>
namespace platform {
extern void configure_encoding();
extern std::string get_settings_file();
extern std::filesystem::path get_settings_file();
extern std::filesystem::path get_controls_file();
}
#endif // UTIL_PLATFORM_H_

View File

@ -1,9 +1,9 @@
#include <iostream>
#include <cmath>
#include <stdint.h>
#include <memory>
#include <filesystem>
#include <stdexcept>
#include "definitions.h"
@ -11,8 +11,11 @@
#include "engine.h"
#include "coders/toml.h"
#include "coders/json.h"
#include "files/files.h"
#include "window/Events.h"
toml::Wrapper create_wrapper(EngineSettings& settings) {
toml::Wrapper wrapper;
toml::Section& display = wrapper.add("display");
@ -38,6 +41,48 @@ toml::Wrapper create_wrapper(EngineSettings& settings) {
return wrapper;
}
std::string write_controls() {
json::JObject* obj = new json::JObject();
for (auto& entry : Events::bindings) {
const auto& binding = entry.second;
json::JObject* jentry = new json::JObject();
switch (binding.type) {
case inputtype::keyboard: jentry->put("type", "keyboard"); break;
case inputtype::button: jentry->put("type", "button"); break;
default: throw std::runtime_error("unsupported control type");
}
jentry->put("code", binding.code);
obj->put(entry.first, jentry);
}
return json::stringify(obj, true, " ");
}
void load_controls(std::string filename, std::string source) {
json::JObject* obj = json::parse(filename, source);
for (auto& entry : Events::bindings) {
auto& binding = entry.second;
json::JObject* jentry = obj->obj(entry.first);
if (jentry == nullptr)
continue;
inputtype type;
std::string typestr;
jentry->str("type", typestr);
if (typestr == "keyboard") {
type = inputtype::keyboard;
} else if (typestr == "button") {
type = inputtype::button;
} else {
std::cerr << "unknown input type '" << typestr << "'" << std::endl;
continue;
}
binding.type = type;
jentry->num("code", binding.code);
}
}
int main() {
platform::configure_encoding();
setup_definitions();
@ -45,21 +90,26 @@ int main() {
EngineSettings settings;
toml::Wrapper wrapper = create_wrapper(settings);
std::string settings_file = platform::get_settings_file();
std::filesystem::path settings_file = platform::get_settings_file();
std::filesystem::path controls_file = platform::get_controls_file();
if (std::filesystem::is_regular_file(settings_file)) {
std::cout << "-- loading settings" << std::endl;
std::string content = files::read_string(settings_file);
toml::Reader reader(&wrapper, settings_file, content);
reader.read();
} else {
std::cout << "-- creating settings file " << settings_file << std::endl;
files::write_string(settings_file, wrapper.write());
}
Engine engine(settings);
setup_bindings();
if (std::filesystem::is_regular_file(controls_file)) {
std::cout << "-- loading controls" << std::endl;
std::string content = files::read_string(controls_file);
load_controls(controls_file.string(), content);
}
engine.mainloop();
std::cout << "-- saving settings" << std::endl;
files::write_string(settings_file, wrapper.write());
files::write_string(controls_file, write_controls());
}
catch (const initialize_error& err) {
std::cerr << "could not to initialize engine" << std::endl;

View File

@ -14,6 +14,7 @@ bool Events::_cursor_locked = false;
bool Events::_cursor_started = false;
std::vector<uint> Events::codepoints;
std::vector<int> Events::pressedKeys;
std::unordered_map<std::string, Binding> Events::bindings;
int Events::initialize(){
_keys = new bool[1032];
@ -64,4 +65,47 @@ void Events::pullEvents(){
codepoints.clear();
pressedKeys.clear();
glfwPollEvents();
for (auto& entry : bindings) {
auto& binding = entry.second;
binding.justChange = false;
bool newstate = false;
switch (binding.type) {
case inputtype::keyboard: newstate = pressed(binding.code); break;
case inputtype::button: newstate = clicked(binding.code); break;
}
if (newstate) {
if (!binding.state) {
binding.state = true;
binding.justChange = true;
}
} else {
if (binding.state) {
binding.state = false;
binding.justChange = true;
}
}
}
}
void Events::bind(std::string name, inputtype type, int code) {
bindings[name] = {type, code, false, false};
}
bool Events::active(std::string name) {
const auto& found = bindings.find(name);
if (found == bindings.end()) {
return false;
}
return found->second.active();
}
bool Events::jactive(std::string name) {
const auto& found = bindings.find(name);
if (found == bindings.end()) {
return false;
}
return found->second.jactive();
}

View File

@ -3,8 +3,32 @@
#include "Window.h"
#include <string>
#include <vector>
#include <unordered_map>
typedef unsigned int uint;
enum class inputtype {
keyboard,
button,
};
struct Binding {
inputtype type;
int code;
bool state = false;
bool justChange = false;
bool active() const {
return state;
}
bool jactive() const {
return state && justChange;
}
};
class Events {
public:
static bool* _keys;
@ -18,6 +42,7 @@ public:
static bool _cursor_started;
static std::vector<uint> codepoints;
static std::vector<int> pressedKeys;
static std::unordered_map<std::string, Binding> bindings;
static int initialize();
static void finalize();
@ -30,6 +55,10 @@ public:
static bool jclicked(int button);
static void toggleCursor();
static void bind(std::string name, inputtype type, int code);
static bool active(std::string name);
static bool jactive(std::string name);
};
#define _MOUSE_BUTTONS 1024