]> granicus.if.org Git - nethack/commitdiff
tty prompting fix and DUMPLOG of prompts+answers
authorPatR <rankin@nethack.org>
Tue, 21 Mar 2017 02:11:48 +0000 (19:11 -0700)
committerPatR <rankin@nethack.org>
Tue, 21 Mar 2017 02:11:48 +0000 (19:11 -0700)
Update DUMPLOG's message history to include player responses to
most queries.  For tty, both getlin() and yn_function().  For other
interfaces, only yn_function() is covered.  (It's intercepted by a
core routine that can take care of the logging; getlin() isn't.)
Also includes saved messages from previous session(s), for the
interfaces which support that (tty), to fill out the logging when
a game ends shortly after a save/restore cycle.

The tty interface was using pline() to display prompt strings.
Having 'MSGTYPE=hide "#"' or 'MSGTYPE=hide "yn"' in .nethackrc
would suppress many prompt strings (in the two examples mentioned,
entering extended commands or the vast majority of yes/no questions,
respectively) and generally lead to substantial confusion even if
done intentionally, so switch to putstr(WIN_MESSAGE) instead.

doc/fixes36.1
include/extern.h
src/cmd.c
src/invent.c
win/tty/getline.c
win/tty/topl.c

index 179ac4fee8ed7c6fa8714470082950009568fb76..63c80b848da82b829ff5b5c5d0e03290544c8326 100644 (file)
@@ -426,6 +426,7 @@ tty: if "--More--" was written to leftmost column (beginning of second line)
        of status line instead back on map) after message line was cleared
 tty: long message lines which wrap when shown on the top line might be
        re-displayed incorrectly by ^P for msg_window={full,combo,reverse}
+tty: MSGTYPE=hide could interfere with display of prompts
 unix/X11: in top level Makefile, some commented out definitions of VARDATND
        misspelled pilemark.xbm (as pilemark.xpm)
 unix: options file with CR+LF line ends and an invalid option line resulted in
@@ -570,7 +571,8 @@ Ray Chason's MS-DOS port restored to functionality with credit to Reddit user
 Ray Chason's MSDOS port support for some VESA modes
 Darshan Shaligram's pet ranged attack
 Jason Dorje Short's key rebinding
-Maxime Bacoux's new dumplog
+Maxime Bacoux's new DUMPLOG: compile-time option to enable logging of
+        end-of-game information into a text file
 
 
 Code Cleanup and Reorganization
index 3f5b3497147c1d659b79a31d41f6ea8c559daf95..fb3b7dfa42b6512bb1d357e49b1794c46d762dda 100644 (file)
@@ -211,7 +211,7 @@ E int FDECL(isok, (int, int));
 E int FDECL(get_adjacent_loc,
             (const char *, const char *, XCHAR_P, XCHAR_P, coord *));
 E const char *FDECL(click_to_cmd, (int, int, int));
-E char FDECL(get_count, (char *, CHAR_P, long, long *));
+E char FDECL(get_count, (char *, CHAR_P, long, long *, BOOLEAN_P));
 #ifdef HANGUPHANDLING
 E void FDECL(hangup, (int));
 E void NDECL(end_of_input);
index 19dcf68529739a308cf7f59bd17f9a018617f619..f9473e6a71ce2698063da29c95ac7a0effbbe5be 100644 (file)
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -4571,11 +4571,12 @@ int x, y, mod;
 }
 
 char
-get_count(allowchars, inkey, maxcount, count)
+get_count(allowchars, inkey, maxcount, count, historical)
 char *allowchars;
 char inkey;
 long maxcount;
 long *count;
+boolean historical; /* whether to include in message history: True => yes */
 {
     char qbuf[QBUFSZ];
     int key;
@@ -4616,10 +4617,19 @@ long *count;
                 Sprintf(qbuf, "Count: %ld", cnt);
                 backspaced = FALSE;
             }
-            pline1(qbuf);
+            /* bypassing pline() keeps intermediate prompt out of
+               DUMPLOG message history */
+            putstr(WIN_MESSAGE, 0, qbuf);
             mark_synch();
         }
     }
+
+    if (historical) {
+        Sprintf(qbuf, "Count: %ld ", *count);
+        (void) key2txt((uchar) key, eos(qbuf));
+        putmsghistory(qbuf, FALSE);
+    }
+
     return key;
 }
 
@@ -4645,7 +4655,7 @@ parse()
     if (!Cmd.num_pad || (foo = readchar()) == Cmd.spkeys[NHKF_COUNT]) {
         long tmpmulti = multi;
 
-        foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti);
+        foo = get_count((char *) 0, '\0', LARGEST_INT, &tmpmulti, FALSE);
         last_multi = multi = tmpmulti;
     }
 #ifdef ALTMETA
