When we were saving message history as part of a game save for insurance,
we were calling remember_topl() and thus inappropriately changing topline
state. This would cause us to mis-manage the topline in subsequent calls
to update the topline.
The code has been re-worked to fix the issue, reduce complexity and make
the code clearer.
When we save gamestate as part of making an insurance snapshot, we will
save message history which will clear toplines but leaving window state
in tack including the need for more.
When fuzzing, we would increment ttyDisplay->inmore but then prematurely
exit more() leaving ttyDisplay->inmore set.
Under various conditions, we can request to remember the topline when
the topline had not yet been acknowledged leaving toplin state in an
inappropriate state.
Messages on tty which bypass message history weren't handling long
lines properly. If the text wrapped to line 2, that continuation
portion was left on the screen after whatever operation that put it
here was finished. (To reproduce: assign a long name to a monster
with a long type name so that the combined length exceeds the display
width, then move the cursor over it with ';' or '/' while autodescribe
is On.)
This time prompting isn't adversely affected.
This effectively reverts 1ad2415315
because it was interfering with prompts that spanned more than one
line (by inserting '--More-- + erase' between displaying of prompt and
getting input for the answer).
So we're back to the situation where autodescribe feedback when moving
the cursor will leave text on the second line if it generates text too
wide for one line. (^R redraws the screen correctly.)
Messages on tty which bypass message history weren't handling long
lines properly. If the text wrapped to line 2, that continuation
portion was left on the screen after whatever operation that put it
here was finished. (To reproduce: assign a long name to a monster
with a long type name so that the combined length exceeds the display
width, then move the cursor over it with ';' or '/' while autodescribe
is On.)
Noticed while testing the history suppression: if you have DECgraphics
enabled and look at a graphics character on the map, the topline shows
x description of x
where 'x' is displayed as it appears on the map (line drawing char).
^P for msg_window:single knows about that and reproduces the effect if
you recall such a line. But msg_window:full/combination/reverse didn't
know about that and dumped it as-is into text output, ending up with a
strange 8-bit character for 'x' instead of the line drawing one.
I think other rendering schemes will be unaffected by this. It's just
duplicating what is done for msg_window:single.
Extend 'putstr(WIN_MESSAGE, attribute, string)'s attribute so that
'custompline(SUPPRESS_HISTORY, ...)' can work with ^P's message
history like DUMPLOG history, in order to keep autodescribe feedback
and intermediate prompts for multi-digit count ('Count: 12', 'Count:
123') prompts out of recall history. The old autodescribe behavior
could easily push all real messages out of the recall buffer when
moving the cursor around for getpos, and the count behavior looked
silly for a four or five digit gold count if you set the msg_window
option to 'full' or 'combination' and viewed them all at once.
Other interfaces may want to follow suit, but this doesn't force them
to make any changes. I added a hook for "urgent messages" that might
be rendered in bold or red or some such and/or override the use of
ESC at --More-- from suppressing further messages, but there aren't
any custompline(URGENT_MESSAGE, ...) calls (potentially "You die...",
for instance) to exercise it. Other people have implemented similar
feature it different ways and I'm not sure whether this one is really
the way to go since the core needs to categorize each message that it
deems to be urgent. MSG_TYPE:stop may be sufficent, although MSG_TYPE
matching can entail a lot of regexp execution overhead at run-time.
Add code to run a fuzz tester, simulating (more-or-less) random
keyboard mashing. There's no option to turn it on, you need to
set iflags.debug_fuzzer on via a debugger or something along
those lines.
I couldn't reproduce the reported problem of the "In what direction?"
being issued after the screen was cleared, but bypassing pline() in
favor of putstr(WIN_MESSAGE) for tty prompts did also bypass
if (vision_full_recalc) vision_recalc(0);
if (u.ux) flush_screen(1);
done in pline(). Inadvertent loss of the latter could conceivably be
responsible for the problem. If so, the escape code used by cl_end()
may be broken for somebody's termcap or terminfo setup since clearing
to the end of the line in the message window shouldn't erase the rest
of the screen.
Regardless, the prompting change also bypassed the ability to show
the prompt with raw_printf() if the display wasn't fully intialized
yet, so some change to the revised prompting was necessary anyway.
Switching back from putstr(WIN_MESSAGE) to pline() resulted in
duplicated entries in DUMPLOG message history, one with bare prompt
followed by another with response appended, so more tweaking was
needed. The result is use of new custompline() instead of normal
pline(). custompline() accepts some message handling flags to give
more control over pline()'s behavior. It's a more general variation
of Norep() but its caller needs to specify an extra argument.
Update DUMPLOG's message history to include player responses to
most queries. For tty, both getlin() and yn_function(). For other
interfaces, only yn_function() is covered. (It's intercepted by a
core routine that can take care of the logging; getlin() isn't.)
Also includes saved messages from previous session(s), for the
interfaces which support that (tty), to fill out the logging when
a game ends shortly after a save/restore cycle.
The tty interface was using pline() to display prompt strings.
Having 'MSGTYPE=hide "#"' or 'MSGTYPE=hide "yn"' in .nethackrc
would suppress many prompt strings (in the two examples mentioned,
entering extended commands or the vast majority of yes/no questions,
respectively) and generally lead to substantial confusion even if
done intentionally, so switch to putstr(WIN_MESSAGE) instead.
Reported directly to devteam last October, for 3.4.3 on NAO,
subject "UI flaw in message history":
"Applying the stethoscope at self informs:
"Status of Xxxxxxxx (piously neutral): Level 14 HP 138(138) AC -15, very
"fast, invisible.--More--
This is reproducible with shorter character name "wizard" by being
"nominally neutral" or "nominally chaotic". I had a 2 digit level
but didn't notice that my AC took up only 1 digit and ended up
using 125ish blessed potions of full healing to get 4 digits of hit
points in order to get the line to wrap between "very" and "fast".
"But the message history with Ctrl-P shows:
"Message History
"
"Status of Xxxxxxxx (piously neutral): Level 14 HP 138(138) AC -15, very
"invisible.
The key was "Message History", indicating msg_window:full or other
setting which causes ^P to bypass the top line message window and
use a general text window to deliver all history lines at once.
The original feedback splits the line by replacing the space
between "very" and "fast" with a newline, which topline handling
notices and processes as special, but then leaves in place.
msg_window:full results in tty_putstr() case NHW_TEXT, which treats
newline as an ordinary character since it doesn't expect to see
that in text. Squeezing out three doubled spaces made room for
"very\nfast," on the top line. process_text_window() attempted to
write it there, but putchar() wrote up through "very," on one line,
then output the newline which resulted in "fast," on the next line.
Then explicit cursor positioning set things up to put "invisible"
at the start of that line, overwriting "fast," so making it appear
to be missing.
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
Allow the 'I' command to show inventory of known blessed items via
pseudo object classes B, C, U, and X. That's instead of an showing
inventory of specific object class. The two can't be combined
because 'I' operates on single character input.
I had to modify tty_yn_function to prevent it from forcing a BUCX
character into lower case (simply using lower case would cause a
conflict with 'u' and 'x' for inventory of shopping bill), and did
that by checking whether any of the acceptable response characters
are upper case. Pretty straightforward and shouldn't impact any
other uses that don't specify upper case choices.
I did the same thing for X11. Other interfaces most likely need
to do something similar. If they don't, a response of 'B' or 'C'
(for menustyle:traditional or menustyle:combination) will simply
not work, without causing any problems, same as typing an invalid
choice, and 'U' or 'X' will give shop feedback instead of the
requested subset of inventory.
The Guidebook revisions are untested.
This reverts commit 7f0f43e6f9 and some related
subsequent commits.
This compiles, but I have not done extensive testing.
Conflicts:
include/config.h
include/decl.h
include/extern.h
include/global.h
include/tradstdc.h
include/wintty.h
src/drawing.c
src/files.c
src/hacklib.c
src/mapglyph.c
src/options.c
sys/winnt/nttty.c
win/tty/getline.c
win/tty/topl.c
win/tty/wintty.c
Hide most of the Unicode support in tty's top line manipulation.
The new code is somewhat fragile, but the clutter from the many instances
of #if UNICODE_WIDEWINPORT was making it difficult to work on some other
changes.
[Make use of recent message history changes.]
Add support to makedefs and the core for including a line of summary
text with quest messages that don't use pline() delivery. The multi-line
record structure of quest.txt begins each entry with %C and ends with %E.
makedefs now examines the %E lines looking for "[anything]" and adds that
to quest.dat where deliver_by_window() can find it. The square brackets
are required in the input and intentionally carried along to the output.
putmsghistory() is used to put the summary text into the message history
buffer for use by ^P, without being displayed first. (So this is a no-op
for interfaces which haven't implemented putmsghistory yet. Maybe
genl_putmsghistory() should pass such text to pline() as a quick hack?)
This adds a few summary lines to quest.txt so that the feature can
be tested. Most of them were written by <Someone> nearly three years
ago. I'm planning to add a couple of new control codes that'll allow some
of them to expand into shorter text. (The one where the Archeologist
leader tells you that the nemesis stole the artifact so your mission is
to find the goal level, defeat the nemesis, and return with the artifact
ends up being roughly 160 characters long.)
[Third of three message history patches.]
Add another argument to putmsghistory() so that it can tell whether
it's processing multiple messages for restore (which should be treated as
being older than any current messages) or a single message to stuff into
history (which should be treated as the most recent message even though
it hasn't been displayed in the message window).
Explicitly truncate the query prompt string to QBUFSZ-1 characters.
For tty and Amiga, no longer include the choices and default within that
length limit; use a bigger buffer to hold them along with the prompt.
[See cvs log for doc/window.doc for more details.]
This patch attempts to add some levels of unicode support
to NetHack.
The master on/off switch for any Unicode support is
defining UNICODE_SUPPORT in config.h. Currently
there is code support for two subsets of unicode support:
UNICODE_DRAWING
If UNICODE_DRAWING is defined, then the data
structures used to house drawing symbols are expanded
to the size of wchar_t, big enough to hold unicode characters.
A typdef called `nhsym' is involved and if UNICODE_DRAWING
is defined, it is wchar_t, otherwise it is uchar.
UNICODE_WIDEWINPORT
If UNICODE_WIDEWINPORT is defined, then the data
structures inside the window port are expanded to the size of
wchar_t, big enough to hold unicode characters. Both map
symbols and text within the window port are expanded, in order
for potential support for displaying multinational characters some
day, but this patch only provides viewing of map symbols.
A typdef called `nhwchar' is involved and if UNICODE_WIDEWINPORT
is defined, it is wchar_t, otherwise it is char.
The only window port with code support for UNICODE_WIDEWINPORT
currently is the TTY port. Don't enable UNICODE_WIDEWINPORT
unless:
- it is a TTY port
- the underlying platform specific routines can
handle the larger data structures.
Don't enable UNICODE_SUPPORT unless:
- your compiler can handle wchar_t.
- your compiler can accept L'a' characters.
- your compiler can accept L"wide" strings.
Note that if your compiler can handle the above, you could
enable the larger data structures (currently if TTY) even if your
platform can't actually display unicode or UTF-8, by messing
with u_putch() in win/tty/wintty.c to only deal regular chars.
That should be the only function that actually pushes wide characters
out to the display.
If you enable UNICODE_SUPPORT, and your platform is capable
you will need to turn on the unicode run-time option to be able to
load unicode character sets from the symbol file, to be able to
push unicode characters to the display. You'll also want to load
a unicode symbol set once the unicode option is toggled on. In
a config file you would do that via these two lines:
OPTIONS=unicode
OPTIONS=symset:Unicode_non_US
The repository was stamped with NETHACK_PRE_UNICODE
prior to applying this patch, and stamped with
NETHACK_POST_UNICODE afterwards. The code differences
between those two tagged versions are this patch.
<Someone> discovered that it is possible to
have wins[WIN_MESSAGE] be null during
a hangup, not sure why yet.
Put a guard in to prevent de-referencing a null pointer.