fix self-recover prompting on windows
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).
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 ### */
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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"))
|
||||
clear_screen(); /* display gets fouled up otherwise */
|
||||
goto gotlock;
|
||||
} else {
|
||||
unlock_file(HLOCK);
|
||||
#if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS)
|
||||
chdirx(orgdir, 0);
|
||||
#endif
|
||||
raw_print("Couldn't destroy old game.");
|
||||
}
|
||||
#else /*SELF_RECOVER*/
|
||||
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 (WINDOWPORT("tty"))
|
||||
#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 recover the old game.");
|
||||
}
|
||||
} 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*/
|
||||
|
||||
@@ -538,7 +538,7 @@ stdio_raw_print(str)
|
||||
const char *str;
|
||||
{
|
||||
if (str)
|
||||
fprintf(stdout, "%s\n", str);
|
||||
fprintf(stdout, "%s", str);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user