synchronize with the main thread on BSoD

This commit is contained in:
Sebastian Krzyszkowiak 2018-12-02 00:26:33 +01:00
parent d5d923daa6
commit 2179d6cdc2
No known key found for this signature in database
GPG key ID: E8F235CF3BDBC3FF
4 changed files with 45 additions and 2 deletions

View file

@ -105,6 +105,10 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
game->_priv.texture_sync_cond = al_create_cond();
game->_priv.texture_sync_mutex = al_create_mutex();
game->_priv.in_bsod = false;
game->_priv.bsod_cond = al_create_cond();
game->_priv.bsod_mutex = al_create_mutex();
game->config.fullscreen = strtol(GetConfigOptionDefault(game, "SuperDerpy", "fullscreen", "1"), NULL, 10);
game->config.music = strtol(GetConfigOptionDefault(game, "SuperDerpy", "music", "10"), NULL, 10);
game->config.voice = strtol(GetConfigOptionDefault(game, "SuperDerpy", "voice", "10"), NULL, 10);
@ -488,6 +492,8 @@ SYMBOL_EXPORT void libsuperderpy_destroy(struct Game* game) {
al_destroy_voice(game->audio.v); // FIXME: doesn't seem to work in Chromium under Emscripten
al_destroy_cond(game->_priv.texture_sync_cond);
al_destroy_mutex(game->_priv.texture_sync_mutex);
al_destroy_cond(game->_priv.bsod_cond);
al_destroy_mutex(game->_priv.bsod_mutex);
al_uninstall_audio();
DeinitConfig(game);
#ifndef __EMSCRIPTEN__

View file

@ -164,6 +164,11 @@ struct Game {
ALLEGRO_MUTEX* texture_sync_mutex;
ALLEGRO_COND* texture_sync_cond;
volatile bool in_bsod;
volatile bool bsod_sync;
ALLEGRO_MUTEX* bsod_mutex;
ALLEGRO_COND* bsod_cond;
struct {
bool verbose, livereload, autopause;
} debug;

View file

@ -269,6 +269,20 @@ static inline bool MainloopTick(struct Game* game) {
}
DrawConsole(game);
al_flip_display();
#ifndef LIBSUPERDERPY_SINGLE_THREAD
if (game->_priv.bsod_sync) {
al_set_target_bitmap(NULL);
game->_priv.bsod_sync = false;
al_signal_cond(game->_priv.bsod_cond);
}
al_lock_mutex(game->_priv.bsod_mutex);
while (game->_priv.in_bsod) {
al_wait_cond(game->_priv.bsod_cond, game->_priv.bsod_mutex);
}
al_unlock_mutex(game->_priv.bsod_mutex);
#endif
}
#else
GamestateLoadingThread(&data);

View file

@ -217,7 +217,19 @@ SYMBOL_EXPORT void FatalErrorWithContext(struct Game* game, int line, const char
va_end(vl);
fprintf(stderr, "%s:%d [%s]\n%s\n", file, line, func, text);
// TODO: synchronize with loading thread
#ifndef LIBSUPERDERPY_SINGLE_THREAD
if (game->_priv.loading.inProgress) {
al_lock_mutex(game->_priv.bsod_mutex);
game->_priv.in_bsod = true;
game->_priv.bsod_sync = true;
while (game->_priv.bsod_sync) {
al_wait_cond(game->_priv.bsod_cond, game->_priv.bsod_mutex);
}
al_unlock_mutex(game->_priv.bsod_mutex);
}
#endif
al_set_target_backbuffer(game->display);
ALLEGRO_TRANSFORM trans;
al_identity_transform(&trans);
@ -227,7 +239,6 @@ SYMBOL_EXPORT void FatalErrorWithContext(struct Game* game, int line, const char
game->_priv.font_bsod = al_create_builtin_font();
}
al_set_target_backbuffer(game->display);
al_clear_to_color(al_map_rgb(0, 0, 170));
al_flip_display();
al_rest(0.6);
@ -309,6 +320,13 @@ SYMBOL_EXPORT void FatalErrorWithContext(struct Game* game, int line, const char
#endif
}
al_use_transform(&game->projection);
#ifndef LIBSUPERDERPY_SINGLE_THREAD
if (game->_priv.loading.inProgress) {
PrintConsole(game, "Resuming the main thread...");
game->_priv.in_bsod = false;
al_signal_cond(game->_priv.bsod_cond);
}
#endif
}
static void TestPath(const char* filename, const char* subpath, char** result) {