static int
curses_inline_query(const char *msg, int (*validator)(int, void*),
                    void *arg, nh_bool cursor_visible,
                    enum keyreq_context context) {
    if (!game_is_running) {
        curses_impossible("Trying to create inline query outside game.");
        return curses_msgwin_generic(msg, validator, arg, cursor_visible,
                                     context);
    } else if (!msgwin) {
        curses_impossible("Trying to create inline query without msgwin.");
        return curses_msgwin_generic(msg, validator, arg, cursor_visible,
                                     context);
    }

    /* We use a temporary message as the game will send a summary of the
       decision along later. */
    curses_temp_message(msg);
    draw_msgwin();

    /* We do not respect cursor_visible here, since we want the cursor focused
       on the prompt. We need to leave a space after it, though. */
    int y, x;
    getyx(msgwin, y, x);
    if (x < COLNO - 1)
        wmove(msgwin, y, x + 1);

    int rv = -1;
    while (rv == -1)
        rv = validator(nh_wgetch(msgwin, context), arg);

    curses_clear_temp_messages();
    draw_msgwin();

    return rv;
}
Exemple #2
0
void
pause_messages(void)
{
    draw_msgwin();
    if (msglines[curline][0])   /* new text printed this turn */
        more();
}
Exemple #3
0
/* called from get_command */
void
new_action(void)
{
    action++;
    start_of_turn_curline = last_redraw_curline = curline;
    draw_msgwin();
}
Exemple #4
0
static void
more(void)
{
    int key, attr = A_NORMAL;
    int cursx, cursy;

    draw_msgwin();

    if (settings.standout)
        attr = A_STANDOUT;

    if (getmaxy(msgwin) == 1) {
        wmove(msgwin, getmaxy(msgwin) - 1, COLNO - 8);
        wattron(msgwin, attr);
        waddstr(msgwin, "--More--");
        wattroff(msgwin, attr);
        wrefresh(msgwin);
    } else {
        newline();
        draw_msgwin();
        wmove(msgwin, getmaxy(msgwin) - 1, COLNO / 2 - 4);
        wattron(msgwin, attr);
        waddstr(msgwin, "--More--");
        wattroff(msgwin, attr);
        wrefresh(msgwin);
    }

    getyx(msgwin, cursy, cursx);
    wtimeout(msgwin, 666);      /* enable blinking */
    do {
        key = nh_wgetch(msgwin);
        draw_map(player.x, player.y);
        wmove(msgwin, cursy, cursx);
        doupdate();
    } while (key != '\n' && key != '\r' && key != ' ' && key != KEY_ESC);
    wtimeout(msgwin, -1);

    if (getmaxy(msgwin) == 1)
        newline();
    draw_msgwin();

    if (key == KEY_ESC)
        stopprint = TRUE;

    /* we want to --more-- by screenfuls, not lines */
    last_redraw_curline = curline;
}
/* Create a new dialog, or reposition an existing one, in an appropriate
   position for showing prompts. Also draw a border around it. */
