curses: save/restore message history

Have the curses interface save and restore message history for use
by ^P.  It doesn't spit the saved messages out into the visible
message window after restore; that's too distracting.
This commit is contained in:
PatR
2019-03-29 17:03:03 -07:00
parent 14d8ed199e
commit 68542da636
5 changed files with 103 additions and 3 deletions

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.289 $ $NHDT-Date: 1553895318 2019/03/29 21:35:18 $
$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.290 $ $NHDT-Date: 1553904170 2019/03/30 00:02:50 $
This fixes36.2 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.1 in April 2018. Please note, however,
@@ -523,6 +523,7 @@ curses: the memory deallocation was releasing previous messages when curses
curses: popup window to show ^P output was removed from screen but never
deleted; further ^P's repeated that cycle; likewise for help which
displays an external text file
curses: preserve ^P message history across save/restore
vms: add compile of isaac64.c to Makefile.src and vmsbuild.com
vms+curses: add compile support but it is known to fail to build

View File

@@ -222,6 +222,8 @@ extern void curses_init_mesg_history(void);
extern void curses_teardown_messages(void);
extern void curses_prev_mesg(void);
extern void curses_count_window(const char *count_text);
char *curses_getmsghistory(BOOLEAN_P);
void curses_putmsghistory(const char *, BOOLEAN_P);
#endif /* WINCURS_H */

View File

@@ -72,8 +72,8 @@ struct window_procs curses_procs = {
curses_end_screen,
genl_outrip,
curses_preference_update,
genl_getmsghistory,
genl_putmsghistory,
curses_getmsghistory,
curses_putmsghistory,
curses_status_init,
curses_status_finish,
genl_status_enablefield,

View File

@@ -693,4 +693,99 @@ get_msg_line(boolean reverse, int mindex)
return current_mesg;
}
/* save/restore code retrieves one ^P message at a time during save and
puts it into save file; if any new messages are added to the list while
that is taking place, the results are likely to be scrambled */
char *
curses_getmsghistory(init)
boolean init;
{
static int nxtidx;
nhprev_mesg *mesg;
if (init)
nxtidx = 0;
else
++nxtidx;
if (nxtidx < num_messages) {
/* we could encode mesg->turn with the text of the message,
but then that text might need to be truncated, and more
significantly, restoring the save file with another
interface wouldn't know how find and decode or remove it;
likewise, restoring another interface's save file with
curses wouldn't find the expected turn info;
so, we live without that */
mesg = get_msg_line(FALSE, nxtidx);
} else
mesg = (nhprev_mesg *) 0;
return mesg ? mesg->str : (char *) 0;
}
/*
* This is called by the core savefile restore routines.
* Each time we are called, we stuff the string into our message
* history recall buffer. The core will send the oldest message
* first (actually it sends them in the order they exist in the
* save file, but that is supposed to be the oldest first).
* These messages get pushed behind any which have been issued
* during this session since they come from a previous session
* and logically precede anything (like "Restoring save file...")
* that's happened now.
*
* Called with a null pointer to finish up restoration.
*
* It's also called by the quest pager code when a block message
* has a one-line summary specified. We put that line directly
* into message history for ^P recall without having displayed it.
*/
void
curses_putmsghistory(msg, restoring_msghist)
const char *msg;
boolean restoring_msghist;
{
static boolean initd = FALSE;
static int stash_count;
static nhprev_mesg *stash_head = 0;
if (restoring_msghist && !initd) {
/* hide any messages we've gathered since starting current session
so that the ^P data will start out empty as we add ones being
restored from save file; we'll put these back after that's done */
stash_count = num_messages, num_messages = 0;
stash_head = first_mesg, first_mesg = (nhprev_mesg *) 0;
last_mesg = (nhprev_mesg *) 0; /* no need to remember the tail */
initd = TRUE;
}
if (msg) {
mesg_add_line(msg);
/* treat all saved and restored messages as turn #1 */
last_mesg->turn = 1L;
} else if (stash_count) {
nhprev_mesg *mesg;
long mesg_turn;
/* put any messages generated during the beginning of the current
session back; they logically follow any from the previous
session's save file */
while (stash_count > 0) {
/* we could manipulate the linked list directly but treating
stashed messages as newly occurring ones is much simpler;
we ignore the backlinks because the list is destroyed as it
gets processed hence there can't be any other traversals */
mesg = stash_head;
stash_head = mesg->next_mesg;
--stash_count;
mesg_turn = mesg->turn;
mesg_add_line(mesg->str);
last_mesg->turn = mesg_turn;
free((genericptr_t) mesg->str);
free((genericptr_t) mesg);
}
initd = FALSE; /* reset */
}
}
/*cursmesg.c*/

View File

@@ -18,5 +18,7 @@ void curses_last_messages(void);
void curses_init_mesg_history(void);
void curses_prev_mesg(void);
void curses_count_window(const char *count_text);
char *curses_getmsghistory(BOOLEAN_P);
void curses_putmsghistory(const char *, BOOLEAN_P);
#endif /* CURSMESG_H */