Esempio n. 1
0
/* returns 1 if save successful */
int
dosave0(boolean emergency)
{
    int fd;
    struct memfile mf;
    boolean log_disabled = iflags.disable_log;

    mnew(&mf, NULL);

    fd = logfile;

    /* when we leave via nh_exit, logging is disabled. It needs to be enabled
       briefly so that log_finish will update the log header. */
    iflags.disable_log = FALSE;
    log_finish(LS_SAVED);
    iflags.disable_log = log_disabled;
    vision_recalc(2);   /* shut down vision to prevent problems in the event of 
                           an impossible() call */

    savegame(&mf);
    store_mf(fd, &mf);  /* also frees mf */

    freedynamicdata();

    return TRUE;
}
Esempio n. 2
0
boolean nh_exit_game(int exit_type)
{
    boolean log_disabled = iflags.disable_log;
    
    if (!api_entry_checkpoint()) { /* not sure anything in here can actually call panic */
	iflags.disable_log = log_disabled;
	return TRUE; /* terminate was called, so exit is successful */
    }
    
    program_state.forced_exit = TRUE;
    
    /* clean up after viewing a game replay */
    if (program_state.viewing)
	nh_view_replay_finish();
	
    xmalloc_cleanup();
    iflags.disable_log = TRUE;
    if (program_state.game_running) {
	switch (exit_type) {
	    case EXIT_REQUEST_SAVE:
		dosave(); /* will ask "really save?" and, if 'y', eventually call terminate. */
		break;
		
	    case EXIT_FORCE_SAVE:
		dosave0(TRUE);
		terminate();
		break;
		
	    case EXIT_REQUEST_QUIT:
		done2();
		break;
		    
	    case EXIT_FORCE_QUIT:
		done(QUIT);
		break; /* not reached */
		
	    case EXIT_PANIC:
		/* freeing things should be safe */
		freedynamicdata();
		dlb_cleanup();
		panic("UI problem.");
		break;
	}
	
	iflags.disable_log = log_disabled;
	api_exit();
	return FALSE;
    }
    
    iflags.disable_log = log_disabled;
    /* calling terminate() will get us out of nested contexts safely, eg:
     * UI_cmdloop -> nh_command -> UI_update_screen (problem happens here) -> nh_exit_game
     * will jump all the way back to UI_cmdloop */
    terminate();
    
    api_exit(); /* not reached */
    return TRUE;
}