#include "handmade_tile.h" #include static struct tile_chunk * get_tile_chunk(struct tile_map *tile_map, unsigned int tile_chunk_x, unsigned int tile_chunk_y, unsigned int tile_chunk_z) { struct tile_chunk *tile_chunk = NULL; if((tile_chunk_x >= 0) && (tile_chunk_x < tile_map->tile_chunk_count_x) && (tile_chunk_y >= 0) && (tile_chunk_y < tile_map->tile_chunk_count_y) && (tile_chunk_z >= 0) && (tile_chunk_z < tile_map->tile_chunk_count_z)) { tile_chunk = &tile_map->tile_chunks[(tile_chunk_z * tile_map->tile_chunk_count_y * tile_map->tile_chunk_count_x) + (tile_chunk_y*tile_map->tile_chunk_count_x) + tile_chunk_x]; } return tile_chunk; } static struct tile_chunk_position get_chunk_position_for(struct tile_map *tile_map, unsigned int abs_tile_x, unsigned int abs_tile_y, unsigned int abs_tile_z) { struct tile_chunk_position result; result.tile_chunk_x = abs_tile_x >> tile_map->chunk_shift; result.tile_chunk_y = abs_tile_y >> tile_map->chunk_shift; result.tile_chunk_z = abs_tile_z; result.rel_tile_x = abs_tile_x & tile_map->chunk_mask; result.rel_tile_y = abs_tile_y & tile_map->chunk_mask; return result; } static unsigned int get_tile_value_unchecked(struct tile_map *tile_map, struct tile_chunk *tile_chunk, unsigned int tile_x, unsigned int tile_y) { unsigned int tile_chunk_value; assert(tile_chunk); assert(tile_x < tile_map->chunk_dim); assert(tile_y < tile_map->chunk_dim); tile_chunk_value = tile_chunk->tiles[tile_y * tile_map->chunk_dim + tile_x]; return tile_chunk_value; } static unsigned int get_tile_chunk_value(struct tile_map *tile_map, struct tile_chunk *tile_chunk, unsigned int test_tile_x, unsigned int test_tile_y) { unsigned int tile_chunk_value = 0; if(tile_chunk && tile_chunk->tiles) { tile_chunk_value = get_tile_value_unchecked(tile_map, tile_chunk, test_tile_x, test_tile_y); } return tile_chunk_value; } static unsigned int get_tile_value(struct tile_map *tile_map, unsigned int abs_tile_x, unsigned int abs_tile_y, unsigned int abs_tile_z) { struct tile_chunk_position chunk_pos = get_chunk_position_for(tile_map, abs_tile_x, abs_tile_y, abs_tile_z); struct tile_chunk *tile_chunk = get_tile_chunk(tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y, chunk_pos.tile_chunk_z); unsigned int tile_chunk_value = get_tile_chunk_value(tile_map, tile_chunk, chunk_pos.rel_tile_x, chunk_pos.rel_tile_y); return tile_chunk_value; } static int is_tile_value_empty(unsigned int tile_value) { int empty = ((tile_value == 1) || (tile_value == 3) || (tile_value == 4)); return empty; } static unsigned int get_tile_value_by_pos(struct tile_map *tile_map, struct tile_map_position pos) { unsigned int tile_chunk_value = get_tile_value(tile_map, pos.abs_tile_x, pos.abs_tile_y, pos.abs_tile_z); return tile_chunk_value; } static void set_tile_value_unchecked(struct tile_map *tile_map, struct tile_chunk *tile_chunk, unsigned int tile_x, unsigned int tile_y, unsigned int tile_value) { assert(tile_chunk); assert(tile_x < tile_map->chunk_dim); assert(tile_y < tile_map->chunk_dim); tile_chunk->tiles[tile_y * tile_map->chunk_dim + tile_x] = tile_value; } static void set_tile_chunk_value(struct tile_map *tile_map, struct tile_chunk *tile_chunk, unsigned int test_tile_x, unsigned int test_tile_y, unsigned int tile_value) { if(tile_chunk && tile_chunk->tiles) { set_tile_value_unchecked(tile_map, tile_chunk, test_tile_x, test_tile_y, tile_value); } } static int is_tile_map_point_empty(struct tile_map *tile_map, struct tile_map_position pos) { unsigned int tile_chunk_value; int empty; tile_chunk_value = get_tile_value_by_pos(tile_map, pos); empty = is_tile_value_empty(tile_chunk_value); return empty; } static void set_tile_value(struct memory_arena *arena, struct tile_map *tile_map, unsigned int abs_tile_x, unsigned int abs_tile_y, unsigned int abs_tile_z, unsigned int tile_value) { struct tile_chunk_position chunk_pos; struct tile_chunk *tile_chunk; chunk_pos = get_chunk_position_for(tile_map, abs_tile_x, abs_tile_y, abs_tile_z); tile_chunk = get_tile_chunk(tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y, chunk_pos.tile_chunk_z); assert(tile_chunk); if(!tile_chunk->tiles) { unsigned int tile_count, tile_index; tile_count = tile_map->chunk_dim*tile_map->chunk_dim; tile_chunk->tiles = PUSH_ARRAY(arena, tile_count, unsigned int); for(tile_index = 0; tile_index < tile_count; tile_index++) { tile_chunk->tiles[tile_index] = 1; } } set_tile_chunk_value(tile_map, tile_chunk, chunk_pos.rel_tile_x, chunk_pos.rel_tile_y, tile_value); } /* TODO: Do these belong more in a "positioning" or "geometry" file? */ static void cannonicalize_coord(struct tile_map *tile_map, unsigned int *tile, float *tile_rel) { /* NOTE: The world is assumed to be toroidal topology. If you step off * one end, you come back on the other.*/ int offset = round_float_to_int(*tile_rel / tile_map->tile_side_in_meters); *tile += offset; *tile_rel -= (float)offset * tile_map->tile_side_in_meters; assert(*tile_rel >= -0.5f*tile_map->tile_side_in_meters); assert(*tile_rel <= 0.5f*tile_map->tile_side_in_meters); } static struct tile_map_position recannonicalize_position(struct tile_map *tile_map, struct tile_map_position pos) { struct tile_map_position result = pos; cannonicalize_coord(tile_map, &result.abs_tile_x, &result.offset.x); cannonicalize_coord(tile_map, &result.abs_tile_y, &result.offset.y); return result; } static int are_on_same_tile(struct tile_map_position *a, struct tile_map_position *b) { int result = ((a->abs_tile_x == b->abs_tile_x) && (a->abs_tile_y == b->abs_tile_y) && (a->abs_tile_z == b->abs_tile_z)); return result; } static struct tile_map_difference subtract_in_float(struct tile_map *tile_map, struct tile_map_position *a, struct tile_map_position *b) { struct tile_map_difference result; struct v2 d_tile_xy; float d_tile_z; d_tile_xy.x = (float)a->abs_tile_x - (float)b->abs_tile_x; d_tile_xy.y = (float)a->abs_tile_y - (float)b->abs_tile_y; d_tile_z = (float)a->abs_tile_z - (float)b->abs_tile_z; result.d_xy = V2Add(V2Multiply(tile_map->tile_side_in_meters, d_tile_xy), V2Subtract(a->offset, b->offset)); /* TODO: Incomplete . . . */ result.d_z = tile_map->tile_side_in_meters*d_tile_z; return result; } static struct tile_map_position centered_tile_point(unsigned int abs_tile_x, unsigned int abs_tile_y, unsigned int abs_tile_z) { struct tile_map_position result; memset(&result, 0, sizeof(result)); result.abs_tile_x = abs_tile_x; result.abs_tile_y = abs_tile_y; result.abs_tile_z = abs_tile_z; return result; }