#include #include #include #include #include "loader.h" #include "main.h" SDL_Texture *tilemap_tileset = NULL, *tilemap_wang_tileset = NULL, *tilemap_tilemap = NULL; #define PACKED __attribute__((__packed__)) struct PACKED sets { uint32_t tilesets_count; uint32_t wang_count; }; struct PACKED map { uint32_t width; uint32_t height; uint32_t layers; 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(void) { SDL_DestroyTexture(tilemap_tileset), tilemap_tileset = NULL; SDL_DestroyTexture(tilemap_wang_tileset), tilemap_wang_tileset = NULL; SDL_DestroyTexture(tilemap_tilemap), tilemap_tilemap = 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_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); for (uint32_t count = sets->tilesets_count; count > 0; count--) { int height = *(uint32_t *) str; str += sizeof (uint32_t); size_t len = strnlen(str, size); if (len == size) { return 1; } 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_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); if (sets->tilesets_count) { int height = *(uint32_t *) str; str += sizeof (uint32_t); size_t len = strnlen(str, size); if (len == size) { return 1; } 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; } 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 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}); } } } SDL_DestroyTexture(tilemap_tilemap), tilemap_tilemap = tilemap; SDL_SetRenderTarget(renderer, NULL); return 0; }