From 1ad39ad67e885245f8c397e8ddc0fe7dfc083870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Madar=C3=A1sz?= Date: Fri, 7 May 2021 16:43:54 +0200 Subject: [PATCH] player movement impl wip --- code/apps/client/header/world_view.h | 3 ++- code/apps/client/source/game.c | 8 +++++-- code/apps/client/source/platform_raylib.c | 14 ++++++++++++ code/apps/client/source/world_view.c | 3 ++- code/common/game.h | 5 +++++ code/common/packet.c | 1 + code/common/packet_utils.h | 22 +++++++++++-------- code/common/packets/pkt_send_keystate.c | 26 ++++++++++++++++++++--- code/common/packets/pkt_send_keystate.h | 5 ++++- code/common/player.c | 4 ++++ code/modules/modules/controllers.h | 2 ++ code/modules/modules/physics.h | 3 ++- code/modules/source/controllers.c | 19 ++++++++++++++++- code/modules/source/physics.c | 9 +++++--- code/vendors/librg.h | 2 -- 15 files changed, 102 insertions(+), 24 deletions(-) diff --git a/code/apps/client/header/world_view.h b/code/apps/client/header/world_view.h index d5ade23..dbadbca 100644 --- a/code/apps/client/header/world_view.h +++ b/code/apps/client/header/world_view.h @@ -4,6 +4,7 @@ #include "world/world.h" typedef struct { + uint16_t view_id; uint64_t owner_id; entity_view_tbl entities; librg_world *tracker; @@ -16,6 +17,6 @@ typedef struct { uint16_t world_size; } world_view; -world_view world_view_create(void); +world_view world_view_create(uint16_t view_id); void world_view_init(world_view *view, uint64_t ent_id, uint16_t block_size, uint16_t chunk_size, uint16_t world_size); void world_view_destroy(world_view *view); diff --git a/code/apps/client/source/game.c b/code/apps/client/source/game.c index ac4b9f1..cf9987a 100644 --- a/code/apps/client/source/game.c +++ b/code/apps/client/source/game.c @@ -16,6 +16,7 @@ #include "packets/pkt_00_init.h" #include "packets/pkt_01_welcome.h" +#include "packets/pkt_send_keystate.h" static int8_t is_viewer_only; @@ -36,7 +37,7 @@ static WORLD_PKT_READER(pkt_reader) { } static WORLD_PKT_WRITER(sp_pkt_writer) { - return world_read(pkt->data, pkt->datalen, 0); + return world_read(pkt->data, pkt->datalen, (void*)game_world_view_get_active()->owner_id); } static WORLD_PKT_WRITER(mp_pkt_writer) { @@ -52,7 +53,7 @@ void world_viewers_init(uint32_t num_viewers) { zpl_buffer_init(world_viewers, zpl_heap(), num_viewers); for (uint32_t i = 0; i < num_viewers; i++) { - world_viewers[i] = world_view_create(); + world_viewers[i] = world_view_create(i); } } @@ -145,3 +146,6 @@ void game_render() { platform_render(); } +void game_action_send_keystate(double x, double y, uint8_t use) { + pkt_send_keystate_send(active_viewer->view_id, x, y, use); +} \ No newline at end of file diff --git a/code/apps/client/source/platform_raylib.c b/code/apps/client/source/platform_raylib.c index 085d5b5..ad74439 100644 --- a/code/apps/client/source/platform_raylib.c +++ b/code/apps/client/source/platform_raylib.c @@ -34,6 +34,20 @@ void platform_input() { if (mouse_z != 0.0f) { render_camera.zoom = zpl_clamp(render_camera.zoom+mouse_z*0.04f, 0.01f, 1.0f); } + + // NOTE(zaklaus): keystate handling + { + double x=0.0, y=0.0; + uint8_t use; + if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) x += 1.0f; + if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) x -= 1.0f; + if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)) y -= 1.0f; + if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)) y += 1.0f; + + use = IsKeyPressed(KEY_SPACE); + + pkt_send_keystate_send(game_world_view_get_active()->view_id, x, y, use); + } } void display_conn_status(); diff --git a/code/apps/client/source/world_view.c b/code/apps/client/source/world_view.c index 14ffb5d..3f54e59 100644 --- a/code/apps/client/source/world_view.c +++ b/code/apps/client/source/world_view.c @@ -35,8 +35,9 @@ int32_t tracker_read_create(librg_world *w, librg_event *e) { return 0; } -world_view world_view_create(void) { +world_view world_view_create(uint16_t view_id) { world_view view = {0}; + view.view_id = view_id; view.tracker = librg_world_create(); entity_view_init(&view.entities); return view; diff --git a/code/common/game.h b/code/common/game.h index 9824684..0d73ca6 100644 --- a/code/common/game.h +++ b/code/common/game.h @@ -7,11 +7,16 @@ void game_shutdown(); uint8_t game_is_running(); int8_t game_is_networked(); +//~ NOTE(zaklaus): game events void game_input(); void game_update(); void game_render(); +//~ NOTE(zaklaus): world view management world_view *game_world_view_get_active(void); world_view *game_world_view_get(uint16_t idx); void game_world_view_set_active_by_idx(uint16_t idx); void game_world_view_set_active(world_view *view); + +//~ NOTE(zaklaus): viewer -> host actions +void game_action_send_keystate(double x, double y, uint8_t use); \ No newline at end of file diff --git a/code/common/packet.c b/code/common/packet.c index f4d462c..80124a5 100644 --- a/code/common/packet.c +++ b/code/common/packet.c @@ -15,6 +15,7 @@ pkt_handler pkt_handlers[] = { {.id = MSG_ID_00_INIT, .handler = pkt_00_init_handler}, {.id = MSG_ID_01_WELCOME, .handler = pkt_01_welcome_handler}, {.id = MSG_ID_LIBRG_UPDATE, .handler = pkt_send_librg_update_handler}, + {.id = MSG_ID_SEND_KEYSTATE, .handler = pkt_send_keystate_handler}, }; uint8_t pkt_buffer[PKT_BUFSIZ]; diff --git a/code/common/packet_utils.h b/code/common/packet_utils.h index e6cae59..eae54a8 100644 --- a/code/common/packet_utils.h +++ b/code/common/packet_utils.h @@ -7,12 +7,12 @@ #define PKT_IF(c) if (c < 0) return -1; #endif -inline void pkt_pack_msg(cw_pack_context *pc, uint32_t args) { +static inline void pkt_pack_msg(cw_pack_context *pc, uint32_t args) { cw_pack_context_init(pc, pkt_buffer, PKT_BUFSIZ, 0); cw_pack_array_size(pc, args); } -inline int32_t pkt_unpack_msg(cw_unpack_context *uc, pkt_header *header, uint32_t args) { +static inline int32_t pkt_unpack_msg(cw_unpack_context *uc, pkt_header *header, uint32_t args) { cw_unpack_context_init(uc, header->data, header->datalen, 0); cw_unpack_next(uc); @@ -23,23 +23,23 @@ inline int32_t pkt_unpack_msg(cw_unpack_context *uc, pkt_header *header, uint32_ return 0; } -inline int32_t pkt_unpack_msg_raw(cw_unpack_context *uc, uint8_t *data, uint32_t datalen, uint32_t args) { +static inline int32_t pkt_unpack_msg_raw(cw_unpack_context *uc, uint8_t *data, uint32_t datalen, uint32_t args) { pkt_header header = {.data = data, .datalen = datalen}; return pkt_unpack_msg(uc, &header, args); } -inline int32_t pkt_validate_eof_msg(cw_unpack_context *uc) { +static inline int32_t pkt_validate_eof_msg(cw_unpack_context *uc) { if (uc->return_code != CWP_RC_OK) return -1; // unpacking failed somwwhere cw_unpack_next(uc); if (uc->return_code != CWP_RC_END_OF_INPUT) return -1; // not finished yet but should be? return 0; } -inline size_t pkt_pack_msg_size(cw_pack_context *pc) { +static inline size_t pkt_pack_msg_size(cw_pack_context *pc) { return pc->current - pc->start; // NOTE(zaklaus): length } -inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, uint16_t view_id, size_t pkt_size, int8_t is_reliable) { +static inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, uint16_t view_id, size_t pkt_size, int8_t is_reliable) { zpl_zero_item(pkt); static uint8_t pkt_data[PKT_BUFSIZ] = {0}; zpl_memcopy(pkt_data, pkt_buffer, pkt_size); @@ -54,7 +54,7 @@ inline int32_t pkt_prep_msg(pkt_header *pkt, pkt_messages id, uint16_t view_id, extern int32_t world_write(pkt_header *pkt, void *udata); -inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_reliable, uint16_t view_id, void *udata) { +static inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_reliable, uint16_t view_id, void *udata) { pkt_header pkt; PKT_IF(pkt_prep_msg(&pkt, id, view_id, pkt_size, is_reliable)); return world_write(&pkt, udata); @@ -101,6 +101,10 @@ inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_relia #define PKT_END .type = CWP_NOT_AN_ITEM #endif +#ifndef PKT_GET_ENT +#define PKT_GET_ENT(h) (ecs_entity_t)(h->udata) +#endif + typedef struct pkt_desc { cwpack_item_types type; size_t offset; @@ -110,7 +114,7 @@ typedef struct pkt_desc { int32_t pkt_unpack_struct(cw_unpack_context *uc, pkt_desc *desc, void *raw_blob, uint32_t blob_size); -inline int32_t pkt_msg_decode(pkt_header *header, pkt_desc* desc, uint32_t args, void *raw_blob, uint32_t blob_size) { +static inline int32_t pkt_msg_decode(pkt_header *header, pkt_desc* desc, uint32_t args, void *raw_blob, uint32_t blob_size) { cw_unpack_context uc = {0}; PKT_IF(pkt_unpack_msg(&uc, header, args)); PKT_IF(pkt_unpack_struct(&uc, desc, raw_blob, blob_size)); @@ -118,7 +122,7 @@ inline int32_t pkt_msg_decode(pkt_header *header, pkt_desc* desc, uint32_t args, return pkt_validate_eof_msg(&uc); } -inline size_t pkt_pack_desc_args(pkt_desc *desc) { +static inline size_t pkt_pack_desc_args(pkt_desc *desc) { size_t cnt = 0; for (pkt_desc *field = desc; field->type != CWP_NOT_AN_ITEM; ++field, ++cnt) {} return cnt; diff --git a/code/common/packets/pkt_send_keystate.c b/code/common/packets/pkt_send_keystate.c index 47d6a15..88c5207 100644 --- a/code/common/packets/pkt_send_keystate.c +++ b/code/common/packets/pkt_send_keystate.c @@ -1,13 +1,23 @@ #include "packet_utils.h" #include "packets/pkt_send_keystate.h" +#include "modules/controllers.h" +#include "world/world.h" pkt_desc pkt_send_keystate_desc[] = { - { PKT_FIELD(CWP_ITEM_DOUBLE, pkt_send_keystate, x) }, - { PKT_FIELD(CWP_ITEM_DOUBLE, pkt_send_keystate, y) }, - { PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_send_keystate, use) }, + { PKT_REAL(pkt_send_keystate, x) }, + { PKT_REAL(pkt_send_keystate, y) }, + { PKT_UINT(pkt_send_keystate, use) }, { PKT_END }, }; +size_t pkt_send_keystate_send(uint16_t view_id, + double x, + double y, + uint8_t use) { + pkt_send_keystate table = { .x = x, .y = y, .use = use }; + return pkt_world_write(MSG_ID_SEND_KEYSTATE, pkt_send_keystate_encode(&table), 1, view_id, NULL); +} + size_t pkt_send_keystate_encode(pkt_send_keystate *table) { cw_pack_context pc = {0}; pkt_pack_msg(&pc, pkt_pack_desc_args(pkt_send_keystate_desc)); @@ -18,6 +28,16 @@ size_t pkt_send_keystate_encode(pkt_send_keystate *table) { int32_t pkt_send_keystate_handler(pkt_header *header) { 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))); + ecs_entity_t e = PKT_GET_ENT(header); + ecs_world_t *ecs = world_ecs(); + + ECS_IMPORT(ecs, Controllers); + Input *i = ecs_get_mut(world_ecs(), e, Input, NULL); + if (i) { + i->x = table.x; + i->y = table.y; + i->use = table.use; + } return 0; } diff --git a/code/common/packets/pkt_send_keystate.h b/code/common/packets/pkt_send_keystate.h index 6c7f4cd..99ced1f 100644 --- a/code/common/packets/pkt_send_keystate.h +++ b/code/common/packets/pkt_send_keystate.h @@ -7,7 +7,10 @@ typedef struct { double y; uint8_t use; } pkt_send_keystate; - +size_t pkt_send_keystate_send(uint16_t view_id, + double x, + double y, + uint8_t use); size_t pkt_send_keystate_encode(pkt_send_keystate *table); pkt_desc pkt_send_keystate_desc[]; diff --git a/code/common/player.c b/code/common/player.c index 27ac6f9..48629c7 100644 --- a/code/common/player.c +++ b/code/common/player.c @@ -7,11 +7,13 @@ #include "modules/general.h" #include "modules/controllers.h" #include "modules/net.h" +#include "modules/physics.h" #include "zpl.h" uint64_t player_spawn(char *name) { ECS_IMPORT(world_ecs(), General); ECS_IMPORT(world_ecs(), Controllers); + ECS_IMPORT(world_ecs(), Physics); ECS_IMPORT(world_ecs(), Net); ecs_entity_t e = ecs_new(world_ecs(), 0); @@ -24,6 +26,8 @@ uint64_t player_spawn(char *name) { ecs_set(world_ecs(), e, ClientInfo, {0}); ecs_set(world_ecs(), e, EcsName, {.alloc_value = name }); ecs_set(world_ecs(), e, Input, {0}); + ecs_set(world_ecs(), e, Velocity, {0}); + ecs_add(world_ecs(), e, Walking); Position *pos = ecs_get_mut(world_ecs(), e, Position, NULL); uint16_t world_dim = world_block_size() * world_chunk_size() * world_world_size(); uint16_t half_world_dim = world_dim / 2; diff --git a/code/modules/modules/controllers.h b/code/modules/modules/controllers.h index 9363743..fa74e96 100644 --- a/code/modules/modules/controllers.h +++ b/code/modules/modules/controllers.h @@ -15,6 +15,7 @@ typedef struct { ECS_DECLARE_ENTITY(EcsBuilder); ECS_DECLARE_TYPE(Player); ECS_DECLARE_TYPE(Builder); + ECS_DECLARE_ENTITY(MovementImpulse); } Controllers; #define ControllersImportHandles(handles)\ @@ -24,5 +25,6 @@ typedef struct { ECS_IMPORT_ENTITY(handles, EcsActor);\ ECS_IMPORT_ENTITY(handles, EcsPlayer);\ ECS_IMPORT_ENTITY(handles, EcsBuilder);\ + ECS_IMPORT_ENTITY(handles, MovementImpulse);\ void ControllersImport(ecs_world_t *ecs); diff --git a/code/modules/modules/physics.h b/code/modules/modules/physics.h index 031247f..2e19574 100644 --- a/code/modules/modules/physics.h +++ b/code/modules/modules/physics.h @@ -1,9 +1,10 @@ #pragma once #include "flecs/flecs.h" +#include "flecs/flecs_meta.h" #include "modules/general.h" -typedef Vector2D Velocity; +ECS_ALIAS(Vector2D, Velocity); typedef struct { ECS_DECLARE_TYPE(Movement); diff --git a/code/modules/source/controllers.c b/code/modules/source/controllers.c index 5f67ea5..f33f850 100644 --- a/code/modules/source/controllers.c +++ b/code/modules/source/controllers.c @@ -2,6 +2,20 @@ #include "modules/general.h" #include "modules/physics.h" +#include "zpl.h" + +// TODO(zaklaus): move to physics +#define CTRL_DRAG_FACTOR 0.20 + +void MovementImpulse(ecs_iter_t *it) { + Input *in = ecs_column(it, Input, 1); + Velocity *v = ecs_column(it, Velocity, 2); + + for (int i = 0; i < it->count; i++) { + v[i].x = zpl_lerp(v[i].x, in[i].x*1000, CTRL_DRAG_FACTOR); + v[i].y = zpl_lerp(v[i].y, in[i].y*1000, CTRL_DRAG_FACTOR); + } +} void ControllersImport(ecs_world_t *ecs) { ECS_MODULE(ecs, Controllers); @@ -9,13 +23,15 @@ void ControllersImport(ecs_world_t *ecs) { ECS_IMPORT(ecs, General); ECS_IMPORT(ecs, Physics); - ECS_IMPORT(ecs, FlecsMeta); + ECS_META(ecs, Input); ECS_TAG(ecs, EcsActor); ECS_TAG(ecs, EcsPlayer); ECS_TAG(ecs, EcsBuilder); + + ECS_SYSTEM(ecs, MovementImpulse, EcsOnUpdate, Input, physics.Velocity); ECS_PREFAB(ecs, Base, general.Position, physics.Velocity, Input, EcsActor); ECS_TYPE(ecs, Player, INSTANCEOF | Base, SWITCH | physics.Movement, CASE | physics.Walking, EcsActor, EcsPlayer); @@ -27,4 +43,5 @@ void ControllersImport(ecs_world_t *ecs) { ECS_SET_ENTITY(EcsBuilder); ECS_SET_TYPE(Builder); ECS_SET_TYPE(Player); + ECS_SET_ENTITY(MovementImpulse); } diff --git a/code/modules/source/physics.c b/code/modules/source/physics.c index e9c6fe5..59520ca 100644 --- a/code/modules/source/physics.c +++ b/code/modules/source/physics.c @@ -1,4 +1,6 @@ #include "modules/physics.h" +#include "world/world.h" +#include "zpl.h" void MoveWalk(ecs_iter_t *it) { Position *p = ecs_column(it, Position, 1); @@ -8,20 +10,21 @@ void MoveWalk(ecs_iter_t *it) { // TODO: handle collisions p[i].x += v[i].x * it->delta_time; p[i].y += v[i].y * it->delta_time; + librg_entity_chunk_set(world_tracker(), it->entities[i], librg_chunk_from_realpos(world_tracker(), p[i].x, p[i].y, 0)); } } void PhysicsImport(ecs_world_t *ecs) { ECS_MODULE(ecs, Physics); ecs_set_name_prefix(ecs, "Physics"); - + ECS_TAG(ecs, Walking); ECS_TAG(ecs, Flying); ECS_TYPE(ecs, Movement, Walking, Flying); - ECS_COMPONENT(ecs, Velocity); + ECS_META(ecs, Velocity); - ECS_SYSTEM(ecs, MoveWalk, EcsOnUpdate, general.Position, Velocity, SWITCH | Movement, CASE | Walking); + ECS_SYSTEM(ecs, MoveWalk, EcsOnUpdate, general.Position, Velocity); ECS_SET_TYPE(Movement); ECS_SET_ENTITY(Walking); diff --git a/code/vendors/librg.h b/code/vendors/librg.h index f991e46..94f2a4c 100644 --- a/code/vendors/librg.h +++ b/code/vendors/librg.h @@ -19979,7 +19979,6 @@ librg_chunk librg_chunk_from_chunkpos(librg_world *world, int16_t chunk_x, int16 int16_t chz = librg_util_chunkoffset_line(chunk_z, wld->chunkoffset.z, wld->worldsize.z); #define kk(aax,aay) (aax > -aay && aax < aay) #define ll(aax,aay) (aax <= -aay || aax >= aay) - zpl_printf("%d %d\n", chz, wld->worldsize.z); if (ll(chx, wld->worldsize.x) || ll(chy, wld->worldsize.y) /*|| ll(chz, wld->worldsize.z)*/) return LIBRG_CHUNK_INVALID; @@ -20472,7 +20471,6 @@ int32_t librg_world_fetch_ownerarray(librg_world *world, const int64_t *owner_id static LIBRG_ALWAYS_INLINE void librg_util_chunkrange(librg_world_t *w, librg_table_i64 *ch, int cx, int cy, int cz, int8_t radius) { int radius2 = radius * radius; - zpl_printf("========================\n"); for (int z=-radius; z<=radius; z++) { for (int y=-radius; y<=radius; y++) { for (int x=-radius; x<=radius; x++) {