Merge branch 'MihailRis:main' into main
BIN
res/block.png
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
BIN
res/textures/block.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 257 KiB After Width: | Height: | Size: 257 KiB |
@ -2,9 +2,12 @@
|
||||
#include "Assets.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
#include "../constants.h"
|
||||
|
||||
using std::unique_ptr;
|
||||
|
||||
AssetsLoader::AssetsLoader(Assets* assets) : assets(assets) {
|
||||
}
|
||||
|
||||
@ -62,18 +65,17 @@ bool _load_texture(Assets* assets, const std::string& filename, const std::strin
|
||||
}
|
||||
|
||||
bool _load_atlas(Assets* assets, const std::string& filename, const std::string& name) {
|
||||
ImageData* image = png::load_image(filename);
|
||||
unique_ptr<ImageData> image (png::load_image(filename));
|
||||
if (image == nullptr) {
|
||||
std::cerr << "failed to load image '" << name << "'" << std::endl;
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < ATLAS_MARGIN_SIZE; i++) {
|
||||
ImageData* newimage = add_atlas_margins(image, 16);
|
||||
delete image;
|
||||
image = newimage;
|
||||
ImageData* newimage = add_atlas_margins(image.get(), 16);
|
||||
image.reset(newimage);
|
||||
}
|
||||
|
||||
Texture* texture = Texture::from(image);
|
||||
Texture* texture = Texture::from(image.get());
|
||||
assets->store(texture, name);
|
||||
return true;
|
||||
}
|
||||
@ -101,14 +103,14 @@ void AssetsLoader::createDefaults(AssetsLoader& loader) {
|
||||
}
|
||||
|
||||
void AssetsLoader::addDefaults(AssetsLoader& loader) {
|
||||
loader.add(ASSET_SHADER, "res/main", "main");
|
||||
loader.add(ASSET_SHADER, "res/lines", "lines");
|
||||
loader.add(ASSET_SHADER, "res/ui", "ui");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/main", "main");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/lines", "lines");
|
||||
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui", "ui");
|
||||
|
||||
loader.add(ASSET_ATLAS, "res/block.png", "block");
|
||||
loader.add(ASSET_TEXTURE, "res/block.png", "block_tex");
|
||||
loader.add(ASSET_TEXTURE, "res/slot.png", "slot");
|
||||
loader.add(ASSET_TEXTURE, "res/menubg.png", "menubg");
|
||||
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/block.png", "block");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/block.png", "block_tex");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/slot.png", "slot");
|
||||
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/menubg.png", "menubg");
|
||||
|
||||
loader.add(ASSET_FONT, "res/font", "normal");
|
||||
loader.add(ASSET_FONT, FONTS_FOLDER"/font", "normal");
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -326,12 +326,12 @@ ImageData* png::load_image(std::string filename) {
|
||||
}
|
||||
|
||||
Texture* png::load_texture(std::string filename) {
|
||||
ImageData* image = _png_load(filename.c_str());
|
||||
unique_ptr<ImageData> image (_png_load(filename.c_str()));
|
||||
if (image == nullptr){
|
||||
std::cerr << "Could not load image " << filename << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
return Texture::from(image);
|
||||
return Texture::from(image.get());
|
||||
}
|
||||
|
||||
void png::write_image(std::string filename, const ImageData* image) {
|
||||
|
||||
@ -20,4 +20,10 @@ inline uint vox_index(int x, int y, int z, int w, int d) {
|
||||
|
||||
#define ATLAS_MARGIN_SIZE 2
|
||||
|
||||
#define RES_FLODER "res/"
|
||||
|
||||
#define SHADERS_FOLDER "res/shaders"
|
||||
#define TEXTURES_FOLDER "res/textures"
|
||||
#define FONTS_FOLDER "res/fonts"
|
||||
|
||||
#endif // SRC_CONSTANTS_H_
|
||||
|
||||
21
src/core_defs.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef SRC_CORE_DEFS_H_
|
||||
#define SRC_CORE_DEFS_H_
|
||||
|
||||
/* blocks and bindings used in engine code */
|
||||
|
||||
#define BLOCK_AIR 0
|
||||
|
||||
#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"
|
||||
#define BIND_HUD_INVENTORY "hud.inventory"
|
||||
|
||||
#endif // SRC_CORE_DEFS_H_
|
||||
@ -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,18 @@ 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);
|
||||
Events::bind(BIND_HUD_INVENTORY, inputtype::keyboard, keycode::TAB);
|
||||
}
|
||||
@ -2,8 +2,8 @@
|
||||
#define DECLARATIONS_H
|
||||
|
||||
#include <iostream>
|
||||
#include "core_defs.h"
|
||||
|
||||
#define BLOCK_AIR 0
|
||||
#define BLOCK_DIRT 1
|
||||
#define BLOCK_GRASS_BLOCK 2
|
||||
#define BLOCK_LAMP 3
|
||||
@ -21,7 +21,8 @@
|
||||
#define BLOCK_METAL 15
|
||||
#define BLOCK_RUST 16
|
||||
|
||||
void setup_definitions();
|
||||
extern void setup_bindings();
|
||||
extern void setup_definitions();
|
||||
|
||||
#endif // DECLARATIONS_H
|
||||
|
||||
|
||||
@ -59,8 +59,6 @@ Engine::Engine(EngineSettings& settings) : settings(settings) {
|
||||
Audio::initialize();
|
||||
gui = new GUI();
|
||||
std::cout << "-- initializing finished" << std::endl;
|
||||
|
||||
setScreen(shared_ptr<Screen>(new MenuScreen(this)));
|
||||
}
|
||||
|
||||
void Engine::updateTimers() {
|
||||
@ -81,6 +79,8 @@ void Engine::updateHotkeys() {
|
||||
}
|
||||
|
||||
void Engine::mainloop() {
|
||||
setScreen(shared_ptr<Screen>(new MenuScreen(this)));
|
||||
|
||||
std::cout << "-- preparing systems" << std::endl;
|
||||
|
||||
Batch2D batch(1024);
|
||||
|
||||
@ -45,6 +45,7 @@ void GUI::act(float delta) {
|
||||
}
|
||||
this->hover = hover;
|
||||
|
||||
auto prevfocus = focus;
|
||||
if (Events::jclicked(0)) {
|
||||
if (pressed == nullptr && this->hover) {
|
||||
pressed = hover;
|
||||
@ -52,7 +53,10 @@ void GUI::act(float delta) {
|
||||
if (focus && focus != pressed) {
|
||||
focus->defocus();
|
||||
}
|
||||
focus = pressed;
|
||||
if (focus != pressed) {
|
||||
focus = pressed;
|
||||
focus->focus(this);
|
||||
}
|
||||
}
|
||||
if (this->hover == nullptr && focus) {
|
||||
focus->defocus();
|
||||
@ -63,9 +67,7 @@ void GUI::act(float delta) {
|
||||
pressed = nullptr;
|
||||
}
|
||||
if (focus) {
|
||||
if (!focus->isfocused()){
|
||||
focus = nullptr;
|
||||
} else if (Events::jpressed(keycode::ESCAPE)) {
|
||||
if (Events::jpressed(keycode::ESCAPE)) {
|
||||
focus->defocus();
|
||||
focus = nullptr;
|
||||
} else {
|
||||
@ -78,8 +80,17 @@ void GUI::act(float delta) {
|
||||
if (Events::clicked(mousecode::BUTTON_1)) {
|
||||
focus->mouseMove(this, mx, my);
|
||||
}
|
||||
if (prevfocus == focus)
|
||||
for (int i = mousecode::BUTTON_1; i < mousecode::BUTTON_1+12; i++) {
|
||||
if (Events::jclicked(i)) {
|
||||
focus->clicked(this, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (focus && !focus->isfocused()) {
|
||||
focus = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GUI::draw(Batch2D* batch, Assets* assets) {
|
||||
|
||||
@ -52,7 +52,6 @@ UINode* UINode::getParent() const {
|
||||
|
||||
void UINode::click(GUI*, int x, int y) {
|
||||
pressed_ = true;
|
||||
focused_ = true;
|
||||
}
|
||||
|
||||
void UINode::mouseRelease(GUI*, int x, int y) {
|
||||
@ -103,7 +102,7 @@ void UINode::size(vec2 size) {
|
||||
this->size_ = size;
|
||||
if (parent) {
|
||||
sizelock = true;
|
||||
parent->refresh();
|
||||
//parent->refresh();
|
||||
sizelock = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,9 @@ namespace gui {
|
||||
virtual void margin(glm::vec4 margin);
|
||||
glm::vec4 margin() const;
|
||||
|
||||
virtual void focus(GUI*) {focused_ = true;}
|
||||
virtual void click(GUI*, int x, int y);
|
||||
virtual void clicked(GUI*, int button) {}
|
||||
virtual void mouseMove(GUI*, int x, int y) {};
|
||||
virtual void mouseRelease(GUI*, int x, int y);
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "../../assets/Assets.h"
|
||||
#include "../../graphics/Batch2D.h"
|
||||
#include "../../graphics/Font.h"
|
||||
#include "../../util/stringutil.h"
|
||||
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
@ -36,7 +37,7 @@ void Label::draw(Batch2D* batch, Assets* assets) {
|
||||
}
|
||||
batch->color = color_;
|
||||
Font* font = assets->getFont(fontName_);
|
||||
vec2 size = this->size();
|
||||
vec2 size = UINode::size();
|
||||
vec2 newsize = vec2(font->calcWidth(text_), font->lineHeight());
|
||||
if (newsize.x > size.x) {
|
||||
this->size(newsize);
|
||||
@ -51,6 +52,11 @@ Label* Label::textSupplier(wstringsupplier supplier) {
|
||||
return this;
|
||||
}
|
||||
|
||||
void Label::size(vec2 sizenew) {
|
||||
UINode::size(vec2(UINode::size().x, sizenew.y));
|
||||
}
|
||||
|
||||
// ================================= Button ===================================
|
||||
Button::Button(shared_ptr<UINode> content, glm::vec4 padding) : Panel(vec2(32,32), padding, 0) {
|
||||
add(content);
|
||||
}
|
||||
@ -86,12 +92,12 @@ Button* Button::listenAction(onaction action) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// ================================ TextBox ===================================
|
||||
TextBox::TextBox(wstring placeholder, vec4 padding)
|
||||
: Panel(vec2(200,32), padding, 0, false),
|
||||
input(L""),
|
||||
placeholder(placeholder) {
|
||||
label = new Label(L"");
|
||||
label->align(Align::center);
|
||||
add(shared_ptr<UINode>(label));
|
||||
}
|
||||
|
||||
@ -151,6 +157,42 @@ wstring TextBox::text() const {
|
||||
return input;
|
||||
}
|
||||
|
||||
// ============================== InputBindBox ================================
|
||||
InputBindBox::InputBindBox(Binding& binding, vec4 padding)
|
||||
: Panel(vec2(100,32), padding, 0, false),
|
||||
binding(binding) {
|
||||
label = new Label(L"");
|
||||
//label->align(Align::center);
|
||||
add(shared_ptr<UINode>(label));
|
||||
}
|
||||
|
||||
shared_ptr<UINode> InputBindBox::getAt(vec2 pos, shared_ptr<UINode> self) {
|
||||
return UINode::getAt(pos, self);
|
||||
}
|
||||
|
||||
void InputBindBox::drawBackground(Batch2D* batch, Assets* assets) {
|
||||
vec2 coord = calcCoord();
|
||||
batch->texture(nullptr);
|
||||
batch->color = (isfocused() ? focusedColor : (hover_ ? hoverColor : color_));
|
||||
batch->rect(coord.x, coord.y, size_.x, size_.y);
|
||||
label->text(util::str2wstr_utf8(binding.text()));
|
||||
}
|
||||
|
||||
void InputBindBox::clicked(GUI*, int button) {
|
||||
binding.type = inputtype::mouse;
|
||||
binding.code = button;
|
||||
defocus();
|
||||
}
|
||||
|
||||
void InputBindBox::keyPressed(int key) {
|
||||
if (key != keycode::ESCAPE) {
|
||||
binding.type = inputtype::keyboard;
|
||||
binding.code = key;
|
||||
}
|
||||
defocus();
|
||||
}
|
||||
|
||||
// ================================ TrackBar ==================================
|
||||
TrackBar::TrackBar(double min, double max, double value, double step, int trackWidth)
|
||||
: UINode(vec2(), vec2(32)), min(min), max(max), value(value), step(step), trackWidth(trackWidth) {
|
||||
color(vec4(0.f, 0.f, 0.f, 0.4f));
|
||||
@ -194,6 +236,7 @@ void TrackBar::mouseMove(GUI*, int x, int y) {
|
||||
}
|
||||
}
|
||||
|
||||
// ================================ CheckBox ==================================
|
||||
CheckBox::CheckBox(bool checked) : UINode(vec2(), vec2(32.0f)), checked_(checked) {
|
||||
color(vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <glm/glm.hpp>
|
||||
#include "UINode.h"
|
||||
#include "panels.h"
|
||||
#include "../../window/input.h"
|
||||
|
||||
class Batch2D;
|
||||
class Assets;
|
||||
@ -36,6 +37,7 @@ namespace gui {
|
||||
virtual void draw(Batch2D* batch, Assets* assets) override;
|
||||
|
||||
virtual Label* textSupplier(wstringsupplier supplier);
|
||||
virtual void size(glm::vec2 size) override;
|
||||
};
|
||||
|
||||
class Button : public Panel {
|
||||
@ -79,6 +81,22 @@ namespace gui {
|
||||
virtual std::wstring text() const;
|
||||
};
|
||||
|
||||
class InputBindBox : public Panel {
|
||||
protected:
|
||||
glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f};
|
||||
glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
Label* label;
|
||||
Binding& binding;
|
||||
public:
|
||||
InputBindBox(Binding& binding, glm::vec4 padding=glm::vec4(6.0f));
|
||||
virtual void drawBackground(Batch2D* batch, Assets* assets) override;
|
||||
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
|
||||
|
||||
virtual void clicked(GUI*, int button) override;
|
||||
virtual void keyPressed(int key) override;
|
||||
virtual bool isfocuskeeper() const override {return true;}
|
||||
};
|
||||
|
||||
class TrackBar : public UINode {
|
||||
protected:
|
||||
glm::vec4 hoverColor {0.01f, 0.02f, 0.03f, 0.5f};
|
||||
|
||||
@ -1,15 +1,14 @@
|
||||
#include "panels.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include "../../window/Window.h"
|
||||
#include "../../assets/Assets.h"
|
||||
#include "../../graphics/Batch2D.h"
|
||||
|
||||
using std::shared_ptr;
|
||||
|
||||
using gui::UINode;
|
||||
using gui::Container;
|
||||
using gui::Panel;
|
||||
using gui::Orientation;
|
||||
using namespace gui;
|
||||
|
||||
using glm::vec2;
|
||||
using glm::vec4;
|
||||
@ -138,7 +137,8 @@ void Panel::refresh() {
|
||||
y += nodesize.y + margin.w + interval;
|
||||
|
||||
float width = size.x - padding.x - padding.z - margin.x - margin.z;
|
||||
node->size(vec2(width, nodesize.y));
|
||||
node->size(vec2(width, nodesize.y));;
|
||||
node->refresh();
|
||||
maxw = fmax(maxw, ex+node->size().x+margin.z+padding.z);
|
||||
}
|
||||
if (resizing_)
|
||||
@ -154,6 +154,7 @@ void Panel::refresh() {
|
||||
|
||||
float height = size.y - padding.y - padding.w - margin.y - margin.w;
|
||||
node->size(vec2(nodesize.x, height));
|
||||
node->refresh();
|
||||
maxh = fmax(maxh, y+margin.y+node->size().y+margin.w+padding.w);
|
||||
}
|
||||
bool increased = maxh > size.y;
|
||||
@ -177,4 +178,53 @@ void Panel::lock(){
|
||||
node->lock();
|
||||
}
|
||||
resizing_ = false;
|
||||
}
|
||||
|
||||
PagesControl::PagesControl() : Container(vec2(), vec2(1)){
|
||||
}
|
||||
|
||||
void PagesControl::add(std::string name, std::shared_ptr<UINode> panel) {
|
||||
pages[name] = Page{panel};
|
||||
}
|
||||
|
||||
void PagesControl::set(std::string name, bool history) {
|
||||
auto found = pages.find(name);
|
||||
if (found == pages.end()) {
|
||||
throw std::runtime_error("no page found");
|
||||
}
|
||||
if (current_.panel) {
|
||||
Container::remove(current_.panel);
|
||||
}
|
||||
if (history) {
|
||||
pageStack.push(curname_);
|
||||
}
|
||||
curname_ = name;
|
||||
current_ = found->second;
|
||||
Container::add(current_.panel);
|
||||
size(current_.panel->size());
|
||||
}
|
||||
|
||||
void PagesControl::back() {
|
||||
if (pageStack.empty())
|
||||
return;
|
||||
std::string name = pageStack.top();
|
||||
pageStack.pop();
|
||||
set(name, false);
|
||||
}
|
||||
|
||||
Page PagesControl::current() {
|
||||
return current_;
|
||||
}
|
||||
|
||||
void PagesControl::clearHistory() {
|
||||
pageStack = std::stack<std::string>();
|
||||
}
|
||||
|
||||
void PagesControl::reset() {
|
||||
clearHistory();
|
||||
if (current_.panel) {
|
||||
curname_ = "";
|
||||
Container::remove(current_.panel);
|
||||
current_ = Page{nullptr};
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,8 @@
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "UINode.h"
|
||||
|
||||
@ -56,5 +58,27 @@ namespace gui {
|
||||
virtual void refresh() override;
|
||||
virtual void lock() override;
|
||||
};
|
||||
|
||||
struct Page {
|
||||
std::shared_ptr<UINode> panel = nullptr;
|
||||
};
|
||||
|
||||
class PagesControl : public Container {
|
||||
protected:
|
||||
std::unordered_map<std::string, Page> pages;
|
||||
std::stack<std::string> pageStack;
|
||||
Page current_;
|
||||
std::string curname_ = "";
|
||||
public:
|
||||
PagesControl();
|
||||
|
||||
void set(std::string name, bool history=true);
|
||||
void add(std::string name, std::shared_ptr<UINode> panel);
|
||||
void back();
|
||||
void clearHistory();
|
||||
void reset();
|
||||
|
||||
Page current();
|
||||
};
|
||||
}
|
||||
#endif // FRONTEND_GUI_PANELS_H_
|
||||
@ -30,6 +30,7 @@
|
||||
#include "gui/GUI.h"
|
||||
#include "screens.h"
|
||||
#include "../engine.h"
|
||||
#include "../core_defs.h"
|
||||
|
||||
using std::wstring;
|
||||
using std::shared_ptr;
|
||||
@ -44,12 +45,15 @@ inline Label* create_label(gui::wstringsupplier supplier) {
|
||||
return label;
|
||||
}
|
||||
|
||||
HudRenderer::HudRenderer(Engine* engine, Level* level) : level(level), assets(engine->getAssets()), guiController(engine->getGUI()) {
|
||||
HudRenderer::HudRenderer(Engine* engine, Level* level) : level(level), assets(engine->getAssets()), gui(engine->getGUI()) {
|
||||
batch = new Batch2D(1024);
|
||||
uicamera = new Camera(vec3(), Window::height);
|
||||
uicamera = new Camera(vec3(), 1);
|
||||
uicamera->perspective = false;
|
||||
uicamera->flipped = true;
|
||||
|
||||
auto pagesptr = gui->get("pages");
|
||||
PagesControl* pages = (PagesControl*)(pagesptr.get());
|
||||
|
||||
Panel* panel = new Panel(vec2(250, 200), vec4(5.0f), 1.0f);
|
||||
debugPanel = shared_ptr<UINode>(panel);
|
||||
panel->listenInterval(1.0f, [this]() {
|
||||
@ -115,37 +119,35 @@ HudRenderer::HudRenderer(Engine* engine, Level* level) : level(level), assets(en
|
||||
panel->refresh();
|
||||
|
||||
panel = new Panel(vec2(350, 200));
|
||||
pauseMenu = shared_ptr<UINode>(panel);
|
||||
auto pauseMenu = shared_ptr<UINode>(panel);
|
||||
panel->color(vec4(0.0f));
|
||||
{
|
||||
Button* button = new Button(L"Continue", vec4(10.0f));
|
||||
button->listenAction([this](GUI*){
|
||||
this->pause = false;
|
||||
pauseMenu->visible(false);
|
||||
button->listenAction([=](GUI*){
|
||||
pages->reset();
|
||||
pause = false;
|
||||
});
|
||||
panel->add(shared_ptr<UINode>(button));
|
||||
}
|
||||
panel->add((new Button(L"Settings", vec4(10.f)))->listenAction([=](GUI* gui) {
|
||||
pauseMenu->visible(false);
|
||||
gui->store("back", pauseMenu);
|
||||
gui->get("settings")->visible(true);
|
||||
pages->set("settings");
|
||||
}));
|
||||
{
|
||||
Button* button = new Button(L"Save and Quit to Menu", vec4(10.f));
|
||||
button->listenAction([this, engine](GUI*){
|
||||
this->pauseMenu->visible(false);
|
||||
engine->setScreen(shared_ptr<Screen>(new MenuScreen(engine)));
|
||||
});
|
||||
panel->add(shared_ptr<UINode>(button));
|
||||
}
|
||||
panel->visible(false);
|
||||
guiController->add(this->debugPanel);
|
||||
guiController->add(this->pauseMenu);
|
||||
|
||||
pages->reset();
|
||||
pages->add("pause", pauseMenu);
|
||||
gui->add(this->debugPanel);
|
||||
}
|
||||
|
||||
HudRenderer::~HudRenderer() {
|
||||
guiController->remove(debugPanel);
|
||||
guiController->remove(pauseMenu);
|
||||
gui->remove(debugPanel);
|
||||
//gui->remove(gui->get("pages"));
|
||||
delete batch;
|
||||
delete uicamera;
|
||||
}
|
||||
@ -157,7 +159,11 @@ void HudRenderer::drawDebug(int fps, bool occlusion){
|
||||
fpsMax = max(fps, fpsMax);
|
||||
}
|
||||
|
||||
void HudRenderer::drawInventory(Player* player) {
|
||||
void HudRenderer::drawInventory(const GfxContext& ctx, Player* player) {
|
||||
const Viewport& viewport = ctx.getViewport();
|
||||
const uint width = viewport.getWidth();
|
||||
const uint height = viewport.getHeight();
|
||||
|
||||
Texture* blocks = assets->getTexture("block_tex");
|
||||
uint size = 48;
|
||||
uint step = 64;
|
||||
@ -165,15 +171,15 @@ void HudRenderer::drawInventory(Player* player) {
|
||||
uint inv_rows = 8;
|
||||
uint inv_w = step*inv_cols + size;
|
||||
uint inv_h = step*inv_rows + size;
|
||||
int inv_x = (Window::width - (inv_w)) / 2;
|
||||
int inv_y = (Window::height - (inv_h)) / 2;
|
||||
int xs = (Window::width - inv_w + step)/2;
|
||||
int ys = (Window::height - inv_h + step)/2;
|
||||
if (Window::width > inv_w*3){
|
||||
inv_x = (Window::width + (inv_w)) / 2;
|
||||
inv_y = (Window::height - (inv_h)) / 2;
|
||||
xs = (Window::width + inv_w + step)/2;
|
||||
ys = (Window::height - inv_h + step)/2;
|
||||
int inv_x = (width - (inv_w)) / 2;
|
||||
int inv_y = (height - (inv_h)) / 2;
|
||||
int xs = (width - inv_w + step)/2;
|
||||
int ys = (height - inv_h + step)/2;
|
||||
if (width > inv_w*3){
|
||||
inv_x = (width + (inv_w)) / 2;
|
||||
inv_y = (height - (inv_h)) / 2;
|
||||
xs = (width + inv_w + step)/2;
|
||||
ys = (height - inv_h + step)/2;
|
||||
}
|
||||
vec4 tint = vec4(1.0f);
|
||||
int mx = Events::x;
|
||||
@ -221,8 +227,7 @@ void HudRenderer::drawInventory(Player* player) {
|
||||
if (Events::jclicked(GLFW_MOUSE_BUTTON_LEFT)) {
|
||||
player->choosenBlock = i+1;
|
||||
}
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
tint = vec4(1.0f);
|
||||
}
|
||||
|
||||
@ -234,17 +239,38 @@ void HudRenderer::drawInventory(Player* player) {
|
||||
}
|
||||
}
|
||||
|
||||
void HudRenderer::draw(){
|
||||
void HudRenderer::update() {
|
||||
PagesControl* pages = (PagesControl*)(gui->get("pages").get());
|
||||
if (Events::jpressed(keycode::ESCAPE) && !gui->isFocusCaught()) {
|
||||
if (pause) {
|
||||
pause = false;
|
||||
pages->reset();
|
||||
} else if (inventoryOpen) {
|
||||
inventoryOpen = false;
|
||||
} else {
|
||||
pause = true;
|
||||
pages->set("pause");
|
||||
}
|
||||
}
|
||||
if (Events::jactive(BIND_HUD_INVENTORY)) {
|
||||
if (!pause) {
|
||||
inventoryOpen = !inventoryOpen;
|
||||
}
|
||||
}
|
||||
if ((pause || inventoryOpen) == Events::_cursor_locked)
|
||||
Events::toggleCursor();
|
||||
}
|
||||
|
||||
void HudRenderer::draw(const GfxContext& ctx){
|
||||
const Viewport& viewport = ctx.getViewport();
|
||||
const uint width = viewport.getWidth();
|
||||
const uint height = viewport.getHeight();
|
||||
auto pages = gui->get("pages");
|
||||
|
||||
debugPanel->visible(level->player->debug);
|
||||
pauseMenu->setCoord((Window::size() - pauseMenu->size()) / 2.0f);
|
||||
pages->setCoord((viewport.size() - pages->size()) / 2.0f);
|
||||
|
||||
auto settingsPanel = guiController->get("settings");
|
||||
settingsPanel->setCoord((Window::size() - settingsPanel->size()) / 2.0f);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
uicamera->fov = Window::height;
|
||||
uicamera->fov = height;
|
||||
|
||||
Shader* uishader = assets->getShader("ui");
|
||||
uishader->use();
|
||||
@ -256,9 +282,7 @@ void HudRenderer::draw(){
|
||||
batch->texture(nullptr);
|
||||
batch->color = vec4(1.0f);
|
||||
if (Events::_cursor_locked && !level->player->debug) {
|
||||
glLineWidth(2);
|
||||
const uint width = Window::width;
|
||||
const uint height = Window::height;
|
||||
batch->lineWidth(2);
|
||||
batch->line(width/2, height/2-6, width/2, height/2+6, 0.2f, 0.2f, 0.2f, 1.0f);
|
||||
batch->line(width/2+6, height/2, width/2-6, height/2, 0.2f, 0.2f, 0.2f, 1.0f);
|
||||
batch->line(width/2-5, height/2-5, width/2+5, height/2+5, 0.9f, 0.9f, 0.9f, 1.0f);
|
||||
@ -266,19 +290,19 @@ void HudRenderer::draw(){
|
||||
}
|
||||
Player* player = level->player;
|
||||
|
||||
batch->rect(Window::width/2-128-4, Window::height-80-4, 256+8, 64+8,
|
||||
batch->rect(width/2-128-4, height-80-4, 256+8, 64+8,
|
||||
0.95f, 0.95f, 0.95f, 0.85f, 0.85f, 0.85f,
|
||||
0.7f, 0.7f, 0.7f,
|
||||
0.55f, 0.55f, 0.55f, 0.45f, 0.45f, 0.45f, 4);
|
||||
batch->rect(Window::width/2-128, Window::height - 80, 256, 64,
|
||||
batch->rect(width/2-128, height - 80, 256, 64,
|
||||
0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 0.75f,
|
||||
0.75f, 0.75f, 0.75f,
|
||||
0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 4);
|
||||
batch->rect(Window::width/2-32+2, Window::height - 80+2, 60, 60,
|
||||
batch->rect(width/2-32+2, height - 80+2, 60, 60,
|
||||
0.45f, 0.45f, 0.45f, 0.55f, 0.55f, 0.55f,
|
||||
0.7f, 0.7f, 0.7f,
|
||||
0.85f, 0.85f, 0.85f, 0.95f, 0.95f, 0.95f, 2);
|
||||
batch->rect(Window::width/2-32+4, Window::height - 80+4, 56, 56,
|
||||
batch->rect(width/2-32+4, height - 80+4, 56, 56,
|
||||
0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 0.75f,
|
||||
0.75f, 0.75f, 0.75f,
|
||||
0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 0.75f, 2);
|
||||
@ -288,39 +312,19 @@ void HudRenderer::draw(){
|
||||
{
|
||||
Block* cblock = Block::blocks[player->choosenBlock];
|
||||
if (cblock->model == BlockModel::block){
|
||||
batch->blockSprite(Window::width/2-24, uicamera->fov - 72, 48, 48, 16, cblock->textureFaces, vec4(1.0f));
|
||||
batch->blockSprite(width/2-24, uicamera->fov - 72, 48, 48, 16, cblock->textureFaces, vec4(1.0f));
|
||||
} else if (cblock->model == BlockModel::xsprite){
|
||||
batch->sprite(Window::width/2-24, uicamera->fov - 72, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f));
|
||||
batch->sprite(width/2-24, uicamera->fov - 72, 48, 48, 16, cblock->textureFaces[3], vec4(1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
if (Events::jpressed(keycode::ESCAPE) && !guiController->isFocusCaught()) {
|
||||
if (pause) {
|
||||
pause = false;
|
||||
pauseMenu->visible(false);
|
||||
settingsPanel->visible(false);
|
||||
} else if (inventoryOpen) {
|
||||
inventoryOpen = false;
|
||||
} else {
|
||||
pause = true;
|
||||
pauseMenu->visible(true);
|
||||
}
|
||||
}
|
||||
if (Events::jpressed(keycode::TAB)) {
|
||||
if (!pause) {
|
||||
inventoryOpen = !inventoryOpen;
|
||||
}
|
||||
}
|
||||
if ((pause || inventoryOpen) == Events::_cursor_locked)
|
||||
Events::toggleCursor();
|
||||
|
||||
if (pause || inventoryOpen) {
|
||||
batch->texture(nullptr);
|
||||
batch->color = vec4(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
batch->rect(0, 0, Window::width, Window::height);
|
||||
batch->rect(0, 0, width, height);
|
||||
}
|
||||
if (inventoryOpen) {
|
||||
drawInventory(player);
|
||||
drawInventory(ctx, player);
|
||||
}
|
||||
batch->render();
|
||||
}
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "../graphics/GfxContext.h"
|
||||
|
||||
class Batch2D;
|
||||
class Camera;
|
||||
class Level;
|
||||
@ -32,13 +34,14 @@ class HudRenderer {
|
||||
bool pause = false;
|
||||
|
||||
std::shared_ptr<gui::UINode> debugPanel;
|
||||
std::shared_ptr<gui::UINode> pauseMenu;
|
||||
gui::GUI* guiController;
|
||||
gui::GUI* gui;
|
||||
public:
|
||||
HudRenderer(Engine* engine, Level* level);
|
||||
~HudRenderer();
|
||||
void drawInventory(Player* player);
|
||||
void draw();
|
||||
|
||||
void update();
|
||||
void drawInventory(const GfxContext& ctx, Player* player);
|
||||
void draw(const GfxContext& context);
|
||||
void drawDebug(int fps, bool occlusion);
|
||||
|
||||
bool isInventoryOpen() const;
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
#include "../window/input.h"
|
||||
#include "../graphics/Shader.h"
|
||||
#include "../graphics/Batch2D.h"
|
||||
#include "../graphics/GfxContext.h"
|
||||
#include "../assets/Assets.h"
|
||||
#include "../world/Level.h"
|
||||
#include "../world/World.h"
|
||||
@ -28,6 +29,7 @@
|
||||
#include "../engine.h"
|
||||
#include "../files/engine_files.h"
|
||||
#include "../util/stringutil.h"
|
||||
#include "../core_defs.h"
|
||||
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
@ -39,53 +41,52 @@ using std::filesystem::u8path;
|
||||
using std::filesystem::directory_iterator;
|
||||
using namespace gui;
|
||||
|
||||
shared_ptr<UINode> create_main_menu_panel(Engine* engine) {
|
||||
shared_ptr<UINode> create_main_menu_panel(Engine* engine, PagesControl* pages) {
|
||||
Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f);
|
||||
shared_ptr<UINode> panelptr(panel);
|
||||
panel->color(vec4(0.0f));
|
||||
panel->setCoord(vec2(10, 10));
|
||||
|
||||
panel->add((new Button(L"New World", vec4(10.f)))->listenAction([=](GUI* gui) {
|
||||
panel->visible(false);
|
||||
gui->get("new-world")->visible(true);
|
||||
pages->set("new-world");
|
||||
}));
|
||||
|
||||
Panel* worldsPanel = new Panel(vec2(390, 200), vec4(5.0f));
|
||||
worldsPanel->color(vec4(0.1f));
|
||||
for (auto const& entry : directory_iterator(enginefs::get_worlds_folder())) {
|
||||
string name = entry.path().filename().string();
|
||||
Button* button = new Button(util::str2wstr_utf8(name),
|
||||
vec4(10.0f, 8.0f, 10.0f, 8.0f));
|
||||
button->color(vec4(0.5f));
|
||||
button->listenAction([engine, panel, name](GUI*) {
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
path worldsFolder = enginefs::get_worlds_folder();
|
||||
if (std::filesystem::is_directory(worldsFolder)) {
|
||||
for (auto const& entry : directory_iterator(worldsFolder)) {
|
||||
string name = entry.path().filename().string();
|
||||
Button* button = new Button(util::str2wstr_utf8(name),
|
||||
vec4(10.0f, 8.0f, 10.0f, 8.0f));
|
||||
button->color(vec4(0.5f));
|
||||
button->listenAction([engine, panel, name](GUI*) {
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
|
||||
auto folder = enginefs::get_worlds_folder()/u8path(name);
|
||||
World* world = new World(name, folder, 42, settings);
|
||||
auto screen = new LevelScreen(engine, world->load(settings));
|
||||
engine->setScreen(shared_ptr<Screen>(screen));
|
||||
});
|
||||
worldsPanel->add(button);
|
||||
auto folder = enginefs::get_worlds_folder()/u8path(name);
|
||||
World* world = new World(name, folder, 42, settings);
|
||||
auto screen = new LevelScreen(engine, world->load(settings));
|
||||
engine->setScreen(shared_ptr<Screen>(screen));
|
||||
});
|
||||
worldsPanel->add(button);
|
||||
}
|
||||
}
|
||||
panel->add(worldsPanel);
|
||||
|
||||
panel->add((new Button(L"Settings", vec4(10.f)))->listenAction([=](GUI* gui) {
|
||||
panel->visible(false);
|
||||
gui->store("back", panelptr);
|
||||
gui->get("settings")->visible(true);
|
||||
pages->set("settings");
|
||||
}));
|
||||
|
||||
panel->add((new Button(L"Quit", vec4(10.f)))->listenAction([](GUI*) {
|
||||
Window::setShouldClose(true);
|
||||
}));
|
||||
panel->refresh();
|
||||
return panelptr;
|
||||
}
|
||||
|
||||
shared_ptr<UINode> create_new_world_panel(Engine* engine) {
|
||||
shared_ptr<UINode> create_new_world_panel(Engine* engine, PagesControl* pages) {
|
||||
Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f);
|
||||
shared_ptr<UINode> panelptr(panel);
|
||||
panel->color(vec4(0.0f));
|
||||
panel->setCoord(vec2(10, 10));
|
||||
|
||||
TextBox* worldNameInput;
|
||||
{
|
||||
@ -163,17 +164,43 @@ shared_ptr<UINode> create_new_world_panel(Engine* engine) {
|
||||
}
|
||||
|
||||
panel->add((new Button(L"Back", vec4(10.f)))->listenAction([=](GUI* gui) {
|
||||
panel->visible(false);
|
||||
gui->get("main-menu")->visible(true);
|
||||
pages->back();
|
||||
}));
|
||||
|
||||
panel->refresh();
|
||||
return panelptr;
|
||||
}
|
||||
|
||||
Panel* create_settings_panel(Engine* engine) {
|
||||
Panel* create_controls_panel(Engine* engine, PagesControl* pages) {
|
||||
Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f);
|
||||
panel->color(vec4(0.0f));
|
||||
panel->setCoord(vec2(10, 10));
|
||||
|
||||
for (auto& entry : Events::bindings){
|
||||
string bindname = entry.first;
|
||||
|
||||
Panel* subpanel = new Panel(vec2(400, 45), vec4(5.0f), 1.0f);
|
||||
subpanel->color(vec4(0.0f));
|
||||
subpanel->orientation(Orientation::horizontal);
|
||||
|
||||
InputBindBox* bindbox = new InputBindBox(entry.second);
|
||||
subpanel->add(bindbox);
|
||||
Label* label = new Label(util::str2wstr_utf8(bindname));
|
||||
label->margin(vec4(6.0f));
|
||||
subpanel->add(label);
|
||||
panel->add(subpanel);
|
||||
}
|
||||
|
||||
panel->add((new Button(L"Back", vec4(10.f)))->listenAction([=](GUI* gui) {
|
||||
pages->back();
|
||||
}));
|
||||
panel->refresh();
|
||||
return panel;
|
||||
}
|
||||
|
||||
shared_ptr<UINode> create_settings_panel(Engine* engine, PagesControl* pages) {
|
||||
Panel* panel = new Panel(vec2(400, 200), vec4(5.0f), 1.0f);
|
||||
panel->color(vec4(0.0f));
|
||||
|
||||
shared_ptr<UINode> panelptr(panel);
|
||||
|
||||
/* Load Distance setting track bar */{
|
||||
panel->add((new Label(L""))->textSupplier([=]() {
|
||||
@ -228,30 +255,44 @@ Panel* create_settings_panel(Engine* engine) {
|
||||
panel->add(checkpanel);
|
||||
}
|
||||
|
||||
panel->add((new Button(L"Back", vec4(10.f)))->listenAction([=](GUI* gui) {
|
||||
panel->visible(false);
|
||||
gui->get("back")->visible(true);
|
||||
panel->add((new Button(L"Controls", vec4(10.f)))->listenAction([=](GUI* gui) {
|
||||
pages->set("controls");
|
||||
}));
|
||||
return panel;
|
||||
|
||||
panel->add((new Button(L"Back", vec4(10.f)))->listenAction([=](GUI* gui) {
|
||||
pages->back();
|
||||
}));
|
||||
panel->refresh();
|
||||
return panelptr;
|
||||
}
|
||||
|
||||
MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) {
|
||||
GUI* gui = engine->getGUI();
|
||||
panel = create_main_menu_panel(engine);
|
||||
newWorldPanel = create_new_world_panel(engine);
|
||||
newWorldPanel->visible(false);
|
||||
|
||||
auto settingsPanel = shared_ptr<UINode>(create_settings_panel(engine));
|
||||
settingsPanel->visible(false);
|
||||
auto pagesptr = gui->get("pages");
|
||||
PagesControl* pages;
|
||||
if (pagesptr == nullptr) {
|
||||
pages = new PagesControl();
|
||||
auto newWorldPanel = create_new_world_panel(engine, pages);
|
||||
|
||||
gui->store("main-menu", panel);
|
||||
gui->store("new-world", newWorldPanel);
|
||||
if (gui->get("settings") == nullptr) {
|
||||
gui->store("settings", settingsPanel);
|
||||
auto settingsPanel = shared_ptr<UINode>(create_settings_panel(engine, pages));
|
||||
auto controlsPanel = shared_ptr<UINode>(create_controls_panel(engine, pages));
|
||||
|
||||
pages->add("new-world", newWorldPanel);
|
||||
pages->add("settings", settingsPanel);
|
||||
pages->add("controls", controlsPanel);
|
||||
|
||||
this->pages = shared_ptr<UINode>(pages);
|
||||
gui->add(this->pages);
|
||||
gui->store("pages", this->pages);
|
||||
} else {
|
||||
this->pages = pagesptr;
|
||||
pages = (PagesControl*)(pagesptr.get());
|
||||
pages->reset();
|
||||
}
|
||||
gui->add(panel);
|
||||
gui->add(newWorldPanel);
|
||||
gui->add(settingsPanel);
|
||||
auto mainMenuPanel = create_main_menu_panel(engine, pages);
|
||||
pages->add("main", mainMenuPanel);
|
||||
pages->set("main");
|
||||
|
||||
batch = new Batch2D(1024);
|
||||
uicamera = new Camera(vec3(), Window::height);
|
||||
@ -260,13 +301,6 @@ MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) {
|
||||
}
|
||||
|
||||
MenuScreen::~MenuScreen() {
|
||||
GUI* gui = engine->getGUI();
|
||||
|
||||
gui->remove("main-menu");
|
||||
gui->remove("new-world");
|
||||
|
||||
gui->remove(newWorldPanel);
|
||||
gui->remove(panel);
|
||||
delete batch;
|
||||
delete uicamera;
|
||||
}
|
||||
@ -275,11 +309,7 @@ void MenuScreen::update(float delta) {
|
||||
}
|
||||
|
||||
void MenuScreen::draw(float delta) {
|
||||
panel->setCoord((Window::size() - panel->size()) / 2.0f);
|
||||
newWorldPanel->setCoord((Window::size() - newWorldPanel->size()) / 2.0f);
|
||||
|
||||
auto settingsPanel = engine->getGUI()->get("settings");
|
||||
settingsPanel->setCoord((Window::size() - settingsPanel->size()) / 2.0f);
|
||||
pages->setCoord((Window::size() - pages->size()) / 2.0f);
|
||||
|
||||
Window::clear();
|
||||
Window::setBgColor(vec3(0.2f, 0.2f, 0.2f));
|
||||
@ -348,13 +378,18 @@ void LevelScreen::update(float delta) {
|
||||
level->update();
|
||||
|
||||
level->chunksController->update(settings.chunks.loadSpeed);
|
||||
|
||||
hud->update();
|
||||
}
|
||||
|
||||
void LevelScreen::draw(float delta) {
|
||||
Camera* camera = level->player->camera;
|
||||
|
||||
worldRenderer->draw(camera, occlusion);
|
||||
hud->draw();
|
||||
Viewport viewport(Window::width, Window::height);
|
||||
GfxContext ctx(nullptr, viewport, nullptr);
|
||||
|
||||
worldRenderer->draw(ctx, camera, occlusion);
|
||||
hud->draw(ctx);
|
||||
if (level->player->debug) {
|
||||
hud->drawDebug( 1 / delta, occlusion);
|
||||
}
|
||||
|
||||
@ -28,8 +28,7 @@ public:
|
||||
};
|
||||
|
||||
class MenuScreen : public Screen {
|
||||
std::shared_ptr<gui::UINode> panel;
|
||||
std::shared_ptr<gui::UINode> newWorldPanel;
|
||||
std::shared_ptr<gui::UINode> pages;
|
||||
Batch2D* batch;
|
||||
Camera* uicamera;
|
||||
public:
|
||||
|
||||
@ -60,51 +60,15 @@ bool WorldRenderer::drawChunk(size_t index, Camera* camera, Shader* shader, bool
|
||||
}
|
||||
mat4 model = glm::translate(mat4(1.0f), vec3(chunk->x*CHUNK_W, 0.0f, chunk->z*CHUNK_D+1));
|
||||
shader->uniformMatrix("u_model", model);
|
||||
mesh->draw(GL_TRIANGLES);
|
||||
mesh->draw();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void WorldRenderer::draw(Camera* camera, bool occlusion){
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
Assets* assets = engine->getAssets();
|
||||
Chunks* chunks = level->chunks;
|
||||
|
||||
vec3 skyColor(0.7f, 0.81f, 1.0f);
|
||||
|
||||
Window::setBgColor(skyColor);
|
||||
Window::clear();
|
||||
Window::viewport(0, 0, Window::width, Window::height);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
float fogFactor = 18.0f / (float)settings.chunks.loadDistance;
|
||||
|
||||
Texture* texture = assets->getTexture("block");
|
||||
Shader* shader = assets->getShader("main");
|
||||
Shader* linesShader = assets->getShader("lines");
|
||||
shader->use();
|
||||
shader->uniformMatrix("u_proj", camera->getProjection());
|
||||
shader->uniformMatrix("u_view", camera->getView());
|
||||
shader->uniform1f("u_gamma", 1.6f);
|
||||
shader->uniform3f("u_skyLightColor", 1.1f,1.1f,1.1f);
|
||||
shader->uniform3f("u_fogColor", skyColor);
|
||||
shader->uniform1f("u_fogFactor", fogFactor);
|
||||
shader->uniform1f("u_fogCurve", settings.graphics.fogCurve);
|
||||
shader->uniform3f("u_cameraPos", camera->position);
|
||||
|
||||
Block* cblock = Block::blocks[level->player->choosenBlock];
|
||||
float multiplier = 0.5f;
|
||||
shader->uniform3f("u_torchlightColor",
|
||||
cblock->emission[0] / 15.0f * multiplier,
|
||||
cblock->emission[1] / 15.0f * multiplier,
|
||||
cblock->emission[2] / 15.0f * multiplier);
|
||||
shader->uniform1f("u_torchlightDistance", 6.0f);
|
||||
texture->bind();
|
||||
|
||||
void WorldRenderer::drawChunks(Chunks* chunks,
|
||||
Camera* camera,
|
||||
Shader* shader,
|
||||
bool occlusion) {
|
||||
std::vector<size_t> indices;
|
||||
|
||||
for (size_t i = 0; i < chunks->volume; i++){
|
||||
shared_ptr<Chunk> chunk = chunks->chunks[i];
|
||||
if (chunk == nullptr)
|
||||
@ -126,34 +90,84 @@ void WorldRenderer::draw(Camera* camera, bool occlusion){
|
||||
for (size_t i = 0; i < indices.size(); i++){
|
||||
chunks->visible += drawChunk(indices[i], camera, shader, occlusion);
|
||||
}
|
||||
}
|
||||
|
||||
shader->uniformMatrix("u_model", mat4(1.0f));
|
||||
|
||||
if (level->playerController->selectedBlockId != -1){
|
||||
Block* selectedBlock = Block::blocks[level->playerController->selectedBlockId];
|
||||
vec3 pos = level->playerController->selectedBlockPosition;
|
||||
linesShader->use();
|
||||
linesShader->uniformMatrix("u_projview", camera->getProjection()*camera->getView());
|
||||
glLineWidth(2.0f);
|
||||
if (selectedBlock->model == BlockModel::block){
|
||||
lineBatch->box(pos.x+0.5f, pos.y+0.5f, pos.z+0.5f, 1.005f,1.005f,1.005f, 0,0,0,0.5f);
|
||||
} else if (selectedBlock->model == BlockModel::xsprite){
|
||||
lineBatch->box(pos.x+0.5f, pos.y+0.35f, pos.z+0.5f, 0.805f,0.705f,0.805f, 0,0,0,0.5f);
|
||||
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool occlusion){
|
||||
Assets* assets = engine->getAssets();
|
||||
Texture* texture = assets->getTexture("block");
|
||||
Shader* shader = assets->getShader("main");
|
||||
Shader* linesShader = assets->getShader("lines");
|
||||
|
||||
const Viewport& viewport = pctx.getViewport();
|
||||
int displayWidth = viewport.getWidth();
|
||||
int displayHeight = viewport.getHeight();
|
||||
{
|
||||
GfxContext ctx = pctx.sub();
|
||||
ctx.depthTest(true);
|
||||
ctx.cullFace(true);
|
||||
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
|
||||
vec3 skyColor(0.7f, 0.81f, 1.0f);
|
||||
|
||||
Window::setBgColor(skyColor);
|
||||
Window::clear();
|
||||
Window::viewport(0, 0, displayWidth, displayHeight);
|
||||
|
||||
float fogFactor = 18.0f / (float)settings.chunks.loadDistance;
|
||||
|
||||
shader->use();
|
||||
shader->uniformMatrix("u_proj", camera->getProjection());
|
||||
shader->uniformMatrix("u_view", camera->getView());
|
||||
shader->uniform1f("u_gamma", 1.6f);
|
||||
shader->uniform3f("u_skyLightColor", 1.1f,1.1f,1.1f);
|
||||
shader->uniform3f("u_fogColor", skyColor);
|
||||
shader->uniform1f("u_fogFactor", fogFactor);
|
||||
shader->uniform1f("u_fogCurve", settings.graphics.fogCurve);
|
||||
shader->uniform3f("u_cameraPos", camera->position);
|
||||
|
||||
Block* cblock = Block::blocks[level->player->choosenBlock];
|
||||
float multiplier = 0.5f;
|
||||
shader->uniform3f("u_torchlightColor",
|
||||
cblock->emission[0] / 15.0f * multiplier,
|
||||
cblock->emission[1] / 15.0f * multiplier,
|
||||
cblock->emission[2] / 15.0f * multiplier);
|
||||
shader->uniform1f("u_torchlightDistance", 6.0f);
|
||||
texture->bind();
|
||||
|
||||
Chunks* chunks = level->chunks;
|
||||
drawChunks(chunks, camera, shader, occlusion);
|
||||
|
||||
shader->uniformMatrix("u_model", mat4(1.0f));
|
||||
|
||||
if (level->playerController->selectedBlockId != -1){
|
||||
Block* block = Block::blocks[level->playerController->selectedBlockId];
|
||||
vec3 pos = level->playerController->selectedBlockPosition;
|
||||
linesShader->use();
|
||||
linesShader->uniformMatrix("u_projview", camera->getProjView());
|
||||
lineBatch->lineWidth(2.0f);
|
||||
if (block->model == BlockModel::block){
|
||||
lineBatch->box(pos.x+0.5f, pos.y+0.5f, pos.z+0.5f,
|
||||
1.008f,1.008f,1.008f, 0,0,0,0.5f);
|
||||
} else if (block->model == BlockModel::xsprite){
|
||||
lineBatch->box(pos.x+0.5f, pos.y+0.35f, pos.z+0.5f,
|
||||
0.805f,0.705f,0.805f, 0,0,0,0.5f);
|
||||
}
|
||||
lineBatch->render();
|
||||
}
|
||||
lineBatch->render();
|
||||
}
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
if (level->player->debug) {
|
||||
float length = 40.f;
|
||||
|
||||
linesShader->use();
|
||||
vec3 tsl = vec3(Window::width/2, -((int)Window::height)/2, 0.f);
|
||||
// top-right: vec3 tsl = vec3(displayWidth - length - 4, -length - 4, 0.f);
|
||||
vec3 tsl = vec3(displayWidth/2, -((int)displayHeight)/2, 0.f);
|
||||
glm::mat4 model(glm::translate(glm::mat4(1.f), tsl));
|
||||
linesShader->uniformMatrix("u_projview", glm::ortho(
|
||||
0.f, (float)Window::width,
|
||||
-(float)Window::height, 0.f,
|
||||
0.f, (float)displayWidth,
|
||||
-(float)displayHeight, 0.f,
|
||||
-length, length) * model * glm::inverse(camera->rotation));
|
||||
|
||||
lineBatch->lineWidth(4.0f);
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
#include <glm/ext.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include "../graphics/GfxContext.h"
|
||||
|
||||
class Level;
|
||||
class Camera;
|
||||
class LineBatch;
|
||||
@ -18,6 +20,7 @@ class Shader;
|
||||
class Texture;
|
||||
class Frustum;
|
||||
class Engine;
|
||||
class Chunks;
|
||||
|
||||
class WorldRenderer {
|
||||
Engine* engine;
|
||||
@ -26,12 +29,13 @@ class WorldRenderer {
|
||||
LineBatch* lineBatch;
|
||||
ChunksRenderer* renderer;
|
||||
bool drawChunk(size_t index, Camera* camera, Shader* shader, bool occlusion);
|
||||
void drawChunks(Chunks* chunks, Camera* camera, Shader* shader, bool occlusion);
|
||||
public:
|
||||
|
||||
WorldRenderer(Engine* engine, Level* level);
|
||||
~WorldRenderer();
|
||||
|
||||
void draw(Camera* camera, bool occlusion);
|
||||
void draw(const GfxContext& context, Camera* camera, bool occlusion);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -361,3 +361,7 @@ void Batch2D::render(unsigned int gl_primitive) {
|
||||
void Batch2D::render() {
|
||||
render(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
void Batch2D::lineWidth(float width) {
|
||||
glLineWidth(width);
|
||||
}
|
||||
|
||||
@ -62,6 +62,8 @@ public:
|
||||
float r4, float g4, float b4, int sh);
|
||||
void render(unsigned int gl_primitive);
|
||||
void render();
|
||||
|
||||
void lineWidth(float width);
|
||||
};
|
||||
|
||||
#endif /* SRC_GRAPHICS_BATCH2D_H_ */
|
||||
|
||||
59
src/graphics/GfxContext.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "GfxContext.h"
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "Batch2D.h"
|
||||
|
||||
GfxContext::GfxContext(const GfxContext* parent, Viewport& viewport, Batch2D* g2d)
|
||||
: parent(parent), viewport(viewport), g2d(g2d) {
|
||||
}
|
||||
|
||||
GfxContext::~GfxContext() {
|
||||
if (parent == nullptr)
|
||||
return;
|
||||
if (depthTest_ != parent->depthTest_) {
|
||||
if (depthTest_) glDisable(GL_DEPTH_TEST);
|
||||
else glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
if (cullFace_ != parent->cullFace_) {
|
||||
if (cullFace_) glDisable(GL_CULL_FACE);
|
||||
else glEnable(GL_CULL_FACE);
|
||||
}
|
||||
}
|
||||
|
||||
const Viewport& GfxContext::getViewport() const {
|
||||
return viewport;
|
||||
}
|
||||
|
||||
Batch2D* GfxContext::getBatch2D() const {
|
||||
return g2d;
|
||||
}
|
||||
|
||||
GfxContext GfxContext::sub() const {
|
||||
auto ctx = GfxContext(this, viewport, g2d);
|
||||
ctx.depthTest_ = depthTest_;
|
||||
ctx.cullFace_ = cullFace_;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void GfxContext::depthTest(bool flag) {
|
||||
if (depthTest_ == flag)
|
||||
return;
|
||||
depthTest_ = flag;
|
||||
if (depthTest_) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
} else {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
void GfxContext::cullFace(bool flag) {
|
||||
if (cullFace_ == flag)
|
||||
return;
|
||||
cullFace_ = flag;
|
||||
if (cullFace_) {
|
||||
glEnable(GL_CULL_FACE);
|
||||
} else {
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
}
|
||||
27
src/graphics/GfxContext.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef GRAPHICS_GFX_CONTEXT_H_
|
||||
#define GRAPHICS_GFX_CONTEXT_H_
|
||||
|
||||
#include "../typedefs.h"
|
||||
#include "Viewport.h"
|
||||
|
||||
class Batch2D;
|
||||
|
||||
class GfxContext {
|
||||
const GfxContext* parent;
|
||||
Viewport& viewport;
|
||||
Batch2D* const g2d;
|
||||
bool depthTest_ = false;
|
||||
bool cullFace_ = false;
|
||||
public:
|
||||
GfxContext(const GfxContext* parent, Viewport& viewport, Batch2D* g2d);
|
||||
~GfxContext();
|
||||
|
||||
Batch2D* getBatch2D() const;
|
||||
const Viewport& getViewport() const;
|
||||
GfxContext sub() const;
|
||||
|
||||
void depthTest(bool flag);
|
||||
void cullFace(bool flag);
|
||||
};
|
||||
|
||||
#endif // GRAPHICS_GFX_CONTEXT_H_
|
||||
13
src/graphics/Viewport.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include "Viewport.h"
|
||||
|
||||
Viewport::Viewport(uint width, uint height)
|
||||
: width(width), height(height) {
|
||||
}
|
||||
|
||||
uint Viewport::getWidth() const {
|
||||
return width;
|
||||
}
|
||||
|
||||
uint Viewport::getHeight() const {
|
||||
return height;
|
||||
}
|
||||
22
src/graphics/Viewport.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef GRAPHICS_VIEWPORT_H_
|
||||
#define GRAPHICS_VIEWPORT_H_
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "../typedefs.h"
|
||||
|
||||
class Viewport {
|
||||
uint width;
|
||||
uint height;
|
||||
public:
|
||||
Viewport(uint width, uint height);
|
||||
|
||||
virtual uint getWidth() const;
|
||||
virtual uint getHeight() const;
|
||||
|
||||
glm::vec2 size() const {
|
||||
return glm::vec2(width, height);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // GRAPHICS_VIEWPORT_H_
|
||||
@ -12,6 +12,8 @@
|
||||
#include "../window/Events.h"
|
||||
#include "../window/input.h"
|
||||
|
||||
#include "../core_defs.h"
|
||||
|
||||
#define CROUCH_SPEED_MUL 0.25f
|
||||
#define CROUCH_SHIFT_Y -0.2f
|
||||
#define RUN_SPEED_MUL 1.5f
|
||||
@ -38,18 +40,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(BIND_MOVE_FORWARD);
|
||||
input.moveBack = Events::active(BIND_MOVE_BACK);
|
||||
input.moveLeft = Events::active(BIND_MOVE_LEFT);
|
||||
input.moveRight = Events::active(BIND_MOVE_RIGHT);
|
||||
input.sprint = Events::active(BIND_MOVE_SPRINT);
|
||||
input.shift = Events::active(BIND_MOVE_CROUCH);
|
||||
input.cheat = Events::active(BIND_MOVE_CHEAT);
|
||||
input.jump = Events::active(BIND_MOVE_JUMP);
|
||||
input.zoom = Events::active(BIND_CAM_ZOOM);
|
||||
|
||||
input.noclip = Events::jpressed(keycode::N);
|
||||
input.flight = Events::jpressed(keycode::F);
|
||||
input.noclip = Events::jactive(BIND_PLAYER_NOCLIP);
|
||||
input.flight = Events::jactive(BIND_PLAYER_FLIGHT);
|
||||
|
||||
// block choice
|
||||
for (int i = 1; i < 10; i++){
|
||||
@ -215,8 +217,21 @@ void PlayerController::updateInteraction(){
|
||||
Camera* camera = player->camera;
|
||||
vec3 end;
|
||||
vec3 norm;
|
||||
|
||||
bool xkey = Events::pressed(keycode::X);
|
||||
bool lclick = Events::jclicked(mousecode::BUTTON_1) ||
|
||||
(xkey && Events::clicked(mousecode::BUTTON_1));
|
||||
bool rclick = Events::jclicked(mousecode::BUTTON_2) ||
|
||||
(xkey && Events::clicked(mousecode::BUTTON_2));
|
||||
float maxDistance = 10.0f;
|
||||
if (xkey) {
|
||||
maxDistance *= 20.0f;
|
||||
}
|
||||
vec3 iend;
|
||||
voxel* vox = chunks->rayCast(camera->position, camera->front, 10.0f, end, norm, iend);
|
||||
voxel* vox = chunks->rayCast(camera->position,
|
||||
camera->front,
|
||||
maxDistance,
|
||||
end, norm, iend);
|
||||
if (vox != nullptr){
|
||||
player->selectedVoxel = *vox;
|
||||
selectedBlockId = vox->id;
|
||||
@ -238,11 +253,11 @@ void PlayerController::updateInteraction(){
|
||||
}
|
||||
|
||||
Block* block = Block::blocks[vox->id];
|
||||
if (Events::jclicked(mousecode::BUTTON_1) && block->breakable){
|
||||
if (lclick && block->breakable){
|
||||
chunks->set(x,y,z, 0, 0);
|
||||
lighting->onBlockSet(x,y,z, 0);
|
||||
}
|
||||
if (Events::jclicked(mousecode::BUTTON_2)){
|
||||
if (rclick){
|
||||
if (block->model != BlockModel::xsprite){
|
||||
x = (int)(iend.x)+(int)(norm.x);
|
||||
y = (int)(iend.y)+(int)(norm.y);
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
#ifndef VOX_TYPEDEFS_H
|
||||
#define VOX_TYPEDEFS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@ -6,3 +9,5 @@ typedef unsigned char ubyte;
|
||||
|
||||
typedef uint8_t blockid_t;
|
||||
typedef uint16_t light_t;
|
||||
|
||||
#endif
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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_
|
||||
@ -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::mouse: jentry->put("type", "mouse"); 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 == "mouse") {
|
||||
type = inputtype::mouse;
|
||||
} 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;
|
||||
|
||||
@ -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::mouse: 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();
|
||||
}
|
||||
|
||||
@ -2,6 +2,11 @@
|
||||
#define WINDOW_EVENTS_H_
|
||||
|
||||
#include "Window.h"
|
||||
#include "input.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
@ -18,6 +23,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 +36,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
|
||||
|
||||
@ -65,7 +65,81 @@ int keycode::NUM_6 = GLFW_KEY_6;
|
||||
int keycode::NUM_7 = GLFW_KEY_7;
|
||||
int keycode::NUM_8 = GLFW_KEY_8;
|
||||
int keycode::NUM_9 = GLFW_KEY_9;
|
||||
int keycode::MENU = GLFW_KEY_MENU;
|
||||
int keycode::PAUSE = GLFW_KEY_PAUSE;
|
||||
int keycode::INSERT = GLFW_KEY_INSERT;
|
||||
int keycode::LEFT_SUPER = GLFW_KEY_LEFT_SUPER;
|
||||
int keycode::RIGHT_SUPER = GLFW_KEY_RIGHT_SUPER;
|
||||
int keycode::DELETE = GLFW_KEY_DELETE;
|
||||
int keycode::PAGE_UP = GLFW_KEY_PAGE_UP;
|
||||
int keycode::PAGE_DOWN = GLFW_KEY_PAGE_DOWN;
|
||||
int keycode::HOME = GLFW_KEY_HOME;
|
||||
int keycode::END = GLFW_KEY_END;
|
||||
int keycode::PRINT_SCREEN = GLFW_KEY_PRINT_SCREEN;
|
||||
int keycode::NUM_LOCK = GLFW_KEY_NUM_LOCK;
|
||||
int keycode::LEFT_BRACKET = GLFW_KEY_LEFT_BRACKET;
|
||||
int keycode::RIGHT_BRACKET = GLFW_KEY_RIGHT_BRACKET;
|
||||
|
||||
const char* keycode::name(int code) {
|
||||
const char* name = glfwGetKeyName(code, glfwGetKeyScancode(code));
|
||||
if (name == nullptr) {
|
||||
switch (code) {
|
||||
case GLFW_KEY_TAB: return "Tab";
|
||||
case GLFW_KEY_LEFT_CONTROL: return "Left Ctrl";
|
||||
case GLFW_KEY_RIGHT_CONTROL: return "Right Ctrl";
|
||||
case GLFW_KEY_LEFT_ALT: return "Left Alt";
|
||||
case GLFW_KEY_RIGHT_ALT: return "Right Alt";
|
||||
case GLFW_KEY_LEFT_SHIFT: return "Left Shift";
|
||||
case GLFW_KEY_RIGHT_SHIFT: return "Right Shift";
|
||||
case GLFW_KEY_CAPS_LOCK: return "Caps-Lock";
|
||||
case GLFW_KEY_SPACE: return "Space";
|
||||
case GLFW_KEY_ESCAPE: return "Esc";
|
||||
case GLFW_KEY_ENTER: return "Enter";
|
||||
case GLFW_KEY_UP: return "Up";
|
||||
case GLFW_KEY_DOWN: return "Down";
|
||||
case GLFW_KEY_LEFT: return "Left";
|
||||
case GLFW_KEY_RIGHT: return "Right";
|
||||
case GLFW_KEY_BACKSPACE: return "Backspace";
|
||||
case GLFW_KEY_F1: return "F1";
|
||||
case GLFW_KEY_F2: return "F2";
|
||||
case GLFW_KEY_F3: return "F3";
|
||||
case GLFW_KEY_F4: return "F4";
|
||||
case GLFW_KEY_F5: return "F5";
|
||||
case GLFW_KEY_F6: return "F6";
|
||||
case GLFW_KEY_F7: return "F7";
|
||||
case GLFW_KEY_F8: return "F8";
|
||||
case GLFW_KEY_F9: return "F9";
|
||||
case GLFW_KEY_F10: return "F10";
|
||||
case GLFW_KEY_F11: return "F11";
|
||||
case GLFW_KEY_F12: return "F12";
|
||||
case GLFW_KEY_DELETE: return "Delete";
|
||||
case GLFW_KEY_HOME: return "Home";
|
||||
case GLFW_KEY_END: return "End";
|
||||
case GLFW_KEY_LEFT_SUPER: return "Left Super";
|
||||
case GLFW_KEY_RIGHT_SUPER: return "Right Super";
|
||||
case GLFW_KEY_PAGE_UP: return "Page Up";
|
||||
case GLFW_KEY_PAGE_DOWN: return "Page Down";
|
||||
case GLFW_KEY_INSERT: return "Insert";
|
||||
case GLFW_KEY_PRINT_SCREEN: return "Print Screen";
|
||||
case GLFW_KEY_NUM_LOCK: return "Num Lock";
|
||||
case GLFW_KEY_MENU: return "Menu";
|
||||
case GLFW_KEY_PAUSE: return "Pause";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
int mousecode::BUTTON_1 = GLFW_MOUSE_BUTTON_1;
|
||||
int mousecode::BUTTON_2 = GLFW_MOUSE_BUTTON_2;
|
||||
int mousecode::BUTTON_3 = GLFW_MOUSE_BUTTON_3;
|
||||
|
||||
const char* mousecode::name(int code) {
|
||||
switch (code) {
|
||||
case GLFW_MOUSE_BUTTON_1: return "LMB";
|
||||
case GLFW_MOUSE_BUTTON_2: return "RMB";
|
||||
case GLFW_MOUSE_BUTTON_3: return "MMB";
|
||||
}
|
||||
return "unknown button";
|
||||
}
|
||||
|
||||
@ -66,12 +66,59 @@ namespace keycode {
|
||||
extern int NUM_7;
|
||||
extern int NUM_8;
|
||||
extern int NUM_9;
|
||||
extern int MENU;
|
||||
extern int PAUSE;
|
||||
extern int INSERT;
|
||||
extern int LEFT_SUPER;
|
||||
extern int RIGHT_SUPER;
|
||||
extern int DELETE;
|
||||
extern int PAGE_UP;
|
||||
extern int PAGE_DOWN;
|
||||
extern int HOME;
|
||||
extern int END;
|
||||
extern int PRINT_SCREEN;
|
||||
extern int NUM_LOCK;
|
||||
extern int LEFT_BRACKET;
|
||||
extern int RIGHT_BRACKET;
|
||||
|
||||
extern const char* name(int code);
|
||||
}
|
||||
|
||||
namespace mousecode {
|
||||
extern int BUTTON_1;
|
||||
extern int BUTTON_2;
|
||||
extern int BUTTON_3;
|
||||
|
||||
extern const char* name(int code);
|
||||
}
|
||||
|
||||
enum class inputtype {
|
||||
keyboard,
|
||||
mouse,
|
||||
};
|
||||
|
||||
struct Binding {
|
||||
inputtype type;
|
||||
int code;
|
||||
bool state = false;
|
||||
bool justChange = false;
|
||||
|
||||
bool active() const {
|
||||
return state;
|
||||
}
|
||||
|
||||
bool jactive() const {
|
||||
return state && justChange;
|
||||
}
|
||||
|
||||
const char* text() const {
|
||||
switch (type) {
|
||||
case inputtype::keyboard: return keycode::name(code);
|
||||
case inputtype::mouse: return mousecode::name(code);
|
||||
}
|
||||
return "<unknown input type>";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // WINDOW_INPUT_H_
|
||||