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.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/src/tilemap.c b/src/tilemap.c
index 34e7c43..ccfe990 100644
--- a/src/tilemap.c
+++ b/src/tilemap.c
@@ -1,11 +1,11 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
-
-#include <SDL2/SDL.h>
+#include <limits.h>
 
 #include "loader.h"
-#include "main.h"
+#include "main.h" // renderer
 
 #include "tilemap.h"
 #include "collision.h"
@@ -71,17 +71,13 @@ collision_T tilemap_area(struct tilemap *tilemap, int x1, int y1, int x2, int y2
 	if (x1 < 0) {
 		x1 = 0;
 	}
-	if (x2 < 0) {
-		x2 = 0;
-	} else if (x2 >= tilemap->width) {
+	if (x2 >= (signed) tilemap->width) {
 		x2 = tilemap->width - 1;
 	}
 	if (y1 < 0) {
 		y1 = 0;
 	}
-	if (y2 < 0) { // for some reason you can bonk your head on nothing without this
-		y2 = 0;
-	} else if (y2 >= tilemap->height) {
+	if (y2 >= (signed) tilemap->height) {
 		y2 = tilemap->height - 1;
 	}
 	return tilemap_area_raw(tilemap, x1, y1, x2, y2);
@@ -90,14 +86,36 @@ collision_T tilemap_area(struct tilemap *tilemap, int x1, int y1, int x2, int y2
 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});
+	int bx = 0, by = 0, vw = w, vh = h;
+	if (x < 0) {
+		bx = -x;
+		vw = w + x * 2;
+		x = 0;
+	}
+	if (y < 0) {
+		by = -y;
+		vh = h + y * 2;
+		y = 0;
+	}
 	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});
+		SDL_RenderCopy(renderer, tilemap->tilemaps[i], &(SDL_Rect) {x * tilemap->parallax[i].x, y * tilemap->parallax[i].y, vw, vh}, &(SDL_Rect) {bx, by, vw, vh});
 	}
 }
 
 void tilemap_foreground(struct tilemap *tilemap, int x, int y, int w, int h) {
+	int bx = 0, by = 0, vw = w, vh = h;
+	if (x < 0) {
+		bx = -x;
+		vw = w + x * 2;
+		x = 0;
+	}
+	if (y < 0) {
+		by = -y;
+		vh = h + y * 2;
+		y = 0;
+	}
 	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});
+		SDL_RenderCopy(renderer, tilemap->tilemaps[i], &(SDL_Rect) {x * tilemap->parallax[i].x, y * tilemap->parallax[i].y, vw, vh}, &(SDL_Rect) {bx, by, vw, vh});
 	}
 }
 
@@ -163,7 +181,7 @@ struct tilemap *tilemap_load(void *data, size_t size) {
 		struct blob col = res_get_collision(str);
 		
 		SDL_RenderCopy(renderer, tex, &(SDL_Rect) {0, 0, 128, height}, &(SDL_Rect) {0, y, 128, height});
-		if (col.data != NULL) { // silence -fsanitize=undefined
+		if (col.data != NULL) { // col.data is only NULL when col.size is 0 but -fsanitize=undefined doesnt know that
 			if (col.size + y * 2 > 0xf0) {
 				fprintf(stderr, "warn: '%s' overflows tile properties\n", str);
 				col.size = 0xf0 - y * 2;
@@ -213,6 +231,9 @@ struct tilemap *tilemap_load(void *data, size_t size) {
 	if (map->width * map->height * map->layers > size - sizeof (struct map)) {
 		goto fail;
 	}
+	if (map->width > INT_MAX || map->height > INT_MAX) {
+		goto fail;
+	}
 
 	tilemap->backdrop.r = map->backdrop.r;
 	tilemap->backdrop.g = map->backdrop.g;