summary refs log tree commit diff
path: root/src/tilemap.c
diff options
context:
space:
mode:
authorzlago2024-09-24 20:54:48 +0200
committerzlago2024-09-24 20:54:48 +0200
commitb23a3ab831f91553d34a48f51370ed9525de07ac (patch)
treebd4adf20ba92d17433f386c0b5347a8d8cc9045f /src/tilemap.c
initial commit
Diffstat (limited to 'src/tilemap.c')
-rw-r--r--src/tilemap.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/tilemap.c b/src/tilemap.c
new file mode 100644
index 0000000..a63cef5
--- /dev/null
+++ b/src/tilemap.c
@@ -0,0 +1,125 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <SDL2/SDL.h>
+
+#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;
+}