Example #1
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;
}
Example #2
0
struct nh_topten_entry *
nh_get_topten(int *out_len, char *statusbuf,
              const char * volatile player, int top,
              int around, boolean own)
{
    struct toptenentry *ttlist, newtt;
    struct nh_topten_entry *score_list;
    boolean game_inited = (wiz1_level.dlevel != 0);
    boolean game_complete = game_inited && moves && program_state.gameover;
    int rank = -1;      /* index of the completed game in the topten list */
    int fd, i, j, sel_count;
    boolean *selected, off_list = FALSE;

    statusbuf[0] = '\0';
    *out_len = 0;

    if (!api_entry_checkpoint())
        return NULL;

    if (!game_inited) {
        /* If nh_get_topten() isn't called after a game, we never went through
           initialization. */
        dlb_init();
        init_dungeons();
    }

    if (!player) {
        if (game_complete)
            player = plname;
        else
            player = "";
    }

    fd = open_datafile(RECORD, O_RDONLY, SCOREPREFIX);
    ttlist = read_topten(fd, TTLISTLEN);
    close(fd);
    if (!ttlist) {
        strcpy(statusbuf, "Cannot open record file!");
        api_exit();
        return NULL;
    }

    /* find the rank of a completed game in the score list */
    if (game_complete && !strcmp(player, plname)) {
        fill_topten_entry(&newtt, end_how);

        /* find this entry in the list */
        for (i = 0; i < TTLISTLEN && validentry(ttlist[i]); i++)
            if (!memcmp(&ttlist[i], &newtt, sizeof (struct toptenentry)))
                rank = i;

        if (wizard || discover)
            sprintf(statusbuf,
                    "Since you were in %s mode, your game was not "
                    "added to the score list.", wizard ? "wizard" : "discover");
        else if (rank >= 0 && rank < 10)
            sprintf(statusbuf, "You made the top ten list!");
        else if (rank)
            sprintf(statusbuf, "You reached the %d%s place on the score list.",
                    rank + 1, ordin(rank + 1));
    }

    /* select scores for display */
    sel_count = 0;
    selected = calloc(TTLISTLEN, sizeof (boolean));

    for (i = 0; i < TTLISTLEN && validentry(ttlist[i]); i++) {
        if (top == -1 || i < top)
            selected[i] = TRUE;

        if (own && !strcmp(player, ttlist[i].name))
            selected[i] = TRUE;

        if (rank != -1 && rank - around <= i && i <= rank + around)
            selected[i] = TRUE;

        if (selected[i])
            sel_count++;
    }

    if (game_complete && sel_count == 0) {
        /* didn't make it onto the list and nothing else is selected */
        ttlist[0] = newtt;
        selected[0] = TRUE;
        sel_count++;
        off_list = TRUE;
    }


    score_list = xmalloc(sel_count * sizeof (struct nh_topten_entry));
    memset(score_list, 0, sel_count * sizeof (struct nh_topten_entry));
    *out_len = sel_count;
    j = 0;
    for (i = 0; i < TTLISTLEN && validentry(ttlist[i]); i++) {
        if (selected[i])
            fill_nh_score_entry(&ttlist[i], &score_list[j++], i + 1, i == rank);
    }

    if (off_list) {
        score_list[0].rank = -1;
        score_list[0].highlight = TRUE;
    }

    if (!game_inited) {
        free_dungeon();
        dlb_cleanup();
    }

    free(selected);
    free(ttlist);

    api_exit();
    return score_list;
}