summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
6 files changed, 124 insertions, 14 deletions
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