add option idlecheckpoint
New experimental option This requires platform support to be useful. Currently an implementation for Windows TTY console is included. A Unix TTY implementation should be achievable I would think, but I haven't pursued that, at least not yet (contributions welcome). I'm not sure whether Qt or X11 interfaces offer a similar timeout capability.. How it works: When idlecheckpoint in on, if the wait for a new input is idle for 10 seconds (length of time to waite is controlled by IDLECHECKPOINT_WAIT_TIME #define in hack.h), save_currentstate() is called to bring everything up-to-date should a hangup or crash occur. The input wait then continues/resumes. The save_currentstate() call is only executed once per input request.
This commit is contained in:
@@ -681,6 +681,16 @@ typedef unsigned char uchar;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* experimential; if the platform/window-port supports it; when the game has
|
||||||
|
* started to wait for player input, and the wait lasts longer than
|
||||||
|
* IDLECHECKPOINT_WAIT_TIME seconds (defined in hack.h or *conf.h), the game
|
||||||
|
* will perform an update to the checkpoint file.
|
||||||
|
* Currently has support in:
|
||||||
|
* WIN32CON
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* #define IDLECHECKPOINT */
|
||||||
|
|
||||||
/* End of Section 4 */
|
/* End of Section 4 */
|
||||||
|
|
||||||
#ifdef TTY_TILES_ESCCODES
|
#ifdef TTY_TILES_ESCCODES
|
||||||
|
|||||||
@@ -246,6 +246,8 @@ struct instance_flags {
|
|||||||
* to input becoming taken over);
|
* to input becoming taken over);
|
||||||
* True => enable fuzzer when entering moveloop */
|
* True => enable fuzzer when entering moveloop */
|
||||||
boolean herecmd_menu; /* use menu when mouseclick on yourself */
|
boolean herecmd_menu; /* use menu when mouseclick on yourself */
|
||||||
|
boolean idlecheckpoint; /* platform should perform a checkpoint update
|
||||||
|
* if waiting for input longer than 10 seconds */
|
||||||
boolean invis_goldsym; /* gold symbol is ' '? */
|
boolean invis_goldsym; /* gold symbol is ' '? */
|
||||||
boolean in_lua; /* executing a lua script */
|
boolean in_lua; /* executing a lua script */
|
||||||
boolean lua_testing; /* doing lua tests */
|
boolean lua_testing; /* doing lua tests */
|
||||||
|
|||||||
@@ -588,6 +588,13 @@ enum inventory_counts {
|
|||||||
/* 2023/11/30 invlet_max is not yet used anywhere */
|
/* 2023/11/30 invlet_max is not yet used anywhere */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef IDLECHECKPOINT_WAIT_TIME
|
||||||
|
#define IDLECHECKPOINT_WAIT_TIME 10 /* seconds to wait before executing a checkpoint;
|
||||||
|
* always #define'd but only has meaning if
|
||||||
|
* IDLECHECKPOINT is defined.
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
|
|
||||||
struct kinfo {
|
struct kinfo {
|
||||||
struct kinfo *next; /* chain of delayed killers */
|
struct kinfo *next; /* chain of delayed killers */
|
||||||
int id; /* uprop keys to ID a delayed killer */
|
int id; /* uprop keys to ID a delayed killer */
|
||||||
|
|||||||
@@ -387,6 +387,9 @@ static int optfn_##a(int, int, boolean, char *, char *);
|
|||||||
Yes, Yes, No, No, NoAlias,
|
Yes, Yes, No, No, NoAlias,
|
||||||
"load IBMGraphics display symbols into symset")
|
"load IBMGraphics display symbols into symset")
|
||||||
#endif
|
#endif
|
||||||
|
NHOPTB(idlecheckpoint, Advanced, 0, opt_in, set_in_game,
|
||||||
|
Off, Yes, No, No, NoAlias, &iflags.idlecheckpoint, Term_Off,
|
||||||
|
"update checkpoint file if input is idle for 10 seconds")
|
||||||
#ifndef MAC
|
#ifndef MAC
|
||||||
NHOPTB(ignintr, Advanced, 0, opt_in, set_in_game,
|
NHOPTB(ignintr, Advanced, 0, opt_in, set_in_game,
|
||||||
Off, Yes, No, No, NoAlias, &flags.ignintr, Term_False,
|
Off, Yes, No, No, NoAlias, &flags.ignintr, Term_False,
|
||||||
|
|||||||
@@ -35,6 +35,10 @@
|
|||||||
#define EARLY_CONFIGFILE_PASS
|
#define EARLY_CONFIGFILE_PASS
|
||||||
#define TTY_PERM_INVENT
|
#define TTY_PERM_INVENT
|
||||||
|
|
||||||
|
#ifdef WIN32CON
|
||||||
|
#define IDLECHECKPOINT
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* -----------------------------------------------------------------
|
* -----------------------------------------------------------------
|
||||||
* The remaining code shouldn't need modification.
|
* The remaining code shouldn't need modification.
|
||||||
|
|||||||
@@ -5310,6 +5310,14 @@ optfn_boolean(
|
|||||||
#endif
|
#endif
|
||||||
go.opt_need_redraw = TRUE;
|
go.opt_need_redraw = TRUE;
|
||||||
break;
|
break;
|
||||||
|
#ifndef IDLECHECKPOINT
|
||||||
|
case opt_idlecheckpoint:
|
||||||
|
pline("There is no underlying support for 'idlecheckpoint'"
|
||||||
|
" compiled in.");
|
||||||
|
iflags.idlecheckpoint = FALSE;
|
||||||
|
give_opt_msg = FALSE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+57
-32
@@ -3097,7 +3097,8 @@ default_checkinput(
|
|||||||
DWORD dwWait;
|
DWORD dwWait;
|
||||||
#endif
|
#endif
|
||||||
int ch = 0;
|
int ch = 0;
|
||||||
boolean valid = 0, done = 0;
|
boolean valid = 0, done = 0, done_a_checkpoint = FALSE;
|
||||||
|
DWORD how_many_milliseconds = 0;
|
||||||
|
|
||||||
#ifdef QWERTZ_SUPPORT
|
#ifdef QWERTZ_SUPPORT
|
||||||
if (numberpad & 0x10) {
|
if (numberpad & 0x10) {
|
||||||
@@ -3107,54 +3108,78 @@ default_checkinput(
|
|||||||
qwertz = FALSE;
|
qwertz = FALSE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
done_a_checkpoint = FALSE;
|
||||||
|
how_many_milliseconds = (iflags.idlecheckpoint)
|
||||||
|
? (IDLECHECKPOINT_WAIT_TIME * 1000)
|
||||||
|
: INFINITE;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
#if defined(SAFERHANGUP)
|
|
||||||
dwWait = WaitForSingleObjectEx(hConIn, // event object to wait for
|
dwWait = WaitForSingleObjectEx(hConIn, // event object to wait for
|
||||||
INFINITE, // waits indefinitely
|
how_many_milliseconds,
|
||||||
TRUE); // alertable wait enabled
|
TRUE); // alertable wait enabled
|
||||||
|
#if defined(SAFERHANGUP)
|
||||||
if (dwWait == WAIT_FAILED)
|
if (dwWait == WAIT_FAILED)
|
||||||
return '\033';
|
return '\033';
|
||||||
#endif
|
#endif
|
||||||
ReadConsoleInput(hConIn, ir, 1, count);
|
#ifdef INSURANCE
|
||||||
if (mode == 0) {
|
if (iflags.idlecheckpoint
|
||||||
if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) {
|
&& dwWait == WAIT_TIMEOUT && !done_a_checkpoint) {
|
||||||
ch = default_processkeystroke(hConIn, ir, &valid, numberpad, 0);
|
/* no input for 30 seconds, so let's take
|
||||||
done = valid;
|
* advantage and do a game checkpoint,
|
||||||
}
|
* then resume the wait.
|
||||||
} else {
|
*/
|
||||||
if (*count > 0) {
|
save_currentstate();
|
||||||
if (ir->EventType == KEY_EVENT
|
done_a_checkpoint = TRUE;
|
||||||
|
} else
|
||||||
|
#endif /* INSURANCE */
|
||||||
|
{
|
||||||
|
ReadConsoleInput(hConIn, ir, 1, count);
|
||||||
|
if (mode == 0) {
|
||||||
|
if ((ir->EventType == KEY_EVENT)
|
||||||
&& ir->Event.KeyEvent.bKeyDown) {
|
&& ir->Event.KeyEvent.bKeyDown) {
|
||||||
|
ch = default_processkeystroke(hConIn, ir, &valid,
|
||||||
|
numberpad, 0);
|
||||||
|
done = valid;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (*count > 0) {
|
||||||
|
if (ir->EventType == KEY_EVENT
|
||||||
|
&& ir->Event.KeyEvent.bKeyDown) {
|
||||||
#ifdef QWERTZ_SUPPORT
|
#ifdef QWERTZ_SUPPORT
|
||||||
if (qwertz)
|
if (qwertz)
|
||||||
numberpad |= 0x10;
|
numberpad |= 0x10;
|
||||||
#endif
|
#endif
|
||||||
ch = default_processkeystroke(hConIn, ir, &valid, numberpad, 0);
|
ch = default_processkeystroke(hConIn, ir, &valid,
|
||||||
|
numberpad, 0);
|
||||||
#ifdef QWERTZ_SUPPORT
|
#ifdef QWERTZ_SUPPORT
|
||||||
numberpad &= ~0x10;
|
numberpad &= ~0x10;
|
||||||
#endif
|
#endif
|
||||||
if (valid)
|
if (valid)
|
||||||
return ch;
|
return ch;
|
||||||
} else if (ir->EventType == MOUSE_EVENT) {
|
} else if (ir->EventType == MOUSE_EVENT) {
|
||||||
if ((ir->Event.MouseEvent.dwEventFlags == 0)
|
if ((ir->Event.MouseEvent.dwEventFlags == 0)
|
||||||
&& (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) {
|
&& (ir->Event.MouseEvent.dwButtonState
|
||||||
cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1;
|
& MOUSEMASK)) {
|
||||||
cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1;
|
cc->x =
|
||||||
|
ir->Event.MouseEvent.dwMousePosition.X + 1;
|
||||||
|
cc->y =
|
||||||
|
ir->Event.MouseEvent.dwMousePosition.Y - 1;
|
||||||
|
|
||||||
if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON)
|
if (ir->Event.MouseEvent.dwButtonState
|
||||||
*mod = CLICK_1;
|
& LEFTBUTTON)
|
||||||
else if (ir->Event.MouseEvent.dwButtonState
|
*mod = CLICK_1;
|
||||||
& RIGHTBUTTON)
|
else if (ir->Event.MouseEvent.dwButtonState
|
||||||
*mod = CLICK_2;
|
& RIGHTBUTTON)
|
||||||
|
*mod = CLICK_2;
|
||||||
#if 0 /* middle button */
|
#if 0 /* middle button */
|
||||||
else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON)
|
else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON)
|
||||||
*mod = CLICK_3;
|
*mod = CLICK_3;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
} else
|
done = 1;
|
||||||
done = 1;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mode ? 0 : ch;
|
return mode ? 0 : ch;
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/
|
|||||||
if WINDOWPORT(tty) {
|
if WINDOWPORT(tty) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 20; ++i) {
|
for (i = 0; i < 5; ++i) {
|
||||||
nh_delay_output();
|
nh_delay_output();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user