summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c100
1 files changed, 78 insertions, 22 deletions
diff --git a/src/main.c b/src/main.c
index 41c239b..922ca20 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,8 +4,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <inttypes.h>
-#include <errno.h>
+#include <errno.h> // ENOENT
+#include <math.h> // used by vk2dSleep
#include "input.h"
#include "loader.h"
@@ -14,8 +14,8 @@
#include "tilemap.h"
-#include "incbin.h"
-#include "libplum.h"
+#include "incbin.h" // game icon
+#include "libplum.h" // decoding game icon
#include "main.h"
@@ -240,10 +240,19 @@ int game_load_level(char *level) {
game_state = STATE_FADE_OUT;
fade = 255;
- int x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2);
- int y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2);
- 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;}
+ int x, y;
+ if (tilemap->width < WINDOW_WIDTH / 8) {
+ x = -((WINDOW_WIDTH - tilemap->width * 8) / 2);
+ } else {
+ x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2);
+ if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > tilemap->width * 8) {x = tilemap->width * 8 - WINDOW_WIDTH;}
+ }
+ if (tilemap->height <= WINDOW_HEIGHT / 8) {
+ y = -((WINDOW_HEIGHT - tilemap->height * 8) / 2);
+ } else {
+ y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2);
+ if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > tilemap->height * 8) {y = tilemap->height * 8 - WINDOW_HEIGHT;}
+ }
game_render(framebuffer, x, y);
SDL_SetRenderTarget(renderer, NULL);
@@ -264,6 +273,27 @@ void game_render_flush(SDL_Texture *framebuffer) {
SDL_RenderPresent(renderer);
}
+// from libertea / <https://github.com/PaoloMazzon>
+double getTime(void) {
+ static double time = -1;
+ if (time == -1)
+ time = SDL_GetPerformanceCounter();
+ return (double)(SDL_GetPerformanceCounter() - time) / SDL_GetPerformanceFrequency();
+}
+
+// also from libertea / <https://github.com/PaoloMazzon>
+void vk2dSleep(double seconds) {
+ if (seconds <= 0)
+ return;
+ double start = SDL_GetPerformanceCounter();
+ double milliseconds = floor(seconds * 1000);
+ SDL_Delay(milliseconds);
+ while ((SDL_GetPerformanceCounter() - start) / (double)SDL_GetPerformanceFrequency() < seconds) {
+ volatile int i = 0;
+ (void) i;
+ }
+}
+
int main(int const argc, char *const *const argv) {
save_file_name = SDL_GetPrefPath("sylvie", "game");
save_file_name = SDL_realloc(save_file_name, strlen(save_file_name) + strlen("save.sav") + 1);
@@ -349,12 +379,13 @@ int main(int const argc, char *const *const argv) {
#if defined(__EMSCRIPTEN__)
scale = 1;
#else
- if (scale <= 0) { // this looks very wrong
+ if (scale <= 0) { // because we used atoi, the user can set scale to -1 or something
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());
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "couldnt get desktop size", SDL_GetError(), NULL);
+ fprintf(stderr, "warn: couldnt get desktop size %s\n", SDL_GetError());
flags |= SDL_WINDOW_RESIZABLE;
+ scale = 3;
} else {
int x = dm.w / 2 / WINDOW_WIDTH;
int y = dm.h / 2 / WINDOW_HEIGHT;
@@ -366,8 +397,10 @@ int main(int const argc, char *const *const argv) {
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);
+ if (dm.refresh_rate < 59) {
+ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_WARNING, "refresh rate", "your monitor appears to have a refresh rate below 60Hz, the game will run slower\n"
+ "you can compile the game from source to disable vsync, unlocking the framerate\n"
+ "TODO: disabling vsync without a recompile", NULL);
}
}
}
@@ -375,12 +408,15 @@ int main(int const argc, char *const *const argv) {
window = SDL_CreateWindow(":3", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH * scale, WINDOW_HEIGHT * scale, flags | SDL_WINDOW_HIDDEN);
if (window == NULL) {
+ fprintf(stderr, "failed to create the game window: %s\n", SDL_GetError());
goto end;
}
+ SDL_SetWindowMinimumSize(window, WINDOW_WIDTH, WINDOW_HEIGHT);
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); // hack, i dont wanna deal with windows discarding render textures
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC);
if (renderer == NULL) {
+ fprintf(stderr, "failed to create a rendering context: %s\n", SDL_GetError());
goto end;
}
SDL_RenderSetLogicalSize(renderer, WINDOW_WIDTH, WINDOW_HEIGHT);
@@ -482,6 +518,8 @@ void main_loop(void) {
int x = 0, y = 0;
while (1) {
#endif
+ double const begin_time = getTime();
+
input_pressed = input_held;
SDL_Event evt;
while (SDL_PollEvent(&evt)) {
@@ -551,7 +589,7 @@ void main_loop(void) {
i = evt.tfinger.fingerId;
touch.positions[i].x = evt.tfinger.x;
touch.positions[i].y = evt.tfinger.y;
- printf("%" PRIu64 " %" PRIu64 " %f %f\n", evt.tfinger.touchId, evt.tfinger.fingerId, evt.tfinger.x, evt.tfinger.y);
+ //printf("%" PRIu64 " %" PRIu64 " %f %f\n", evt.tfinger.touchId, evt.tfinger.fingerId, evt.tfinger.x, evt.tfinger.y);
reset_touch:
touch.input_touch = 0;
for (size_t i = 0; i < touch.allocated; i++) {
@@ -654,10 +692,18 @@ void main_loop(void) {
}
}
- x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2);
- y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2);
- 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;}
+ if (tilemap->width < WINDOW_WIDTH / 8) {
+ x = -((WINDOW_WIDTH - tilemap->width * 8) / 2);
+ } else {
+ x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2);
+ if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > tilemap->width * 8) {x = tilemap->width * 8 - WINDOW_WIDTH;}
+ }
+ if (tilemap->height <= WINDOW_HEIGHT / 8) {
+ y = -((WINDOW_HEIGHT - tilemap->height * 8) / 2);
+ } else {
+ y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2);
+ if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > tilemap->height * 8) {y = tilemap->height * 8 - WINDOW_HEIGHT;}
+ }
game_render(framebuffer, x, y);
game_render_flush(framebuffer);
@@ -675,10 +721,18 @@ void main_loop(void) {
if (fade == 255) {
if (game_load_level(game_next_level)) {
game_state = STATE_FADE_OUT;
- x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2);
- y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2);
- 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;}
+ if (tilemap->width < WINDOW_WIDTH / 8) {
+ x = -((WINDOW_WIDTH - tilemap->width * 8) / 2);
+ } else {
+ x = (entities.player[0].x / 16) - (WINDOW_WIDTH / 2);
+ if (x < 0) {x = 0;} else if (x + WINDOW_WIDTH > tilemap->width * 8) {x = tilemap->width * 8 - WINDOW_WIDTH;}
+ }
+ if (tilemap->height <= WINDOW_HEIGHT / 8) {
+ y = -((WINDOW_HEIGHT - tilemap->height * 8) / 2);
+ } else {
+ y = (entities.player[0].y / 16) - (WINDOW_HEIGHT / 2);
+ if (y < 0) {y = 0;} else if (y + WINDOW_HEIGHT > tilemap->height * 8) {y = tilemap->height * 8 - WINDOW_HEIGHT;}
+ }
game_render(framebuffer, x, y);
SDL_SetRenderTarget(renderer, NULL);
@@ -705,6 +759,8 @@ void main_loop(void) {
#if defined(__EMSCRIPTEN__)
return;
#else
+ double const end_time = getTime();
+ vk2dSleep(1.0/60.0 - (end_time - begin_time));
}
#endif