rewrite block system

isolation_bkp/dynres
Dominik Madarász 2021-11-02 12:49:03 +01:00
parent f8da96b968
commit 365b3e8ee3
13 changed files with 127 additions and 127 deletions

View File

@ -16,6 +16,15 @@ typedef enum {
// NOTE(zaklaus): blocks
ASSET_FENCE,
ASSET_DEV,
ASSET_GROUND,
ASSET_DIRT,
ASSET_WATER,
ASSET_LAVA,
ASSET_WALL,
ASSET_HILL,
ASSET_HILL_SNOW,
ASSET_HOLE,
MAX_ASSETS,
FORCE_ASSET_UINT16 = UINT16_MAX

View File

@ -1,16 +1,24 @@
#include "assets.h"
#define ASSET_TEX(asset)\
{\
.id = asset,\
.kind = AKIND_TEXTURE,\
}
static asset assets[] = {
{
.id = ASSET_EMPTY,
.kind = AKIND_TEXTURE,
},
{
.id = ASSET_DEMO_ICEMAKER,
.kind = AKIND_TEXTURE,
},
{
.id = ASSET_FENCE,
.kind = AKIND_TEXTURE,
}
ASSET_TEX(ASSET_EMPTY),
ASSET_TEX(ASSET_DEMO_ICEMAKER),
// NOTE(zaklaus): blocks
ASSET_TEX(ASSET_FENCE),
ASSET_TEX(ASSET_DEV),
ASSET_TEX(ASSET_GROUND),
ASSET_TEX(ASSET_DIRT),
ASSET_TEX(ASSET_WATER),
ASSET_TEX(ASSET_LAVA),
ASSET_TEX(ASSET_WALL),
ASSET_TEX(ASSET_HILL),
ASSET_TEX(ASSET_HILL_SNOW),
ASSET_TEX(ASSET_HOLE),
};

View File

@ -58,7 +58,7 @@ ActSpawnCirclingDriver(void) {
void
ActPlaceIceRink(void) {
ecs_entity_t plr = camera_get().ent_id;
uint8_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
uint8_t watr_id = blocks_find(ASSET_WATER);
Position const *p = ecs_get(world_ecs(), plr, Position);
float const bs = WORLD_BLOCK_SIZE;

View File

@ -96,7 +96,7 @@ void entity_view_mark_for_fadein(entity_view_tbl *map, uint64_t ent_id) {
void entity_view_update_chunk_texture(entity_view_tbl *map, uint64_t ent_id, void *world_view) {
entity_view *view = entity_view_tbl_get(map, ent_id);
if (view->kind != EKIND_CHUNK) return;
blocks_build_chunk_tex(ent_id, view->blocks, view->outer_blocks, world_view);
blocks_build_chunk_tex(ent_id, view->blocks, world_view);
}
void entity_view_remove_chunk_texture(entity_view_tbl *map, uint64_t ent_id) {

View File

@ -12,31 +12,19 @@ Texture2D LoadImageEco(const char *name) {
return LoadTexture(filename);
}
Texture2D texgen_build_block(uint32_t biome, uint32_t kind) {
switch (biome) {
case BLOCK_BIOME_DEV: {
switch (kind) {
case BLOCK_KIND_GROUND: return LoadImageEco("grass");
case BLOCK_KIND_DIRT: return LoadImageEco("dirt");
case BLOCK_KIND_WALL: return LoadImageEco("asphalt");
case BLOCK_KIND_HILL_SNOW:
case BLOCK_KIND_HILL: return LoadImageEco("rock");
case BLOCK_KIND_WATER: return LoadImageEco("water");
case BLOCK_KIND_LAVA: return LoadImageEco("lava");
}
}
}
Image img = GenImageColor(WORLD_BLOCK_SIZE,WORLD_BLOCK_SIZE,ColorFromHSV(biome+kind*30, 0.13f, 0.89f));
Texture2D tex = LoadTextureFromImage(img);
UnloadImage(img);
return tex;
}
Texture2D texgen_build_sprite(asset_id id) {
switch (id) {
case ASSET_DEMO_ICEMAKER: return LoadImageEco("demo_icemaker");
// NOTE(zaklaus): blocks
case ASSET_FENCE: return LoadImageEco("fence");
case ASSET_GROUND: return LoadImageEco("grass");
case ASSET_DIRT: return LoadImageEco("dirt");
case ASSET_WALL: return LoadImageEco("asphalt");
case ASSET_HILL_SNOW:
case ASSET_HILL: return LoadImageEco("rock");
case ASSET_WATER: return LoadImageEco("water");
case ASSET_LAVA: return LoadImageEco("lava");
default: {
Image img = GenImageColor(1, 1, RAYWHITE);

View File

@ -4,5 +4,4 @@
#include "world/blocks.h"
#include "assets.h"
Texture2D texgen_build_block(uint32_t biome, uint32_t kind);
Texture2D texgen_build_sprite(asset_id id);

View File

@ -40,7 +40,7 @@ void item_use(ecs_world_t *ecs, ItemDrop *it, Position p) {
switch (item_get_usage(item_id)) {
case UKIND_PLACE:{
world_block_lookup l = world_block_from_realpos(p.x, p.y);
if (world_chunk_place_block(l.chunk_id, l.id, blocks_find(desc->place.biome, desc->place.kind)) )
if (world_chunk_place_block(l.chunk_id, l.id, blocks_find(desc->place.kind)) )
it->quantity--;
}break;
}

View File

@ -19,8 +19,7 @@ typedef struct {
// NOTE(zaklaus): usage data
union {
struct {
block_biome biome;
block_kind kind;
asset_id kind;
} place;
};
} item_desc;

View File

@ -1,18 +1,22 @@
#include "items.h"
#define ITEM_BLOCK(asset, qty, build_asset)\
{\
.kind = asset,\
.usage = UKIND_PLACE,\
.max_quantity = qty,\
.place = {\
.kind = build_asset,\
}\
}
#define ITEM_SELF(asset, qty) ITEM_BLOCK(asset, qty, asset)
static item_desc items[] = {
{
.kind = 0,
.max_quantity = 0,
},
{
.kind = ASSET_DEMO_ICEMAKER,
.usage = UKIND_PLACE,
.max_quantity = 64,
.place = {
.biome = BLOCK_BIOME_DEV,
.kind = BLOCK_KIND_WATER,
}
}
};
ITEM_BLOCK(ASSET_DEMO_ICEMAKER, 64, ASSET_WATER),
ITEM_SELF(ASSET_FENCE, 64),
};

View File

@ -20,50 +20,38 @@ static void chunks_unload_textures(uint64_t key, RenderTexture2D *value) {
}
typedef struct {
char *name;
asset_id kind;
uint32_t flags;
uint32_t kind;
uint32_t biome;
char symbol;
float drag;
float friction;
float bounce;
// NOTE(zaklaus): viewer data
Texture2D img;
uint16_t slot;
} block;
#include "blocks_list.c"
int32_t blocks_setup(void) {
for (uint32_t i=0; i<BLOCKS_COUNT; i++) {
block *b = &blocks[i];
b->img = texgen_build_block(b->biome, b->kind);
blocks[i].slot = assets_find(blocks[i].kind);
}
blocks__chunk_tbl_init(&baked_chunks, zpl_heap());
return 0;
}
void blocks_destroy(void) {
for (uint32_t i=0; i<BLOCKS_COUNT; i++) {
UnloadTexture(blocks[i].img);
}
blocks__chunk_tbl_map_mut(&baked_chunks, chunks_unload_textures);
blocks__chunk_tbl_destroy(&baked_chunks);
}
uint8_t blocks_find(uint32_t biome, uint32_t kind) {
for (uint32_t i=0; i<BLOCKS_COUNT; i++) {
if (blocks[i].biome == biome && blocks[i].kind == kind)
uint8_t blocks_find(asset_id kind) {
for (uint8_t i=0; i<BLOCKS_COUNT; i++) {
if (blocks[i].kind == kind)
return i;
}
return BLOCK_INVALID;
}
char *blocks_get_name(uint8_t id) {
return blocks[id].name;
return 0xF;
}
char blocks_get_symbol(uint8_t id) {
@ -74,14 +62,6 @@ uint32_t blocks_get_flags(uint8_t id) {
return blocks[id].flags;
}
uint32_t blocks_get_biome(uint8_t id) {
return blocks[id].biome;
}
uint32_t blocks_get_kind(uint8_t id) {
return blocks[id].kind;
}
float blocks_get_drag(uint8_t id) {
return blocks[id].drag;
}
@ -95,39 +75,25 @@ float blocks_get_bounce(uint8_t id) {
}
void *blocks_get_img(uint8_t id) {
return (void*)&blocks[id].img;
return assets_get_tex(blocks[id].slot);
}
void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, uint8_t *outer_chunk_blocks, void *raw_view) {
void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, void *raw_view) {
world_view *view = (world_view*)raw_view;
uint16_t blk_dims = WORLD_BLOCK_SIZE * WORLD_TEXTURE_BLOCK_SCALE;
uint16_t blk_dims = (uint16_t)(WORLD_BLOCK_SIZE * WORLD_TEXTURE_BLOCK_SCALE);
uint16_t dims = blk_dims * view->chunk_size;
RenderTexture2D canvas = LoadRenderTexture(dims, dims);
BeginTextureMode(canvas);
ClearBackground(WHITE);
for (int y = 0; y < view->chunk_size; y += 1) {
for (int x = 0; x < view->chunk_size; x += 1) {
#if 0
Texture2D blk = blocks[chunk_blocks[(y*view->chunk_size)+x]].img;
Rectangle src = {0, 0, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE};
Rectangle dst = {x*blk_dims, y*blk_dims, blk_dims, blk_dims};
DrawTexturePro(blk, src, dst, (Vector2){0.0f,0.0f}, 0.0f, WHITE);
#else
static float rots[] = { 0.0f, 90.0f, 180.f, 270.0f };
float rot = rots[(int32_t)(perlin_fbm(view->seed, x, y, 1.2f, 3) * 4.0f) % 4];
float half_block = blk_dims / 2.0f;
Texture2D blk = blocks[chunk_blocks[(y*view->chunk_size)+x]].img;
Texture2D blk = *(Texture2D*)blocks_get_img(chunk_blocks[(y*view->chunk_size)+x]);
Rectangle src = {0, 0, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE};
Rectangle dst = {x*blk_dims + half_block, y*blk_dims + half_block, blk_dims, blk_dims};
DrawTexturePro(blk, src, dst, (Vector2){half_block, half_block}, rot, WHITE);
#if 0
if (outer_chunk_blocks[(y*view->chunk_size)+x] != 0) {
Texture2D blk2 = blocks[outer_chunk_blocks[(y*view->chunk_size)+x]].img;
DrawTexturePro(blk2, src, dst, (Vector2){half_block, half_block}, rot, WHITE);
}
#endif
#endif
}
}
EndTextureMode();

View File

@ -1,25 +1,20 @@
#pragma once
#include "system.h"
#define BLOCK_INVALID 0xF
#include "assets.h"
typedef enum {
BLOCK_FLAG_COLLISION = (1 << 1),
BLOCK_FLAG_HAZARD = (1 << 2),
} block_flags;
#include "blocks_info.h"
int32_t blocks_setup(void);
void blocks_destroy(void);
uint8_t blocks_find(uint32_t biome, uint32_t kind);
uint8_t blocks_find(asset_id kind);
char *blocks_get_name(uint8_t id);
char blocks_get_symbol(uint8_t id);
uint32_t blocks_get_flags(uint8_t id);
uint32_t blocks_get_biome(uint8_t id);
uint32_t blocks_get_kind(uint8_t id);
float blocks_get_drag(uint8_t id);
float blocks_get_friction(uint8_t id);
float blocks_get_bounce(uint8_t id);
@ -27,6 +22,6 @@ float blocks_get_bounce(uint8_t id);
// NOTE(zaklaus): viewer-related functions
void *blocks_get_img(uint8_t id);
void blocks_build_chunk_tex(uint64_t id, uint8_t *blocks, uint8_t *outer_blocks, void *view);
void blocks_build_chunk_tex(uint64_t id, uint8_t *blocks, void *view);
void *blocks_get_chunk_tex(uint64_t id);
void blocks_remove_chunk_tex(uint64_t id);

View File

@ -1,12 +1,18 @@
#include "world/blocks.h"
#define BLOCK(a, f, s, ...)\
{\
.kind = a, .flags = f, .symbol = s, __VA_ARGS__\
}
static block blocks[] = {
{.name = "empty", .flags = 0, .kind = BLOCK_KIND_EMPTY, .biome = 0, .symbol = ' ', .drag = 1.0f, .friction = 1.0f },
{.name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.', .drag = 1.0f, .friction = 1.0f },
{.name = "base-dirt", .flags = 0, .kind = BLOCK_KIND_DIRT, .biome = 0, .symbol = ',', .drag = 2.1f , .friction = 1.0f },
{.name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f },
{.name = "base-hill", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL, .biome = 0, .symbol = '^', .drag = 1.0f , .friction = 1.0f },
{.name = "base-hill-snow", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL_SNOW, .biome = 0, .symbol = '*', .drag = 1.0f , .friction = 1.0f },
{.name = "base-water", .flags = 0, .kind = BLOCK_KIND_WATER, .biome = 0, .symbol = '~', .drag = 0.11f , .friction = 1.0f },
{.name = "base-lava", .flags = BLOCK_FLAG_HAZARD, .kind = BLOCK_KIND_LAVA, .biome = 0, .symbol = '!', .drag = 6.2f , .friction = 4.0f },
BLOCK(ASSET_EMPTY, 0, ' ', .drag = 1.0f, .friction = 1.0f),
BLOCK(ASSET_GROUND, 0, '.', .drag = 1.0f, .friction = 1.0f),
BLOCK(ASSET_DIRT, 0, ',', .drag = 2.1f , .friction = 1.0f),
BLOCK(ASSET_WALL, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f),
BLOCK(ASSET_HILL, BLOCK_FLAG_COLLISION, '^', .drag = 1.0f , .friction = 1.0f),
BLOCK(ASSET_HILL_SNOW, BLOCK_FLAG_COLLISION, '*', .drag = 1.0f , .friction = 1.0f),
BLOCK(ASSET_WATER, 0, '~', .drag = 0.11f , .friction = 1.0f),
BLOCK(ASSET_LAVA, BLOCK_FLAG_HAZARD, '!', .drag = 6.2f , .friction = 4.0f),
BLOCK(ASSET_FENCE, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f),
};

View File

@ -10,6 +10,7 @@
#include "modules/components.h"
#include "vehicle.h"
#include "items.h"
#include "world/blocks_info.h"
#define WORLD_BLOCK_OBSERVER(name) uint8_t name(uint8_t id, uint32_t block_idx)
typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
@ -17,6 +18,27 @@ typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
#define WORLD_PERLIN_FREQ 100
#define WORLD_PERLIN_OCTAVES 1
#define BLOCK_INVALID 0xF
uint8_t worldgen_biome_find(uint32_t biome, uint32_t kind) {
asset_id asset = ASSET_INVALID;
switch (biome) {
case BLOCK_BIOME_DEV: {
switch (kind) {
case BLOCK_KIND_GROUND: asset = ASSET_GROUND; break;
case BLOCK_KIND_DIRT: asset = ASSET_DIRT; break;
case BLOCK_KIND_WALL: asset = ASSET_WALL; break;
case BLOCK_KIND_HILL_SNOW:
case BLOCK_KIND_HILL: asset = ASSET_HILL; break;
case BLOCK_KIND_WATER: asset = ASSET_WATER; break;
case BLOCK_KIND_LAVA: asset = ASSET_LAVA; break;
}
}
}
return blocks_find(asset);
}
static world_data *world;
static void world_fill_rect(uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
@ -66,18 +88,14 @@ static void world_fill_rect_anchor(uint8_t id, uint32_t x, uint32_t y, uint32_t
}
static WORLD_BLOCK_OBSERVER(shaper) {
uint32_t biome = blocks_get_biome(id);
uint32_t kind = blocks_get_kind(id);
uint32_t old_biome = blocks_get_biome(world->data[block_idx]);
uint32_t old_kind = blocks_get_kind(world->data[block_idx]);
uint32_t kind = id;
uint32_t old_kind = world->data[block_idx];
if (biome == old_biome) {
if (kind == BLOCK_KIND_WALL && kind == old_kind) {
return blocks_find(biome, BLOCK_KIND_HILL);
}
if (kind == BLOCK_KIND_HILL && kind == old_kind) {
return blocks_find(biome, BLOCK_KIND_HILL_SNOW);
}
if (kind == BLOCK_KIND_WALL && kind == old_kind) {
return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL);
}
if (kind == BLOCK_KIND_HILL && kind == old_kind) {
return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL_SNOW);
}
return id;
@ -134,11 +152,11 @@ 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 = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
uint8_t grnd_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
uint8_t dirt_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT);
uint8_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
uint8_t lava_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA);
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);
srand(world->seed);
@ -197,6 +215,14 @@ int32_t worldgen_test(world_data *wld) {
dest->x = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE);
}
for (int i=0; i<RAND_RANGE(328, 164); i++) {
uint64_t e = item_spawn(ASSET_FENCE, 64);
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
dest->x = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE);
}
#endif
return WORLD_ERROR_NONE;