summary refs log tree commit diff
path: root/src/tilemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tilemap.c')
-rw-r--r--src/tilemap.c64
1 files changed, 57 insertions, 7 deletions
diff --git a/src/tilemap.c b/src/tilemap.c
index 84d2509..af2c163 100644
--- a/src/tilemap.c
+++ b/src/tilemap.c
@@ -14,19 +14,40 @@ struct tilemap *tilemap = NULL, *next_tilemap = NULL;
 
 #define PACKED __attribute__((__packed__))
 
+uint8_t const MAGIC[4] = "TMv1";
+
 struct PACKED sets {
+	uint8_t magic[4];
 	uint32_t tilesets_count;
 	uint32_t wang_count;
 };
 
 struct PACKED map {
+	struct {
+		uint8_t r, g, b, a;
+	} backdrop;
 	uint32_t width;
 	uint32_t height;
 	uint32_t layers;
+	uint32_t middleground;
 	uint8_t tiles[];
 };
 
-void free_tilemap(struct tilemap *tilemap) {
+void tilemap_background(struct tilemap *tilemap, int x, int y, int w, int h) {
+	SDL_SetRenderDrawColor(renderer, tilemap->backdrop.r, tilemap->backdrop.g, tilemap->backdrop.b, tilemap->backdrop.a);
+	SDL_RenderFillRect(renderer, &(SDL_Rect) {0, 0, w, h});
+	for (int i = 0; i < tilemap->middleground; i++) {
+		SDL_RenderCopy(renderer, tilemap->tilemaps[i], &(SDL_Rect) {x * tilemap->parallax[i].x, y * tilemap->parallax[i].y, w, h}, &(SDL_Rect) {0, 0, w, h});
+	}
+}
+
+void tilemap_foreground(struct tilemap *tilemap, int x, int y, int w, int h) {
+	for (int i = tilemap->middleground; i < tilemap->layers; i++) {
+		SDL_RenderCopy(renderer, tilemap->tilemaps[i], &(SDL_Rect) {x * tilemap->parallax[i].x, y * tilemap->parallax[i].y, w, h}, &(SDL_Rect) {0, 0, w, h});
+	}
+}
+
+void tilemap_free(struct tilemap *tilemap) {
 	SDL_DestroyTexture(tilemap->tileset);
 	SDL_DestroyTexture(tilemap->wang_tileset);
 	free(tilemap->parallax);
@@ -38,11 +59,23 @@ void free_tilemap(struct tilemap *tilemap) {
 	free(tilemap);
 }
 
-struct tilemap *load_tilemap(void *data, size_t size) {
+struct tilemap *tilemap_load(void *data, size_t size) {
+	size_t const insize = size;
+
+	struct sets *const sets = data;
+	data = sets + 1;
+	size -= sizeof (struct sets);
+
+	if (memcmp(sets->magic, MAGIC, sizeof (MAGIC)) != 0) {
+		fprintf(stderr, "error: unsupported level format (got '%.4s' expected '%.4s')\n", sets->magic, MAGIC);
+		return NULL;
+	}
+
 	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);
@@ -51,9 +84,6 @@ struct tilemap *load_tilemap(void *data, size_t size) {
 	tilemap->collision = NULL;
 	tilemap->tilemaps = NULL;
 
-	struct sets *const sets = data;
-	data = sets + 1;
-	size -= sizeof (struct sets);
 	char *str = data;
 	int y = 0;
 	SDL_SetRenderTarget(renderer, tilemap->tileset);
@@ -95,7 +125,7 @@ struct tilemap *load_tilemap(void *data, size_t size) {
 		str += sizeof (uint32_t);
 		size_t len = strnlen(str, size);
 		if (len == size) {
-			free_tilemap(tilemap);
+			tilemap_free(tilemap);
 			return NULL;
 		}
 		void *tex = res_get_texture(str).data;
@@ -117,11 +147,29 @@ struct tilemap *load_tilemap(void *data, size_t size) {
 		goto fail;
 	}
 
+	tilemap->backdrop.r = map->backdrop.r;
+	tilemap->backdrop.g = map->backdrop.g;
+	tilemap->backdrop.b = map->backdrop.b;
+	tilemap->backdrop.a = map->backdrop.a;
 	tilemap->width = map->width;
 	tilemap->height = map->height;
 	tilemap->layers = map->layers;
+	tilemap->middleground = map->middleground;
 	tilemap->tilemaps = malloc(sizeof (void *) * tilemap->layers);
 	
+	if (tilemap->middleground > tilemap->layers) {
+		goto fail;
+	} else if (tilemap->middleground == 0) {
+		fputs("warn: map has no middle ground\n", stderr);
+		tilemap->collision = calloc(tilemap->width, tilemap->height * sizeof (collision_T));
+	} else {
+		tilemap->collision = malloc(tilemap->width * tilemap->height * sizeof (collision_T));
+		size_t const ll = (tilemap->middleground - 1) * map->width * map->height;
+		for (size_t i = 0; i < tilemap->width * tilemap->height; i++) {
+			tilemap->collision[i] = collision[map->tiles[i + ll]];
+		}
+	}
+	
 	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);
@@ -170,11 +218,13 @@ struct tilemap *load_tilemap(void *data, size_t size) {
 
 	size -= sizeof (struct parallax) * map->layers;
 	
+	tilemap->input_bytes = insize - size;
+	//fprintf(stderr, "size: %zuB remaining: %zuB total: %zuB\n", tilemap->input_bytes, size, insize);
 	SDL_SetRenderTarget(renderer, NULL);
 	return tilemap;
 	
 	fail:
-	free_tilemap(tilemap);
+	tilemap_free(tilemap);
 	SDL_SetRenderTarget(renderer, NULL);
 	return NULL;
 }