From 12a53d83e062fc7ec5838c94d575b94a7310d6cd Mon Sep 17 00:00:00 2001 From: davidovski Date: Mon, 10 Jul 2023 01:46:56 +0100 Subject: add tile atlas to mapfile --- src/tiled.c | 6 +++--- src/tiledfile.c | 61 ++++++++++++++++++++++++++++++++++++++---------------- src/tiledfile.h | 2 +- tools/createmap.py | 36 +++++++++++++++++++++++++++----- 4 files changed, 78 insertions(+), 27 deletions(-) diff --git a/src/tiled.c b/src/tiled.c index 2cb1cb0..b679e3c 100644 --- a/src/tiled.c +++ b/src/tiled.c @@ -6,16 +6,16 @@ #define SCREEN_W 1280 #define SCREEN_H 720 -const int atlasSize[2] = {2, 2}; int main() { InitWindow(SCREEN_W, SCREEN_H, "tiled"); Shader shader = LoadShader(0, "tiled.glsl"); - Texture2D tilemap = loadTileMap("map.tiles"); + int atlasSize[2] = {0, 0}; + Texture2D tilemap, atlas; + loadTileMap("map.tiles", &tilemap, &atlas, atlasSize); - Texture atlas = LoadTexture("atlas.png"); RenderTexture2D target = LoadRenderTexture(SCREEN_W, SCREEN_H); float resolution[2] = {SCREEN_W, SCREEN_H}; diff --git a/src/tiledfile.c b/src/tiledfile.c index c1ba42e..0b37bae 100644 --- a/src/tiledfile.c +++ b/src/tiledfile.c @@ -5,8 +5,9 @@ const int i = 1; #define is_bigendian() ( (*(char*)&i) == 0 ) -Texture2D processTilemapTexture(int * tilelayout, int width, int height) { +void processTilemapTexture(Texture2D *loc, int * tilelayout, int width, int height) { Color *pixels = (Color*) malloc(width * height * sizeof(Color)); + printf("%d x %d\n", width, height); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { @@ -25,14 +26,32 @@ Texture2D processTilemapTexture(int * tilelayout, int width, int height) { .mipmaps = 1 }; - Texture2D checked = LoadTextureFromImage(checkedIm); + *loc = LoadTextureFromImage(checkedIm); UnloadImage(checkedIm); - return checked; } +void readrgba(Texture2D *loc, int width, int height, FILE *file) { + char *pixels = malloc(width*height*4); + printf("%d\n", width*height*4); + fread(pixels, (size_t) width*height*4, (size_t) 1, file); + + Image checkedIm = { + .data = pixels, + .width = width, + .height = height, + .format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, + .mipmaps = 1 + }; + + *loc = LoadTextureFromImage(checkedIm); + UnloadImage(checkedIm); + +} + + //! read a big endian bytes from file -int readb(char *out, size_t noBytes, FILE *file) { +int readb(char * out, size_t noBytes, FILE * file) { if (!fread(out, (size_t)1, (size_t) noBytes, file)) return 1; @@ -51,11 +70,11 @@ int readb(char *out, size_t noBytes, FILE *file) { } -Texture2D loadTileMap(char *filename) { - int width, height, tilebytes; - int *tilelayout; +void loadTileMap(char * filename, Texture2D * tilemap, Texture2D * atlas, int * atlasSize) { + int width, height, tilebytes, tilesize, atlasWidth, atlasHeight; + int * tilelayout; - FILE *file; + FILE * file; file = fopen(filename, "rb"); // skip header @@ -64,17 +83,23 @@ Texture2D loadTileMap(char *filename) { readb((char *)&width, 4, file); // 4 bytes for int height readb((char *)&height, 4, file); - // 1 byte saying how big each tile is + // 4 bytes saying how big each tile is readb((char *)&tilebytes, 4, file); - printf("tilebytes: %d\n", tilebytes); + fprintf(stderr, "loading %d bytes per tile for %d tiles\n", tilebytes, width*height); tilelayout = malloc(width*height*tilebytes); - int tile; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - readb((char *)&tile, tilebytes, file); - tilelayout[y*width + x] = tile; - } - } - return processTilemapTexture(tilelayout, width, height); + fread(tilelayout, tilebytes, width*height, file); + processTilemapTexture(tilemap, tilelayout, width, height); + + // read the pixel size of each tile + readb((char *)&tilesize, 4, file); + // read the atlas size + readb((char *)&atlasWidth, 4, file); + readb((char *)&atlasHeight, 4, file); + atlasSize[0] = atlasWidth; + atlasSize[1] = atlasHeight; + + // read the atlas itself + readrgba(atlas, atlasWidth * tilesize, atlasHeight * tilesize, file); + fprintf(stderr, "Successfully loaded tilemap from %s\n", filename); } diff --git a/src/tiledfile.h b/src/tiledfile.h index cf2980b..02342b3 100644 --- a/src/tiledfile.h +++ b/src/tiledfile.h @@ -1,3 +1,3 @@ #include -Texture2D loadTileMap(char *filename); +void loadTileMap(char * filename, Texture2D * tilemap, Texture2D * atlas, int * atlasSize); diff --git a/tools/createmap.py b/tools/createmap.py index 59fb315..36f6ca9 100755 --- a/tools/createmap.py +++ b/tools/createmap.py @@ -1,12 +1,33 @@ #!/usr/bin/env python import sys +from math import ceil, log +from PIL import Image outfile = "map.tiles" -WIDTH = 500 -HEIGHT = 100 +ATLASFILE = "atlas.png" + +TILESIZE = 16 +WIDTH = 1024 +HEIGHT = 1024 + +# create atlas bytes +image = Image.open(ATLASFILE).convert("RGBA") + + +# check if atlas is suitable +if image.width % TILESIZE != 0 or image.height % TILESIZE != 0: + print(f"Atlas image must be divisible by {TILESIZE}", file=sys.err) + sys.exit(1) + +# calculate number of possible tiles (adding 1 for the empty tile) +tilecount = (image.width * image.height) / (TILESIZE**2) + 1 + +atlas_width = image.width // TILESIZE +atlas_height = image.width // TILESIZE + # number of bytes each tile needs to represent -TILEBYTES = 25 +tilebytes = ceil(log(tilecount, 256)) HEADER = "TILEFILEv1" @@ -14,10 +35,15 @@ with open(outfile, "wb") as file: file.write(bytes(HEADER, "ascii")) file.write(WIDTH.to_bytes(4, 'big')); file.write(HEIGHT.to_bytes(4, 'big')); - file.write(TILEBYTES.to_bytes(4, 'big')); + file.write(tilebytes.to_bytes(4, 'big')); + for y in range(HEIGHT): for x in range(WIDTH): index = (x + y) % 5 - file.write(index.to_bytes(TILEBYTES, 'big')); + file.write(index.to_bytes(tilebytes, 'big')); + file.write(TILESIZE.to_bytes(4, 'big')); + file.write(atlas_width.to_bytes(4, 'big')); + file.write(atlas_height.to_bytes(4, 'big')); + file.write(image.tobytes()) -- cgit v1.2.1