HandmadeHero/project/engine/tile_map.cpp
2023-10-11 23:58:04 -04:00

132 lines
3.7 KiB
C++

#if INTELLISENSE_DIRECTIVES
#include "tile_map.hpp"
#endif
NS_ENGINE_BEGIN
inline
void cannonicalize_coord( TileMap* tile_map, u32* tile_coord, f32* pos_coord )
{
assert( tile_map != nullptr );
assert( tile_coord != nullptr );
f32 tile_size = scast(f32, tile_map->tile_size_in_meters);
// Note(Ed) : World is assumed to be a "torodial topology"
s32 offset = round( (* pos_coord) / tile_size );
u32 new_tile_coord = (* tile_coord) + offset;
f32 new_pos_coord = (* pos_coord) - scast(f32, offset) * tile_size;
assert( new_pos_coord >= -tile_size * 0.5f );
assert( new_pos_coord <= tile_size * 0.5f );
(* tile_coord) = new_tile_coord;
(* pos_coord) = new_pos_coord;
}
inline
TileMapPosition recannonicalize_position( TileMap* tile_map, TileMapPosition pos )
{
assert( tile_map != nullptr );
TileMapPosition result = pos;
cannonicalize_coord( tile_map, & result.tile_x, & result.x );
cannonicalize_coord( tile_map, & result.tile_y, & result.y );
return result;
}
inline
u32 TileChunk_get_tile_value( TileChunk* tile_chunk, TileMap* tile_map, u32 x, u32 y )
{
assert( tile_map != nullptr );
assert( tile_chunk != nullptr );
assert( x < tile_map->chunk_dimension );
assert( y < tile_map->chunk_dimension );
u32 value = tile_chunk->tiles[ (y * tile_map->chunk_dimension) + x ];
return value;
}
inline
void TileChunk_set_tile_value( TileChunk* tile_chunk, TileMap* tile_map, u32 x, u32 y , u32 value)
{
assert( tile_map != nullptr );
assert( tile_chunk != nullptr );
assert( x < tile_map->chunk_dimension );
assert( y < tile_map->chunk_dimension );
tile_chunk->tiles[ (y * tile_map->chunk_dimension) + x ] = value;
}
inline
TileChunk* TileMap_get_chunk( TileMap* tile_map, s32 tile_chunk_x, s32 tile_chunk_y )
{
TileChunk* chunk = nullptr;
if ( tile_chunk_x >= 0 && tile_chunk_x < scast(s32, tile_map->tile_chunks_num_x)
&& tile_chunk_y >= 0 && tile_chunk_y < scast(s32, tile_map->tile_chunks_num_y) )
{
chunk = & tile_map->chunks[ tile_chunk_y * tile_map->tile_chunks_num_x + tile_chunk_x ];
}
return chunk;
}
inline
TileChunkPosition get_tile_chunk_position_for( TileMap* tile_map, u32 abs_tile_x, u32 abs_tile_y )
{
assert( tile_map != nullptr );
TileChunkPosition chunk_pos {};
chunk_pos.tile_chunk_x = abs_tile_x >> tile_map->chunk_shift;
chunk_pos.tile_chunk_y = abs_tile_y >> tile_map->chunk_shift;
chunk_pos.tile_x = abs_tile_x & tile_map->chunk_mask;
chunk_pos.tile_y = abs_tile_y & tile_map->chunk_mask;
return chunk_pos;
}
u32 TileMap_get_tile_value( TileMap* tile_map, u32 tile_x, u32 tile_y )
{
assert( tile_map != nullptr );
u32 value = 0;
TileChunkPosition chunk_pos = get_tile_chunk_position_for( tile_map, tile_x, tile_y );
TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y );
if ( chunk )
value = TileChunk_get_tile_value( chunk, tile_map, chunk_pos.tile_x, chunk_pos.tile_y );
return value;
}
internal
b32 TileMap_is_point_empty( TileMap* tile_map, TileMapPosition position )
{
assert( tile_map != nullptr );
u32 chunk_value = TileMap_get_tile_value( tile_map, position.tile_x, position.tile_y );
b32 is_empty = chunk_value == 0;
return is_empty;
}
internal
void TileMap_set_tile_value( MemoryArena* arena, TileMap* tile_map, u32 abs_tile_x, u32 abs_tile_y, u32 value )
{
TileChunkPosition chunk_pos = get_tile_chunk_position_for( tile_map, abs_tile_x, abs_tile_y );
TileChunk* chunk = TileMap_get_chunk( tile_map, chunk_pos.tile_chunk_x, chunk_pos.tile_chunk_y );
#if 0
if ( chunk == nullptr )
{
}
#else
assert( chunk != nullptr );
#endif
TileChunk_set_tile_value( chunk, tile_map, chunk_pos.tile_x, chunk_pos.tile_y, value );
}
NS_ENGINE_END