worldgen basic demo
parent
61403ce807
commit
bdb04aa2b0
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
|
@ -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);
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 = '~'},
|
||||||
|
};
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
id,name,flags
|
|
||||||
0,base_ground,0
|
|
||||||
1,base_wall,1
|
|
|
Loading…
Reference in New Issue