From 9942429dbb83fed5532c070f8afe41d6ddcd66d2 Mon Sep 17 00:00:00 2001 From: zlago Date: Wed, 25 Sep 2024 14:02:49 +0200 Subject: parallax --- src/incbin.h | 7 +++ src/incbin.s | 7 +++ src/main.c | 47 ++++++++++++++++---- src/res/icon.png | Bin 0 -> 239 bytes src/tilemap.c | 132 +++++++++++++++++++++++++++++++++++-------------------- src/tilemap.h | 20 +++++++-- 6 files changed, 154 insertions(+), 59 deletions(-) create mode 100644 src/incbin.h create mode 100644 src/incbin.s create mode 100644 src/res/icon.png (limited to 'src') 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 Binary files /dev/null and b/src/res/icon.png differ diff --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); -- cgit 1.4.1-2-gfad0