// ------------------------------------------------------------- // exit system // ------------------------------------------------------------- void t_game_application::exit( int return_value ) { clear_music_cache(); stop_all_sounds(); // FIXME: if a bink window is currently playing and this call is NOT made, the game will crash // because the bink window destructors are NOT being called. t_window::get_main_window()->close(); if (g_cursor != 0) { g_cursor->close(); g_cursor = 0; } t_window::close_system(); ::exit( return_value ); }
int PlayMusicQueued(int musnum) { // Just get the queue size if (musnum < 0) return play.music_queue_size; if ((IsMusicPlaying() == 0) && (play.music_queue_size == 0)) { newmusic(musnum); return 0; } if (play.music_queue_size >= MAX_QUEUED_MUSIC) { debug_script_log("Too many queued music, cannot add %d", musnum); return 0; } if ((play.music_queue_size > 0) && (play.music_queue[play.music_queue_size - 1] >= QUEUED_MUSIC_REPEAT)) { quit("!PlayMusicQueued: cannot queue music after a repeating tune has been queued"); } if (play.music_repeat) { debug_script_log("Queuing music %d to loop", musnum); musnum += QUEUED_MUSIC_REPEAT; } else { debug_script_log("Queuing music %d", musnum); } play.music_queue[play.music_queue_size] = musnum; play.music_queue_size++; if (play.music_queue_size == 1) { clear_music_cache(); cachedQueuedMusic = load_music_from_disk(musnum, (play.music_repeat > 0)); } return play.music_queue_size; }
// Prepares engine for actual save restore (stops processes, cleans up memory) void DoBeforeRestore(PreservedParams &pp) { pp.SpeechVOX = play.want_speech; pp.MusicVOX = play.separate_music_lib; unload_old_room(); delete raw_saved_screen; raw_saved_screen = NULL; remove_screen_overlay(-1); is_complete_overlay = 0; is_text_overlay = 0; // cleanup dynamic sprites // NOTE: sprite 0 is a special constant sprite that cannot be dynamic for (int i = 1; i < spriteset.GetSpriteSlotCount(); ++i) { if (game.SpriteInfos[i].Flags & SPF_DYNAMICALLOC) { // do this early, so that it changing guibuts doesn't // affect the restored data free_dynamic_sprite(i); } } // cleanup GUI backgrounds for (int i = 0; i < game.numgui; ++i) { delete guibg[i]; guibg[i] = NULL; if (guibgbmp[i]) gfxDriver->DestroyDDB(guibgbmp[i]); guibgbmp[i] = NULL; } // preserve script data sizes and cleanup scripts pp.GlScDataSize = gameinst->globaldatasize; delete gameinstFork; delete gameinst; gameinstFork = NULL; gameinst = NULL; pp.ScMdDataSize.resize(numScriptModules); for (int i = 0; i < numScriptModules; ++i) { pp.ScMdDataSize[i] = moduleInst[i]->globaldatasize; delete moduleInstFork[i]; delete moduleInst[i]; moduleInst[i] = NULL; } play.FreeProperties(); delete roominstFork; delete roominst; roominstFork = NULL; roominst = NULL; delete dialogScriptsInst; dialogScriptsInst = NULL; resetRoomStatuses(); troom.FreeScriptData(); troom.FreeProperties(); free_do_once_tokens(); // unregister gui controls from API exports // TODO: find out why are we doing this here? perhaps remove if we do full managed pool reset in DoBeforeRestore for (int i = 0; i < game.numgui; ++i) { unexport_gui_controls(i); } // NOTE: channels are array of MAX_SOUND_CHANNELS+1 size for (int i = 0; i <= MAX_SOUND_CHANNELS; ++i) { stop_and_destroy_channel_ex(i, false); } clear_music_cache(); }