summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorzlago2024-09-25 14:02:49 +0200
committerzlago2024-09-25 14:19:32 +0200
commit9942429dbb83fed5532c070f8afe41d6ddcd66d2 (patch)
tree70f7d3872de143a7f256b3913e2bf52724d23c3a /src
parentb23a3ab831f91553d34a48f51370ed9525de07ac (diff)
parallax
Diffstat (limited to 'src')
-rw-r--r--src/incbin.h7
-rw-r--r--src/incbin.s7
-rw-r--r--src/main.c47
-rw-r--r--src/res/icon.pngbin0 -> 239 bytes
-rw-r--r--src/tilemap.c132
-rw-r--r--src/tilemap.h20
6 files changed, 154 insertions, 59 deletions
diff --git a/src/incbin.h b/src/incbin.h
new file mode 100644
index 0000000..72c149b
--- /dev/null
+++ b/src/incbin.h
@@ -0,0 +1,7 @@
+#if defined(__APPLE__)
+extern char const game_icon[], game_icon_end[];
+#else
+extern char const _game_icon[], _game_icon_end[];
+#define game_icon     _game_icon
+#define game_icon_end _game_icon_end
+#endif
diff --git a/src/incbin.s b/src/incbin.s
new file mode 100644
index 0000000..9d6420b
--- /dev/null
+++ b/src/incbin.s
@@ -0,0 +1,7 @@
+// binary includes
+
+.data
+
+_game_icon: .incbin "res/icon.png"
+_game_icon_end:
+.global _game_icon, _game_icon_end
diff --git a/src/main.c b/src/main.c
index a304797..bf23ee0 100644
--- a/src/main.c
+++ b/src/main.c
@@ -9,6 +9,9 @@
 
 #include "tilemap.h"
 
+#include "incbin.h"
+#include "libplum.h"
+
 SDL_Window *window = NULL;
 SDL_Renderer *renderer = NULL;
 
@@ -37,7 +40,7 @@ int main(int argc, char **argv) {
 	if (window == NULL) {
 		goto end;
 	}
-	renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE| SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC);
+	renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC);
 	if (renderer == NULL) {
 		goto end;
 	}
@@ -46,7 +49,7 @@ int main(int argc, char **argv) {
 	{
 		res_init_texture();
 		res_init_map();
-		init_tilemap();
+		//init_tilemap();
 		void *a = util_executableRelativePath("assets.res", *argv, 0);
 		puts(a);
 		if (loadResources(a)) {
@@ -55,10 +58,28 @@ int main(int argc, char **argv) {
 		}
 		free(a);
 		struct blob map = res_get_map("out");
-		printf("load_tilemap %u\n", load_tilemap(map.data, map.size));
+		tilemap = load_tilemap(map.data, map.size);
+		printf("load_tilemap %p\n", tilemap);
 		SDL_SetRenderTarget(renderer, NULL);
 	}
 
+	unsigned error;
+	struct plum_image *image = plum_load_image(game_icon, game_icon_end - game_icon, PLUM_COLOR_32 | PLUM_ALPHA_INVERT, &error);
+	if (image == NULL) {
+		fprintf(stderr, "error: libplum: %s\n", plum_get_error_text(error));
+		goto icon_done;
+	}
+	SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(image->data, image->width, image->height, 32, image->width * 4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
+	if (surface == NULL) {
+		plum_destroy_image(image);
+		fprintf(stderr, "error: SDL2: %s\n", SDL_GetError());
+		goto icon_done;
+	}
+	SDL_SetWindowIcon(window, surface);
+	SDL_FreeSurface(surface);
+	plum_destroy_image(image);
+	icon_done:
+
 	SDL_ShowWindow(window);
 	
 	int x = 0, y = 0;
@@ -118,8 +139,11 @@ int main(int argc, char **argv) {
 							break;
 						case SDL_WINDOWEVENT_MOVED: // a window is moved
 							//fprintf(stderr, "window %u moved %4i %4i\n", evt.window.windowID, evt.window.data1, evt.window.data2);
-							//wx = evt.window.data1;
-							//wy = evt.window.data2;
+							break;
+						case SDL_WINDOWEVENT_RESIZED: // a window is resized
+							//fprintf(stderr, "window %u resized %4i %4i\n", evt.window.windowID, evt.window.data1, evt.window.data2);
+							break;
+						case SDL_WINDOWEVENT_SIZE_CHANGED: // ?
 							break;
 						case SDL_WINDOWEVENT_MINIMIZED:
 							//fprintf(stderr, "window %u minimized\n", evt.window.windowID);
@@ -159,18 +183,23 @@ int main(int argc, char **argv) {
 		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);
-		//SDL_RenderCopy(renderer, tilemap_tileset, &(SDL_Rect) {0, 0, 128, 90}, &(SDL_Rect) {0, 0, 128, 90});
-		SDL_RenderCopy(renderer, tilemap_tilemap, &(SDL_Rect) {x, y, WINDOW_WIDTH, WINDOW_HEIGHT}, &(SDL_Rect) {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT});
+
 		x += input_right(input_now) - input_left(input_now);
 		y += input_down(input_now) - input_up(input_now);
-		if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > 29 * 8) {x = 29 * 8 - WINDOW_WIDTH;}
-		if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > 19 * 8) {y = 19 * 8 - WINDOW_HEIGHT;}
+		if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > tilemap->width * 8) {x = tilemap->width * 8 - WINDOW_WIDTH;}
+		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});
+		}
 		//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;
 	SDL_DestroyRenderer(renderer);
 	SDL_DestroyWindow(window);
 	//SDL_QuitSubSystem(INIT_SUBSYSTEMS);
diff --git a/src/res/icon.png b/src/res/icon.png
new file mode 100644
index 0000000..04d5199
--- /dev/null
+++ b/src/res/icon.png
Binary files differdiff --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;
 }
diff --git a/src/tilemap.h b/src/tilemap.h
index 54e051b..dc0f938 100644
--- a/src/tilemap.h
+++ b/src/tilemap.h
@@ -1,5 +1,19 @@
-extern void /*SDL_Texture*/ *tilemap_tileset, *tilemap_wang_tileset, *tilemap_tilemap;
+#pragma once
+
+extern struct tilemap {
+	void *tileset;
+	void *wang_tileset;
+	unsigned width;
+	unsigned height;
+	unsigned layers;
+	unsigned behind;
+	struct parallax {
+		float x, y;
+	} *parallax;
+	unsigned *collision;
+	void **tilemaps;
+} *tilemap, *next_tilemap;
 
 void init_tilemap(void);
-void free_tilemap(void);
-int load_tilemap(void const *data, size_t size);
+void free_tilemap(struct tilemap *tilemap);
+struct tilemap *load_tilemap(void const *data, size_t size);