From 08a19108678e772ab52ee195be74101b2792accb Mon Sep 17 00:00:00 2001 From: Bart House Date: Wed, 10 Jul 2019 22:16:08 -0700 Subject: [PATCH 1/3] Improved readability of topline state management. --- include/decl.h | 6 ++++++ win/tty/getline.c | 6 +++--- win/tty/topl.c | 24 ++++++++++++------------ win/tty/wintty.c | 48 ++++++++++++++++++++++++++--------------------- 4 files changed, 48 insertions(+), 36 deletions(-) diff --git a/include/decl.h b/include/decl.h index 5ebaa326e..6c0f9721c 100644 --- a/include/decl.h +++ b/include/decl.h @@ -455,6 +455,12 @@ struct early_opt { boolean valallowed; }; +/* topline states */ +#define TOPLINE_EMPTY 0 /* empty */ +#define TOPLINE_NEED_MORE 1 /* non-empty, need --More-- */ +#define TOPLINE_NON_EMPTY 2 /* non-empty, no --More-- required */ +#define TOPLINE_SPECIAL_PROMPT 3 /* special prompt state */ + #undef E #endif /* DECL_H */ diff --git a/win/tty/getline.c b/win/tty/getline.c index f4894a950..a3abfcc53 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -52,10 +52,10 @@ getlin_hook_proc hook; struct WinDesc *cw = wins[WIN_MESSAGE]; boolean doprev = 0; - if (ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) + if (ttyDisplay->toplin == TOPLINE_NEED_MORE && !(cw->flags & WIN_STOP)) more(); cw->flags &= ~WIN_STOP; - ttyDisplay->toplin = 3; /* special prompt state */ + ttyDisplay->toplin = TOPLINE_SPECIAL_PROMPT; ttyDisplay->inread++; /* issue the prompt */ @@ -193,7 +193,7 @@ getlin_hook_proc hook; } else tty_nhbell(); } - ttyDisplay->toplin = 2; /* nonempty, no --More-- required */ + ttyDisplay->toplin = TOPLINE_NON_EMPTY; ttyDisplay->inread--; clear_nhwindow(WIN_MESSAGE); /* clean up after ourselves */ diff --git a/win/tty/topl.c b/win/tty/topl.c index 62fb3eb53..d2a889cc9 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -138,7 +138,7 @@ const char *str; end_glyphout(); /* in case message printed during graphics output */ putsyms(str); cl_end(); - ttyDisplay->toplin = 1; + ttyDisplay->toplin = TOPLINE_NEED_MORE; if (ttyDisplay->cury && otoplin != 3) more(); } @@ -151,7 +151,7 @@ const char *str; struct WinDesc *cw = wins[WIN_MESSAGE]; if (!(cw->flags & WIN_STOP)) { - if (ttyDisplay->cury && ttyDisplay->toplin == 2) + if (ttyDisplay->cury && ttyDisplay->toplin == TOPLINE_NON_EMPTY) tty_clear_nhwindow(WIN_MESSAGE); cw->curx = cw->cury = 0; @@ -159,8 +159,8 @@ const char *str; cl_end(); addtopl(str); - if (ttyDisplay->cury && ttyDisplay->toplin != 3) - ttyDisplay->toplin = 2; + if (ttyDisplay->cury && ttyDisplay->toplin != TOPLINE_SPECIAL_PROMPT) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; } } @@ -196,7 +196,7 @@ const char *s; tty_curs(BASE_WINDOW, cw->curx + 1, cw->cury); putsyms(s); cl_end(); - ttyDisplay->toplin = 1; + ttyDisplay->toplin = TOPLINE_NEED_MORE; } void @@ -236,7 +236,7 @@ more() home(); cl_end(); } - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; ttyDisplay->inmore = 0; } @@ -252,7 +252,7 @@ register const char *bp; /* 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->flags & WIN_STOP)) + if ((ttyDisplay->toplin == TOPLINE_NEED_MORE || (cw->flags & WIN_STOP)) && cw->cury == 0 && n0 + (int) strlen(toplines) + 3 < CO - 8 /* room for --More-- */ && (notdied = strncmp(bp, "You die", 7)) != 0) { @@ -263,9 +263,9 @@ register const char *bp; addtopl(bp); return; } else if (!(cw->flags & WIN_STOP)) { - if (ttyDisplay->toplin == 1) { + if (ttyDisplay->toplin == TOPLINE_NEED_MORE) { more(); - } else if (cw->cury) { /* for when flags.toplin == 2 && cury > 1 */ + } else if (cw->cury) { /* for toplin == TOPLINE_NON_EMPTY && cury > 1 */ docorner(1, cw->cury + 1); /* reset cury = 0 if redraw screen */ cw->curx = cw->cury = 0; /* from home--cls() & docorner(1,n) */ } @@ -381,10 +381,10 @@ char def; char prompt[BUFSZ]; yn_number = 0L; - if (ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) + if (ttyDisplay->toplin == TOPLINE_NEED_MORE && !(cw->flags & WIN_STOP)) more(); cw->flags &= ~WIN_STOP; - ttyDisplay->toplin = 3; /* special prompt state */ + ttyDisplay->toplin = TOPLINE_SPECIAL_PROMPT; ttyDisplay->inread++; if (resp) { char *rb, respbuf[QBUFSZ]; @@ -531,7 +531,7 @@ char def; dumplogmsg(toplines); #endif ttyDisplay->inread--; - ttyDisplay->toplin = 2; + ttyDisplay->toplin = TOPLINE_NON_EMPTY; if (ttyDisplay->intr) ttyDisplay->intr--; if (wins[WIN_MESSAGE]->cury) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 1411839da..8ea315ab1 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -332,7 +332,7 @@ int sig_unused UNUSED; new_status_window(); if (u.ux) { i = ttyDisplay->toplin; - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; docrt(); bot(); ttyDisplay->toplin = i; @@ -420,7 +420,7 @@ char **argv UNUSED; /* set up tty descriptor */ ttyDisplay = (struct DisplayDesc *) alloc(sizeof (struct DisplayDesc)); - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; ttyDisplay->rows = hgt; ttyDisplay->cols = wid; ttyDisplay->curx = ttyDisplay->cury = 0; @@ -1621,12 +1621,12 @@ winid window; switch (cw->type) { case NHW_MESSAGE: - if (ttyDisplay->toplin) { + if (ttyDisplay->toplin != TOPLINE_EMPTY) { home(); cl_end(); if (cw->cury) docorner(1, cw->cury + 1); - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; } break; case NHW_STATUS: @@ -2317,12 +2317,13 @@ boolean blocking; /* with ttys, all windows are blocking */ switch (cw->type) { case NHW_MESSAGE: - if (ttyDisplay->toplin == 1) { + if (ttyDisplay->toplin == TOPLINE_NEED_MORE) { more(); - ttyDisplay->toplin = 1; /* more resets this */ + ttyDisplay->toplin = TOPLINE_NEED_MORE; /* more resets this */ tty_clear_nhwindow(window); + /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ } else - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; cw->curx = cw->cury = 0; if (!cw->active) iflags.window_inited = TRUE; @@ -2330,8 +2331,8 @@ boolean blocking; /* with ttys, all windows are blocking */ case NHW_MAP: end_glyphout(); if (blocking) { - if (!ttyDisplay->toplin) - ttyDisplay->toplin = 1; + if (ttyDisplay->toplin != TOPLINE_EMPTY) + ttyDisplay->toplin = TOPLINE_NEED_MORE; tty_display_nhwindow(WIN_MESSAGE, TRUE); return; } @@ -2361,7 +2362,7 @@ boolean blocking; /* with ttys, all windows are blocking */ cw->offx = 0; if (cw->type == NHW_MENU) cw->offy = 0; - if (ttyDisplay->toplin == 1) + if (ttyDisplay->toplin == TOPLINE_NEED_MORE) tty_display_nhwindow(WIN_MESSAGE, TRUE); #ifdef H2344_BROKEN if (cw->maxrow >= (int) ttyDisplay->rows @@ -2377,7 +2378,7 @@ boolean blocking; /* with ttys, all windows are blocking */ cl_eos(); } else clear_screen(); - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; } else { if (WIN_MESSAGE != WIN_ERR) tty_clear_nhwindow(WIN_MESSAGE); @@ -2406,8 +2407,9 @@ winid window; switch (cw->type) { case NHW_MESSAGE: - if (ttyDisplay->toplin) + if (ttyDisplay->toplin != TOPLINE_EMPTY) tty_display_nhwindow(WIN_MESSAGE, TRUE); + /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ /*FALLTHRU*/ case NHW_STATUS: case NHW_BASE: @@ -3158,10 +3160,11 @@ const char *mesg; response to a prompt, we'll assume that the display is up to date */ tty_putstr(WIN_MESSAGE, 0, mesg); /* if `mesg' didn't wrap (triggering --More--), force --More-- now */ - if (ttyDisplay->toplin == 1) { + if (ttyDisplay->toplin == TOPLINE_NEED_MORE) { more(); - ttyDisplay->toplin = 1; /* more resets this */ + ttyDisplay->toplin = TOPLINE_NEED_MORE; /* more resets this */ tty_clear_nhwindow(WIN_MESSAGE); + /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ } /* normally means skip further messages, but in this case it means cancel the current prompt; any other messages should @@ -3201,7 +3204,7 @@ tty_wait_synch() (void) fflush(stdout); } else if (ttyDisplay->inread > program_state.gameover) { /* this can only happen if we were reading and got interrupted */ - ttyDisplay->toplin = 3; + ttyDisplay->toplin = TOPLINE_SPECIAL_PROMPT; /* do this twice; 1st time gets the Quit? message again */ (void) tty_doprev_message(); (void) tty_doprev_message(); @@ -3530,8 +3533,9 @@ tty_nhgetch() i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ else if (i == EOF) i = '\033'; /* same for EOF */ - if (ttyDisplay && ttyDisplay->toplin == 1) - ttyDisplay->toplin = 2; + /* topline has been seen - we can clear need for more */ + if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; #ifdef TTY_TILES_ESCCODES { /* hack to force output of the window select code */ @@ -3610,8 +3614,9 @@ tty_nhgetch() i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ else if (i == EOF) i = '\033'; /* same for EOF */ - if (ttyDisplay && ttyDisplay->toplin == 1) - ttyDisplay->toplin = 2; + /* topline has been seen - we can clear need for more */ + if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; #ifdef TTY_TILES_ESCCODES { /* hack to force output of the window select code */ @@ -3656,8 +3661,9 @@ int *x, *y, *mod; i = ntposkey(x, y, mod); if (!i && mod && (*mod == 0 || *mod == EOF)) i = '\033'; /* map NUL or EOF to ESC, nethack doesn't expect either */ - if (ttyDisplay && ttyDisplay->toplin == 1) - ttyDisplay->toplin = 2; + /* topline has been seen - we can clear need for more */ + if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; #else /* !WIN32CON */ nhUse(x); nhUse(y); From 188eedc65458e9646569c794f816515f5cb3a35b Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 11 Jul 2019 01:02:34 -0700 Subject: [PATCH 2/3] curses: #extended command vs erase/kill chars Support erase char and kill char when getting an extended command. Also, show the cursor so that it's obvious where input focus is. --- doc/fixes36.3 | 3 ++- win/curses/cursdial.c | 26 ++++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 3d8a5ed9e..391e849da 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.92 $ $NHDT-Date: 1562806584 2019/07/11 00:56:24 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.93 $ $NHDT-Date: 1562832141 2019/07/11 08:02:21 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -175,6 +175,7 @@ curses: when map window was clipped, the 'scrollbars' shown to indicate which the 2nd and 3rd fifths (for example) were currently within view curses: support users's setting for erase char and kill char when getting a line of input with 'popup_dialog' Off (already supported for popup On) +curses: support erase char and kill char when choosing an extended command curses: attempting to use ^H to rush left actually executed ^G (#wizgenesis) curses: disable the attempt to support Ctrl+Left_click as an alternate way to generate Right_click for systems with one-button mouse or trackpad; diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 7dccffa78..cb65610f5 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -17,6 +17,10 @@ #define strncasecmp strncmpi #endif +/* defined in sys//tty.c or cursmain.c as last resort; + set up by curses_init_nhwindows() */ +extern char erase_char, kill_char; + /* * Note: * @@ -412,7 +416,7 @@ curses_ext_cmd() wmove(extwin, starty, startx + 2); waddstr(extwin, cur_choice); wmove(extwin, starty, (int) strlen(cur_choice) + startx + 2); - wprintw(extwin, " "); + wclrtoeol(extwin); /* if we have an autocomplete command, AND it matches uniquely */ if (matches == 1) { @@ -421,12 +425,12 @@ curses_ext_cmd() wprintw(extwin, "%s", extcmdlist[ret].ef_txt + (int) strlen(cur_choice)); curses_toggle_color_attr(extwin, NONE, A_UNDERLINE, OFF); - mvwprintw(extwin, starty, - (int) strlen(extcmdlist[ret].ef_txt) + 2, " "); } + curs_set(1); wrefresh(extwin); letter = getch(); + curs_set(0); prompt_width = (int) strlen(cur_choice); matches = 0; @@ -448,8 +452,9 @@ curses_ext_cmd() } if (letter == '\177') /* DEL/Rubout */ - letter = '\b'; - if (letter == '\b' || letter == KEY_BACKSPACE) { + letter = '\b'; + if (letter == '\b' || letter == KEY_BACKSPACE + || (erase_char && letter == (int) (uchar) erase_char)) { if (prompt_width == 0) { ret = -1; break; @@ -458,7 +463,15 @@ curses_ext_cmd() letter = '*'; prompt_width--; } + + /* honor kill_char if it's ^U or similar, but not if it's '@' */ + } else if (kill_char && letter == (int) (uchar) kill_char + && (letter < ' ' || letter >= '\177')) { /*ASCII*/ + cur_choice[0] = '\0'; + letter = '*'; + prompt_width = 0; } + if (letter != '*' && prompt_width < maxlen) { cur_choice[prompt_width] = letter; cur_choice[prompt_width + 1] = '\0'; @@ -486,7 +499,8 @@ curses_ext_cmd() } curses_destroy_win(extwin); - if (extwin2) curses_destroy_win(extwin2); + if (extwin2) + curses_destroy_win(extwin2); return ret; } From bfbe4e71ce69ef562303d6d78caf91878c6043cf Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 11 Jul 2019 02:54:02 -0700 Subject: [PATCH 3/3] make #panic honor paranoid_confirmatin:quit If 'paranoid_confirmation:quit' is set, require "yes" instead of 'y' to execute the wizard mode #panic command. --- doc/Guidebook.mn | 21 +++++++++++++++++---- doc/Guidebook.tex | 26 ++++++++++++++++++++------ doc/fixes36.3 | 3 ++- src/cmd.c | 5 +++-- 4 files changed, 42 insertions(+), 13 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 9b215d2fb..ce6d40df0 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.311 $ $NHDT-Date: 1562719337 2019/07/10 00:42:17 $ +.\" $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.312 $ $NHDT-Date: 1562838836 2019/07/11 09:53:56 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines. @@ -1104,6 +1104,12 @@ Autocompletes. Default key is \(oqM-e\(cq. .lp #exploremode Enter the explore mode. +.lp "" +Requires confirmation; default response is \f(CRn\fP (no). +To really switch to explore mode, respond with \f(CRy\fP. +You can set the +.op paranoid_confirmation:quit +option to require a response of \f(CRyes\fP instead. .lp "#fire " Fire ammunition from quiver. Default key is \(oqf\(cq. @@ -1211,6 +1217,12 @@ Test the panic routine. Terminates the current game. Autocompletes. Debug mode only. +.lp "" +Asks for confirmation; default is \f(CRn\fP (no); continue playing. +To really panic, respond with \f(CRy\fP. +You can set the +.op paranoid_confirmation:quit +option to require a response of \f(CRyes\fP instead. .lp "#pay " Pay your shopping bill. Default key is \(oqp\(cq. @@ -1251,10 +1263,11 @@ Default key is \(oqM-q\(cq. .lp "" Since using this command by accident would throw away the current game, you are asked to confirm your intent before quitting. -By default a response of \(oqy\(cq acknowledges that intent. +Default response is \f(CRn\fP (no); continue playing. +To really quit, respond with \f(CRy\fP. You can set the -.op paranoid_confirmation -option to require a response of \(lqyes\(rq instead. +.op paranoid_confirmation:quit +option to require a response of \f(CRyes\fP instead. .lp "#quiver " Select ammunition for quiver. Default key is \(oqQ\(cq. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index d642cfed5..7cb9bf0b1 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1216,7 +1216,13 @@ Advance or check weapon and spell skills. Autocompletes. Default key is `{\tt M-e}'. %.lp \item[\tb{\#exploremode}] -Enter the explore mode. +Enter the explore mode.\\ +%.lp "" +Requires confirmation; default response is `{\tt n}' (no). +To really switch to explore mode, respond with `{\tt y}'. +You can set the +{\it paranoid\verb+_+confirmation:quit\/} +option to require a response of ``{\tt yes}'' instead. %.lp \item[\tb{\#fire}] Fire ammunition from quiver. Default key is `{\tt f}'. @@ -1324,7 +1330,13 @@ Default keys are `{\tt \^{}O}', and `{\tt M-O}'. Test the panic routine. Terminates the current game. Autocompletes. -Debug mode only. +Debug mode only.\\ +%.lp "" +Asks for confirmation; default is `{\tt n}' (no); continue playing. +To really panic, respond with `{\tt y}''. +You can set the +{\it paranoid\verb+_+confirmation:quit\/} +option to require a response of ``{\tt yes}'' instead. %.lp \item[\tb{\#pay}] Pay your shopping bill. Default key is `{\tt p}'. @@ -1361,12 +1373,14 @@ Quaff (drink) something. Default key is `{\tt q}'. %.lp \item[\tb{\#quit}] Quit the program without saving your game. Autocompletes. -Default key is `{\tt M-q}'. +Default key is `{\tt M-q}'.\\ %.lp "" Since using this command by accident would throw away the current game, -you are asked to confirm your intent before quitting. By default a -response of `{\tt y}' acknowledges that intent. You can set the -{\it paranoid\verb+_+confirmation\/} +you are asked to confirm your intent before quitting. +Default response is `{\tt n}' (no); continue playing. +To really quit, respond with `{\tt y}'. +You can set the +{\it paranoid\verb+_+confirmation:quit\/} option to require a response of ``{\tt yes}'' instead. %.lp \item[\tb{\#quiver}] diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 391e849da..909dbd345 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.93 $ $NHDT-Date: 1562832141 2019/07/11 08:02:21 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.94 $ $NHDT-Date: 1562838835 2019/07/11 09:53:55 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -104,6 +104,7 @@ detect unseen/secret door detection/^E failed to find monsters hiding under when farlook describes a monster at a visible spot as trapped, reveal the trap fix theft when poly'd into nymph form; 3.6.2 change made that anger the victim hero poly'd into nymph would steal gold along with other items +change wizard mode #panic to require "yes" if 'paranoid_confirm:quit' is set Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/cmd.c b/src/cmd.c index b4f613de1..d577d8e91 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1562532731 2019/07/07 20:52:11 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.339 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1562838823 2019/07/11 09:53:43 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.340 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1002,7 +1002,8 @@ wiz_panic(VOID_ARGS) u.uen = u.uenmax = 1000; return 0; } - if (yn("Do you want to call panic() and end your game?") == 'y') + if (paranoid_query(ParanoidQuit, + "Do you want to call panic() and end your game?")) panic("Crash test."); return 0; }