diff --git a/src/gamestate.h b/src/gamestate.h index 9949495..5410fb4 100644 --- a/src/gamestate.h +++ b/src/gamestate.h @@ -26,6 +26,7 @@ struct Gamestate_API { void (*Gamestate_Draw)(struct Game* game, void* data); void (*Gamestate_Logic)(struct Game* game, void* data, double delta); + void (*Gamestate_Tick)(struct Game* game, void* data); void* (*Gamestate_Load)(struct Game* game, void (*progress)(struct Game* game)); void (*Gamestate_PostLoad)(struct Game* game, void* data); diff --git a/src/internal.c b/src/internal.c index 1d872a5..f7de112 100644 --- a/src/internal.c +++ b/src/internal.c @@ -42,7 +42,7 @@ SYMBOL_INTERNAL void DrawGamestates(struct Game* game) { } struct Gamestate* tmp = game->_priv.gamestates; if (game->handlers.predraw) { - (*game->handlers.predraw)(game); + game->handlers.predraw(game); } while (tmp) { if ((tmp->loaded) && (tmp->started)) { @@ -51,7 +51,7 @@ SYMBOL_INTERNAL void DrawGamestates(struct Game* game) { if (game->handlers.compositor) { // don't clear when uncomposited al_clear_to_color(al_map_rgb(0, 0, 0)); // even if everything is going to be redrawn, it optimizes tiled rendering } - (*tmp->api->Gamestate_Draw)(game, tmp->data); + tmp->api->Gamestate_Draw(game, tmp->data); // TODO: save and restore more state for careless gamestating } tmp = tmp->next; @@ -71,24 +71,37 @@ SYMBOL_INTERNAL void DrawGamestates(struct Game* game) { game->handlers.compositor(game, game->_priv.gamestates); } if (game->handlers.postdraw) { - (*game->handlers.postdraw)(game); + game->handlers.postdraw(game); } } SYMBOL_INTERNAL void LogicGamestates(struct Game* game, double delta) { struct Gamestate* tmp = game->_priv.gamestates; if (game->handlers.prelogic) { - (*game->handlers.prelogic)(game, delta); + game->handlers.prelogic(game, delta); } while (tmp) { if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) { game->_priv.current_gamestate = tmp; - (*tmp->api->Gamestate_Logic)(game, tmp->data, delta); + tmp->api->Gamestate_Logic(game, tmp->data, delta); } tmp = tmp->next; } if (game->handlers.postlogic) { - (*game->handlers.postlogic)(game, delta); + game->handlers.postlogic(game, delta); + } +} + +SYMBOL_INTERNAL void TickGamestates(struct Game* game) { + struct Gamestate* tmp = game->_priv.gamestates; + while (tmp) { + if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) { + game->_priv.current_gamestate = tmp; + if (tmp->api->Gamestate_Tick) { + tmp->api->Gamestate_Tick(game, tmp->data); + } + } + tmp = tmp->next; } } @@ -99,7 +112,7 @@ SYMBOL_INTERNAL void ReloadGamestates(struct Game* game) { if (tmp->loaded) { game->_priv.current_gamestate = tmp; if (tmp->api->Gamestate_Reload) { - (*tmp->api->Gamestate_Reload)(game, tmp->data); + tmp->api->Gamestate_Reload(game, tmp->data); } } tmp = tmp->next; @@ -111,7 +124,7 @@ SYMBOL_INTERNAL void EventGamestates(struct Game* game, ALLEGRO_EVENT* ev) { while (tmp) { if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) { game->_priv.current_gamestate = tmp; - (*tmp->api->Gamestate_ProcessEvent)(game, tmp->data, ev); + tmp->api->Gamestate_ProcessEvent(game, tmp->data, ev); } tmp = tmp->next; } @@ -215,7 +228,7 @@ SYMBOL_INTERNAL void* GamestateLoadingThread(void* arg) { struct GamestateLoadingThreadData* data = arg; data->game->_priv.loading.inProgress = true; al_set_new_bitmap_flags(data->bitmap_flags); - data->gamestate->data = (*data->gamestate->api->Gamestate_Load)(data->game, &GamestateProgress); + data->gamestate->data = data->gamestate->api->Gamestate_Load(data->game, &GamestateProgress); if (data->game->_priv.loading.progress != data->gamestate->progressCount) { PrintConsole(data->game, "[%s] WARNING: Gamestate_ProgressCount does not match the number of progress invokations (%d)!", data->gamestate->name, data->game->_priv.loading.progress); if (data->game->config.debug) { @@ -268,8 +281,8 @@ SYMBOL_INTERNAL void GamestateProgress(struct Game* game) { DrawGamestates(game); 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); + 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); } game->_priv.loading.time += delta; DrawConsole(game); @@ -311,6 +324,7 @@ SYMBOL_INTERNAL bool LinkGamestate(struct Game* game, struct Gamestate* gamestat if (!(gamestate->api->Gamestate_ProcessEvent = dlsym(gamestate->handle, "Gamestate_ProcessEvent"))) { GS_ERROR; } // optional + gamestate->api->Gamestate_Tick = dlsym(gamestate->handle, "Gamestate_Tick"); gamestate->api->Gamestate_PostLoad = dlsym(gamestate->handle, "Gamestate_PostLoad"); gamestate->api->Gamestate_Pause = dlsym(gamestate->handle, "Gamestate_Pause"); gamestate->api->Gamestate_Resume = dlsym(gamestate->handle, "Gamestate_Resume"); diff --git a/src/internal.h b/src/internal.h index eb78bf8..9268a62 100644 --- a/src/internal.h +++ b/src/internal.h @@ -71,6 +71,7 @@ struct ScreenshotThreadData { void SimpleCompositor(struct Game* game, struct Gamestate* gamestates); void DrawGamestates(struct Game* game); void LogicGamestates(struct Game* game, double delta); +void TickGamestates(struct Game* game); void EventGamestates(struct Game* game, ALLEGRO_EVENT* ev); void ReloadGamestates(struct Game* game); void FreezeGamestates(struct Game* game); diff --git a/src/libsuperderpy.c b/src/libsuperderpy.c index 0ec5cbe..713a369 100644 --- a/src/libsuperderpy.c +++ b/src/libsuperderpy.c @@ -344,8 +344,6 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game* game) { return 0; } -bool redraw = false; - SYMBOL_INTERNAL void libsuperderpy_mainloop_exit(struct Game* game) { libsuperderpy_destroy(game); free(game); @@ -355,17 +353,13 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop_exit(struct Game* game) { SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) { struct Game* game = (struct Game*)g; - redraw = true; - while (!al_is_event_queue_empty(game->_priv.event_queue) || redraw) { -#else - bool redraw = false; - while (1) { #endif + do { ClearGarbage(game); // TODO: split mainloop to functions to make it readable ALLEGRO_EVENT ev; - if (game->_priv.draw && (((redraw || true) && al_is_event_queue_empty(game->_priv.event_queue)) || (game->_priv.gamestate_scheduled))) { + if (game->_priv.draw && ((al_is_event_queue_empty(game->_priv.event_queue)) || (game->_priv.gamestate_scheduled))) { game->_priv.gamestate_scheduled = false; struct Gamestate* tmp = game->_priv.gamestates; @@ -524,12 +518,13 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) { LogicGamestates(game, delta); DrawGamestates(game); } - //redraw = true; DrawConsole(game); - //al_wait_for_vsync(); al_flip_display(); - redraw = false; + +#ifdef __EMSCRIPTEN__ + return; +#endif } else { #ifdef __EMSCRIPTEN__ @@ -547,10 +542,7 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) { } if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game->_priv.timer)) { - /*double delta = al_get_time() - game->_priv.timestamp; - game->_priv.timestamp += delta; - LogicGamestates(game, delta); - redraw = true;*/ + TickGamestates(game); } else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { #ifdef __EMSCRIPTEN__ libsuperderpy_mainloop_exit(game); @@ -638,7 +630,7 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) { } EventGamestates(game, &ev); } - } + } while (true); #ifndef __EMSCRIPTEN__ if (game->handlers.destroy) {