diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c3afb7..d310dec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ endif() include_directories(code/common code/vendors code/vendors/flecs) +add_subdirectory(code/modules) add_subdirectory(code/common) add_subdirectory(code/vendors) diff --git a/code/apps/client/CMakeLists.txt b/code/apps/client/CMakeLists.txt index 72f5777..c39682f 100644 --- a/code/apps/client/CMakeLists.txt +++ b/code/apps/client/CMakeLists.txt @@ -17,9 +17,9 @@ add_executable(eco2d-cli source/platform_text.c ) -set(LIBS client-common cwpack eco2d-common) +set(LIBS client-common cwpack eco2d-common eco2d-modules flecs-bundle) -include_directories(header) +include_directories(header ../../modules) target_link_libraries(eco2d-client raylib ${LIBS}) target_link_libraries(eco2d-cli ${LIBS}) diff --git a/code/apps/client/source/main.c b/code/apps/client/source/main.c index d467957..a505822 100644 --- a/code/apps/client/source/main.c +++ b/code/apps/client/source/main.c @@ -1,27 +1,125 @@ #define ZPL_IMPL #include "zpl.h" +#include "system.h" #include "game.h" +#include "world/world.h" +#include "packets/packet.h" #include "signal_handling.h" #include "network.h" -int main(void) -{ - sighandler_register(); - game_init(); - network_init(); - network_client_connect("127.0.0.1", 27000); +#include "flecs/flecs.h" +#include "flecs/flecs_dash.h" +#include "flecs/flecs_systems_civetweb.h" +#include "flecs/flecs_os_api_stdcpp.h" +#define DEFAULT_WORLD_SEED 302097 +#define DEFAULT_BLOCK_SIZE 64 /* amount of units within a block (single axis) */ +#define DEFAULT_CHUNK_SIZE 3 /* amount of blocks within a chunk (single axis) */ +#define DEFAULT_WORLD_SIZE 8 /* amount of chunks within a world (single axis) */ + +static WORLD_PKT_READER(pkt_reader) { + pkt_header header = {0}; + uint32_t ok = pkt_header_decode(&header, data, datalen); + + if (ok && header.ok) { + return pkt_handlers[header.id].handler(&header); + } else { + zpl_printf("[warn] unknown packet id %d (header %d data %d)\n", header.id, ok, header.ok); + } + return -1; +} + +static WORLD_PKT_WRITER(sp_pkt_writer) { + return world_read(pkt->data, pkt->datalen); +} + +static WORLD_PKT_WRITER(mp_pkt_writer) { + return 0; // TODO(zaklaus): enet send packet +} + +inline int32_t pkt_world_write(pkt_messages id, size_t pkt_size, int8_t is_reliable) { + pkt_header pkt; + PKT_IF(pkt_prep_msg(&pkt, id, pkt_size, is_reliable)); + return world_write(&pkt); +} + +int main(int argc, char** argv) +{ + zpl_opts opts={0}; + zpl_opts_init(&opts, zpl_heap(), argv[0]); + + zpl_opts_add(&opts, "?", "help", "the HELP section", ZPL_OPTS_FLAG); + zpl_opts_add(&opts, "s", "single-player", "play single-player game.", ZPL_OPTS_FLAG); + zpl_opts_add(&opts, "s", "seed", "world seed", ZPL_OPTS_INT); + zpl_opts_add(&opts, "r", "random-seed", "generate random world seed", ZPL_OPTS_FLAG); + zpl_opts_add(&opts, "bs", "block-size", "amount of units within a block (single axis)", ZPL_OPTS_INT); + zpl_opts_add(&opts, "cs", "chunk-size", "amount of blocks within a chunk (single axis)", ZPL_OPTS_INT); + zpl_opts_add(&opts, "ws", "world-size", "amount of chunks within a world (single axis)", ZPL_OPTS_INT); + + uint32_t ok = zpl_opts_compile(&opts, argc, argv); + + if (!ok) { + zpl_opts_print_errors(&opts); + zpl_opts_print_help(&opts); + return -1; + } + + uint8_t is_networked_play = !zpl_opts_has_arg(&opts, "single-player"); + int32_t seed = zpl_opts_integer(&opts, "seed", DEFAULT_WORLD_SEED); + uint16_t block_size = zpl_opts_integer(&opts, "block-size", DEFAULT_BLOCK_SIZE); + uint16_t chunk_size = zpl_opts_integer(&opts, "chunk-size", DEFAULT_CHUNK_SIZE); + uint16_t world_size = zpl_opts_integer(&opts, "world-size", DEFAULT_WORLD_SIZE); + + if (zpl_opts_has_arg(&opts, "random-seed")) { + zpl_random rnd={0}; + zpl_random_init(&rnd); + seed = zpl_random_gen_u32(&rnd); + zpl_printf("Seed: %u\n", seed); + } + + sighandler_register(); + stdcpp_set_os_api(); + game_init(); + + if (is_networked_play) { + world_init_minimal(0, 0, 0, pkt_reader, mp_pkt_writer); + network_init(); + network_client_connect("127.0.0.1", 27000); + } else { + world_init(seed, block_size, chunk_size, world_size, pkt_reader, sp_pkt_writer); + + pkt_01_welcome table = {.block_size = block_size, .chunk_size = chunk_size, .world_size = world_size}; + pkt_world_write(MSG_ID_01_WELCOME, pkt_01_welcome_encode(&table), 1); + } + + /* server dashboard */ + { + ECS_IMPORT(world_ecs(), FlecsDash); + ECS_IMPORT(world_ecs(), FlecsSystemsCivetweb); + + ecs_set(world_ecs(), 0, EcsDashServer, {.port = 27001}); + ecs_set_target_fps(world_ecs(), 60); + } + while (game_is_running()) { game_input(); game_update(); game_render(); - network_client_tick(); + if (is_networked_play) network_client_tick(); + else world_update(); } - network_client_disconnect(); game_shutdown(); sighandler_unregister(); - network_destroy(); + + if (is_networked_play) { + network_client_disconnect(); + network_destroy(); + } else { + world_destroy(); + } + + zpl_opts_free(&opts); return 0; } diff --git a/code/apps/playground/CMakeLists.txt b/code/apps/playground/CMakeLists.txt index 102eb59..ee504df 100644 --- a/code/apps/playground/CMakeLists.txt +++ b/code/apps/playground/CMakeLists.txt @@ -2,6 +2,6 @@ add_executable(playground source/main.c ) -include_directories(header) -target_link_libraries(playground eco2d-common cwpack) +include_directories(header ../modules ../common) +target_link_libraries(playground eco2d-common eco2d-modules flecs-bundle cwpack) link_system_libs(playground) diff --git a/code/apps/playground/source/main.c b/code/apps/playground/source/main.c index 324efef..c1e8723 100644 --- a/code/apps/playground/source/main.c +++ b/code/apps/playground/source/main.c @@ -2,7 +2,10 @@ #define ZPL_NANO #include -#include "mock.h" +#define LIBRG_IMPL +#define LIBRG_CUSTOM_ZPL +#include "librg.h" + #include "packets/packet.h" int32_t mock_pkt_decode(pkt_desc *desc, uint32_t args, size_t msg_size, void *data, uint32_t size) { @@ -15,21 +18,17 @@ int32_t mock_pkt_decode(pkt_desc *desc, uint32_t args, size_t msg_size, void *da int main(void) { pkt_01_welcome test_data = { - .chunk_size = world_chunk_size(), - .chunk_amount = world_chunk_amount() + .chunk_size = 4, + .world_size = 8 }; - for (int i = 0; i < 4; i += 1){ - test_data.numbers[i] = i*2; - } - size_t msg_size = pkt_01_welcome_encode(&test_data); pkt_01_welcome resp = {0}; if (mock_pkt_decode(pkt_01_welcome_desc, 3, msg_size, PKT_STRUCT_PTR(&resp))) { zpl_printf("[err] oopsie!\n"); } - zpl_printf("size %d, amt %d, num[1] %d struct %d msg %d\n", resp.chunk_size, resp.chunk_amount, resp.numbers[1], sizeof(pkt_01_welcome), msg_size); + zpl_printf("size %d, amt %d, struct %d msg %d\n", resp.chunk_size, resp.world_size, sizeof(pkt_01_welcome), msg_size); return 0; } diff --git a/code/apps/server/CMakeLists.txt b/code/apps/server/CMakeLists.txt index f1730be..fb87034 100644 --- a/code/apps/server/CMakeLists.txt +++ b/code/apps/server/CMakeLists.txt @@ -1,22 +1,13 @@ -add_subdirectory(modules) - add_executable(eco2d-server source/main.c source/network.c source/utils/options.c - source/world/perlin.c - source/world/world.c - source/world/blocks.c header/network.h header/utils/options.h - header/world/perlin.h - header/world/world.h - header/world/blocks.h - header/world/blocks_info.h ) -include_directories(header modules) +include_directories(header ../../modules) target_compile_definitions(eco2d-server PRIVATE SERVER) target_link_libraries(eco2d-server eco2d-common eco2d-modules flecs-bundle cwpack) link_system_libs(eco2d-server) diff --git a/code/apps/server/header/world/blocks.h b/code/apps/server/header/world/blocks.h deleted file mode 100644 index 4f6ec36..0000000 --- a/code/apps/server/header/world/blocks.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once -#include "system.h" - -#define BLOCK_INVALID 0xF - -typedef enum { - BLOCK_FLAG_COLLISION = (1 << 0) -} block_flags; - -#include "blocks_info.h" - -uint8_t blocks_find(uint32_t biome, uint32_t kind); - -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_biome(uint8_t id); -uint32_t blocks_get_kind(uint8_t id); diff --git a/code/apps/server/header/world/blocks_info.h b/code/apps/server/header/world/blocks_info.h deleted file mode 100644 index 34a9aae..0000000 --- a/code/apps/server/header/world/blocks_info.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -typedef enum { - BLOCK_KIND_DEV, - BLOCK_KIND_GROUND, - BLOCK_KIND_WATER, - BLOCK_KIND_WALL, - BLOCK_KIND_HILL, - BLOCK_KIND_HILL_SNOW, - 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; diff --git a/code/apps/server/header/world/perlin.h b/code/apps/server/header/world/perlin.h deleted file mode 100644 index 66f184d..0000000 --- a/code/apps/server/header/world/perlin.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "system.h" - -double perlin_noise2d(int32_t seed, double x, double y); -double perlin_fbm(int32_t seed, double x, double y, double freq, uint32_t octaves); diff --git a/code/apps/server/header/world/world.h b/code/apps/server/header/world/world.h deleted file mode 100644 index f6c7b1b..0000000 --- a/code/apps/server/header/world/world.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "system.h" -#include "librg.h" -#include "flecs/flecs.h" - -#define WORLD_ERROR_NONE +0x0000 -#define WORLD_ERROR_OUTOFMEM -0x0001 -#define WORLD_ERROR_INVALID_BLOCKS -0x0002 -#define WORLD_ERROR_INVALID_DIMENSIONS -0x0003 -#define WORLD_ERROR_INVALID_BUFFER -0x0004 -#define WORLD_ERROR_TRACKER_FAILED -0x0005 - -int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size); -int32_t world_destroy(void); -int32_t world_update(void); - -uint32_t world_buf(uint8_t const **ptr, uint32_t *width); -ecs_world_t * world_ecs(void); -librg_world * world_tracker(void); - -uint16_t world_chunk_size(void); -uint16_t world_chunk_amount(void); \ No newline at end of file diff --git a/code/apps/server/modules/CMakeLists.txt b/code/apps/server/modules/CMakeLists.txt deleted file mode 100644 index 889cca7..0000000 --- a/code/apps/server/modules/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -file(GLOB MODULES modules/*.h source/*.c) -add_library(eco2d-modules STATIC ${MODULES}) -include_directories(.) diff --git a/code/apps/server/modules/modules/controllers.h b/code/apps/server/modules/modules/controllers.h deleted file mode 100644 index 9363743..0000000 --- a/code/apps/server/modules/modules/controllers.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include "flecs/flecs.h" -#include "flecs/flecs_meta.h" - -ECS_STRUCT(Input, { - double x; - double y; - uint8_t use; -}); - -typedef struct { - ECS_DECLARE_COMPONENT(Input); - ECS_DECLARE_ENTITY(EcsActor); - ECS_DECLARE_ENTITY(EcsPlayer); - ECS_DECLARE_ENTITY(EcsBuilder); - ECS_DECLARE_TYPE(Player); - ECS_DECLARE_TYPE(Builder); -} Controllers; - -#define ControllersImportHandles(handles)\ - ECS_IMPORT_COMPONENT(handles, Input);\ - ECS_IMPORT_TYPE(handles, Player);\ - ECS_IMPORT_TYPE(handles, Builder);\ - ECS_IMPORT_ENTITY(handles, EcsActor);\ - ECS_IMPORT_ENTITY(handles, EcsPlayer);\ - ECS_IMPORT_ENTITY(handles, EcsBuilder);\ - -void ControllersImport(ecs_world_t *ecs); diff --git a/code/apps/server/modules/modules/general.h b/code/apps/server/modules/modules/general.h deleted file mode 100644 index 448168b..0000000 --- a/code/apps/server/modules/modules/general.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "flecs/flecs.h" -#include "flecs/flecs_meta.h" - -ECS_STRUCT(Vector2D, { - int16_t x; - int16_t y; -}); - -ECS_STRUCT(Drawable, { - uint16_t id; -}); - -ECS_ALIAS(Vector2D, Chunk); -ECS_ALIAS(Vector2D, Position); - -typedef struct { - ECS_DECLARE_COMPONENT(Chunk); - ECS_DECLARE_COMPONENT(Position); - ECS_DECLARE_COMPONENT(Vector2D); - ECS_DECLARE_COMPONENT(Drawable); -} General; - -#define GeneralImportHandles(handles)\ - ECS_IMPORT_COMPONENT(handles, Chunk);\ - ECS_IMPORT_COMPONENT(handles, Vector2D);\ - ECS_IMPORT_COMPONENT(handles, Position);\ - ECS_IMPORT_COMPONENT(handles, Drawable);\ - -void GeneralImport(ecs_world_t *ecs); diff --git a/code/apps/server/modules/modules/net.h b/code/apps/server/modules/modules/net.h deleted file mode 100644 index 349b6bc..0000000 --- a/code/apps/server/modules/modules/net.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include "flecs/flecs.h" -#include "flecs/flecs_meta.h" - -ECS_STRUCT(ClientInfo, { - uint16_t peer_id; -}); - -typedef struct { - ECS_DECLARE_ENTITY(EcsClient); - ECS_DECLARE_COMPONENT(ClientInfo); -} Net; - -#define NetImportHandles(handles)\ - ECS_IMPORT_ENTITY(handles, EcsClient);\ - ECS_IMPORT_COMPONENT(handles, ClientInfo);\ - -void NetImport(ecs_world_t *ecs); diff --git a/code/apps/server/modules/modules/physics.h b/code/apps/server/modules/modules/physics.h deleted file mode 100644 index 031247f..0000000 --- a/code/apps/server/modules/modules/physics.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include "flecs/flecs.h" - -#include "modules/general.h" - -typedef Vector2D Velocity; - -typedef struct { - ECS_DECLARE_TYPE(Movement); - ECS_DECLARE_ENTITY(Walking); - ECS_DECLARE_ENTITY(Flying); - ECS_DECLARE_COMPONENT(Velocity); - ECS_DECLARE_ENTITY(MoveWalk); -} Physics; - -#define PhysicsImportHandles(handles)\ - ECS_IMPORT_TYPE(handles, Movement);\ - ECS_IMPORT_ENTITY(handles, Walking);\ - ECS_IMPORT_ENTITY(handles, Flying);\ - ECS_IMPORT_COMPONENT(handles, Velocity);\ - ECS_IMPORT_ENTITY(handles, MoveWalk);\ - -void PhysicsImport(ecs_world_t *ecs); diff --git a/code/apps/server/modules/source/controllers.c b/code/apps/server/modules/source/controllers.c deleted file mode 100644 index 5f67ea5..0000000 --- a/code/apps/server/modules/source/controllers.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "modules/controllers.h" - -#include "modules/general.h" -#include "modules/physics.h" - -void ControllersImport(ecs_world_t *ecs) { - ECS_MODULE(ecs, Controllers); - ecs_set_name_prefix(ecs, "Controllers"); - - 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_PREFAB(ecs, Base, general.Position, physics.Velocity, Input, EcsActor); - ECS_TYPE(ecs, Player, INSTANCEOF | Base, SWITCH | physics.Movement, CASE | physics.Walking, EcsActor, EcsPlayer); - ECS_TYPE(ecs, Builder, INSTANCEOF | Base, SWITCH | physics.Movement, CASE | physics.Flying, EcsActor, EcsBuilder); - - ECS_SET_COMPONENT(Input); - ECS_SET_ENTITY(EcsActor); - ECS_SET_ENTITY(EcsPlayer); - ECS_SET_ENTITY(EcsBuilder); - ECS_SET_TYPE(Builder); - ECS_SET_TYPE(Player); -} diff --git a/code/apps/server/modules/source/general.c b/code/apps/server/modules/source/general.c deleted file mode 100644 index 5aa3411..0000000 --- a/code/apps/server/modules/source/general.c +++ /dev/null @@ -1,19 +0,0 @@ -#include "modules/general.h" - -void GeneralImport(ecs_world_t *ecs) { - ECS_MODULE(ecs, General); - ecs_set_name_prefix(ecs, "General"); - - ECS_COMPONENT(ecs, Chunk); - ECS_COMPONENT(ecs, Position); - - ECS_IMPORT(ecs, FlecsMeta); - - ECS_META(ecs, Vector2D); - ECS_META(ecs, Drawable); - - ECS_SET_COMPONENT(Chunk); - ECS_SET_COMPONENT(Vector2D); - ECS_SET_COMPONENT(Position); - ECS_SET_COMPONENT(Drawable); -} diff --git a/code/apps/server/modules/source/net.c b/code/apps/server/modules/source/net.c deleted file mode 100644 index 084441c..0000000 --- a/code/apps/server/modules/source/net.c +++ /dev/null @@ -1,16 +0,0 @@ -#include "modules/net.h" - -void NetImport(ecs_world_t *ecs) { - ECS_MODULE(ecs, Net); - - ecs_set_name_prefix(ecs, "Net"); - - ECS_TAG(ecs, EcsClient); - - ECS_IMPORT(ecs, FlecsMeta); - - ECS_META(ecs, ClientInfo); - - ECS_EXPORT_ENTITY(EcsClient); - ECS_EXPORT_COMPONENT(ClientInfo); -} diff --git a/code/apps/server/modules/source/physics.c b/code/apps/server/modules/source/physics.c deleted file mode 100644 index e9c6fe5..0000000 --- a/code/apps/server/modules/source/physics.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "modules/physics.h" - -void MoveWalk(ecs_iter_t *it) { - Position *p = ecs_column(it, Position, 1); - Velocity *v = ecs_column(it, Velocity, 2); - - for (int i = 0; i < it->count; i++) { - // TODO: handle collisions - p[i].x += v[i].x * it->delta_time; - p[i].y += v[i].y * it->delta_time; - } -} - -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_SYSTEM(ecs, MoveWalk, EcsOnUpdate, general.Position, Velocity, SWITCH | Movement, CASE | Walking); - - ECS_SET_TYPE(Movement); - ECS_SET_ENTITY(Walking); - ECS_SET_ENTITY(Flying); - ECS_SET_COMPONENT(Velocity); - ECS_SET_ENTITY(MoveWalk); -} diff --git a/code/apps/server/source/main.c b/code/apps/server/source/main.c index eea0433..aac3fbf 100644 --- a/code/apps/server/source/main.c +++ b/code/apps/server/source/main.c @@ -24,6 +24,16 @@ } \ } while (0) +static WORLD_PKT_READER(mp_pkt_reader) { + // TODO(zaklaus): implement this + return -1; +} + +static WORLD_PKT_WRITER(mp_pkt_writer) { + // TODO(zaklaus): implement this + return -1; +} + zpl_global zpl_b32 is_running = true; int main(int argc, char** argv) { @@ -67,7 +77,7 @@ int main(int argc, char** argv) { stdcpp_set_os_api(); zpl_printf("[INFO] Generating world of size: %d x %d\n", world_size, world_size); - IF(world_init(seed, block_size, chunk_size, world_size)); + IF(world_init(seed, block_size, chunk_size, world_size, mp_pkt_reader, mp_pkt_writer)); /* server dashboard */ { diff --git a/code/apps/server/source/utils/options.c b/code/apps/server/source/utils/options.c index abeded0..587fb9b 100644 --- a/code/apps/server/source/utils/options.c +++ b/code/apps/server/source/utils/options.c @@ -5,7 +5,7 @@ #include "utils/options.h" void generate_minimap(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) { - world_init(seed, block_size, chunk_size, world_size); + world_init(seed, block_size, chunk_size, world_size, NULL, NULL); uint8_t const *world; uint32_t world_length = chunk_size * world_size; diff --git a/code/apps/server/source/world/blocks.c b/code/apps/server/source/world/blocks.c deleted file mode 100644 index f8d6a96..0000000 --- a/code/apps/server/source/world/blocks.c +++ /dev/null @@ -1,49 +0,0 @@ -#include "zpl.h" -#include "world/blocks.h" - -// todo: csv parsing + utils - -#define BLOCKS_COUNT (sizeof(blocks)/sizeof(block)) - -typedef struct { - uint8_t tex_id; - char *name; - uint32_t flags; - uint32_t kind; - uint32_t biome; - char symbol; -} block; - -#include "blocks_list.c" - -uint8_t blocks_find(uint32_t biome, uint32_t kind) { - for (int i=0; i -#include "world/perlin.h" - -// adapted from: https://gist.github.com/nowl/828013#gistcomment-2807232 - -static const uint8_t PERLIN_PERM_TABLE[] = { - 208,34,231,213,32,248,233,56,161,78,24,140,71,48,140,254,245,255,247,247,40, - 185,248,251,245,28,124,204,204,76,36,1,107,28,234,163,202,224,245,128,167,204, - 9,92,217,54,239,174,173,102,193,189,190,121,100,108,167,44,43,77,180,204,8,81, - 70,223,11,38,24,254,210,210,177,32,81,195,243,125,8,169,112,32,97,53,195,13, - 203,9,47,104,125,117,114,124,165,203,181,235,193,206,70,180,174,0,167,181,41, - 164,30,116,127,198,245,146,87,224,149,206,57,4,192,210,65,210,129,240,178,105, - 228,108,245,148,140,40,35,195,38,58,65,207,215,253,65,85,208,76,62,3,237,55,89, - 232,50,217,64,244,157,199,121,252,90,17,212,203,149,152,140,187,234,177,73,174, - 193,100,192,143,97,53,145,135,19,103,13,90,135,151,199,91,239,247,33,39,145, - 101,120,99,3,186,86,99,41,237,203,111,79,220,135,158,42,30,154,120,67,87,167, - 135,176,183,191,253,115,184,21,233,58,129,233,142,39,128,211,118,137,139,255, - 114,20,218,113,154,27,127,246,250,1,8,198,250,209,92,222,173,21,88,102,219 -}; - -static int32_t perlin_noise2_sample(int32_t seed, int32_t x, int32_t y) { - int32_t yindex = (y + seed) % 256; - if (yindex < 0) - yindex += 256; - int32_t xindex = (PERLIN_PERM_TABLE[yindex] + x) % 256; - if (xindex < 0) - xindex += 256; - return PERLIN_PERM_TABLE[xindex]; -} - -static double perlin_lerp(double x, double y, double t) { - return x + t*(y - x); -} - -static double perlin_smooth_lerp(double x, double y, double t) { - return perlin_lerp(x, y, t * t * (3-2*t)); -} - -double perlin_noise2d(int32_t seed, double x, double y) { - int32_t x_int = floor(x); - int32_t y_int = floor(y); - double x_frac = x - x_int; - double y_frac = y - y_int; - int32_t s = perlin_noise2_sample(seed, x_int, y_int); - int32_t t = perlin_noise2_sample(seed, x_int+1, y_int); - int32_t u = perlin_noise2_sample(seed, x_int, y_int+1); - int32_t v = perlin_noise2_sample(seed, x_int+1, y_int+1); - double low = perlin_smooth_lerp(s, t, x_frac); - double high = perlin_smooth_lerp(u, v, x_frac); - double result = perlin_smooth_lerp(low, high, y_frac); - return result; -} - -double perlin_fbm(int32_t seed, double x, double y, double freq, uint32_t octaves) { - double xa = x*freq; - double ya = y*freq; - double amp = 1.0; - double res = 0.0; - double div = 0.0; - - for (uint32_t i=0; i max_length || !peer->data) { - // return LIBRG_WRITE_REJECT; - // } - - // /* write data and return how much we've written */ - // memcpy(buffer, peer->data, sizeof(vec3)); - // return sizeof(vec3); -} - -int32_t world_init(int32_t seed, uint16_t block_size, uint16_t chunk_size, uint16_t world_size) { - if (world.data) { - world_destroy(); - } - - world.seed = seed; - world.block_size = block_size; - world.chunk_size = chunk_size; - world.world_size = world_size; - - world.width = chunk_size * world_size; - world.height = chunk_size * world_size; - world.size = world.width * world.height; - world.data = zpl_malloc(sizeof(uint8_t)*world.size); - - if (!world.data) { - return WORLD_ERROR_OUTOFMEM; - } - - world.ecs = ecs_init(); - ecs_set_entity_range(world.ecs, 0, UINT32_MAX); - //ecs_set_threads(world.ecs, 4); - - world.tracker = librg_world_create(); - - if (world.tracker == NULL) { - zpl_printf("[ERROR] An error occurred while trying to create a server world.\n"); - return WORLD_ERROR_TRACKER_FAILED; - } - - zpl_printf("[INFO] Created a new server world\n"); - - /* config our world grid */ - librg_config_chunksize_set(world.tracker, block_size * chunk_size, block_size * chunk_size, 1); - librg_config_chunkamount_set(world.tracker, world_size, world_size, 1); - librg_config_chunkoffset_set(world.tracker, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID, LIBRG_OFFSET_MID); - - ECS_IMPORT(world.ecs, General); - - for (int i = 0; i < chunk_size * chunk_size; ++i) { - ecs_entity_t e = ecs_new(world.ecs, 0); - ecs_set(world.ecs, e, Chunk, { - .x = i % chunk_size, - .y = i / chunk_size, - }); - - librg_entity_track(world.tracker, e); - librg_entity_chunk_set(world.tracker, e, i); - } - - // librg_event_set(world.tracker, LIBRG_WRITE_UPDATE, world_write_update); - // librg_event_set(world.tracker, LIBRG_READ_UPDATE, server_read_update); - - return world_gen(); -} - -int32_t world_destroy(void) { - librg_world_destroy(world.tracker); - ecs_fini(world.ecs); - zpl_mfree(world.data); - zpl_memset(&world, 0, sizeof(world)); - zpl_printf("[INFO] World was destroyed.\n"); - return WORLD_ERROR_NONE; -} - -int32_t world_update() { - ecs_progress(world.ecs, 0); - return 0; -} - -uint32_t world_buf(uint8_t const **ptr, uint32_t *width) { - ZPL_ASSERT_NOT_NULL(world.data); - ZPL_ASSERT_NOT_NULL(ptr); - *ptr = world.data; - if (width) *width = world.width; - return world.size; -} - -ecs_world_t * world_ecs() { - return world.ecs; -} - -librg_world * world_tracker() { - return world.tracker; -} - -uint16_t world_chunk_size(void) { - return world.chunk_size; -} - -uint16_t world_chunk_amount(void) { - return world.world_size; -} - -#include "world_gen.c" diff --git a/code/apps/server/source/world/world_gen.c b/code/apps/server/source/world/world_gen.c deleted file mode 100644 index d845a3d..0000000 --- a/code/apps/server/source/world/world_gen.c +++ /dev/null @@ -1,133 +0,0 @@ -#include "zpl.h" - -#include -#include - -#include "world/world.h" -#include "world/blocks.h" -#include "world/perlin.h" - -#define WORLD_BLOCK_OBSERVER(name) uint32_t name(uint32_t id, uint32_t block_idx) -typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc); - -#define WORLD_PERLIN_FREQ 1.0 -#define WORLD_PERLIN_OCTAVES 1 - -static void world_fill_rect(uint32_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= world.width) continue; - if (cy < 0 || cy >= world.height) continue; - uint32_t i = (cy*world.width) + cx; - - if (proc) { - uint32_t new_id = (*proc)(id, i); - if (new_id != BLOCK_INVALID) { - id = new_id; - } - else continue; - } - - world.data[i] = id; - } - } -} - -static void world_fill_circle(uint32_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= world.width) continue; - if (cy < 0 || cy >= world.height) continue; - uint32_t i = (cy*world.width) + cx; - - if (proc) { - uint32_t new_id = (*proc)(id, i); - if (new_id != BLOCK_INVALID) { - id = new_id; - } - else continue; - } - - world.data[i] = id; - } - } -} - -static void world_fill_rect_anchor(uint32_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(id, x-w2, y-h2, w, h, proc); -} - -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]); - - 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); - } - } - - return id; -} - -static uint8_t world_perlin_cond(uint32_t block_idx, double chance) { - uint32_t x = block_idx % world.width; - uint32_t y = block_idx / world.width; - - return perlin_fbm(world.seed, x, y, WORLD_PERLIN_FREQ, WORLD_PERLIN_OCTAVES) < chance; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise80) { - return world_perlin_cond(block_idx, 0.80) ? shaper(id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise50) { - return world_perlin_cond(block_idx, 0.50) ? shaper(id, block_idx) : BLOCK_INVALID; -} - -static WORLD_BLOCK_OBSERVER(shaper_noise33) { - return world_perlin_cond(block_idx, 0.33) ? shaper(id, block_idx) : BLOCK_INVALID; -} - -static void world_fill_mountain(uint32_t x, uint32_t y) { - -} - -#define RAND_RANGE(x,y) (x + (int)rand()%(y-(x))) - -int32_t world_gen() { - // 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); - - srand(world.seed); - - // walls - world_fill_rect(wall_id, 0, 0, world.width, world.height, NULL); - - // ground - world_fill_rect(grnd_id, 1, 1, world.width-2, world.height-2, NULL); - - // water - for (int i=0; idatalen = packed_size; table->ok = 1; - return pkt_validate_eof_msg(&uc); + return pkt_validate_eof_msg(&uc) != -1; } int32_t pkt_unpack_struct(cw_unpack_context *uc, pkt_desc *desc, void *raw_blob, uint32_t blob_size) { diff --git a/code/common/packets/packet.h b/code/common/packets/packet.h index 21d5c18..75b4e70 100644 --- a/code/common/packets/packet.h +++ b/code/common/packets/packet.h @@ -14,6 +14,7 @@ typedef struct pkt_header { uint16_t sender; uint8_t *data; uint32_t datalen; + int8_t is_reliable; int8_t ok; } pkt_header; @@ -25,6 +26,7 @@ typedef struct { pkt_handler_proc *handler; } pkt_handler; +int32_t pkt_header_encode(pkt_messages id, void *data, size_t datalen); int32_t pkt_header_decode(pkt_header *table, void *data, size_t datalen); extern pkt_handler pkt_handlers[]; diff --git a/code/common/packets/packet_utils.h b/code/common/packets/packet_utils.h index b8ece1d..1b83d6c 100644 --- a/code/common/packets/packet_utils.h +++ b/code/common/packets/packet_utils.h @@ -3,6 +3,10 @@ #include "packet.h" #include "cwpack/cwpack.h" +#ifndef PKT_IF +#define PKT_IF(c) if (c < 0) return -1; +#endif + 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); @@ -35,6 +39,18 @@ 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, 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); + + pkt->data = pkt_buffer; + pkt->datalen = pkt_header_encode(id, pkt_data, pkt_size); + pkt->is_reliable = is_reliable; + pkt->id = id; + return 0; +} + #ifndef PKT_OFFSETOF #if defined(_MSC_VER) || defined(ZPL_COMPILER_TINYC) # define PKT_OFFSETOF(Type, element) ((size_t) & (((Type *)0)->element)) @@ -60,10 +76,6 @@ inline size_t pkt_pack_msg_size(cw_pack_context *pc) { #define PKT_END .type = CWP_NOT_AN_ITEM #endif -#ifndef PKT_IF -#define PKT_IF(c) if (c < 0) return -1; -#endif - typedef struct pkt_desc { cwpack_item_types type; size_t offset; diff --git a/code/common/packets/pkt_01_welcome.c b/code/common/packets/pkt_01_welcome.c index 5260c40..81b161d 100644 --- a/code/common/packets/pkt_01_welcome.c +++ b/code/common/packets/pkt_01_welcome.c @@ -1,10 +1,10 @@ #include "pkt_01_welcome.h" +#include "world.h" pkt_desc pkt_01_welcome_desc[] = { + { PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, block_size) }, { PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, chunk_size) }, - { PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, chunk_amount) }, - { PKT_ARRAY(pkt_01_welcome, numbers) }, - { PKT_ARRAY(pkt_01_welcome, structs) }, + { PKT_FIELD(CWP_ITEM_POSITIVE_INTEGER, pkt_01_welcome, world_size) }, { PKT_END }, }; @@ -19,6 +19,8 @@ int32_t pkt_01_welcome_handler(pkt_header *header) { pkt_01_welcome table; PKT_IF(pkt_msg_decode(header, pkt_01_welcome_desc, 3, PKT_STRUCT_PTR(&table))); - zpl_printf("we received: chunk_size: %d and chunk_amount: %d\n", table.chunk_size, table.chunk_amount); + zpl_printf("we received: block_size: %d, chunk_size: %d and world_size: %d\n", table.block_size, table.chunk_size, table.world_size); + + world_init_minimal(table.block_size, table.chunk_size, table.world_size, NULL, NULL); return 0; } diff --git a/code/common/packets/pkt_01_welcome.h b/code/common/packets/pkt_01_welcome.h index 7bc21db..c138c3c 100644 --- a/code/common/packets/pkt_01_welcome.h +++ b/code/common/packets/pkt_01_welcome.h @@ -4,10 +4,9 @@ #define PKT_01_NUMBERS_SIZ 32 typedef struct { - uint32_t chunk_size; - uint32_t chunk_amount; - uint16_t numbers[PKT_01_NUMBERS_SIZ]; - pkt_header structs[64]; + uint16_t block_size; + uint16_t chunk_size; + uint16_t world_size; } pkt_01_welcome; size_t pkt_01_welcome_encode(pkt_01_welcome *table);