summary refs log tree commit diff
diff options
context:
space:
mode:
authorzlago2024-09-30 15:57:29 +0200
committerzlago2024-09-30 15:57:29 +0200
commite4ad2c9362254ab3213c4cb7c743b6bbd72b6346 (patch)
treed839f778a15f65b09fb0f0b773a500168e75afcc
parent45512bbc85188e3adb4eda597d0d2fa5530de651 (diff)
commandline parameters
-rw-r--r--GNUmakefile8
-rwxr-xr-xbuild.sh2
-rw-r--r--src/entity.h3
-rw-r--r--src/main.c125
-rw-r--r--src/player.c3
-rw-r--r--src/tilemap.c3
-rw-r--r--src/util.c2
-rw-r--r--src/util.h2
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