diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.c | 15 | ||||
-rw-r--r-- | src/res/untitled.tmx | 5 | ||||
-rw-r--r-- | src/tilemap.c | 64 | ||||
-rw-r--r-- | src/tilemap.h | 15 |
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); |