#include #include #include "tileset.h" #include "../memory/memory.h" BzTileset BZ_TILESET_INVALID = {.isValid = false}; BzTileShape bzCuteObjectToTileShape(cute_tiled_object_t *object) { BzTileShape shape = {BZ_TILE_SHAPE_NONE}; if (object->ellipse) shape.type = BZ_TILE_SHAPE_ELLIPSE; else if (object->point) shape.type = BZ_TILE_SHAPE_POINT; else if (!object->vertices) shape.type = BZ_TILE_SHAPE_RECT; else return shape; shape.x = object->x; shape.y = object->y; shape.sizeX = object->width; shape.sizeY = object->height; if (shape.type == BZ_TILE_SHAPE_ELLIPSE) { // Adjust to use radius and position to be center shape.sizeX *= 0.5f; shape.sizeY *= 0.5f; shape.x += shape.sizeX; shape.y += shape.sizeY; } return shape; } BzTileset bzTilesetCreate(const BzTilesetDesc *desc) { BzTileset tileset = {}; cute_tiled_tileset_t *cuteTileset = cute_tiled_load_external_tileset(desc->path, NULL); tileset.tiles = LoadTexture(desc->texturePath); tileset.startID = cuteTileset->firstgid; tileset.tileWidth = cuteTileset->tilewidth; tileset.tileHeight = cuteTileset->tileheight; tileset.offsetX = cuteTileset->tileoffset_x; tileset.offsetY = cuteTileset->tileoffset_y; tileset.width = tileset.tiles.width / tileset.tileWidth; tileset.height = tileset.tiles.height / tileset.tileHeight; tileset.tileCount = tileset.width * tileset.height; tileset.tileColliders = bzAlloc(tileset.tileCount * sizeof(*tileset.tileColliders)); for (i32 i = 0; i < tileset.tileCount; i++) { tileset.tileColliders[i] = (BzTileShape) {BZ_TILE_SHAPE_NONE}; } cute_tiled_tile_descriptor_t *cuteTile = cuteTileset->tiles; for (; cuteTile; cuteTile = cuteTile->next) { if (!cuteTile->objectgroup) continue; cute_tiled_object_t *cuteObject = cuteTile->objectgroup->objects; // NOTE: Only supporting single collider (integer values) if (cuteObject) { BzTileShape collider = bzCuteObjectToTileShape(cuteObject); tileset.tileColliders[cuteTile->tile_index] = collider; } } if (tileset.tiles.width != cuteTileset->imagewidth || tileset.tiles.height != cuteTileset->imageheight) { cute_tiled_free_external_tileset(cuteTileset); bzTilesetDestroy(&tileset); return BZ_TILESET_INVALID; } cute_tiled_free_external_tileset(cuteTileset); tileset.isValid = true; return tileset; } BzTile bzTilesetGetTile(BzTileset *tileset, BzTile tile) { if (tile == 0) return -1; tile = tile - tileset->startID; BZ_ASSERT(tile >= 0 && tile < tileset->tileCount); return tile; } Rectangle bzTilesetGetTileRegion(BzTileset *tileset, BzTile tileID) { tileID = tileID - tileset->startID; if (tileID < 0 || tileID >= tileset->tileCount) { return (Rectangle){}; } int posX = tileID % tileset->width; int posY = tileID / tileset->width; return (Rectangle) {posX * tileset->tileWidth, posY * tileset->tileHeight, tileset->tileWidth, tileset->tileHeight}; } BzTileShape bzTilesetGetTileCollider(BzTileset *tileset, BzTile tileID) { tileID = tileID - tileset->startID; if (tileID < 0 || tileID >= tileset->tileCount) { return (BzTileShape) {.type = BZ_TILE_SHAPE_NONE}; } return tileset->tileColliders[tileID]; } void bzTilesetDestroy(BzTileset *tileset) { UnloadTexture(tileset->tiles); bzFree(tileset->tileColliders); *tileset = BZ_TILESET_INVALID; }