summaryrefslogtreecommitdiff
path: root/src/common.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common.hpp')
-rw-r--r--src/common.hpp114
1 files changed, 101 insertions, 13 deletions
diff --git a/src/common.hpp b/src/common.hpp
index aaf1cad..2dd7c45 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -2,16 +2,37 @@
#include <cstdint>
#include <cmath>
#include <map>
+#include <unordered_set>
#include <SFML/Graphics.hpp>
-namespace game {
- class entity_t {
- virtual void render(sf::RenderWindow *window) = 0;
+namespace procgen {
+ class prng_t {
+ uint32_t state = 0;
+
+ public:
+ void seed(uint32_t seed);
+ uint32_t next(void);
+ float next_float(void);
+ void unit_vec(float out[2]);
+
+ };
+
+ class perlin_noise_t {
+ size_t size;
+ float (*table)[2] = nullptr;
+
+ float table_dot(size_t nx, size_t ny, float dx, float dy);
+
+ public:
+ ~perlin_noise_t();
+
+ void generate(prng_t *prng, size_t size);
+ float get(float x, float y, float scale);
};
}
namespace world {
- #define SECTOR_SIZE 16
+ #define SECTOR_SIZE 8
class tile_t {
public:
@@ -27,30 +48,59 @@ namespace world {
bool operator<(sector_index_t B) const;
};
+ class entity_t;
+
class sector_t {
- std::vector<game::entity_t*> entities;
public:
+ sf::FloatRect bounds;
+ std::unordered_set<entity_t*> ents;
+
bool empty = true;
tile_t tiles[SECTOR_SIZE * SECTOR_SIZE];
-
- void generate(sector_index_t index);
};
class world_t {
+ procgen::prng_t prng;
+ procgen::perlin_noise_t perlin;
std::map<sector_index_t, sector_t> sectors;
+ void generate(sector_t *sector, sector_index_t index);
+
public:
+ world_t(void);
sector_t *get_sector(sector_index_t index);
tile_t *get_tile(ssize_t x, ssize_t y);
- void link(game::entity_t *entity);
- void unlink(game::entity_t *entity);
void render(sf::RenderWindow *window);
};
+
+ class entity_t {
+ world_t *parent_world;
+ std::vector<sector_t*> parents;
+
+ public:
+ sf::Vector2f origin, size;
+
+ void link(world_t *world);
+ void unlink();
+ };
+}
+
+namespace game {
+ class state_t {
+ world::world_t world;
+
+ public:
+ void tick(void);
+ void render(sf::RenderWindow *window_);
+ };
}
namespace interface {
class state_t {
+ sf::RenderWindow *window;
+ game::state_t *game;
+
struct {
sf::Vector2f center;
int target_zoom = 3;
@@ -60,11 +110,49 @@ namespace interface {
} camera;
public:
- sf::RenderWindow *window;
- world::world_t *world;
-
- state_t(sf::RenderWindow *window_, world::world_t *world_);
+ state_t(sf::RenderWindow *window_, game::state_t *game);
void tick(void);
void render(void);
};
}
+
+// Divide and round to minus infinity.
+template <typename T>
+T divide_rmi(T x, T y, T *rem)
+{
+ T rv;
+
+ if (x >= 0) {
+ *rem = x % y;
+ return x / y;
+ }
+
+ rv = (x + 1) / y - 1;
+ *rem = x - rv * y;
+ return rv;
+}
+
+// Modulo operation. y is expected to be positive.
+template <typename T>
+T mod(T x, T y)
+{
+ return (x % y) + (x < 0 ? y : 0);
+}
+
+// Linear interpolation.
+template <typename T>
+T lerp(T a, T b, T x)
+{
+ return a * (1 - x) + b * x;
+}
+
+// Bilinear interpolation.
+template <typename T>
+T bilerp(T a, T b, T c, T d, T x, T y)
+{
+ T ab, cd;
+
+ ab = lerp(a, b, x);
+ cd = lerp(c, d, x);
+ return lerp(ab, cd, y);
+}