worldgen basic demo

isolation_bkp/dynres
Dominik Madarász 2021-01-11 17:20:12 +01:00
parent 61403ce807
commit bdb04aa2b0
10 changed files with 103 additions and 57 deletions

View File

@ -4,13 +4,16 @@ add_executable(eco2d-server
source/perlin.c source/perlin.c
source/options.c source/options.c
source/world.c source/world.c
source/world_gen.c
source/blocks.c source/blocks.c
header/network.h header/network.h
header/perlin.h header/perlin.h
header/options.h header/options.h
header/world.h header/world.h
header/world_gen.h
header/blocks.h header/blocks.h
header/blocks_info.h
) )
include_directories(eco2d-server header) include_directories(eco2d-server header)

View File

@ -1,18 +1,18 @@
#pragma once #pragma once
#include "system.h" #include "system.h"
#define BLOCKS_ERROR_NONE +0x0000 #define BLOCK_INVALID 0xF
#define BLOCKS_ERROR_OUTOFMEM -0x0001
#define BLOCKS_ERROR_NOTFOUND -0x0002
#define BLOCKS_ERROR_INVALID -0x0003
typedef enum { typedef enum {
BLOCK_FLAG_COLLISION = (1 << 0) BLOCK_FLAG_COLLISION = (1 << 0)
} block_flags; } block_flags;
int32_t blocks_init(void); #include "blocks_info.h"
int32_t blocks_destroy(void);
uint8_t blocks_find(uint32_t biome, uint32_t kind);
// persisting buffer // persisting buffer
char *blocks_get_name(uint8_t id); char *blocks_get_name(uint8_t id);
uint8_t blocks_get_tex_id(uint8_t id);
char blocks_get_symbol(uint8_t id);
uint32_t blocks_get_flags(uint8_t id); uint32_t blocks_get_flags(uint8_t id);

View File

@ -0,0 +1,18 @@
#pragma once
typedef enum {
BLOCK_KIND_DEV,
BLOCK_KIND_GROUND,
BLOCK_KIND_WATER,
BLOCK_KIND_WALL,
BLOCK_KIND_HOLE,
} block_kind;
typedef enum {
BLOCK_BIOME_DEV,
BLOCK_BIOME_PLAIN,
BLOCK_BIOME_FOREST,
BLOCK_BIOME_DESERT,
BLOCK_BIOME_ICE,
BLOCK_BIOME_OCEAN,
} block_biome;

View File

@ -0,0 +1,3 @@
#pragma once
int32_t world_gen(uint8_t *world, uint32_t size, uint32_t width, uint32_t height, int32_t seed);

View File

@ -4,47 +4,39 @@
// todo: csv parsing + utils // todo: csv parsing + utils
#define BLOCK_NAMELEN 80 #define BLOCK_NAMELEN 80
#define BLOCKS_COUNT (sizeof(blocks)/sizeof(block))
typedef struct { typedef struct {
uint8_t id; uint8_t tex_id;
char name[BLOCK_NAMELEN]; char name[BLOCK_NAMELEN];
uint32_t flags; uint32_t flags;
uint32_t kind;
uint32_t biome;
char symbol;
} block; } block;
static block *blocks = NULL; #include "blocks_list.c"
static uint32_t blocks_count = 0;
int blocks_comparer(void const *a, void const *b) { uint8_t blocks_find(uint32_t biome, uint32_t kind) {
block *ba = (block*)a; for (int i=0; i<BLOCKS_COUNT; i++) {
uint8_t bb = *(uint8_t*)b; if (blocks[i].biome == biome && blocks[i].kind == kind)
return ba->id < bb ? -1 : ba->id > bb; return i;
} }
return BLOCK_INVALID;
static block *blocks_find(uint8_t id) {
ZPL_ASSERT_NOT_NULL(blocks);
int32_t index = zpl_binary_search((void*)blocks, blocks_count, sizeof(block), (void*)&id, blocks_comparer);
ZPL_ASSERT_MSG(index != -1, "block could not be found");
return &blocks[index];
}
int32_t blocks_init(void) {
// todo read csv by lines, linecount-1 == blocks_count
// preallocate and assign values
return BLOCKS_ERROR_NONE;
}
int32_t blocks_destroy(void) {
ZPL_ASSERT_NOT_NULL(blocks);
zpl_mfree(blocks);
return BLOCKS_ERROR_NONE;
} }
char *blocks_get_name(uint8_t id) { char *blocks_get_name(uint8_t id) {
ZPL_ASSERT_NOT_NULL(blocks); return blocks[id].name;
return blocks_find(id)->name; }
uint8_t blocks_get_tex_id(uint8_t id) {
return blocks[id].tex_id;
}
char blocks_get_symbol(uint8_t id) {
return blocks[id].symbol;
} }
uint32_t blocks_get_flags(uint8_t id) { uint32_t blocks_get_flags(uint8_t id) {
ZPL_ASSERT_NOT_NULL(blocks); return blocks[id].flags;
return blocks_find(id)->flags;
} }

