mirror of
https://gitlab.com/dosowisko.net/libsuperderpy.git
synced 2025-02-01 02:56:43 +01:00
don't use timer for ticking; rely on delta instead
Timer was causing an infinite loop in cases where ticking took more time than 1/60 sec.
This commit is contained in:
parent
8d4ee68936
commit
d0316cd789
5 changed files with 18 additions and 45 deletions
|
@ -87,12 +87,19 @@ SYMBOL_INTERNAL void DrawGamestates(struct Game* game) {
|
|||
|
||||
SYMBOL_INTERNAL void LogicGamestates(struct Game* game, double delta) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
int ticks = floor((game->time + delta) / ALLEGRO_BPS_TO_SECS(60.0)) - floor(game->time / ALLEGRO_BPS_TO_SECS(60.0));
|
||||
game->time += delta;
|
||||
if (game->_priv.params.handlers.prelogic) {
|
||||
game->_priv.params.handlers.prelogic(game, delta);
|
||||
}
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused) && (!tmp->pending_stop)) {
|
||||
game->_priv.current_gamestate = tmp;
|
||||
if (tmp->api->tick) {
|
||||
for (int i = 0; i < ticks; i++) {
|
||||
tmp->api->tick(game, tmp->data);
|
||||
}
|
||||
}
|
||||
tmp->api->logic(game, tmp->data, delta);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
|
@ -102,19 +109,6 @@ SYMBOL_INTERNAL void LogicGamestates(struct Game* game, double 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->tick) {
|
||||
tmp->api->tick(game, tmp->data);
|
||||
}
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void ReloadGamestates(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
ReloadShaders(game, true);
|
||||
|
@ -576,7 +570,6 @@ SYMBOL_INTERNAL void PauseExecution(struct Game* game) {
|
|||
return;
|
||||
}
|
||||
game->_priv.paused = true;
|
||||
al_stop_timer(game->_priv.timer);
|
||||
al_detach_voice(game->audio.v);
|
||||
FreezeGamestates(game);
|
||||
PrintConsole(game, "Engine halted.");
|
||||
|
@ -612,7 +605,6 @@ SYMBOL_INTERNAL void ResumeExecution(struct Game* game) {
|
|||
}
|
||||
UnfreezeGamestates(game);
|
||||
al_attach_mixer_to_voice(game->audio.mixer, game->audio.v);
|
||||
al_resume_timer(game->_priv.timer);
|
||||
game->_priv.paused = false;
|
||||
game->_priv.timestamp = al_get_time();
|
||||
PrintConsole(game, "Engine resumed.");
|
||||
|
|
|
@ -90,7 +90,6 @@ struct ScreenshotThreadData {
|
|||
void SimpleCompositor(struct Game* game, struct Gamestate* gamestates, ALLEGRO_BITMAP* loading_fb);
|
||||
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);
|
||||
|
|
|
@ -96,6 +96,8 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
game->_priv.bsod_cond = al_create_cond();
|
||||
game->_priv.bsod_mutex = al_create_mutex();
|
||||
|
||||
game->_priv.speed = ALLEGRO_BPS_TO_SECS(60.0);
|
||||
|
||||
game->_priv.mutex = al_create_mutex();
|
||||
|
||||
game->config.fullscreen = strtol(GetConfigOptionDefault(game, "SuperDerpy", "fullscreen", "1"), NULL, 10);
|
||||
|
@ -338,16 +340,9 @@ SYMBOL_EXPORT int libsuperderpy_start(struct Game* game) {
|
|||
al_register_event_source(game->_priv.event_queue, &(game->event_source));
|
||||
|
||||
al_clear_to_color(al_map_rgb(0, 0, 0));
|
||||
game->_priv.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); // logic timer
|
||||
if (!game->_priv.timer) {
|
||||
FatalError(game, true, "Failed to create logic timer.");
|
||||
return 1;
|
||||
}
|
||||
al_register_event_source(game->_priv.event_queue, al_get_timer_event_source(game->_priv.timer));
|
||||
|
||||
ReloadShaders(game, false);
|
||||
al_flip_display();
|
||||
al_start_timer(game->_priv.timer);
|
||||
|
||||
{
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
|
@ -471,7 +466,6 @@ SYMBOL_EXPORT void libsuperderpy_destroy(struct Game* game) {
|
|||
free(game->_priv.garbage->data);
|
||||
game->_priv.garbage = game->_priv.garbage->next;
|
||||
}
|
||||
al_destroy_timer(game->_priv.timer);
|
||||
Console_Unload(game);
|
||||
al_destroy_display(game->display);
|
||||
al_destroy_user_event_source(&(game->event_source));
|
||||
|
|
|
@ -195,10 +195,11 @@ struct Game {
|
|||
char console[5][1024];
|
||||
unsigned int console_pos;
|
||||
ALLEGRO_EVENT_QUEUE* event_queue; /*!< Main event queue. */
|
||||
ALLEGRO_TIMER* timer; /*!< Main LPS (logic) timer. */
|
||||
bool showconsole; /*!< If true, game console is rendered on screen. */
|
||||
bool showtimeline;
|
||||
|
||||
double speed; /*!< Speed of the game in FPS. 60 == 1x */
|
||||
|
||||
struct {
|
||||
double old_time, fps, time;
|
||||
int frames_done;
|
||||
|
|
|
@ -21,12 +21,6 @@
|
|||
|
||||
static inline void HandleEvent(struct Game* game, ALLEGRO_EVENT* ev) {
|
||||
switch (ev->type) {
|
||||
case ALLEGRO_EVENT_TIMER:
|
||||
if (ev->timer.source == game->_priv.timer) {
|
||||
TickGamestates(game);
|
||||
}
|
||||
break;
|
||||
|
||||
case ALLEGRO_EVENT_DISPLAY_HALT_DRAWING:
|
||||
PauseExecution(game);
|
||||
al_acknowledge_drawing_halt(game->display);
|
||||
|
@ -155,23 +149,23 @@ static inline void HandleDebugEvent(struct Game* game, ALLEGRO_EVENT* ev) {
|
|||
}
|
||||
break;
|
||||
case ALLEGRO_KEY_F9:
|
||||
al_set_timer_speed(game->_priv.timer, ALLEGRO_BPS_TO_SECS(60.0));
|
||||
game->_priv.speed = ALLEGRO_BPS_TO_SECS(60.0);
|
||||
game->_priv.showconsole = true;
|
||||
PrintConsole(game, "DEBUG: Gameplay speed: 1.00x");
|
||||
break;
|
||||
case ALLEGRO_KEY_F10: {
|
||||
double speed = ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game->_priv.timer)); // inverting
|
||||
double speed = ALLEGRO_BPS_TO_SECS(game->_priv.speed); // inverting
|
||||
speed -= 10;
|
||||
if (speed < 10) { speed = 10; }
|
||||
al_set_timer_speed(game->_priv.timer, ALLEGRO_BPS_TO_SECS(speed));
|
||||
game->_priv.speed = ALLEGRO_BPS_TO_SECS(speed);
|
||||
game->_priv.showconsole = true;
|
||||
PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0);
|
||||
} break;
|
||||
case ALLEGRO_KEY_F11: {
|
||||
double speed = ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game->_priv.timer)); // inverting
|
||||
double speed = ALLEGRO_BPS_TO_SECS(game->_priv.speed); // inverting
|
||||
speed += 10;
|
||||
if (speed > 600) { speed = 600; }
|
||||
al_set_timer_speed(game->_priv.timer, ALLEGRO_BPS_TO_SECS(speed));
|
||||
game->_priv.speed = ALLEGRO_BPS_TO_SECS(speed);
|
||||
game->_priv.showconsole = true;
|
||||
PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0);
|
||||
} break;
|
||||
|
@ -274,16 +268,13 @@ static inline bool MainloopTick(struct Game* game) {
|
|||
while (tmp) {
|
||||
if (tmp->pending_unload) {
|
||||
PrintConsole(game, "Unloading gamestate \"%s\"...", tmp->name);
|
||||
al_stop_timer(game->_priv.timer);
|
||||
tmp->loaded = false;
|
||||
tmp->pending_unload = false;
|
||||
game->_priv.current_gamestate = tmp;
|
||||
(*tmp->api->unload)(game, tmp->data);
|
||||
al_resume_timer(game->_priv.timer);
|
||||
PrintConsole(game, "Gamestate \"%s\" unloaded successfully.", tmp->name);
|
||||
}
|
||||
if (tmp->pending_load) {
|
||||
al_stop_timer(game->_priv.timer);
|
||||
if (tmp->show_loading) {
|
||||
(*game->_priv.loading.gamestate->api->start)(game, game->_priv.loading.gamestate->data);
|
||||
}
|
||||
|
@ -373,7 +364,6 @@ static inline bool MainloopTick(struct Game* game) {
|
|||
game->loading.shown = false;
|
||||
}
|
||||
tmp->show_loading = true;
|
||||
al_resume_timer(game->_priv.timer);
|
||||
game->_priv.timestamp = al_get_time();
|
||||
}
|
||||
|
||||
|
@ -394,13 +384,11 @@ static inline bool MainloopTick(struct Game* game) {
|
|||
while (tmp) {
|
||||
if ((tmp->pending_start) && (tmp->loaded)) {
|
||||
PrintConsole(game, "Starting gamestate \"%s\"...", tmp->name);
|
||||
al_stop_timer(game->_priv.timer);
|
||||
game->_priv.current_gamestate = tmp;
|
||||
tmp->started = true;
|
||||
tmp->pending_start = false;
|
||||
|
||||
(*tmp->api->start)(game, tmp->data);
|
||||
al_resume_timer(game->_priv.timer);
|
||||
game->_priv.timestamp = al_get_time();
|
||||
PrintConsole(game, "Gamestate \"%s\" started successfully.", tmp->name);
|
||||
}
|
||||
|
@ -420,8 +408,7 @@ static inline bool MainloopTick(struct Game* game) {
|
|||
|
||||
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));
|
||||
game->time += delta;
|
||||
delta *= ALLEGRO_BPS_TO_SECS(game->_priv.speed / (1 / 60.f));
|
||||
|
||||
#ifdef LIBSUPERDERPY_IMGUI
|
||||
ImGui_ImplAllegro5_NewFrame();
|
||||
|
|
Loading…
Reference in a new issue