Compare commits
3 Commits
fb0aa65d00
...
bb74d13e89
Author | SHA1 | Date |
---|---|---|
Eric-Paul Ickhorn | bb74d13e89 | |
Eric-Paul Ickhorn | 14d560dbf5 | |
Eric-Paul Ickhorn | 3a017e678e |
|
@ -7,6 +7,13 @@ gcc -g3 -o dependencies/build/glad.o \
|
|||
-I dependencies/include/ -Wall
|
||||
|
||||
gcc -g3 -o techneck.elf \
|
||||
code/source-c/*.c code/source-c/entity/*.c code/source-c/utility/*.c code/source-c/physics/*.c dependencies/build/glad.o \
|
||||
code/source-c/*.c \
|
||||
code/source-c/entity/*.c \
|
||||
code/source-c/utility/*.c \
|
||||
code/source-c/world/*.c \
|
||||
code/source-c/world/update/*.c \
|
||||
code/source-c/world/generator/*.c \
|
||||
code/source-c/physics/*.c \
|
||||
dependencies/build/glad.o \
|
||||
-I dependencies/include -I code/source-c/ -lGL -lSDL2 -lm -Wall
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <entity/registration.h>
|
||||
#include <chunk_pool.h>
|
||||
#include <chunk.h>
|
||||
#include <world.h>
|
||||
#include <world/chunk_pool.h>
|
||||
#include <world/chunk.h>
|
||||
#include <world/world.h>
|
||||
#include <state.h>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
@ -32,6 +32,9 @@ void tc_create_chunk_entity(tc_entity_s *entity, void *userdata)
|
|||
void tc_delete_chunk_entity(tc_entity_s *entity)
|
||||
{
|
||||
tc_chunk_s *chunk = entity->specific;
|
||||
tc_world_s *world = chunk->location.world;
|
||||
tc_run_hooklist(&world->on_chunk_delete, entity);
|
||||
|
||||
if(chunk->vao != 0) glDeleteVertexArrays(1, &chunk->vao);
|
||||
if(chunk->vbo != 0) glDeleteBuffers(1, &chunk->vbo);
|
||||
|
||||
|
@ -39,8 +42,10 @@ void tc_delete_chunk_entity(tc_entity_s *entity)
|
|||
if(chunk->vertex_uvs != NULL) free(chunk->vertex_uvs);
|
||||
|
||||
tc_physics_entity_s *physics_body = tc_get_pointer_from_entity(entity, "physics_body");
|
||||
if(physics_body != 0)
|
||||
{
|
||||
tc_remove_physics_entity(physics_body);
|
||||
|
||||
}
|
||||
tc_deallocate_chunk(entity->specific);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,9 @@ tc_entity_registry_s tc_init_entity_registry()
|
|||
registry.num_intervals = 0;
|
||||
registry.intervals = calloc(sizeof(tc_interval_s *), registry.intervals_capacity);
|
||||
registry.pool = tc_create_entity_pool(512);
|
||||
registry.tags_capacity = 512;
|
||||
registry.num_tags = 0;
|
||||
registry.tags = calloc(sizeof(tc_entity_tag_s), registry.tags_capacity);
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
@ -325,7 +328,8 @@ void tc_send_pointer_to_entity(tc_entity_s *entity, char *event_name, void *poin
|
|||
tc_entity_event_s event;
|
||||
event.identifier = event_name;
|
||||
event.value.pointer = pointer;
|
||||
entity->type->functions.fn_send_event(entity, event);
|
||||
tc_entity_type_s *type = entity->type;
|
||||
type->functions.fn_send_event(entity, event);
|
||||
}
|
||||
|
||||
void tc_send_string_to_entity(tc_entity_s *entity, char *event_name, char *string)
|
||||
|
@ -375,6 +379,75 @@ void tc_tick_intervals()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
tc_entity_tag_s * tc_get_tag(char *name)
|
||||
{
|
||||
for(u32_t tag_index = 0; tag_index < tc_game_state_g.entity_registry.num_tags; ++tag_index)
|
||||
{
|
||||
if(!strcmp(tc_game_state_g.entity_registry.tags[tag_index].name, name))
|
||||
return &tc_game_state_g.entity_registry.tags[tag_index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tc_entity_tag_s * tc_allocate_tag(char *name)
|
||||
{
|
||||
if(tc_game_state_g.entity_registry.num_tags
|
||||
>=
|
||||
tc_game_state_g.entity_registry.tags_capacity
|
||||
) {
|
||||
tc_game_state_g.entity_registry.tags_capacity *= 2;
|
||||
tc_game_state_g.entity_registry.tags =
|
||||
realloc(tc_game_state_g.entity_registry.tags, sizeof(tc_entity_tag_s) * tc_game_state_g.entity_registry.tags_capacity);
|
||||
}
|
||||
tc_entity_tag_s *tag = &tc_game_state_g.entity_registry.tags[tc_game_state_g.entity_registry.num_tags];
|
||||
|
||||
tag->name = name;
|
||||
tag->users_capacity = 64;
|
||||
tag->num_users = 0;
|
||||
tag->users = calloc(sizeof(tc_entity_s *), tag->users_capacity);
|
||||
++tag->num_users;
|
||||
|
||||
return tag;
|
||||
|
||||
}
|
||||
tc_entity_tag_s * tc_get_or_allocate_tag(char *name)
|
||||
{
|
||||
tc_entity_tag_s *tag = tc_get_tag(name);
|
||||
if(tag == NULL) return tc_allocate_tag(name);
|
||||
return tag;
|
||||
}
|
||||
|
||||
void tc_add_user_to_tag(tc_entity_tag_s *tag, tc_entity_s *entity)
|
||||
{
|
||||
if(tag->num_users >= tag->users_capacity)
|
||||
{
|
||||
tag->users_capacity *= 2;
|
||||
tag->users = realloc(tag->users, sizeof(tc_entity_s *) * tag->users_capacity);
|
||||
}
|
||||
tag->users[tag->num_users] = entity;
|
||||
++tag->num_users;
|
||||
}
|
||||
|
||||
void tc_tag_entity(tc_entity_s *entity, char *name)
|
||||
{
|
||||
tc_entity_tag_s *tag = tc_get_or_allocate_tag(name);
|
||||
tc_add_user_to_tag(tag, entity);
|
||||
}
|
||||
|
||||
u32_t tc_count_entitites_with_tag(char *name)
|
||||
{
|
||||
return tc_get_tag(name)->num_users;
|
||||
}
|
||||
|
||||
void tc_list_entities_with_tag(char *name, tc_entity_s **entities, u32_t max)
|
||||
{
|
||||
tc_entity_tag_s *tag = tc_get_tag(name);
|
||||
|
||||
memcpy(entities, tag->users, tc_min(max, tag->num_users) * sizeof(tc_entity_s *));
|
||||
}
|
||||
|
||||
/*
|
||||
void tc_draw_all_entities_of_type(char *name)
|
||||
{
|
|
@ -2,8 +2,8 @@
|
|||
#ifndef TC_ENTITY_H
|
||||
#define TC_ENTITY_H
|
||||
|
||||
#include "utility/location.h"
|
||||
#include "utility/utility.h"
|
||||
#include <utility/location.h>
|
||||
#include <utility/utility.h>
|
||||
|
||||
typedef struct tc_interval tc_interval_s;
|
||||
typedef struct tc_entity_event tc_entity_event_s;
|
||||
|
@ -13,6 +13,7 @@ typedef struct tc_entity tc_entity_s;
|
|||
typedef struct tc_entity_pool tc_entity_pool_s;
|
||||
typedef struct tc_entity_pool_entry tc_entity_pool_entry_s;
|
||||
typedef struct tc_entity_registry tc_entity_registry_s;
|
||||
typedef struct tc_entity_tag tc_entity_tag_s;
|
||||
|
||||
typedef void (*tc_entity_create_fn) (tc_entity_s *entity, void *userdata);
|
||||
typedef void (*tc_entity_delete_fn) (tc_entity_s *entity);
|
||||
|
@ -51,6 +52,16 @@ struct tc_entity_type
|
|||
tc_entity_s **instances;
|
||||
};
|
||||
|
||||
struct tc_entity_tag
|
||||
{
|
||||
char *name;
|
||||
|
||||
u32_t users_capacity;
|
||||
u32_t num_users;
|
||||
tc_entity_s **users;
|
||||
|
||||
};
|
||||
|
||||
struct tc_entity_attribute
|
||||
{
|
||||
char *name;
|
||||
|
@ -116,6 +127,10 @@ struct tc_entity_registry
|
|||
u32_t intervals_capacity;
|
||||
u32_t num_intervals;
|
||||
tc_interval_s *intervals;
|
||||
|
||||
u32_t tags_capacity;
|
||||
u32_t num_tags;
|
||||
tc_entity_tag_s *tags;
|
||||
};
|
||||
|
||||
tc_entity_pool_s * tc_create_entity_pool (u32_t capacity);
|
||||
|
@ -137,17 +152,22 @@ char * tc_get_string_from_entity (tc_entity_s *en
|
|||
i64_t tc_get_integer_from_entity (tc_entity_s *entity, char *attr_name);
|
||||
f64_t tc_get_float_from_entity (tc_entity_s *entity, char *attr_name);
|
||||
|
||||
void tc_tag_entity (tc_entity_s *entity, char *name);
|
||||
|
||||
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, i64_t integer);
|
||||
void tc_send_float_to_entity (tc_entity_s *entity, char *event_name, f64_t floating);
|
||||
|
||||
void tc_schedule_interval (tc_entity_s *entity, float wanted_delta, void (*fn_interval)(tc_entity_s *entity));
|
||||
void tc_tick_intervals ();
|
||||
// void tc_schedule_interval (tc_entity_s *entity, float wanted_delta, void (*fn_interval)(tc_entity_s *entity));
|
||||
// void tc_tick_intervals ();
|
||||
void tc_draw_all_entities_of_type (char *name);
|
||||
|
||||
tc_entity_s * tc_allocate_entity ();
|
||||
void tc_deallocate_entity (tc_entity_s *entity);
|
||||
|
||||
u32_t tc_count_entitites_with_tag (char *name);
|
||||
void tc_list_entities_with_tag (char *name, tc_entity_s **entities, u32_t max);
|
||||
|
||||
#endif // TC_ENTITY_H
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
#ifndef TC_ENTITY_REGISTRATION_H
|
||||
#define TC_ENTITY_REGISTRATION_H
|
||||
|
||||
#include "../entity.h"
|
||||
#include <entity/entity.h>
|
||||
|
||||
void tc_register_chunk_entity ();
|
||||
void tc_register_player_entity ();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "state.h"
|
||||
#include "world.h"
|
||||
#include "entity/registration.h"
|
||||
#include <state.h>
|
||||
#include <world/world.h>
|
||||
#include <entity/registration.h>
|
||||
#include <world/update/world_update.h>
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
|
@ -62,7 +63,11 @@ void tc_load_textures()
|
|||
|
||||
void tc_init()
|
||||
{
|
||||
tc_start_world_updater();
|
||||
tc_init_renderer (&tc_game_state_g);
|
||||
|
||||
|
||||
tc_promise_s main_world_promise = tc_worldupdate_register_world ();
|
||||
tc_game_state_g.asset_storage = tc_init_asset_storage("assets/");
|
||||
tc_load_textures();
|
||||
tc_game_state_g.block_registry = tc_init_blocks();
|
||||
|
@ -74,7 +79,7 @@ void tc_init()
|
|||
tc_add_to_hooklist(&tc_game_state_g.on_world_create, (tc_fn_hook) &tc_create_world_physics, NULL);
|
||||
|
||||
tc_init_worlds();
|
||||
tc_game_state_g.main_world = tc_new_world(&tc_default_terrain_generator_g);
|
||||
// tc_game_state_g.main_world = tc_new_world(&tc_default_terrain_generator_g);
|
||||
tc_game_state_g.player = tc_create_entity("player", NULL);
|
||||
tc_game_state_g.viewer = tc_game_state_g.player;
|
||||
|
||||
|
@ -89,7 +94,7 @@ void tc_init()
|
|||
|
||||
void tc_cleanup()
|
||||
{
|
||||
tc_unload_world(tc_game_state_g.main_world);
|
||||
// tc_unload_world(tc_game_state_g.main_world);
|
||||
tc_cleanup_chunk_pool();
|
||||
SDL_GL_DeleteContext(tc_game_state_g.renderer.gl_context);
|
||||
SDL_DestroyWindow(tc_game_state_g.renderer.window);
|
||||
|
|
|
@ -83,7 +83,7 @@ void render()
|
|||
tc_shader_uniform_mat4f(&tc_game_state_g.renderer.draw_shader, "projection_matrix", projection_matrix);
|
||||
tc_shader_uniform_mat4f(&tc_game_state_g.renderer.draw_shader, "view_matrix", view_matrix);
|
||||
|
||||
tc_draw_world(tc_game_state_g.main_world);
|
||||
// tc_draw_world(tc_game_state_g.main_world);
|
||||
|
||||
SDL_GL_SwapWindow(tc_game_state_g.renderer.window);
|
||||
}
|
||||
|
@ -284,11 +284,11 @@ bool update()
|
|||
tc_move_viewer_to(camera_position.x, camera_position.y, camera_position.z);
|
||||
tc_rotate_viewer_to(camera_rotation.x, camera_rotation.y, camera_rotation.z);
|
||||
|
||||
tc_game_state_g.main_world->spawn_loader->center.grid_coords.x = ((int32_t) camera_position.x) / 32 - UPDATE_DISTANCE;
|
||||
tc_game_state_g.main_world->spawn_loader->center.grid_coords.y = ((int32_t) camera_position.y) / 32 - UPDATE_DISTANCE;
|
||||
tc_game_state_g.main_world->spawn_loader->center.grid_coords.z = - ((int32_t) camera_position.z) / 32 - UPDATE_DISTANCE;
|
||||
// tc_game_state_g.main_world->spawn_loader->center.grid_coords.x = ((int32_t) camera_position.x) / 32 - UPDATE_DISTANCE;
|
||||
// tc_game_state_g.main_world->spawn_loader->center.grid_coords.y = ((int32_t) camera_position.y) / 32 - UPDATE_DISTANCE;
|
||||
// tc_game_state_g.main_world->spawn_loader->center.grid_coords.z = - ((int32_t) camera_position.z) / 32 - UPDATE_DISTANCE;
|
||||
|
||||
tc_update_world(tc_game_state_g.main_world);
|
||||
// tc_update_world(tc_game_state_g.main_world);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ void tc_add_physics_object(tc_physics_simulation_s *simulation, tc_physics_entit
|
|||
|
||||
void tc_add_physics_object_to(tc_physics_entity_s *container, tc_physics_entity_s *object)
|
||||
{
|
||||
if(container != NULL) object->super = container;
|
||||
|
||||
if((container->value.group.num_entities+1)
|
||||
>=
|
||||
container->value.group.entities_capacity
|
||||
|
@ -76,7 +78,7 @@ i32_t tc_physics_find_entity_in_group(tc_physics_entity_s *group, tc_physics_ent
|
|||
i32_t index = 0;
|
||||
while(index < group->value.group.num_entities)
|
||||
{
|
||||
if(entity->super->value.group.entities[group->value.group.num_entities]
|
||||
if(group->value.group.entities[group->value.group.num_entities]
|
||||
==
|
||||
entity
|
||||
) return index;
|
||||
|
@ -99,15 +101,18 @@ void tc_remove_physics_entity(tc_physics_entity_s *entity)
|
|||
{
|
||||
if(entity->super == NULL) return;
|
||||
|
||||
tc_free_physics_entity(entity);
|
||||
|
||||
// Fill up the gap created inside the entities-array.
|
||||
|
||||
i32_t index = 0;
|
||||
if((index = tc_physics_find_entity_in_group(entity->super, entity)) == -1) return;
|
||||
tc_physics_entity_s *super = entity->super;
|
||||
|
||||
entity->super->value.group.entities[index] =
|
||||
entity->super->value.group.entities[entity->super->value.group.num_entities-1];
|
||||
i32_t index = 0;
|
||||
if((index = tc_physics_find_entity_in_group(super, entity)) == -1) return;
|
||||
|
||||
super->value.group.entities[index] =
|
||||
super->value.group.entities[super->value.group.num_entities-1];
|
||||
--super->value.group.num_entities;
|
||||
|
||||
tc_free_physics_entity(entity);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <physics/primitives.h>
|
||||
#include <utility/utility.h>
|
||||
#include <entity.h>
|
||||
#include <entity/entity.h>
|
||||
|
||||
typedef struct tc_physics_entity tc_physics_entity_s;
|
||||
typedef struct tc_entity_physics_attributes tc_entity_physics_attributes_s;
|
||||
|
|
|
@ -8,9 +8,9 @@
|
|||
|
||||
#include <assets.h>
|
||||
#include <shaders.h>
|
||||
#include <entity.h>
|
||||
#include <entity/entity.h>
|
||||
#include <blocks.h>
|
||||
#include <world.h>
|
||||
#include <world/world.h>
|
||||
#include <utility/utility.h>
|
||||
|
||||
typedef struct tc_camera
|
||||
|
@ -37,7 +37,7 @@ typedef struct
|
|||
tc_asset_storage_s asset_storage;
|
||||
tc_block_registry_s block_registry;
|
||||
tc_entity_registry_s entity_registry;
|
||||
tc_world_s *main_world;
|
||||
// tc_world_s *main_world;
|
||||
tc_entity_s *viewer;
|
||||
tc_entity_s *player;
|
||||
|
||||
|
|
|
@ -10,3 +10,9 @@ f32_t tc_rad_to_deg(f32_t radians)
|
|||
return radians / (3.1415*2.0f) * 360.0f;
|
||||
}
|
||||
|
||||
i64_t tc_min(i64_t first, i64_t second)
|
||||
{
|
||||
if(first < second) return first;
|
||||
return second;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,8 @@ struct tc_mat3f
|
|||
f32_t tc_deg_to_rad (f32_t degrees);
|
||||
f32_t tc_rad_to_deg (f32_t radians);
|
||||
|
||||
i64_t tc_min (i64_t first, i64_t second);
|
||||
|
||||
bool_t tc_vec4f_equ (tc_vec4f_s vector_1, tc_vec4f_s vector_2);
|
||||
bool_t tc_vec3f_equ (tc_vec3f_s vector_1, tc_vec3f_s vector_2);
|
||||
bool_t tc_vec2f_equ (tc_vec2f_s vector_1, tc_vec2f_s vector_2);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "world.h"
|
||||
#include <utility/utility.h>
|
||||
|
||||
int tc_perlin_permutation[] = {
|
||||
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225,
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#ifndef TC_PROMISE_H
|
||||
#define TC_PROMISE_H
|
||||
|
||||
#include <utility/utility.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u64_t issueing_tick;
|
||||
u32_t identifier;
|
||||
|
||||
} tc_promise_s;
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include <chunk.h>
|
||||
#include <world/chunk.h>
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <stddef.h>
|
||||
|
@ -38,6 +38,10 @@ void tc_draw_chunkloader_zone(tc_chunkloader_s *loader)
|
|||
tc_chunklist_s *list = &loader->chunklist;
|
||||
for(tc_chunklist_entry_s *current = list->first; current != NULL; current = current->next)
|
||||
{
|
||||
if(current->entity == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
tc_send_pointer_to_entity(current->entity, "draw", 0);
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#define TC_CHUNK_H
|
||||
|
||||
#include <utility/location.h>
|
||||
#include <entity.h>
|
||||
#include <entity/entity.h>
|
||||
|
||||
typedef struct tc_chunk tc_chunk_s;
|
||||
typedef struct tc_chunkloader tc_chunkloader_s;
|
|
@ -3,7 +3,7 @@
|
|||
#define TC_CHUNK_POOL_H
|
||||
|
||||
#include <utility/utility.h>
|
||||
#include <chunk.h>
|
||||
#include <world/chunk.h>
|
||||
|
||||
typedef struct tc_chunk_pool tc_chunk_pool_s;
|
||||
typedef struct tc_chunk_pool_entry tc_chunk_pool_entry_s;
|
|
@ -1,5 +1,6 @@
|
|||
#include "world.h"
|
||||
#include "entity.h"
|
||||
#include <world/world.h>
|
||||
#include <entity/entity.h>
|
||||
#include <state.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
@ -95,7 +96,6 @@ void tc_chunklist_add_item(tc_chunklist_s *list, tc_entity_s *chunk)
|
|||
new_entry.entity = chunk;
|
||||
new_entry.next = list->first;
|
||||
(*list->first_free) = new_entry;
|
||||
list->first = list->first_free;
|
||||
|
||||
// Link everything together
|
||||
|
||||
|
@ -104,6 +104,7 @@ void tc_chunklist_add_item(tc_chunklist_s *list, tc_entity_s *chunk)
|
|||
list->first_free->previous = NULL;
|
||||
|
||||
// Finally assign it
|
||||
list->first = list->first_free;
|
||||
list->first_free = tc_chunklist_find_first_free(list);
|
||||
}
|
||||
|
||||
|
@ -117,6 +118,9 @@ void tc_chunklist_remove_item(tc_chunklist_s *list, tc_entity_s *chunk)
|
|||
if(entry->previous != NULL)
|
||||
entry->previous->next = entry->next;
|
||||
|
||||
if(entry->next != NULL)
|
||||
entry->next->previous = entry->previous;
|
||||
|
||||
entry->entity = NULL;
|
||||
list->first_free = entry;
|
||||
}
|
||||
|
@ -130,7 +134,7 @@ tc_chunkloader_s tc_create_chunkloader(tc_chunk_location_s location)
|
|||
loader.extent.y = UPDATE_DISTANCE * 2 + 1;
|
||||
loader.extent.z = UPDATE_DISTANCE * 2 + 1;
|
||||
loader.center = location;
|
||||
loader.chunklist = tc_create_chunklist(200);
|
||||
loader.chunklist = tc_create_chunklist(512);
|
||||
loader.needs_reload = FALSE;
|
||||
|
||||
return loader;
|
||||
|
@ -149,13 +153,13 @@ void tc_delete_chunkloader(tc_chunkloader_s loader)
|
|||
|
||||
bool_t tc_coord_is_within_loaders_range(tc_chunkloader_s *loader, tc_vec3i_s coord)
|
||||
{
|
||||
if(coord.x < (loader->center.grid_coords.x - loader->extent.x / 2)) return FALSE;
|
||||
if(coord.y < (loader->center.grid_coords.y - loader->extent.y / 2)) return FALSE;
|
||||
if(coord.z < (loader->center.grid_coords.z - loader->extent.z / 2)) return FALSE;
|
||||
if(coord.x < ((loader->center.grid_coords.x - loader->extent.x / 2)-1)) return FALSE;
|
||||
if(coord.y < ((loader->center.grid_coords.y - loader->extent.y / 2)-1)) return FALSE;
|
||||
if(coord.z < ((loader->center.grid_coords.z - loader->extent.z / 2)-1)) return FALSE;
|
||||
|
||||
if(coord.x > (loader->center.grid_coords.x + loader->extent.x / 2)) return FALSE;
|
||||
if(coord.y > (loader->center.grid_coords.y + loader->extent.y / 2)) return FALSE;
|
||||
if(coord.z > (loader->center.grid_coords.z + loader->extent.z / 2)) return FALSE;
|
||||
if(coord.x > ((loader->center.grid_coords.x + loader->extent.x / 2)+1)) return FALSE;
|
||||
if(coord.y > ((loader->center.grid_coords.y + loader->extent.y / 2)+1)) return FALSE;
|
||||
if(coord.z > ((loader->center.grid_coords.z + loader->extent.z / 2)+1)) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -178,7 +182,9 @@ void tc_unload_chunk_at(tc_chunkloader_s *loader, tc_chunk_location_s location)
|
|||
if(entity == NULL) return;
|
||||
|
||||
tc_chunk_s *chunk = entity->specific;
|
||||
tc_world_s *world = location.world;
|
||||
|
||||
tc_run_hooklist(&world->on_chunk_unload, entity);
|
||||
--chunk->refcounter;
|
||||
|
||||
if(chunk->refcounter < 1)
|
|
@ -1,4 +1,4 @@
|
|||
#include "world.h"
|
||||
#include <world/world.h>
|
||||
|
||||
bool_t tc_generate_default_terrain_chunk(tc_worldgen_s *gen, tc_chunk_s *chunk)
|
||||
{
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
#ifndef TC_WORLD_UPDATER_INTERNAL_H
|
||||
#define TC_WORLD_UPDATER_INTERNAL_H
|
||||
|
||||
#include <world/world.h>
|
||||
#include <utility/location.h>
|
||||
#include <utility/promise.h>
|
||||
|
||||
typedef struct tc_world_updater_queue tc_world_updater_queue_s;
|
||||
typedef struct tc_world_updater_command tc_world_updater_command_s;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TC_WORLD_UPDATER_COMMAND_UNKNOWN,
|
||||
TC_WORLD_UPDATER_COMMAND_MOVE_CHUNKLOADER,
|
||||
TC_WORLD_UPDATER_COMMAND_PLACE_BLOCK,
|
||||
TC_WORLD_UPDATER_COMMAND_STOP,
|
||||
TC_WORLD_UPDATER_COMMAND_ADD_WORLD,
|
||||
TC_WORLD_UPDATER_COMMAND_ADD_CHUNKLOADER,
|
||||
TC_WORLD_UPDATER_COMMAND_DELETE_CHUNKLOADER,
|
||||
TC_WORLD_UPDATER_COMMAND_GET_WORLD,
|
||||
TC_WORLD_UPDATER_COMMAND_GET_CHUNKLOADER,
|
||||
TC_WORLD_UPDATER_COMMAND_GET_CHUNKLIST
|
||||
|
||||
} tc_world_update_command_e;
|
||||
|
||||
struct tc_world_updater_command
|
||||
{
|
||||
tc_world_updater_command_s *next;
|
||||
tc_world_updater_command_s *previous;
|
||||
|
||||
tc_world_update_command_e type;
|
||||
|
||||
union command
|
||||
{
|
||||
struct move_chunkloader_command
|
||||
{
|
||||
u32_t loader_id;
|
||||
tc_chunk_location_s new_location;
|
||||
} move_chunkloader;
|
||||
|
||||
struct place_block_command
|
||||
{
|
||||
tc_block_s block;
|
||||
tc_block_location_s location;
|
||||
|
||||
} place_block;
|
||||
|
||||
struct get_item
|
||||
{
|
||||
u32_t index;
|
||||
u32_t promise;
|
||||
|
||||
} get_item;
|
||||
|
||||
} specific;
|
||||
|
||||
bool_t is_used;
|
||||
};
|
||||
|
||||
struct tc_world_updater_queue
|
||||
{
|
||||
tc_world_updater_command_s *first;
|
||||
tc_world_updater_command_s *last;
|
||||
bool_t in_action;
|
||||
|
||||
u32_t capacity;
|
||||
tc_world_updater_command_s *commands;
|
||||
};
|
||||
|
||||
void tc_worldupdate_initialize_promises ();
|
||||
tc_world_updater_queue_s tc_new_world_updater_queue (u32_t capacity);
|
||||
bool_t tc_issue_world_updater_command (
|
||||
tc_world_updater_queue_s *queue, tc_world_updater_command_s command
|
||||
);
|
||||
|
||||
tc_world_updater_command_s tc_world_updater_query_next_command
|
||||
(tc_world_updater_queue_s *queue);
|
||||
|
||||
|
||||
tc_promise_s tc_worldupdate_reserve_world_promise ();
|
||||
tc_promise_s tc_worldupdate_reserve_chunkloader_promise ();
|
||||
tc_promise_s tc_worldupdate_reserve_chunklist_promise ();
|
||||
|
||||
void tc_worldupate_set_world_promise (u32_t identifier, tc_world_s *world);
|
||||
void tc_worldupate_set_chunkloader_promise (u32_t identifier, tc_chunkloader_s *chunkloader);
|
||||
void tc_worldupate_set_chunklist_promise (u32_t identifier, tc_chunklist_s *chunklist);
|
||||
|
||||
tc_world_updater_queue_s tc_new_world_updater_queue
|
||||
(u32_t capacity);
|
||||
|
||||
void tc_worldupdater_execute_move_chunkloader (tc_world_updater_command_s command);
|
||||
void tc_worldupdater_execute_place_block (tc_world_updater_command_s command);
|
||||
void tc_worldupdater_execute_stop (tc_world_updater_command_s command);
|
||||
void tc_worldupdater_execute_add_world (tc_world_updater_command_s command);
|
||||
void tc_worldupdater_execute_add_chunkloader (tc_world_updater_command_s command);
|
||||
void tc_worldupdater_execute_delete_chunkloader (tc_world_updater_command_s command);
|
||||
void tc_worldupdater_execute_get_world (tc_world_updater_command_s command);
|
||||
void tc_worldupdater_execute_get_chunkloader (tc_world_updater_command_s command);
|
||||
void tc_worldupdater_execute_get_chunklist (tc_world_updater_command_s command);
|
||||
|
||||
#endif // TC_WORLD_UPDATER_INTERNAL_H
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
#include <world/update/world_update.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
u32_t tc_promise_identifier_counter = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t identifier;
|
||||
tc_world_s *world;
|
||||
|
||||
} tc_worldupdate_world_promise_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t identifier;
|
||||
tc_chunkloader_s *chunkloader;
|
||||
|
||||
} tc_worldupdate_chunkloader_promise_s;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32_t identifier;
|
||||
tc_chunklist_s *chunklist;
|
||||
|
||||
} tc_worldupdate_chunklist_promise_s;
|
||||
|
||||
tc_worldupdate_world_promise_s *tc_worldupdate_worlds_promise_registry = NULL;
|
||||
tc_worldupdate_chunkloader_promise_s *tc_worldupdate_chunkloader_promise_registry = NULL;
|
||||
tc_worldupdate_chunklist_promise_s *tc_worldupdate_chunklist_promise_registry = NULL;
|
||||
|
||||
#define TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE 4096
|
||||
|
||||
void tc_worldupdate_initialize_promises()
|
||||
{
|
||||
tc_worldupdate_worlds_promise_registry = calloc(sizeof(tc_worldupdate_world_promise_s), TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE);
|
||||
tc_worldupdate_chunkloader_promise_registry = calloc(sizeof(tc_worldupdate_chunkloader_promise_s), TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE);
|
||||
tc_worldupdate_chunklist_promise_registry = calloc(sizeof(tc_worldupdate_chunklist_promise_s), TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
tc_promise_s tc_worldupdate_reserve_world_promise()
|
||||
{
|
||||
u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_world_promise_s *entry = &tc_worldupdate_worlds_promise_registry[index];
|
||||
if(entry->identifier == 0)
|
||||
if(entry->world != NULL)
|
||||
{
|
||||
++tc_promise_identifier_counter;
|
||||
tc_promise_s promise;
|
||||
promise.identifier = tc_promise_identifier_counter;
|
||||
entry->identifier = promise.identifier;
|
||||
entry->world = NULL;
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
tc_promise_s promise;
|
||||
promise.identifier = 0;
|
||||
promise.issueing_tick = 0;
|
||||
return promise;
|
||||
}
|
||||
|
||||
tc_promise_s tc_worldupdate_reserve_chunkloader_promise()
|
||||
{
|
||||
u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_chunkloader_promise_s *entry = &tc_worldupdate_chunkloader_promise_registry[index];
|
||||
if(entry->identifier == 0)
|
||||
if(entry->chunkloader != NULL)
|
||||
{
|
||||
++tc_promise_identifier_counter;
|
||||
tc_promise_s promise;
|
||||
promise.identifier = tc_promise_identifier_counter;
|
||||
entry->identifier = promise.identifier;
|
||||
entry->chunkloader = NULL;
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
tc_promise_s promise;
|
||||
promise.identifier = 0;
|
||||
promise.issueing_tick = 0;
|
||||
return promise;
|
||||
}
|
||||
|
||||
tc_promise_s tc_worldupdate_reserve_chunklist_promise()
|
||||
{
|
||||
u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_chunklist_promise_s *entry = &tc_worldupdate_chunklist_promise_registry[index];
|
||||
if(entry->identifier == 0)
|
||||
if(entry->chunklist != NULL)
|
||||
{
|
||||
++tc_promise_identifier_counter;
|
||||
tc_promise_s promise;
|
||||
promise.identifier = tc_promise_identifier_counter;
|
||||
entry->identifier = promise.identifier;
|
||||
entry->chunklist = NULL;
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
tc_promise_s promise;
|
||||
promise.identifier = 0;
|
||||
promise.issueing_tick = 0;
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const tc_world_s * tc_worldupdate_claim_world_promise(tc_promise_s promise)
|
||||
{
|
||||
u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_world_promise_s *entry = &tc_worldupdate_worlds_promise_registry[index];
|
||||
if(entry->identifier == promise.identifier)
|
||||
if(entry->world != NULL)
|
||||
{
|
||||
entry->identifier = 0;
|
||||
return entry->world;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const tc_chunkloader_s * tc_worldupdate_claim_chunkloader_promise(tc_promise_s promise)
|
||||
{
|
||||
u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_chunkloader_promise_s *entry = &tc_worldupdate_chunkloader_promise_registry[index];
|
||||
if(entry->identifier == promise.identifier)
|
||||
if(entry->chunkloader != NULL)
|
||||
{
|
||||
entry->identifier = 0;
|
||||
return entry->chunkloader;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const tc_chunklist_s * tc_worldupdate_claim_chunks_promise(tc_promise_s promise)
|
||||
{
|
||||
u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_chunklist_promise_s *entry = &tc_worldupdate_chunklist_promise_registry[index];
|
||||
if(entry->identifier == promise.identifier)
|
||||
if(entry->chunklist != NULL)
|
||||
{
|
||||
entry->identifier = 0;
|
||||
return entry->chunklist;
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void tc_worldupate_set_world_promise(u32_t identifier, tc_world_s *world)
|
||||
{
|
||||
u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_world_promise_s *entry = &tc_worldupdate_worlds_promise_registry[index];
|
||||
if(entry->identifier == identifier)
|
||||
entry->world = world;
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
void tc_worldupate_set_chunkloader_promise(u32_t identifier, tc_chunkloader_s *chunkloader)
|
||||
{u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_chunkloader_promise_s *entry = &tc_worldupdate_chunkloader_promise_registry[index];
|
||||
if(entry->identifier == identifier)
|
||||
entry->chunkloader = chunkloader;
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
void tc_worldupate_set_chunklist_promise(u32_t identifier, tc_chunklist_s *chunklist)
|
||||
{
|
||||
u32_t index = 0;
|
||||
while(index < TC_WORLDUPDATE_PROMISE_REGISTRY_SIZE)
|
||||
{
|
||||
tc_worldupdate_chunklist_promise_s *entry = &tc_worldupdate_chunklist_promise_registry[index];
|
||||
if(entry->identifier == identifier)
|
||||
entry->chunklist = chunklist;
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
#include <world/update/internal.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
tc_world_updater_queue_s tc_new_world_updater_queue(u32_t capacity)
|
||||
{
|
||||
tc_world_updater_queue_s queue;
|
||||
queue.capacity = capacity;
|
||||
queue.commands = calloc(sizeof(tc_world_updater_command_s), capacity);
|
||||
queue.first = NULL;
|
||||
queue.last = NULL;
|
||||
queue.in_action = FALSE;
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
||||
// tc_allocate_world_updater_command: Returns a pointer to a command-slot in the given queue.
|
||||
// Sub-function of tc_issue_world_updater_command
|
||||
tc_world_updater_command_s * tc_allocate_world_updater_command(tc_world_updater_queue_s *queue)
|
||||
{
|
||||
u32_t command_index = 0;
|
||||
while(command_index < queue->capacity)
|
||||
{
|
||||
if(!queue->commands[command_index].is_used)
|
||||
return &queue->commands[command_index];
|
||||
|
||||
++command_index;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool_t tc_issue_world_updater_command(tc_world_updater_queue_s *queue, tc_world_updater_command_s command)
|
||||
{
|
||||
while(queue->in_action) continue;
|
||||
queue->in_action = TRUE;
|
||||
|
||||
tc_world_updater_command_s *queue_command = tc_allocate_world_updater_command(queue);
|
||||
if(queue_command == NULL) return FALSE;
|
||||
|
||||
command.is_used = TRUE;
|
||||
(*queue_command) = command;
|
||||
queue_command->previous = queue->last;
|
||||
queue_command->next = NULL;
|
||||
|
||||
if(queue->last != NULL) queue->last->next = queue_command;
|
||||
if(queue->first == NULL) queue->first = queue_command;
|
||||
queue->last = queue_command;
|
||||
|
||||
queue->in_action = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
tc_world_updater_command_s tc_world_updater_query_next_command(tc_world_updater_queue_s *queue)
|
||||
{
|
||||
while(queue->in_action) continue;
|
||||
queue->in_action = TRUE;
|
||||
|
||||
tc_world_updater_command_s *queue_command = queue->first;
|
||||
tc_world_updater_command_s command;
|
||||
memset(&command, 0x00, sizeof(tc_world_updater_command_s));
|
||||
|
||||
if(queue_command != NULL)
|
||||
{
|
||||
command = *queue_command;
|
||||
|
||||
queue_command->is_used = FALSE;
|
||||
}
|
||||
queue->in_action = FALSE;
|
||||
|
||||
return command;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#include <world/update/internal.h>
|
||||
|
||||
void tc_worldupdater_execute_move_chunkloader(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void tc_worldupdater_execute_place_block(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void tc_worldupdater_execute_stop(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void tc_worldupdater_execute_add_world(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void tc_worldupdater_execute_add_chunkloader(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void tc_worldupdater_execute_delete_chunkloader(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void tc_worldupdater_execute_get_world(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void tc_worldupdater_execute_get_chunkloader(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void tc_worldupdater_execute_get_chunklist(tc_world_updater_command_s command)
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
#ifndef TC_WORLD_CONFIGURATION_H
|
||||
#define TC_WORLD_CONFIGURATION_H
|
||||
|
||||
#include <world/world.h>
|
||||
#include <world/chunk.h>
|
||||
#include <utility/location.h>
|
||||
#include <utility/promise.h>
|
||||
|
||||
void tc_activate_world (u32_t identifier);
|
||||
void tc_deactivate_world (u32_t identifier);
|
||||
|
||||
void tc_update_world (u32_t identifier);
|
||||
|
||||
#endif TC_WORLD_CONFIGURATION_H
|
||||
|
|
@ -0,0 +1,212 @@
|
|||
#include <world/update/world_update.h>
|
||||
#include <world/update/internal.h>
|
||||
|
||||
typedef struct tc_world_registry
|
||||
{
|
||||
u32_t worlds_capacity;
|
||||
u32_t num_worlds;
|
||||
tc_world_s *worlds;
|
||||
|
||||
} tc_world_registry_s;
|
||||
|
||||
typedef struct tc_world_updater
|
||||
{
|
||||
bool_t running;
|
||||
tc_world_updater_queue_s queue;
|
||||
tc_world_registry_s world_registry;
|
||||
|
||||
SDL_Thread *sdl_thread;
|
||||
|
||||
} tc_world_updater_s;
|
||||
|
||||
tc_world_updater_s *tc_world_updater_g = NULL;
|
||||
|
||||
#define TICKS_PER_SECOND 2
|
||||
#define WORLD_UPDATES_PER_SECOND 0.5
|
||||
|
||||
void tc_update_all_worlds(tc_world_registry_s *registry)
|
||||
{
|
||||
for(u32_t world_index = 0; world_index < registry->num_worlds; ++world_index)
|
||||
{
|
||||
tc_world_s *world = ®istry->worlds[world_index];
|
||||
tc_update_world(world);
|
||||
}
|
||||
}
|
||||
|
||||
void tc_world_updater_run(void *data)
|
||||
{
|
||||
u64_t tick_at_start = 0;
|
||||
|
||||
u64_t world_update_count = 0;
|
||||
|
||||
tc_world_updater_s *updater = data;
|
||||
updater->running = TRUE;
|
||||
while(updater->running)
|
||||
{
|
||||
tick_at_start = SDL_GetTicks();
|
||||
|
||||
if((tick_at_start / WORLD_UPDATES_PER_SECOND) == world_update_count)
|
||||
{
|
||||
|
||||
++world_update_count;
|
||||
}
|
||||
|
||||
if(tc_world_updater_g->queue.in_action)
|
||||
{
|
||||
while(tc_world_updater_g->queue.in_action) continue;
|
||||
}
|
||||
|
||||
tc_world_updater_command_s command =
|
||||
tc_world_updater_query_next_command(&tc_world_updater_g->queue);
|
||||
|
||||
switch(command.type)
|
||||
{
|
||||
case TC_WORLD_UPDATER_COMMAND_UNKNOWN: break;
|
||||
case TC_WORLD_UPDATER_COMMAND_MOVE_CHUNKLOADER: tc_worldupdater_execute_move_chunkloader(command);
|
||||
case TC_WORLD_UPDATER_COMMAND_PLACE_BLOCK: tc_worldupdater_execute_place_block(command);
|
||||
case TC_WORLD_UPDATER_COMMAND_STOP: tc_worldupdater_execute_stop(command);
|
||||
case TC_WORLD_UPDATER_COMMAND_ADD_WORLD: tc_worldupdater_execute_add_world(command);
|
||||
case TC_WORLD_UPDATER_COMMAND_ADD_CHUNKLOADER: tc_worldupdater_execute_add_chunkloader(command);
|
||||
case TC_WORLD_UPDATER_COMMAND_DELETE_CHUNKLOADER: tc_worldupdater_execute_delete_chunkloader(command);
|
||||
case TC_WORLD_UPDATER_COMMAND_GET_WORLD: tc_worldupdater_execute_get_world(command);
|
||||
case TC_WORLD_UPDATER_COMMAND_GET_CHUNKLOADER: tc_worldupdater_execute_get_chunkloader(command);
|
||||
case TC_WORLD_UPDATER_COMMAND_GET_CHUNKLIST: tc_worldupdater_execute_get_chunklist(command);
|
||||
}
|
||||
|
||||
u64_t tick_at_end = SDL_GetTicks();
|
||||
|
||||
|
||||
|
||||
SDL_Delay((1000 / TICKS_PER_SECOND) - (tick_at_end - tick_at_start));
|
||||
}
|
||||
}
|
||||
|
||||
tc_world_registry_s tc_new_world_registry()
|
||||
{
|
||||
tc_world_registry_s registry;
|
||||
registry.num_worlds = 0;
|
||||
registry.worlds_capacity = 64;
|
||||
registry.worlds = calloc(sizeof(tc_world_s), registry.worlds_capacity);
|
||||
|
||||
return registry;
|
||||
}
|
||||
|
||||
void tc_start_world_updater()
|
||||
{
|
||||
tc_worldupdate_initialize_promises(4096);
|
||||
|
||||
tc_world_updater_g = malloc(sizeof(tc_world_updater_s));
|
||||
tc_world_updater_g->world_registry = tc_new_world_registry();
|
||||
tc_world_updater_g->sdl_thread = SDL_CreateThread((SDL_ThreadFunction) &tc_world_updater_run, "w_update", &tc_world_updater_g);
|
||||
tc_world_updater_g->queue = tc_new_world_updater_queue(4096);
|
||||
|
||||
SDL_DetachThread(tc_world_updater_g->sdl_thread);
|
||||
}
|
||||
|
||||
tc_promise_s tc_worldupdate_register_world()
|
||||
{
|
||||
tc_promise_s promise = tc_worldupdate_reserve_world_promise();
|
||||
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
tc_promise_s tc_worldupdate_add_chunkloader()
|
||||
{
|
||||
tc_promise_s promise = tc_worldupdate_reserve_chunkloader_promise();
|
||||
tc_world_updater_command_s command;
|
||||
command.type = TC_WORLD_UPDATER_COMMAND_ADD_CHUNKLOADER;
|
||||
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
void tc_worldupdate_delete_chunkloader(u32_t loader_id)
|
||||
{
|
||||
tc_world_updater_command_s command;
|
||||
command.type = TC_WORLD_UPDATER_COMMAND_DELETE_CHUNKLOADER;
|
||||
command.specific.get_item.index = loader_id;
|
||||
|
||||
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
|
||||
}
|
||||
|
||||
u32_t tc_worldupdate_get_chunkloader_count_of_world(u32_t world_id)
|
||||
{
|
||||
return 0; // TODO
|
||||
}
|
||||
|
||||
u32_t tc_worldupdate_get_world_count()
|
||||
{
|
||||
return 0; // TODO
|
||||
}
|
||||
|
||||
tc_promise_s tc_worldupdate_get_world(u32_t index)
|
||||
{
|
||||
tc_promise_s promise = tc_worldupdate_reserve_world_promise();
|
||||
tc_world_updater_command_s command;
|
||||
command.type = TC_WORLD_UPDATER_COMMAND_GET_WORLD;
|
||||
command.specific.get_item.index = index;
|
||||
command.specific.get_item.promise = promise.identifier;
|
||||
|
||||
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
tc_promise_s tc_worldupdate_get_chunkloader_of_world(u32_t world_id, u32_t index)
|
||||
{
|
||||
tc_promise_s promise = tc_worldupdate_reserve_chunkloader_promise();
|
||||
tc_world_updater_command_s command;
|
||||
command.type = TC_WORLD_UPDATER_COMMAND_GET_CHUNKLOADER;
|
||||
command.specific.get_item.index = index;
|
||||
command.specific.get_item.promise = promise.identifier;
|
||||
|
||||
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
tc_promise_s tc_worldupdate_get_chunks_of_chunkloader(u32_t loader_id)
|
||||
{
|
||||
tc_promise_s promise = tc_worldupdate_reserve_chunklist_promise();
|
||||
tc_world_updater_command_s command;
|
||||
command.type = TC_WORLD_UPDATER_COMMAND_GET_CHUNKLIST;
|
||||
command.specific.get_item.index = loader_id;
|
||||
command.specific.get_item.promise = promise.identifier;
|
||||
|
||||
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void tc_worldupdate_move_chunkloader_to(u32_t loader_id, tc_chunk_location_s location)
|
||||
{
|
||||
tc_world_updater_command_s command;
|
||||
command.type = TC_WORLD_UPDATER_COMMAND_MOVE_CHUNKLOADER;
|
||||
command.specific.move_chunkloader.loader_id = loader_id;
|
||||
command.specific.move_chunkloader.new_location = location;
|
||||
|
||||
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
|
||||
}
|
||||
|
||||
void tc_worldupdate_place_block(tc_block_location_s location, tc_block_s block)
|
||||
{
|
||||
tc_world_updater_command_s command;
|
||||
command.type = TC_WORLD_UPDATER_COMMAND_PLACE_BLOCK;
|
||||
command.specific.place_block.location = location;
|
||||
command.specific.place_block.block = block;
|
||||
|
||||
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
|
||||
}
|
||||
|
||||
void tc_worldupdate_stop()
|
||||
{
|
||||
tc_world_updater_command_s command;
|
||||
command.type = TC_WORLD_UPDATER_COMMAND_STOP;
|
||||
|
||||
tc_issue_world_updater_command(&tc_world_updater_g->queue, command);
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
#ifndef TC_WORLD_UPDATE_H
|
||||
#define TC_WORLD_UPDATE_H
|
||||
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#include <world/world.h>
|
||||
#include <world/chunk.h>
|
||||
#include <utility/location.h>
|
||||
#include <utility/promise.h>
|
||||
|
||||
void tc_start_world_updater ();
|
||||
|
||||
tc_promise_s tc_worldupdate_register_world ();
|
||||
void tc_worldupdate_remove_world (u32_t world_id);
|
||||
|
||||
tc_promise_s tc_worldupdate_add_chunkloader ();
|
||||
void tc_worldupdate_delete_chunkloader (u32_t loader_id);
|
||||
|
||||
u32_t tc_worldupdate_get_world_count ();
|
||||
tc_promise_s tc_worldupdate_get_world (u32_t index);
|
||||
|
||||
u32_t tc_worldupdate_get_chunkloader_count_of_world (u32_t world_id);
|
||||
tc_promise_s tc_worldupdate_get_chunkloader_of_world (u32_t world_id, u32_t index);
|
||||
tc_promise_s tc_worldupdate_get_chunks_of_chunkloader (u32_t loader_id);
|
||||
|
||||
void tc_worldupdate_move_chunkloader_to (u32_t loader_id, tc_chunk_location_s location);
|
||||
void tc_worldupdate_place_block (tc_block_location_s location, tc_block_s block);
|
||||
void tc_worldupdate_stop ();
|
||||
|
||||
const tc_world_s * tc_worldupdate_claim_world_promise (tc_promise_s promise);
|
||||
const tc_chunkloader_s * tc_worldupdate_claim_chunkloader_promise (tc_promise_s promise);
|
||||
const tc_chunklist_s * tc_worldupdate_claim_chunks_promise (tc_promise_s promise);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#include <world.h>
|
||||
#include <world/world.h>
|
||||
#include <state.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -48,6 +48,9 @@ tc_chunkloader_s tc_create_spawn_loader(tc_world_s *world)
|
|||
|
||||
tc_chunkloader_s loader = tc_create_chunkloader(loader_location);
|
||||
loader.is_rendered = TRUE;
|
||||
loader.extent.x = 9.0f;
|
||||
loader.extent.z = 9.0f;
|
||||
loader.extent.y = 3.0f;
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
@ -59,6 +62,7 @@ tc_world_s * tc_new_world(tc_worldgen_s *generator)
|
|||
world->before_chunk_generate = tc_new_hooklist(16);
|
||||
world->after_chunk_generate = tc_new_hooklist(16);
|
||||
world->on_chunk_delete = tc_new_hooklist(16);
|
||||
world->on_chunk_unload = tc_new_hooklist(16);
|
||||
world->on_chunk_update = tc_new_hooklist(16);
|
||||
world->worldgen = &tc_default_terrain_generator_g;
|
||||
world->num_loaders = 1;
|
|
@ -8,9 +8,9 @@
|
|||
#include <hook.h>
|
||||
#include <physics/simulation.h>
|
||||
#include <utility/math.h>
|
||||
#include <entity.h>
|
||||
#include <chunk.h>
|
||||
#include <chunk_pool.h>
|
||||
#include <entity/entity.h>
|
||||
#include <world/chunk.h>
|
||||
#include <world/chunk_pool.h>
|
||||
|
||||
|
||||
#define UPDATE_DISTANCE 2
|
||||
|
@ -52,8 +52,9 @@ struct tc_world
|
|||
tc_hooklist_s on_chunk_create;
|
||||
tc_hooklist_s before_chunk_generate;
|
||||
tc_hooklist_s after_chunk_generate;
|
||||
tc_hooklist_s on_chunk_delete;
|
||||
tc_hooklist_s on_chunk_update;
|
||||
tc_hooklist_s on_chunk_unload;
|
||||
tc_hooklist_s on_chunk_delete;
|
||||
};
|
||||
|
||||
extern tc_worldgen_s tc_default_terrain_generator_g;
|
|
@ -1,9 +1,11 @@
|
|||
#include <world.h>
|
||||
#include <world/world.h>
|
||||
|
||||
#include <stddef.h> // For NULL
|
||||
#include <stdio.h>
|
||||
|
||||
void tc_initialize_chunk_physics(tc_entity_s *chunk_entity, void *userdata)
|
||||
{
|
||||
|
||||
tc_chunk_s *chunk = chunk_entity->specific;
|
||||
tc_world_s *world = chunk->location.world;
|
||||
tc_physics_simulation_s *simulation = world->physics;
|
||||
|
@ -41,10 +43,19 @@ void tc_initialize_chunk_physics(tc_entity_s *chunk_entity, void *userdata)
|
|||
tc_set_pointer_for_entity(chunk_entity, "physics_body", chunk_body);
|
||||
}
|
||||
|
||||
void tc_free_chunk_physics(tc_entity_s *chunk_entity, void *userdata)
|
||||
{
|
||||
tc_physics_entity_s *body =
|
||||
tc_get_pointer_from_entity(chunk_entity, "physics_body");
|
||||
|
||||
tc_remove_physics_entity(body);
|
||||
}
|
||||
|
||||
void tc_create_world_physics(tc_world_s *world, void *userdata)
|
||||
{
|
||||
world->physics = tc_new_physics_simulation();
|
||||
tc_add_to_hooklist(&world->on_chunk_create, (tc_fn_hook) tc_initialize_chunk_physics, NULL);
|
||||
tc_add_to_hooklist(&world->on_chunk_update, (tc_fn_hook) tc_initialize_chunk_physics, NULL);
|
||||
// tc_add_to_hooklist(&world->on_chunk_update, (tc_fn_hook) tc_initialize_chunk_physics, NULL);
|
||||
tc_add_to_hooklist(&world->on_chunk_delete, (tc_fn_hook) tc_free_chunk_physics, NULL);
|
||||
}
|
||||
|
Loading…
Reference in New Issue