Proper layer rendering

This commit is contained in:
2023-11-08 08:37:09 +01:00
parent 120cb7503b
commit ca1cd4b1f9
8 changed files with 218 additions and 89 deletions

View File

@@ -24,7 +24,6 @@ set(BreezeSources
breeze/utils/tokenizer.c
breeze/world/layer.c
breeze/world/map.c
breeze/world/tileset.c
)
@@ -37,7 +36,6 @@ set(BreezeHeaders
breeze/utils/tokenizer.h
breeze/world/layer.h
breeze/world/map.h
breeze/world/tileset.h

View File

@@ -8,7 +8,6 @@
#include "breeze/utils/tokenizer.h"
#include "breeze/world/layer.h"
#include "breeze/world/map.h"
#include "breeze/world/tileset.h"

View File

@@ -1 +0,0 @@
#include "layer.h"

View File

@@ -1,4 +0,0 @@
#ifndef BREEZE_LAYER_H
#define BREEZE_LAYER_H
#endif //BREEZE_LAYER_H

View File

@@ -1 +1,144 @@
#include "map.h"
#include "../core/memory.h"
#include "../math/vec2i.h"
#include <cute_tiled.h>
BzTileMap BZ_TILEMAP_INVALID = {.isValid = false};
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc) {
BzTileMap map = {};
i32 tilesetCount = desc->tilesetCount;
if (tilesetCount == 0) {
// Auto detect tileset count.
for (i32 i = 0; i < BZ_MAX_MAP_TILESETS; i++) {
if (!desc->tilesets[i].isValid)
break;
tilesetCount++;
}
}
map.tilesetCount = tilesetCount;
for (i32 i = 0; i < map.tilesetCount; i++) {
map.tilesets[i] = desc->tilesets[i];
}
cute_tiled_map_t *cuteMap = cute_tiled_load_map_from_file(desc->path, NULL);
map.backgroundColor = GetColor(cuteMap->backgroundcolor);
map.width = cuteMap->width;
map.height = cuteMap->height;
map.tileWidth = cuteMap->tilewidth;
map.tileHeight = cuteMap->tileheight;
cute_tiled_layer_t *cuteLayer = cuteMap->layers;
while (cuteLayer) {
BZ_ASSERT(map.layerCount < BZ_MAX_MAP_LAYERS);
BzTileLayer *layer = map.layers + map.layerCount;
layer->id = cuteLayer->id;
layer->dataCount = cuteLayer->data_count;
layer->data = NULL;
if (layer->dataCount > 0) {
layer->data = bzAlloc(layer->dataCount * sizeof(*layer->data));
layer->minData = layer->maxData = (i16) cuteLayer->data[0];
for (i32 i = 0; i < layer->dataCount; i++) {
layer->data[i] = (i16) cuteLayer->data[i];
if (layer->data[i] < layer->minData)
layer->minData = layer->data[i];
else if (layer->data[i] > layer->maxData)
layer->maxData = layer->data[i];
}
}
layer->width = cuteLayer->width;
layer->height = cuteLayer->height;
layer->offsetX = cuteLayer->offsetx;
layer->offsetY = cuteLayer->offsety;
layer->opacity = cuteLayer->opacity;
map.layerCount++;
cuteLayer = cuteLayer->next;
}
cute_tiled_tileset_t *cuteTileset = cuteMap->tilesets;
tilesetCount = 0;
while ((cuteTileset = cuteTileset->next)) tilesetCount++;
BZ_ASSERT(tilesetCount == map.tilesetCount);
cuteTileset = cuteMap->tilesets;
for (i32 i = 0; i < map.tilesetCount; i++) {
BzTileset *tileset = map.tilesets + i;
tileset->startID = cuteTileset->firstgid;
cuteTileset = cuteTileset->next;
}
// Assign tilesets to layers
for (i32 i = 0; i < map.layerCount; i++) {
BzTileLayer *layer = map.layers + i;
layer->tilesetIdx = -1;
for (i32 j = map.tilesetCount - 1; j >= 0; j--) {
BzTileset *tileset = map.tilesets + j;
if (tileset->startID >= layer->minData &&
tileset->startID <= layer->maxData) {
layer->tilesetIdx = j;
break;
}
}
}
cute_tiled_free_map(cuteMap);
map.isValid = true;
return map;
}
static void drawLayer(BzTileLayer *layer, BzTileset *tileset) {
if (!tileset) return;
if (layer->minData == layer->maxData) return;
Vector2 drawPos = {layer->offsetX, layer->offsetY};
for (i32 y = 0; y < layer->height; y++) {
for (i32 x = 0; x < layer->width; x++) {
i16 tile = bzTileLayerGetTile(layer, x, y);
if (tile - tileset->startID != -1) {
Rectangle rec = bzTilesetGetTileRegion(tileset, tile);
DrawTextureRec(tileset->tiles, rec, drawPos, WHITE);
}
drawPos.x += (float) tileset->tileWidth;
}
drawPos.x = layer->offsetX;
drawPos.y += (float) tileset->tileHeight;
}
}
void bzTileMapDraw(BzTileMap *map) {
for (i32 i = 0; i < map->layerCount; i++) {
BzTileLayer *layer = map->layers + i;
BzTileset *tileset = NULL;
if (layer->tilesetIdx != -1) {
tileset = map->tilesets + layer->tilesetIdx;
}
drawLayer(map->layers + i, tileset);
}
}
void bzTileMapDestroy(BzTileMap *tilemap) {
for (i32 i = 0; i < tilemap->layerCount; i++) {
BzTileLayer *layer = tilemap->layers + i;
bzFree(layer->data);
layer->data = NULL;
layer->dataCount = 0;
}
*tilemap = BZ_TILEMAP_INVALID;
}
int16_t bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y) {
return layer->data[layer->width * y + x];
}

