From 9e8290773b29a2cf515f65b2f4997d0e79d57bab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20R=2E=20Miguel?= Date: Sat, 16 May 2020 16:23:23 -0300 Subject: [PATCH] Shutdown subsystems on exit Porting from testing, originally by @fgsfdsfgs --- src/pc/audio/audio_api.h | 1 + src/pc/audio/audio_null.c | 8 ++++++-- src/pc/audio/audio_sdl.c | 14 +++++++++++++- src/pc/controller/controller_api.h | 4 ++++ src/pc/controller/controller_entry_point.c | 7 +++++++ src/pc/controller/controller_keyboard.c | 4 ++++ src/pc/controller/controller_recorded_tas.c | 8 ++++++++ src/pc/controller/controller_sdl.c | 12 ++++++++++++ src/pc/gfx/gfx_opengl.c | 6 +++++- src/pc/gfx/gfx_pc.c | 11 +++++++++++ src/pc/gfx/gfx_pc.h | 1 + src/pc/gfx/gfx_rendering_api.h | 1 + src/pc/gfx/gfx_sdl2.c | 13 ++++++++++++- src/pc/gfx/gfx_window_manager_api.h | 1 + src/pc/pc_main.c | 20 +++++++++++++++----- 15 files changed, 101 insertions(+), 10 deletions(-) diff --git a/src/pc/audio/audio_api.h b/src/pc/audio/audio_api.h index 26794dd6..b40130e0 100644 --- a/src/pc/audio/audio_api.h +++ b/src/pc/audio/audio_api.h @@ -10,6 +10,7 @@ struct AudioAPI { int (*buffered)(void); int (*get_desired_buffered)(void); void (*play)(const uint8_t *buf, size_t len); + void (*shutdown)(void); }; #endif diff --git a/src/pc/audio/audio_null.c b/src/pc/audio/audio_null.c index 8a244e4b..4d0dd923 100644 --- a/src/pc/audio/audio_null.c +++ b/src/pc/audio/audio_null.c @@ -15,9 +15,13 @@ static int audio_null_get_desired_buffered(void) { static void audio_null_play(const uint8_t *buf, size_t len) { } +static void audio_null_shutdown(void) { +} + struct AudioAPI audio_null = { audio_null_init, audio_null_buffered, audio_null_get_desired_buffered, - audio_null_play -}; + audio_null_play, + audio_null_shutdown +}; \ No newline at end of file diff --git a/src/pc/audio/audio_sdl.c b/src/pc/audio/audio_sdl.c index 2f13ccde..beb5a1e6 100644 --- a/src/pc/audio/audio_sdl.c +++ b/src/pc/audio/audio_sdl.c @@ -40,9 +40,21 @@ static void audio_sdl_play(const uint8_t *buf, size_t len) { } } +static void audio_sdl_shutdown(void) +{ + if (SDL_WasInit(SDL_INIT_AUDIO)) { + if (dev != 0) { + SDL_CloseAudioDevice(dev); + dev = 0; + } + SDL_QuitSubSystem(SDL_INIT_AUDIO); + } +} + struct AudioAPI audio_sdl = { audio_sdl_init, audio_sdl_buffered, audio_sdl_get_desired_buffered, - audio_sdl_play + audio_sdl_play, + audio_sdl_shutdown }; \ No newline at end of file diff --git a/src/pc/controller/controller_api.h b/src/pc/controller/controller_api.h index fdd6e503..2f9c1d16 100644 --- a/src/pc/controller/controller_api.h +++ b/src/pc/controller/controller_api.h @@ -13,10 +13,14 @@ struct ControllerAPI { void (*read)(OSContPad *pad); // read controller and update N64 pad values u32 (*rawkey)(void); // returns last pressed virtual key or VK_INVALID if none void (*reconfig)(void); // (optional) call when bindings have changed + void (*shutdown)(void); // (optional) call in osContReset }; // used for binding keys u32 controller_get_raw_key(void); void controller_reconfigure(void); +// calls the shutdown() function of all controller subsystems +void controller_shutdown(void); + #endif diff --git a/src/pc/controller/controller_entry_point.c b/src/pc/controller/controller_entry_point.c index 536b0798..90c10c1d 100644 --- a/src/pc/controller/controller_entry_point.c +++ b/src/pc/controller/controller_entry_point.c @@ -65,6 +65,13 @@ u32 controller_get_raw_key(void) { return VK_INVALID; } +void controller_shutdown(void) { + for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) { + if (controller_implementations[i]->shutdown) + controller_implementations[i]->shutdown(); + } +} + void controller_reconfigure(void) { for (size_t i = 0; i < sizeof(controller_implementations) / sizeof(struct ControllerAPI *); i++) { if (controller_implementations[i]->reconfig) diff --git a/src/pc/controller/controller_keyboard.c b/src/pc/controller/controller_keyboard.c index c9421a24..9fb4b635 100644 --- a/src/pc/controller/controller_keyboard.c +++ b/src/pc/controller/controller_keyboard.c @@ -107,10 +107,14 @@ static u32 keyboard_rawkey(void) { return ret; } +static void keyboard_shutdown(void) { +} + struct ControllerAPI controller_keyboard = { VK_BASE_KEYBOARD, keyboard_init, keyboard_read, keyboard_rawkey, keyboard_bindkeys, + keyboard_shutdown }; diff --git a/src/pc/controller/controller_recorded_tas.c b/src/pc/controller/controller_recorded_tas.c index f05c0558..2fcd5b54 100644 --- a/src/pc/controller/controller_recorded_tas.c +++ b/src/pc/controller/controller_recorded_tas.c @@ -23,6 +23,13 @@ static void tas_read(OSContPad *pad) { } } +static void tas_shutdown(void) { + if (fp != NULL) { + fclose(fp); + fp = NULL; + } +} + static u32 tas_rawkey(void) { return VK_INVALID; } @@ -33,4 +40,5 @@ struct ControllerAPI controller_recorded_tas = { tas_read, tas_rawkey, NULL, // no rebinding + tas_shutdown }; diff --git a/src/pc/controller/controller_sdl.c b/src/pc/controller/controller_sdl.c index 171a31f4..62aa2acf 100644 --- a/src/pc/controller/controller_sdl.c +++ b/src/pc/controller/controller_sdl.c @@ -204,10 +204,22 @@ static u32 controller_sdl_rawkey(void) { return VK_INVALID; } +static void controller_sdl_shutdown(void) { + if (SDL_WasInit(SDL_INIT_GAMECONTROLLER)) { + if (sdl_cntrl) { + SDL_GameControllerClose(sdl_cntrl); + sdl_cntrl = NULL; + } + SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER); + } + init_ok = false; +} + struct ControllerAPI controller_sdl = { VK_BASE_SDL_GAMEPAD, controller_sdl_init, controller_sdl_read, controller_sdl_rawkey, controller_sdl_bind, + controller_sdl_shutdown }; diff --git a/src/pc/gfx/gfx_opengl.c b/src/pc/gfx/gfx_opengl.c index b7067e91..b283b7e2 100644 --- a/src/pc/gfx/gfx_opengl.c +++ b/src/pc/gfx/gfx_opengl.c @@ -481,6 +481,9 @@ static void gfx_opengl_start_frame(void) { glEnable(GL_SCISSOR_TEST); } +static void gfx_opengl_shutdown(void) { +} + struct GfxRenderingAPI gfx_opengl_api = { gfx_opengl_z_is_from_0_to_1, gfx_opengl_unload_shader, @@ -500,5 +503,6 @@ struct GfxRenderingAPI gfx_opengl_api = { gfx_opengl_set_use_alpha, gfx_opengl_draw_triangles, gfx_opengl_init, - gfx_opengl_start_frame + gfx_opengl_start_frame, + gfx_opengl_shutdown }; diff --git a/src/pc/gfx/gfx_pc.c b/src/pc/gfx/gfx_pc.c index 7052ad60..67c45ecb 100644 --- a/src/pc/gfx/gfx_pc.c +++ b/src/pc/gfx/gfx_pc.c @@ -1547,3 +1547,14 @@ void gfx_end_frame(void) { gfx_wapi->swap_buffers_end(); } } + +void gfx_shutdown(void) { + if (gfx_rapi) { + if (gfx_rapi->shutdown) gfx_rapi->shutdown(); + gfx_rapi = NULL; + } + if (gfx_wapi) { + if (gfx_wapi->shutdown) gfx_wapi->shutdown(); + gfx_wapi = NULL; + } +} \ No newline at end of file diff --git a/src/pc/gfx/gfx_pc.h b/src/pc/gfx/gfx_pc.h index 6903597c..8d62e2b7 100644 --- a/src/pc/gfx/gfx_pc.h +++ b/src/pc/gfx/gfx_pc.h @@ -15,5 +15,6 @@ void gfx_init(struct GfxWindowManagerAPI *wapi, struct GfxRenderingAPI *rapi); void gfx_start_frame(void); void gfx_run(Gfx *commands); void gfx_end_frame(void); +void gfx_shutdown(void); #endif diff --git a/src/pc/gfx/gfx_rendering_api.h b/src/pc/gfx/gfx_rendering_api.h index 58d79435..75aedef9 100644 --- a/src/pc/gfx/gfx_rendering_api.h +++ b/src/pc/gfx/gfx_rendering_api.h @@ -27,6 +27,7 @@ struct GfxRenderingAPI { void (*draw_triangles)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris); void (*init)(void); void (*start_frame)(void); + void (*shutdown)(void); }; #endif diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index e7018476..57ff486d 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -24,6 +24,7 @@ #include "src/pc/controller/controller_keyboard.h" static SDL_Window *wnd; +static SDL_GLContext ctx = NULL; static int inverted_scancode_table[512]; static bool cur_fullscreen; @@ -235,6 +236,15 @@ static double gfx_sdl_get_time(void) { return 0.0; } + +static void gfx_sdl_shutdown(void) { + if (SDL_WasInit(0)) { + if (ctx) { SDL_GL_DeleteContext(ctx); ctx = NULL; } + if (wnd) { SDL_DestroyWindow(wnd); wnd = NULL; } + SDL_Quit(); + } +} + struct GfxWindowManagerAPI gfx_sdl = { gfx_sdl_init, gfx_sdl_main_loop, @@ -243,5 +253,6 @@ struct GfxWindowManagerAPI gfx_sdl = { gfx_sdl_start_frame, gfx_sdl_swap_buffers_begin, gfx_sdl_swap_buffers_end, - gfx_sdl_get_time + gfx_sdl_get_time, + gfx_sdl_shutdown }; diff --git a/src/pc/gfx/gfx_window_manager_api.h b/src/pc/gfx/gfx_window_manager_api.h index 9c68cd10..45826711 100644 --- a/src/pc/gfx/gfx_window_manager_api.h +++ b/src/pc/gfx/gfx_window_manager_api.h @@ -13,6 +13,7 @@ struct GfxWindowManagerAPI { void (*swap_buffers_begin)(void); void (*swap_buffers_end)(void); double (*get_time)(void); // For debug + void (*shutdown)(void); }; #endif diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c index 52d8339b..93774fe2 100644 --- a/src/pc/pc_main.c +++ b/src/pc/pc_main.c @@ -84,6 +84,20 @@ void produce_one_frame(void) { gfx_end_frame(); } +void audio_shutdown(void) { + if (audio_api) { + if (audio_api->shutdown) audio_api->shutdown(); + audio_api = NULL; + } +} + +void game_shutdown(void) { + configfile_save(CONFIG_FILE); + controller_shutdown(); + audio_shutdown(); + gfx_shutdown(); +} + #ifdef TARGET_WEB static void em_main_loop(void) { } @@ -117,17 +131,13 @@ static void on_anim_frame(double time) { } #endif -static void save_config(void) { - configfile_save(CONFIG_FILE); -} - void main_func(void) { static u64 pool[0x165000/8 / 4 * sizeof(void *)]; main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0])); gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT); configfile_load(CONFIG_FILE); - atexit(save_config); + atexit(game_shutdown); #ifdef TARGET_WEB emscripten_set_main_loop(em_main_loop, 0, 0);