summaryrefslogtreecommitdiff
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);