raise block indexing to 16-bits!

isolation_bkp/dynres
Dominik Madarász 2021-11-03 18:38:32 +01:00
parent 7ecff06ae8
commit 16d2b41f3c
7 changed files with 72 additions and 72 deletions

View File

@ -48,9 +48,9 @@ typedef struct entity_view {
float max_hp;
// TODO(zaklaus): Find a way to stream dynamic arrays
uint8_t blocks_used;
uint8_t blocks[256];
uint8_t outer_blocks[256];
uint16_t blocks_used;
uint16_t blocks[256];
uint16_t outer_blocks[256];
uint32_t color;
uint8_t is_dirty;
int64_t tex;

View File

@ -37,7 +37,7 @@ typedef struct {
#include "blocks_list.c"
int32_t blocks_setup(void) {
for (uint32_t i=0; i<BLOCKS_COUNT; i++) {
for (uint16_t i=0; i<BLOCKS_COUNT; i++) {
blocks[i].slot = assets_find(blocks[i].kind);
}
blocks__chunk_tbl_init(&baked_chunks, zpl_heap());
@ -49,51 +49,51 @@ void blocks_destroy(void) {
blocks__chunk_tbl_destroy(&baked_chunks);
}
uint8_t blocks_find(asset_id kind) {
for (uint8_t i=0; i<BLOCKS_COUNT; i++) {
uint16_t blocks_find(asset_id kind) {
for (uint16_t i=0; i<BLOCKS_COUNT; i++) {
if (blocks[i].kind == kind)
return i;
}
return 0xF;
}
asset_id blocks_get_asset(uint8_t id) {
asset_id blocks_get_asset(uint16_t id) {
return blocks[id].kind;
}
char blocks_get_symbol(uint8_t id) {
char blocks_get_symbol(uint16_t id) {
return blocks[id].symbol;
}
uint32_t blocks_get_flags(uint8_t id) {
uint32_t blocks_get_flags(uint16_t id) {
return blocks[id].flags;
}
float blocks_get_drag(uint8_t id) {
float blocks_get_drag(uint16_t id) {
return blocks[id].drag;
}
float blocks_get_friction(uint8_t id) {
float blocks_get_friction(uint16_t id) {
return blocks[id].friction;
}
float blocks_get_bounce(uint8_t id) {
float blocks_get_bounce(uint16_t id) {
return blocks[id].bounce;
}
float blocks_get_velx(uint8_t id) {
float blocks_get_velx(uint16_t id) {
return blocks[id].velx;
}
float blocks_get_vely(uint8_t id) {
float blocks_get_vely(uint16_t id) {
return blocks[id].vely;
}
void *blocks_get_img(uint8_t id) {
void *blocks_get_img(uint16_t id) {
return assets_get_tex(blocks[id].slot);
}
void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, void *raw_view) {
void blocks_build_chunk_tex(uint64_t id, uint16_t *chunk_blocks, void *raw_view) {
world_view *view = (world_view*)raw_view;
uint16_t blk_dims = (uint16_t)(WORLD_BLOCK_SIZE * WORLD_TEXTURE_BLOCK_SCALE);
uint16_t dims = blk_dims * view->chunk_size;

View File

@ -11,20 +11,20 @@ typedef enum {
int32_t blocks_setup(void);
void blocks_destroy(void);
uint8_t blocks_find(asset_id kind);
uint16_t blocks_find(asset_id kind);
asset_id blocks_get_asset(uint8_t id);
char blocks_get_symbol(uint8_t id);
uint32_t blocks_get_flags(uint8_t id);
float blocks_get_drag(uint8_t id);
float blocks_get_friction(uint8_t id);
float blocks_get_bounce(uint8_t id);
float blocks_get_velx(uint8_t id);
float blocks_get_vely(uint8_t id);
asset_id blocks_get_asset(uint16_t id);
char blocks_get_symbol(uint16_t id);
uint32_t blocks_get_flags(uint16_t id);
float blocks_get_drag(uint16_t id);
float blocks_get_friction(uint16_t id);
float blocks_get_bounce(uint16_t id);
float blocks_get_velx(uint16_t id);
float blocks_get_vely(uint16_t id);
// NOTE(zaklaus): viewer-related functions
void *blocks_get_img(uint8_t id);
void *blocks_get_img(uint16_t id);
void blocks_build_chunk_tex(uint64_t id, uint8_t *blocks, void *view);
void blocks_build_chunk_tex(uint64_t id, uint16_t *blocks, void *view);
void *blocks_get_chunk_tex(uint64_t id);
void blocks_remove_chunk_tex(uint64_t id);

View File

@ -24,4 +24,4 @@ static block blocks[] = {
BLOCK(ASSET_BELT_DOWN, 0, '@', .drag = 1.0f , .friction = 1.0f, .vely = 150.0f),
};
ZPL_STATIC_ASSERT(sizeof(blocks)/sizeof(blocks[0]) < 256, "too many registered blocks! (max. 256)");
ZPL_STATIC_ASSERT(sizeof(blocks)/sizeof(block) < ZPL_U16_MAX, "too many registered blocks! (max. 65536)");

View File

@ -173,8 +173,8 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
librg_event_set(world.tracker, LIBRG_WRITE_REMOVE, tracker_write_remove);
librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, tracker_write_update);
world.data = zpl_malloc(sizeof(uint8_t)*world.size);
world.outer_data = zpl_malloc(sizeof(uint8_t)*world.size);
world.data = zpl_malloc(sizeof(uint16_t)*world.size);
world.outer_data = zpl_malloc(sizeof(uint16_t)*world.size);
if (!world.data || !world.outer_data) {
return WORLD_ERROR_OUTOFMEM;
@ -186,8 +186,8 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
ECS_IMPORT(world.ecs, Systems);
world.ecs_update = ecs_query_new(world.ecs, "components.ClientInfo, components.Position");
world.chunk_mapping = zpl_malloc(sizeof(ecs_entity_t)*zpl_square(chunk_amount));
world.block_mapping = zpl_malloc(sizeof(uint8_t*)*zpl_square(chunk_amount));
world.outer_block_mapping = zpl_malloc(sizeof(uint8_t*)*zpl_square(chunk_amount));
world.block_mapping = zpl_malloc(sizeof(uint16_t*)*zpl_square(chunk_amount));
world.outer_block_mapping = zpl_malloc(sizeof(uint16_t*)*zpl_square(chunk_amount));
world_snapshot_init(&streamer_snapshot, zpl_heap());
int32_t world_build_status = worldgen_test(&world);
@ -208,8 +208,8 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
librg_entity_chunk_set(world.tracker, e, i);
librg_chunk_to_chunkpos(world.tracker, i, &chunk->x, &chunk->y, NULL);
world.chunk_mapping[i] = e;
world.block_mapping[i] = zpl_malloc(sizeof(uint8_t)*zpl_square(chunk_size));
world.outer_block_mapping[i] = zpl_malloc(sizeof(uint8_t)*zpl_square(chunk_size));
world.block_mapping[i] = zpl_malloc(sizeof(uint16_t)*zpl_square(chunk_size));
world.outer_block_mapping[i] = zpl_malloc(sizeof(uint16_t)*zpl_square(chunk_size));
chunk->id = i;
chunk->is_dirty = false;
@ -218,7 +218,7 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
int chk_x = chunk->x * chunk_size;
int chk_y = chunk->y * chunk_size;
uint8_t *c = &world.block_mapping[i][(y*chunk_size)+x];
uint16_t *c = &world.block_mapping[i][(y*chunk_size)+x];
*c = world.data[(chk_y+y)*world.dim + (chk_x+x)];
c = &world.outer_block_mapping[i][(y*chunk_size)+x];
@ -255,7 +255,7 @@ int32_t world_destroy(void) {
#define WORLD_LIBRG_BUFSIZ 2000000
static void world_tracker_update(uint8_t ticker, uint32_t freq, uint8_t radius) {
static void world_tracker_update(uint16_t ticker, uint32_t freq, uint8_t radius) {
if (world.tracker_update[ticker] > zpl_time_rel_ms()) return;
world.tracker_update[ticker] = zpl_time_rel_ms() + freq;
@ -333,7 +333,7 @@ int32_t world_write(pkt_header *pkt, void *udata) {
return -1;
}
uint32_t world_buf(uint8_t const **ptr, uint32_t *width) {
uint32_t world_buf(uint16_t const **ptr, uint32_t *width) {
ZPL_ASSERT_NOT_NULL(world.data);
ZPL_ASSERT_NOT_NULL(ptr);
*ptr = world.data;
@ -413,7 +413,7 @@ world_block_lookup world_block_from_realpos(float x, float y) {
uint16_t bx = (uint16_t)chx / WORLD_BLOCK_SIZE;
uint16_t by = (uint16_t)chy / WORLD_BLOCK_SIZE;
uint16_t block_idx = (by*world.chunk_size)+bx;
uint8_t block_id = world.outer_block_mapping[chunk_id][block_idx];
uint16_t block_id = world.outer_block_mapping[chunk_id][block_idx];
bool is_outer = true;
if (block_id == 0) {
block_id = world.block_mapping[chunk_id][block_idx];
@ -453,7 +453,7 @@ void world_chunk_destroy_block(float x, float y, bool drop_item) {
}
world_block_lookup world_block_from_index(int64_t id, uint16_t block_idx) {
uint8_t block_id = world.outer_block_mapping[id][block_idx];
uint16_t block_id = world.outer_block_mapping[id][block_idx];
if (block_id == 0) {
block_id = world.block_mapping[id][block_idx];
}
@ -477,19 +477,19 @@ int64_t world_chunk_from_entity(ecs_entity_t id) {
return librg_entity_chunk_get(world.tracker, id);
}
void world_chunk_replace_worldgen_block(int64_t id, uint16_t block_idx, uint8_t block_id) {
void world_chunk_replace_worldgen_block(int64_t id, uint16_t block_idx, uint16_t block_id) {
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
world.block_mapping[id][block_idx] = block_id;
world_chunk_mark_dirty(world.chunk_mapping[id]);
}
void world_chunk_replace_block(int64_t id, uint16_t block_idx, uint8_t block_id) {
void world_chunk_replace_block(int64_t id, uint16_t block_idx, uint16_t block_id) {
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
world.outer_block_mapping[id][block_idx] = block_id;
world_chunk_mark_dirty(world.chunk_mapping[id]);
}
bool world_chunk_place_block(int64_t id, uint16_t block_idx, uint8_t block_id) {
bool world_chunk_place_block(int64_t id, uint16_t block_idx, uint16_t block_id) {
ZPL_ASSERT(block_idx >= 0 && block_idx < zpl_square(world.chunk_size));
if (world.outer_block_mapping[id][block_idx] != 0 && block_id != 0) return false;
world.outer_block_mapping[id][block_idx] = block_id;
@ -497,7 +497,7 @@ bool world_chunk_place_block(int64_t id, uint16_t block_idx, uint8_t block_id) {
return true;
}
uint8_t *world_chunk_get_blocks(int64_t id) {
uint16_t *world_chunk_get_blocks(int64_t id) {
return world.block_mapping[id];
}
@ -508,7 +508,7 @@ void world_chunk_mark_dirty(ecs_entity_t e) {
if (chunk) chunk->is_dirty = true;
}
uint8_t world_chunk_is_dirty(ecs_entity_t e) {
uint16_t world_chunk_is_dirty(ecs_entity_t e) {
bool was_added=false;
Chunk *chunk = ecs_get_mut(world_ecs(), e, Chunk, &was_added);
ZPL_ASSERT(!was_added);
@ -537,7 +537,7 @@ int64_t *world_chunk_query_entities(int64_t e, size_t *ents_len, int8_t radius)
return ents;
}
uint8_t world_entity_valid(ecs_entity_t e) {
bool world_entity_valid(ecs_entity_t e) {
if (!e) return false;
return ecs_is_alive(world_ecs(), e);
}

View File

@ -31,14 +31,14 @@ typedef WORLD_PKT_WRITER(world_pkt_writer_proc);
typedef struct {
bool is_paused;
uint8_t *data;
uint8_t *outer_data;
uint16_t *data;
uint16_t *outer_data;
uint32_t seed;
uint32_t size;
uint16_t chunk_size;
uint16_t chunk_amount;
uint8_t **block_mapping;
uint8_t **outer_block_mapping;
uint16_t **block_mapping;
uint16_t **outer_block_mapping;
uint16_t dim;
uint64_t tracker_update[3];
uint8_t active_layer_id;
@ -59,7 +59,7 @@ int32_t world_update(void);
int32_t world_read(void* data, uint32_t datalen, void *udata);
int32_t world_write(pkt_header *pkt, void *udata);
uint32_t world_buf(uint8_t const **ptr, uint32_t *width);
uint32_t world_buf(uint16_t const **ptr, uint32_t *width);
uint32_t world_seed(void);
ecs_world_t *world_ecs(void);
void world_set_stage(ecs_world_t *ecs);
@ -78,7 +78,7 @@ ecs_entity_t world_chunk_mapping(librg_chunk id);
typedef struct {
uint16_t id;
uint8_t block_id;
uint16_t block_id;
ecs_entity_t chunk_e;
int64_t chunk_id;
float ox, oy;
@ -91,25 +91,25 @@ int64_t world_chunk_from_realpos(float x, float y);
int64_t world_chunk_from_entity(ecs_entity_t id);
// NOTE(zaklaus): This changes the inner chunk layer, it should only be used for terraforming!
void world_chunk_replace_worldgen_block(int64_t id, uint16_t block_idx, uint8_t block_id);
void world_chunk_replace_worldgen_block(int64_t id, uint16_t block_idx, uint16_t block_id);
// NOTE(zaklaus): Replaces a block unconditionally
void world_chunk_replace_block(int64_t id, uint16_t block_idx, uint8_t block_id);
void world_chunk_replace_block(int64_t id, uint16_t block_idx, uint16_t block_id);
// NOTE(zaklaus): Places a block only if the outer layer's chunk slot is empty,
// it also allows us to remove a block from outer layer unconditionally
bool world_chunk_place_block(int64_t id, uint16_t block_idx, uint8_t block_id);
bool world_chunk_place_block(int64_t id, uint16_t block_idx, uint16_t block_id);
// NOTE(zaklaus): Convenience method to replace block with air and drop item optionally
void world_chunk_destroy_block(float x, float y, bool drop_item);
uint8_t *world_chunk_get_blocks(int64_t id);
uint16_t *world_chunk_get_blocks(int64_t id);
void world_chunk_mark_dirty(ecs_entity_t e);
uint8_t world_chunk_is_dirty(ecs_entity_t e);
uint16_t world_chunk_is_dirty(ecs_entity_t e);
// NOTE(zaklaus): Uses locally persistent buffer !!
int64_t *world_chunk_fetch_entities(librg_chunk chunk_id, size_t *ents_len);
int64_t *world_chunk_fetch_entities_realpos(float x, float y, size_t *ents_len);
int64_t *world_chunk_query_entities(int64_t e, size_t *ents_len, int8_t radius);
uint8_t world_entity_valid(ecs_entity_t e);
bool world_entity_valid(ecs_entity_t e);

View File

@ -12,7 +12,7 @@
#include "items.h"
#include "world/blocks_info.h"
#define WORLD_BLOCK_OBSERVER(name) uint8_t name(uint8_t *data, uint8_t id, uint32_t block_idx)
#define WORLD_BLOCK_OBSERVER(name) uint16_t name(uint16_t *data, uint16_t id, uint32_t block_idx)
typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
#define WORLD_PERLIN_FREQ 100
@ -20,7 +20,7 @@ typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
#define BLOCK_INVALID 0xF
uint8_t worldgen_biome_find(uint32_t biome, uint32_t kind) {
uint16_t worldgen_biome_find(uint32_t biome, uint32_t kind) {
asset_id asset = ASSET_INVALID;
switch (biome) {
case BLOCK_BIOME_DEV: {
@ -41,7 +41,7 @@ uint8_t worldgen_biome_find(uint32_t biome, uint32_t kind) {
static world_data *world;
static void world_fill_rect(uint8_t *data, uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
static void world_fill_rect(uint16_t *data, uint16_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
for (uint32_t cy=y; cy<y+h; cy++) {
for (uint32_t cx=x; cx<x+w; cx++) {
if (cx < 0 || cx >= world->dim) continue;
@ -49,7 +49,7 @@ static void world_fill_rect(uint8_t *data, uint8_t id, uint32_t x, uint32_t y, u
uint32_t i = (cy*world->dim) + cx;
if (proc) {
uint8_t new_id = (*proc)(data, id, i);
uint16_t new_id = (*proc)(data, id, i);
if (new_id != BLOCK_INVALID) {
id = new_id;
}
@ -61,7 +61,7 @@ static void world_fill_rect(uint8_t *data, uint8_t id, uint32_t x, uint32_t y, u
}
}
static void world_fill_circle(uint8_t *data, uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
static void world_fill_circle(uint16_t *data, uint16_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
for (uint32_t cy=y; cy<y+h; cy++) {
for (uint32_t cx=x; cx<x+w; cx++) {
if (cx < 0 || cx >= world->dim) continue;
@ -69,7 +69,7 @@ static void world_fill_circle(uint8_t *data, uint8_t id, uint32_t x, uint32_t y,
uint32_t i = (cy*world->dim) + cx;
if (proc) {
uint8_t new_id = (*proc)(data, id, i);
uint16_t new_id = (*proc)(data, id, i);
if (new_id != BLOCK_INVALID) {
id = new_id;
}
@ -81,7 +81,7 @@ static void world_fill_circle(uint8_t *data, uint8_t id, uint32_t x, uint32_t y,
}
}
static void world_fill_rect_anchor(uint8_t *data, uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, float ax, float ay, world_block_observer_proc *proc) {
static void world_fill_rect_anchor(uint16_t *data, uint16_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, float ax, float ay, world_block_observer_proc *proc) {
uint32_t w2 = (uint32_t)floorf(w*ax);
uint32_t h2 = (uint32_t)floorf(h*ay);
world_fill_rect(data, id, x-w2, y-h2, w, h, proc);
@ -101,14 +101,14 @@ static WORLD_BLOCK_OBSERVER(shaper) {
return id;
}
static uint8_t world_perlin_cond_offset(uint32_t block_idx, double chance, uint32_t ofx, uint32_t ofy) {
static uint16_t world_perlin_cond_offset(uint32_t block_idx, double chance, uint32_t ofx, uint32_t ofy) {
uint32_t x = block_idx % world->dim + ofx;
uint32_t y = block_idx / world->dim + ofy;
return perlin_fbm(world->seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance;
}
static uint8_t world_perlin_cond(uint32_t block_idx, double chance) {
static uint16_t world_perlin_cond(uint32_t block_idx, double chance) {
return world_perlin_cond_offset(block_idx, chance, 0, 0);
}
@ -162,12 +162,12 @@ int32_t worldgen_test(world_data *wld) {
// TODO: perform world gen
// atm, we will fill the world with ground and surround it by walls
uint8_t wall_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
uint8_t grnd_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
uint8_t dirt_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT);
uint8_t watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
uint8_t lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA);
uint8_t tree_id = blocks_find(ASSET_TREE);
uint16_t wall_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
uint16_t grnd_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
uint16_t dirt_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT);
uint16_t watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
uint16_t lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA);
uint16_t tree_id = blocks_find(ASSET_TREE);
srand(world->seed);