]> git.lizzy.rs Git - dragonblocks-bedrock.git/commitdiff
Add files via upload
authorEliasFleckenstein03 <54945686+EliasFleckenstein03@users.noreply.github.com>
Fri, 14 Feb 2020 16:44:21 +0000 (17:44 +0100)
committerGitHub <noreply@github.com>
Fri, 14 Feb 2020 16:44:21 +0000 (17:44 +0100)
42 files changed:
CMakeLists.txt [new file with mode: 0644]
README.txt [new file with mode: 0644]
builtin/cpp.lua [new file with mode: 0644]
builtin/functions.lua [new file with mode: 0644]
builtin/init.lua [new file with mode: 0644]
builtin/register.lua [new file with mode: 0644]
game/init.lua [new file with mode: 0644]
game/nodes.lua [new file with mode: 0644]
install.sh [new file with mode: 0644]
src/game.cpp [new file with mode: 0644]
src/game.h [new file with mode: 0644]
src/graphics.cpp [new file with mode: 0644]
src/graphics.h [new file with mode: 0644]
src/inventory.cpp [new file with mode: 0644]
src/inventory.h [new file with mode: 0644]
src/main.cpp [new file with mode: 0644]
src/map.cpp [new file with mode: 0644]
src/map.h [new file with mode: 0644]
src/mapgen.cpp [new file with mode: 0644]
src/mapgen.h [new file with mode: 0644]
src/mods.cpp [new file with mode: 0644]
src/mods.h [new file with mode: 0644]
src/node.cpp [new file with mode: 0644]
src/node.h [new file with mode: 0644]
src/texture.cpp [new file with mode: 0644]
src/texture.h [new file with mode: 0644]
src/threads.cpp [new file with mode: 0644]
src/threads.h [new file with mode: 0644]
src/util.cpp [new file with mode: 0644]
src/util.h [new file with mode: 0644]
textures/air.png [new file with mode: 0644]
textures/bedrock.png [new file with mode: 0644]
textures/cobble.png [new file with mode: 0644]
textures/dirt.png [new file with mode: 0644]
textures/grass.png [new file with mode: 0644]
textures/leaves.png [new file with mode: 0644]
textures/mese.png [new file with mode: 0644]
textures/sand.png [new file with mode: 0644]
textures/stone.png [new file with mode: 0644]
textures/unknown_node.png [new file with mode: 0644]
textures/water.png [new file with mode: 0644]
textures/wood.png [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4f3b030
--- /dev/null
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.0)
+project(dragonblocks)
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
+add_executable(dragonblocks
+       src/game.cpp
+    src/graphics.cpp
+    src/inventory.cpp
+       src/main.cpp
+       src/map.cpp
+       src/mapgen.cpp
+       src/mods.cpp
+       src/node.cpp
+    src/texture.cpp
+    src/threads.cpp
+       src/util.cpp
+)
+
+target_link_libraries(dragonblocks
+       GL
+       freeglut
+       lua5.3
+       pthread
+       png16
+       m
+)
diff --git a/README.txt b/README.txt
new file mode 100644 (file)
index 0000000..2f173d8
--- /dev/null
@@ -0,0 +1,82 @@
+DRAGONBLOCKS BEDROCK EDITION
+Written in C++
+An Open Source Project by Elias Fleckenstein
+
+1. General
+       1.1. What this is about
+               Dragonblocks originaly was a Browsergame I made that should be some kind of 2D Minetest (Minetest (www.minetest.net) is a game similar to 
+               Minecraft, except Minetest is free & open source and is meant to be modded). The JavaScript Edition is hosted at www.dragonblocks.tk and 
+               further developed then this C++ Version, through the C++ Version has advantages like map saving and lot larger map. I decided to call the 
+               C++ Version "Bedrock Edition" as a joke for the Minecraft C++ Version is Called Bedrock or Pocket Edition.
+       1.2. Version
+               This is the Dragonblocks Bedrock Edition 3.0.
+       1.4. Bugs
+               Please Report Bugs to eliasfleckenstein@web.de.
+       1.5. License
+               Copyright 2020 Elias Fleckenstein <eliasfleckenstein@web.de>
+               
+               This program is free software; you can redistribute it and/or modify
+               it under the terms of the GNU General Public License as published by
+               the Free Software Foundation; either version 2 of the License, or
+               (at your option) any later version.
+               
+               This program is distributed in the hope that it will be useful,
+               but WITHOUT ANY WARRANTY; without even the implied warranty of
+               MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+               GNU General Public License for more details.
+
+               You should have received a copy of the GNU General Public License
+               along with this program; if not, write to the Free Software
+               Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+               MA 02110-1301, USA.
+
+2. Starting the Game
+       2.1. Platform Compability
+               This Game was developed on linux, therefore following instructions are only for linux users, basically because I have no idea how to
+               port the game to other platforms. Feel free to add building instructions for other systems over github.
+       2.3. Download
+               You can download the game using git:
+                       $ git clone https://
+       2.2. Dependencies:
+               You need Freeglut, OpenGl, Cmake, Liblua and Libpng.
+               If you are on Debian/Ubuntu You can install them over apt: 
+                       $ sudo apt install liblua5.3-dev freeglut3-dev libgl1-mesa-dev cmake libpng-dev
+    2.3. Building
+        to Build dragonblocks run:
+            $ cd dragonblocks
+            $ cmake .
+            $ make
+       2.4. Exectute
+               2.4.1. Run-In-Place
+                       Invoke dragonblocks by typing:
+                $ cd dragonblocks
+                $ bin/dragonblocks --worldname <your_worldname>
+            To see a list of worlds do:
+                $ bin/dragonblocks --worldlist
+            You can select a world from this list or create a new one.
+            For more info run:
+                               $ bin/dragonblocks --help
+               2.4.2. Installation
+                       You can install dragonblocks by doing:
+                               $ sudo ./install.sh
+                       It will copy the dragonblocks directory to /usr/share/dragonblocks and place a script in
+                       /usr/bin/dragonblocks that starts dragonblocks.
+
+3. Developing
+       3.1. The Lua Modding API
+               If you want to add a lua file to the game, place it in the game folder and add a dofile() in game/init.lua
+               Note: The lua api currently consists of only two functions. If you want to add something I'm open to ideas or code.
+               dragonblocks.register_node(obj)
+                       Register a new node
+                       obj has to contain:
+                               name: string - the itemstring. It should follow the convention "modulename:nodename"
+                               texture: string - the texture path. Textures should be placed in the textures folder and have to be 16 x 16 px.
+                       obj can contain:
+                               stable: boolean - Nodes like water or air are unstable. [default = true]
+                               hidden: boolean - The Node will be hidden in the invenotry. [default = false]
+                               translucent: boolean - Whether the node's texture should be transparent. [default = false]
+               dragonblocks.log(text)
+                       Log something.
+       3.2. The C++ API
+               The C++ API is probably to big to explain here, but if you do C++ you should understand it. In case you have questions, feel free to
+               ask them on github. You can also contribute code if you want.
diff --git a/builtin/cpp.lua b/builtin/cpp.lua
new file mode 100644 (file)
index 0000000..a6cd19d
--- /dev/null
@@ -0,0 +1,5 @@
+local cpp_last_node = 0
+function cpp_get_next_node()
+    cpp_last_node = cpp_last_node + 1
+    return core.nodes[cpp_last_node]           
+end
diff --git a/builtin/functions.lua b/builtin/functions.lua
new file mode 100644 (file)
index 0000000..124d049
--- /dev/null
@@ -0,0 +1,3 @@
+dragonblocks.log = function(text)
+       print("[LUA] "..text)
+end
diff --git a/builtin/init.lua b/builtin/init.lua
new file mode 100644 (file)
index 0000000..cafcae1
--- /dev/null
@@ -0,0 +1,15 @@
+core = {}
+dragonblocks = {}
+dragonblocks.settings = {}
+
+dofile("builtin/register.lua")
+dofile("builtin/functions.lua")
+dofile("builtin/cpp.lua")
+
+--local popenfile = io.popen("ls game")
+--for filename in popenfile:lines() do
+--     dofile("game/"..filename.."/init.lua")
+--end
+--popenfile:close()
+
+dofile("game/init.lua")
diff --git a/builtin/register.lua b/builtin/register.lua
new file mode 100644 (file)
index 0000000..eaf3322
--- /dev/null
@@ -0,0 +1,20 @@
+core.nodes = {}
+dragonblocks.register_node = function(obj)
+       if obj and obj.name and obj.texture then
+               core.nodes[#core.nodes+1] = {}
+               core.nodes[#core.nodes].name = obj.name
+               core.nodes[#core.nodes].texture = obj.texture
+               core.nodes[#core.nodes].stable = false
+               if obj.stable == nil or obj.stable == true then
+                       core.nodes[#core.nodes].stable = true
+               end
+               core.nodes[#core.nodes].hidden = false
+               if obj.hidden then
+                       core.nodes[#core.nodes].hidden = true
+               end
+               core.nodes[#core.nodes].translucent = false
+               if obj.translucent then
+                       core.nodes[#core.nodes].translucent = true
+               end
+       end             
+end
diff --git a/game/init.lua b/game/init.lua
new file mode 100644 (file)
index 0000000..00e904c
--- /dev/null
@@ -0,0 +1,7 @@
+dragonblocks.log(" ____                              _     _            _         ")
+dragonblocks.log("|  _ \\ _ __ __ _  __ _  ___  _ __ | |__ | | ___   ___| | _____  ")
+dragonblocks.log("| | | | '__/ _` |/ _` |/ _ \\| '_ \\| '_ \\| |/ _ \\ / __| |/ / __| ")
+dragonblocks.log("| |_| | | | (_| | (_| | (_) | | | | |_) | | (_) | (__|   <\\__ \\ ")
+dragonblocks.log("|____/|_|  \\__,_|\\__, |\\___/|_| |_|_.__/|_|\\___/ \\___|_|\\_\\___/ ")
+dragonblocks.log("                 |___/                                          ")
+dofile("game/nodes.lua")
diff --git a/game/nodes.lua b/game/nodes.lua
new file mode 100644 (file)
index 0000000..88b321d
--- /dev/null
@@ -0,0 +1,50 @@
+dragonblocks.register_node({
+       name = "dragonblocks:air",
+       texture = "textures/air.png",
+       stable = false,
+       hidden = true,
+       translucent = true,
+})
+dragonblocks.register_node({
+       name = "dragonblocks:stone",
+       texture = "textures/stone.png"
+})
+dragonblocks.register_node({
+       name = "dragonblocks:dirt",
+       texture = "textures/dirt.png"
+})
+dragonblocks.register_node({
+       name = "dragonblocks:grass", 
+       texture = "textures/grass.png"
+})
+dragonblocks.register_node({
+       name = "dragonblocks:wood", 
+       texture = "textures/wood.png"
+})
+dragonblocks.register_node({
+       name = "dragonblocks:water", 
+       texture = "textures/water.png",
+       stable = false,
+       translucent = true,
+})
+dragonblocks.register_node({
+       name = "dragonblocks:leaves", 
+       texture = "textures/leaves.png",
+       translucent = true,
+})
+dragonblocks.register_node({
+       name = "dragonblocks:bedrock", 
+       texture = "textures/bedrock.png"
+})
+dragonblocks.register_node({
+       name = "dragonblocks:mese", 
+       texture = "textures/mese.png"
+})
+dragonblocks.register_node({
+       name = "dragonblocks:sand", 
+       texture = "textures/sand.png"
+})
+dragonblocks.register_node({
+       name = "dragonblocks:cobble", 
+       texture = "textures/cobble.png"
+})
diff --git a/install.sh b/install.sh
new file mode 100644 (file)
index 0000000..639c232
--- /dev/null
@@ -0,0 +1,7 @@
+#! /bin/bash
+cp . /usr/share/dragonblocks -R
+echo "
+cd /usr/share/dragonblocks
+bin/dragonblocks \$*
+" > /usr/bin/dragonblocks
+chmod +x /usr/bin/dragonblocks
diff --git a/src/game.cpp b/src/game.cpp
new file mode 100644 (file)
index 0000000..5af8be6
--- /dev/null
@@ -0,0 +1,84 @@
+#include <string>
+#include <iostream>
+#include <cstdio>
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "mods.h"
+#include "game.h"
+using namespace std;
+
+void Game::log(string text, int level){
+       string prefix;
+       int color;
+       switch(level){
+               case WARNING: 
+                       color = ORANGE;
+                       prefix = "WARNING"; 
+                       break;
+               case ERROR:
+                       color = RED;
+                       prefix = "ERROR"; 
+                       break;
+               case INFO:
+                       color = LIGHTBLUE;
+                       prefix = "INFO"; 
+                       break;
+               case LOG:
+                       color = BLUE;
+                       prefix = "LOG"; 
+                       break;
+               case EASTEREGG:
+                       color = VIOLET;
+                       prefix = "EASTEREGG";
+               default: break;
+       }
+       cout << "\e[3" << color << "m" << "[" << prefix << "] \e[0m" << text << endl;
+       if(logfile_fd)
+               fprintf(logfile_fd, "[%s] %s\n", prefix.c_str(), text.c_str());
+}
+void Game::log(string text){
+       log(text, LOG);
+}
+void Game::help(){
+       cout << "Usage: " << argv[0] << "[OPTIONS]" << endl;
+       cout << "Options:" << endl;
+       cout << "\t" << "-h" << "\t" << "--help" << "\t\t\t" << "Display this help and exit." << endl;
+       cout << "\t" << "-v" << "\t" << "--version" << "\t\t" << "Display version info." << endl;
+       cout << "\t" << "-p" << "\t" << "--worldpath [PATH]" << "\t" << "Set world path." << endl;
+       cout << "\t" << "-w" << "\t" << "--worldname [PATH]" << "\t" << "Select world by name (Worlds are placed in ~/.dragonblocks/worlds/)." << endl;
+       cout << "\t" << "-r" << "\t" << "--worldlist" << "\t\t" << "Show a list of your worlds." << endl;
+       cout << "\t" << "-s" << "\t" << "--seed [NUMBER]" << "\t\t" << "Set seed." << endl;
+       cout << "\t" << "-l" << "\t" << "--logfile [PATH]" << "\t" << "Set logfile." << endl;
+}
+void Game::version(){
+       cout << "DRAGONBLOCKS BEDROCK EDITION" << endl;
+       cout << "Written in C++" << endl;
+       cout << "An Open Source Project by Elias Fleckenstein" << endl;
+       cout << "Dragonblocks " << VERSION << endl;
+}
+void Game::worldlist(){
+       log("Your worlds:");
+       DIR *folder;
+    struct dirent *entry;
+    int files = 0;
+
+    folder = opendir(((string)getenv("HOME")+"/.dragonblocks/worlds/").c_str());
+    if(!folder){
+               Game::log("Cant Open World Directory", ERROR);
+               exit(EXIT_FAILURE);
+       }
+    while(entry = readdir(folder))
+    {
+        files++;
+               if(files > 2)
+                       cout << "\t" << entry->d_name;
+    }
+       if(files <= 2)
+               cout << "\tYou have no Worlds yet.";
+    cout << endl;
+       closedir(folder);
+
+    return;
+}
diff --git a/src/game.h b/src/game.h
new file mode 100644 (file)
index 0000000..53ac862
--- /dev/null
@@ -0,0 +1,43 @@
+#ifndef _GAME_H_
+#define _GAME_H_
+#include <string>
+#include <cstdio>
+
+#include "map.h"
+#include "inventory.h"
+
+#define WARNING 1
+#define ERROR 2
+#define INFO -1
+#define EASTEREGG 17
+#define LOG 0
+
+#define VERSION "3.0"
+
+#define BLACK 0
+#define RED 1
+#define GREEN 2
+#define ORANGE 3
+#define BLUE 4
+#define VIOLET 5
+#define LIGHTBLUE 6
+#define GREY 7
+
+class Game{
+       public:
+               static int *argc;
+               static char **argv;
+               static int seed;
+               static std::string mapfile;
+               static std::string logfile;
+               static FILE *logfile_fd;
+               static Map *map;
+               static void log(std::string);
+               static void log(std::string, int);
+               static void help();
+               static void version();
+               static void worldlist();
+               static Inventory *inventory;
+};
+
+#endif
diff --git a/src/graphics.cpp b/src/graphics.cpp
new file mode 100644 (file)
index 0000000..c8011c0
--- /dev/null
@@ -0,0 +1,130 @@
+#include <GL/freeglut.h>
+#include <cstring>
+#include <string>
+#include <iostream>
+#include "graphics.h"
+#include "util.h"
+#include "game.h"
+#include "mapgen.h"
+
+position Graphics::pointed;
+position Graphics::pos = {MAPWIDTH/2 - DISPLAYWIDTH/2, MAPHEIGHT/2 - DISPLAYHEIGHT/2};
+
+using namespace std;
+void Graphics::display(){
+       glClear(GL_COLOR_BUFFER_BIT);
+       //sky
+       drawRectangle(0, 0, DISPLAYWIDTH*BLOCKWIDTH, DISPLAYHEIGHT*BLOCKWIDTH, "#87CEEB");
+       //map
+       for(int x = 0; x < DISPLAYWIDTH; x++){
+               for(int y = 0; y < DISPLAYHEIGHT; y++){
+                       Game::map -> getNode(x+pos.x, y+pos.y) -> texture -> draw(x*BLOCKWIDTH, y*BLOCKWIDTH, BLOCKWIDTH, BLOCKWIDTH);
+               }
+       }
+       //pointed block
+       if(pointed.x < DISPLAYWIDTH){
+               drawRectangle(pointed.x * BLOCKWIDTH, pointed.y * BLOCKWIDTH, BLOCKWIDTH, 1, COLOR_BLACK);
+               drawRectangle(pointed.x * BLOCKWIDTH + BLOCKWIDTH - 1, pointed.y * BLOCKWIDTH, 1, BLOCKWIDTH, COLOR_BLACK);
+               drawRectangle(pointed.x * BLOCKWIDTH, pointed.y * BLOCKWIDTH + BLOCKWIDTH - 1, BLOCKWIDTH, 1, COLOR_BLACK);
+               drawRectangle(pointed.x * BLOCKWIDTH, pointed.y * BLOCKWIDTH, 1, BLOCKWIDTH, COLOR_BLACK);
+       }
+       //inventory
+       
+       drawRectangle(DISPLAYWIDTH*BLOCKWIDTH, 0, INVWIDTH, DISPLAYHEIGHT*BLOCKWIDTH, "#B4B4B4");
+       drawRectangle(DISPLAYWIDTH*BLOCKWIDTH, Game::inventory->selected * INVWIDTH, INVWIDTH, INVWIDTH, "#636363");
+       for(int i = 0; i < Game::inventory->count; i++)
+               Game::inventory -> getSlot(i) -> texture -> draw(BLOCKWIDTH*DISPLAYWIDTH + (INVWIDTH-INVBLOCKWIDTH)/2, i * INVWIDTH + (INVWIDTH-INVBLOCKWIDTH)/2, INVBLOCKWIDTH, INVBLOCKWIDTH);
+       //infotext
+       writeText(5, 5, (string)"Dragonblocks "+VERSION, GLUT_BITMAP_9_BY_15, COLOR_WHITE);
+       string infotext = "pos: ("+to_string(pos.x)+", "+to_string(pos.y)+"), seed: "+to_string(Game::seed);
+       if(pointed.x < DISPLAYWIDTH)
+               infotext += ", pointed: "+ Game::map->getNode(pointed.x+pos.x, pointed.y+pos.y)->name + "("+to_string(pointed.x+pos.x)+", "+to_string(pointed.y+pos.y)+")";
+       writeText(5, 20, infotext, GLUT_BITMAP_9_BY_15, COLOR_WHITE);
+       //writeText(5, 35, "world: "+Game::mapfile, GLUT_BITMAP_9_BY_15, COLOR_WHITE);
+       glFlush();
+}
+void Graphics::reshape(int width, int height){
+       glViewport(0, 0, width, height);       /* Establish viewing area to cover entire window. */
+       glMatrixMode(GL_PROJECTION);  /* Start modifying the projection matrix. */
+       glLoadIdentity();             /* Reset project matrix. */
+       glOrtho(0, width, 0, height, -1, 1);   /* Map abstract coords directly to window coords. */
+       glScalef(1, -1, 1);           /* Invert Y axis so increasing Y goes down. */
+       glTranslatef(0, -height, 0);       /* Shift origin up to upper-pos.x corner. */
+}
+void Graphics::init(){
+       glutInit(Game::argc, Game::argv);
+       glutCreateWindow("Dragonblocks");
+       glutReshapeWindow(DISPLAYWIDTH*BLOCKWIDTH+INVWIDTH, DISPLAYHEIGHT*BLOCKWIDTH);
+       glutDisplayFunc(display);
+       glutReshapeFunc(reshape);
+       glutKeyboardFunc(keyboard);
+       glutSpecialFunc(special);
+       glutMouseFunc(mouse);
+       glutPassiveMotionFunc(motion);
+       glutMotionFunc(motion);
+       glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
+       glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+       glutMainLoop();
+}
+void Graphics::keyboard(unsigned char key, int x, int y){
+}
+void Graphics::special(int key, int x, int y){
+       switch(key){
+               case GLUT_KEY_LEFT:
+                       if(pos.x > 0)
+                               pos.x--;
+                       break;
+               case GLUT_KEY_UP:
+                       if(pos.y > 0)
+                               pos.y--;
+                       break;
+               case GLUT_KEY_RIGHT:
+                       if(pos.x < MAPWIDTH-DISPLAYWIDTH)
+                               pos.x++;
+                       break;
+               case GLUT_KEY_DOWN:
+                       if(pos.y < MAPHEIGHT-DISPLAYHEIGHT)
+                               pos.y++;
+                       break;
+       }
+}
+void Graphics::mouse(int key, int action, int x, int y){
+       if(action == 0){
+               if(x < BLOCKWIDTH*DISPLAYWIDTH){
+                       switch(key){
+                               case 0:
+                                       if(Game::map -> getNode(pointed.x+pos.x, pointed.y+pos.y)->stable)
+                                               Game::map -> setNode(pointed.x+pos.x, pointed.y+pos.y, MAPGEN_AIR);
+                                       break;
+                               case 2:
+                                       if(! Game::map -> getNode(pointed.x+pos.x, pointed.y+pos.y)->stable)
+                                               Game::map -> setNode(pointed.x+pos.x, pointed.y+pos.y, Game::inventory->getSelectedSlot());
+                                       break;
+                       }
+               }
+               else{
+                       Game::inventory->select(y/INVWIDTH);
+               }
+       }
+}
+void Graphics::motion(int x, int y){
+       pointed.x = x / BLOCKWIDTH;
+       pointed.y = y / BLOCKWIDTH;
+}
+void Graphics::writeText(int x, int y, string text, void *font, color c){
+       glColor3f(c.red, c.green, c.blue);
+       glRasterPos2i(x, y+10);
+       char *s = strdup(text.c_str());
+       --s;
+       while(*++s)
+               glutBitmapCharacter(font, *s);
+}
+void Graphics::drawRectangle(int x, int y, int width, int height, color c){
+       glColor3f(c.red, c.green, c.blue);
+       glBegin(GL_POLYGON);
+       glVertex2i(x, y);
+       glVertex2i(x+width, y);
+       glVertex2i(x+width, y+height);
+       glVertex2i(x, y+height);
+       glEnd();
+}
diff --git a/src/graphics.h b/src/graphics.h
new file mode 100644 (file)
index 0000000..d1d23ab
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef _GRAPHICS_H_
+#define _GRAPHICS_H_
+
+#include <string>
+#include "texture.h"
+#include "util.h"
+
+
+#define BLOCKWIDTH 32
+#define DISPLAYWIDTH 25
+#define DISPLAYHEIGHT 25
+#define INVBLOCKWIDTH 64
+#define INVWIDTH 80
+
+#define COLOR_WHITE {1,1,1}
+#define COLOR_BLACK {0,0,0}
+
+
+class Graphics{
+       public:
+               static void init();
+               
+               static position pointed;
+               static position pos;
+               
+               //handlers
+               static void display();
+               static void keyboard(unsigned char, int, int);
+               static void mouse(int, int, int, int);
+               static void special(int, int, int);
+               static void reshape(int, int);
+               static void motion(int, int);
+               
+               //functions
+               static void drawRectangle(int, int, int, int, color);
+               static void writeText(int, int, std::string, void*, color);
+};
+#endif
diff --git a/src/inventory.cpp b/src/inventory.cpp
new file mode 100644 (file)
index 0000000..257b181
--- /dev/null
@@ -0,0 +1,24 @@
+#include "node.h"
+#include "inventory.h" 
+Inventory::Inventory(){
+       count = 0;
+       selected = 0;
+       for(int i = 0; i < Node::count; i++){
+               if(! Node::getNodeById(i) -> hidden){
+                       list[count] = Node::getNodeById(i);
+                       count++;
+               }
+       }
+}
+Node *Inventory::getSlot(int nr){
+       if(nr >= 0 && nr < count)
+               return list[nr];
+       return list[0]; 
+}
+void Inventory::select(int nr){
+       if(nr >= 0 && nr < count)
+               selected = nr;
+}
+Node *Inventory::getSelectedSlot(){
+       return list[selected];
+}
diff --git a/src/inventory.h b/src/inventory.h
new file mode 100644 (file)
index 0000000..64f6b17
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _INVENTORY_H_
+#define _INVENTORY_H_
+
+#include "node.h" 
+
+class Inventory{
+       public:
+               int count;
+               int selected;
+               Node *list[MAXNODES];
+               Node *getSlot(int);
+               void select(int);
+               Node *getSelectedSlot();
+               Inventory();
+};
+
+#endif
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644 (file)
index 0000000..3bfa32c
--- /dev/null
@@ -0,0 +1,113 @@
+#include <stdio.h>
+#include <string>
+#include <stdlib.h>
+#include <time.h>
+#include <getopt.h>
+#include <iostream>
+#include <cstdio> 
+#include <unistd.h>
+#include "graphics.h"
+#include "map.h"
+#include "game.h"
+#include "node.h"
+#include "mapgen.h"
+#include "mods.h"
+#include "threads.h"
+#include "inventory.h"
+
+using namespace std;
+
+Map *Game::map;
+string Game::mapfile;
+string Game::logfile;
+int Game::seed;
+char **Game::argv;
+int *Game::argc;
+FILE *Game::logfile_fd;
+Inventory *Game::inventory;
+
+int main(int argc, char **argv){
+       if((string)argv[0] != "bin/dragonblocks"){
+               string command = "cd ..; bin/dragonblocks -w world ";
+               while(*++argv)
+                       command += *argv;
+               exit(system(command.c_str()));
+       }
+       create_dir_if_not_exists((string)getenv("HOME")+"/.dragonblocks");
+       create_dir_if_not_exists((string)getenv("HOME")+"/.dragonblocks/worlds");
+       Game::argc = &argc;
+       Game::argv = argv;
+       Game::seed = time(0);
+       Game::logfile = (string)getenv("HOME")+"/.dragonblocks/dragonblocks.log";
+       const char *short_options = "hrvs:l:w:p:";
+       const struct option long_options[] = {
+               {"help", 0, NULL, 'h'},
+               {"version", 0, NULL, 'v'},
+               {"worldname", 1, NULL, 'w'},
+               {"worldpath", 1, NULL, 'p'},
+               {"worldlist", 0, NULL, 'r'},
+               {"seed", 1, NULL, 's'},
+               {"logfile", 1, NULL, 'l'},
+               {NULL, 0, NULL, 0},
+       };
+       int next_option;
+       while((next_option = getopt_long(argc, argv, short_options, long_options, NULL)) != -1){
+               switch(next_option){
+                       case 'h':
+                               Game::help();
+                               exit(EXIT_SUCCESS);
+                               break;
+                       case 'v':
+                               Game::version();
+                               exit(EXIT_SUCCESS);
+                               break;
+                       case 'p':
+                               Game::mapfile = optarg;
+                               break;
+                       case 'w':
+                               Game::mapfile = (string)getenv("HOME")+"/.dragonblocks/worlds/"+optarg;
+                               break;
+                       case 's':
+                               Game::seed = atoi(optarg);
+                               break;
+                       case 'l':
+                               Game::logfile = optarg;
+                               break;
+                       case 'r':
+                               Game::worldlist();
+                               exit(0);
+                               break;  
+                       case '?':
+                               Game::log("Invalid Usage", ERROR);
+                               Game::help();
+                               exit(EXIT_FAILURE);
+                               break;
+               };
+       }
+       if(Game::logfile_fd = fopen(Game::logfile.c_str(), "a"))
+               fprintf(Game::logfile_fd, "\n--------------------------------------------------\n");
+       else
+               Game::log((string)"Failed to open log file " + Game::logfile, WARNING);
+       Game::log((string)"Welcome to Dragonblocks "+VERSION);
+       srand(Game::seed);
+       new Node("unknown_node", "textures/unknown_node.png", true, true, false);
+       Mods::init();
+       Game::inventory = new Inventory();
+       Game::map = new Map();
+       if(Game::mapfile == ""){
+               Game::log("No World Specified", ERROR);
+               exit(EXIT_FAILURE);
+       }
+       if(fopen(Game::mapfile.c_str(), "r"))
+               Game::map->load();
+       else
+               Mapgen();
+       Threads::startMapBackupThread();
+       Threads::startGraphicUpdateThread();
+       Threads::addSignalHandlers();
+       Graphics::init();
+       Game::log("Closed Window, Exiting.");
+       Game::map -> save();
+       return 0;
+}
+
diff --git a/src/map.cpp b/src/map.cpp
new file mode 100644 (file)
index 0000000..7e5f3bd
--- /dev/null
@@ -0,0 +1,53 @@
+#include <string>
+#include <stdlib.h>
+#include <cstring>
+#include <cstdio>
+#include "map.h"
+#include "node.h"
+#include "game.h"
+using namespace std;
+Node *Map::getNode(int x, int y){
+       if(x < MAPWIDTH && y < MAPHEIGHT && x > -1 && y > -1)
+               return content[x][y];
+       return NULL;    
+}
+void Map::setNode(int x, int y, Node *n){
+       if(x < MAPWIDTH && y < MAPHEIGHT && x > -1 && y > -1)
+               content[x][y] = n;
+}
+void Map::setNode(int x, int y, string n){
+       setNode(x, y, Node::getNodeByName(n));
+}
+void Map::load(){
+       Game::log("Loading Map from " + Game::mapfile);
+       FILE *mapfile = fopen(Game::mapfile.c_str(), "r");
+       if(mapfile){
+               for(int x = 0; x < MAPWIDTH; x++)
+                       for(int y = 0; y < MAPHEIGHT; y++){
+                               char buffer[512] = {0};
+                               fscanf(mapfile, "%s", buffer);
+                               setNode(x, y, buffer);
+                       }
+               fclose(mapfile);
+               Game::log("Loaded Map");
+       }
+       else{
+               Game::log("Could not Load Map.", ERROR);
+               exit(EXIT_FAILURE);
+       }
+}
+void Map::save(){
+       Game::log("Saving Map to " + Game::mapfile);
+       FILE *mapfile = fopen(Game::mapfile.c_str(), "w");
+       if(mapfile){
+               for(int x = 0; x < MAPWIDTH; x++){
+                       for(int y = 0; y < MAPHEIGHT; y++)
+                               fprintf(mapfile,"%s ", getNode(x,y)->name.c_str());
+                       fprintf(mapfile, "\n");
+               }
+               fclose(mapfile);
+               Game::log("Saved Map");
+       }
+       else
+               Game::log("Could not Save Map.", ERROR);
+}
diff --git a/src/map.h b/src/map.h
new file mode 100644 (file)
index 0000000..c7c83cc
--- /dev/null
+++ b/src/map.h
@@ -0,0 +1,21 @@
+#ifndef _MAP_H_
+#define _MAP_H_
+
+#include <string>
+
+#include "node.h"
+
+#define MAPWIDTH 500
+#define MAPHEIGHT 100
+
+class Map{
+       public:
+               Node *getNode(int, int);
+               void setNode(int, int, Node *);
+               void setNode(int, int, std::string);
+               void load();
+               void save();
+       private: 
+               Node *content[MAPWIDTH][MAPHEIGHT];
+};
+#endif
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
new file mode 100644 (file)
index 0000000..cb2efe1
--- /dev/null
@@ -0,0 +1,121 @@
+#include <string>
+#include <iostream>
+#include <stdlib.h>
+#include <math.h>  
+
+#include "mapgen.h"
+#include "map.h"
+#include "node.h"
+#include "util.h"
+#include "game.h"
+
+using namespace std;
+void Mapgen(){
+       Game::log("Generating Map");
+       //Air
+       for(int x = 0; x < MAPWIDTH; x++){
+               for(int y = 0; y < MAPHEIGHT; y++){
+                       Game::map->setNode(x,y,MAPGEN_AIR);
+                       }
+               }
+       //Seed 13 Easteregg
+       if(Game::seed == 13){
+               for(int x = 0; x < MAPWIDTH; x++){
+                       for(int y = 0; y < MAPHEIGHT; y++){
+                               Game::map->setNode(x,y,MAPGEN_BEDROCK);
+                       }
+               }
+               Game::log("LOL Seed 13", EASTEREGG);
+               return;
+       }
+       //Bottom
+       int bottom[MAPWIDTH];
+       bottom[0] = random(MAPHEIGHT/2 - MAPHEIGHT/10, MAPHEIGHT/2);
+       for(int x = 1; x < MAPWIDTH; x++){
+               bottom[x] = bottom[x-1] + random(-1,1);
+               }
+       //Smooth        
+       for(int x = 1; x < MAPWIDTH-1; x++){
+               if(bottom[x] > bottom[x+1] && bottom[x] > bottom[x-1]) bottom[x]--;
+               else if(bottom[x] < bottom[x+1] && bottom[x] < bottom[x-1])bottom[x]++; 
+               }
+       //Dirt with Grass
+       for(int x = 0; x < MAPWIDTH; x++){
+               Game::map->setNode(x,bottom[x],MAPGEN_GRASS);
+               }
+       //Dirt          
+       for(int x = 0; x < MAPWIDTH; x++){
+               for(int y = bottom[x]+1; y < bottom[x]+5; y++){
+                       Game::map->setNode(x,y,MAPGEN_DIRT);
+                       }
+               }
+       //Stone
+       for(int x = 0; x < MAPWIDTH; x++){
+               for(int y = bottom[x]+5; y < MAPHEIGHT; y++){
+                       Game::map->setNode(x,y,MAPGEN_STONE);
+                       }
+               }
+       //Mese
+       for(int x = 0; x < MAPWIDTH; x++){
+               for(int y = bottom[x]+10; y < MAPHEIGHT; y++){
+                       if((rand() % 100) == 0) Game::map->setNode(x,y,MAPGEN_MESE);
+                       }
+               }               
+       //Bedrock
+       for(int x = 0; x < MAPWIDTH; x++){
+               Game::map->setNode(x,MAPHEIGHT-1,MAPGEN_BEDROCK);
+               if(random(0,1) == 0){
+                       Game::map->setNode(x,MAPHEIGHT-2,MAPGEN_BEDROCK);
+                       if(random(0,2) == 0){
+                               Game::map->setNode(x,MAPHEIGHT-3,MAPGEN_BEDROCK);
+                               }
+                       }
+               }
+       //Water
+       int flatcount = 0;
+       for(int x = 1; x < MAPWIDTH; x++){
+               if(bottom[x] == bottom[x-1]) flatcount++;
+               else if(flatcount > 7){
+                       int leftborder = rand() % 2;
+                       int rightborder = rand() % 2;
+                       for(int mx = x-flatcount-3; mx < x+2; mx++){
+                               for(int y = bottom[mx];y < bottom[mx]+5;y++){
+                                       if(Game::map->getNode(mx,y) == MAPGEN_STONE) break;
+                                       if(Game::map->getNode(mx,y) == MAPGEN_DIRT || Game::map->getNode(mx,y) == MAPGEN_GRASS) Game::map->setNode(mx,y,MAPGEN_SAND);
+                                       }
+                               }
+                       for(int mx = x-flatcount+leftborder;mx < x-1-rightborder;mx++) Game::map->setNode(mx,bottom[x-1],MAPGEN_WATER);
+                       for(int mx = x-flatcount+1+leftborder;mx < x-2-rightborder;mx++) Game::map->setNode(mx,bottom[x-1]+1,MAPGEN_WATER);
+                       for(int mx = x-flatcount+2+leftborder; mx < x-3-rightborder;mx++) Game::map->setNode(mx,bottom[x-1]+2,MAPGEN_WATER);
+                       flatcount = 0;
+                       }
+               else flatcount = 0;
+               }       
+       //Tree
+       int treecount = rand() % MAPWIDTH/10;
+       int treepos[treecount];
+       for(int i = 0; i < treecount; i++){
+               while(true){
+                       bool cont = true;
+                       treepos[i] = rand() % MAPWIDTH;
+                       for(int j = 0; j < i; j++){
+                               if(abs(treepos[j]-treepos[i]) < 3) cont = false; 
+                               }
+                       if(!(Game::map->getNode(treepos[i],bottom[treepos[i]]) == MAPGEN_GRASS)) cont = false;  
+                       if(cont) break; 
+                       }
+               int x = treepos[i];
+               int y = bottom[x] - 1;  
+               Game::map->setNode(x,y,MAPGEN_WOOD);
+               Game::map->setNode(x,y-1,MAPGEN_WOOD);
+               Game::map->setNode(x,y-2,MAPGEN_LEAVES);
+               Game::map->setNode(x,y-3,MAPGEN_LEAVES);
+               Game::map->setNode(x,y-4,MAPGEN_LEAVES);
+               Game::map->setNode(x-1,y-2,MAPGEN_LEAVES);
+               Game::map->setNode(x-1,y-3,MAPGEN_LEAVES);
+               Game::map->setNode(x-1,y-4,MAPGEN_LEAVES);
+               Game::map->setNode(x+1,y-2,MAPGEN_LEAVES);
+               Game::map->setNode(x+1,y-3,MAPGEN_LEAVES);
+               Game::map->setNode(x+1,y-4,MAPGEN_LEAVES);      
+               }
+       }
diff --git a/src/mapgen.h b/src/mapgen.h
new file mode 100644 (file)
index 0000000..50400aa
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef _MAPGEN_H_
+#define _MAPGEN_H_
+
+#include "map.h"
+
+#define MAPGEN_AIR Node::getNodeByName("dragonblocks:air")
+#define MAPGEN_GRASS Node::getNodeByName("dragonblocks:grass")
+#define MAPGEN_DIRT Node::getNodeByName("dragonblocks:dirt")
+#define MAPGEN_STONE Node::getNodeByName("dragonblocks:stone")
+#define MAPGEN_BEDROCK Node::getNodeByName("dragonblocks:bedrock")
+#define MAPGEN_MESE Node::getNodeByName("dragonblocks:mese")
+#define MAPGEN_LEAVES Node::getNodeByName("dragonblocks:leaves")
+#define MAPGEN_WOOD Node::getNodeByName("dragonblocks:wood")
+#define MAPGEN_WATER Node::getNodeByName("dragonblocks:water")
+#define MAPGEN_SAND Node::getNodeByName("dragonblocks:sand")
+
+void Mapgen();
+
+
+
+#endif
diff --git a/src/mods.cpp b/src/mods.cpp
new file mode 100644 (file)
index 0000000..9bc1442
--- /dev/null
@@ -0,0 +1,87 @@
+#include <cstring>
+#include <cstdio>
+#include <cerrno>
+#include <string>
+#include <iostream>
+
+#include "node.h"
+#include "mods.h"
+#include "game.h"
+#include "util.h"
+#include "graphics.h"
+
+using namespace std;
+
+lua_State *Mods::lua_vm;
+
+void Mods::init(){
+       Game::log("Initializing Mods");
+       lua_vm = luaL_newstate();
+       luaL_openlibs(lua_vm);
+       if(! check_lua(luaL_dofile(lua_vm, "builtin/init.lua"))){
+               Game::log("Failed to load Builtin", ERROR);
+               exit(EXIT_FAILURE);
+       return;
+       }
+       
+       for(;;){
+               lua_getglobal(lua_vm, "cpp_get_next_node");
+               if(!lua_isfunction(lua_vm, -1)){
+                       Game::log("Lua is sick. What's Wrong with her?", EASTEREGG);
+                       Game::log("No, seriously, something is wrong with the lua builtin (it is missing the function cpp_get_next_node)", ERROR);
+                       exit(EXIT_FAILURE);
+               }
+               lua_pcall(lua_vm, 0, 1, 0);
+               if(! lua_istable(lua_vm, -1))
+                       break;
+               
+               lua_pushstring(lua_vm, "name");
+               lua_gettable(lua_vm, -2);
+               if(!lua_isstring(lua_vm,-1))
+                       continue;
+               string name = lua_tostring(lua_vm,-1);
+               lua_pop(lua_vm, 1);
+               
+               lua_pushstring(lua_vm, "texture");
+               lua_gettable(lua_vm, -2);
+               if(!lua_isstring(lua_vm,-1))
+                       continue;
+               string texture = lua_tostring(lua_vm,-1);
+               lua_pop(lua_vm, 1);
+               
+               lua_pushstring(lua_vm, "hidden");
+               lua_gettable(lua_vm, -2);
+               if(!lua_isboolean(lua_vm,-1))
+                       continue;
+               bool hidden = lua_toboolean(lua_vm,-1);
+               lua_pop(lua_vm, 1);
+               
+               lua_pushstring(lua_vm, "stable");
+               lua_gettable(lua_vm, -2);
+               if(!lua_isboolean(lua_vm,-1))
+                       continue;
+               bool stable = lua_toboolean(lua_vm,-1);
+               lua_pop(lua_vm, 1);
+               
+               lua_pushstring(lua_vm, "translucent");
+               lua_gettable(lua_vm, -2);
+               if(!lua_isboolean(lua_vm,-1))
+                       continue;
+               bool translucent = lua_toboolean(lua_vm,-1);
+               lua_pop(lua_vm, 1);
+               
+               new Node(name, texture, hidden, stable, translucent);
+               Game::log("Registered Node " + name, INFO);
+       }
+}
+bool Mods::check_lua(int code){
+       if(code == LUA_OK)
+               return true;
+       else{
+               error(lua_tostring(lua_vm, -1));
+               return false;
+       }
+}
+void Mods::error(string text){
+       Game::log("\e[34mlua: \e[0m" + text, ERROR);
+}
diff --git a/src/mods.h b/src/mods.h
new file mode 100644 (file)
index 0000000..5e06c82
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _MODS_H_
+#define _MODS_H_
+
+#include <string>
+
+extern "C"{
+       #include <lua5.3/lua.h>
+       #include <lua5.3/lauxlib.h>
+       #include <lua5.3/lualib.h>
+}
+
+class Mods{
+       public:
+               static lua_State *lua_vm;
+               static bool check_lua(int);
+               static void init();
+               static void error(std::string);
+};
+#endif
diff --git a/src/node.cpp b/src/node.cpp
new file mode 100644 (file)
index 0000000..9fcd618
--- /dev/null
@@ -0,0 +1,44 @@
+#include <string>
+#include <stdlib.h>
+#include <iostream>
+#include "node.h"
+#include "game.h"
+#include "texture.h"
+using namespace std;
+
+int Node::count = 0;
+Node *Node::list[MAXNODES];
+
+Node::Node(string n, string t, bool h, bool s, bool tr){
+       if (Node::count >= MAXNODES)
+               Game::log("Too many registered Nodes", ERROR);
+       else{
+               name = n;
+               id = Node::count;
+               hidden = h;
+               stable = s;
+               Node::list[id] = this;
+               texture = new Texture(t,tr);
+               Node::count++;
+       }
+}
+Node *Node::getNodeById(int id){
+       if(id < count && id > -1)
+               return list[id];
+       return list[0]; 
+}
+Node *Node::getNodeByName(string name){
+       for(int i = 0; i < count; i++){
+               if(list[i]->name == name ){
+                       return list[i];
+               }
+       }
+       Game::log("Node "+name+" not found", WARNING);  
+       return list[0];         
+}      
+bool Node::operator==(Node *node){
+       return id == node->id;
+}
+bool Node::operator==(string n){
+       return name == n;
+}
diff --git a/src/node.h b/src/node.h
new file mode 100644 (file)
index 0000000..027bcbd
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _NODE_H_
+#define _NODE_H_
+#include <string>
+#include "texture.h"
+#define MAXNODES 1024
+
+
+class Node{
+       public:
+               int id;
+               std::string name;
+               static Node *getNodeById(int);
+               static Node *getNodeByName(std::string);
+               static Node *list[MAXNODES];
+               static int count;
+               bool operator==(Node *);
+               bool operator==(std::string);
+               Texture *texture;
+               bool hidden;
+               bool stable;
+               bool translucent;
+               Node(std::string, std::string, bool, bool, bool);
+};
+#endif
+
diff --git a/src/texture.cpp b/src/texture.cpp
new file mode 100644 (file)
index 0000000..a0d88fc
--- /dev/null
@@ -0,0 +1,74 @@
+#include <GL/freeglut.h>
+#include <png.h>
+#include <string>
+#include <iostream>
+#include <cstring>
+#include <cassert>
+#include <cstdio>
+
+#include "game.h"
+#include "graphics.h"
+#include "texture.h"
+
+
+using namespace std;
+
+
+Texture::Texture(string filename, bool t){
+       translucent = t;
+       dummyimage = false;
+       FILE *file = fopen(filename.c_str(), "rb");
+       if(!file){
+               Game::log("Failed to Load Image " + filename + ": File not found. Using a dummy Image.", WARNING);
+               dummyimage = true;
+               return;
+       }
+       png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+       assert(png);
+       png_infop info = png_create_info_struct(png);
+       assert(info);
+       png_init_io(png, file);
+       png_read_info(png, info);
+       width = png_get_image_width(png, info);
+       height = png_get_image_height(png, info);
+       color_type = png_get_color_type(png, info);
+       bit_depth  = png_get_bit_depth(png, info);
+       if(bit_depth == 16)
+               png_set_strip_16(png);
+       if(color_type == PNG_COLOR_TYPE_PALETTE)
+               png_set_palette_to_rgb(png);
+       #ifndef _WIN32
+       if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
+               png_set_expand_gray_1_2_4_to_8(png);
+       #endif
+       if(png_get_valid(png, info, PNG_INFO_tRNS))
+               png_set_tRNS_to_alpha(png);
+       if(color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)
+               png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
+       if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+               png_set_gray_to_rgb(png);
+       png_read_update_info(png, info);
+       row_pointers = (png_bytep*)malloc(sizeof(png_bytep) *height);
+       for(int y = 0; y < height; y++) {
+               row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png,info));
+       }
+       png_read_image(png, row_pointers);
+       fclose(file);
+       png_destroy_read_struct(&png, &info, NULL);
+}
+void Texture::draw(int displayX, int displayY, int displayWidth, int displayHeight){
+       if(dummyimage){
+               Graphics::drawRectangle(displayX, displayY, displayWidth, displayHeight, {0, 0, 0});
+               return;
+       }
+       int scaleX = (float)displayWidth/width;
+       int scaleY = (float)displayHeight/height;
+       for(int y = 0; y < height; y++) {
+               png_bytep row = row_pointers[y];
+               for(int x = 0; x < width; x++) {
+                       png_bytep px = &(row[x * 4]);
+                       if(!translucent || px[0] || px[1] || px[2])
+                               Graphics::drawRectangle(x*scaleX + displayX, y*scaleY + displayY, scaleX, scaleY, {(float)px[0]/255, (float)px[1]/255, (float)px[2]/255});
+               }
+       }
+}
diff --git a/src/texture.h b/src/texture.h
new file mode 100644 (file)
index 0000000..6a059bf
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _TEXTURE_H_
+#define _TEXTURE_H_
+
+#include <png.h>
+#include <string>
+
+class Texture{
+       public:
+               int width;
+               int height;
+               void draw(int, int, int, int);
+               Texture(std::string, bool);
+       private:
+               png_byte color_type;
+               png_byte bit_depth;
+               png_bytep *row_pointers;
+               bool dummyimage;
+               bool translucent;
+};
+#endif
diff --git a/src/threads.cpp b/src/threads.cpp
new file mode 100644 (file)
index 0000000..b4471a4
--- /dev/null
@@ -0,0 +1,57 @@
+#include <pthread.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <GL/glut.h>
+#include <iostream>
+#include <algorithm>
+#include "threads.h"
+#include "graphics.h"
+#include "game.h"
+
+
+using namespace std;
+
+void Threads::startMapBackupThread(){
+       Game::log("Starting Map Backup Thread");
+       pthread_t thread_id;
+       pthread_create(&thread_id, NULL, &mapBackupThread, NULL);
+}
+void *Threads::mapBackupThread(void *unused){
+       while(true){
+               sleep(MAP_BACKUP_INTERVAL);
+               Game::map -> save();
+       }
+       return NULL;
+}
+void Threads::startGraphicUpdateThread(){
+       Game::log("Starting Graphic Update Thread");
+       pthread_t thread_id;
+       pthread_create(&thread_id, NULL, &graphicUpdateThread, NULL);
+}
+void *Threads::graphicUpdateThread(void *unused){
+       while(true){
+               usleep(1);
+               if(glutGetWindow())
+                       glutPostRedisplay();
+       }
+       return NULL;
+}
+void Threads::addSignalHandlers(){
+#ifndef _WIN32
+       struct sigaction sa_sigterm;
+       sa_sigterm.sa_handler = &signal_handler;
+       sigaction(SIGTERM, &sa_sigterm, NULL);
+       
+       struct sigaction sa_sigint;
+       sa_sigint.sa_handler = &signal_handler;
+       sigaction(SIGINT, &sa_sigint, NULL);
+#endif
+}
+void Threads::signal_handler(int signal_number){
+#ifndef _WIN32
+       Game::log((string)"Got "+sys_siglist[signal_number]+" Signal, Exiting.");
+       Game::map -> save();
+       exit(0);
+#endif 
+}
diff --git a/src/threads.h b/src/threads.h
new file mode 100644 (file)
index 0000000..e8fce5b
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _THREADS_H_
+#define _THREADS_H_
+
+#define MAP_BACKUP_INTERVAL 15
+
+class Threads{
+       public:
+               static void startMapBackupThread();
+               static void addSignalHandlers();
+               static void startGraphicUpdateThread();
+       private:
+               static void *mapBackupThread(void *);
+               static void *graphicUpdateThread(void *);
+               static void signal_handler(int);
+};
+#endif
+
diff --git a/src/util.cpp b/src/util.cpp
new file mode 100644 (file)
index 0000000..600a742
--- /dev/null
@@ -0,0 +1,40 @@
+#include <stdlib.h>
+#include <cstring>
+#include <cstdio>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <cstdio>
+#include <string>
+
+#include "util.h"
+#include "game.h"
+
+using namespace std;
+int random(int min, int max){
+       return min + rand() % (max - min + 1);
+}
+color::color(const char *htmlcolor){
+       unsigned int r, g, b;
+       sscanf(htmlcolor, "#%2x%2x%2x", &r, &g, &b);
+       red = (float) r / 255;
+       green = (float) g / 255;
+       blue = (float) b / 255;
+}
+color::color(float r, float g, float b){
+       red = r;
+       green = g;
+       blue = b;
+}
+void create_dir_if_not_exists(string d){
+       const char *dir = d.c_str();
+       struct stat dir_exists_st = {0};        
+       if(stat(dir, &dir_exists_st) == -1){
+               Game::log((string)dir + " doesn't exist, creating", INFO);
+               #ifdef _WIN32
+               mkdir(dir);
+               #else
+               mkdir(dir, 0700);
+               #endif
+       }
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644 (file)
index 0000000..05419cd
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef _UTIL_H_
+#define _UTIL_H_
+#include <string>
+class color{
+       public:
+               float red;
+               float green;
+               float blue;
+               color(const char *);
+               color(float, float, float);
+};
+class position{
+       public:
+               int x;
+               int y;
+};
+
+int random(int, int);
+void create_dir_if_not_exists(std::string d);
+#endif
diff --git a/textures/air.png b/textures/air.png
new file mode 100644 (file)
index 0000000..cfdb4c8
Binary files /dev/null and b/textures/air.png differ
diff --git a/textures/bedrock.png b/textures/bedrock.png
new file mode 100644 (file)
index 0000000..2d29423
Binary files /dev/null and b/textures/bedrock.png differ
diff --git a/textures/cobble.png b/textures/cobble.png
new file mode 100644 (file)
index 0000000..d379840
Binary files /dev/null and b/textures/cobble.png differ
diff --git a/textures/dirt.png b/textures/dirt.png
new file mode 100644 (file)
index 0000000..afe4a2e
Binary files /dev/null and b/textures/dirt.png differ
diff --git a/textures/grass.png b/textures/grass.png
new file mode 100644 (file)
index 0000000..2608cd7
Binary files /dev/null and b/textures/grass.png differ
diff --git a/textures/leaves.png b/textures/leaves.png
new file mode 100644 (file)
index 0000000..ba09fe1
Binary files /dev/null and b/textures/leaves.png differ
diff --git a/textures/mese.png b/textures/mese.png
new file mode 100644 (file)
index 0000000..e30994e
Binary files /dev/null and b/textures/mese.png differ
diff --git a/textures/sand.png b/textures/sand.png
new file mode 100644 (file)
index 0000000..645a300
Binary files /dev/null and b/textures/sand.png differ
diff --git a/textures/stone.png b/textures/stone.png
new file mode 100644 (file)
index 0000000..63cb7c4
Binary files /dev/null and b/textures/stone.png differ
diff --git a/textures/unknown_node.png b/textures/unknown_node.png
new file mode 100644 (file)
index 0000000..cb59ff4
Binary files /dev/null and b/textures/unknown_node.png differ
diff --git a/textures/water.png b/textures/water.png
new file mode 100644 (file)
index 0000000..00500e9
Binary files /dev/null and b/textures/water.png differ
diff --git a/textures/wood.png b/textures/wood.png
new file mode 100644 (file)
index 0000000..10e297b
Binary files /dev/null and b/textures/wood.png differ