]> granicus.if.org Git - nethack/commitdiff
fix self-recover prompting on windows
authornhmall <nhmall@nethack.org>
Wed, 4 Dec 2019 04:32:12 +0000 (23:32 -0500)
committernhmall <nhmall@nethack.org>
Wed, 4 Dec 2019 04:32:12 +0000 (23:32 -0500)
the prompting on Windows wasn't working correctly if a prior game had crashed
and the self-recover feature was trying to kick in. This impacts tty, curses,
and mswin (GUI).

doc/fixes36.3
include/extern.h
sys/winnt/Makefile.msc
sys/winnt/nttty.c
sys/winnt/windmain.c
win/share/safeproc.c

index baf32548d9d11bf6c1bda23bf4ba838f46659669..d0b52cd5d919e61b2735d755ce77cacf942397a9 100644 (file)
@@ -327,6 +327,7 @@ windows: fix --showpaths output for the data file which relies on being
        constructed programmatically to incorporate the version suffix
 windows+tty: add code to make keypad support for swap_yz behave (currently
        commented out in include/ntconf.h)
+windows: fix self-recover user prompting (tty, curses, mswin)
 
 
 Platform- and/or Interface-Specific Fixes or Features
index 88f71fed9211236a6370b60022e4560d8fba1ba0..0ac10abee629d3394b820a51b1956ca8dbf49d03 100644 (file)
@@ -1823,15 +1823,17 @@ E char *FDECL(dowhatdoes_core, (CHAR_P, char *));
 E int NDECL(dohelp);
 E int NDECL(dohistory);
 
-/* ### pcmain.c ### */
+/* ### xxmain.c ### */
 
 #if defined(MICRO) || defined(WIN32)
 #ifdef CHDIR
 E void FDECL(chdirx, (char *, BOOLEAN_P));
 #endif /* CHDIR */
 E boolean NDECL(authorize_wizard_mode);
-
 #endif /* MICRO || WIN32 */
+#if defined(WIN32)
+E int NDECL(getlock);
+#endif
 
 /* ### pcsys.c ### */
 
@@ -1869,10 +1871,10 @@ E void FDECL(msleep, (unsigned));
 
 #if defined(MICRO)
 E void FDECL(regularize, (char *));
-#endif /* MICRO */
 #if defined(PC_LOCKING)
 E void NDECL(getlock);
 #endif
+#endif /* MICRO */
 
 /* ### pickup.c ### */
 
index 8e0da5bd49af36b32d4889f3c1729ad092b1e10c..550c71fc07daba70972e2458315d8f696fbdc677 100644 (file)
@@ -73,7 +73,7 @@ DEBUGINFO = Y
 #    of your PDCurses C files.
 #
 #ADD_CURSES=Y
-#PDCURSES_TOP=..\..\pdcurses
+#PDCURSES_TOP=..\lib\pdcurses
 #
 #==============================================================================
 # This marks the end of the BUILD DECISIONS section.
index 9c96ae8a4bac43951ab44b449d6d4fa02e52cf8e..2760b549365fb26c67812c423a697685e2b34de9 100644 (file)
@@ -680,13 +680,37 @@ cl_end()
 void
 raw_clear_screen()
 {
-    buffer_fill_to_end(console.back_buffer, &clear_cell, 0, 0);
+    if (WINDOWPORT("tty")) {
+        cell_t * back = console.back_buffer;
+        cell_t * front = console.front_buffer;
+        COORD pos;
+        DWORD unused;
+
+        for (pos.Y = 0; pos.Y < console.height; pos.Y++) {
+            for (pos.X = 0; pos.X < console.width; pos.X++) {
+                 WriteConsoleOutputAttribute(console.hConOut, &back->attribute,
+                                             1, pos, &unused);
+                 front->attribute = back->attribute;
+                 if (console.has_unicode) {
+                     WriteConsoleOutputCharacterW(console.hConOut,
+                             &back->character, 1, pos, &unused);
+                 } else {
+                     char ch = (char)back->character;
+                     WriteConsoleOutputCharacterA(console.hConOut, &ch, 1, pos,
+                                                         &unused);
+                 }
+                 *front = *back;
+                 back++;
+                 front++;
+            }
+        }
+    }
 }
 
 void
 clear_screen()
 {
-    raw_clear_screen();
+    buffer_fill_to_end(console.back_buffer, &clear_cell, 0, 0);    
     home();
 }
 
index 5fba32d744a97bd5f5bb79a2987d4827a79a203b..332d363ddda88ebba5cd788d94dbec1873cdb5bd 100644 (file)
@@ -39,6 +39,13 @@ extern void NDECL(backsp);
 extern void NDECL(clear_screen);
 #undef E
 
+#ifdef _MSC_VER
+#ifdef kbhit
+#undef kbhit
+#endif
+#include <conio.h.>
+#endif
+
 #ifdef PC_LOCKING
 static int NDECL(eraseoldlocks);
 #endif
