diff --git a/include/decl.h b/include/decl.h index 662821287..642989027 100644 --- a/include/decl.h +++ b/include/decl.h @@ -101,6 +101,7 @@ struct sinfo { int in_self_recover; int in_parseoptions; /* in parseoptions */ int config_error_ready; /* config_error_add is ready, available */ + int beyond_savefile_load; /* set when past savefile loading */ #ifdef PANICLOG int in_paniclog; #endif @@ -1262,6 +1263,8 @@ struct instance_globals { /* per-level glyph mapping flags */ long glyphmap_perlevel_flags; + int early_raw_messages; /* if raw_prints occurred early prior + to g.beyond_savefile_load */ unsigned long magic; /* validate that structure layout is preserved */ }; diff --git a/src/decl.c b/src/decl.c index 5cf81733a..a38095876 100644 --- a/src/decl.c +++ b/src/decl.c @@ -693,6 +693,7 @@ const struct instance_globals g_init = { /* per-level glyph mapping flags */ 0L, /* glyphmap_perlevel_flags */ + 0, /* early_raw_messages */ IVMAGIC /* used to validate that structure layout has been preserved */ }; diff --git a/src/pline.c b/src/pline.c index 3fac368d8..24dcc49a8 100644 --- a/src/pline.c +++ b/src/pline.c @@ -462,6 +462,8 @@ raw_printf(const char *line, ...) va_start(the_args, line); vraw_printf(line, the_args); va_end(the_args); + if (!g.program_state.beyond_savefile_load) + g.early_raw_messages++; } DISABLE_WARNING_FORMAT_NONLITERAL @@ -489,6 +491,8 @@ vraw_printf(const char *line, va_list the_args) #if defined(MSGHANDLER) execplinehandler(line); #endif + if (!g.program_state.beyond_savefile_load) + g.early_raw_messages++; } void diff --git a/src/restore.c b/src/restore.c index 51d068656..31d07b141 100644 --- a/src/restore.c +++ b/src/restore.c @@ -870,6 +870,17 @@ dorecover(NHFILE* nhfp) run_timers(); /* expire all timers that have gone off while away */ g.program_state.restoring = 0; /* affects bot() so clear before docrt() */ + + if (g.early_raw_messages && !g.program_state.beyond_savefile_load) { + /* + * We're about to obliterate some potentially important + * startup messages, so give the player a chance to see them. + */ + g.early_raw_messages = 0; + wait_synch(); + } + g.program_state.beyond_savefile_load = 0; + docrt(); clear_nhwindow(WIN_MESSAGE); diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 53fe67df1..6f9dc42e0 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -235,7 +235,12 @@ main(int argc, char *argv[]) iflags.news = FALSE; /* in case dorecover() fails */ } #endif - pline("Restoring save file..."); + /* if there are early trouble-messages issued, let's + * not go overtop of them with a pline just yet */ + if (g.early_raw_messages) + raw_print("Restoring save file..."); + else + pline("Restoring save file..."); mark_synch(); /* flush output */ if (dorecover(nhfp)) { resuming = TRUE; /* not starting new game */ diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index cd8a7daa8..c44da845b 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -171,7 +171,7 @@ getlock(void) /* this is a candidate for paranoid_confirmation */ c = yn(destroy_old_game_prompt); } else { - (void) printf("\n%s [yn] ", destroy_old_game_prompt); + (void) raw_printf("\n%s [yn] ", destroy_old_game_prompt); (void) fflush(stdout); if ((c = getchar()) != EOF) { int tmp; diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index ec0ca58c1..f67826287 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -625,7 +625,10 @@ attempt_restore: iflags.news = FALSE; } #endif - pline("Restoring save file..."); + if (g.early_raw_messages) + raw_print("Restoring save file..."); + else + pline("Restoring save file..."); mark_synch(); /* flush output */ if (dorecover(nhfp)) { resuming = TRUE; /* not starting new game */ @@ -1193,7 +1196,7 @@ getlock(void) : "not start a new game"); if (istty) clear_screen(); - pline(oops); + raw_printf("%s", oops); if (prompt_result == 1) { /* recover */ if (recover_savefile()) { #if 0 diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index b6185801a..78125da75 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -469,6 +469,7 @@ windows_console_custom_nhgetch(void) return _getch(); } +extern int windows_console_custom_nhgetch(void); void getreturn(const char *str) @@ -481,6 +482,8 @@ getreturn(const char *str) in_getreturn = TRUE; Sprintf(buf,"Hit %s.", str); raw_print(buf); + if (WINDOWPORT("tty")) + windows_console_custom_nhgetch(); wait_synch(); in_getreturn = FALSE; return; diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 89ad67f1b..f7c22458e 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -115,12 +115,12 @@ struct window_procs tty_procs = { | WC2_HILITE_STATUS | WC2_HITPOINTBAR | WC2_FLUSH_STATUS | WC2_RESET_STATUS #endif - | WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_URGENT_MESG | WC2_STATUSLINES) + | WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_URGENT_MESG | WC2_STATUSLINES | WC2_U_UTF8STR #if !defined(NO_TERMS) || defined(WIN32) | WC2_U_24BITCOLOR #endif - , + ), #ifdef TEXTCOLOR {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ #else @@ -481,12 +481,29 @@ tty_init_nhwindows(int *argcp UNUSED, char **argv UNUSED) tty_clear_nhwindow(BASE_WINDOW); - tty_putstr(BASE_WINDOW, 0, ""); + /* Once pline() is functional, error-related prompts such as + * those relating to save files etc. can intrude on the + * copyright information display because their prompts are + * up at the very top in the message window. + * Move the copyright information a little further down to + * row 3, out of the way. */ + + tty_curs(BASE_WINDOW, 1, 4); for (i = 1; i <= 4; ++i) tty_putstr(BASE_WINDOW, 0, copyright_banner_line(i)); tty_putstr(BASE_WINDOW, 0, ""); tty_display_nhwindow(BASE_WINDOW, FALSE); + /* Move to a default location for the "Shall I pick .." player + * selection prompts, which also use the BASE_WINDOW. Leave + * room for as many as 3 unexpected raw_prints early startup + * messages above that. + * If there is a topline message prompt, before the + * "Shall I pick ..." prompt, the latter will end up appearing + * immediately after the topline message prompt. There should + * now be room. */ + tty_curs(BASE_WINDOW, 1, 11); + /* 'statuslines' defaults to set_in_config, allowed but invisible; make it dynamically settable if feasible, otherwise visible */ if (tty_procs.wincap2 & WC2_STATUSLINES)