WINDOW *
newdialog(int height, int width, int dismissable, WINDOW *win)
{
    int starty, startx;

    if (height < 3)
        height = 3;
    if (height > LINES)
        height = LINES;
    if (width > COLS)
        width = COLS;

    if (game_is_running) {
        /* instead of covering up messages, draw the dialog as if it were a
           message */
        fresh_message_line(TRUE);
        draw_msgwin();
        if (getmaxx(msgwin) < getmaxx(stdscr))
            width = getmaxx(msgwin) + (ui_flags.draw_outer_frame_lines ? 2 : 0);
        else
            width = getmaxx(stdscr);
        startx = 0;
        starty = getmaxy(msgwin) - (ui_flags.draw_outer_frame_lines ? 0 : 1);
    } else {
        /* out of game, keep dialogs centred */
        starty = (LINES - height) / 2;
        startx = (COLS - width) / 2;
    }

    redraw_popup_windows();

    if (!win)
        win = newwin_onscreen(height, width, starty, startx);
    else {
        mvwin(win, starty, startx);
        wresize(win, height, width);
    }

    werase(win);
    keypad(win, TRUE);
    meta(win, TRUE);
    nh_window_border(win, dismissable);
    return win;
}
Exemple #6
0
void
replay_commandloop(int fd)
{
    int key, move, count;
    char buf[BUFSZ], qbuf[BUFSZ];
    nh_bool ret, firsttime = TRUE;
    struct nh_replay_info rinfo;
    struct nh_cmd_arg noarg;
    struct nh_cmd_desc *cmd;

    create_game_windows();
    if (!nh_view_replay_start(fd, &curses_replay_windowprocs, &rinfo))
        return;
    load_keymap();

    while (1) {
        draw_msgwin();
        curses_update_status(NULL);
        draw_sidebar();
        draw_replay_info(&rinfo);
        if (firsttime)
            show_replay_help();
        firsttime = FALSE;

        key = get_map_key(TRUE);
        switch (key) {
            /* step forward */
        case KEY_RIGHT:
        case ' ':
            ret = nh_view_replay_step(&rinfo, REPLAY_FORWARD, 1);
            draw_replay_info(&rinfo);
            if (ret == FALSE) {
                key =
                    curses_msgwin("You have reached the end of this game. "
                                  "Go back or press ESC to exit.");
                if (key == KEY_ESC)
                    goto out;
            }
            break;

            /* step backward */
        case KEY_LEFT:
            nh_view_replay_step(&rinfo, REPLAY_BACKWARD, 1);
            draw_replay_info(&rinfo);
            break;

        case KEY_ESC:
            goto out;

        case 'g':
            strncpy(qbuf, "What move do you want to jump to?", BUFSZ);
            if (rinfo.max_moves > 0)
                sprintf(qbuf + strlen(qbuf), " (Max: %d)", rinfo.max_moves);

            curses_getline(qbuf, buf);
            if (buf[0] == '\033' || !(move = atoi(buf)))
                break;
            nh_view_replay_step(&rinfo, REPLAY_GOTO, move);
            break;

        case KEY_F(12):        /* timetest! */
            if (allow_timetest())
                timetest(fd, &rinfo);
            break;

        default:
            count = 0;
            noarg.argtype = CMD_ARG_NONE;
            cmd = keymap[key];
            if (!cmd)
                break;
            if (cmd->flags & CMD_UI)
                handle_internal_cmd(&cmd, &noarg, &count);
            if (cmd)
                nh_command(cmd->name, count, &noarg);
            break;
        }
    }

out:
    nh_view_replay_finish();
    free_keymap();
    destroy_game_windows();
    cleanup_messages();
}
Exemple #7
0
static void
timetest(int fd, struct nh_replay_info *rinfo)
{
    char buf[BUFSZ];
    hp_time t_start, t_end;
    long ms;
    int mmax, initial, revpos;

    initial = rinfo->moves;
    nh_view_replay_step(rinfo, REPLAY_GOTO, 0);

    /* run forward */
    gettime(&t_start);
    while (rinfo->actions < rinfo->max_actions) {
        nh_view_replay_step(rinfo, REPLAY_FORWARD, 1);
        curses_update_status(NULL);
        draw_replay_info(rinfo);
        doupdate();
    }
    draw_msgwin();
    gettime(&t_end);
    ms = clock_delta_ms(&t_start, &t_end);
    snprintf(buf, BUFSZ,
             "%d actions replayed with display in %ld ms. (%ld actions/sec)",
             rinfo->max_actions, ms, rinfo->max_actions * 1000 / ms);
    curses_msgwin(buf);

    /* reset the entire replay state to delete checkpoints */
    mmax = rinfo->moves;        /* max_moves may not be available if this is a
                                   replay of a crashed game */
    nh_view_replay_finish();
    nh_view_replay_start(fd, &curses_replay_windowprocs, rinfo);

    /* run forward without showing the map etc. */
    gettime(&t_start);
    nh_view_replay_step(rinfo, REPLAY_GOTO, mmax);
    gettime(&t_end);
    ms = clock_delta_ms(&t_start, &t_end);
    snprintf(buf, BUFSZ,
             "%d actions replayed without display in %ld ms. (%ld actions/sec)",
             rinfo->actions, ms, rinfo->actions * 1000 / ms);
    curses_msgwin(buf);

    /* run backward */
    revpos = rinfo->actions;
    gettime(&t_start);
    while (rinfo->actions > 0 && revpos < rinfo->actions + 1000) {
        nh_view_replay_step(rinfo, REPLAY_BACKWARD, 1);
        curses_update_status(NULL);
        draw_msgwin();
        draw_replay_info(rinfo);
        doupdate();
    }
    gettime(&t_end);
    ms = clock_delta_ms(&t_start, &t_end);
    snprintf(buf, BUFSZ,
             "%d actions replayed backward with display in %ld ms. (%ld actions/sec)",
             revpos - rinfo->actions, ms,
             (revpos - rinfo->actions) * 1000 / ms);
    curses_msgwin(buf);

    nh_view_replay_step(rinfo, REPLAY_GOTO, initial);
}
Exemple #8
0
static void
curses_print_message_core(int turn, const char *msg, nh_bool canblock)
{
    int hsize, vsize, maxlen;
    nh_bool died;

    if (!msghistory)
        alloc_hist_array();

    if (turn != prevturn)
        start_of_turn_curline = last_redraw_curline = curline;

    if (turn < prevturn)        /* going back in time can happen during replay */
        prune_messages(turn);

    if (!*msg)
        return; /* empty message. done. */

    if (action > prevaction) {
        /* re-enable output if it was stopped and start a new line */
        stopprint = FALSE;
        newline();
    }
    prevturn = turn;
    prevaction = action;

    store_message(turn, msg);

    if (stopprint)
        return;

    /* 
     * generally we want to put as many messages on one line as possible to
     * maximize space usage. A new line is begun after each player turn or if
     * more() is called via pause_messages(). "You die" also deserves its own line.
     * 
     * If the message area is only one line high, space for "--More--" must be
     * reserved at the end of the line, otherwise  --More-- is shown on a new line.
     */

    getmaxyx(msgwin, vsize, hsize);

    maxlen = hsize;
    if (maxlen >= COLNO)
        maxlen = COLNO - 1;
    if (vsize == 1)
        maxlen -= 8;    /* for "--More--" */

    died = !strncmp(msg, "You die", 7);
    if (strlen(msglines[curline]) + strlen(msg) + 1 < maxlen && !died) {
        if (msglines[curline][0])
            strcat(msglines[curline], "  ");
        strcat(msglines[curline], msg);
    } else {
        int idx, output_count;
        char **output;

        wrap_text(maxlen, msg, &output_count, &output);

        for (idx = 0; idx < output_count; idx++) {
            if (strlen(msglines[curline]) > 0)
                fresh_message_line(canblock);
            if (stopprint)
                break;  /* may get set in more() */
            strcpy(msglines[curline], output[idx]);
        }

        free_wrap(output);
    }

    draw_msgwin();
}