diff --git a/doc/fixes36.2 b/doc/fixes36.2 index ce18f2e31..edbd2c4ca 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -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 diff --git a/include/wincurs.h b/include/wincurs.h index 79893ddcd..165facaba 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -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 */ diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 100719370..8dba85a93 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -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, diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index ccbc6f1e0..57cc5636b 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -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*/ diff --git a/win/curses/cursmesg.h b/win/curses/cursmesg.h index f6002356d..803b0fb5b 100644 --- a/win/curses/cursmesg.h +++ b/win/curses/cursmesg.h @@ -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 */