mirror of
https://gitlab.com/dosowisko.net/libsuperderpy.git
synced 2025-03-04 09:11:27 +01:00
gamestate: add optional Gamestate_Tick function for logic with fixed interval
This commit is contained in:
parent
4c12939afe
commit
9953d3f171
4 changed files with 35 additions and 27 deletions
|
@ -26,6 +26,7 @@
|
||||||
struct Gamestate_API {
|
struct Gamestate_API {
|
||||||
void (*Gamestate_Draw)(struct Game* game, void* data);
|
void (*Gamestate_Draw)(struct Game* game, void* data);
|
||||||
void (*Gamestate_Logic)(struct Game* game, void* data, double delta);
|
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_Load)(struct Game* game, void (*progress)(struct Game* game));
|
||||||
void (*Gamestate_PostLoad)(struct Game* game, void* data);
|
void (*Gamestate_PostLoad)(struct Game* game, void* data);
|
||||||
|
|
|
@ -42,7 +42,7 @@ SYMBOL_INTERNAL void DrawGamestates(struct Game* game) {
|
||||||
}
|
}
|
||||||
struct Gamestate* tmp = game->_priv.gamestates;
|
struct Gamestate* tmp = game->_priv.gamestates;
|
||||||
if (game->handlers.predraw) {
|
if (game->handlers.predraw) {
|
||||||
(*game->handlers.predraw)(game);
|
game->handlers.predraw(game);
|
||||||
}
|
}
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if ((tmp->loaded) && (tmp->started)) {
|
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
|
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
|
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
|
// TODO: save and restore more state for careless gamestating
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
|
@ -71,24 +71,37 @@ SYMBOL_INTERNAL void DrawGamestates(struct Game* game) {
|
||||||
game->handlers.compositor(game, game->_priv.gamestates);
|
game->handlers.compositor(game, game->_priv.gamestates);
|
||||||
}
|
}
|
||||||
if (game->handlers.postdraw) {
|
if (game->handlers.postdraw) {
|
||||||
(*game->handlers.postdraw)(game);
|
game->handlers.postdraw(game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SYMBOL_INTERNAL void LogicGamestates(struct Game* game, double delta) {
|
SYMBOL_INTERNAL void LogicGamestates(struct Game* game, double delta) {
|
||||||
struct Gamestate* tmp = game->_priv.gamestates;
|
struct Gamestate* tmp = game->_priv.gamestates;
|
||||||
if (game->handlers.prelogic) {
|
if (game->handlers.prelogic) {
|
||||||
(*game->handlers.prelogic)(game, delta);
|
game->handlers.prelogic(game, delta);
|
||||||
}
|
}
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||||
game->_priv.current_gamestate = tmp;
|
game->_priv.current_gamestate = tmp;
|
||||||
(*tmp->api->Gamestate_Logic)(game, tmp->data, delta);
|
tmp->api->Gamestate_Logic(game, tmp->data, delta);
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
if (game->handlers.postlogic) {
|
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) {
|
if (tmp->loaded) {
|
||||||
game->_priv.current_gamestate = tmp;
|
game->_priv.current_gamestate = tmp;
|
||||||
if (tmp->api->Gamestate_Reload) {
|
if (tmp->api->Gamestate_Reload) {
|
||||||
(*tmp->api->Gamestate_Reload)(game, tmp->data);
|
tmp->api->Gamestate_Reload(game, tmp->data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
|
@ -111,7 +124,7 @@ SYMBOL_INTERNAL void EventGamestates(struct Game* game, ALLEGRO_EVENT* ev) {
|
||||||
while (tmp) {
|
while (tmp) {
|
||||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||||
game->_priv.current_gamestate = tmp;
|
game->_priv.current_gamestate = tmp;
|
||||||
(*tmp->api->Gamestate_ProcessEvent)(game, tmp->data, ev);
|
tmp->api->Gamestate_ProcessEvent(game, tmp->data, ev);
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
|
@ -215,7 +228,7 @@ SYMBOL_INTERNAL void* GamestateLoadingThread(void* arg) {
|
||||||
struct GamestateLoadingThreadData* data = arg;
|
struct GamestateLoadingThreadData* data = arg;
|
||||||
data->game->_priv.loading.inProgress = true;
|
data->game->_priv.loading.inProgress = true;
|
||||||
al_set_new_bitmap_flags(data->bitmap_flags);
|
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) {
|
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);
|
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) {
|
if (data->game->config.debug) {
|
||||||
|
@ -268,8 +281,8 @@ SYMBOL_INTERNAL void GamestateProgress(struct Game* game) {
|
||||||
DrawGamestates(game);
|
DrawGamestates(game);
|
||||||
double delta = al_get_time() - game->_priv.loading.time;
|
double delta = al_get_time() - game->_priv.loading.time;
|
||||||
if (game->_priv.loading.current->showLoading) {
|
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_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_Draw(game, game->_priv.loading.gamestate->data);
|
||||||
}
|
}
|
||||||
game->_priv.loading.time += delta;
|
game->_priv.loading.time += delta;
|
||||||
DrawConsole(game);
|
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; }
|
if (!(gamestate->api->Gamestate_ProcessEvent = dlsym(gamestate->handle, "Gamestate_ProcessEvent"))) { GS_ERROR; }
|
||||||
|
|
||||||
// optional
|
// optional
|
||||||
|
gamestate->api->Gamestate_Tick = dlsym(gamestate->handle, "Gamestate_Tick");
|
||||||
gamestate->api->Gamestate_PostLoad = dlsym(gamestate->handle, "Gamestate_PostLoad");
|
gamestate->api->Gamestate_PostLoad = dlsym(gamestate->handle, "Gamestate_PostLoad");
|
||||||
gamestate->api->Gamestate_Pause = dlsym(gamestate->handle, "Gamestate_Pause");
|
gamestate->api->Gamestate_Pause = dlsym(gamestate->handle, "Gamestate_Pause");
|
||||||
gamestate->api->Gamestate_Resume = dlsym(gamestate->handle, "Gamestate_Resume");
|
gamestate->api->Gamestate_Resume = dlsym(gamestate->handle, "Gamestate_Resume");
|
||||||
|
|
|
@ -71,6 +71,7 @@ struct ScreenshotThreadData {
|
||||||
void SimpleCompositor(struct Game* game, struct Gamestate* gamestates);
|
void SimpleCompositor(struct Game* game, struct Gamestate* gamestates);
|
||||||
void DrawGamestates(struct Game* game);
|
void DrawGamestates(struct Game* game);
|
||||||
void LogicGamestates(struct Game* game, double delta);
|
void LogicGamestates(struct Game* game, double delta);
|
||||||
|
void TickGamestates(struct Game* game);
|
||||||
void EventGamestates(struct Game* game, ALLEGRO_EVENT* ev);
|
void EventGamestates(struct Game* game, ALLEGRO_EVENT* ev);
|
||||||
void ReloadGamestates(struct Game* game);
|
void ReloadGamestates(struct Game* game);
|
||||||
void FreezeGamestates(struct Game* game);
|
void FreezeGamestates(struct Game* game);
|
||||||
|
|
|
@ -344,8 +344,6 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game* game) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool redraw = false;
|
|
||||||
|
|
||||||
SYMBOL_INTERNAL void libsuperderpy_mainloop_exit(struct Game* game) {
|
SYMBOL_INTERNAL void libsuperderpy_mainloop_exit(struct Game* game) {
|
||||||
libsuperderpy_destroy(game);
|
libsuperderpy_destroy(game);
|
||||||
free(game);
|
free(game);
|
||||||
|
@ -355,17 +353,13 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop_exit(struct Game* game) {
|
||||||
|
|
||||||
SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) {
|
SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) {
|
||||||
struct Game* game = (struct Game*)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
|
#endif
|
||||||
|
do {
|
||||||
ClearGarbage(game);
|
ClearGarbage(game);
|
||||||
|
|
||||||
// TODO: split mainloop to functions to make it readable
|
// TODO: split mainloop to functions to make it readable
|
||||||
ALLEGRO_EVENT ev;
|
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;
|
game->_priv.gamestate_scheduled = false;
|
||||||
struct Gamestate* tmp = game->_priv.gamestates;
|
struct Gamestate* tmp = game->_priv.gamestates;
|
||||||
|
|
||||||
|
@ -524,12 +518,13 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) {
|
||||||
LogicGamestates(game, delta);
|
LogicGamestates(game, delta);
|
||||||
DrawGamestates(game);
|
DrawGamestates(game);
|
||||||
}
|
}
|
||||||
//redraw = true;
|
|
||||||
|
|
||||||
DrawConsole(game);
|
DrawConsole(game);
|
||||||
//al_wait_for_vsync();
|
|
||||||
al_flip_display();
|
al_flip_display();
|
||||||
redraw = false;
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
#ifdef __EMSCRIPTEN__
|
#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)) {
|
if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game->_priv.timer)) {
|
||||||
/*double delta = al_get_time() - game->_priv.timestamp;
|
TickGamestates(game);
|
||||||
game->_priv.timestamp += delta;
|
|
||||||
LogicGamestates(game, delta);
|
|
||||||
redraw = true;*/
|
|
||||||
} else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
|
} else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
libsuperderpy_mainloop_exit(game);
|
libsuperderpy_mainloop_exit(game);
|
||||||
|
@ -638,7 +630,7 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) {
|
||||||
}
|
}
|
||||||
EventGamestates(game, &ev);
|
EventGamestates(game, &ev);
|
||||||
}
|
}
|
||||||
}
|
} while (true);
|
||||||
|
|
||||||
#ifndef __EMSCRIPTEN__
|
#ifndef __EMSCRIPTEN__
|
||||||
if (game->handlers.destroy) {
|
if (game->handlers.destroy) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue