summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c15
-rw-r--r--src/res/untitled.tmx5
-rw-r--r--src/tilemap.c64
-rw-r--r--src/tilemap.h15
4 files changed, 79 insertions, 20 deletions
diff --git a/src/main.c b/src/main.c
index 6da4d9a..eccd351 100644
--- a/src/main.c
+++ b/src/main.c
@@ -46,6 +46,7 @@ int main(int argc, char **argv) {
 		goto end;
 	}
 	SDL_RenderSetLogicalSize(renderer, WINDOW_WIDTH, WINDOW_HEIGHT);
+	SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
 	
 	{
 		res_init();
@@ -57,7 +58,7 @@ int main(int argc, char **argv) {
 		}
 		free(a);
 		struct blob map = res_get_map("untitled");
-		tilemap = load_tilemap(map.data, map.size);
+		tilemap = tilemap_load(map.data, map.size);
 		printf("load_tilemap %p\n", (void *) tilemap);
 		SDL_SetRenderTarget(renderer, NULL);
 	}
@@ -125,6 +126,8 @@ int main(int argc, char **argv) {
 				case SDL_MOUSEWHEEL: // the scroll wheel gets rolled
 					//fprintf(stderr, "scrolled by %2i %2i %4.1f %4.1f\n", evt.wheel.x, evt.wheel.y, evt.wheel.preciseX, evt.wheel.preciseY);
 					break;
+				case SDL_CLIPBOARDUPDATE: // annoying
+					break;
 				case SDL_WINDOWEVENT: // window related events
 					switch (evt.window.event) {
 						case SDL_WINDOWEVENT_SHOWN:
@@ -179,9 +182,6 @@ int main(int argc, char **argv) {
 		SDL_SetRenderTarget(renderer, NULL);
 		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
 		SDL_RenderClear(renderer);
-		SDL_SetRenderDrawColor(renderer, 0, 128, 255, 0);
-		SDL_RenderFillRect(renderer, &(SDL_Rect) {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT});
-		SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
 
 		x += input_right(input_now) - input_left(input_now);
 		y += input_down(input_now) - input_up(input_now);
@@ -189,16 +189,15 @@ int main(int argc, char **argv) {
 		if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > tilemap->height * 8) {y = tilemap->height * 8 - WINDOW_HEIGHT;}
 		
 		//SDL_RenderCopy(renderer, tilemap->wang_tileset, &(SDL_Rect) {0, 0, 128, 90}, &(SDL_Rect) {0, 0, 128, 90});
-		for (int i = 0; i < tilemap->layers; i++) {
-			SDL_RenderCopy(renderer, tilemap->tilemaps[i], &(SDL_Rect) {x * tilemap->parallax[i].x, y * tilemap->parallax[i].y, WINDOW_WIDTH, WINDOW_HEIGHT}, &(SDL_Rect) {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT});
-		}
+		tilemap_background(tilemap, x, y, WINDOW_WIDTH, WINDOW_HEIGHT);
+		tilemap_foreground(tilemap, x, y, WINDOW_WIDTH, WINDOW_HEIGHT);
 		//SDL_RenderCopy(renderer, res_get_texture("meow").data, &(SDL_Rect) {0, 0, 128, 90}, &(SDL_Rect) {0, 0, 128, 90});
 		// then we wait for the next video frame 
 		SDL_RenderPresent(renderer);
 	}
 	
 	end:
-	free_tilemap(tilemap), tilemap = NULL;
+	tilemap_free(tilemap), tilemap = NULL;
 	SDL_DestroyRenderer(renderer);
 	SDL_DestroyWindow(window);
 	//SDL_QuitSubSystem(INIT_SUBSYSTEMS);
diff --git a/src/res/untitled.tmx b/src/res/untitled.tmx
index 51b506c..6a8bbd0 100644
--- a/src/res/untitled.tmx
+++ b/src/res/untitled.tmx
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="8" tileheight="8" infinite="0" nextlayerid="7" nextobjectid="6">
+<map version="1.10" tiledversion="1.11.0" orientation="orthogonal" renderorder="right-down" width="30" height="20" tilewidth="8" tileheight="8" infinite="0" backgroundcolor="#63acef" nextlayerid="7" nextobjectid="6">
  <properties>
   <property name="custom 1" value="1234"/>
   <property name="custom 2" type="bool" value="true"/>
@@ -32,6 +32,9 @@
 </data>
  </layer>
  <group id="5" name="Group Layer 1">
+  <properties>
+   <property name="middleground" type="bool" value="true"/>
+  </properties>
   <layer id="1" name="Tile Layer 1" width="30" height="20" offsetx="-4" offsety="-4">
    <data encoding="csv">
 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
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;
 }
diff --git a/src/tilemap.h b/src/tilemap.h
index 587bdf6..912b67f 100644
--- a/src/tilemap.h
+++ b/src/tilemap.h
@@ -4,17 +4,24 @@
 extern struct tilemap {
 	void *tileset;
 	void *wang_tileset;
+	struct {
+		unsigned char r, g, b, a;
+	} backdrop;
 	unsigned width;
 	unsigned height;
 	unsigned layers;
-	unsigned behind;
+	unsigned middleground;
 	struct parallax {
 		float x, y;
 	} *parallax;
 	collision_T *collision;
 	void **tilemaps;
+	size_t input_bytes;
 } *tilemap, *next_tilemap;
 
-void init_tilemap(void);
-void free_tilemap(struct tilemap *tilemap);
-struct tilemap *load_tilemap(void *data, size_t size);
+// render the fore/back ground of the tilemap to `renderer`
+void tilemap_background(struct tilemap *tilemap, int x, int y, int w, int h);
+void tilemap_foreground(struct tilemap *tilemap, int x, int y, int w, int h);
+
+void tilemap_free(struct tilemap *tilemap);
+struct tilemap *tilemap_load(void *data, size_t size);