From: jwalz Date: Sat, 5 Jan 2002 21:06:02 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: MOVE2GIT~3562 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4e009433edd041f7a4db1158a63aaa592a7d11f3;p=nethack *** empty log message *** --- diff --git a/win/tty/topl.c b/win/tty/topl.c new file mode 100644 index 000000000..98d4248e5 --- /dev/null +++ b/win/tty/topl.c @@ -0,0 +1,372 @@ +/* SCCS Id: @(#)topl.c 3.3 96/10/24 */ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" + +#ifdef TTY_GRAPHICS + +#include "tcap.h" +#include "wintty.h" +#include + +#ifndef C /* this matches src/cmd.c */ +#define C(c) (0x1f & (c)) +#endif + +STATIC_DCL void FDECL(redotoplin, (const char*)); +STATIC_DCL void FDECL(topl_putsym, (CHAR_P)); +STATIC_DCL void NDECL(remember_topl); +STATIC_DCL void FDECL(removetopl, (int)); + +#ifdef OVLB + +int +tty_doprev_message() +{ + register struct WinDesc *cw = wins[WIN_MESSAGE]; + + ttyDisplay->dismiss_more = C('p'); /* allowed at --More-- */ + do { + morc = 0; + if (cw->maxcol == cw->maxrow) + redotoplin(toplines); + else if (cw->data[cw->maxcol]) + redotoplin(cw->data[cw->maxcol]); + cw->maxcol--; + if (cw->maxcol < 0) cw->maxcol = cw->rows-1; + if (!cw->data[cw->maxcol]) + cw->maxcol = cw->maxrow; + } while (morc == C('p')); + ttyDisplay->dismiss_more = 0; + return 0; +} + +#endif /* OVLB */ +#ifdef OVL1 + +STATIC_OVL void +redotoplin(str) + const char *str; +{ + int otoplin = ttyDisplay->toplin; + home(); + if(*str & 0x80) { + /* kludge for the / command, the only time we ever want a */ + /* graphics character on the top line */ + g_putch((int)*str++); + ttyDisplay->curx++; + } + end_glyphout(); /* in case message printed during graphics output */ + putsyms(str); + cl_end(); + ttyDisplay->toplin = 1; + if(ttyDisplay->cury && otoplin != 3) + more(); +} + +STATIC_OVL void +remember_topl() +{ + register struct WinDesc *cw = wins[WIN_MESSAGE]; + int idx = cw->maxrow; + unsigned len = strlen(toplines) + 1; + + if (len > (unsigned)cw->datlen[idx]) { + if (cw->data[idx]) free(cw->data[idx]); + len += (8 - (len & 7)); /* pad up to next multiple of 8 */ + cw->data[idx] = (char *)alloc(len); + cw->datlen[idx] = (short)len; + } + Strcpy(cw->data[idx], toplines); + cw->maxcol = cw->maxrow = (idx + 1) % cw->rows; +} + +void +addtopl(s) +const char *s; +{ + register struct WinDesc *cw = wins[WIN_MESSAGE]; + + tty_curs(BASE_WINDOW,cw->curx+1,cw->cury); + putsyms(s); + cl_end(); + ttyDisplay->toplin = 1; +} + +#endif /* OVL1 */ +#ifdef OVL2 + +void +more() +{ + struct WinDesc *cw = wins[WIN_MESSAGE]; + + /* avoid recursion -- only happens from interrupts */ + if(ttyDisplay->inmore++) + return; + + if(ttyDisplay->toplin) { + tty_curs(BASE_WINDOW, cw->curx+1, cw->cury); + if(cw->curx >= CO - 8) topl_putsym('\n'); + } + + if(flags.standout) + standoutbeg(); + putsyms(defmorestr); + if(flags.standout) + standoutend(); + + xwaitforspace("\033 "); + + if(morc == '\033') + cw->flags |= WIN_STOP; + + if(ttyDisplay->toplin && cw->cury) { + docorner(1, cw->cury+1); + cw->curx = cw->cury = 0; + home(); + } else if(morc == '\033') { + cw->curx = cw->cury = 0; + home(); + cl_end(); + } + ttyDisplay->toplin = 0; + ttyDisplay->inmore = 0; +} + +void +update_topl(bp) + register const char *bp; +{ + register char *tl, *otl; + register int n0; + int notdied = 1; + struct WinDesc *cw = wins[WIN_MESSAGE]; + + /* If there is room on the line, print message on same line */ + /* But messages like "You die..." deserve their own line */ + n0 = strlen(bp); + if(ttyDisplay->toplin == 1 && cw->cury == 0 && + n0 + (int)strlen(toplines) + 3 < CO-8 && /* room for --More-- */ + (notdied = strncmp(bp, "You die", 7))) { + Strcat(toplines, " "); + Strcat(toplines, bp); + cw->curx += 2; + if(!(cw->flags & WIN_STOP)) + addtopl(bp); + return; + } else if(!(cw->flags & WIN_STOP)) { + if(ttyDisplay->toplin == 1) more(); + else if(cw->cury) { /* for when flags.toplin == 2 && cury > 1 */ + docorner(1, cw->cury+1); /* reset cury = 0 if redraw screen */ + cw->curx = cw->cury = 0;/* from home--cls() & docorner(1,n) */ + } + } + remember_topl(); + (void) strncpy(toplines, bp, TBUFSZ); + toplines[TBUFSZ - 1] = 0; + + for(tl = toplines; n0 >= CO; ){ + otl = tl; + for(tl+=CO-1; tl != otl && !isspace(*tl); --tl) ; + if(tl == otl) { + /* Eek! A huge token. Try splitting after it. */ + tl = index(otl, ' '); + if (!tl) break; /* No choice but to spit it out whole. */ + } + *tl++ = '\n'; + n0 = strlen(tl); + } + if(!notdied) cw->flags &= ~WIN_STOP; + if(!(cw->flags & WIN_STOP)) redotoplin(toplines); +} + +STATIC_OVL +void +topl_putsym(c) + char c; +{ + register struct WinDesc *cw = wins[WIN_MESSAGE]; + + if(cw == (struct WinDesc *) 0) panic("Putsym window MESSAGE nonexistant"); + + switch(c) { + case '\b': + if(ttyDisplay->curx == 0 && ttyDisplay->cury > 0) + tty_curs(BASE_WINDOW, CO, (int)ttyDisplay->cury-1); + backsp(); + ttyDisplay->curx--; + cw->curx = ttyDisplay->curx; + return; + case '\n': + cl_end(); + ttyDisplay->curx = 0; + ttyDisplay->cury++; + cw->cury = ttyDisplay->cury; + break; + default: + if(ttyDisplay->curx == CO-1) + topl_putsym('\n'); /* 1 <= curx <= CO; avoid CO */ + ttyDisplay->curx++; + } + cw->curx = ttyDisplay->curx; + if(cw->curx == 0) cl_end(); + (void) putchar(c); +} + +void +putsyms(str) + const char *str; +{ + while(*str) + topl_putsym(*str++); +} + +STATIC_OVL void +removetopl(n) +register int n; +{ + /* assume addtopl() has been done, so ttyDisplay->toplin is already set */ + while (n-- > 0) putsyms("\b \b"); +} + +extern char erase_char; /* from xxxtty.c; don't need kill_char */ + +char +tty_yn_function(query,resp, def) +const char *query,*resp; +char def; +/* + * Generic yes/no function. 'def' is the default (returned by space or + * return; 'esc' returns 'q', or 'n', or the default, depending on + * what's in the string. The 'query' string is printed before the user + * is asked about the string. + * If resp is NULL, any single character is accepted and returned. + * If not-NULL, only characters in it are allowed (exceptions: the + * quitchars are always allowed, and if it contains '#' then digits + * are allowed); if it includes an , anything beyond that won't + * be shown in the prompt to the user but will be acceptable as input. + */ +{ + register char q; + char rtmp[40]; + boolean digit_ok, allow_num; + struct WinDesc *cw = wins[WIN_MESSAGE]; + boolean doprev = 0; + char prompt[QBUFSZ]; + + if(ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) more(); + cw->flags &= ~WIN_STOP; + ttyDisplay->toplin = 3; /* special prompt state */ + ttyDisplay->inread++; + if (resp) { + char *rb, respbuf[QBUFSZ]; + + allow_num = (index(resp, '#') != 0); + Strcpy(respbuf, resp); + /* any acceptable responses that follow aren't displayed */ + if ((rb = index(respbuf, '\033')) != 0) *rb = '\0'; + Sprintf(prompt, "%s [%s] ", query, respbuf); + if (def) Sprintf(eos(prompt), "(%c) ", def); + pline("%s", prompt); + } else { + pline("%s ", query); + q = readchar(); + goto clean_up; + } + + do { /* loop until we get valid input */ + q = lowc(readchar()); + if (q == '\020') { /* ctrl-P */ + if(!doprev) (void) tty_doprev_message(); /* need two initially */ + (void) tty_doprev_message(); + doprev = 1; + q = '\0'; /* force another loop iteration */ + continue; + } else if (doprev) { + /* BUG[?]: this probably ought to check whether the + character which has just been read is an acceptable + response; if so, skip the reprompt and use it. */ + tty_clear_nhwindow(WIN_MESSAGE); + cw->maxcol = cw->maxrow; + doprev = 0; + addtopl(prompt); + q = '\0'; /* force another loop iteration */ + continue; + } + digit_ok = allow_num && digit(q); + if (q == '\033') { + if (index(resp, 'q')) + q = 'q'; + else if (index(resp, 'n')) + q = 'n'; + else + q = def; + break; + } else if (index(quitchars, q)) { + q = def; + break; + } + if (!index(resp, q) && !digit_ok) { + tty_nhbell(); + q = (char)0; + } else if (q == '#' || digit_ok) { + char z, digit_string[2]; + int n_len = 0; + long value = 0; + addtopl("#"), n_len++; + digit_string[1] = '\0'; + if (q != '#') { + digit_string[0] = q; + addtopl(digit_string), n_len++; + value = q - '0'; + q = '#'; + } + do { /* loop until we get a non-digit */ + z = lowc(readchar()); + if (digit(z)) { + value = (10 * value) + (z - '0'); + if (value < 0) break; /* overflow: try again */ + digit_string[0] = z; + addtopl(digit_string), n_len++; + } else if (z == 'y' || index(quitchars, z)) { + if (z == '\033') value = -1; /* abort */ + z = '\n'; /* break */ + } else if (z == erase_char || z == '\b') { + if (n_len <= 1) { value = -1; break; } + else { value /= 10; removetopl(1), n_len--; } + } else { + value = -1; /* abort */ + tty_nhbell(); + break; + } + } while (z != '\n'); + if (value > 0) yn_number = value; + else if (value == 0) q = 'n'; /* 0 => "no" */ + else { /* remove number from top line, then try again */ + removetopl(n_len), n_len = 0; + q = '\0'; + } + } + } while(!q); + + if (q != '#') { + Sprintf(rtmp, "%c", q); + addtopl(rtmp); + } + clean_up: + ttyDisplay->inread--; + ttyDisplay->toplin = 2; + if (ttyDisplay->intr) ttyDisplay->intr--; + if(wins[WIN_MESSAGE]->cury) + tty_clear_nhwindow(WIN_MESSAGE); + + return q; +} + +#endif /* OVL2 */ + +#endif /* TTY_GRAPHICS */ + +/*topl.c*/