summaryrefslogtreecommitdiff
path: root/src/tilemap.c
diff options
context:
space:
mode:
authorzlago2024-09-27 18:34:24 +0200
committerzlago2024-09-27 18:34:24 +0200
commite304b0a4acc3f0870f55e6b584c464096333dfdc (patch)
tree9c985b966d758020e0aa0efdd8cbdb69ec716412 /src/tilemap.c
parentd3dc2389c308278442831f370950b2d25e5fa734 (diff)
tilemap collision
the 'middle ground' layer is the only layer which is solid, and the boundary between the background and the foreground additionally, the maps now can have a custom sky color
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;
}