code: various bits and pieces

isolation_bkp/dynres
Dominik Madarász 2021-08-09 15:35:47 +02:00
parent f0dbc5a651
commit 999763f197
17 changed files with 121 additions and 44 deletions

View File

@ -16,6 +16,7 @@ add_executable(eco2d
src/entity_view.c src/entity_view.c
src/packet.c src/packet.c
src/player.c src/player.c
src/vehicle.c
src/signal_handling.c src/signal_handling.c
src/profiler.c src/profiler.c
src/debug_ui.c src/debug_ui.c

View File

@ -89,6 +89,16 @@ static debug_item items[] = {
} }
} }
}, },
{
.kind = DITEM_LIST,
.name = "debug actions",
.list = {
.items = (debug_item[]) {
{ .kind = DITEM_BUTTON, .name = "spawn car", .on_click = ActSpawnCar },
{ .kind = DITEM_END },
}
}
},
{ {
.kind = DITEM_LIST, .kind = DITEM_LIST,
.name = "profilers", .name = "profilers",

View File

@ -1,8 +1,14 @@
#include "debug_ui.h" #include "debug_ui.h"
#include "raylib.h" #include "raylib.h"
#include "vehicle.h"
#include "game.h" #include "game.h"
static inline void static inline void
ActExitGame(void) { ActExitGame(void) {
game_request_close(); game_request_close();
} }
static inline void
ActSpawnCar(void) {
vehicle_spawn();
}

View File

@ -10,14 +10,12 @@
#include "zpl.h" #include "zpl.h"
uint64_t entity_spawn(uint16_t class_id) { uint64_t entity_spawn(uint16_t class_id) {
ECS_IMPORT(world_ecs(), Components);
ecs_entity_t e = ecs_new(world_ecs(), 0); ecs_entity_t e = ecs_new(world_ecs(), 0);
ecs_set(world_ecs(), e, Velocity, {0}); w_ecs_set(e, Velocity, {0});
ecs_set(world_ecs(), e, Classify, { .id = class_id }); w_ecs_set(e, Classify, { .id = class_id });
ecs_add(world_ecs(), e, Walking); w_ecs_add(e, Walking);
Position *pos = ecs_get_mut(world_ecs(), e, Position, NULL); Position *pos = w_ecs_get_mut(e, Position, NULL);
#if 1 #if 1
pos->x=rand() % world_dim(); pos->x=rand() % world_dim();
pos->y=rand() % world_dim(); pos->y=rand() % world_dim();

View File

@ -7,6 +7,7 @@
typedef enum { typedef enum {
EKIND_SERVER = 0, EKIND_SERVER = 0,
EKIND_PLAYER, EKIND_PLAYER,
EKIND_VEHICLE,
EKIND_DEMO_NPC, EKIND_DEMO_NPC,
EKIND_MONSTER, EKIND_MONSTER,
EKIND_CHUNK, EKIND_CHUNK,

View File

@ -81,7 +81,7 @@ world_view *game_world_view_get_active(void) {
void game_world_view_cycle_active(int8_t dir) { void game_world_view_cycle_active(int8_t dir) {
uint16_t idx = (uint16_t)(active_viewer - world_viewers); uint16_t idx = (uint16_t)(active_viewer - world_viewers);
game_world_view_set_active_by_idx((idx+dir)%zpl_buffer_count(world_viewers)); game_world_view_set_active_by_idx(zpl_max(0, (idx+dir)%zpl_buffer_count(world_viewers)));
} }
void game_world_view_set_active_by_idx(uint16_t idx) { void game_world_view_set_active_by_idx(uint16_t idx) {
ZPL_ASSERT(idx >= 0 && idx < zpl_buffer_count(world_viewers)); ZPL_ASSERT(idx >= 0 && idx < zpl_buffer_count(world_viewers));

View File

@ -28,13 +28,12 @@ size_t pkt_00_init_send(uint16_t view_id) {
} }
int32_t pkt_00_init_handler(pkt_header *header) { int32_t pkt_00_init_handler(pkt_header *header) {
ECS_IMPORT(world_ecs(), Components);
pkt_00_init table; pkt_00_init table;
PKT_IF(pkt_msg_decode(header, pkt_00_init_desc, pkt_pack_desc_args(pkt_00_init_desc), PKT_STRUCT_PTR(&table))); PKT_IF(pkt_msg_decode(header, pkt_00_init_desc, pkt_pack_desc_args(pkt_00_init_desc), PKT_STRUCT_PTR(&table)));
uint64_t peer_id = (uint64_t)header->udata; uint64_t peer_id = (uint64_t)header->udata;
uint64_t ent_id = player_spawn(NULL); uint64_t ent_id = player_spawn(NULL);
ecs_set(world_ecs(), ent_id, ClientInfo, {.peer = ent_id, .view_id = header->view_id }); w_ecs_set(ent_id, ClientInfo, {.peer = ent_id, .view_id = header->view_id });
pkt_01_welcome_send(peer_id, header->view_id, ent_id, world_chunk_size(), world_chunk_amount()); pkt_01_welcome_send(peer_id, header->view_id, ent_id, world_chunk_size(), world_chunk_amount());
return 0; return 0;
} }

View File

@ -32,11 +32,9 @@ int32_t pkt_send_keystate_handler(pkt_header *header) {
pkt_send_keystate table; pkt_send_keystate table;
PKT_IF(pkt_msg_decode(header, pkt_send_keystate_desc, pkt_pack_desc_args(pkt_send_keystate_desc), PKT_STRUCT_PTR(&table))); PKT_IF(pkt_msg_decode(header, pkt_send_keystate_desc, pkt_pack_desc_args(pkt_send_keystate_desc), PKT_STRUCT_PTR(&table)));
ecs_entity_t e = PKT_GET_ENT(header); ecs_entity_t e = PKT_GET_ENT(header);
ecs_world_t *ecs = world_ecs();
ECS_IMPORT(ecs, Components); Input *i = w_ecs_get_mut(e, Input, NULL);
Input *i = ecs_get_mut(world_ecs(), e, Input, NULL); if (i && !i->is_blocked) {
if (i) {
i->x = table.x; i->x = table.x;
i->y = table.y; i->y = table.y;
i->use = table.use; i->use = table.use;

View File

@ -19,14 +19,12 @@ uint64_t player_spawn(char *name) {
name = zpl_bprintf("player_%d", e); name = zpl_bprintf("player_%d", e);
} }
ECS_IMPORT(world_ecs(), Components);
ecs_set(world_ecs(), e, EcsName, {.alloc_value = name }); ecs_set(world_ecs(), e, EcsName, {.alloc_value = name });
ecs_add(world_ecs(), e, EcsClient); w_ecs_add(e, EcsClient);
ecs_set(world_ecs(), e, ClientInfo, {0}); w_ecs_set(e, ClientInfo, {0});
ecs_set(world_ecs(), e, Input, {0}); w_ecs_set(e, Input, {0});
ecs_set(world_ecs(), e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP}); w_ecs_set(e, Health, {.hp = PLAYER_MAX_HP, .max_hp = PLAYER_MAX_HP});
ecs_add(world_ecs(), e, Player); w_ecs_add(e, Player);
librg_entity_owner_set(world_tracker(), e, (int64_t)e); librg_entity_owner_set(world_tracker(), e, (int64_t)e);
@ -36,3 +34,6 @@ uint64_t player_spawn(char *name) {
void player_despawn(uint64_t ent_id) { void player_despawn(uint64_t ent_id) {
entity_despawn(ent_id); entity_despawn(ent_id);
} }
void player_freeze(uint64_t id, uint8_t state, uint8_t clear) {
}

View File

@ -3,3 +3,5 @@
uint64_t player_spawn(char *name); uint64_t player_spawn(char *name);
void player_despawn(uint64_t ent_id); void player_despawn(uint64_t ent_id);
void player_freeze(uint64_t id, uint8_t state, uint8_t clear);

View File

@ -0,0 +1,17 @@
#include "vehicle.h"
#include "entity.h"
#include "entity_view.h"
#include "world/world.h"
#include "modules/components.h"
uint64_t vehicle_spawn(void) {
ecs_entity_t e = entity_spawn(EKIND_VEHICLE);
w_ecs_add(e, Vehicle);
return (uint64_t)e;
}
void vehicle_despawn(uint64_t ent_id) {
entity_despawn(ent_id);
}

View File

@ -0,0 +1,7 @@
#pragma once
#include "system.h"
uint64_t vehicle_spawn(void);
void vehicle_despawn(uint64_t id);

View File

@ -10,39 +10,44 @@
#include "packets/pkt_send_librg_update.h" #include "packets/pkt_send_librg_update.h"
ZPL_TABLE(static, world_snapshot, world_snapshot_, entity_view);
static world_data world = {0}; static world_data world = {0};
static Components const *ecs_components; static world_snapshot streamer_snapshot;
static ecs_entity_t components_handle;
entity_view world_build_entity_view(int64_t e) { entity_view world_build_entity_view(int64_t e) {
ECS_IMPORT(world.ecs, Components); entity_view *cached_ev = world_snapshot_get(&streamer_snapshot, e);
if (cached_ev) return *cached_ev;
entity_view view = {0}; entity_view view = {0};
const Classify *classify = ecs_get(world.ecs, e, Classify); const Classify *classify = w_ecs_get(e, Classify);
assert(classify); assert(classify);
view.kind = classify->id; view.kind = classify->id;
const Position *pos = ecs_get(world.ecs, e, Position); const Position *pos = w_ecs_get(e, Position);
if (pos) { if (pos) {
view.x = pos->x; view.x = pos->x;
view.y = pos->y; view.y = pos->y;
} }
const Velocity *vel = ecs_get(world.ecs, e, Velocity); const Velocity *vel = w_ecs_get(e, Velocity);
if (vel) { if (vel) {
view.flag |= EFLAG_INTERP; view.flag |= EFLAG_INTERP;
view.vx = vel->x; view.vx = vel->x;
view.vy = vel->y; view.vy = vel->y;
} }
const Health *health = ecs_get(world.ecs, e, Health); const Health *health = w_ecs_get(e, Health);
if (health) { if (health) {
view.hp = health->hp; view.hp = health->hp;
view.max_hp = health->max_hp; view.max_hp = health->max_hp;
} }
if (ecs_get(world.ecs, e, Chunk)) { if (w_ecs_get(e, Chunk)) {
Chunk *chpos = ecs_get_mut(world.ecs, e, Chunk, 0); Chunk *chpos = w_ecs_get_mut(e, Chunk, 0);
view.x = chpos->x; view.x = chpos->x;
view.y = chpos->y; view.y = chpos->y;
view.blocks_used = 1; view.blocks_used = 1;
@ -54,6 +59,7 @@ entity_view world_build_entity_view(int64_t e) {
} }
} }
world_snapshot_set(&streamer_snapshot, e, view);
return view; return view;
} }
@ -90,7 +96,6 @@ int32_t tracker_write_update(librg_world *w, librg_event *e) {
entity_view view = world_build_entity_view(entity_id); entity_view view = world_build_entity_view(entity_id);
// NOTE(zaklaus): exclude chunks from updates as they never move // NOTE(zaklaus): exclude chunks from updates as they never move
// TODO(zaklaus): use dirty flag to send updates if chunk changes
{ {
if (view.kind == EKIND_CHUNK && !view.is_dirty) { if (view.kind == EKIND_CHUNK && !view.is_dirty) {
return LIBRG_WRITE_REJECT; return LIBRG_WRITE_REJECT;
@ -149,7 +154,8 @@ int32_t world_init(int32_t seed, uint16_t chunk_size, uint16_t chunk_amount) {
world.ecs_update = ecs_query_new(world.ecs, "components.ClientInfo, components.Position"); 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.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.block_mapping = zpl_malloc(sizeof(uint8_t*)*zpl_square(chunk_amount));
ecs_components = ecs_get(world.ecs, ecs_typeid(Components), Components); components_handle = ecs_typeid(Components);
world_snapshot_init(&streamer_snapshot, zpl_heap());
int32_t world_build_status = worldgen_test(&world); int32_t world_build_status = worldgen_test(&world);
ZPL_ASSERT(world_build_status >= 0); ZPL_ASSERT(world_build_status >= 0);
@ -190,6 +196,7 @@ int32_t world_destroy(void) {
zpl_mfree(world.block_mapping[i]); zpl_mfree(world.block_mapping[i]);
} }
zpl_mfree(world.block_mapping); zpl_mfree(world.block_mapping);
world_snapshot_destroy(&streamer_snapshot);
zpl_memset(&world, 0, sizeof(world)); zpl_memset(&world, 0, sizeof(world));
zpl_printf("[INFO] World was destroyed.\n"); zpl_printf("[INFO] World was destroyed.\n");
return WORLD_ERROR_NONE; return WORLD_ERROR_NONE;
@ -202,8 +209,6 @@ static void world_tracker_update(uint8_t ticker, uint32_t freq, uint8_t radius)
world.tracker_update[ticker] = zpl_time_rel_ms() + freq; world.tracker_update[ticker] = zpl_time_rel_ms() + freq;
profile(PROF_WORLD_WRITE) { profile(PROF_WORLD_WRITE) {
ECS_IMPORT(world.ecs, Components);
ecs_iter_t it = ecs_query_iter(world.ecs_update); ecs_iter_t it = ecs_query_iter(world.ecs_update);
static char buffer[WORLD_LIBRG_BUFSIZ] = {0}; static char buffer[WORLD_LIBRG_BUFSIZ] = {0};
world.active_layer_id = ticker; world.active_layer_id = ticker;
@ -230,13 +235,18 @@ static void world_tracker_update(uint8_t ticker, uint32_t freq, uint8_t radius)
pkt_send_librg_update((uint64_t)p[i].peer, p[i].view_id, ticker, buffer, datalen); pkt_send_librg_update((uint64_t)p[i].peer, p[i].view_id, ticker, buffer, datalen);
} }
} }
// NOTE(zaklaus): clear out our streaming snapshot
// TODO(zaklaus): move this to zpl
{
zpl_array_clear(streamer_snapshot.hashes);
zpl_array_clear(streamer_snapshot.entries);
}
} }
} }
int32_t world_update() { int32_t world_update() {
ECS_IMPORT(world.ecs, Components);
profile (PROF_UPDATE_SYSTEMS) { profile (PROF_UPDATE_SYSTEMS) {
ecs_progress(world.ecs, 0.0f); ecs_progress(world.ecs, 0.0f);
} }
@ -273,11 +283,12 @@ ecs_world_t * world_ecs() {
return world.ecs; return world.ecs;
} }
Components const* world_components(void) { Components const *world_components(void) {
return ecs_components; ecs_entity_t ecs_typeid(Components) = components_handle;
return ecs_get(world.ecs, ecs_typeid(Components), Components);
} }
librg_world * world_tracker() { librg_world *world_tracker() {
return world.tracker; return world.tracker;
} }
@ -366,14 +377,14 @@ uint8_t *world_chunk_get_blocks(int64_t id) {
void world_chunk_mark_dirty(ecs_entity_t e) { void world_chunk_mark_dirty(ecs_entity_t e) {
bool was_added=false; bool was_added=false;
Chunk *chunk = (Chunk *)ecs_get_mut_w_entity(world.ecs, e, ecs_components->ecs_typeid(Chunk), &was_added); Chunk *chunk = w_ecs_get_mut(e, Chunk, &was_added);
assert(!was_added); assert(!was_added);
if (chunk) chunk->is_dirty = true; if (chunk) chunk->is_dirty = true;
} }
uint8_t world_chunk_is_dirty(ecs_entity_t e) { uint8_t world_chunk_is_dirty(ecs_entity_t e) {
bool was_added=false; bool was_added=false;
Chunk *chunk = (Chunk *)ecs_get_mut_w_entity(world.ecs, e, ecs_components->ecs_typeid(Chunk), &was_added); Chunk *chunk = w_ecs_get_mut(e, Chunk, &was_added);
assert(!was_added); assert(!was_added);
if (chunk) return chunk->is_dirty; if (chunk) return chunk->is_dirty;
return false; return false;

View File

@ -3,6 +3,7 @@
#include "librg.h" #include "librg.h"
#include "packet.h" #include "packet.h"
#include "flecs/flecs.h" #include "flecs/flecs.h"
#include "flecs/flecs_meta.h"
#include "modules/components.h" #include "modules/components.h"
#define WORLD_ERROR_NONE +0x0000 #define WORLD_ERROR_NONE +0x0000
@ -52,9 +53,9 @@ int32_t world_read(void* data, uint32_t datalen, void *udata);
int32_t world_write(pkt_header *pkt, 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(uint8_t const **ptr, uint32_t *width);
ecs_world_t * world_ecs(void); ecs_world_t *world_ecs(void);
Components const* world_components(void); Components const *world_components(void);
librg_world * world_tracker(void); librg_world *world_tracker(void);
uint16_t world_chunk_size(void); uint16_t world_chunk_size(void);
uint16_t world_chunk_amount(void); uint16_t world_chunk_amount(void);
@ -78,3 +79,20 @@ uint8_t *world_chunk_get_blocks(int64_t id);
void world_chunk_mark_dirty(ecs_entity_t e); void world_chunk_mark_dirty(ecs_entity_t e);
uint8_t world_chunk_is_dirty(ecs_entity_t e); uint8_t world_chunk_is_dirty(ecs_entity_t e);
// NOTE(zaklaus): flecs wrappers for easier world access
#define w_ecs_set(entity, component, ...)\
ecs_set_ptr_w_entity(world_ecs(), entity, world_components()->ecs_typeid(component), sizeof(component), &(component)__VA_ARGS__)
#define w_ecs_add(entity, component)\
ecs_add_type(world_ecs(), entity, world_components()->ecs_type(component))
#define w_ecs_get(entity, component)\
((const component*)ecs_get_w_entity(world_ecs(), entity, world_components()->ecs_typeid(component)))
#define w_ecs_get_ref(ref, entity, component)\
((const component*)ecs_get_ref_w_entity(world_ecs(), ref, entity, world_components()->ecs_typeid(component)))
#define w_ecs_get_mut(entity, component, is_added)\
((component*)ecs_get_mut_w_entity(world_ecs(), entity, world_components()->ecs_typeid(component), is_added))

View File

@ -13,6 +13,7 @@ void ComponentsImport(ecs_world_t *ecs) {
ECS_META(ecs, Input); ECS_META(ecs, Input);
ECS_META(ecs, Health); ECS_META(ecs, Health);
ECS_META(ecs, Classify); ECS_META(ecs, Classify);
ECS_META(ecs, Vehicle);
ECS_TAG(ecs, Walking); ECS_TAG(ecs, Walking);
ECS_TAG(ecs, Flying); ECS_TAG(ecs, Flying);
@ -37,6 +38,7 @@ void ComponentsImport(ecs_world_t *ecs) {
ECS_SET_COMPONENT(Input); ECS_SET_COMPONENT(Input);
ECS_SET_COMPONENT(Health); ECS_SET_COMPONENT(Health);
ECS_SET_COMPONENT(Classify); ECS_SET_COMPONENT(Classify);
ECS_SET_COMPONENT(Vehicle);
ECS_SET_ENTITY(EcsClient); ECS_SET_ENTITY(EcsClient);
ECS_SET_ENTITY(Walking); ECS_SET_ENTITY(Walking);
ECS_SET_ENTITY(Flying); ECS_SET_ENTITY(Flying);

View File

@ -26,6 +26,7 @@ ECS_STRUCT(Input, {
float y; float y;
uint8_t use; uint8_t use;
uint8_t sprint; uint8_t sprint;
uint8_t is_blocked;
}); });
ECS_STRUCT(ClientInfo, { ECS_STRUCT(ClientInfo, {
@ -46,6 +47,10 @@ ECS_STRUCT(Classify, {
uint16_t id; uint16_t id;
}); });
ECS_STRUCT(Vehicle, {
uint64_t seats[4];
});
typedef struct { typedef struct {
ECS_DECLARE_COMPONENT(Chunk); ECS_DECLARE_COMPONENT(Chunk);
ECS_DECLARE_COMPONENT(Position); ECS_DECLARE_COMPONENT(Position);
@ -56,6 +61,7 @@ typedef struct {
ECS_DECLARE_COMPONENT(ClientInfo); ECS_DECLARE_COMPONENT(ClientInfo);
ECS_DECLARE_COMPONENT(Health); ECS_DECLARE_COMPONENT(Health);
ECS_DECLARE_COMPONENT(Classify); ECS_DECLARE_COMPONENT(Classify);
ECS_DECLARE_COMPONENT(Vehicle);
ECS_DECLARE_ENTITY(EcsActor); ECS_DECLARE_ENTITY(EcsActor);
ECS_DECLARE_ENTITY(EcsPlayer); ECS_DECLARE_ENTITY(EcsPlayer);
ECS_DECLARE_ENTITY(EcsBuilder); ECS_DECLARE_ENTITY(EcsBuilder);
@ -78,6 +84,7 @@ ECS_IMPORT_COMPONENT(handles, Velocity);\
ECS_IMPORT_COMPONENT(handles, ClientInfo);\ ECS_IMPORT_COMPONENT(handles, ClientInfo);\
ECS_IMPORT_COMPONENT(handles, Health);\ ECS_IMPORT_COMPONENT(handles, Health);\
ECS_IMPORT_COMPONENT(handles, Classify);\ ECS_IMPORT_COMPONENT(handles, Classify);\
ECS_IMPORT_COMPONENT(handles, Vehicle);\
ECS_IMPORT_TYPE(handles, Player);\ ECS_IMPORT_TYPE(handles, Player);\
ECS_IMPORT_TYPE(handles, Builder);\ ECS_IMPORT_TYPE(handles, Builder);\
ECS_IMPORT_TYPE(handles, Movement);\ ECS_IMPORT_TYPE(handles, Movement);\

View File

@ -149,7 +149,6 @@ void MovementImpulse(ecs_iter_t *it) {
void DemoNPCMoveAround(ecs_iter_t *it) { void DemoNPCMoveAround(ecs_iter_t *it) {
Velocity *v = ecs_column(it, Velocity, 1); Velocity *v = ecs_column(it, Velocity, 1);
for (int i = 0; i < it->count; i++) { for (int i = 0; i < it->count; i++) {
v[i].x = zpl_lerp(v[i].x, (rand()%3-1)*DEMO_NPC_MOVE_SPEED, DEMO_NPC_CHANGEDIR_FACTOR); v[i].x = zpl_lerp(v[i].x, (rand()%3-1)*DEMO_NPC_MOVE_SPEED, DEMO_NPC_CHANGEDIR_FACTOR);
v[i].y = zpl_lerp(v[i].y, (rand()%3-1)*DEMO_NPC_MOVE_SPEED, DEMO_NPC_CHANGEDIR_FACTOR); v[i].y = zpl_lerp(v[i].y, (rand()%3-1)*DEMO_NPC_MOVE_SPEED, DEMO_NPC_CHANGEDIR_FACTOR);