@@ -4902,7 +4912,13 @@ yn_function(query, resp, def)
 const char *query, *resp;
 char def;
 {
-    char qbuf[QBUFSZ];
+    char res, qbuf[QBUFSZ];
+#ifdef DUMPLOG
+    extern unsigned saved_pline_index; /* pline.c */
+    unsigned idx = saved_pline_index;
+    /* buffer to hold query+space+formatted_single_char_response */
+    char dumplog_buf[QBUFSZ + 1 + 15]; /* [QBUFSZ+1+7] should suffice */
+#endif
 
     iflags.last_msg = PLNMSG_UNKNOWN; /* most recent pline is clobbered */
 
@@ -4914,7 +4930,18 @@ char def;
         Strcpy(&qbuf[QBUFSZ - 1 - 3], "...");
         query = qbuf;
     }
-    return (*windowprocs.win_yn_function)(query, resp, def);
+    res = (*windowprocs.win_yn_function)(query, resp, def);
+#ifdef DUMPLOG
+    if (idx == saved_pline_index) {
+        /* when idx is still the same as saved_pline_index, the interface
+           didn't put the prompt into saved_plines[]; we put a simplified
+           version in there now (without response choices or default) */
+        Sprintf(dumplog_buf, "%s ", query);
+        (void) key2txt((uchar) res, eos(dumplog_buf));
+        dumplogmsg(dumplog_buf);
+    }
+#endif
+    return res;
 }
 
 /* for paranoid_confirm:quit,die,attack prompting */
index fb0099bb8908e4f2b228a9b020fdc609f2f40aa3..added0caa2f1365e2baa9503fed8e515b3f296ea 100644 (file)
@@ -1313,7 +1313,7 @@ register const char *let, *word;
                 pline("No count allowed with this command.");
                 continue;
             }
-            ilet = get_count(NULL, ilet, LARGEST_INT, &tmpcnt);
+            ilet = get_count(NULL, ilet, LARGEST_INT, &tmpcnt, TRUE);
             if (tmpcnt) {
                 cnt = tmpcnt;
                 cntgiven = TRUE;
index 4d86f9a118cd5799deef7560c484fb0912d00235..8d61aabfe5df727cb1183a98b2e8315d8ec2db1e 100644 (file)
@@ -14,6 +14,7 @@
 #include "func_tab.h"
 
 char morc = 0; /* tell the outside world what char you chose */
+STATIC_VAR boolean suppress_history;
 STATIC_DCL boolean FDECL(ext_cmd_getlin_hook, (char *));
 
 typedef boolean FDECL((*getlin_hook_proc), (char *));
@@ -35,6 +36,7 @@ tty_getlin(query, bufp)
 const char *query;
 register char *bufp;
 {
+    suppress_history = FALSE;
     hooked_tty_getlin(query, bufp, (getlin_hook_proc) 0);
 }
 
@@ -48,13 +50,20 @@ getlin_hook_proc hook;
     register int c;
     struct WinDesc *cw = wins[WIN_MESSAGE];
     boolean doprev = 0;
+    char tmpbuf[BUFSZ]; /* [QBUFSZ+1] should suffice */
 
     if (ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP))
         more();
     cw->flags &= ~WIN_STOP;
     ttyDisplay->toplin = 3; /* special prompt state */
     ttyDisplay->inread++;
