From 28d378a9cf82f7f57067c99c24c85c8b0195354d Mon Sep 17 00:00:00 2001 From: xtreme8000 Date: Thu, 15 Oct 2020 12:46:56 +0200 Subject: [PATCH] Refactor damaged voxel code * now unlimited number of damaged voxels possible --- src/map.c | 90 +++++++++++++++++++++++++---------------------------- src/utils.c | 45 +++++++++++++++++++++++++++ src/utils.h | 1 + 3 files changed, 88 insertions(+), 48 deletions(-) diff --git a/src/map.c b/src/map.c index 8ece8bc..ff0b238 100644 --- a/src/map.c +++ b/src/map.c @@ -53,12 +53,11 @@ float fog_color[4] = {0.5F, 0.9098F, 1.0F, 1.0F}; float map_sun[4]; struct damaged_voxel { - uint32_t x, y, z; int damage; - int used; float timer; -} map_damaged_voxels[8]; +}; +HashTable map_damaged_voxels; struct tesselator map_damaged_tesselator; int map_object_visible(float x, float y, float z) { @@ -66,40 +65,53 @@ int map_object_visible(float x, float y, float z) { } int map_damage(int x, int y, int z, int damage) { - struct damaged_voxel* oldest = map_damaged_voxels; - - for(int k = 0; k < 8; k++) { - struct damaged_voxel* voxel = map_damaged_voxels + k; + uint32_t key = pos_key(x, y, z); + struct damaged_voxel* voxel = ht_lookup(&map_damaged_voxels, &key); - if(voxel->used && voxel->x == x && voxel->y == y && voxel->z == z) { - voxel->damage = min(damage + voxel->damage, 100); - voxel->timer = window_time(); + if(voxel) { + voxel->damage = min(damage + voxel->damage, 100); + voxel->timer = window_time(); - return voxel->damage; - } + return voxel->damage; + } else { + ht_insert(&map_damaged_voxels, &key, + &(struct damaged_voxel) { + .damage = damage, + .timer = window_time(), + }); - if((voxel->used && voxel->timer < oldest->timer) || !voxel->used) - oldest = voxel; + return damage; } - - oldest->used = 1; - oldest->x = x; - oldest->y = y; - oldest->z = z; - oldest->damage = damage; - oldest->timer = window_time(); - return damage; } int map_damage_get(int x, int y, int z) { - for(int k = 0; k < 8; k++) { - struct damaged_voxel* voxel = map_damaged_voxels + k; + uint32_t key = pos_key(x, y, z); + struct damaged_voxel* voxel = ht_lookup(&map_damaged_voxels, &key); - if(voxel->used && voxel->x == x && voxel->y == y && voxel->z == z) - return voxel->damage; - } + return voxel ? voxel->damage : 0; +} + +static bool damaged_voxel_update(void* key, void* value, void* user) { + uint32_t pos = *(uint32_t*)key; + struct damaged_voxel* voxel = (struct damaged_voxel*)value; + struct tesselator* tess = (struct tesselator*)user; + int x = pos_keyx(pos); + int y = pos_keyy(pos); + int z = pos_keyz(pos); - return 0; + if(window_time() - voxel->timer > 10.0F || map_isair(x, y, z)) + return true; + + tesselator_set_color(tess, rgba(0, 0, 0, voxel->damage * 1.9125F)); + + tesselator_addi_cube_face(tess, CUBE_FACE_Z_N, x, y, z); + tesselator_addi_cube_face(tess, CUBE_FACE_Z_P, x, y, z); + tesselator_addi_cube_face(tess, CUBE_FACE_X_N, x, y, z); + tesselator_addi_cube_face(tess, CUBE_FACE_X_P, x, y, z); + tesselator_addi_cube_face(tess, CUBE_FACE_Y_P, x, y, z); + tesselator_addi_cube_face(tess, CUBE_FACE_Y_N, x, y, z); + + return false; } void map_damaged_voxels_render() { @@ -113,24 +125,7 @@ void map_damaged_voxels_render() { tesselator_clear(&map_damaged_tesselator); - for(int k = 0; k < 8; k++) { - struct damaged_voxel* voxel = map_damaged_voxels + k; - - if(voxel->used) { - if(window_time() - voxel->timer > 10.0F || map_isair(voxel->x, voxel->y, voxel->z)) { - voxel->used = 0; - } else { - tesselator_set_color(&map_damaged_tesselator, rgba(0, 0, 0, voxel->damage * 1.9125F)); - - tesselator_addi_cube_face(&map_damaged_tesselator, CUBE_FACE_Z_N, voxel->x, voxel->y, voxel->z); - tesselator_addi_cube_face(&map_damaged_tesselator, CUBE_FACE_Z_P, voxel->x, voxel->y, voxel->z); - tesselator_addi_cube_face(&map_damaged_tesselator, CUBE_FACE_X_N, voxel->x, voxel->y, voxel->z); - tesselator_addi_cube_face(&map_damaged_tesselator, CUBE_FACE_X_P, voxel->x, voxel->y, voxel->z); - tesselator_addi_cube_face(&map_damaged_tesselator, CUBE_FACE_Y_P, voxel->x, voxel->y, voxel->z); - tesselator_addi_cube_face(&map_damaged_tesselator, CUBE_FACE_Y_N, voxel->x, voxel->y, voxel->z); - } - } - } + ht_iterate_remove(&map_damaged_voxels, &map_damaged_tesselator, damaged_voxel_update); tesselator_draw(&map_damaged_tesselator, 1); @@ -492,8 +487,7 @@ void map_init() { tesselator_create(&map_damaged_tesselator, VERTEX_INT, 0); pthread_rwlock_init(&map_lock, NULL); - for(int k = 0; k < 8; k++) - map_damaged_voxels[k].used = 0; + ht_setup(&map_damaged_voxels, sizeof(uint32_t), sizeof(struct damaged_voxel), 16); for(int k = 0; k < 32; k++) map_collapsing_structures[k].used = 0; diff --git a/src/utils.c b/src/utils.c index 5450e81..78bf2a6 100644 --- a/src/utils.c +++ b/src/utils.c @@ -17,6 +17,8 @@ along with BetterSpades. If not, see . */ +#include + #include "utils.h" static int base64_map(char c) { @@ -35,6 +37,8 @@ static int base64_map(char c) { // works in place int base64_decode(char* data, int len) { + assert(data && len > 0); + int buffer = 0; int buffer_len = 0; int data_index = 0; @@ -54,10 +58,14 @@ int base64_decode(char* data, int len) { } int int_cmp(void* first_key, void* second_key, size_t key_size) { + assert(first_key && second_key); + return (*(uint32_t*)first_key) != (*(uint32_t*)second_key); } size_t int_hash(void* raw_key, size_t key_size) { + assert(raw_key); + uint32_t x = *(uint32_t*)raw_key; x = ((x >> 16) ^ x) * 0x45d9f3b; x = ((x >> 16) ^ x) * 0x45d9f3b; @@ -65,7 +73,44 @@ size_t int_hash(void* raw_key, size_t key_size) { return x; } +void ht_iterate_remove(HashTable* ht, void* user, bool (*callback)(void* key, void* value, void* user)) { + assert(ht && callback); + + bool removed = false; + + for(size_t chain = 0; chain < ht->capacity; chain++) { + HTNode* node = ht->nodes[chain]; + HTNode* prev = NULL; + + while(node) { + if(callback(node->key, node->value, user)) { + if(prev) { + prev->next = node->next; + } else { + ht->nodes[chain] = node->next; + } + + HTNode* del = node; + node = node->next; + + _ht_destroy_node(del); + + ht->size--; + removed = true; + } else { + prev = node; + node = node->next; + } + } + } + + if(removed && _ht_should_shrink(ht)) + _ht_adjust_capacity(ht); +} + bool ht_iterate(HashTable* ht, void* user, bool (*callback)(void* key, void* value, void* user)) { + assert(ht && callback); + for(size_t chain = 0; chain < ht->capacity; chain++) { HTNode* node = ht->nodes[chain]; diff --git a/src/utils.h b/src/utils.h index a7b31f8..02ab750 100644 --- a/src/utils.h +++ b/src/utils.h @@ -29,6 +29,7 @@ int base64_decode(char* data, int len); int int_cmp(void* first_key, void* second_key, size_t key_size); size_t int_hash(void* raw_key, size_t key_size); +void ht_iterate_remove(HashTable* ht, void* user, bool (*callback)(void* key, void* value, void* user)); bool ht_iterate(HashTable* ht, void* user, bool (*callback)(void* key, void* value, void* user)); #endif