View File

@ -0,0 +1,7 @@
#include "blocks.h"
static block blocks[] = {
{.tex_id = 0, .name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.'},
{.tex_id = 1, .name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#'},
{.tex_id = 2, .name = "base-water", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WATER, .biome = 0, .symbol = '~'},
};

View File

@ -1,18 +1,19 @@
#include "options.h" #include "options.h"
#include "perlin.h" #include "world.h"
#include "blocks.h"
#include "zpl.h" #include "zpl.h"
#define TEST_MAP_DIM 32 #define TEST_MAP_DIM 32
#define TEST_MAP_DEPTH 18
static char *map_pattern = "~~..,,oo---OO^^^@@";
void generate_minimap(int32_t seed) { void generate_minimap(int32_t seed) {
for (uint32_t y=0; y<TEST_MAP_DIM; y++) { world_init(seed, TEST_MAP_DIM, TEST_MAP_DIM);
for (uint32_t x=0; x<TEST_MAP_DIM; x++) { uint8_t *world;
double sample = perlin_fbm(seed, x, y, 1.0, 1) * TEST_MAP_DEPTH; uint32_t len = world_buf(&world, NULL);
zpl_printf("%c", map_pattern[(uint32_t)sample]); for (int i=0; i<len; i++) {
if (i > 0 && i % TEST_MAP_DIM == 0) {
zpl_printf("\n");
} }
zpl_printf("\n"); zpl_printf("%c", blocks_get_symbol(world[i]));
} }
world_destroy();
} }

View File

@ -4,8 +4,7 @@
static uint8_t *world = NULL; static uint8_t *world = NULL;
static uint32_t world_size = 0; static uint32_t world_size = 0;
static uint32_t world_width = 0; static uint32_t world_width = 0;
static uint32_t world_height = 0;
static int32_t world_gen(int32_t seed);
int32_t world_init(int32_t seed, uint8_t width, uint8_t height) { int32_t world_init(int32_t seed, uint8_t width, uint8_t height) {
if (world) { if (world) {
@ -13,12 +12,13 @@ int32_t world_init(int32_t seed, uint8_t width, uint8_t height) {
} }
world_size = width*height; world_size = width*height;
world_width = width; world_width = width;
world_height = height;
world = zpl_malloc(sizeof(uint8_t)*world_size); world = zpl_malloc(sizeof(uint8_t)*world_size);
if (!world) { if (!world) {
return WORLD_ERROR_OUTOFMEM; return WORLD_ERROR_OUTOFMEM;
} }
return world_gen(seed); return world_gen(world, world_size, world_width, world_height, seed);
} }
int32_t world_destroy(void) { int32_t world_destroy(void) {
@ -34,9 +34,3 @@ uint32_t world_buf(uint8_t const **ptr, uint32_t *width) {
if (width) *width = world_width; if (width) *width = world_width;
return world_size; return world_size;
} }
static int32_t world_gen(int32_t seed) {
// TODO: perform world gen
return WORLD_ERROR_NONE;
}

View File

@ -0,0 +1,31 @@
#include "world.h"
#include "blocks.h"
#include "zpl.h"
static void world_fill(uint8_t *world, uint32_t width, uint32_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h) {
for (uint32_t cy=y; cy<y+h; cy++) {
for (uint32_t cx=x; cx<x+w; cx++) {
uint32_t i = (cy*width) + cx;
world[i] = id;
}
}
}
int32_t world_gen(uint8_t *world, uint32_t size, uint32_t width, uint32_t height, int32_t seed) {
// TODO: perform world gen
// atm, we will fill the world with ground and surround it by walls
uint32_t wall_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
uint32_t grnd_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
uint32_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
// walls
world_fill(world, width, wall_id, 0, 0, width, height);
// ground
world_fill(world, width, grnd_id, 1, 1, width-2, height-2);
// water
world_fill(world, width, watr_id, 5, 5, 3, 3);
return WORLD_ERROR_NONE;
}

View File

@ -1,3 +0,0 @@
id,name,flags
0,base_ground,0
1,base_wall,1
1 id name flags
2 0 base_ground 0
3 1 base_wall 1