From 03662be548435cc25517ec7568f09aafab67bae0 Mon Sep 17 00:00:00 2001 From: Manuel Alfayate Corchete Date: Wed, 8 Apr 2020 13:27:02 +0200 Subject: [PATCH] =?UTF-8?q?Remove=20atexit()=20calls=20and=20implement=20a?= =?UTF-8?q?=20diablo=5Fdeinit()=20function=20instea=E2=80=A6=20(#694)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove atexit() calls and implement a diablo_deinit() function instead that cleans up every subsystem if it has been init before. --- Source/appfat.cpp | 2 +- Source/diablo.cpp | 44 ++++++++++++++++++++++++++++++----- Source/diablo.h | 4 ++++ Source/init.cpp | 4 ++-- Source/init.h | 2 ++ Source/movie.cpp | 2 +- SourceX/DiabloUI/diabloui.cpp | 2 +- SourceX/DiabloUI/fonts.cpp | 10 ++++++-- SourceX/DiabloUI/fonts.h | 1 + SourceX/display.cpp | 6 ++--- SourceX/dx.cpp | 3 +++ 11 files changed, 64 insertions(+), 16 deletions(-) diff --git a/Source/appfat.cpp b/Source/appfat.cpp index ce32ce099..7809c51f5 100644 --- a/Source/appfat.cpp +++ b/Source/appfat.cpp @@ -27,7 +27,7 @@ void app_fatal(const char *pszFmt, ...) va_end(va); - exit(1); + diablo_quit(1); } void MsgBox(const char *pszFmt, va_list va) diff --git a/Source/diablo.cpp b/Source/diablo.cpp index 3e77f953f..13c12e874 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -80,6 +80,12 @@ char *spszMsgTbl[4] = { /** INI files variable names for quick message keys */ char *spszMsgHotKeyTbl[4] = { "F9", "F10", "F11", "F12" }; +/** To know if these things have been done when we get to the diablo_deinit() function */ +BOOL was_archives_init = false; +BOOL was_ui_init = false; +BOOL was_snd_init = false; +BOOL was_sfx_init = false; + void FreeGameMem() { music_stop(); @@ -270,13 +276,13 @@ void diablo_init() SFileEnableDirectAccess(TRUE); init_archives(); - atexit(init_cleanup); + was_archives_init = true; UiInitialize(); #ifdef SPAWN UiSetSpawned(TRUE); #endif - atexit(UiDestroy); + was_ui_init = true; ReadOnlyTest(); @@ -285,9 +291,10 @@ void diablo_init() diablo_init_screen(); snd_init(NULL); - atexit(sound_cleanup); + was_snd_init = true; + sound_init(); - atexit(effects_cleanup_sfx); + was_sfx_init = true; } void diablo_splash() @@ -305,12 +312,37 @@ void diablo_splash() UiTitleDialog(); } +void diablo_deinit() +{ + if (was_sfx_init) + effects_cleanup_sfx(); + if (was_snd_init) + sound_cleanup(); + if (was_ui_init) + UiDestroy(); + if (was_archives_init) + init_cleanup(); + if (was_window_init) + dx_cleanup(); // Cleanup SDL surfaces stuff, so we have to do it before SDL_Quit(). + if (was_fonts_init) + FontsCleanup(); + if (SDL_WasInit(SDL_INIT_EVERYTHING & ~SDL_INIT_HAPTIC)) + SDL_Quit(); +} + +void diablo_quit(int exitStatus) +{ + diablo_deinit(); + exit(exitStatus); +} + int DiabloMain(int argc, char **argv) { diablo_parse_flags(argc, argv); diablo_init(); diablo_splash(); mainmenu_loop(); + diablo_deinit(); return 0; } @@ -341,7 +373,7 @@ static void print_help_and_exit() printf(" %-20s %-30s\n", "-t <##>", "Set current quest level"); #endif printf("\nReport bugs at https://github.com/diasurgical/devilutionX/\n"); - exit(0); + diablo_quit(0); } void diablo_parse_flags(int argc, char **argv) @@ -351,7 +383,7 @@ void diablo_parse_flags(int argc, char **argv) print_help_and_exit(); } else if (strcasecmp("--version", argv[i]) == 0) { printf("%s v%s\n", PROJECT_NAME, PROJECT_VERSION); - exit(0); + diablo_quit(0); } else if (strcasecmp("--data-dir", argv[i]) == 0) { basePath = argv[++i]; #ifdef _WIN32 diff --git a/Source/diablo.h b/Source/diablo.h index eee31b176..e2e265905 100644 --- a/Source/diablo.h +++ b/Source/diablo.h @@ -26,6 +26,9 @@ extern int DebugMonsters[10]; extern BOOLEAN cineflag; extern int force_redraw; extern BOOL visiondebug; +/* These are defined in fonts.h */ +extern BOOL was_fonts_init; +extern void FontsCleanup(); /** unused */ extern BOOL scrollflag; extern BOOL light4flag; @@ -48,6 +51,7 @@ int DiabloMain(int argc, char **argv); void diablo_parse_flags(int argc, char **argv); void diablo_init_screen(); void diablo_reload_process(HINSTANCE hInstance); +void diablo_quit(int exitStatus); BOOL PressEscKey(); LRESULT DisableInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); LRESULT GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); diff --git a/Source/init.cpp b/Source/init.cpp index 6a1c7bb0c..6f2e48cd0 100644 --- a/Source/init.cpp +++ b/Source/init.cpp @@ -52,7 +52,7 @@ void init_create_window() if (!SpawnWindow(PROJECT_NAME, SCREEN_WIDTH, SCREEN_HEIGHT)) app_fatal("Unable to create main window"); dx_init(NULL); - atexit(dx_cleanup); + was_window_init = true; gbActive = true; gpBufStart = &gpBuffer[BUFFER_WIDTH * SCREEN_Y]; gpBufEnd = (BYTE *)(BUFFER_WIDTH * (SCREEN_HEIGHT + SCREEN_Y)); @@ -132,7 +132,7 @@ LRESULT MainWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) case WM_QUERYNEWPALETTE: return 1; case WM_QUERYENDSESSION: - exit(0); + diablo_quit(0); } return 0; diff --git a/Source/init.h b/Source/init.h index 8f39bd291..1955fe51d 100644 --- a/Source/init.h +++ b/Source/init.h @@ -27,6 +27,8 @@ LRESULT MainWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); void init_activate_window(HWND hWnd, BOOL bActive); WNDPROC SetWindowProc(WNDPROC NewProc); +extern BOOL was_window_init; /** defined in dx.cpp */ + /* rdata */ /* data */ diff --git a/Source/movie.cpp b/Source/movie.cpp index 88cdab550..0d2c0102e 100644 --- a/Source/movie.cpp +++ b/Source/movie.cpp @@ -36,7 +36,7 @@ void play_movie(char *pszMovie, BOOL user_can_close) break; case WM_QUIT: SVidPlayEnd(video_stream); - exit(0); + diablo_quit(0); break; } } diff --git a/SourceX/DiabloUI/diabloui.cpp b/SourceX/DiabloUI/diabloui.cpp index 0f46ce971..1582f695d 100644 --- a/SourceX/DiabloUI/diabloui.cpp +++ b/SourceX/DiabloUI/diabloui.cpp @@ -328,7 +328,7 @@ void UiHandleEvents(SDL_Event *event) } if (event->type == SDL_QUIT) - exit(0); + diablo_quit(0); #ifndef USE_SDL1 if (event->type == SDL_JOYDEVICEADDED || event->type == SDL_JOYDEVICEREMOVED) { diff --git a/SourceX/DiabloUI/fonts.cpp b/SourceX/DiabloUI/fonts.cpp index c1dec4b1b..1c67ecbc0 100644 --- a/SourceX/DiabloUI/fonts.cpp +++ b/SourceX/DiabloUI/fonts.cpp @@ -5,6 +5,8 @@ namespace dvl { TTF_Font *font = nullptr; BYTE *FontTables[4]; Art ArtFonts[4][2]; +/** This is so we know ttf has been init when we get to the diablo_deinit() function */ +BOOL was_fonts_init = false; namespace { @@ -53,9 +55,9 @@ void LoadTtfFont() { if (!TTF_WasInit()) { if (TTF_Init() == -1) { SDL_Log("TTF_Init: %s", TTF_GetError()); - exit(1); + diablo_quit(1); } - atexit(TTF_Quit); + was_fonts_init = true; } font = TTF_OpenFont(TTF_FONT_PATH, 17); @@ -74,4 +76,8 @@ void UnloadTtfFont() { font = nullptr; } +void FontsCleanup() { + TTF_Quit(); +} + } // namespace dvl diff --git a/SourceX/DiabloUI/fonts.h b/SourceX/DiabloUI/fonts.h index 4848bbd9d..c872c8eeb 100644 --- a/SourceX/DiabloUI/fonts.h +++ b/SourceX/DiabloUI/fonts.h @@ -33,5 +33,6 @@ void UnloadArtFonts(); void LoadTtfFont(); void UnloadTtfFont(); +void FontsCleanup(); } // namespace dvl diff --git a/SourceX/display.cpp b/SourceX/display.cpp index 7cbf82e15..cb5d6fc11 100644 --- a/SourceX/display.cpp +++ b/SourceX/display.cpp @@ -19,7 +19,9 @@ namespace dvl { -extern SDL_Surface *renderer_texture_surface; // defined in dx.cpp +extern BOOL was_window_init; /** defined in dx.cpp */ + +extern SDL_Surface *renderer_texture_surface; /** defined in dx.cpp */ #ifdef USE_SDL1 void SetVideoMode(int width, int height, int bpp, std::uint32_t flags) { @@ -51,8 +53,6 @@ bool SpawnWindow(const char *lpWindowName, int nWidth, int nHeight) ErrSdl(); } - atexit(SDL_Quit); - #ifdef USE_SDL1 SDL_EnableUNICODE(1); #endif diff --git a/SourceX/dx.cpp b/SourceX/dx.cpp index c5ba91124..c8bb73840 100644 --- a/SourceX/dx.cpp +++ b/SourceX/dx.cpp @@ -32,6 +32,9 @@ SDL_Surface *renderer_texture_surface = nullptr; /** 8-bit surface wrapper around #gpBuffer */ SDL_Surface *pal_surface; +/** To know if surfaces have been initialized or not */ +BOOL was_window_init = false; + static void dx_create_back_buffer() { pal_surface = SDL_CreateRGBSurfaceWithFormat(0, BUFFER_WIDTH, BUFFER_HEIGHT, 8, SDL_PIXELFORMAT_INDEX8);