From 9942429dbb83fed5532c070f8afe41d6ddcd66d2 Mon Sep 17 00:00:00 2001 From: zlago Date: Wed, 25 Sep 2024 14:02:49 +0200 Subject: parallax --- src/tilemap.c | 132 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 47 deletions(-) (limited to 'src/tilemap.c') diff --git a/src/tilemap.c b/src/tilemap.c index a63cef5..3f19f0e 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -7,7 +7,9 @@ #include "loader.h" #include "main.h" -SDL_Texture *tilemap_tileset = NULL, *tilemap_wang_tileset = NULL, *tilemap_tilemap = NULL; +#include "tilemap.h" + +struct tilemap *tilemap = NULL, *next_tilemap = NULL; #define PACKED __attribute__((__packed__)) @@ -23,25 +25,37 @@ struct PACKED map { uint8_t tiles[]; }; -void init_tilemap(void) { - tilemap_tileset = SDL_CreateTexture(renderer, SDL_PIXELTYPE_UNKNOWN, SDL_TEXTUREACCESS_TARGET, 128, 128); - tilemap_wang_tileset = SDL_CreateTexture(renderer, SDL_PIXELTYPE_UNKNOWN, SDL_TEXTUREACCESS_TARGET, 128, 128); - SDL_SetTextureBlendMode(tilemap_wang_tileset, SDL_BLENDMODE_BLEND); +void free_tilemap(struct tilemap *tilemap) { + SDL_DestroyTexture(tilemap->tileset); + SDL_DestroyTexture(tilemap->wang_tileset); + free(tilemap->parallax); + free(tilemap->collision); + for (int i = 0; i < tilemap->layers; i++) { + SDL_DestroyTexture(tilemap->tilemaps[i]); + } + free(tilemap->tilemaps); + free(tilemap); } -void free_tilemap(void) { - SDL_DestroyTexture(tilemap_tileset), tilemap_tileset = NULL; - SDL_DestroyTexture(tilemap_wang_tileset), tilemap_wang_tileset = NULL; - SDL_DestroyTexture(tilemap_tilemap), tilemap_tilemap = NULL; -} +struct tilemap *load_tilemap(void const *data, size_t size) { + struct tilemap *tilemap = malloc(sizeof (struct tilemap)); + if (tilemap == NULL) { + return NULL; + } + tilemap->tileset = SDL_CreateTexture(renderer, SDL_PIXELTYPE_UNKNOWN, SDL_TEXTUREACCESS_TARGET, 128, 128); + tilemap->wang_tileset = SDL_CreateTexture(renderer, SDL_PIXELTYPE_UNKNOWN, SDL_TEXTUREACCESS_TARGET, 128, 128); + SDL_SetTextureBlendMode(tilemap->wang_tileset, SDL_BLENDMODE_BLEND); + tilemap->layers = 0; + tilemap->parallax = NULL; + tilemap->collision = NULL; + tilemap->tilemaps = NULL; -int load_tilemap(void const *data, size_t size) { struct sets const *const sets = data; data = sets + 1; size -= sizeof (struct sets); char const *str = data; int y = 0; - SDL_SetRenderTarget(renderer, tilemap_tileset); + SDL_SetRenderTarget(renderer, tilemap->tileset); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); @@ -50,20 +64,18 @@ int load_tilemap(void const *data, size_t size) { str += sizeof (uint32_t); size_t len = strnlen(str, size); if (len == size) { - return 1; + goto fail; } void *tex = res_get_texture(str).data; - //printf("%u %u\n", y, height); SDL_RenderCopy(renderer, tex, &(SDL_Rect) {0, 0, 128, height}, &(SDL_Rect) {0, y, 128, height}); - //printf("%s %u\n", str, tex); y += height; str += len + 1; size -= len + 4 + 1; } - SDL_SetRenderTarget(renderer, tilemap_wang_tileset); + SDL_SetRenderTarget(renderer, tilemap->wang_tileset); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); @@ -72,54 +84,80 @@ int load_tilemap(void const *data, size_t size) { str += sizeof (uint32_t); size_t len = strnlen(str, size); if (len == size) { - return 1; + free_tilemap(tilemap); + return NULL; } void *tex = res_get_texture(str).data; - //printf("%u %u\n", y, height); SDL_RenderCopy(renderer, tex, &(SDL_Rect) {0, 0, 128, height}, &(SDL_Rect) {0, 0, 128, height}); - //printf("%s %u\n", str, tex); str += len + 1; size -= len + 4 + 1; } struct map const *const map = (void *) str; - if (map->width * map->height * map->layers != size - sizeof (struct map)) { - return 1; + if (map->width * map->height * map->layers > size - sizeof (struct map)) { + goto fail; } + + tilemap->width = map->width; + tilemap->height = map->height; + tilemap->layers = map->layers; + tilemap->tilemaps = malloc(sizeof (void *) * tilemap->layers); - SDL_Texture *tilemap = SDL_CreateTexture(renderer, SDL_PIXELTYPE_UNKNOWN, SDL_TEXTUREACCESS_TARGET, map->width * 8, map->height * 8); - SDL_SetTextureBlendMode(tilemap, SDL_BLENDMODE_BLEND); - SDL_SetRenderTarget(renderer, tilemap); - - for (int y = 0; y < map->height; y++) { - for (int x = 0; x < map->width; x++) { - unsigned tile = map->tiles[x + map->width * y]; - int tileX = tile & 0x0f; - int tileY = tile >> 4; - SDL_RenderCopy(renderer, tilemap_tileset, &(SDL_Rect) {tileX * 8, tileY * 8, 8, 8}, &(SDL_Rect) {x * 8, y * 8, 8, 8}); + for (int l = 0; l < tilemap->layers; l++) { + SDL_Texture *layer = SDL_CreateTexture(renderer, SDL_PIXELTYPE_UNKNOWN, SDL_TEXTUREACCESS_TARGET, map->width * 8, map->height * 8); + SDL_SetTextureBlendMode(layer, SDL_BLENDMODE_BLEND); + SDL_SetRenderTarget(renderer, layer); + + size_t const ll = l * map->width * map->height; + for (int y = 0; y < map->height; y++) { + size_t const yy = y * map->width; + for (int x = 0; x < map->width; x++) { + unsigned tile = map->tiles[x + yy + ll]; + int tileX = tile & 0x0f; + int tileY = tile >> 4; + SDL_RenderCopy(renderer, tilemap->tileset, &(SDL_Rect) {tileX * 8, tileY * 8, 8, 8}, &(SDL_Rect) {x * 8, y * 8, 8, 8}); + } } - } - - for (int tile = 0xf0; tile < 0x100; tile++) { - for (int y = 0; y < map->height - 1; y++) { - for (int x = 0; x < map->width - 1; x++) { - int tl = map->tiles[x + map->width * y] == tile; - int tr = map->tiles[x + 1 + map->width * y] == tile; - int bl = map->tiles[x + map->width * (y + 1)] == tile; - int br = map->tiles[x + 1 + map->width * (y + 1)] == tile; - //int tileX = tl << 3 | tr << 2 | bl << 1 | br << 0; - int tileX = tl << 0 | tr << 1 | bl << 2 | br << 3; - int tileY = tile & 0x0f; - SDL_RenderCopy(renderer, tilemap_wang_tileset, &(SDL_Rect) {tileX * 8, tileY * 8, 8, 8}, &(SDL_Rect) {x * 8 + 4, y * 8 + 4, 8, 8}); + + for (int tile = 0xf0; tile < 0x100; tile++) { + for (int y = 0; y < map->height - 1; y++) { + size_t const yy = y * map->width; + for (int x = 0; x < map->width - 1; x++) { + int tl = map->tiles[x + yy + ll] == tile; + int tr = map->tiles[x + 1 + yy + ll] == tile; + int bl = map->tiles[x + yy + map->width + ll] == tile; + int br = map->tiles[x + 1 + yy + map->width + ll] == tile; + int tileX = tl << 0 | tr << 1 | bl << 2 | br << 3; + int tileY = tile & 0x0f; + SDL_RenderCopy(renderer, tilemap->wang_tileset, &(SDL_Rect) {tileX * 8, tileY * 8, 8, 8}, &(SDL_Rect) {x * 8 + 4, y * 8 + 4, 8, 8}); + } } } - } - SDL_DestroyTexture(tilemap_tilemap), tilemap_tilemap = tilemap; + tilemap->tilemaps[l] = layer; + } + + float *parallax = (void *) (map->tiles + map->width * map->height * map->layers); + size -= (char *) parallax - (char *) map; + if (sizeof (struct parallax) * map->layers > size) { + goto fail; + } + + tilemap->parallax = malloc(sizeof (struct parallax) * map->layers); + for (int i = 0; i < map->layers; i++) { + tilemap->parallax[i].x = *parallax++; + tilemap->parallax[i].y = *parallax++; + } + size -= sizeof (struct parallax) * map->layers; + SDL_SetRenderTarget(renderer, NULL); + return tilemap; - return 0; + fail: + free_tilemap(tilemap); + SDL_SetRenderTarget(renderer, NULL); + return NULL; } -- cgit 1.4.1-2-gfad0