-    pline("%s ", query);
+    /*
+     * This used to use pline("%s ", query), but that made getline
+     * prompts be susceptible to suppression via the MSGTYPE mechanism.
+     * Having 'MSGTYPE=hide "# "' was particularly confusing.
+     */
+    Sprintf(tmpbuf, "%s ", query);
+    tty_putstr(WIN_MESSAGE, 0, tmpbuf);
     *obufp = 0;
     for (;;) {
         (void) fflush(stdout);
@@ -82,6 +91,7 @@ getlin_hook_proc hook;
         if (c == '\020') { /* ctrl-P */
             if (iflags.prevmsg_window != 's') {
                 int sav = ttyDisplay->inread;
+
                 ttyDisplay->inread = 0;
                 (void) tty_doprev_message();
                 ttyDisplay->inread = sav;
@@ -136,9 +146,9 @@ getlin_hook_proc hook;
 #endif /* not NEWAUTOCOMP */
             break;
         } else if (' ' <= (unsigned char) c && c != '\177'
+                   /* avoid isprint() - some people don't have it
+                      ' ' is not always a printing char */
                    && (bufp - obufp < BUFSZ - 1 && bufp - obufp < COLNO)) {
-/* avoid isprint() - some people don't have it
-   ' ' is not always a printing char */
 #ifdef NEWAUTOCOMP
             char *i = eos(bufp);
 
@@ -166,7 +176,7 @@ getlin_hook_proc hook;
 #endif /* NEWAUTOCOMP */
             }
         } else if (c == kill_char || c == '\177') { /* Robert Viduya */
-/* this test last - @ might be the kill_char */
+            /* this test last - @ might be the kill_char */
 #ifndef NEWAUTOCOMP
             while (bufp != obufp) {
                 bufp--;
@@ -185,6 +195,17 @@ getlin_hook_proc hook;
     ttyDisplay->toplin = 2; /* nonempty, no --More-- required */
     ttyDisplay->inread--;
     clear_nhwindow(WIN_MESSAGE); /* clean up after ourselves */
+
+    if (suppress_history) {
+        /* prevent next message from pushing current query+answer into
+           tty message history */
+        *toplines = '\0';
+#ifdef DUMPLOG
+    } else {
+        /* needed because we've bypassed pline() */
+        dumplogmsg(toplines);
+#endif
+    }
 }
 
 void
@@ -267,9 +288,14 @@ tty_get_ext_cmd()
 
     if (iflags.extmenu)
         return extcmd_via_menu();
-    /* maybe a runtime option? */
-    /* hooked_tty_getlin("#", buf, flags.cmd_comp ? ext_cmd_getlin_hook :
-     * (getlin_hook_proc) 0); */
+
+    suppress_history = TRUE;
+    /* maybe a runtime option?
+     * hooked_tty_getlin("#", buf,
+     *                   (flags.cmd_comp && !in_doagain)
+     *                      ? ext_cmd_getlin_hook
+     *                      : (getlin_hook_proc) 0);
+     */
     hooked_tty_getlin("#", buf, in_doagain ? (getlin_hook_proc) 0
                                            : ext_cmd_getlin_hook);
     (void) mungspaces(buf);
index dd6758a4e26bf71083c65dcdc232725481b99e15..cefc08f958609cb881d7b5e1c9ccebd079b30978 100644 (file)
@@ -331,6 +331,7 @@ register int n;
 
 extern char erase_char; /* from xxxtty.c; don't need kill_char */
 
+/* returns a single keystroke; also sets 'yn_number' */
 char
 tty_yn_function(query, resp, def)
 const char *query, *resp;
@@ -354,6 +355,7 @@ char def;
     boolean doprev = 0;
     char prompt[BUFSZ];
 
+    yn_number = 0L;
     if (ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP))
         more();
     cw->flags &= ~WIN_STOP;
@@ -383,11 +385,14 @@ char def;
         /* not pline("%s ", prompt);
            trailing space is wanted here in case of reprompt */
         Strcat(prompt, " ");
-        pline("%s", prompt);
+        /* pline("%s", prompt); -- see comment in hooked_tty_getlin() */
+        tty_putstr(WIN_MESSAGE, 0, prompt);
     } else {
         /* no restriction on allowed response, so always preserve case */
         /* preserve_case = TRUE; -- moot since we're jumping to the end */
-        pline("%s ", query);
+        /* pline("%s ", query); -- see above about tty_getlin() */
+        Sprintf(prompt, "%s ", query);
+        tty_putstr(WIN_MESSAGE, 0, prompt);
         q = readchar();
         goto clean_up;
     }
@@ -444,6 +449,7 @@ char def;
             char z, digit_string[2];
             int n_len = 0;
             long value = 0;
+
             addtopl("#"), n_len++;
             digit_string[1] = '\0';
             if (q != '#') {
@@ -491,11 +497,16 @@ char def;
         }
     } while (!q);
 
-    if (q != '#') {
-        Sprintf(rtmp, "%c", q);
-        addtopl(rtmp);
-    }
-clean_up:
+ clean_up:
+    if (yn_number)
+        Sprintf(rtmp, "#%ld", yn_number);
+    else
+        (void) key2txt(q, rtmp);
+    /* addtopl(rtmp); -- rewrite toplines instead */
+    Sprintf(toplines, "%s%s", prompt, rtmp);
+#ifdef DUMPLOG
+    dumplogmsg(toplines);
+#endif
     ttyDisplay->inread--;
     ttyDisplay->toplin = 2;
     if (ttyDisplay->intr)
@@ -636,6 +647,9 @@ boolean restoring_msghist;
 {
     static boolean initd = FALSE;
     int idx;
+#ifdef DUMPLOG
+    extern unsigned saved_pline_index; /* pline.c */
+#endif
 
     if (restoring_msghist && !initd) {
         /* we're restoring history from the previous session, but new
@@ -645,18 +659,27 @@ boolean restoring_msghist;
            restored ones are being put into place */
         msghistory_snapshot(TRUE);
         initd = TRUE;
+#ifdef DUMPLOG
+        /* this suffices; there's no need to scrub saved_pline[] pointers */
+        saved_pline_index = 0;
+#endif
     }
 
     if (msg) {
-        /* move most recent message to history, make this become most recent
-         */
+        /* move most recent message to history, make this become most recent */
         remember_topl();
         Strcpy(toplines, msg);
+#ifdef DUMPLOG
+        dumplogmsg(toplines);
+#endif
     } else if (snapshot_mesgs) {
         /* done putting arbitrary messages in; put the snapshot ones back */
         for (idx = 0; snapshot_mesgs[idx]; ++idx) {
             remember_topl();
             Strcpy(toplines, snapshot_mesgs[idx]);
+#ifdef DUMPLOG
+            dumplogmsg(toplines);
+#endif
         }
         /* now release the snapshot */
         free_msghistory_snapshot(TRUE);