Mercurial > molko
changeset 248:37771eaf4245
core: use vsync and improve game loop
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 01 Dec 2020 12:56:11 +0100 |
parents | e8d6754984dd |
children | f4dc208aa1e3 |
files | libmlk-core/core/game.c libmlk-core/core/window.c libmlk-core/core/window.h |
diffstat | 3 files changed, 39 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/libmlk-core/core/game.c Tue Dec 01 12:55:55 2020 +0100 +++ b/libmlk-core/core/game.c Tue Dec 01 12:56:11 2020 +0100 @@ -26,6 +26,7 @@ #include "state.h" #include "painter.h" #include "util.h" +#include "window.h" struct game game; @@ -103,8 +104,14 @@ game_loop(void) { struct clock clock = {0}; - double frametimemax = 1000.0 / 60.0; - unsigned int frametime = 0; + unsigned int elapsed = 0; + unsigned int frametime; + + if (window.framerate > 0) + frametime = 1000 / window.framerate; + else + /* Assuming 50.0 FPS. */ + frametime = 1000.0 / 50.0; while (game.state) { clock_start(&clock); @@ -112,17 +119,17 @@ for (union event ev; event_poll(&ev); ) game_handle(&ev); - game_update(frametime); + game_update(elapsed); game_draw(); /* - * Sleep not the full left time to allow context switches and - * such. + * If vsync is enabled, it should have wait, otherwise sleep + * a little to save CPU cycles. */ - if (frametime < frametimemax) - delay((frametimemax - frametime) / 4); + if ((elapsed = clock_elapsed(&clock)) < frametime) + delay(frametime - elapsed); - frametime = clock_elapsed(&clock); + elapsed = clock_elapsed(&clock); } }
--- a/libmlk-core/core/window.c Tue Dec 01 12:55:55 2020 +0100 +++ b/libmlk-core/core/window.c Tue Dec 01 12:56:11 2020 +0100 @@ -50,6 +50,15 @@ } static void +load_framerate(void) +{ + SDL_DisplayMode mode; + + if (SDL_GetWindowDisplayMode(handle.win, &mode) == 0) + window.framerate = mode.refresh_rate; +} + +static void finish_cursors(void) { for (size_t i = 0; i < NELEM(cursors); ++i) @@ -57,20 +66,30 @@ SDL_FreeCursor(cursors[i]); } +static bool +load_window(const char *title, unsigned int w, unsigned int h) +{ + return (handle.win = SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, 0)); +} + +static bool +load_renderer(void) +{ + return (handle.renderer = SDL_CreateRenderer(handle.win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)); +} + bool window_open(const char *title, unsigned int w, unsigned int h) { assert(title); - if (SDL_CreateWindowAndRenderer(w, h, SDL_WINDOW_OPENGL, - &handle.win, &handle.renderer) < 0) + if (!load_window(title, w, h) || !load_renderer()) return errorf("%s", SDL_GetError()); - SDL_SetWindowTitle(handle.win, title); - window.w = w; window.h = h; + load_framerate(); load_cursors(); return true;
--- a/libmlk-core/core/window.h Tue Dec 01 12:55:55 2020 +0100 +++ b/libmlk-core/core/window.h Tue Dec 01 12:56:11 2020 +0100 @@ -33,6 +33,7 @@ struct window { unsigned int w; /*!< (-) Window width. */ unsigned int h; /*!< (-) Window height. */ + unsigned int framerate; /*!< (-) Device screen refresh rate. */ void *handle; /*!< (*) Native handle. */ };