From 8d6cb03cd83b9f6576909058601af54f16c8acfe Mon Sep 17 00:00:00 2001 From: Paweł Redman Date: Mon, 9 Oct 2017 19:24:08 +0200 Subject: Refactoring and basic map generation. --- src/common.hpp | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 101 insertions(+), 13 deletions(-) (limited to 'src/common.hpp') 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 #include #include +#include #include -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 entities; public: + sf::FloatRect bounds; + std::unordered_set 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 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 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 +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 +T mod(T x, T y) +{ + return (x % y) + (x < 0 ? y : 0); +} + +// Linear interpolation. +template +T lerp(T a, T b, T x) +{ + return a * (1 - x) + b * x; +} + +// Bilinear interpolation. +template +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); +} -- cgit