From 5008ae2dbd09dacf042e855b6cf1dda218a2e7a7 Mon Sep 17 00:00:00 2001 From: Eric-Paul Ickhorn Date: Sat, 14 Oct 2023 15:04:52 +0200 Subject: [PATCH] Wrote basic entity system --- build.bash | 2 +- code/source-c/chunk_pool.c | 1 + code/source-c/entity.c | 109 ++++++++++++++++++++++++++++ code/source-c/entity.h | 104 ++++++++++++++++++++++++++ code/source-c/entity/player.c | 60 +++++++++++++++ code/source-c/entity/registration.c | 7 ++ code/source-c/entity/registration.h | 11 +++ code/source-c/entity_pool.c | 52 +++++++++++++ code/source-c/initialization.c | 3 + code/source-c/location.c | 16 ++++ code/source-c/location.h | 18 +++++ code/source-c/state.h | 2 + 12 files changed, 384 insertions(+), 1 deletion(-) create mode 100644 code/source-c/entity.c create mode 100644 code/source-c/entity.h create mode 100644 code/source-c/entity/player.c create mode 100644 code/source-c/entity/registration.c create mode 100644 code/source-c/entity/registration.h create mode 100644 code/source-c/entity_pool.c create mode 100644 code/source-c/location.c create mode 100644 code/source-c/location.h diff --git a/build.bash b/build.bash index 6d6f5d5..773ce5c 100644 --- a/build.bash +++ b/build.bash @@ -7,6 +7,6 @@ gcc -g3 -o dependencies/build/glad.o \ -I dependencies/include/ -Wall gcc -g3 -o techneck.elf \ - code/source-c/*.c dependencies/build/glad.o \ + code/source-c/*.c code/source-c/entity/*.c dependencies/build/glad.o \ -I dependencies/include -lGL -lSDL2 -lm -Wall diff --git a/code/source-c/chunk_pool.c b/code/source-c/chunk_pool.c index 313900c..d019398 100644 --- a/code/source-c/chunk_pool.c +++ b/code/source-c/chunk_pool.c @@ -1,6 +1,7 @@ #include "world.h" #include +#include void tc_reset_chunk_pool(tc_chunk_pool_s *chunk_pool) { diff --git a/code/source-c/entity.c b/code/source-c/entity.c new file mode 100644 index 0000000..6d1f288 --- /dev/null +++ b/code/source-c/entity.c @@ -0,0 +1,109 @@ +#include "entity.h" +#include "state.h" + +#include +#include + +tc_entity_registry_s tc_init_entity_registry() +{ + tc_entity_registry_s registry; + registry.types_capacity = 64; + registry.num_types = 0; + registry.types = calloc(sizeof(tc_entity_type_s), registry.types_capacity); + registry.entities_capacity = 512; + registry.num_entities = 0; + registry.entities = calloc(sizeof(tc_entity_s *), registry.entities_capacity); + + return registry; +} + +void tc_register_entity_type(tc_entity_type_s type) +{ + if(tc_game_state_g.entity_registry.num_types + >= + tc_game_state_g.entity_registry.types_capacity + ) { + tc_game_state_g.entity_registry.types_capacity *= 2; + tc_game_state_g.entity_registry.types = + realloc( + tc_game_state_g.entity_registry.types, + tc_game_state_g.entity_registry.types_capacity + ); + } + + tc_game_state_g.entity_registry.types[tc_game_state_g.entity_registry.num_types] = type; + + ++tc_game_state_g.entity_registry.num_types; +} + +tc_entity_type_s * tc_get_entity_type_from_name(char *internal_name) +{ + uint32_t num_types = tc_game_state_g.entity_registry.num_types; + tc_entity_type_s *types = tc_game_state_g.entity_registry.types; + + uint32_t index = 0; + while(index < num_types) + { + if(!strcmp(types[index].internal_name, internal_name)) return &types[index]; + ++index; + } + return NULL; +} + +tc_entity_s * tc_create_entity(char *type) +{ + tc_entity_type_s *type_struct = tc_get_entity_type_from_name(type); + if(type_struct == NULL) return NULL; + + return type_struct->functions.fn_create(); +} + +void tc_spawn_entity(tc_entity_s *entity, tc_location_s location) +{ + entity->type->functions.fn_spawn(entity, location); +} + +void tc_teleport_entity(tc_entity_s *entity, tc_location_s location) +{ + entity->type->functions.fn_teleport(entity, location); +} + +void tc_delete_entity(tc_entity_s *entity) +{ + entity->type->functions.fn_delete(entity); +} + + + +void tc_send_pointer_to_entity(tc_entity_s *entity, char *event_name, void *pointer) +{ + tc_entity_event_s event; + event.event_type = event_name; + event.value.pointer = pointer; + entity->type->functions.fn_send_event(entity, event); +} + +void tc_send_string_to_entity(tc_entity_s *entity, char *event_name, char *string) +{ + tc_entity_event_s event; + event.event_type = event_name; + event.value.string = string; + entity->type->functions.fn_send_event(entity, event); +} + +void tc_send_integer_to_entity(tc_entity_s *entity, char *event_name, int64_t integer) +{ + tc_entity_event_s event; + event.event_type = event_name; + event.value.integer = integer; + entity->type->functions.fn_send_event(entity, event); +} + +void tc_send_float_to_entity(tc_entity_s *entity, char *event_name, double floating) +{ + tc_entity_event_s event; + event.event_type = event_name; + event.value.floating = floating; + entity->type->functions.fn_send_event(entity, event); +} + diff --git a/code/source-c/entity.h b/code/source-c/entity.h new file mode 100644 index 0000000..c1bf046 --- /dev/null +++ b/code/source-c/entity.h @@ -0,0 +1,104 @@ + +#ifndef TC_ENTITY_H +#define TC_ENTITY_H + +#include "location.h" +#include "utility.h" + +typedef struct tc_entity_event tc_entity_event_s; +typedef struct tc_entity_type tc_entity_type_s; +typedef struct tc_entity_attribute tc_entity_attribute_s; +typedef struct tc_entity tc_entity_s; +typedef struct tc_entity_registry tc_entity_registry_s; + + +typedef struct +{ + tc_entity_s * (*fn_create) (); + void (*fn_spawn) (tc_entity_s *entity, tc_location_s location); + void (*fn_teleport) (tc_entity_s *entity, tc_location_s location); + void (*fn_delete) (tc_entity_s *entity); + void (*fn_send_event) (tc_entity_s *entity, tc_entity_event_s event); + +} tc_fn_entity_s; + +struct tc_entity_event +{ + char *event_type; + + union + { + void *pointer; + char *string; + int64_t integer; + double floating; + } value; +}; + +struct tc_entity_type +{ + char *internal_name; + char *display_name; + + tc_fn_entity_s functions; + +}; + +struct tc_entity_attribute +{ + char *name; + uint32_t index; + + union + { + void *pointer; + char *string; + int64_t integer; + } value; + +}; + +struct tc_entity +{ + tc_location_s location; + tc_entity_type_s *type; + + uint16_t attributes_capacity; + uint16_t num_attributes; + tc_entity_attribute_s *attributes; + + void *specific; + +}; + +struct tc_entity_registry +{ + uint32_t types_capacity; + uint32_t num_types; + tc_entity_type_s *types; + + uint32_t entities_capacity; + uint32_t num_entities; + tc_entity_s **entities; +}; + +tc_entity_registry_s tc_init_entity_registry (); +void tc_register_entity_type (tc_entity_type_s type); + +tc_entity_type_s * tc_get_entity_type_from_name (char *name); + +tc_entity_s * tc_create_entity (char *type); +void tc_spawn_entity (tc_entity_s *entity, tc_location_s location); +void tc_teleport_entity (tc_entity_s *entity, tc_location_s location); +void tc_delete_entity (tc_entity_s *entity); + +void tc_send_pointer_to_entity (tc_entity_s *entity, char *event_name, void *pointer); +void tc_send_string_to_entity (tc_entity_s *entity, char *event_name, char *string); +void tc_send_integer_to_entity (tc_entity_s *entity, char *event_name, int64_t integer); +void tc_send_float_to_entity (tc_entity_s *entity, char *event_name, double floating); + +tc_entity_s * tc_allocate_entity (); +void tc_deallocate_entity (tc_entity_s *entity); + +#endif // TC_ENTITY_H + diff --git a/code/source-c/entity/player.c b/code/source-c/entity/player.c new file mode 100644 index 0000000..e5eec16 --- /dev/null +++ b/code/source-c/entity/player.c @@ -0,0 +1,60 @@ +#include "registration.h" + +#include + +tc_entity_type_s *tc_player_entity_type_g = NULL; + +tc_entity_s * tc_fn_create_player_entity() +{ + tc_entity_s *entity = tc_allocate_entity(); + entity->type = tc_player_entity_type_g; + entity->location = tc_zero_location(); + entity->specific = NULL; + entity->num_attributes = 0; + entity->attributes_capacity = 8; + entity->attributes = + calloc(sizeof(tc_entity_attribute_s), entity->attributes_capacity); + + return entity; +} + +void tc_fn_spawn_player_entity(tc_entity_s *entity, tc_location_s location) +{ + if(entity->location.world != NULL) return; + + entity->location = location; +} + +void tc_fn_teleport_player_entity(tc_entity_s *entity, tc_location_s location) +{ + entity->location = location; +} + +void tc_fn_delete_player_entity(tc_entity_s *entity) +{ + if(entity->specific != NULL) free(entity->specific); + tc_deallocate_entity(entity); +} + +void tc_fn_send_event_player_entity(tc_entity_s *entity, tc_entity_event_s event) +{ + +} + + + +void tc_register_player_entity() +{ + tc_entity_type_s type; + type.internal_name = "player"; + type.display_name = "Player"; + type.functions.fn_create = tc_fn_create_player_entity; + type.functions.fn_spawn = tc_fn_spawn_player_entity; + type.functions.fn_teleport = tc_fn_teleport_player_entity; + type.functions.fn_delete = tc_fn_delete_player_entity; + type.functions.fn_send_event = tc_fn_send_event_player_entity; + + tc_register_entity_type(type); + + tc_player_entity_type_g = tc_get_entity_type_from_name("player"); +} diff --git a/code/source-c/entity/registration.c b/code/source-c/entity/registration.c new file mode 100644 index 0000000..d6648d2 --- /dev/null +++ b/code/source-c/entity/registration.c @@ -0,0 +1,7 @@ +#include "registration.h" + +void tc_register_entities() +{ + tc_register_player_entity(); +} + diff --git a/code/source-c/entity/registration.h b/code/source-c/entity/registration.h new file mode 100644 index 0000000..5dac8b7 --- /dev/null +++ b/code/source-c/entity/registration.h @@ -0,0 +1,11 @@ + +#ifndef TC_ENTITY_REGISTRATION_H +#define TC_ENTITY_REGISTRATION_H + +#include "../entity.h" + +void tc_register_player_entity (); +void tc_register_entities (); + +#endif // #ifndef TC_ENTITY_REGISTRATION_H + diff --git a/code/source-c/entity_pool.c b/code/source-c/entity_pool.c new file mode 100644 index 0000000..a404937 --- /dev/null +++ b/code/source-c/entity_pool.c @@ -0,0 +1,52 @@ +#include "entity.h" +#include "state.h" + +#include + +tc_entity_s * tc_allocate_entity() +{ + tc_entity_registry_s registry = tc_game_state_g.entity_registry; + + uint32_t entity_index = 0; + while(entity_index < registry.entities_capacity) + { + if(registry.entities[entity_index] == NULL) + { + registry.entities[entity_index] = malloc(sizeof(tc_entity_s)); + ++registry.num_entities; + return registry.entities[entity_index]; + } + ++entity_index; + } + + registry.entities_capacity *= 2; + registry.entities = + realloc(registry.entities, sizeof(tc_entity_s *) * registry.entities_capacity); + + registry.entities[registry.num_entities] = malloc(sizeof(tc_entity_s)); + ++registry.num_entities; + + return registry.entities[registry.num_entities-1]; +} + +void tc_deallocate_entity(tc_entity_s *entity) +{ + if(entity->specific != NULL) free(entity->specific); + if(entity->attributes != NULL) free(entity->attributes); + + tc_entity_registry_s registry = tc_game_state_g.entity_registry; + + uint32_t entity_index = 0; + while(entity_index < registry.entities_capacity) + { + if(registry.entities[entity_index] == entity) + { + registry.entities[entity_index] = NULL; + break; + } + ++entity_index; + } + + free(entity); +} + diff --git a/code/source-c/initialization.c b/code/source-c/initialization.c index f0dfc27..a2775c8 100644 --- a/code/source-c/initialization.c +++ b/code/source-c/initialization.c @@ -1,5 +1,6 @@ #include "state.h" #include "world.h" +#include "entity/registration.h" #include @@ -64,6 +65,8 @@ void tc_init() tc_load_textures(); tc_game_state_g.block_registry = tc_init_blocks(); tc_create_blocks(); + tc_game_state_g.entity_registry = tc_init_entity_registry(); + tc_register_entities(); tc_init_worlds(); tc_game_state_g.main_world = tc_new_world(&tc_default_terrain_generator_g); diff --git a/code/source-c/location.c b/code/source-c/location.c new file mode 100644 index 0000000..850d42f --- /dev/null +++ b/code/source-c/location.c @@ -0,0 +1,16 @@ +#include "location.h" + +#include + +tc_location_s tc_zero_location() +{ + tc_location_s location; + location.world = NULL; + location.position.x = 0.0f; + location.position.y = 0.0f; + location.position.z = 0.0f; + location.rotation = location.position; + + return location; +} + diff --git a/code/source-c/location.h b/code/source-c/location.h new file mode 100644 index 0000000..4445e86 --- /dev/null +++ b/code/source-c/location.h @@ -0,0 +1,18 @@ + +#ifndef TC_LOCATION_H +#define TC_LOCATION_H + +#include "world.h" + +typedef struct tc_location +{ + tc_world_s *world; + tc_vec3_s position; + tc_vec3_s rotation; + +} tc_location_s; + +tc_location_s tc_zero_location(); + +#endif // TC_LOCATION_H + diff --git a/code/source-c/state.h b/code/source-c/state.h index e3e0f2d..c893489 100644 --- a/code/source-c/state.h +++ b/code/source-c/state.h @@ -8,6 +8,7 @@ #include "assets.h" #include "shaders.h" +#include "entity.h" #include "blocks.h" #include "world.h" #include "utility.h" @@ -35,6 +36,7 @@ typedef struct tc_renderer_s renderer; tc_asset_storage_s asset_storage; tc_block_registry_s block_registry; + tc_entity_registry_s entity_registry; tc_world_s *main_world; tc_image_s *block_texture_atlas;