@@ -50,6 +57,8 @@ char FDECL(windows_yn_function, (const char *, const char *, CHAR_P));
 static void FDECL(windows_getlin, (const char *, char *));
 extern int NDECL(windows_console_custom_nhgetch);
 void NDECL(safe_routines);
+int NDECL(tty_self_recover_prompt);
+int NDECL(other_self_recover_prompt);
 
 char orgdir[PATHLEN];
 boolean getreturn_enabled;
@@ -460,7 +469,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
         fnamebuf, encodedfnamebuf, BUFSZ);
     Sprintf(lock, "%s", encodedfnamebuf);
     /* regularize(lock); */ /* we encode now, rather than substitute */
-    getlock();
+    if (getlock() == 0)
+        nethack_exit(EXIT_SUCCESS);
 
     /* Set up level 0 file to keep the game state.
      */
@@ -997,15 +1007,16 @@ eraseoldlocks()
     return (1);   /* success! */
 }
 
-void
+int
 getlock()
 {
-    register int fd, c, ci, ct, ern;
+    register int fd, ern, prompt_result = 0;
     int fcmask = FCMASK;
     char tbuf[BUFSZ];
     const char *fq_lock;
 #define OOPS_BUFSZ 512
     char oops[OOPS_BUFSZ];
+    boolean istty = WINDOWPORT("tty");
 
     /* we ignore QUIT and INT at this point */
     if (!lock_file(HLOCK, LOCKPREFIX, 10)) {
@@ -1050,56 +1061,41 @@ getlock()
 
     (void) nhclose(fd);
 
-    if (iflags.window_inited || WINDOWPORT("curses")) {
-#ifdef SELF_RECOVER
-        c = yn("There are files from a game in progress under your name. "
-               "Recover?");
-#else
-        pline("There is already a game in progress under your name.");
-        pline("You may be able to use \"recover %s\" to get it back.\n",
-              tbuf);
-        c = yn("Do you want to destroy the old game?");
-#endif
-    } else {
-        c = 'n';
-        ct = 0;
-#ifdef SELF_RECOVER
-        raw_print("There are files from a game in progress under your name. "
-              "Recover? [yn]");
-#else
-        raw_print("\nThere is already a game in progress under your name.\n");
-        raw_print("If this is unexpected, you may be able to use \n");
-        raw_print("\"recover %s\" to get it back.", tbuf);
-        raw_print("\nDo you want to destroy the old game? [yn] ");
-#endif
-        while ((ci = nhgetch()) != '\n') {
-            if (ct > 0) {
-                raw_print("\b \b");
-                ct = 0;
-                c = 'n';
-            }
-            if (ci == 'y' || ci == 'n' || ci == 'Y' || ci == 'N') {
-                ct = 1;
-                c = ci;
-            }
-        }
-    }
-    if (c == 'y' || c == 'Y')
-#ifndef SELF_RECOVER
-        if (eraseoldlocks()) {
-            if (WINDOWPORT("tty"))
+    if (WINDOWPORT("tty"))
+        prompt_result = tty_self_recover_prompt();
+    else
+        prompt_result = other_self_recover_prompt();
+    /*
+     * prompt_result == 1  means recover old game.
+     * prompt_result == -1 means willfully destroy the old game.
+     * prompt_result == 0 should just exit.
+     */
+    Sprintf(oops, "You chose to %s.",
+                (prompt_result == -1)
+                    ? "destroy the old game and start a new one"
+                    : (prompt_result == 1)
+                        ? "recover the old game"
+                        : "not start a new game");
+    if (istty)
+        clear_screen();
+    pline(oops);
+    if (prompt_result == 1) {          /* recover */
+        if (recover_savefile()) {
+#if 0
+            if (istty)
                 clear_screen(); /* display gets fouled up otherwise */
+#endif
             goto gotlock;
         } else {
             unlock_file(HLOCK);
 #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
             chdirx(orgdir, 0);
 #endif
-            raw_print("Couldn't destroy old game.");
+            raw_print("Couldn't recover the old game.");
         }
-#else /*SELF_RECOVER*/
-        if (recover_savefile()) {
-            if (WINDOWPORT("tty"))
+    } else if (prompt_result < 0) {    /* destroy old game */
+        if (eraseoldlocks()) {
+            if (istty)
                 clear_screen(); /* display gets fouled up otherwise */
             goto gotlock;
         } else {
@@ -1107,16 +1103,15 @@ getlock()
 #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
             chdirx(orgdir, 0);
 #endif
-            raw_print("Couldn't recover old game.");
+            raw_print("Couldn't destroy the old game.");
+            return 0;
         }
-#endif /*SELF_RECOVER*/
-    else {
+    } else {
         unlock_file(HLOCK);
 #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
         chdirx(orgdir, 0);
 #endif
-        Sprintf(oops, "%s", "Cannot start a new game.");
-        raw_print(oops);
+        return 0;
     }
 
 gotlock:
@@ -1147,6 +1142,7 @@ gotlock:
             error("cannot close lock (%s)", fq_lock);
         }
     }
+    return 1;
 }
 #endif /* PC_LOCKING */
 
@@ -1187,4 +1183,133 @@ const char * b_path;
     return FALSE;
 }
 
+/*
+ * returns:
+ *     1 if game should be recovered
+ *    -1 if old game should be destroyed, allowing new game to proceed.
+ */
+int
+tty_self_recover_prompt()
+{
+    register int c, ci, ct, pl, retval = 0;
+    /* for saving/replacing functions, if needed */
+    struct window_procs saved_procs = {0};
+
+    pl = 1;
+    c = 'n';
+    ct = 0;
+    saved_procs = windowprocs;
+    safe_routines();
+    raw_print("\n");
+    raw_print("\n");
+    raw_print("\n");
+    raw_print("\n");
+    raw_print("\n");
+    raw_print("There are files from a game in progress under your name. ");
+    raw_print("Recover? [yn] ");
+
+ tty_ask_again:
+
+    while ((ci = nhgetch()) && !(ci == '\n' || ci == 13)) {
+        if (ct > 0) {
+            /* invalid answer */
+            raw_print("\b \b");
+            ct = 0;
+            c = 'n';
+        }
+        if (ci == 'y' || ci == 'n' || ci == 'Y' || ci == 'N') {
+            ct = 1;
+            c = ci;
+#ifdef _MSC_VER
+            _putch(ci);
+#endif
+        }
+    }
+
+    if (pl == 1 && (c == 'n' || c == 'N')) {
+        /* no to recover */
+        raw_print("\n\nAre you sure you wish to destroy the old game rather than try to\n");
+        raw_print("recover it? [yn] ");
+        c = 'n';
+        ct = 0;
+        pl = 2;
+        goto tty_ask_again;
+    }
+
+    if (pl == 2 && (c == 'n' || c == 'N')) {
+        /* no to destruction of old game */
+        retval = 0;
+    } else {
+        /* only yes answers get here */
+        if (pl == 2)
+            retval = -1;  /* yes, do destroy the old game anyway */
+        else
+            retval = 1;   /* yes, do recover the old game */
+    }
+    if (saved_procs.name[0]) {
+        windowprocs = saved_procs;
+        raw_clear_screen();
+    }
+    return retval;
+}
+
+int
+other_self_recover_prompt()
+{
+    register int c, ci, ct, pl, retval = 0;
+    boolean ismswin = WINDOWPORT("mswin"),
+            iscurses = WINDOWPORT("curses");
+
+    pl = 1;
+    c = 'n';
+    ct = 0;
+    if (iflags.window_inited || WINDOWPORT("curses")) {
+        c = yn("There are files from a game in progress under your name. "
+               "Recover?");
+    } else {
+        c = 'n';
+        ct = 0;
+        raw_print("There are files from a game in progress under your name. "
+              "Recover? [yn]");
+    }
+
+ other_ask_again:
+
+    if (!ismswin && !iscurses) {
+        while ((ci = nhgetch()) && !(ci == '\n' || ci == 13)) {
+            if (ct > 0) {
+                /* invalid answer */
+                raw_print("\b \b");
+                ct = 0;
+                c = 'n';
+            }
+            if (ci == 'y' || ci == 'n' || ci == 'Y' || ci == 'N') {
+                ct = 1;
+                c = ci;
+            }
+        }
+    }
+    if (pl == 1 && (c == 'n' || c == 'N')) {
+        /* no to recover */
+        c = yn("Are you sure you wish to destroy the old game, rather than try to "
+                  "recover it? [yn] ");
+        pl = 2;
+        if (!ismswin && !iscurses) {
+            c = 'n';
+            ct = 0;
+            goto other_ask_again;
+        }
+    }
+    if (pl == 2 && (c == 'n' || c == 'N')) {
+        /* no to destruction of old game */
+        retval = 0;
+    } else {
+        /* only yes answers get here */
+        if (pl == 2)
+            retval = -1;  /* yes, do destroy the old game anyway */
+        else
+            retval = 1;   /* yes, do recover the old game */
+    }
+    return retval;
+}
 /*windmain.c*/
index b0f75220a2784d8659bc9b9ffa58907715fb8150..28896c9c26ac3eff8c509fa07efed5db855e23e5 100644 (file)
@@ -538,7 +538,7 @@ stdio_raw_print(str)
 const char *str;
 {
     if (str)
-        fprintf(stdout, "%s\n", str);
+        fprintf(stdout, "%s", str);
     return;
 }