View File

@@ -1,4 +1,62 @@
#ifndef BREEZE_MAP_H
#define BREEZE_MAP_H
#include "tileset.h"
#define BZ_MAX_MAP_LAYERS 16
#define BZ_MAX_MAP_TILESETS 8
typedef struct BzTileLayer {
i32 id;
int16_t *data;
i32 dataCount;
i16 minData;
i16 maxData;
i32 width;
i32 height;
f32 offsetX;
f32 offsetY;
f32 opacity;
i32 tilesetIdx;
} BzTileLayer;
typedef struct BzTileMapDesc {
const char *path;
BzTileset tilesets[BZ_MAX_MAP_TILESETS];
i32 tilesetCount;
} BzTileMapDesc;
typedef struct BzTileMap {
Color backgroundColor;
i32 width;
i32 height;
i32 tileWidth;
i32 tileHeight;
BzTileLayer layers[BZ_MAX_MAP_LAYERS];
i32 layerCount;
BzTileset tilesets[BZ_MAX_MAP_TILESETS];
i32 tilesetCount;
bool isValid;
} BzTileMap;
extern BzTileMap BZ_TILEMAP_INVALID;
int16_t bzTileLayerGetTile(BzTileLayer *layer, i32 x, i32 y);
BzTileMap bzTileMapCreate(const BzTileMapDesc *desc);
void bzTileMapDraw(BzTileMap *map);
void bzTileMapDestroy(BzTileMap *tilemap);
#endif //BREEZE_MAP_H

View File

@@ -1,6 +1,8 @@
#ifndef BREEZE_TILESET_H
#define BREEZE_TILESET_H
#include "../defines.h"
#include <raylib.h>
typedef struct BzTilesetDesc {
@@ -10,13 +12,13 @@ typedef struct BzTilesetDesc {
typedef struct BzTileset {
Texture2D tiles;
int startID;
int tileWidth;
int tileHeight;
int width;
int height;
int offsetX;
int offsetY;
i32 startID;
i32 tileWidth;
i32 tileHeight;
i32 width;
i32 height;
i32 offsetX;
i32 offsetY;
bool isValid;
} BzTileset;