diff --git a/src/sim_step.c b/src/sim_step.c index 1fb53d5f..fdc3d31c 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -374,16 +374,29 @@ INTERNAL void test_spawn_tile(struct sim_snapshot *world, struct v2 world_pos) -INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort, arg_a, arg_b, udata) +INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort_x, arg_a, arg_b, udata) { (UNUSED)udata; struct sim_ent *a = *(struct sim_ent **)arg_a; struct sim_ent *b = *(struct sim_ent **)arg_b; - struct v2i32 index_a = a->tile_chunk_index; - struct v2i32 index_b = b->tile_chunk_index; + i32 a_x = a->tile_chunk_index.x; + i32 b_x = b->tile_chunk_index.x; i32 res = 0; - res = 2 * ((index_a.y < index_b.y) - (index_a.y > index_b.y)) + ((index_a.x < index_b.x) - (index_a.x > index_b.x)); + res = (a_x < b_x) - (a_x > b_x); + return res; +} + +INTERNAL SORT_COMPARE_FUNC_DEF(tile_chunk_sort_y, arg_a, arg_b, udata) +{ + (UNUSED)udata; + struct sim_ent *a = *(struct sim_ent **)arg_a; + struct sim_ent *b = *(struct sim_ent **)arg_b; + i32 a_y = a->tile_chunk_index.y; + i32 b_y = b->tile_chunk_index.y; + + i32 res = 0; + res = (a_y < b_y) - (a_y > b_y); return res; } @@ -403,10 +416,10 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) } /* Sort tile chunks */ - /* NOTE: We sort tile chunks from top-left to bottom-right so that cross + /* NOTE: We sort tile chunks from left-right and top-bottom so that cross * chunk tile checks only have to happen in one direction (because we * know the left & top chunks have already been processed) */ - struct sim_ent **sorted_tile_chunks = arena_dry_push(scratch.arena, struct sim_ent *); + struct sim_ent **x_sorted_tile_chunks = arena_dry_push(scratch.arena, struct sim_ent *); u64 sorted_tile_chunks_count = 0; for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; @@ -416,7 +429,11 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) ++sorted_tile_chunks_count; } } - merge_sort(sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*sorted_tile_chunks), tile_chunk_sort, NULL); + struct sim_ent **y_sorted_tile_chunks = arena_push_array_no_zero(scratch.arena, struct sim_ent *, sorted_tile_chunks_count); + MEMCPY(y_sorted_tile_chunks, x_sorted_tile_chunks, sizeof(*x_sorted_tile_chunks) * sorted_tile_chunks_count); + + merge_sort(x_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*x_sorted_tile_chunks), tile_chunk_sort_x, NULL); + merge_sort(y_sorted_tile_chunks, sorted_tile_chunks_count, sizeof(*y_sorted_tile_chunks), tile_chunk_sort_y, NULL); struct wall_node { struct v2i32 start; @@ -433,150 +450,150 @@ INTERNAL void test_generate_walls(struct sim_snapshot *world) /* Generate horizontal wall nodes */ for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) { - struct sim_ent *chunk = sorted_tile_chunks[sorted_index]; + struct sim_ent *chunk = x_sorted_tile_chunks[sorted_index]; struct v2i32 chunk_index = chunk->tile_chunk_index; - /* Generate horizontal wall nodes */ - { - struct sim_ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y - 1)); - struct sim_ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y + 1)); - /* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */ - i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + !bottom_chunk->valid; - i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + 1; - for (i32 tile_y = 0; tile_y < y_iterations; ++tile_y) { - i32 wall_start = -1; - i32 wall_end = -1; - for (i32 tile_x = 0; tile_x < x_iterations; ++tile_x) { - enum sim_tile_kind tile = SIM_TILE_KIND_NONE; - if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) { - tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y)); - } - b32 should_have_top_wall = false; - if (tile_x < SIM_TILES_PER_CHUNK_SQRT) { - enum sim_tile_kind top_tile = SIM_TILE_KIND_NONE; - if (tile_y == 0) { - if (top_chunk->valid) { - struct v2i32 top_tile_local_index = V2I32(tile_x, SIM_TILES_PER_CHUNK_SQRT - 1); - top_tile = sim_get_chunk_tile(top_chunk, top_tile_local_index); - } - } else { - top_tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y - 1)); + struct sim_ent *top_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y - 1)); + struct sim_ent *bottom_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x, chunk_index.y + 1)); + /* If there's no chunk below this one, then do an extra iteration (since walls are created at the top of each tile) */ + i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + !bottom_chunk->valid; + i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + 1; + for (i32 tile_y = 0; tile_y < y_iterations; ++tile_y) { + i32 wall_start = -1; + i32 wall_end = -1; + for (i32 tile_x = 0; tile_x < x_iterations; ++tile_x) { + enum sim_tile_kind tile = SIM_TILE_KIND_NONE; + if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) { + tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y)); + } + b32 should_have_top_wall = false; + if (tile_x < SIM_TILES_PER_CHUNK_SQRT) { + enum sim_tile_kind top_tile = SIM_TILE_KIND_NONE; + if (tile_y == 0) { + if (top_chunk->valid) { + struct v2i32 top_tile_local_index = V2I32(tile_x, SIM_TILES_PER_CHUNK_SQRT - 1); + top_tile = sim_get_chunk_tile(top_chunk, top_tile_local_index); } - if (tile == SIM_TILE_KIND_WALL) { - /* Process wall tile */ - should_have_top_wall = top_tile != SIM_TILE_KIND_WALL; - } else { - /* Process non-wall tile */ - should_have_top_wall = top_tile == SIM_TILE_KIND_WALL; + } else { + top_tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y - 1)); + } + if (tile == SIM_TILE_KIND_WALL) { + /* Process wall tile */ + should_have_top_wall = top_tile != SIM_TILE_KIND_WALL; + } else { + /* Process non-wall tile */ + should_have_top_wall = top_tile == SIM_TILE_KIND_WALL; + } + } + if (should_have_top_wall) { + if (wall_start < 0) { + /* Start wall */ + wall_start = tile_x; + } + /* Extend wall */ + wall_end = tile_x + 1; + } else if (wall_end >= 0) { + /* Stop wall */ + struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_start, tile_y)); + struct v2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_end, tile_y)); + struct wall_node *node = NULL; + if (wall_start == 0) { + u64 start_hash = rand_u64_from_seed(*(u64 *)&start); + struct dict_entry *entry = dict_get_entry(&horizontal_ends_dict, start_hash); + if (entry) { + /* Existing wall exists accross chunk boundary */ + node = (struct wall_node *)entry->value; + dict_remove_entry(&horizontal_ends_dict, entry); } } - if (should_have_top_wall) { - if (wall_start < 0) { - /* Start wall */ - wall_start = tile_x; - } - /* Extend wall */ - wall_end = tile_x + 1; - } else if (wall_end >= 0) { - /* Stop wall */ - struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_start, tile_y)); - struct v2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(wall_end, tile_y)); - struct wall_node *node = NULL; - if (wall_start == 0) { - u64 start_hash = rand_u64_from_seed(*(u64 *)&start); - struct dict_entry *entry = dict_get_entry(&horizontal_ends_dict, start_hash); - if (entry) { - /* Existing wall exists accross chunk boundary */ - node = (struct wall_node *)entry->value; - dict_remove_entry(&horizontal_ends_dict, entry); - } - } - if (!node) { - node = arena_push(scratch.arena, struct wall_node); - node->start = start; - node->next = first_wall; - first_wall = node; - } - node->end = end; - if (wall_end == SIM_TILES_PER_CHUNK_SQRT) { - u64 end_hash = rand_u64_from_seed(*(u64 *)&end); - dict_set(scratch.arena, &horizontal_ends_dict, end_hash, node); - } - wall_start = -1; - wall_end = -1; + if (!node) { + node = arena_push(scratch.arena, struct wall_node); + node->start = start; + node->next = first_wall; + first_wall = node; } + node->end = end; + if (wall_end == SIM_TILES_PER_CHUNK_SQRT) { + u64 end_hash = rand_u64_from_seed(*(u64 *)&end); + dict_set(scratch.arena, &horizontal_ends_dict, end_hash, node); + } + wall_start = -1; + wall_end = -1; } } } - /* Generate vertical wall nodes */ - { - struct sim_ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x - 1, chunk_index.y)); - struct sim_ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x + 1, chunk_index.y)); - /* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */ - i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + 1; - i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + !right_chunk->valid; - for (i32 tile_x = 0; tile_x < x_iterations; ++tile_x) { - i32 wall_start = -1; - i32 wall_end = -1; - for (i32 tile_y = 0; tile_y < y_iterations; ++tile_y) { - enum sim_tile_kind tile = SIM_TILE_KIND_NONE; - if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) { - tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y)); - } + } - b32 should_have_left_wall = false; - if (tile_y < SIM_TILES_PER_CHUNK_SQRT) { - enum sim_tile_kind left_tile = SIM_TILE_KIND_NONE; - if (tile_x == 0) { - if (left_chunk->valid) { - struct v2i32 left_tile_local_index = V2I32(SIM_TILES_PER_CHUNK_SQRT - 1, tile_y); - left_tile = sim_get_chunk_tile(left_chunk, left_tile_local_index); - } - } else { - left_tile = sim_get_chunk_tile(chunk, V2I32(tile_x - 1, tile_y)); + /* Generate vertical wall nodes */ + for (u64 sorted_index = 0; sorted_index < sorted_tile_chunks_count; ++sorted_index) { + struct sim_ent *chunk = y_sorted_tile_chunks[sorted_index]; + struct v2i32 chunk_index = chunk->tile_chunk_index; + struct sim_ent *left_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x - 1, chunk_index.y)); + struct sim_ent *right_chunk = sim_tile_chunk_from_chunk_index(world, V2I32(chunk_index.x + 1, chunk_index.y)); + /* If there's no chunk to the right of this one, then do an extra iteration (since walls are created on the left of each tile) */ + i32 y_iterations = SIM_TILES_PER_CHUNK_SQRT + 1; + i32 x_iterations = SIM_TILES_PER_CHUNK_SQRT + !right_chunk->valid; + for (i32 tile_x = 0; tile_x < x_iterations; ++tile_x) { + i32 wall_start = -1; + i32 wall_end = -1; + for (i32 tile_y = 0; tile_y < y_iterations; ++tile_y) { + enum sim_tile_kind tile = SIM_TILE_KIND_NONE; + if (tile_x < SIM_TILES_PER_CHUNK_SQRT && tile_y < SIM_TILES_PER_CHUNK_SQRT) { + tile = sim_get_chunk_tile(chunk, V2I32(tile_x, tile_y)); + } + + b32 should_have_left_wall = false; + if (tile_y < SIM_TILES_PER_CHUNK_SQRT) { + enum sim_tile_kind left_tile = SIM_TILE_KIND_NONE; + if (tile_x == 0) { + if (left_chunk->valid) { + struct v2i32 left_tile_local_index = V2I32(SIM_TILES_PER_CHUNK_SQRT - 1, tile_y); + left_tile = sim_get_chunk_tile(left_chunk, left_tile_local_index); } - if (tile == SIM_TILE_KIND_WALL) { - /* Process wall tile */ - should_have_left_wall = left_tile != SIM_TILE_KIND_WALL; - } else { - /* Process non-wall tile */ - should_have_left_wall = left_tile == SIM_TILE_KIND_WALL; + } else { + left_tile = sim_get_chunk_tile(chunk, V2I32(tile_x - 1, tile_y)); + } + if (tile == SIM_TILE_KIND_WALL) { + /* Process wall tile */ + should_have_left_wall = left_tile != SIM_TILE_KIND_WALL; + } else { + /* Process non-wall tile */ + should_have_left_wall = left_tile == SIM_TILE_KIND_WALL; + } + } + if (should_have_left_wall) { + if (wall_start < 0) { + /* Start wall */ + wall_start = tile_y; + } + /* Extend wall */ + wall_end = tile_y + 1; + } else if (wall_end >= 0) { + /* Stop wall */ + struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_start)); + struct v2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_end)); + struct wall_node *node = NULL; + if (wall_start == 0) { + u64 start_hash = rand_u64_from_seed(*(u64 *)&start); + struct dict_entry *entry = dict_get_entry(&vertical_ends_dict, start_hash); + if (entry) { + /* Existing wall exists accross chunk boundary */ + node = (struct wall_node *)entry->value; + dict_remove_entry(&vertical_ends_dict, entry); } } - if (should_have_left_wall) { - if (wall_start < 0) { - /* Start wall */ - wall_start = tile_y; - } - /* Extend wall */ - wall_end = tile_y + 1; - } else if (wall_end >= 0) { - /* Stop wall */ - struct v2i32 start = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_start)); - struct v2i32 end = sim_world_tile_index_from_local_tile_index(chunk_index, V2I32(tile_x, wall_end)); - struct wall_node *node = NULL; - if (wall_start == 0) { - u64 start_hash = rand_u64_from_seed(*(u64 *)&start); - struct dict_entry *entry = dict_get_entry(&vertical_ends_dict, start_hash); - if (entry) { - /* Existing wall exists accross chunk boundary */ - node = (struct wall_node *)entry->value; - dict_remove_entry(&vertical_ends_dict, entry); - } - } - if (!node) { - node = arena_push(scratch.arena, struct wall_node); - node->start = start; - node->next = first_wall; - first_wall = node; - } - node->end = end; - if (wall_end == SIM_TILES_PER_CHUNK_SQRT) { - u64 end_hash = rand_u64_from_seed(*(u64 *)&end); - dict_set(scratch.arena, &vertical_ends_dict, end_hash, node); - } - wall_start = -1; - wall_end = -1; + if (!node) { + node = arena_push(scratch.arena, struct wall_node); + node->start = start; + node->next = first_wall; + first_wall = node; } + node->end = end; + if (wall_end == SIM_TILES_PER_CHUNK_SQRT) { + u64 end_hash = rand_u64_from_seed(*(u64 *)&end); + dict_set(scratch.arena, &vertical_ends_dict, end_hash, node); + } + wall_start = -1; + wall_end = -1; } } } diff --git a/src/user.c b/src/user.c index bdc7c9e3..1464d67c 100644 --- a/src/user.c +++ b/src/user.c @@ -1861,9 +1861,6 @@ INTERNAL void user_update(void) draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Video memory usage: %F MiB"), FMT_FLOAT((f64)gstat_get(GSTAT_VRAM_USAGE) / 1024 / 1024))); pos.y += spacing; - - draw_text(G.ui_cmd_buffer, font, pos, string_format(temp.arena, LIT("Video memory budget: %F GiB"), FMT_FLOAT((f64)gstat_get(GSTAT_VRAM_BUDGET) / 1024 / 1024 / 1024))); - pos.y += spacing; pos.y += spacing; #if 0