From 6c59ef1049f6ae8603febef86b8a0fa21acc8205 Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Thu, 22 Nov 2018 04:53:51 +0100 Subject: [PATCH] add support for routing the loading gamestate through compositor --- src/internal.c | 24 ++++++++++++++++++++---- src/libsuperderpy.c | 6 ++++++ src/libsuperderpy.h | 3 +-- src/mainloop.c | 10 +++------- src/utils.c | 4 ++-- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/internal.c b/src/internal.c index 84b33ed..ae005cf 100644 --- a/src/internal.c +++ b/src/internal.c @@ -34,6 +34,9 @@ SYMBOL_INTERNAL void SimpleCompositor(struct Game* game, struct Gamestate* games } tmp = tmp->next; } + if (game->_priv.loading.inProgress) { + al_draw_bitmap(game->loading_fb, 0, 0, 0); + } } SYMBOL_INTERNAL void DrawGamestates(struct Game* game) { @@ -57,6 +60,16 @@ SYMBOL_INTERNAL void DrawGamestates(struct Game* game) { tmp = tmp->next; } + if (game->_priv.loading.inProgress) { + // same as above, but for the loading gamestate + game->_priv.current_gamestate = NULL; + SetFramebufferAsTarget(game); + if (game->handlers.compositor) { + al_clear_to_color(al_map_rgb(0, 0, 0)); + } + game->_priv.loading.gamestate->api->Gamestate_Draw(game, game->_priv.loading.gamestate->data); + } + if (game->handlers.compositor) { ALLEGRO_TRANSFORM t; al_set_target_backbuffer(game->display); @@ -163,6 +176,12 @@ SYMBOL_INTERNAL void ResizeGamestates(struct Game* game) { } tmp = tmp->next; } + al_destroy_bitmap(game->loading_fb); + if (game->handlers.compositor) { + game->loading_fb = CreateNotPreservedBitmap(game->_priv.clip_rect.w, game->_priv.clip_rect.h); + } else { + game->loading_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); + } } SYMBOL_INTERNAL void DrawConsole(struct Game* game) { @@ -278,13 +297,10 @@ SYMBOL_INTERNAL void GamestateProgress(struct Game* game) { al_unlock_mutex(game->_priv.texture_sync_mutex); #else al_convert_memory_bitmaps(); - DrawGamestates(game); - SetFramebufferAsTarget(game); - al_clear_to_color(al_map_rgb(0, 0, 0)); double delta = al_get_time() - game->_priv.loading.time; if (game->_priv.loading.current->showLoading) { game->_priv.loading.gamestate->api->Gamestate_Logic(game, game->_priv.loading.gamestate->data, delta); - game->_priv.loading.gamestate->api->Gamestate_Draw(game, game->_priv.loading.gamestate->data); + DrawGamestates(game); } game->_priv.loading.time += delta; DrawConsole(game); diff --git a/src/libsuperderpy.c b/src/libsuperderpy.c index 94cfe43..80976ba 100644 --- a/src/libsuperderpy.c +++ b/src/libsuperderpy.c @@ -317,6 +317,12 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* game->loading_progress = 0; + if (game->handlers.compositor) { + game->loading_fb = CreateNotPreservedBitmap(game->_priv.clip_rect.w, game->_priv.clip_rect.h); + } else { + game->loading_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 game; } diff --git a/src/libsuperderpy.h b/src/libsuperderpy.h index 72ad492..2e49f43 100644 --- a/src/libsuperderpy.h +++ b/src/libsuperderpy.h @@ -110,8 +110,6 @@ struct Game { bool showconsole; /*!< If true, game console is rendered on screen. */ bool showtimeline; - ALLEGRO_BITMAP* fb; /*!< Default framebuffer. */ - struct { double old_time, fps, time; int frames_done; @@ -171,6 +169,7 @@ struct Game { ALLEGRO_EVENT_SOURCE event_source; float loading_progress; + ALLEGRO_BITMAP* loading_fb; struct { bool (*event)(struct Game* game, ALLEGRO_EVENT* ev); diff --git a/src/mainloop.c b/src/mainloop.c index 006b24b..c20d8a4 100644 --- a/src/mainloop.c +++ b/src/mainloop.c @@ -250,16 +250,10 @@ static inline bool MainloopTick(struct Game* game) { #ifndef LIBSUPERDERPY_SINGLE_THREAD al_run_detached_thread(GamestateLoadingThread, &data); while (game->_priv.loading.inProgress) { - DrawGamestates(game); - SetFramebufferAsTarget(game); - al_clear_to_color(al_map_rgb(0, 0, 0)); double delta = al_get_time() - game->_priv.loading.time; if (tmp->showLoading) { (*game->_priv.loading.gamestate->api->Gamestate_Logic)(game, game->_priv.loading.gamestate->data, delta); - (*game->_priv.loading.gamestate->api->Gamestate_Draw)(game, game->_priv.loading.gamestate->data); - if (game->handlers.postdraw) { - game->handlers.postdraw(game); - } + DrawGamestates(game); } game->_priv.loading.time += delta; game->time += delta; // TODO: ability to disable passing time during loading @@ -284,6 +278,8 @@ static inline bool MainloopTick(struct Game* game) { tmp->api->Gamestate_PostLoad(game, tmp->data); } + tmp->showLoading = true; + game->_priv.loading.progress++; CalculateProgress(game); PrintConsole(game, "Gamestate \"%s\" loaded successfully in %f seconds.", tmp->name, al_get_time() - time); diff --git a/src/utils.c b/src/utils.c index 2f2524e..ef93a38 100644 --- a/src/utils.c +++ b/src/utils.c @@ -486,8 +486,8 @@ SYMBOL_EXPORT void WindowCoordsToViewport(struct Game* game, int* x, int* y) { } SYMBOL_EXPORT ALLEGRO_BITMAP* GetFramebuffer(struct Game* game) { - if (game->_priv.loading.inProgress) { - return al_get_backbuffer(game->display); + if (!game->_priv.current_gamestate) { + return game->loading_fb; } return game->_priv.current_gamestate->fb; }