Shutdown subsystems on exit

Porting from testing, originally by @fgsfdsfgs
This commit is contained in:
Vinícius R. Miguel 2020-05-16 16:23:23 -03:00
parent 8722b09bb4
commit 9e8290773b
15 changed files with 101 additions and 10 deletions

View File

@ -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

View File

@ -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
};

View File

@ -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
};

View File

@ -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

View File

@ -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)

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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
};

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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
};

View File

@ -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

View File

@ -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);