From 3938a78503c8099b409f4cb5e511464d1fb70b22 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Mon, 16 Apr 2018 01:06:58 +0200 Subject: [PATCH] live reloading --- src/internal.c | 30 +++++++++++++++++++++++++----- src/internal.h | 2 ++ src/libsuperderpy.c | 20 +++++++++++++++++--- src/libsuperderpy.h | 2 ++ 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/internal.c b/src/internal.c index 736c460..bfb720b 100644 --- a/src/internal.c +++ b/src/internal.c @@ -267,6 +267,11 @@ SYMBOL_INTERNAL bool OpenGamestate(struct Game* game, struct Gamestate* gamestat FatalError(game, false, "Error while opening gamestate \"%s\": %s", gamestate->name, dlerror()); // TODO: move out return false; } + if (game->handlers.compositor) { + gamestate->fb = CreateNotPreservedBitmap(game->_priv.clip_rect.w, game->_priv.clip_rect.h); + } else { + gamestate->fb = al_create_sub_bitmap(al_get_backbuffer(game->display), game->_priv.clip_rect.x, game->_priv.clip_rect.y, game->_priv.clip_rect.w, game->_priv.clip_rect.h); + } return true; } @@ -312,11 +317,6 @@ SYMBOL_INTERNAL struct Gamestate* AllocateGamestate(struct Game* game, const cha tmp->pending_unload = false; tmp->next = NULL; tmp->api = NULL; - if (game->handlers.compositor) { - tmp->fb = CreateNotPreservedBitmap(game->_priv.clip_rect.w, game->_priv.clip_rect.h); - } else { - tmp->fb = al_create_sub_bitmap(al_get_backbuffer(game->display), game->_priv.clip_rect.x, game->_priv.clip_rect.y, game->_priv.clip_rect.w, game->_priv.clip_rect.h); - } return tmp; } @@ -489,3 +489,23 @@ SYMBOL_INTERNAL char* GetLibraryPath(struct Game* game, char* filename) { al_destroy_path(path); return result; } + +SYMBOL_INTERNAL void PauseExecution(struct Game* game) { + game->_priv.paused = true; + PrintConsole(game, "DEBUG: game execution paused."); +} + +SYMBOL_INTERNAL void ResumeExecution(struct Game* game) { + PrintConsole(game, "DEBUG: reloading the gamestates..."); + struct Gamestate* tmp = game->_priv.gamestates; + while (tmp) { + char* name = strdup(tmp->name); + CloseGamestate(game, tmp); + tmp->name = name; + OpenGamestate(game, tmp); + LinkGamestate(game, tmp); + tmp = tmp->next; + } + game->_priv.paused = false; + PrintConsole(game, "DEBUG: game execution resumed."); +} diff --git a/src/internal.h b/src/internal.h index 1938547..8ff57cb 100644 --- a/src/internal.h +++ b/src/internal.h @@ -89,5 +89,7 @@ bool LinkGamestate(struct Game* game, struct Gamestate* gamestate); void CloseGamestate(struct Game* game, struct Gamestate* gamestate); struct Gamestate* AllocateGamestate(struct Game* game, const char* name); char* GetLibraryPath(struct Game* game, char* filename); +void PauseExecution(struct Game* game); +void ResumeExecution(struct Game* game); #endif diff --git a/src/libsuperderpy.c b/src/libsuperderpy.c index 4c2d5fc..cffc131 100644 --- a/src/libsuperderpy.c +++ b/src/libsuperderpy.c @@ -74,6 +74,8 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* game->_priv.garbage = NULL; game->_priv.timelines = NULL; + game->_priv.paused = false; + game->handlers.event = NULL; game->handlers.destroy = NULL; game->handlers.compositor = NULL; @@ -463,10 +465,12 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) { double delta = al_get_time() - game->_priv.timestamp; game->_priv.timestamp += delta; delta *= ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game->_priv.timer) / (1 / 60.f)); - LogicGamestates(game, delta); + if (!game->_priv.paused) { + LogicGamestates(game, delta); + DrawGamestates(game); + } //redraw = true; - DrawGamestates(game); DrawConsole(game); //al_wait_for_vsync(); al_flip_display(); @@ -516,6 +520,10 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) { al_acknowledge_resize(game->display); SetupViewport(game, game->viewport_config); ResizeGamestates(game); + } else if ((game->config.debug) && (ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_OUT)) { + PauseExecution(game); + } else if ((game->config.debug) && (ev.type == ALLEGRO_EVENT_DISPLAY_SWITCH_IN)) { + ResumeExecution(game); } #ifdef ALLEGRO_ANDROID else if ((ev.type == ALLEGRO_EVENT_KEY_CHAR) && ((ev.keyboard.keycode == ALLEGRO_KEY_MENU) || (ev.keyboard.keycode == ALLEGRO_KEY_TILDE) || (ev.keyboard.keycode == ALLEGRO_KEY_BACKQUOTE))) { @@ -529,10 +537,16 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) { } else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F1)) { int i; for (i = 0; i < 512; i++) { - LogicGamestates(game, ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game->_priv.timer))); + LogicGamestates(game, 1.0 / 60.0); } game->_priv.showconsole = true; PrintConsole(game, "DEBUG: 512 frames skipped..."); + } else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F9)) { + if (game->_priv.paused) { + PauseExecution(game); + } else { + ResumeExecution(game); + } } else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F10)) { double speed = ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game->_priv.timer)); // inverting speed -= 10; diff --git a/src/libsuperderpy.h b/src/libsuperderpy.h index 6ec5a94..8664ff6 100644 --- a/src/libsuperderpy.h +++ b/src/libsuperderpy.h @@ -132,6 +132,8 @@ struct Game { int w, h; } clip_rect; + bool paused; + #ifdef ALLEGRO_MACOSX char cwd[MAXPATHLEN]; #endif