This commit is contained in:
A-lex-Ra
2024-02-03 09:16:10 +06:00
58 changed files with 1217 additions and 492 deletions
+6 -1
View File
@@ -9,7 +9,12 @@ on:
jobs: jobs:
build-appimage: build-appimage:
runs-on: ubuntu-20.04 strategy:
matrix:
include:
- os: ubuntu-latest
runs-on: ${{ matrix.os }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
+2 -2
View File
@@ -45,7 +45,7 @@ if(MSVC)
endif() endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /source-charset:UTF-8") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /source-charset:UTF-8")
else() else()
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -lstdc++fs target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra
# additional warnings # additional warnings
-Wformat-nonliteral -Wcast-align -Wformat-nonliteral -Wcast-align
-Wpointer-arith -Wundef -Wpointer-arith -Wundef
@@ -114,7 +114,7 @@ if(UNIX)
endif() endif()
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie -lstdc++fs")
endif() endif()
include_directories(${LUA_INCLUDE_DIR}) include_directories(${LUA_INCLUDE_DIR})
+9 -9
View File
@@ -50,20 +50,20 @@ void AssetsLoader::createDefaults(AssetsLoader& loader) {
loader.addLoader(ASSET_ATLAS, assetload::atlas); loader.addLoader(ASSET_ATLAS, assetload::atlas);
} }
void AssetsLoader::addDefaults(AssetsLoader& loader, bool allAssets) { void AssetsLoader::addDefaults(AssetsLoader& loader, bool world) {
if (allAssets) { loader.add(ASSET_FONT, FONTS_FOLDER"/font", "normal");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/main", "main"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui", "ui");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/lines", "lines"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/main", "main");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui", "ui"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/lines", "lines");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/menubg.png", "gui/menubg");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/delete_icon.png", "gui/delete_icon");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/no_icon.png", "gui/no_icon");
if (world) {
loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui3d", "ui3d"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/ui3d", "ui3d");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/background", "background"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/background", "background");
loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen"); loader.add(ASSET_SHADER, SHADERS_FOLDER"/skybox_gen", "skybox_gen");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/menubg.png", "gui/menubg");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/delete_icon.png", "gui/delete_icon");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/gui/no_icon.png", "gui/no_icon");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon"); loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/moon.png", "misc/moon");
loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/sun.png", "misc/sun"); loader.add(ASSET_TEXTURE, TEXTURES_FOLDER"/misc/sun.png", "misc/sun");
loader.add(ASSET_FONT, FONTS_FOLDER"/font", "normal");
} }
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/blocks", "blocks"); loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/blocks", "blocks");
loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/items", "items"); loader.add(ASSET_ATLAS, TEXTURES_FOLDER"/items", "items");
+1 -1
View File
@@ -36,7 +36,7 @@ public:
bool loadNext(); bool loadNext();
static void createDefaults(AssetsLoader& loader); static void createDefaults(AssetsLoader& loader);
static void addDefaults(AssetsLoader& loader, bool allAssets); static void addDefaults(AssetsLoader& loader, bool world);
const ResPaths* getPaths() const; const ResPaths* getPaths() const;
}; };
+11 -10
View File
@@ -20,12 +20,14 @@ bool assetload::texture(Assets* assets,
const ResPaths* paths, const ResPaths* paths,
const std::string filename, const std::string filename,
const std::string name) { const std::string name) {
Texture* texture = png::load_texture(paths->find(filename).string()); std::unique_ptr<Texture> texture(
png::load_texture(paths->find(filename).string())
);
if (texture == nullptr) { if (texture == nullptr) {
std::cerr << "failed to load texture '" << name << "'" << std::endl; std::cerr << "failed to load texture '" << name << "'" << std::endl;
return false; return false;
} }
assets->store(texture, name); assets->store(texture.release(), name);
return true; return true;
} }
@@ -92,21 +94,21 @@ bool assetload::font(Assets* assets,
const ResPaths* paths, const ResPaths* paths,
const std::string filename, const std::string filename,
const std::string name) { const std::string name) {
std::vector<Texture*> pages; std::vector<std::unique_ptr<Texture>> pages;
for (size_t i = 0; i <= 4; i++) { for (size_t i = 0; i <= 4; i++) {
std::string name = filename + "_" + std::to_string(i) + ".png"; std::string name = filename + "_" + std::to_string(i) + ".png";
name = paths->find(name).string(); name = paths->find(name).string();
Texture* texture = png::load_texture(name); std::unique_ptr<Texture> texture (png::load_texture(name));
if (texture == nullptr) { if (texture == nullptr) {
std::cerr << "failed to load bitmap font '" << name; std::cerr << "failed to load bitmap font '" << name;
std::cerr << "' (missing page " << std::to_string(i) << ")"; std::cerr << "' (missing page " << std::to_string(i) << ")";
std::cerr << std::endl; std::cerr << std::endl;
return false; return false;
} }
pages.push_back(texture); pages.push_back(std::move(texture));
} }
Font* font = new Font(pages, pages[0]->height / 16); int res = pages[0]->height / 16;
assets->store(font, name); assets->store(new Font(std::move(pages), res, 4), name);
return true; return true;
} }
@@ -135,7 +137,6 @@ bool assetload::animation(Assets* assets,
auto frameArr = root->list("frames"); auto frameArr = root->list("frames");
Frame temp;
float frameDuration = DEFAULT_FRAME_DURATION; float frameDuration = DEFAULT_FRAME_DURATION;
std::string frameName; std::string frameName;
@@ -164,7 +165,7 @@ bool assetload::animation(Assets* assets,
if (!appendAtlas(builder, file)) continue; if (!appendAtlas(builder, file)) continue;
} }
Atlas* srcAtlas = builder.build(2); std::unique_ptr<Atlas> srcAtlas (builder.build(2));
Texture* srcTex = srcAtlas->getTexture(); Texture* srcTex = srcAtlas->getTexture();
Texture* dstTex = dstAtlas->getTexture(); Texture* dstTex = dstAtlas->getTexture();
@@ -196,7 +197,7 @@ bool assetload::animation(Assets* assets,
} }
} }
assets->store(srcAtlas, name + "_animation"); assets->store(srcAtlas.release(), name + "_animation");
assets->store(animation); assets->store(animation);
return true; return true;
+47 -15
View File
@@ -4,19 +4,6 @@
#include <stdexcept> #include <stdexcept>
#include <math.h> #include <math.h>
inline int char2int(int c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'a' && c <= 'f') {
return 10 + c - 'a';
}
if (c >= 'A' && c <= 'F') {
return 10 + c - 'A';
}
return -1;
}
inline double power(double base, int64_t power) { inline double power(double base, int64_t power) {
double result = 1.0; double result = 1.0;
for (int64_t i = 0; i < power; i++) { for (int64_t i = 0; i < power; i++) {
@@ -98,6 +85,18 @@ void BasicParser::skipWhitespace() {
} }
} }
void BasicParser::skip(size_t n) {
n = std::min(n, source.length()-pos);
for (size_t i = 0; i < n; i++) {
char next = source[pos++];
if (next == '\n') {
line++;
linestart = pos;
}
}
}
void BasicParser::skipLine() { void BasicParser::skipLine() {
while (hasNext()) { while (hasNext()) {
if (source[pos] == '\n') { if (source[pos] == '\n') {
@@ -110,10 +109,28 @@ void BasicParser::skipLine() {
} }
} }
bool BasicParser::skipTo(const std::string& substring) {
size_t idx = source.find(substring, pos);
if (idx == std::string::npos) {
skip(source.length()-pos);
return false;
} else {
skip(idx-pos);
return true;
}
}
bool BasicParser::hasNext() { bool BasicParser::hasNext() {
return pos < source.length(); return pos < source.length();
} }
bool BasicParser::isNext(const std::string& substring) {
if (source.length() - pos < substring.length()) {
return false;
}
return source.substr(pos, substring.length()) == substring;
}
char BasicParser::nextChar() { char BasicParser::nextChar() {
if (!hasNext()) { if (!hasNext()) {
throw error("unexpected end"); throw error("unexpected end");
@@ -129,6 +146,17 @@ void BasicParser::expect(char expected) {
pos++; pos++;
} }
void BasicParser::expect(const std::string& substring) {
if (substring.empty())
return;
for (uint i = 0; i < substring.length(); i++) {
if (source.length() <= pos + i || source[pos+i] != substring[i]) {
throw error(escape_string(substring)+" expected");
}
}
pos += substring.length();
}
void BasicParser::expectNewLine() { void BasicParser::expectNewLine() {
while (hasNext()) { while (hasNext()) {
char next = source[pos]; char next = source[pos];
@@ -145,6 +173,10 @@ void BasicParser::expectNewLine() {
} }
} }
void BasicParser::goBack() {
if (pos) pos--;
}
char BasicParser::peek() { char BasicParser::peek() {
skipWhitespace(); skipWhitespace();
if (pos >= source.length()) { if (pos >= source.length()) {
@@ -171,7 +203,7 @@ std::string BasicParser::parseName() {
int64_t BasicParser::parseSimpleInt(int base) { int64_t BasicParser::parseSimpleInt(int base) {
char c = peek(); char c = peek();
int index = char2int(c); int index = hexchar2int(c);
if (index == -1 || index >= base) { if (index == -1 || index >= base) {
throw error("invalid number literal"); throw error("invalid number literal");
} }
@@ -182,7 +214,7 @@ int64_t BasicParser::parseSimpleInt(int base) {
while (c == '_') { while (c == '_') {
c = source[++pos]; c = source[++pos];
} }
index = char2int(c); index = hexchar2int(c);
if (index == -1 || index >= base) { if (index == -1 || index >= base) {
return value; return value;
} }
+18
View File
@@ -41,6 +41,19 @@ inline bool is_identifier_part(int c) {
return is_identifier_start(c) || is_digit(c); return is_identifier_start(c) || is_digit(c);
} }
inline int hexchar2int(int c) {
if (c >= '0' && c <= '9') {
return c - '0';
}
if (c >= 'a' && c <= 'f') {
return 10 + c - 'a';
}
if (c >= 'A' && c <= 'F') {
return 10 + c - 'A';
}
return -1;
}
extern std::string escape_string(std::string s); extern std::string escape_string(std::string s);
class parsing_error : public std::runtime_error { class parsing_error : public std::runtime_error {
@@ -70,12 +83,17 @@ protected:
uint linestart = 0; uint linestart = 0;
virtual void skipWhitespace(); virtual void skipWhitespace();
void skip(size_t n);
void skipLine(); void skipLine();
bool skipTo(const std::string& substring);
void expect(char expected); void expect(char expected);
void expect(const std::string& substring);
char peek(); char peek();
char nextChar(); char nextChar();
bool hasNext(); bool hasNext();
bool isNext(const std::string& substring);
void expectNewLine(); void expectNewLine();
void goBack();
std::string parseName(); std::string parseName();
int64_t parseSimpleInt(int base); int64_t parseSimpleInt(int base);
+1 -1
View File
@@ -34,7 +34,7 @@ std::vector<ubyte> gzip::compress(const ubyte* src, size_t size) {
std::vector<ubyte> gzip::decompress(const ubyte* src, size_t size) { std::vector<ubyte> gzip::decompress(const ubyte* src, size_t size) {
// getting uncompressed data length from gzip footer // getting uncompressed data length from gzip footer
size_t decompressed_size = *(uint32_t*)(src+size-4); size_t decompressed_size = *reinterpret_cast<const uint32_t*>(src+size-4);
std::vector<ubyte> buffer; std::vector<ubyte> buffer;
buffer.resize(decompressed_size); buffer.resize(decompressed_size);
+354
View File
@@ -0,0 +1,354 @@
#include "xml.h"
#include <charconv>
#include <stdexcept>
#include <sstream>
#include "../util/stringutil.h"
using namespace xml;
Attribute::Attribute(std::string name, std::string text)
: name(name),
text(text) {
}
const std::string& Attribute::getName() const {
return name;
}
const std::string& Attribute::getText() const {
return text;
}
int64_t Attribute::asInt() const {
return std::stoll(text);
}
double Attribute::asFloat() const {
return util::parse_double(text);
}
bool Attribute::asBool() const {
return text == "true" || text == "1";
}
Node::Node(std::string tag) : tag(tag) {
}
void Node::add(xmlelement element) {
elements.push_back(element);
}
void Node::set(std::string name, std::string text) {
attrs[name] = Attribute(name, text);
}
const std::string& Node::getTag() const {
return tag;
}
const xmlattribute Node::attr(const std::string& name) const {
auto found = attrs.find(name);
if (found == attrs.end()) {
throw std::runtime_error("element <"+tag+" ...> missing attribute "+name);
}
return found->second;
}
const xmlattribute Node::attr(const std::string& name, const std::string& def) const {
auto found = attrs.find(name);
if (found == attrs.end()) {
return Attribute(name, def);
}
return found->second;
}
bool Node::has(const std::string& name) const {
auto found = attrs.find(name);
return found != attrs.end();
}
xmlelement Node::sub(size_t index) {
return elements.at(index);
}
size_t Node::size() const {
return elements.size();
}
const std::vector<xmlelement>& Node::getElements() const {
return elements;
}
const xmlelements_map& Node::getAttributes() const {
return attrs;
}
Document::Document(std::string version, std::string encoding)
: version(version),
encoding(encoding) {
}
void Document::setRoot(xmlelement element) {
this->root = element;
}
xmlelement Document::getRoot() const {
return root;
}
const std::string& Document::getVersion() const {
return version;
}
const std::string& Document::getEncoding() const {
return encoding;
}
Parser::Parser(std::string filename, std::string source)
: BasicParser(filename, source) {
}
xmlelement Parser::parseOpenTag() {
std::string tag = parseXMLName();
auto node = std::make_shared<Node>(tag);
char c;
while (true) {
skipWhitespace();
c = peek();
if (c == '/' || c == '>' || c == '?')
break;
std::string attrname = parseXMLName();
std::string attrtext = "";
skipWhitespace();
if (peek() == '=') {
nextChar();
skipWhitespace();
expect('"');
attrtext = parseString('"');
}
node->set(attrname, attrtext);
}
return node;
}
void Parser::parseDeclaration() {
std::string version = "1.0";
std::string encoding = "UTF-8";
expect('<');
if (peek() == '?') {
nextChar();
xmlelement node = parseOpenTag();
expect("?>");
if (node->getTag() != "xml") {
throw error("invalid declaration");
}
version = node->attr("version", version).getText();
encoding = node->attr("encoding", encoding).getText();
if (encoding != "utf-8" && encoding != "UTF-8") {
throw error("UTF-8 encoding is only supported");
}
} else {
goBack();
}
document = std::make_shared<Document>(version, encoding);
}
void Parser::parseComment() {
expect("!--");
if (skipTo("-->")) {
skip(3);
} else {
throw error("comment close missing");
}
}
std::string Parser::parseText() {
size_t start = pos;
while (hasNext()) {
char c = peek();
if (c == '<') {
break;
}
nextChar();
}
return source.substr(start, pos-start);
}
inline bool is_xml_identifier_start(char c) {
return is_identifier_start(c) || c == ':';
}
inline bool is_xml_identifier_part(char c) {
return is_identifier_part(c) || c == '-' || c == '.' || c == ':';
}
std::string Parser::parseXMLName() {
char c = peek();
if (!is_xml_identifier_start(c)) {
throw error("identifier expected");
}
int start = pos;
while (hasNext() && is_xml_identifier_part(source[pos])) {
pos++;
}
return source.substr(start, pos-start);
}
xmlelement Parser::parseElement() {
// text element
if (peek() != '<') {
auto element = std::make_shared<Node>("#");
auto text = parseText();
util::replaceAll(text, "&quot;", "\"");
util::replaceAll(text, "&apos;", "'");
util::replaceAll(text, "&lt;", "<");
util::replaceAll(text, "&gt;", ">");
util::replaceAll(text, "&amp;", "&");
element->set("#", text);
return element;
}
nextChar();
// <!--element-->
if (peek() == '!') {
if (isNext("!DOCTYPE ")) {
throw error("XML DTD is not supported yet");
}
parseComment();
return nullptr;
}
auto element = parseOpenTag();
char c = nextChar();
// <element/>
if (c == '/') {
expect('>');
}
// <element>...</element>
else if (c == '>') {
skipWhitespace();
while (!isNext("</")) {
auto sub = parseElement();
if (sub) {
element->add(sub);
}
skipWhitespace();
}
skip(2);
expect(element->getTag());
expect('>');
}
// <element?>
else {
throw error("invalid syntax");
}
return element;
}
xmldocument Parser::parse() {
parseDeclaration();
xmlelement root = nullptr;
while (root == nullptr) {
root = parseElement();
}
document->setRoot(root);
return document;
}
xmldocument xml::parse(std::string filename, std::string source) {
Parser parser(filename, source);
return parser.parse();
}
inline void newline(
std::stringstream& ss,
bool nice,
const std::string& indentStr,
int indent
) {
if (!nice)
return;
ss << '\n';
for (int i = 0; i < indent; i++) {
ss << indentStr;
}
}
static void stringifyElement(
std::stringstream& ss,
const xmlelement element,
bool nice,
const std::string& indentStr,
int indent
) {
if (element->isText()) {
std::string text = element->attr("#").getText();
util::replaceAll(text, "&", "&amp;");
util::replaceAll(text, "\"","&quot;");
util::replaceAll(text, "'", "&apos;");
util::replaceAll(text, "<", "&lt;");
util::replaceAll(text, ">", "&gt;");
ss << text;
return;
}
const std::string& tag = element->getTag();
ss << '<' << tag;
auto& attrs = element->getAttributes();
if (!attrs.empty()) {
ss << ' ';
int count = 0;
for (auto& entry : attrs) {
auto attr = entry.second;
ss << attr.getName();
if (!attr.getText().empty()) {
ss << "=" << escape_string(attr.getText());
}
if (count + 1 < int(attrs.size())) {
ss << " ";
}
count++;
}
}
auto& elements = element->getElements();
if (elements.size() == 1 && elements[0]->isText()) {
ss << ">";
stringifyElement(ss, elements[0], nice, indentStr, indent+1);
ss << "</" << tag << ">";
return;
}
if (!elements.empty()) {
ss << '>';
for (auto& sub : elements) {
newline(ss, nice, indentStr, indent+1);
stringifyElement(ss, sub, nice, indentStr, indent+1);
}
newline(ss, nice, indentStr, indent);
ss << "</" << tag << ">";
} else {
ss << "/>";
}
}
std::string xml::stringify(
const xmldocument document,
bool nice,
const std::string& indentStr
) {
std::stringstream ss;
// XML declaration
ss << "<?xml version=\"" << document->getVersion();
ss << "\" encoding=\"UTF-8\" ?>";
newline(ss, nice, indentStr, 0);
stringifyElement(ss, document->getRoot(), nice, indentStr, 0);
return ss.str();
}
+134
View File
@@ -0,0 +1,134 @@
#ifndef CODERS_XML_H_
#define CODERS_XML_H_
#include <string>
#include <memory>
#include <vector>
#include <unordered_map>
#include "commons.h"
namespace xml {
class Node;
class Attribute;
class Document;
typedef Attribute xmlattribute;
typedef std::shared_ptr<Node> xmlelement;
typedef std::shared_ptr<Document> xmldocument;
typedef std::unordered_map<std::string, xmlattribute> xmlelements_map;
class Attribute {
std::string name;
std::string text;
public:
Attribute() {};
Attribute(std::string name, std::string text);
const std::string& getName() const;
const std::string& getText() const;
int64_t asInt() const;
double asFloat() const;
bool asBool() const;
};
/* XML element class. Text element has tag 'text' and attribute 'text' */
class Node {
std::string tag;
std::unordered_map<std::string, xmlattribute> attrs;
std::vector<xmlelement> elements;
public:
Node(std::string tag);
/* Add sub-element */
void add(xmlelement element);
/* Set attribute value. Creates attribute if does not exists */
void set(std::string name, std::string text);
/* Get element tag */
const std::string& getTag() const;
inline bool isText() const {
return getTag() == "#";
}
inline const std::string& text() const {
return attr("#").getText();
}
/* Get attribute by name
@param name attribute name
@throws std::runtime_error if element has no attribute
@return xmlattribute - {name, value} */
const xmlattribute attr(const std::string& name) const;
/* Get attribute by name
@param name name
@param def default value will be returned wrapped in xmlattribute
if element has no attribute
@return xmlattribute - {name, value} or {name, def} if not found*/
const xmlattribute attr(const std::string& name, const std::string& def) const;
/* Check if element has attribute
@param name attribute name */
bool has(const std::string& name) const;
/* Get sub-element by index
@throws std::out_of_range if an invalid index given */
xmlelement sub(size_t index);
/* Get number of sub-elements */
size_t size() const;
const std::vector<xmlelement>& getElements() const;
const xmlelements_map& getAttributes() const;
};
class Document {
xmlelement root = nullptr;
std::string version;
std::string encoding;
public:
Document(std::string version, std::string encoding);
void setRoot(xmlelement element);
xmlelement getRoot() const;
const std::string& getVersion() const;
const std::string& getEncoding() const;
};
class Parser : public BasicParser {
xmldocument document;
xmlelement parseOpenTag();
xmlelement parseElement();
void parseDeclaration();
void parseComment();
std::string parseText();
std::string parseXMLName();
public:
Parser(std::string filename, std::string source);
xmldocument parse();
};
/* Serialize XML Document to string
@param document serializing document
@param nice use human readable format
(with indents and line-separators)
@param indentStr indentation characters sequence
(default - 4 spaces)*/
extern std::string stringify(
const xmldocument document,
bool nice=true,
const std::string& indentStr=" "
);
/* Read XML Document from string
@param filename file name will be shown in error messages
@param source xml source code string */
extern xmldocument parse(std::string filename, std::string source);
}
#endif // CODERS_XML_H_
+2 -2
View File
@@ -71,7 +71,7 @@ Content* ContentBuilder::build() {
// Generating runtime info // Generating runtime info
def->rt.id = blockDefsIndices.size(); def->rt.id = blockDefsIndices.size();
def->rt.emissive = *((uint32_t*)def->emission); def->rt.emissive = *reinterpret_cast<uint32_t*>(def->emission);
def->rt.solid = def->model == BlockModel::block; def->rt.solid = def->model == BlockModel::block;
if (def->rotatable) { if (def->rotatable) {
@@ -95,7 +95,7 @@ Content* ContentBuilder::build() {
// Generating runtime info // Generating runtime info
def->rt.id = itemDefsIndices.size(); def->rt.id = itemDefsIndices.size();
def->rt.emissive = *((uint32_t*)def->emission); def->rt.emissive = *reinterpret_cast<uint32_t*>(def->emission);
itemDefsIndices.push_back(def); itemDefsIndices.push_back(def);
} }
+1 -1
View File
@@ -9,7 +9,7 @@
#include <set> #include <set>
#include "../typedefs.h" #include "../typedefs.h"
typedef std::set<unsigned char> DrawGroups; using DrawGroups = std::set<unsigned char>;
class Block; class Block;
class ItemDef; class ItemDef;
+1 -1
View File
@@ -74,7 +74,7 @@ void ContentLoader::fixPackIndices() {
std::unique_ptr<dynamic::Map> root; std::unique_ptr<dynamic::Map> root;
if (fs::is_regular_file(indexFile)) { if (fs::is_regular_file(indexFile)) {
root = std::move(files::read_json(indexFile)); root = files::read_json(indexFile);
} else { } else {
root.reset(new dynamic::Map()); root.reset(new dynamic::Map());
} }
+1 -1
View File
@@ -8,7 +8,7 @@ namespace fs = std::filesystem;
class Block; class Block;
class ItemDef; class ItemDef;
class ContentPack; struct ContentPack;
class ContentBuilder; class ContentBuilder;
namespace dynamic { namespace dynamic {
+4 -9
View File
@@ -1,6 +1,4 @@
#include "definitions.h" #include "core_defs.h"
#include <glm/glm.hpp>
#include "items/ItemDef.h" #include "items/ItemDef.h"
#include "content/Content.h" #include "content/Content.h"
@@ -9,11 +7,9 @@
#include "window/input.h" #include "window/input.h"
#include "voxels/Block.h" #include "voxels/Block.h"
using glm::vec3;
// All in-game definitions (blocks, items, etc..) // All in-game definitions (blocks, items, etc..)
void setup_definitions(ContentBuilder* builder) { // Strange function, need to REDO ? void corecontent::setup(ContentBuilder* builder) {
Block* block = new Block("core:air", "air"); Block* block = builder->createBlock("core:air");
block->replaceable = true; block->replaceable = true;
block->drawGroup = 1; block->drawGroup = 1;
block->lightPassing = true; block->lightPassing = true;
@@ -22,13 +18,12 @@ void setup_definitions(ContentBuilder* builder) { // Strange function, need to R
block->selectable = false; block->selectable = false;
block->model = BlockModel::none; block->model = BlockModel::none;
block->pickingItem = "core:empty"; block->pickingItem = "core:empty";
builder->add(block);
ItemDef* item = builder->createItem("core:empty"); ItemDef* item = builder->createItem("core:empty");
item->iconType = item_icon_type::none; item->iconType = item_icon_type::none;
} }
void setup_bindings() { void corecontent::setup_bindings() {
Events::bind(BIND_MOVE_FORWARD, inputtype::keyboard, keycode::W); Events::bind(BIND_MOVE_FORWARD, inputtype::keyboard, keycode::W);
Events::bind(BIND_MOVE_BACK, inputtype::keyboard, keycode::S); Events::bind(BIND_MOVE_BACK, inputtype::keyboard, keycode::S);
Events::bind(BIND_MOVE_RIGHT, inputtype::keyboard, keycode::D); Events::bind(BIND_MOVE_RIGHT, inputtype::keyboard, keycode::D);
+7 -1
View File
@@ -3,7 +3,6 @@
#include <string> #include <string>
const std::string TEXTURE_NOTFOUND = "notfound"; const std::string TEXTURE_NOTFOUND = "notfound";
/* bindings used in engine code */ /* bindings used in engine code */
@@ -24,4 +23,11 @@ const std::string BIND_PLAYER_BUILD = "player.build";
const std::string BIND_PLAYER_PICK = "player.pick"; const std::string BIND_PLAYER_PICK = "player.pick";
const std::string BIND_HUD_INVENTORY = "hud.inventory"; const std::string BIND_HUD_INVENTORY = "hud.inventory";
class ContentBuilder;
namespace corecontent {
extern void setup_bindings();
extern void setup(ContentBuilder* builder);
}
#endif // SRC_CORE_DEFS_H_ #endif // SRC_CORE_DEFS_H_
-13
View File
@@ -1,13 +0,0 @@
#ifndef DECLARATIONS_H
#define DECLARATIONS_H
#include <iostream>
#include "core_defs.h"
class ContentBuilder;
extern void setup_bindings();
extern void setup_definitions(ContentBuilder* builder);
#endif // DECLARATIONS_H
+10
View File
@@ -0,0 +1,10 @@
#ifndef DELEGATES_H_
#define DELEGATES_H_
#include <functional>
#include <string>
typedef std::function<void()> runnable;
typedef std::function<void(const std::string&)> stringconsumer;
#endif // DELEGATES_H_
+5 -5
View File
@@ -37,7 +37,7 @@
#include "frontend/locale/langs.h" #include "frontend/locale/langs.h"
#include "logic/scripting/scripting.h" #include "logic/scripting/scripting.h"
#include "definitions.h" #include "core_defs.h"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@@ -56,7 +56,7 @@ Engine::Engine(EngineSettings& settings, EnginePaths* paths)
assets.reset(new Assets()); assets.reset(new Assets());
AssetsLoader loader(assets.get(), resPaths.get()); AssetsLoader loader(assets.get(), resPaths.get());
AssetsLoader::createDefaults(loader); AssetsLoader::createDefaults(loader);
AssetsLoader::addDefaults(loader, true); AssetsLoader::addDefaults(loader, false);
Shader::preprocessor->setPaths(resPaths.get()); Shader::preprocessor->setPaths(resPaths.get());
while (loader.hasNext()) { while (loader.hasNext()) {
@@ -148,7 +148,7 @@ inline const std::string checkPacks(const std::unordered_set<std::string>& packs
void Engine::loadContent() { void Engine::loadContent() {
auto resdir = paths->getResources(); auto resdir = paths->getResources();
ContentBuilder contentBuilder; ContentBuilder contentBuilder;
setup_definitions(&contentBuilder); corecontent::setup(&contentBuilder);
paths->setContentPacks(&contentPacks); paths->setContentPacks(&contentPacks);
std::vector<fs::path> resRoots; std::vector<fs::path> resRoots;
@@ -183,7 +183,7 @@ void Engine::loadContent() {
std::cout << "-- loading assets" << std::endl; std::cout << "-- loading assets" << std::endl;
AssetsLoader loader(new_assets.get(), resPaths.get()); AssetsLoader loader(new_assets.get(), resPaths.get());
AssetsLoader::createDefaults(loader); AssetsLoader::createDefaults(loader);
AssetsLoader::addDefaults(loader, false); AssetsLoader::addDefaults(loader, true);
while (loader.hasNext()) { while (loader.hasNext()) {
if (!loader.loadNext()) { if (!loader.loadNext()) {
new_assets.reset(); new_assets.reset();
@@ -214,7 +214,7 @@ void Engine::setScreen(std::shared_ptr<Screen> screen) {
void Engine::setLanguage(std::string locale) { void Engine::setLanguage(std::string locale) {
settings.ui.language = locale; settings.ui.language = locale;
langs::setup(paths->getResources(), locale, contentPacks); langs::setup(paths->getResources(), locale, contentPacks);
menus::create_menus(this, gui->getMenu()); menus::create_menus(this);
} }
gui::GUI* Engine::getGUI() { gui::GUI* Engine::getGUI() {
+13 -13
View File
@@ -30,10 +30,10 @@ fs::path EnginePaths::getScreenshotFile(std::string ext) {
ss << std::put_time(&tm, format); ss << std::put_time(&tm, format);
std::string datetimestr = ss.str(); std::string datetimestr = ss.str();
fs::path filename = folder/fs::path("screenshot-"+datetimestr+"."+ext); fs::path filename = folder/fs::u8path("screenshot-"+datetimestr+"."+ext);
uint index = 0; uint index = 0;
while (fs::exists(filename)) { while (fs::exists(filename)) {
filename = folder/fs::path("screenshot-"+datetimestr+"-"+std::to_string(index)+"."+ext); filename = folder/fs::u8path("screenshot-"+datetimestr+"-"+std::to_string(index)+"."+ext);
index++; index++;
} }
return filename; return filename;
@@ -59,7 +59,7 @@ std::vector<fs::path> EnginePaths::scanForWorlds() {
continue; continue;
} }
fs::path worldFolder = entry.path(); fs::path worldFolder = entry.path();
fs::path worldFile = worldFolder/fs::path(WorldFiles::WORLD_FILE); fs::path worldFile = worldFolder/fs::u8path(WorldFiles::WORLD_FILE);
if (!fs::is_regular_file(worldFile)) { if (!fs::is_regular_file(worldFile)) {
continue; continue;
} }
@@ -91,31 +91,31 @@ void EnginePaths::setContentPacks(std::vector<ContentPack>* contentPacks) {
fs::path EnginePaths::resolve(std::string path) { fs::path EnginePaths::resolve(std::string path) {
size_t separator = path.find(':'); size_t separator = path.find(':');
if (separator == std::string::npos) { if (separator == std::string::npos) {
return fs::path(path); return fs::u8path(path);
} }
std::string prefix = path.substr(0, separator); std::string prefix = path.substr(0, separator);
std::string filename = path.substr(separator+1); std::string filename = path.substr(separator+1);
if (prefix == "res" || prefix == "core") { if (prefix == "res" || prefix == "core") {
return resources/fs::path(filename); return resources/fs::u8path(filename);
} }
if (prefix == "user") { if (prefix == "user") {
return userfiles/fs::path(filename); return userfiles/fs::u8path(filename);
} }
if (prefix == "world") { if (prefix == "world") {
return worldFolder/fs::path(filename); return worldFolder/fs::u8path(filename);
} }
if (contentPacks) { if (contentPacks) {
for (auto& pack : *contentPacks) { for (auto& pack : *contentPacks) {
if (pack.id == prefix) { if (pack.id == prefix) {
return pack.folder/fs::path(filename); return pack.folder/fs::u8path(filename);
} }
} }
} }
return fs::path("./"+filename); return fs::u8path("./"+filename);
} }
ResPaths::ResPaths(fs::path mainRoot, std::vector<fs::path> roots) ResPaths::ResPaths(fs::path mainRoot, std::vector<fs::path> roots)
@@ -125,19 +125,19 @@ ResPaths::ResPaths(fs::path mainRoot, std::vector<fs::path> roots)
fs::path ResPaths::find(const std::string& filename) const { fs::path ResPaths::find(const std::string& filename) const {
for (int i = roots.size()-1; i >= 0; i--) { for (int i = roots.size()-1; i >= 0; i--) {
auto& root = roots[i]; auto& root = roots[i];
fs::path file = root / fs::path(filename); fs::path file = root / fs::u8path(filename);
if (fs::exists(file)) { if (fs::exists(file)) {
return file; return file;
} }
} }
return mainRoot / fs::path(filename); return mainRoot / fs::u8path(filename);
} }
std::vector<fs::path> ResPaths::listdir(const std::string& folderName) const { std::vector<fs::path> ResPaths::listdir(const std::string& folderName) const {
std::vector<fs::path> entries; std::vector<fs::path> entries;
for (int i = roots.size()-1; i >= 0; i--) { for (int i = roots.size()-1; i >= 0; i--) {
auto& root = roots[i]; auto& root = roots[i];
fs::path folder = root / fs::path(folderName); fs::path folder = root / fs::u8path(folderName);
if (!fs::is_directory(folder)) if (!fs::is_directory(folder))
continue; continue;
for (const auto& entry : fs::directory_iterator(folder)) { for (const auto& entry : fs::directory_iterator(folder)) {
@@ -145,7 +145,7 @@ std::vector<fs::path> ResPaths::listdir(const std::string& folderName) const {
} }
} }
{ {
fs::path folder = mainRoot / fs::path(folderName); fs::path folder = mainRoot / fs::u8path(folderName);
if (!fs::is_directory(folder)) if (!fs::is_directory(folder))
return entries; return entries;
for (const auto& entry : fs::directory_iterator(folder)) { for (const auto& entry : fs::directory_iterator(folder)) {
+3 -2
View File
@@ -289,10 +289,11 @@ void SlotView::clicked(gui::GUI* gui, int button) {
if (stack.isEmpty()) { if (stack.isEmpty()) {
stack.set(grabbed); stack.set(grabbed);
stack.setCount(1); stack.setCount(1);
} else { grabbed.setCount(grabbed.getCount()-1);
} else if (stack.accepts(grabbed)){
stack.setCount(stack.getCount()+1); stack.setCount(stack.getCount()+1);
grabbed.setCount(grabbed.getCount()-1);
} }
grabbed.setCount(grabbed.getCount()-1);
} }
} }
} }
-2
View File
@@ -120,8 +120,6 @@ class InventoryView : public gui::Container {
InventoryInteraction* interaction; InventoryInteraction* interaction;
std::vector<SlotView*> slots; std::vector<SlotView*> slots;
int scroll = 0;
public: public:
InventoryView( InventoryView(
const Content* content, const Content* content,
+1 -1
View File
@@ -106,7 +106,7 @@ void WorldRenderer::drawChunks(Chunks* chunks,
} }
float px = camera->position.x / (float)CHUNK_W; float px = camera->position.x / (float)CHUNK_W;
float pz = camera->position.z / (float)CHUNK_D; float pz = camera->position.z / (float)CHUNK_D;
std::sort(indices.begin(), indices.end(), [this, chunks, px, pz](size_t i, size_t j) { std::sort(indices.begin(), indices.end(), [chunks, px, pz](size_t i, size_t j) {
auto a = chunks->chunks[i]; auto a = chunks->chunks[i];
auto b = chunks->chunks[j]; auto b = chunks->chunks[j];
return ((a->x + 0.5f - px)*(a->x + 0.5f - px) + return ((a->x + 0.5f - px)*(a->x + 0.5f - px) +
+1 -1
View File
@@ -39,7 +39,7 @@ Skybox::Skybox(uint size, Shader* shader)
-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f
}; };
vattr attrs[] {2, 0}; vattr attrs[] {{2}, {0}};
mesh = std::make_unique<Mesh>(vertices, 6, attrs); mesh = std::make_unique<Mesh>(vertices, 6, attrs);
sprites.push_back(skysprite { sprites.push_back(skysprite {
+12 -19
View File
@@ -13,30 +13,23 @@
#include "../../window/input.h" #include "../../window/input.h"
#include "../../window/Camera.h" #include "../../window/Camera.h"
using glm::vec2;
using glm::vec3;
using std::string;
using std::shared_ptr;
using namespace gui; using namespace gui;
GUI::GUI() { GUI::GUI() {
container = new Container(vec2(0, 0), vec2(1000)); container = std::make_shared<Container>(glm::vec2(0, 0), glm::vec2(1000));
uicamera = std::make_unique<Camera>(glm::vec3(), Window::height);
uicamera = new Camera(vec3(), Window::height);
uicamera->perspective = false; uicamera->perspective = false;
uicamera->flipped = true; uicamera->flipped = true;
menu = new PagesControl(); menu = std::make_shared<PagesControl>();
container->add(menu); container->add(menu);
container->scrollable(false); container->scrollable(false);
} }
GUI::~GUI() { GUI::~GUI() {
delete uicamera;
delete container;
} }
PagesControl* GUI::getMenu() { std::shared_ptr<PagesControl> GUI::getMenu() {
return menu; return menu;
} }
@@ -85,7 +78,7 @@ void GUI::actMouse(float delta) {
} }
void GUI::act(float delta) { void GUI::act(float delta) {
container->setSize(vec2(Window::width, Window::height)); container->setSize(glm::vec2(Window::width, Window::height));
container->act(delta); container->act(delta);
auto prevfocus = focus; auto prevfocus = focus;
@@ -132,7 +125,7 @@ void GUI::draw(const GfxContext* pctx, Assets* assets) {
container->draw(pctx, assets); container->draw(pctx, assets);
} }
shared_ptr<UINode> GUI::getFocused() const { std::shared_ptr<UINode> GUI::getFocused() const {
return focus; return focus;
} }
@@ -144,19 +137,19 @@ void GUI::addBack(std::shared_ptr<UINode> panel) {
container->addBack(panel); container->addBack(panel);
} }
void GUI::add(shared_ptr<UINode> panel) { void GUI::add(std::shared_ptr<UINode> panel) {
container->add(panel); container->add(panel);
} }
void GUI::remove(shared_ptr<UINode> panel) { void GUI::remove(std::shared_ptr<UINode> panel) {
container->remove(panel); container->remove(panel);
} }
void GUI::store(string name, shared_ptr<UINode> node) { void GUI::store(std::string name, std::shared_ptr<UINode> node) {
storage[name] = node; storage[name] = node;
} }
shared_ptr<UINode> GUI::get(string name) { std::shared_ptr<UINode> GUI::get(std::string name) {
auto found = storage.find(name); auto found = storage.find(name);
if (found == storage.end()) { if (found == storage.end()) {
return nullptr; return nullptr;
@@ -164,11 +157,11 @@ shared_ptr<UINode> GUI::get(string name) {
return found->second; return found->second;
} }
void GUI::remove(string name) { void GUI::remove(std::string name) {
storage.erase(name); storage.erase(name);
} }
void GUI::setFocus(shared_ptr<UINode> node) { void GUI::setFocus(std::shared_ptr<UINode> node) {
if (focus) { if (focus) {
focus->defocus(); focus->defocus();
} }
+4 -7
View File
@@ -44,28 +44,25 @@ class Camera;
*/ */
namespace gui { namespace gui {
typedef std::function<void()> runnable;
typedef std::function<void(const std::string&)> stringconsumer;
class UINode; class UINode;
class Container; class Container;
class PagesControl; class PagesControl;
class GUI { class GUI {
Container* container; std::shared_ptr<Container> container;
std::shared_ptr<UINode> hover = nullptr; std::shared_ptr<UINode> hover = nullptr;
std::shared_ptr<UINode> pressed = nullptr; std::shared_ptr<UINode> pressed = nullptr;
std::shared_ptr<UINode> focus = nullptr; std::shared_ptr<UINode> focus = nullptr;
std::unordered_map<std::string, std::shared_ptr<UINode>> storage; std::unordered_map<std::string, std::shared_ptr<UINode>> storage;
Camera* uicamera; std::unique_ptr<Camera> uicamera;
PagesControl* menu; std::shared_ptr<PagesControl> menu;
void actMouse(float delta); void actMouse(float delta);
public: public:
GUI(); GUI();
~GUI(); ~GUI();
PagesControl* getMenu(); std::shared_ptr<PagesControl> getMenu();
std::shared_ptr<UINode> getFocused() const; std::shared_ptr<UINode> getFocused() const;
bool isFocusCaught() const; bool isFocusCaught() const;
+17
View File
@@ -88,6 +88,14 @@ void UINode::setInteractive(bool flag) {
interactive = flag; interactive = flag;
} }
void UINode::setResizing(bool flag) {
resizing = flag;
}
bool UINode::isResizing() const {
return resizing;
}
vec2 UINode::calcCoord() const { vec2 UINode::calcCoord() const {
if (parent) { if (parent) {
return coord + parent->calcCoord() + parent->contentOffset(); return coord + parent->calcCoord() + parent->contentOffset();
@@ -115,6 +123,15 @@ void UINode::setSize(vec2 size) {
void UINode::setColor(vec4 color) { void UINode::setColor(vec4 color) {
this->color = color; this->color = color;
this->hoverColor = color;
}
void UINode::setHoverColor(glm::vec4 newColor) {
this->hoverColor = newColor;
}
glm::vec4 UINode::getHoverColor() const {
return hoverColor;
} }
vec4 UINode::getColor() const { vec4 UINode::getColor() const {
+28 -2
View File
@@ -13,23 +13,26 @@ namespace gui {
class UINode; class UINode;
class GUI; class GUI;
typedef std::function<void(GUI*)> onaction; using onaction = std::function<void(GUI*)>;
typedef std::function<void(GUI*, double)> onnumberchange; using onnumberchange = std::function<void(GUI*, double)>;
enum class Align { enum class Align {
left, center, right left, center, right
}; };
class UINode { class UINode {
protected: protected:
glm::vec2 coord; glm::vec2 coord;
glm::vec2 size; glm::vec2 size;
glm::vec4 color {1.0f}; glm::vec4 color {1.0f};
glm::vec4 hoverColor {1.0f};
glm::vec4 margin {1.0f}; glm::vec4 margin {1.0f};
bool visible = true; bool visible = true;
bool hover = false; bool hover = false;
bool pressed = false; bool pressed = false;
bool focused = false; bool focused = false;
bool interactive = true; bool interactive = true;
bool resizing = true;
Align align = Align::left; Align align = Align::left;
UINode* parent = nullptr; UINode* parent = nullptr;
UINode(glm::vec2 coord, glm::vec2 size); UINode(glm::vec2 coord, glm::vec2 size);
@@ -50,9 +53,16 @@ namespace gui {
virtual void setParent(UINode* node); virtual void setParent(UINode* node);
UINode* getParent() const; UINode* getParent() const;
/* Set element color (doesn't affect inner elements).
Also replaces hover color to avoid adding extra properties. */
virtual void setColor(glm::vec4 newColor); virtual void setColor(glm::vec4 newColor);
/* Get element color */
glm::vec4 getColor() const; glm::vec4 getColor() const;
virtual void setHoverColor(glm::vec4 newColor);
glm::vec4 getHoverColor() const;
virtual void setMargin(glm::vec4 margin); virtual void setMargin(glm::vec4 margin);
glm::vec4 getMargin() const; glm::vec4 getMargin() const;
@@ -66,18 +76,34 @@ namespace gui {
bool isPressed() const; bool isPressed() const;
void defocus(); void defocus();
bool isFocused() const; bool isFocused() const;
/* Check if elements catches all user input when focused */
virtual bool isFocuskeeper() const {return false;} virtual bool isFocuskeeper() const {return false;}
virtual void typed(unsigned int codepoint) {}; virtual void typed(unsigned int codepoint) {};
virtual void keyPressed(int key) {}; virtual void keyPressed(int key) {};
/* Check if screen position is inside of the element
@param pos screen position */
virtual bool isInside(glm::vec2 pos); virtual bool isInside(glm::vec2 pos);
/* Get element under the cursor.
@param pos cursor screen position
@param self shared pointer to element
@return self, sub-element or nullptr if element is not interractive */
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self); virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self);
/* Check if element is opaque for cursor */
virtual bool isInteractive() const; virtual bool isInteractive() const;
/* Make the element opaque (true) or transparent (false) for cursor */
virtual void setInteractive(bool flag); virtual void setInteractive(bool flag);
virtual void setResizing(bool flag);
virtual bool isResizing() const;
/* Get inner content offset. Used for scroll */
virtual glm::vec2 contentOffset() {return glm::vec2(0.0f);}; virtual glm::vec2 contentOffset() {return glm::vec2(0.0f);};
/* Calculate screen position of the element */
virtual glm::vec2 calcCoord() const; virtual glm::vec2 calcCoord() const;
virtual void setCoord(glm::vec2 coord); virtual void setCoord(glm::vec2 coord);
virtual glm::vec2 getSize() const; virtual glm::vec2 getSize() const;
+50 -23
View File
@@ -20,6 +20,7 @@ Label::Label(std::string text, std::string fontName)
: UINode(vec2(), vec2(text.length() * 8, 15)), : UINode(vec2(), vec2(text.length() * 8, 15)),
text(util::str2wstr_utf8(text)), text(util::str2wstr_utf8(text)),
fontName_(fontName) { fontName_(fontName) {
setInteractive(false);
} }
@@ -27,6 +28,7 @@ Label::Label(std::wstring text, std::string fontName)
: UINode(vec2(), vec2(text.length() * 8, 15)), : UINode(vec2(), vec2(text.length() * 8, 15)),
text(text), text(text),
fontName_(fontName) { fontName_(fontName) {
setInteractive(false);
} }
void Label::setText(std::wstring text) { void Label::setText(std::wstring text) {
@@ -46,12 +48,23 @@ void Label::draw(const GfxContext* pctx, Assets* assets) {
batch->color = getColor(); batch->color = getColor();
Font* font = assets->getFont(fontName_); Font* font = assets->getFont(fontName_);
vec2 size = getSize(); vec2 size = getSize();
vec2 newsize = vec2(font->calcWidth(text), font->lineHeight()); vec2 newsize = vec2(
if (newsize.x > size.x) { font->calcWidth(text),
setSize(newsize); font->getLineHeight()+font->getYOffset()
size = newsize; );
}
vec2 coord = calcCoord(); vec2 coord = calcCoord();
switch (align) {
case Align::left:
break;
case Align::center:
coord.x += (size.x-newsize.x)*0.5f;
break;
case Align::right:
coord.x += size.x-newsize.x;
break;
}
coord.y += (size.y-newsize.y)*0.5f;
font->draw(batch, text, coord.x, coord.y); font->draw(batch, text, coord.x, coord.y);
} }
@@ -60,10 +73,6 @@ Label* Label::textSupplier(wstringsupplier supplier) {
return this; return this;
} }
void Label::setSize(vec2 sizenew) {
UINode::setSize(vec2(UINode::getSize().x, sizenew.y));
}
// ================================= Image ==================================== // ================================= Image ====================================
Image::Image(std::string texture, vec2 size) : UINode(vec2(), size), texture(texture) { Image::Image(std::string texture, vec2 size) : UINode(vec2(), size), texture(texture) {
setInteractive(false); setInteractive(false);
@@ -87,17 +96,34 @@ Button::Button(std::shared_ptr<UINode> content, glm::vec4 padding)
padding[1]+padding[3]+margin[1]+margin[3])); padding[1]+padding[3]+margin[1]+margin[3]));
add(content); add(content);
scrollable(false); scrollable(false);
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
} }
Button::Button(std::wstring text, glm::vec4 padding, glm::vec4 margin) Button::Button(
: Panel(vec2(32,32), padding, 0) std::wstring text,
vec4 padding,
onaction action,
vec2 size
) : Panel(size, padding, 0)
{ {
setMargin(margin); if (size.y < 0.0f) {
size = vec2(
glm::max(padding.x + padding.z + text.length()*8, size.x),
glm::max(padding.y + padding.w + 16, size.y)
);
}
setSize(size);
if (action) {
listenAction(action);
}
scrollable(false); scrollable(false);
label = std::make_shared<Label>(text); label = std::make_shared<Label>(text);
label->setAlign(Align::center); label->setAlign(Align::center);
label->setSize(size-vec2(padding.z+padding.x, padding.w+padding.y));
add(label); add(label);
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
} }
void Button::setText(std::wstring text) { void Button::setText(std::wstring text) {
@@ -120,8 +146,11 @@ Button* Button::textSupplier(wstringsupplier supplier) {
return this; return this;
} }
void Button::setHoverColor(glm::vec4 color) { void Button::refresh() {
hoverColor = color; Panel::refresh();
if (label) {
label->setSize(size-vec2(padding.z+padding.x, padding.w+padding.y));
}
} }
void Button::drawBackground(const GfxContext* pctx, Assets* assets) { void Button::drawBackground(const GfxContext* pctx, Assets* assets) {
@@ -159,6 +188,7 @@ void Button::textAlign(Align align) {
// ============================== RichButton ================================== // ============================== RichButton ==================================
RichButton::RichButton(vec2 size) : Container(vec2(), size) { RichButton::RichButton(vec2 size) : Container(vec2(), size) {
setHoverColor(glm::vec4(0.05f, 0.1f, 0.15f, 0.75f));
} }
void RichButton::mouseRelease(GUI* gui, int x, int y) { void RichButton::mouseRelease(GUI* gui, int x, int y) {
@@ -175,10 +205,6 @@ RichButton* RichButton::listenAction(onaction action) {
return this; return this;
} }
void RichButton::setHoverColor(glm::vec4 color) {
hoverColor = color;
}
void RichButton::drawBackground(const GfxContext* pctx, Assets* assets) { void RichButton::drawBackground(const GfxContext* pctx, Assets* assets) {
vec2 coord = calcCoord(); vec2 coord = calcCoord();
auto batch = pctx->getBatch2D(); auto batch = pctx->getBatch2D();
@@ -189,11 +215,12 @@ void RichButton::drawBackground(const GfxContext* pctx, Assets* assets) {
// ================================ TextBox =================================== // ================================ TextBox ===================================
TextBox::TextBox(std::wstring placeholder, vec4 padding) TextBox::TextBox(std::wstring placeholder, vec4 padding)
: Panel(vec2(200,32), padding, 0, false), : Panel(vec2(200,32), padding, 0),
input(L""), input(L""),
placeholder(placeholder) { placeholder(placeholder) {
label = std::make_shared<Label>(L""); label = std::make_shared<Label>(L"");
add(label); add(label);
setHoverColor(glm::vec4(0.05f, 0.1f, 0.2f, 0.75f));
} }
void TextBox::drawBackground(const GfxContext* pctx, Assets* assets) { void TextBox::drawBackground(const GfxContext* pctx, Assets* assets) {
@@ -251,7 +278,7 @@ bool TextBox::isValid() const {
return valid; return valid;
} }
void TextBox::setOnEditStart(gui::runnable oneditstart) { void TextBox::setOnEditStart(runnable oneditstart) {
onEditStart = oneditstart; onEditStart = oneditstart;
} }
@@ -312,9 +339,9 @@ void TextBox::text(std::wstring value) {
// ============================== InputBindBox ================================ // ============================== InputBindBox ================================
InputBindBox::InputBindBox(Binding& binding, vec4 padding) InputBindBox::InputBindBox(Binding& binding, vec4 padding)
: Panel(vec2(100,32), padding, 0, false), : Panel(vec2(100,32), padding, 0),
binding(binding) { binding(binding) {
label = new Label(L""); label = std::make_shared<Label>(L"");
add(label); add(label);
scrollable(false); scrollable(false);
} }
@@ -437,7 +464,7 @@ FullCheckBox::FullCheckBox(std::wstring text, glm::vec2 size, bool checked)
: Panel(size), : Panel(size),
checkbox(std::make_shared<CheckBox>(checked)){ checkbox(std::make_shared<CheckBox>(checked)){
setColor(vec4(0.0f)); setColor(vec4(0.0f));
orientation(Orientation::horizontal); setOrientation(Orientation::horizontal);
add(checkbox); add(checkbox);
+18 -19
View File
@@ -6,25 +6,27 @@
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "GUI.h" #include "GUI.h"
#include "UINode.h" #include "UINode.h"
#include "panels.h" #include "panels.h"
#include "../../window/input.h" #include "../../window/input.h"
#include "../../delegates.h"
class Batch2D; class Batch2D;
class Assets; class Assets;
namespace gui { namespace gui {
typedef std::function<std::wstring()> wstringsupplier; using wstringsupplier = std::function<std::wstring()>;
typedef std::function<void(std::wstring)> wstringconsumer; using wstringconsumer = std::function<void(std::wstring)>;
typedef std::function<double()> doublesupplier; using doublesupplier = std::function<double()>;
typedef std::function<void(double)> doubleconsumer; using doubleconsumer = std::function<void(double)>;
typedef std::function<bool()> boolsupplier; using boolsupplier = std::function<bool()>;
typedef std::function<void(bool)> boolconsumer; using boolconsumer = std::function<void(bool)>;
typedef std::function<bool(const std::wstring&)> wstringchecker; using wstringchecker = std::function<bool(const std::wstring&)>;
class Label : public UINode { class Label : public UINode {
protected: protected:
@@ -41,7 +43,6 @@ namespace gui {
virtual void draw(const GfxContext* pctx, Assets* assets) override; virtual void draw(const GfxContext* pctx, Assets* assets) override;
virtual Label* textSupplier(wstringsupplier supplier); virtual Label* textSupplier(wstringsupplier supplier);
virtual void setSize(glm::vec2 size) override;
}; };
class Image : public UINode { class Image : public UINode {
@@ -55,15 +56,17 @@ namespace gui {
class Button : public Panel { class Button : public Panel {
protected: protected:
glm::vec4 hoverColor {0.05f, 0.1f, 0.15f, 0.75f};
glm::vec4 pressedColor {0.0f, 0.0f, 0.0f, 0.95f}; glm::vec4 pressedColor {0.0f, 0.0f, 0.0f, 0.95f};
std::vector<onaction> actions; std::vector<onaction> actions;
std::shared_ptr<Label> label = nullptr; std::shared_ptr<Label> label = nullptr;
public: public:
Button(std::shared_ptr<UINode> content, glm::vec4 padding=glm::vec4(2.0f)); Button(std::shared_ptr<UINode> content,
glm::vec4 padding=glm::vec4(2.0f));
Button(std::wstring text, Button(std::wstring text,
glm::vec4 padding=glm::vec4(2.0f), glm::vec4 padding,
glm::vec4 margin=glm::vec4(1.0f)); onaction action,
glm::vec2 size=glm::vec2(-1));
virtual void drawBackground(const GfxContext* pctx, Assets* assets) override; virtual void drawBackground(const GfxContext* pctx, Assets* assets) override;
@@ -79,12 +82,11 @@ namespace gui {
virtual Button* textSupplier(wstringsupplier supplier); virtual Button* textSupplier(wstringsupplier supplier);
virtual void setHoverColor(glm::vec4 color); virtual void refresh() override;
}; };
class RichButton : public Container { class RichButton : public Container {
protected: protected:
glm::vec4 hoverColor {0.05f, 0.1f, 0.15f, 0.75f};
glm::vec4 pressedColor {0.0f, 0.0f, 0.0f, 0.95f}; glm::vec4 pressedColor {0.0f, 0.0f, 0.0f, 0.95f};
std::vector<onaction> actions; std::vector<onaction> actions;
public: public:
@@ -94,13 +96,10 @@ namespace gui {
virtual void mouseRelease(GUI*, int x, int y) override; virtual void mouseRelease(GUI*, int x, int y) override;
virtual RichButton* listenAction(onaction action); virtual RichButton* listenAction(onaction action);
virtual void setHoverColor(glm::vec4 color);
}; };
class TextBox : public Panel { class TextBox : public Panel {
protected: protected:
glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f};
glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f}; glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f};
glm::vec4 invalidColor {0.1f, 0.05f, 0.03f, 1.0f}; glm::vec4 invalidColor {0.1f, 0.05f, 0.03f, 1.0f};
std::shared_ptr<Label> label; std::shared_ptr<Label> label;
@@ -113,7 +112,7 @@ namespace gui {
bool valid = true; bool valid = true;
public: public:
TextBox(std::wstring placeholder, TextBox(std::wstring placeholder,
glm::vec4 padding=glm::vec4(2.0f)); glm::vec4 padding=glm::vec4(4.0f));
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override; virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
@@ -137,7 +136,7 @@ namespace gui {
protected: protected:
glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f}; glm::vec4 hoverColor {0.05f, 0.1f, 0.2f, 0.75f};
glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f}; glm::vec4 focusedColor {0.0f, 0.0f, 0.0f, 1.0f};
Label* label; std::shared_ptr<Label> label;
Binding& binding; Binding& binding;
public: public:
InputBindBox(Binding& binding, glm::vec4 padding=glm::vec4(6.0f)); InputBindBox(Binding& binding, glm::vec4 padding=glm::vec4(6.0f));
+42 -31
View File
@@ -5,30 +5,34 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "../locale/langs.h" #include "../locale/langs.h"
#include "../../delegates.h"
using namespace gui; using namespace gui;
using glm::vec2; using glm::vec2;
using glm::vec4; using glm::vec4;
Button* guiutil::backButton(PagesControl* menu) { std::shared_ptr<Button> guiutil::backButton(std::shared_ptr<PagesControl> menu) {
return (new Button(langs::get(L"Back"), vec4(10.f)))->listenAction([=](GUI* gui) { return std::make_shared<Button>(
menu->back(); langs::get(L"Back"), vec4(10.f), [=](GUI*) {
}); menu->back();
}
);
} }
Button* guiutil::gotoButton( std::shared_ptr<Button> guiutil::gotoButton(
std::wstring text, std::wstring text,
const std::string& page, const std::string& page,
PagesControl* menu) { std::shared_ptr<PagesControl> menu
) {
text = langs::get(text, L"menu"); text = langs::get(text, L"menu");
return (new Button(text, vec4(10.f)))->listenAction([=](GUI* gui) { return std::make_shared<Button>(text, vec4(10.f), [=](GUI* gui) {
menu->set(page); menu->setPage(page);
}); });
} }
void guiutil::alert(GUI* gui, const std::wstring& text, gui::runnable on_hidden) { void guiutil::alert(GUI* gui, const std::wstring& text, runnable on_hidden) {
PagesControl* menu = gui->getMenu(); auto menu = gui->getMenu();
Panel* panel = new Panel(vec2(500, 200), vec4(8.0f), 8.0f); auto panel = std::make_shared<Panel>(vec2(500, 200), vec4(8.0f), 8.0f);
panel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.5f)); panel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.5f));
// TODO: implement built-in text wrapping // TODO: implement built-in text wrapping
@@ -43,48 +47,55 @@ void guiutil::alert(GUI* gui, const std::wstring& text, gui::runnable on_hidden)
} }
extra = std::min(extra, wrap_length); extra = std::min(extra, wrap_length);
std::wstring part = text.substr(offset, extra); std::wstring part = text.substr(offset, extra);
panel->add(new Label(part)); panel->add(std::make_shared<Label>(part));
offset += extra; offset += extra;
} }
} else { } else {
panel->add(new Label(text)); panel->add(std::make_shared<Label>(text));
} }
panel->add((new Button(langs::get(L"Ok"), vec4(10.f)))->listenAction([=](GUI* gui) { panel->add(std::make_shared<Button>(
if (on_hidden) langs::get(L"Ok"), vec4(10.f),
on_hidden(); [=](GUI* gui) {
menu->back(); if (on_hidden) {
})); on_hidden();
}
menu->back();
}
));
panel->refresh(); panel->refresh();
menu->add("<alert>", panel); menu->addPage("<alert>", panel);
menu->set("<alert>"); menu->setPage("<alert>");
} }
void guiutil::confirm( void guiutil::confirm(
GUI* gui, GUI* gui,
const std::wstring& text, const std::wstring& text,
gui::runnable on_confirm, runnable on_confirm,
std::wstring yestext, std::wstring yestext,
std::wstring notext) { std::wstring notext) {
if (yestext.empty()) yestext = langs::get(L"Yes"); if (yestext.empty()) yestext = langs::get(L"Yes");
if (notext.empty()) notext = langs::get(L"No"); if (notext.empty()) notext = langs::get(L"No");
PagesControl* menu = gui->getMenu(); auto menu = gui->getMenu();
Panel* panel = new Panel(vec2(600, 200), vec4(8.0f), 8.0f); auto panel = std::make_shared<Panel>(vec2(600, 200), vec4(8.0f), 8.0f);
panel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.5f)); panel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.5f));
panel->add(new Label(text)); panel->add(std::make_shared<Label>(text));
Panel* subpanel = new Panel(vec2(600, 53)); auto subpanel = std::make_shared<Panel>(vec2(600, 53));
subpanel->setColor(vec4(0)); subpanel->setColor(vec4(0));
subpanel->add((new Button(yestext, vec4(8.0f)))->listenAction([=](GUI*){
subpanel->add(std::make_shared<Button>(yestext, vec4(8.f), [=](GUI*){
if (on_confirm) if (on_confirm)
on_confirm(); on_confirm();
menu->back(); menu->back();
})); }));
subpanel->add((new Button(notext, vec4(8.0f)))->listenAction([=](GUI*){
subpanel->add(std::make_shared<Button>(notext, vec4(8.f), [=](GUI*){
menu->back(); menu->back();
})); }));
panel->add(subpanel); panel->add(subpanel);
panel->refresh(); panel->refresh();
menu->add("<confirm>", panel); menu->addPage("<confirm>", panel);
menu->set("<confirm>"); menu->setPage("<confirm>");
} }
+24 -5
View File
@@ -1,19 +1,38 @@
#ifndef FRONTEND_GUI_GUI_UTIL_H_ #ifndef FRONTEND_GUI_GUI_UTIL_H_
#define FRONTEND_GUI_GUI_UTIL_H_ #define FRONTEND_GUI_GUI_UTIL_H_
#include <memory>
#include <string> #include <string>
#include "GUI.h" #include "GUI.h"
#include "../../delegates.h"
namespace gui { namespace gui {
class Button; class Button;
} }
namespace guiutil { namespace guiutil {
gui::Button* backButton(gui::PagesControl* menu); std::shared_ptr<gui::Button> backButton(
gui::Button* gotoButton(std::wstring text, const std::string& page, gui::PagesControl* menu); std::shared_ptr<gui::PagesControl> menu
void alert(gui::GUI* gui, const std::wstring& text, gui::runnable on_hidden=nullptr); );
void confirm(gui::GUI* gui, const std::wstring& text, gui::runnable on_confirm=nullptr,
std::wstring yestext=L"", std::wstring notext=L""); std::shared_ptr<gui::Button> gotoButton(
std::wstring text,
const std::string& page,
std::shared_ptr<gui::PagesControl> menu
);
void alert(
gui::GUI* gui,
const std::wstring& text,
runnable on_hidden=nullptr
);
void confirm(
gui::GUI* gui,
const std::wstring& text,
runnable on_confirm=nullptr,
std::wstring yestext=L"",
std::wstring notext=L"");
} }
#endif // FRONTEND_GUI_GUI_UTIL_H_ #endif // FRONTEND_GUI_GUI_UTIL_H_
+56 -57
View File
@@ -14,6 +14,7 @@ using glm::vec4;
Container::Container(vec2 coord, vec2 size) : UINode(coord, size) { Container::Container(vec2 coord, vec2 size) : UINode(coord, size) {
actualLength = size.y; actualLength = size.y;
setColor(glm::vec4());
} }
std::shared_ptr<UINode> Container::getAt(vec2 pos, std::shared_ptr<UINode> self) { std::shared_ptr<UINode> Container::getAt(vec2 pos, std::shared_ptr<UINode> self) {
@@ -96,6 +97,17 @@ void Container::draw(const GfxContext* pctx, Assets* assets) {
} }
} }
void Container::drawBackground(const GfxContext* pctx, Assets* assets) {
if (color.a <= 0.0f)
return;
vec2 coord = calcCoord();
auto batch = pctx->getBatch2D();
batch->texture(nullptr);
batch->color = color;
batch->rect(coord.x, coord.y, size.x, size.y);
}
void Container::addBack(std::shared_ptr<UINode> node) { void Container::addBack(std::shared_ptr<UINode> node) {
nodes.insert(nodes.begin(), node); nodes.insert(nodes.begin(), node);
node->setParent(this); node->setParent(this);
@@ -108,10 +120,6 @@ void Container::add(std::shared_ptr<UINode> node) {
refresh(); refresh();
} }
void Container::add(UINode* node) {
add(std::shared_ptr<UINode>(node));
}
void Container::add(std::shared_ptr<UINode> node, glm::vec2 coord) { void Container::add(std::shared_ptr<UINode> node, glm::vec2 coord) {
node->setCoord(coord); node->setCoord(coord);
add(node); add(node);
@@ -131,71 +139,74 @@ void Container::listenInterval(float interval, ontimeout callback, int repeat) {
intervalEvents.push_back({callback, interval, 0.0f, repeat}); intervalEvents.push_back({callback, interval, 0.0f, repeat});
} }
Panel::Panel(vec2 size, glm::vec4 padding, float interval, bool resizing) void Container::setSize(glm::vec2 size) {
UINode::setSize(size);
refresh();
}
Panel::Panel(vec2 size, glm::vec4 padding, float interval)
: Container(vec2(), size), : Container(vec2(), size),
padding(padding), padding(padding),
interval(interval), interval(interval) {
resizing_(resizing) {
setColor(vec4(0.0f, 0.0f, 0.0f, 0.75f)); setColor(vec4(0.0f, 0.0f, 0.0f, 0.75f));
} }
Panel::~Panel() { Panel::~Panel() {
} }
void Panel::drawBackground(const GfxContext* pctx, Assets* assets) { void Panel::setMaxLength(int value) {
vec2 coord = calcCoord(); maxLength = value;
auto batch = pctx->getBatch2D();
batch->texture(nullptr);
batch->color = color;
batch->rect(coord.x, coord.y, size.x, size.y);
} }
void Panel::maxLength(int value) { int Panel::getMaxLength() const {
maxLength_ = value; return maxLength;
} }
int Panel::maxLength() const { void Panel::setPadding(glm::vec4 padding) {
return maxLength_; this->padding = padding;
refresh();
}
glm::vec4 Panel::getPadding() const {
return padding;
}
void Panel::cropToContent() {
if (maxLength > 0.0f) {
setSize(vec2(getSize().x, glm::min(maxLength, actualLength)));
} else {
setSize(vec2(getSize().x, actualLength));
}
}
void Panel::add(std::shared_ptr<UINode> node) {
Container::add(node);
refresh();
cropToContent();
} }
void Panel::refresh() { void Panel::refresh() {
float x = padding.x; float x = padding.x;
float y = padding.y; float y = padding.y;
vec2 size = getSize(); vec2 size = getSize();
if (orientation_ == Orientation::vertical) { if (orientation == Orientation::vertical) {
float maxw = size.x; float maxw = size.x;
for (auto& node : nodes) { for (auto& node : nodes) {
vec2 nodesize = node->getSize(); vec2 nodesize = node->getSize();
const vec4 margin = node->getMargin(); const vec4 margin = node->getMargin();
y += margin.y; y += margin.y;
float ex; float ex = x + margin.x;
float spacex = size.x - margin.z - padding.z;
switch (node->getAlign()) {
case Align::center:
ex = x + fmax(0.0f, spacex - nodesize.x) / 2.0f;
break;
case Align::right:
ex = x + spacex - nodesize.x;
break;
default:
ex = x + margin.x;
}
node->setCoord(vec2(ex, y)); node->setCoord(vec2(ex, y));
y += nodesize.y + margin.w + interval; y += nodesize.y + margin.w + interval;
float width = size.x - padding.x - padding.z - margin.x - margin.z; float width = size.x - padding.x - padding.z - margin.x - margin.z;
node->setSize(vec2(width, nodesize.y));; if (node->isResizing()) {
node->setSize(vec2(width, nodesize.y));
}
node->refresh(); node->refresh();
maxw = fmax(maxw, ex+node->getSize().x+margin.z+padding.z); maxw = fmax(maxw, ex+node->getSize().x+margin.z+padding.z);
} }
if (resizing_) {
if (maxLength_)
setSize(vec2(size.x, glm::min(maxLength_, (int)(y+padding.w))));
else
setSize(vec2(size.x, y+padding.w));
}
actualLength = y + padding.w; actualLength = y + padding.w;
} else { } else {
float maxh = size.y; float maxh = size.y;
@@ -206,27 +217,19 @@ void Panel::refresh() {
node->setCoord(vec2(x, y+margin.y)); node->setCoord(vec2(x, y+margin.y));
x += nodesize.x + margin.z + interval; x += nodesize.x + margin.z + interval;
float height = size.y - padding.y - padding.w - margin.y - margin.w;
node->setSize(vec2(nodesize.x, height));
node->refresh(); node->refresh();
maxh = fmax(maxh, y+margin.y+node->getSize().y+margin.w+padding.w); maxh = fmax(maxh, y+margin.y+node->getSize().y+margin.w+padding.w);
} }
if (resizing_) {
if (maxLength_)
setSize(vec2(glm::min(maxLength_, (int)(x+padding.z)), size.y));
else
setSize(vec2(x+padding.z, size.y));
}
actualLength = size.y; actualLength = size.y;
} }
} }
void Panel::orientation(Orientation orientation) { void Panel::setOrientation(Orientation orientation) {
this->orientation_ = orientation; this->orientation = orientation;
} }
Orientation Panel::orientation() const { Orientation Panel::getOrientation() const {
return orientation_; return orientation;
} }
PagesControl::PagesControl() : Container(vec2(), vec2(1)){ PagesControl::PagesControl() : Container(vec2(), vec2(1)){
@@ -236,15 +239,11 @@ bool PagesControl::has(std::string name) {
return pages.find(name) != pages.end(); return pages.find(name) != pages.end();
} }
void PagesControl::add(std::string name, std::shared_ptr<UINode> panel) { void PagesControl::addPage(std::string name, std::shared_ptr<UINode> panel) {
pages[name] = Page{panel}; pages[name] = Page{panel};
} }
void PagesControl::add(std::string name, UINode* panel) { void PagesControl::setPage(std::string name, bool history) {
add(name, std::shared_ptr<UINode>(panel));
}
void PagesControl::set(std::string name, bool history) {
auto found = pages.find(name); auto found = pages.find(name);
if (found == pages.end()) { if (found == pages.end()) {
throw std::runtime_error("no page found"); throw std::runtime_error("no page found");
@@ -266,7 +265,7 @@ void PagesControl::back() {
return; return;
std::string name = pageStack.top(); std::string name = pageStack.top();
pageStack.pop(); pageStack.pop();
set(name, false); setPage(name, false);
} }
Page& PagesControl::current() { Page& PagesControl::current() {
+23 -15
View File
@@ -12,7 +12,8 @@ class Batch2D;
class Assets; class Assets;
namespace gui { namespace gui {
typedef std::function<void()> ontimeout; using ontimeout = std::function<void()>;
struct IntervalEvent { struct IntervalEvent {
ontimeout callback; ontimeout callback;
float interval; float interval;
@@ -34,40 +35,48 @@ namespace gui {
Container(glm::vec2 coord, glm::vec2 size); Container(glm::vec2 coord, glm::vec2 size);
virtual void act(float delta) override; virtual void act(float delta) override;
virtual void drawBackground(const GfxContext* pctx, Assets* assets) {}; virtual void drawBackground(const GfxContext* pctx, Assets* assets);
virtual void draw(const GfxContext* pctx, Assets* assets) override; virtual void draw(const GfxContext* pctx, Assets* assets) override;
virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override; virtual std::shared_ptr<UINode> getAt(glm::vec2 pos, std::shared_ptr<UINode> self) override;
virtual void addBack(std::shared_ptr<UINode> node); virtual void addBack(std::shared_ptr<UINode> node);
virtual void add(std::shared_ptr<UINode> node); virtual void add(std::shared_ptr<UINode> node);
virtual void add(UINode* node);
virtual void add(std::shared_ptr<UINode> node, glm::vec2 coord); virtual void add(std::shared_ptr<UINode> node, glm::vec2 coord);
virtual void remove(std::shared_ptr<UINode> node); virtual void remove(std::shared_ptr<UINode> node);
virtual void scrolled(int value) override; virtual void scrolled(int value) override;
virtual void scrollable(bool flag); virtual void scrollable(bool flag);
void listenInterval(float interval, ontimeout callback, int repeat=-1); void listenInterval(float interval, ontimeout callback, int repeat=-1);
virtual glm::vec2 contentOffset() override {return glm::vec2(0.0f, scroll);}; virtual glm::vec2 contentOffset() override {return glm::vec2(0.0f, scroll);};
virtual void setSize(glm::vec2 size);
}; };
class Panel : public Container { class Panel : public Container {
protected: protected:
Orientation orientation_ = Orientation::vertical; Orientation orientation = Orientation::vertical;
glm::vec4 padding {2.0f}; glm::vec4 padding {2.0f};
float interval = 2.0f; float interval = 2.0f;
bool resizing_; int maxLength = 0;
int maxLength_ = 0;
public: public:
Panel(glm::vec2 size, glm::vec4 padding=glm::vec4(2.0f), float interval=2.0f, bool resizing=true); Panel(
glm::vec2 size,
glm::vec4 padding=glm::vec4(2.0f),
float interval=2.0f
);
virtual ~Panel(); virtual ~Panel();
virtual void drawBackground(const GfxContext* pctx, Assets* assets) override; virtual void cropToContent();
virtual void orientation(Orientation orientation); virtual void setOrientation(Orientation orientation);
Orientation orientation() const; Orientation getOrientation() const;
virtual void add(std::shared_ptr<UINode> node) override;
virtual void refresh() override; virtual void refresh() override;
virtual void maxLength(int value); virtual void setMaxLength(int value);
int maxLength() const; int getMaxLength() const;
virtual void setPadding(glm::vec4 padding);
glm::vec4 getPadding() const;
}; };
struct Page { struct Page {
@@ -88,9 +97,8 @@ namespace gui {
PagesControl(); PagesControl();
bool has(std::string name); bool has(std::string name);
void set(std::string name, bool history=true); void setPage(std::string name, bool history=true);
void add(std::string name, std::shared_ptr<UINode> panel); void addPage(std::string name, std::shared_ptr<UINode> panel);
void add(std::string name, UINode* panel);
void back(); void back();
void clearHistory(); void clearHistory();
void reset(); void reset();
+12 -10
View File
@@ -60,7 +60,7 @@ static std::shared_ptr<Label> create_label(gui::wstringsupplier supplier) {
std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) { std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) {
auto level = frontend->getLevel(); auto level = frontend->getLevel();
auto panel = std::make_shared<Panel>(vec2(250, 200), vec4(5.0f), 1.0f); auto panel = std::make_shared<Panel>(vec2(250, 200), vec4(5.0f), 2.0f);
panel->listenInterval(0.5f, [this]() { panel->listenInterval(0.5f, [this]() {
fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin); fpsString = std::to_wstring(fpsMax)+L" / "+std::to_wstring(fpsMin);
fpsMin = fps; fpsMin = fps;
@@ -68,7 +68,7 @@ std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) {
}); });
panel->setCoord(vec2(10, 10)); panel->setCoord(vec2(10, 10));
panel->add(create_label([this](){ return L"fps: "+this->fpsString;})); panel->add(create_label([this](){ return L"fps: "+this->fpsString;}));
panel->add(create_label([this](){ panel->add(create_label([](){
return L"meshes: " + std::to_wstring(Mesh::meshesCount); return L"meshes: " + std::to_wstring(Mesh::meshesCount);
})); }));
panel->add(create_label([=](){ panel->add(create_label([=](){
@@ -97,18 +97,18 @@ std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) {
})); }));
for (int ax = 0; ax < 3; ax++){ for (int ax = 0; ax < 3; ax++){
Panel* sub = new Panel(vec2(10, 27), vec4(0.0f)); auto sub = std::make_shared<Panel>(vec2(10, 27), vec4(0.0f));
sub->orientation(Orientation::horizontal); sub->setOrientation(Orientation::horizontal);
std::wstring str = L"x: "; std::wstring str = L"x: ";
str[0] += ax; str[0] += ax;
Label* label = new Label(str); auto label = std::make_shared<Label>(str);
label->setMargin(vec4(2, 3, 2, 3)); label->setMargin(vec4(2, 3, 2, 3));
sub->add(label); sub->add(label);
sub->setColor(vec4(0.0f)); sub->setColor(vec4(0.0f));
// Coord input // Coord input
TextBox* box = new TextBox(L""); auto box = std::make_shared<TextBox>(L"");
box->textSupplier([=]() { box->textSupplier([=]() {
Hitbox* hitbox = level->player->hitbox.get(); Hitbox* hitbox = level->player->hitbox.get();
return util::to_wstring(hitbox->position[ax], 2); return util::to_wstring(hitbox->position[ax], 2);
@@ -139,19 +139,21 @@ std::shared_ptr<UINode> HudRenderer::createDebugPanel(Engine* engine) {
return L"time: "+timeString; return L"time: "+timeString;
})); }));
{ {
TrackBar* bar = new TrackBar(0.0f, 1.0f, 1.0f, 0.005f, 8); auto bar = std::make_shared<TrackBar>(0.0f, 1.0f, 1.0f, 0.005f, 8);
bar->supplier([=]() {return level->world->daytime;}); bar->supplier([=]() {return level->world->daytime;});
bar->consumer([=](double val) {level->world->daytime = val;}); bar->consumer([=](double val) {level->world->daytime = val;});
panel->add(bar); panel->add(bar);
} }
{ {
TrackBar* bar = new TrackBar(0.0f, 1.0f, 0.0f, 0.005f, 8); auto bar = std::make_shared<TrackBar>(0.0f, 1.0f, 0.0f, 0.005f, 8);
bar->supplier([=]() {return WorldRenderer::fog;}); bar->supplier([=]() {return WorldRenderer::fog;});
bar->consumer([=](double val) {WorldRenderer::fog = val;}); bar->consumer([=](double val) {WorldRenderer::fog = val;});
panel->add(bar); panel->add(bar);
} }
{ {
auto checkbox = new FullCheckBox(L"Show Chunk Borders", vec2(400, 32)); auto checkbox = std::make_shared<FullCheckBox>(
L"Show Chunk Borders", vec2(400, 24)
);
checkbox->supplier([=]() { checkbox->supplier([=]() {
return engine->getSettings().debug.showChunkBorders; return engine->getSettings().debug.showChunkBorders;
}); });
@@ -334,7 +336,7 @@ void HudRenderer::update(bool visible) {
closeInventory(); closeInventory();
} else { } else {
pause = true; pause = true;
menu->set("pause"); menu->setPage("pause");
} }
} }
if (visible && Events::jactive(BIND_HUD_INVENTORY)) { if (visible && Events::jactive(BIND_HUD_INVENTORY)) {
+145 -118
View File
@@ -37,6 +37,8 @@ using glm::vec4;
namespace fs = std::filesystem; namespace fs = std::filesystem;
using namespace gui; using namespace gui;
const int PACKS_PANEL_WIDTH = 550;
inline uint64_t randU64() { inline uint64_t randU64() {
srand(time(NULL)); srand(time(NULL));
return rand() ^ (rand() << 8) ^ return rand() ^ (rand() << 8) ^
@@ -46,74 +48,87 @@ inline uint64_t randU64() {
((uint64_t)rand() << 56); ((uint64_t)rand() << 56);
} }
std::shared_ptr<Panel> create_page( static std::shared_ptr<Label> create_label(gui::wstringsupplier supplier) {
Engine* engine, auto label = std::make_shared<Label>(L"-");
std::string name, label->textSupplier(supplier);
int width, return label;
float opacity, }
int interval) {
PagesControl* menu = engine->getGUI()->getMenu(); static std::shared_ptr<Panel> create_page(
Engine* engine,
std::string name,
int width,
float opacity,
int interval
) {
auto menu = engine->getGUI()->getMenu();
auto panel = std::make_shared<Panel>( auto panel = std::make_shared<Panel>(
vec2(width, 200), vec4(8.0f), interval vec2(width, 200), vec4(8.0f), interval
); );
panel->setColor(vec4(0.0f, 0.0f, 0.0f, opacity)); panel->setColor(vec4(0.0f, 0.0f, 0.0f, opacity));
menu->add(name, panel); menu->addPage(name, panel);
return panel; return panel;
} }
Button* create_button(std::wstring text, static std::shared_ptr<Button> create_button(
glm::vec4 padding, std::wstring text,
glm::vec4 margin, vec4 padding,
gui::onaction action) { vec4 margin,
gui::onaction action
auto btn = new Button(langs::get(text, L"menu"), ) {
padding, margin); auto btn = std::make_shared<Button>(
btn->listenAction(action); langs::get(text, L"menu"), padding, action
);
btn->setMargin(margin);
return btn; return btn;
} }
void show_content_missing(Engine* engine, const Content* content, static void show_content_missing(
std::shared_ptr<ContentLUT> lut) { Engine* engine,
const Content* content,
std::shared_ptr<ContentLUT> lut
) {
auto* gui = engine->getGUI(); auto* gui = engine->getGUI();
auto* menu = gui->getMenu(); auto menu = gui->getMenu();
auto panel = create_page(engine, "missing-content", 500, 0.5f, 8); auto panel = create_page(engine, "missing-content", 500, 0.5f, 8);
panel->add(new Label(langs::get(L"menu.missing-content"))); panel->add(std::make_shared<Label>(langs::get(L"menu.missing-content")));
Panel* subpanel = new Panel(vec2(500, 100)); auto subpanel = std::make_shared<Panel>(vec2(500, 100));
subpanel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.5f)); subpanel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.5f));
for (auto& entry : lut->getMissingContent()) { for (auto& entry : lut->getMissingContent()) {
Panel* hpanel = new Panel(vec2(500, 30)); auto hpanel = std::make_shared<Panel>(vec2(500, 30));
hpanel->setColor(vec4(0.0f)); hpanel->setColor(vec4(0.0f));
hpanel->orientation(Orientation::horizontal); hpanel->setOrientation(Orientation::horizontal);
Label* namelabel = new Label(util::str2wstr_utf8(entry.name)); auto namelabel = std::make_shared<Label>(util::str2wstr_utf8(entry.name));
namelabel->setColor(vec4(1.0f, 0.2f, 0.2f, 0.5f)); namelabel->setColor(vec4(1.0f, 0.2f, 0.2f, 0.5f));
auto contentname = util::str2wstr_utf8(contenttype_name(entry.type)); auto contentname = util::str2wstr_utf8(contenttype_name(entry.type));
Label* typelabel = new Label(L"["+contentname+L"]"); auto typelabel = std::make_shared<Label>(L"["+contentname+L"]");
typelabel->setColor(vec4(0.5f)); typelabel->setColor(vec4(0.5f));
hpanel->add(typelabel); hpanel->add(typelabel);
hpanel->add(namelabel); hpanel->add(namelabel);
subpanel->add(hpanel); subpanel->add(hpanel);
} }
subpanel->maxLength(400); subpanel->setMaxLength(400);
panel->add(subpanel); panel->add(subpanel);
panel->add((new Button(langs::get(L"Back to Main Menu", L"menu"), panel->add(std::make_shared<Button>(
vec4(8.0f))) langs::get(L"Back to Main Menu", L"menu"), vec4(8.0f), [=](GUI*){
->listenAction([=](GUI*){ menu->back();
menu->back(); }
})); ));
menu->set("missing-content"); menu->setPage("missing-content");
} }
void show_convert_request( void show_convert_request(
Engine* engine, Engine* engine,
const Content* content, const Content* content,
std::shared_ptr<ContentLUT> lut, std::shared_ptr<ContentLUT> lut,
fs::path folder) { fs::path folder
) {
guiutil::confirm(engine->getGUI(), langs::get(L"world.convert-request"), guiutil::confirm(engine->getGUI(), langs::get(L"world.convert-request"),
[=]() { [=]() {
// TODO: add multithreading here // TODO: add multithreading here
@@ -125,7 +140,8 @@ void show_convert_request(
}, L"", langs::get(L"Cancel")); }, L"", langs::get(L"Cancel"));
} }
void create_languages_panel(Engine* engine, PagesControl* menu) { void create_languages_panel(Engine* engine) {
auto menu = engine->getGUI()->getMenu();
auto panel = create_page(engine, "languages", 400, 0.5f, 1); auto panel = create_page(engine, "languages", 400, 0.5f, 1);
panel->scrollable(true); panel->scrollable(true);
@@ -138,11 +154,14 @@ void create_languages_panel(Engine* engine, PagesControl* menu) {
auto& locale = langs::locales_info.at(name); auto& locale = langs::locales_info.at(name);
std::string& fullName = locale.name; std::string& fullName = locale.name;
Button* button = new Button(util::str2wstr_utf8(fullName), vec4(10.f)); auto button = std::make_shared<Button>(
button->listenAction([=](GUI*) { util::str2wstr_utf8(fullName),
engine->setLanguage(name); vec4(10.f),
menu->back(); [=](GUI*) {
}); engine->setLanguage(name);
menu->back();
}
);
panel->add(button); panel->add(button);
} }
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(menu));
@@ -191,10 +210,10 @@ void open_world(std::string name, Engine* engine) {
} }
} }
Panel* create_worlds_panel(Engine* engine) { std::shared_ptr<Panel> create_worlds_panel(Engine* engine) {
auto panel = new Panel(vec2(390, 200), vec4(5.0f)); auto panel = std::make_shared<Panel>(vec2(390, 200), vec4(5.0f));
panel->setColor(vec4(1.0f, 1.0f, 1.0f, 0.07f)); panel->setColor(vec4(1.0f, 1.0f, 1.0f, 0.07f));
panel->maxLength(400); panel->setMaxLength(400);
auto paths = engine->getPaths(); auto paths = engine->getPaths();
@@ -205,13 +224,10 @@ Panel* create_worlds_panel(Engine* engine) {
auto btn = std::make_shared<RichButton>(vec2(390, 46)); auto btn = std::make_shared<RichButton>(vec2(390, 46));
btn->setColor(vec4(1.0f, 1.0f, 1.0f, 0.1f)); btn->setColor(vec4(1.0f, 1.0f, 1.0f, 0.1f));
btn->setHoverColor(vec4(1.0f, 1.0f, 1.0f, 0.17f)); btn->setHoverColor(vec4(1.0f, 1.0f, 1.0f, 0.17f));
auto label = std::make_shared<Label>(namews);
label->setInteractive(false);
btn->add(label, vec2(8, 8));
btn->listenAction([=](GUI*) { btn->listenAction([=](GUI*) {
open_world(name, engine); open_world(name, engine);
}); });
btn->add(std::make_shared<Label>(namews), vec2(8, 8));
auto image = std::make_shared<Image>("gui/delete_icon", vec2(32, 32)); auto image = std::make_shared<Image>("gui/delete_icon", vec2(32, 32));
image->setColor(vec4(1, 1, 1, 0.5f)); image->setColor(vec4(1, 1, 1, 0.5f));
@@ -219,49 +235,49 @@ Panel* create_worlds_panel(Engine* engine) {
auto delbtn = std::make_shared<Button>(image, vec4(2)); auto delbtn = std::make_shared<Button>(image, vec4(2));
delbtn->setColor(vec4(0.0f)); delbtn->setColor(vec4(0.0f));
delbtn->setHoverColor(vec4(1.0f, 1.0f, 1.0f, 0.17f)); delbtn->setHoverColor(vec4(1.0f, 1.0f, 1.0f, 0.17f));
btn->add(delbtn, vec2(330, 3));
delbtn->listenAction([=](GUI* gui) { delbtn->listenAction([=](GUI* gui) {
guiutil::confirm(gui, langs::get(L"delete-confirm", L"world")+ guiutil::confirm(gui, langs::get(L"delete-confirm", L"world")+
L" ("+util::str2wstr_utf8(folder.u8string())+L")", [=]() L" ("+util::str2wstr_utf8(folder.u8string())+L")", [=]()
{ {
std::cout << "deleting " << folder.u8string() << std::endl; std::cout << "deleting " << folder.u8string() << std::endl;
fs::remove_all(folder); fs::remove_all(folder);
menus::refresh_menus(engine, gui->getMenu()); menus::refresh_menus(engine);
}); });
}); });
btn->add(delbtn, vec2(330, 3));
panel->add(btn); panel->add(btn);
} }
return panel; return panel;
} }
void create_main_menu_panel(Engine* engine, PagesControl* menu) { void create_main_menu_panel(Engine* engine) {
auto menu = engine->getGUI()->getMenu();
auto panel = create_page(engine, "main", 400, 0.0f, 1); auto panel = create_page(engine, "main", 400, 0.0f, 1);
panel->add(guiutil::gotoButton(L"New World", "new-world", menu)); panel->add(guiutil::gotoButton(L"New World", "new-world", menu));
panel->add(create_worlds_panel(engine)); panel->add(create_worlds_panel(engine));
panel->add(guiutil::gotoButton(L"Settings", "settings", menu)); panel->add(guiutil::gotoButton(L"Settings", "settings", menu));
panel->add((new Button(langs::get(L"Quit", L"menu"), vec4(10.f)))
->listenAction([](GUI* gui) { panel->add(std::make_shared<Button>(
Window::setShouldClose(true); langs::get(L"Quit", L"menu"), vec4(10.f), [](GUI*) {
})); Window::setShouldClose(true);
}
));
} }
typedef std::function<void(const ContentPack& pack)> packconsumer; typedef std::function<void(const ContentPack& pack)> packconsumer;
const int PACKS_PANEL_WIDTH = 550;
std::shared_ptr<Panel> create_packs_panel( std::shared_ptr<Panel> create_packs_panel(
const std::vector<ContentPack>& packs, const std::vector<ContentPack>& packs,
Engine* engine, Engine* engine,
bool backbutton, bool backbutton,
packconsumer callback) packconsumer callback
{ ){
auto assets = engine->getAssets(); auto assets = engine->getAssets();
auto panel = std::make_shared<Panel>(vec2(PACKS_PANEL_WIDTH, 200), vec4(5.0f)); auto panel = std::make_shared<Panel>(vec2(PACKS_PANEL_WIDTH, 200), vec4(5.0f));
panel->setColor(vec4(1.0f, 1.0f, 1.0f, 0.07f)); panel->setColor(vec4(1.0f, 1.0f, 1.0f, 0.07f));
panel->maxLength(400); panel->setMaxLength(400);
panel->scrollable(true); panel->scrollable(true);
for (auto& pack : packs) { for (auto& pack : packs) {
@@ -298,7 +314,7 @@ std::shared_ptr<Panel> create_packs_panel(
descriptionlabel->setColor(vec4(1, 1, 1, 0.7f)); descriptionlabel->setColor(vec4(1, 1, 1, 0.7f));
packpanel->add(descriptionlabel, vec2(80, 28)); packpanel->add(descriptionlabel, vec2(80, 28));
packpanel->add(std::make_shared<Image>(icon, glm::vec2(64)), vec2(8)); packpanel->add(std::make_shared<Image>(icon, vec2(64)), vec2(8));
packpanel->setColor(vec4(0.06f, 0.12f, 0.18f, 0.7f)); packpanel->setColor(vec4(0.06f, 0.12f, 0.18f, 0.7f));
panel->add(packpanel); panel->add(packpanel);
@@ -310,7 +326,8 @@ std::shared_ptr<Panel> create_packs_panel(
} }
// TODO: refactor // TODO: refactor
void create_content_panel(Engine* engine, PagesControl* menu) { void create_content_panel(Engine* engine) {
auto menu = engine->getGUI()->getMenu();
auto paths = engine->getPaths(); auto paths = engine->getPaths();
auto mainPanel = create_page(engine, "content", PACKS_PANEL_WIDTH, 0.0f, 5); auto mainPanel = create_page(engine, "content", PACKS_PANEL_WIDTH, 0.0f, 5);
@@ -355,8 +372,8 @@ void create_content_panel(Engine* engine, PagesControl* menu) {
engine->setScreen(std::make_shared<MenuScreen>(engine)); engine->setScreen(std::make_shared<MenuScreen>(engine));
open_world(wname, engine); open_world(wname, engine);
}); });
menu->add("content-packs", panel); menu->addPage("content-packs", panel);
menu->set("content-packs"); menu->setPage("content-packs");
})); }));
mainPanel->add(guiutil::backButton(menu)); mainPanel->add(guiutil::backButton(menu));
} }
@@ -375,7 +392,7 @@ inline uint64_t str2seed(std::wstring seedstr) {
} }
} }
void create_new_world_panel(Engine* engine, PagesControl* menu) { void create_new_world_panel(Engine* engine) {
auto panel = create_page(engine, "new-world", 400, 0.0f, 1); auto panel = create_page(engine, "new-world", 400, 0.0f, 1);
panel->add(std::make_shared<Label>(langs::get(L"Name", L"world"))); panel->add(std::make_shared<Label>(langs::get(L"Name", L"world")));
@@ -398,54 +415,59 @@ void create_new_world_panel(Engine* engine, PagesControl* menu) {
if (!nameInput->validate()) if (!nameInput->validate())
return; return;
std::wstring name = nameInput->text(); std::string name = util::wstr2str_utf8(nameInput->text());
std::string nameutf8 = util::wstr2str_utf8(name); uint64_t seed = str2seed(seedInput->text());
EnginePaths* paths = engine->getPaths();
std::wstring seedstr = seedInput->text();
uint64_t seed = str2seed(seedstr);
std::cout << "world seed: " << seed << std::endl; std::cout << "world seed: " << seed << std::endl;
auto folder = paths->getWorldsFolder()/fs::u8path(nameutf8); EnginePaths* paths = engine->getPaths();
auto folder = paths->getWorldsFolder()/fs::u8path(name);
try { try {
engine->loadAllPacks(); engine->loadAllPacks();
engine->loadContent(); engine->loadContent();
paths->setWorldFolder(folder); paths->setWorldFolder(folder);
} catch (const contentpack_error& error) { } catch (const contentpack_error& error) {
guiutil::alert(engine->getGUI(), guiutil::alert(
langs::get(L"Content Error", L"menu")+ engine->getGUI(),
L":\n"+util::str2wstr_utf8(std::string(error.what())+ langs::get(L"Content Error", L"menu")+L":\n"+
"\npack '"+error.getPackId()+"' from "+ util::str2wstr_utf8(
error.getFolder().u8string())); std::string(error.what())+
"\npack '"+error.getPackId()+"' from "+
error.getFolder().u8string()
)
);
return; return;
} catch (const std::runtime_error& error) { } catch (const std::runtime_error& error) {
guiutil::alert(engine->getGUI(), guiutil::alert(
langs::get(L"Content Error", L"menu")+ engine->getGUI(),
L": "+util::str2wstr_utf8(error.what())); langs::get(L"Content Error", L"menu")+
L": "+util::str2wstr_utf8(error.what())
);
return; return;
} }
Level* level = World::create( Level* level = World::create(
nameutf8, folder, seed, name, folder, seed,
engine->getSettings(), engine->getSettings(),
engine->getContent(), engine->getContent(),
engine->getContentPacks()); engine->getContentPacks()
);
engine->setScreen(std::make_shared<LevelScreen>(engine, level)); engine->setScreen(std::make_shared<LevelScreen>(engine, level));
})); }));
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(engine->getGUI()->getMenu()));
} }
void create_controls_panel(Engine* engine, PagesControl* menu) { void create_controls_panel(Engine* engine) {
auto menu = engine->getGUI()->getMenu();
auto panel = create_page(engine, "controls", 400, 0.0f, 1); auto panel = create_page(engine, "controls", 400, 0.0f, 1);
/* Camera sensitivity setting track bar */{ /* Camera sensitivity setting track bar */{
panel->add((new Label(L""))->textSupplier([=]() { panel->add(create_label([=]() {
float s = engine->getSettings().camera.sensitivity; float s = engine->getSettings().camera.sensitivity;
return langs::get(L"Mouse Sensitivity", L"settings")+L": "+ return langs::get(L"Mouse Sensitivity", L"settings")+L": "+
util::to_wstring(s, 1); util::to_wstring(s, 1);
})); }));
TrackBar* trackbar = new TrackBar(0.1, 10.0, 2.0, 0.1, 4); auto trackbar = std::make_shared<TrackBar>(0.1, 10.0, 2.0, 0.1, 4);
trackbar->supplier([=]() { trackbar->supplier([=]() {
return engine->getSettings().camera.sensitivity; return engine->getSettings().camera.sensitivity;
}); });
@@ -455,19 +477,18 @@ void create_controls_panel(Engine* engine, PagesControl* menu) {
panel->add(trackbar); panel->add(trackbar);
} }
Panel* scrollPanel = new Panel(vec2(400, 200), vec4(2.0f), 1.0f); auto scrollPanel = std::make_shared<Panel>(vec2(400, 200), vec4(2.0f), 1.0f);
scrollPanel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.3f)); scrollPanel->setColor(vec4(0.0f, 0.0f, 0.0f, 0.3f));
scrollPanel->maxLength(400); scrollPanel->setMaxLength(400);
for (auto& entry : Events::bindings){ for (auto& entry : Events::bindings){
std::string bindname = entry.first; std::string bindname = entry.first;
Panel* subpanel = new Panel(vec2(400, 40), vec4(5.0f), 1.0f); auto subpanel = std::make_shared<Panel>(vec2(400, 40), vec4(5.0f), 1.0f);
subpanel->setColor(vec4(0.0f)); subpanel->setColor(vec4(0.0f));
subpanel->orientation(Orientation::horizontal); subpanel->setOrientation(Orientation::horizontal);
subpanel->add(std::make_shared<InputBindBox>(entry.second));
InputBindBox* bindbox = new InputBindBox(entry.second); auto label = std::make_shared<Label>(langs::get(util::str2wstr_utf8(bindname)));
subpanel->add(bindbox);
Label* label = new Label(langs::get(util::str2wstr_utf8(bindname)));
label->setMargin(vec4(6.0f)); label->setMargin(vec4(6.0f));
subpanel->add(label); subpanel->add(label);
scrollPanel->add(subpanel); scrollPanel->add(subpanel);
@@ -476,16 +497,17 @@ void create_controls_panel(Engine* engine, PagesControl* menu) {
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(menu));
} }
void create_settings_panel(Engine* engine, PagesControl* menu) { void create_settings_panel(Engine* engine) {
auto menu = engine->getGUI()->getMenu();
auto panel = create_page(engine, "settings", 400, 0.0f, 1); auto panel = create_page(engine, "settings", 400, 0.0f, 1);
/* Load Distance setting track bar */{ /* Load Distance setting track bar */{
panel->add((new Label(L""))->textSupplier([=]() { panel->add(create_label([=]() {
return langs::get(L"Load Distance", L"settings")+L": " + return langs::get(L"Load Distance", L"settings")+L": " +
std::to_wstring(engine->getSettings().chunks.loadDistance); std::to_wstring(engine->getSettings().chunks.loadDistance);
})); }));
TrackBar* trackbar = new TrackBar(3, 66, 10, 1, 3); auto trackbar = std::make_shared<TrackBar>(3, 66, 10, 1, 3);
trackbar->supplier([=]() { trackbar->supplier([=]() {
return engine->getSettings().chunks.loadDistance; return engine->getSettings().chunks.loadDistance;
}); });
@@ -496,12 +518,12 @@ void create_settings_panel(Engine* engine, PagesControl* menu) {
} }
/* Load Speed setting track bar */{ /* Load Speed setting track bar */{
panel->add((new Label(L""))->textSupplier([=]() { panel->add(create_label([=]() {
return langs::get(L"Load Speed", L"settings")+L": " + return langs::get(L"Load Speed", L"settings")+L": " +
std::to_wstring(engine->getSettings().chunks.loadSpeed); std::to_wstring(engine->getSettings().chunks.loadSpeed);
})); }));
TrackBar* trackbar = new TrackBar(1, 32, 10, 1, 1); auto trackbar = std::make_shared<TrackBar>(1, 32, 10, 1, 1);
trackbar->supplier([=]() { trackbar->supplier([=]() {
return engine->getSettings().chunks.loadSpeed; return engine->getSettings().chunks.loadSpeed;
}); });
@@ -512,13 +534,13 @@ void create_settings_panel(Engine* engine, PagesControl* menu) {
} }
/* Fog Curve setting track bar */{ /* Fog Curve setting track bar */{
panel->add((new Label(L""))->textSupplier([=]() { panel->add(create_label([=]() {
float value = engine->getSettings().graphics.fogCurve; float value = engine->getSettings().graphics.fogCurve;
return langs::get(L"Fog Curve", L"settings")+L": " + return langs::get(L"Fog Curve", L"settings")+L": " +
util::to_wstring(value, 1); util::to_wstring(value, 1);
})); }));
TrackBar* trackbar = new TrackBar(1.0, 6.0, 1.0, 0.1, 2); auto trackbar = std::make_shared<TrackBar>(1.0, 6.0, 1.0, 0.1, 2);
trackbar->supplier([=]() { trackbar->supplier([=]() {
return engine->getSettings().graphics.fogCurve; return engine->getSettings().graphics.fogCurve;
}); });
@@ -529,12 +551,12 @@ void create_settings_panel(Engine* engine, PagesControl* menu) {
} }
/* Fov setting track bar */{ /* Fov setting track bar */{
panel->add((new Label(L""))->textSupplier([=]() { panel->add(create_label([=]() {
int fov = (int)engine->getSettings().camera.fov; int fov = (int)engine->getSettings().camera.fov;
return langs::get(L"FOV", L"settings")+L": "+std::to_wstring(fov)+L"°"; return langs::get(L"FOV", L"settings")+L": "+std::to_wstring(fov)+L"°";
})); }));
TrackBar* trackbar = new TrackBar(30.0, 120.0, 90, 1, 4); auto trackbar = std::make_shared<TrackBar>(30.0, 120.0, 90, 1, 4);
trackbar->supplier([=]() { trackbar->supplier([=]() {
return engine->getSettings().camera.fov; return engine->getSettings().camera.fov;
}); });
@@ -545,7 +567,9 @@ void create_settings_panel(Engine* engine, PagesControl* menu) {
} }
/* V-Sync checkbox */{ /* V-Sync checkbox */{
auto checkbox = new FullCheckBox(langs::get(L"V-Sync", L"settings"), vec2(400, 32)); auto checkbox = std::make_shared<FullCheckBox>(
langs::get(L"V-Sync", L"settings"), vec2(400, 32)
);
checkbox->supplier([=]() { checkbox->supplier([=]() {
return engine->getSettings().display.swapInterval != 0; return engine->getSettings().display.swapInterval != 0;
}); });
@@ -556,9 +580,11 @@ void create_settings_panel(Engine* engine, PagesControl* menu) {
} }
/* Backlight checkbox */{ /* Backlight checkbox */{
auto checkbox = new FullCheckBox(langs::get(L"Backlight", L"settings"), vec2(400, 32)); auto checkbox = std::make_shared<FullCheckBox>(
langs::get(L"Backlight", L"settings"), vec2(400, 32)
);
checkbox->supplier([=]() { checkbox->supplier([=]() {
return engine->getSettings().graphics.backlight != 0; return engine->getSettings().graphics.backlight;
}); });
checkbox->consumer([=](bool checked) { checkbox->consumer([=](bool checked) {
engine->getSettings().graphics.backlight = checked; engine->getSettings().graphics.backlight = checked;
@@ -576,15 +602,16 @@ void create_settings_panel(Engine* engine, PagesControl* menu) {
panel->add(guiutil::backButton(menu)); panel->add(guiutil::backButton(menu));
} }
void create_pause_panel(Engine* engine, PagesControl* menu) { void create_pause_panel(Engine* engine) {
auto menu = engine->getGUI()->getMenu();
auto panel = create_page(engine, "pause", 400, 0.0f, 1); auto panel = create_page(engine, "pause", 400, 0.0f, 1);
panel->add(create_button(L"Continue", vec4(10.0f), vec4(1), [=](GUI*){ panel->add(create_button(L"Continue", vec4(10.0f), vec4(1), [=](GUI*){
menu->reset(); menu->reset();
})); }));
panel->add(create_button(L"Content", vec4(10.0f), vec4(1), [=](GUI*) { panel->add(create_button(L"Content", vec4(10.0f), vec4(1), [=](GUI*) {
create_content_panel(engine, menu); create_content_panel(engine);
menu->set("content"); menu->setPage("content");
})); }));
panel->add(guiutil::gotoButton(L"Settings", "settings", menu)); panel->add(guiutil::gotoButton(L"Settings", "settings", menu));
@@ -596,16 +623,16 @@ void create_pause_panel(Engine* engine, PagesControl* menu) {
})); }));
} }
void menus::create_menus(Engine* engine, PagesControl* menu) { void menus::create_menus(Engine* engine) {
create_new_world_panel(engine, menu); create_new_world_panel(engine);
create_settings_panel(engine, menu); create_settings_panel(engine);
create_controls_panel(engine, menu); create_controls_panel(engine);
create_pause_panel(engine, menu); create_pause_panel(engine);
create_languages_panel(engine, menu); create_languages_panel(engine);
create_main_menu_panel(engine, menu); create_main_menu_panel(engine);
} }
void menus::refresh_menus(Engine* engine, PagesControl* menu) { void menus::refresh_menus(Engine* engine) {
create_main_menu_panel(engine, menu); create_main_menu_panel(engine);
create_new_world_panel(engine, menu); create_new_world_panel(engine);
} }
+2 -6
View File
@@ -3,13 +3,9 @@
class Engine; class Engine;
namespace gui {
class PagesControl;
}
namespace menus { namespace menus {
void create_menus(Engine* engine, gui::PagesControl* menu); void create_menus(Engine* engine);
void refresh_menus(Engine* engine, gui::PagesControl* menu); void refresh_menus(Engine* engine);
} }
#endif // FRONTEND_MENU_H_ #endif // FRONTEND_MENU_H_
+2 -2
View File
@@ -45,9 +45,9 @@ Screen::~Screen() {
MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) { MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) {
auto menu = engine->getGUI()->getMenu(); auto menu = engine->getGUI()->getMenu();
menus::refresh_menus(engine, menu); menus::refresh_menus(engine);
menu->reset(); menu->reset();
menu->set("main"); menu->setPage("main");
uicamera.reset(new Camera(glm::vec3(), Window::height)); uicamera.reset(new Camera(glm::vec3(), Window::height));
uicamera->perspective = false; uicamera->perspective = false;
+4 -5
View File
@@ -11,17 +11,17 @@ using glm::vec2;
using glm::vec3; using glm::vec3;
using glm::vec4; using glm::vec4;
Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1.0f, 1.0f, 1.0f){ Batch2D::Batch2D(size_t capacity) : capacity(capacity), color(1.0f){
const vattr attrs[] = { const vattr attrs[] = {
{2}, {2}, {4}, {0} {2}, {2}, {4}, {0}
}; };
buffer = new float[capacity * B2D_VERTEX_SIZE]; buffer = new float[capacity * B2D_VERTEX_SIZE];
mesh = new Mesh(buffer, 0, attrs); mesh = std::make_unique<Mesh>(buffer, 0, attrs);
index = 0; index = 0;
unsigned char pixels[] = { ubyte pixels[] = {
255, 255, 255, 255, 0xFF, 0xFF, 0xFF, 0xFF
}; };
blank = new Texture(pixels, 1, 1, GL_RGBA); blank = new Texture(pixels, 1, 1, GL_RGBA);
_texture = nullptr; _texture = nullptr;
@@ -30,7 +30,6 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), offset(0), color(1.0f, 1
Batch2D::~Batch2D(){ Batch2D::~Batch2D(){
delete blank; delete blank;
delete[] buffer; delete[] buffer;
delete mesh;
} }
void Batch2D::begin(){ void Batch2D::begin(){
+2 -2
View File
@@ -1,6 +1,7 @@
#ifndef SRC_GRAPHICS_BATCH2D_H_ #ifndef SRC_GRAPHICS_BATCH2D_H_
#define SRC_GRAPHICS_BATCH2D_H_ #define SRC_GRAPHICS_BATCH2D_H_
#include <memory>
#include <stdlib.h> #include <stdlib.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
@@ -13,8 +14,7 @@ class Sprite;
class Batch2D { class Batch2D {
float* buffer; float* buffer;
size_t capacity; size_t capacity;
size_t offset; std::unique_ptr<Mesh> mesh;
Mesh* mesh;
size_t index; size_t index;
Texture* blank; Texture* blank;
+1 -2
View File
@@ -13,8 +13,7 @@ using glm::vec3;
using glm::vec4; using glm::vec4;
Batch3D::Batch3D(size_t capacity) Batch3D::Batch3D(size_t capacity)
: capacity(capacity), : capacity(capacity) {
offset(0) {
const vattr attrs[] = { const vattr attrs[] = {
{3}, {2}, {4}, {0} {3}, {2}, {4}, {0}
}; };
-1
View File
@@ -12,7 +12,6 @@ class Texture;
class Batch3D { class Batch3D {
float* buffer; float* buffer;
size_t capacity; size_t capacity;
size_t offset;
Mesh* mesh; Mesh* mesh;
size_t index; size_t index;
+11 -8
View File
@@ -4,16 +4,19 @@
using glm::vec4; using glm::vec4;
Font::Font(std::vector<Texture*> pages, int lineHeight) : lineHeight_(lineHeight), pages(pages) { Font::Font(std::vector<std::unique_ptr<Texture>> pages, int lineHeight, int yoffset)
: lineHeight(lineHeight), yoffset(yoffset), pages(std::move(pages)) {
} }
Font::~Font(){ Font::~Font(){
for (Texture* texture : pages)
delete texture;
} }
int Font::lineHeight() const { int Font::getYOffset() const {
return lineHeight_; return yoffset;
}
int Font::getLineHeight() const {
return lineHeight;
} }
bool Font::isPrintableChar(int c) { bool Font::isPrintableChar(int c) {
@@ -48,11 +51,11 @@ void Font::draw(Batch2D* batch, std::wstring text, int x, int y, int style) {
if (isPrintableChar(c)){ if (isPrintableChar(c)){
int charpage = c >> 8; int charpage = c >> 8;
if (charpage == page){ if (charpage == page){
Texture* texture = pages[charpage]; Texture* texture = pages[charpage].get();
if (texture == nullptr){ if (texture == nullptr){
texture = pages[0]; texture = pages[0].get();
} }
batch->texture(pages[charpage]); batch->texture(texture);
switch (style){ switch (style){
case STYLE_SHADOW: case STYLE_SHADOW:
+7 -4
View File
@@ -1,6 +1,7 @@
#ifndef GRAPHICS_FONT_H_ #ifndef GRAPHICS_FONT_H_
#define GRAPHICS_FONT_H_ #define GRAPHICS_FONT_H_
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include "../typedefs.h" #include "../typedefs.h"
@@ -13,13 +14,15 @@ const uint STYLE_SHADOW = 1;
const uint STYLE_OUTLINE = 2; const uint STYLE_OUTLINE = 2;
class Font { class Font {
int lineHeight_; int lineHeight;
int yoffset;
public: public:
std::vector<Texture*> pages; std::vector<std::unique_ptr<Texture>> pages;
Font(std::vector<Texture*> pages, int lineHeight); Font(std::vector<std::unique_ptr<Texture>> pages, int lineHeight, int yoffset);
~Font(); ~Font();
int lineHeight() const; int getLineHeight() const;
int getYOffset() const;
int calcWidth(std::wstring text); int calcWidth(std::wstring text);
// int getGlyphWidth(char c); // int getGlyphWidth(char c);
bool isPrintableChar(int c); bool isPrintableChar(int c);
+10 -4
View File
@@ -8,17 +8,23 @@ const uint LB_VERTEX_SIZE = (3+4);
LineBatch::LineBatch(size_t capacity) : capacity(capacity) { LineBatch::LineBatch(size_t capacity) : capacity(capacity) {
const vattr attrs[] = { {3},{4}, {0} }; const vattr attrs[] = { {3},{4}, {0} };
buffer = new float[capacity * LB_VERTEX_SIZE * 2]; buffer = new float[capacity * LB_VERTEX_SIZE * 2];
mesh = new Mesh(buffer, 0, attrs); mesh = std::make_unique<Mesh>(buffer, 0, attrs);
index = 0; index = 0;
} }
LineBatch::~LineBatch(){ LineBatch::~LineBatch(){
delete[] buffer; delete[] buffer;
delete mesh;
} }
void LineBatch::line(float x1, float y1, float z1, float x2, float y2, float z2, void LineBatch::line(
float r, float g, float b, float a) { float x1, float y1,
float z1, float x2,
float y2, float z2,
float r, float g, float b, float a
) {
if (index + LB_VERTEX_SIZE * 2 >= capacity) {
render();
}
buffer[index] = x1; buffer[index] = x1;
buffer[index+1] = y1; buffer[index+1] = y1;
buffer[index+2] = z1; buffer[index+2] = z1;
+2 -1
View File
@@ -1,13 +1,14 @@
#ifndef GRAPHICS_LINEBATCH_H_ #ifndef GRAPHICS_LINEBATCH_H_
#define GRAPHICS_LINEBATCH_H_ #define GRAPHICS_LINEBATCH_H_
#include <memory>
#include <stdlib.h> #include <stdlib.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
class Mesh; class Mesh;
class LineBatch { class LineBatch {
Mesh* mesh; std::unique_ptr<Mesh> mesh;
float* buffer; float* buffer;
size_t index; size_t index;
size_t capacity; size_t capacity;
+1 -1
View File
@@ -19,7 +19,7 @@ Texture::Texture(ubyte* data, int width, int height, uint format)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glGenerateMipmap(GL_TEXTURE_2D); glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 2); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
-3
View File
@@ -19,9 +19,6 @@ private:
uint padding; uint padding;
std::unique_ptr<WorldGenerator> generator; std::unique_ptr<WorldGenerator> generator;
/* Average measured microseconds duration of loadVisible call */
int64_t avgDurationMcs = 1000;
/* Process one chunk: load it or calculate lights for it */ /* Process one chunk: load it or calculate lights for it */
bool loadVisible(); bool loadVisible();
bool buildLights(std::shared_ptr<Chunk> chunk); bool buildLights(std::shared_ptr<Chunk> chunk);
+6 -6
View File
@@ -25,7 +25,7 @@ inline int lua_pushivec3(lua_State* L, int x, int y, int z) {
return 3; return 3;
} }
inline void luaL_openlib(lua_State* L, const char* name, const luaL_Reg* libfuncs, int nup) { inline void openlib(lua_State* L, const char* name, const luaL_Reg* libfuncs, int nup) {
lua_newtable(L); lua_newtable(L);
luaL_setfuncs(L, libfuncs, nup); luaL_setfuncs(L, libfuncs, nup);
lua_setglobal(L, name); lua_setglobal(L, name);
@@ -409,11 +409,11 @@ static int l_print(lua_State* L) {
lua_setglobal(L, NAME)) lua_setglobal(L, NAME))
void apilua::create_funcs(lua_State* L) { void apilua::create_funcs(lua_State* L) {
luaL_openlib(L, "pack", packlib, 0); openlib(L, "pack", packlib, 0);
luaL_openlib(L, "world", worldlib, 0); openlib(L, "world", worldlib, 0);
luaL_openlib(L, "player", playerlib, 0); openlib(L, "player", playerlib, 0);
luaL_openlib(L, "time", timelib, 0); openlib(L, "time", timelib, 0);
luaL_openlib(L, "file", filelib, 0); openlib(L, "file", filelib, 0);
lua_addfunc(L, l_print, "print"); lua_addfunc(L, l_print, "print");
lua_addfunc(L, l_block_index, "block_index"); lua_addfunc(L, l_block_index, "block_index");
+14
View File
@@ -101,6 +101,20 @@ void scripting::initialize(Engine* engine) {
load_script(fs::path("stdlib.lua")); load_script(fs::path("stdlib.lua"));
} }
// todo: luaL state check
runnable scripting::create_runnable(
const std::string& filename,
const std::string& src
) {
return [=](){
if (luaL_loadbuffer(L, src.c_str(), src.length(), filename.c_str())) {
handleError(L);
return;
}
call_func(L, 0, filename);
};
}
void scripting::on_world_load(Level* level, BlocksController* blocks) { void scripting::on_world_load(Level* level, BlocksController* blocks) {
scripting::level = level; scripting::level = level;
scripting::content = level->content; scripting::content = level->content;
+8
View File
@@ -1,6 +1,8 @@
#include <string> #include <string>
#include <filesystem> #include <filesystem>
#include "../../delegates.h"
namespace fs = std::filesystem; namespace fs = std::filesystem;
class Engine; class Engine;
@@ -20,6 +22,12 @@ namespace scripting {
extern BlocksController* blocks; extern BlocksController* blocks;
void initialize(Engine* engine); void initialize(Engine* engine);
runnable create_runnable(
const std::string& filename,
const std::string& source
);
void on_world_load(Level* level, BlocksController* blocks); void on_world_load(Level* level, BlocksController* blocks);
void on_world_save(); void on_world_save();
void on_world_quit(); void on_world_quit();
+7 -8
View File
@@ -4,18 +4,17 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>
typedef unsigned int uint; using uint = unsigned int;
// use for bytes arrays // use for bytes arrays
typedef uint8_t ubyte; using ubyte = uint8_t;
// content indices // content indices
typedef uint32_t itemid_t; using itemid_t = uint32_t;
typedef uint16_t blockid_t; using blockid_t = uint16_t;
typedef uint32_t itemcount_t; using itemcount_t = uint32_t;
using blockstate_t = uint16_t;
typedef uint16_t blockstate_t; using light_t = uint16_t;
typedef uint16_t light_t;
#endif #endif
+27
View File
@@ -252,3 +252,30 @@ std::vector<ubyte> util::base64_decode(const char* str, size_t size) {
std::vector<ubyte> util::base64_decode(const std::string& str) { std::vector<ubyte> util::base64_decode(const std::string& str) {
return base64_decode(str.c_str(), str.size()); return base64_decode(str.c_str(), str.size());
} }
int util::replaceAll(std::string& str, const std::string& from, const std::string& to) {
int count = 0;
size_t offset = 0;
while (true) {
size_t start_pos = str.find(from, offset);
if(start_pos == std::string::npos)
break;
str.replace(start_pos, from.length(), to);
offset = start_pos + to.length();
count++;
break;
}
return count;
}
// replace it with std::from_chars in the far far future
double util::parse_double(const std::string& str) {
std::istringstream ss(str);
ss.imbue(std::locale("C"));
double d;
ss >> d;
if (ss.fail()) {
throw std::runtime_error("invalid number format");
}
return d;
}
+4
View File
@@ -26,6 +26,10 @@ namespace util {
extern std::string base64_encode(const ubyte* data, size_t size); extern std::string base64_encode(const ubyte* data, size_t size);
extern std::vector<ubyte> base64_decode(const char* str, size_t size); extern std::vector<ubyte> base64_decode(const char* str, size_t size);
extern std::vector<ubyte> base64_decode(const std::string& str); extern std::vector<ubyte> base64_decode(const std::string& str);
extern int replaceAll(std::string& str, const std::string& from, const std::string& to);
extern double parse_double(const std::string& str);
} }
#endif // UTIL_STRINGUTIL_H_ #endif // UTIL_STRINGUTIL_H_
+2 -2
View File
@@ -5,7 +5,7 @@
#include <filesystem> #include <filesystem>
#include <stdexcept> #include <stdexcept>
#include "definitions.h" #include "core_defs.h"
#include "engine.h" #include "engine.h"
#include "util/platform.h" #include "util/platform.h"
#include "coders/toml.h" #include "coders/toml.h"
@@ -38,7 +38,7 @@ int main(int argc, char** argv) {
toml::Reader reader(wrapper.get(), settings_file.string(), text); toml::Reader reader(wrapper.get(), settings_file.string(), text);
reader.read(); reader.read();
} }
setup_bindings(); corecontent::setup_bindings();
Engine engine(settings, &paths); Engine engine(settings, &paths);
if (fs::is_regular_file(controls_file)) { if (fs::is_regular_file(controls_file)) {
std::cout << "-- loading controls" << std::endl; std::cout << "-- loading controls" << std::endl;
+1 -1
View File
@@ -13,7 +13,7 @@ struct AABB;
class Content; class Content;
class ContentIndices; class ContentIndices;
class Chunk; class Chunk;
class voxel; struct voxel;
class WorldFiles; class WorldFiles;
class LevelEvents; class LevelEvents;
+1 -1
View File
@@ -3,7 +3,7 @@
#include "../typedefs.h" #include "../typedefs.h"
class voxel; struct voxel;
class Content; class Content;
class WorldGenerator { class WorldGenerator {
+4
View File
@@ -84,6 +84,10 @@ public:
uint getNextInventoryId() { uint getNextInventoryId() {
return nextInventoryId++; return nextInventoryId++;
} }
const Content* getContent() const {
return content;
}
}; };
#endif /* WORLD_WORLD_H_ */ #endif /* WORLD_WORLD_H_ */