diff options
author | zlago | 2024-09-30 15:57:29 +0200 |
---|---|---|
committer | zlago | 2024-09-30 15:57:29 +0200 |
commit | e4ad2c9362254ab3213c4cb7c743b6bbd72b6346 (patch) | |
tree | d839f778a15f65b09fb0f0b773a500168e75afcc | |
parent | 45512bbc85188e3adb4eda597d0d2fa5530de651 (diff) |
commandline parameters
-rw-r--r-- | GNUmakefile | 8 | ||||
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | src/entity.h | 3 | ||||
-rw-r--r-- | src/main.c | 125 | ||||
-rw-r--r-- | src/player.c | 3 | ||||
-rw-r--r-- | src/tilemap.c | 3 | ||||
-rw-r--r-- | src/util.c | 2 | ||||
-rw-r--r-- | src/util.h | 2 |
8 files changed, 129 insertions, 19 deletions
diff --git a/GNUmakefile b/GNUmakefile index 2e4afa6..f16eaa2 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -14,10 +14,10 @@ deps := $(addprefix out/${NS}/,$(notdir $(patsubst %.c,%.d,$(wildcard src/*.c))) .PHONY: all run clean -all: out/${NS}/a.out +all: out/${NS}/a.out out/assets.res -run: out/${NS}/a.out - ./$< +run: out/${NS}/a.out out/assets.res + ./$^ clean: ${RM} -r out/${NS}/ @@ -39,7 +39,7 @@ out/${NS}/incbin.o: src/incbin.s | out/${NS}/ out/${NS}/%.d: src/%.c | out/${NS}/ ${CC} ${cflags} ${CPPFLAGS} -MM -MG -MF $@ -MT "${@:.d=.o} $@" $< -out/${NS}/a.out: ${objs} out/${NS}/incbin.o | out/${NS}/ out/assets.res +out/${NS}/a.out: ${objs} out/${NS}/incbin.o | out/${NS}/ ${CC} -o $@ $^ ${cflags} ${ldflags} include assets.mk diff --git a/build.sh b/build.sh index 3a08184..7f72b4d 100755 --- a/build.sh +++ b/build.sh @@ -5,7 +5,7 @@ case $1 in NS=gl CFLAGS='-g1 -Os' make ;; ms-windows) - NS=w CFLAGS='-g1 -Os' CC='x86_64-w64-mingw32-cc' make + NS=w CFLAGS='-g1 -Os -mwindows' CC='x86_64-w64-mingw32-cc' make ;; leak) NS=leak CC='cc -fsanitize=leak' CFLAGS='-g -O0' make diff --git a/src/entity.h b/src/entity.h index 5b34bac..52a2eac 100644 --- a/src/entity.h +++ b/src/entity.h @@ -2,6 +2,9 @@ #include "loader.h" +#define from_fixed(a) (a / 16) +#define to_fixed(a) (a * 16) + struct entity { int (*update)(struct entity *self); int (*hurt)(struct entity *self, int damage); diff --git a/src/main.c b/src/main.c index 0e53a68..b2244d2 100644 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,8 @@ #include "main.h" +#include <getopt.h> + SDL_Window *window = NULL; SDL_Renderer *renderer = NULL; @@ -37,14 +39,109 @@ struct entity player[1] = {0}; struct entity *player_new(void); int player_property(struct entity *const restrict entity, char const *const restrict property, char const *const restrict value); -int main(int argc, char **argv) { +int main(int const argc, char *const *const argv) { + struct option opts[] = { + {"help", 0, NULL, 'h'}, + {"scale", 1, NULL, 's'}, + {"resizable", 2, NULL, 'r'}, + {"fullscreen", 2, NULL, 'f'}, + {"maximize", 2, NULL, 'm'}, + {"border", 2, NULL, 'b'}, + {NULL, 0, NULL, 0 }, + }; + int opt, li; + unsigned scale = 0, flags = 0, error = 0; + while ((opt = getopt_long(argc, argv, "h", opts, &li)) != -1) { + switch (opt) { + case 'h': + printf("usage:\n\t%s\n\t%s [mod.zip]\n", argv[0], argv[0]); + return 0; + + case 's': + scale = atoi(optarg); + break; + + case 'r': + if (optarg == NULL || strcmp(optarg, "true") == 0) { + flags |= SDL_WINDOW_RESIZABLE; + } else if (strcmp(optarg, "false") == 0) { + flags &= ~SDL_WINDOW_RESIZABLE; + } else { + fprintf(stderr, "%s=%s -- expected 'true' or 'false'\n", opts[li].name, optarg); + error = 1; + } + break; + + case 'f': + if (optarg == NULL || strcmp(optarg, "true") == 0) { + flags |= SDL_WINDOW_FULLSCREEN; + } else if (strcmp(optarg, "false") == 0) { + flags &= ~SDL_WINDOW_FULLSCREEN; + } else { + fprintf(stderr, "%s=%s -- expected 'true' or 'false'\n", opts[li].name, optarg); + error = 1; + } + break; + + case 'm': + if (optarg == NULL || strcmp(optarg, "true") == 0) { + flags |= SDL_WINDOW_MAXIMIZED; + } else if (strcmp(optarg, "false") == 0) { + flags &= ~SDL_WINDOW_MAXIMIZED; + } else { + fprintf(stderr, "%s=%s -- expected 'true' or 'false'\n", opts[li].name, optarg); + error = 1; + } + break; + + case 'b': + if (optarg == NULL || strcmp(optarg, "true") == 0) { + flags &= ~SDL_WINDOW_BORDERLESS; + } else if (strcmp(optarg, "false") == 0) { + flags |= SDL_WINDOW_BORDERLESS; + } else { + fprintf(stderr, "%s=%s -- expected 'true' or 'false'\n", opts[li].name, optarg); + error = 1; + } + break; + + default: + error = 1; + } + } + if (error) { + return EXIT_FAILURE; + } + if (SDL_Init(INIT_SUBSYSTEMS)) { fprintf(stderr, "failed to initialize SDL2: %s\n", SDL_GetError()); return EXIT_FAILURE; } SDL_StopTextInput(); + if (scale == 0) { + SDL_DisplayMode dm; + if (SDL_GetDesktopDisplayMode(0, &dm) != 0) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "couldnt get desktop size", SDL_GetError(), NULL); + fprintf(stderr, "info: couldnt get desktop size %s\n", SDL_GetError()); + flags |= SDL_WINDOW_RESIZABLE; + } else { + int x = dm.w / 2 / WINDOW_WIDTH; + int y = dm.h / 2 / WINDOW_HEIGHT; + if (x < y) { + scale = x; + } else { + scale = y; + } + if (scale == 0) { + scale = 1; + } + if (dm.refresh_rate != 60) { + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "refresh rate", "this game currently only runs well on 60Hz displays", NULL); + } + } + } - window = SDL_CreateWindow(":3", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN); + window = SDL_CreateWindow(":3", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH * scale, WINDOW_HEIGHT * scale, flags | SDL_WINDOW_HIDDEN); if (window == NULL) { goto end; } @@ -57,13 +154,23 @@ int main(int argc, char **argv) { { res_init(); - void *a = util_executableRelativePath("assets.res", *argv, 0); - puts(a); - if (loadResources(a)) { - fputs("loading resources failed\n", stderr); - return 1; + if (optind == argc) { + void *a = util_executableRelativePath("assets.res", *argv, 0); + puts(a); + if (loadResources(a)) { + fputs("loading resources failed\n", stderr); + return 1; + } + free(a); + } else { + while (optind < argc) { + if (loadResources(argv[optind])) { + fprintf(stderr, "loading %s failed\n", argv[optind]); + return 1; + } + optind++; + } } - free(a); struct blob map = res_get_map("untitled"); tilemap = tilemap_load(map.data, map.size); //memmem(map.data + tilemap->byte_count, map.size - tilemap->byte_count, (char []) {0, 0}, 2); @@ -71,7 +178,7 @@ int main(int argc, char **argv) { SDL_SetRenderTarget(renderer, NULL); } - unsigned error; + /* unsigned error; // identical variable is declared higher up */ 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)); diff --git a/src/player.c b/src/player.c index 9eed3a8..2e0346d 100644 --- a/src/player.c +++ b/src/player.c @@ -4,9 +4,6 @@ #include "tilemap.h" #include <stdbool.h> -#define from_fixed(a) (a / 16) -#define to_fixed(a) (a * 16) - #define SIZE 8 #define ACCELERATION 1 #define FRICTION 2 diff --git a/src/tilemap.c b/src/tilemap.c index 7dbc4dd..ea53e2f 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -114,6 +114,9 @@ struct tilemap *tilemap_load(void *data, size_t size) { struct sets *const sets = data; data = sets + 1; + if (size < sizeof (struct sets)) { + return NULL; + } size -= sizeof (struct sets); if (memcmp(sets->magic, MAGIC, sizeof (MAGIC)) != 0) { diff --git a/src/util.c b/src/util.c index f6b00a9..21aeb22 100644 --- a/src/util.c +++ b/src/util.c @@ -51,7 +51,7 @@ void *util_loadFile(FILE *const restrict file, size_t *const restrict outsize) { #define DIR_SEPARATOR '\\' // DOS #endif -char *util_executableRelativePath(char *path, char *execPath, size_t dirLength) { // allocated on the heap +char *util_executableRelativePath(char const *const path, char const *const execPath, size_t dirLength) { // allocated on the heap dirLength = 0; if (dirLength == 0) { for (dirLength = strlen(execPath); dirLength > 0 && execPath[dirLength - 1] != DIR_SEPARATOR; dirLength--) diff --git a/src/util.h b/src/util.h index 9e882fc..2a9f689 100644 --- a/src/util.h +++ b/src/util.h @@ -1,4 +1,4 @@ #pragma once void *util_loadFile(FILE *const restrict file, size_t *const restrict outsize); -char *util_executableRelativePath(char *path, char *execPath, size_t dirLength); // allocated on the heap +char *util_executableRelativePath(char const *const path, char const *const execPath, size_t dirLength); // allocated on the heap |