Commit Graph

72 Commits

Author SHA1 Message Date
PatR
fcd38bdbef couple of interface comments 2019-05-05 13:38:58 -07:00
PatR
6c84ccc241 status 'fieldorder'
DEC C in one of its non-ANSI modes didn't like
 fieldorder = test ? &array1 : &array2;
It first complained that '&' applied to an array has no effect (which
was typically true in pre-ANSI environments) and once those '&'s are
ignored, the attempted assignment didn't match the variable's type.
That code was actually more complicated that it needed to be; slightly
simpler code works as intended.
2019-04-19 12:28:14 -07:00
nhmall
5258bb0ed4 adjust for recently released MS Visual Studio 2019
win\curses\cursstat.c(886) : error C4703: potentially uninitialized local pointer variable 'p' used
2019-04-09 00:35:02 -04:00
PatR
0e425d645f curses vs !HILITE_STATUS
The curses interface wouldn't build with HILITE_STATUS disabled.  I
started adapting it to handle genl_status_update() but that was taking
too much effort with each niggling detail leading to another.  This
goes the opposite direction:  forcing the old STATUS_VIA_WINDOWPORT
behavior without having that #define available.  That dragged along a
bunch of unexpected changes too.
2019-04-06 15:53:51 -07:00
PatR
8c4e792770 curses ">>" (terse "--More--")
I've noticed many instances of the game pausing and not being sure why,
then pressing <space> and having it resume.  The curses interface had
a tendency to put its equivalent of the --More-- prompt, >>, somewhere
where that wasn't visible, either off the right hand edge (possibly) or
underneath the window borders if those were enabled.  Especially the
very last one it issues prior to exit.  (An extra one compared to tty
behavior.)

This ended up being a pretty substantial overhaul of message window
handling.  I wouldn't be surprised if it has off-by-one errors which
happen to be paired up and cancel each other out.  ">>" is still drawn
in orange if guicolor is on, now in inverse video when that is off.
If it happens to be drawn at the same screen location in consecutive
instances, the first ">" will toggle between blink and not blink so
that there'll be no doubt as to whether the keypress registered when
dismissing it (moot if the text preceding it is different but there's
no attempt to be smart enough to check that, just screen placement).
2019-04-04 17:55:40 -07:00
PatR
e5fea0291e curses prompting
Make the same fix to curses that was done for tty in 3.6.1:  don't
let MSGTYPE entries be matched against prompt strings.  Like tty,
curses was using ordinary pline() to issue prompts; something like
MSGTYPE=hide"yn"
could wreak havoc.  Switch to custompline(OVERRIDE_MSGTYPE,...).
2019-04-04 13:52:14 -07:00
PatR
be966cfe5a curses ^P msg_window:Full
This changes the recently added msg_window:f for curses to start
viewing the old messages on the last page rather than the first.  For
msg_window:Reversed (the default for curses) and for either direction
when all of the message history happens to fit on one page, there's
no change.  But for multiple pages, the FIFO feedback now pads the top
of the first page with blank lines so that the last page is full, and
it starts out showing that last page first.  So if you only want to go
back few or several messages, they will be in view immediately.

Old layout:
|first message (oldest)   |  |1st message of last page |
|2nd message of 1st page  |  | ...                     |
| ...                     |  |final (most recent) mesg |
| ...                     |  | (blank filler)          |
|last message of 1st page |  | (blank filler)          |
|             (1 of 2) => |  |          <= (2 of 2)    |
and ^P started with first page visible and needed normal menu handling,
<space> or '>' or '|', to go forward to view the most recent messages.

New layout:
|1st message of last page |  | (blank filler)          |
|2nd message of last page |  | (blank filler)          |
| ...                     |  |first message (oldest)   |
| ...                     |  | ...                     |
|final (most recent)      |  |last message of 1st page |
| <= (2 of 2)             |  |    (1 of 2) =>          |
and ^P starts on last page (two of two in this example) but can go
back with '<' and '^'.

So if the total size takes one and third pages (which isn't uncommon
for the default number of kept messages), you'll see 3/4 of the most
recent messages on the initial screen, then you can page backward if
you want to see the other 1/4.

The page indicator is deliberately drawn a bit differently just to
draw attention to the fact you're starting on the last page.  I'm not
sure whether that is actually worthwhile but it was trivial to do.
2019-04-02 01:11:59 -07:00
PatR
cd12422af5 curses message suppression
The curses interface was using 'moves' as if it meant "moves" rather
than "turns".  Typing ESC at >> (curses' terser version of --More--)
prompt would suppress messages for the rest of the current turn rather
than just the rest of the current move.  So if the hero got an extra
move due to being Fast, there would be no feedback during that move.
2019-03-31 15:34:46 -07:00
PatR
c8fdb040cb curses status highlighting
window.doc states that the colormasks argument to status_update() is
only relevant for BL_CONDITION, but curses was relying on it to be
passed for BL_FLUSH as well.  Yesterday's changes stopped the latter
and broke highlighting of status conditions.  Other interfaces appear
to honor the description in window.doc.
2019-03-31 07:04:23 -07:00
PatR
68542da636 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.
2019-03-29 17:03:03 -07:00
PatR
99ed00012e curses message history
The curses interface maintains message history in a doubly linked list
with a capacity limit.  Once capacity is reached, the list head is
advanced and the old head discarded, but it was leaving the new head's
'previous element' link pointing at that discarded element.
  tmp_mesg = first_mesg->next_mesg;
(at this stage, tmp_mesg->prev_mesg points at first_mesg),
  free(first_mesg);
  first_mesg = tmp_mesg;
(with necessary 'first_mesg->prev_msg = NULL' missing).  The situation
wasn't a significant problem because traversing the list was limited
by a counter.  Going from tail back to head exhausted the counter
without ever accessing the stale pointer.

Since it wasn't noticeable, I haven't added a fixes entry for this.
I've also changed it to do fewer memory allocations and frees by
reusing the old list head instead of always allocating a new element
and freeing the one being replaced.
2019-03-26 02:30:59 -07:00
PatR
76d350dd8c curses horizontal status
The unresolved "first problem" mentioned earlier in commit
382286cb99 was caused by stale values
in status fields which had become disabled.  Polymorphing left an
old BL_XP value and returning to original form left an old BL_HD one.
They weren't displayed but the stale value was included in the line
length calculation, resulting in 4 or 5 columns being set aside for
a phantom value.  That implicitly reduced the available length of the
line and could result in extra spaces separating other fields being
squeezed out while unused spaces remained at the end of the line.

Experience points, time, and score didn't trigger this problem because
they were being explicitly excluded if disabled.  So stale values for
them when they had been enabled then later disabled didn't matter.
2019-03-26 01:47:33 -07:00
PatR
382286cb99 curses status display
I noticed a couple of things wrong--that I was fairly sure that I
had working correctly before--and after fixing the second one, the
first has mysteriously disappeared.

First problem, which may or may not still be a problem:  extra spaces
were being removed from the second line of 2-line status even though
there were still 4 or 5 available spaces to the right of the status
conditions.  It was behaving as if it thought the line was narrower
than actual size, or conversely, that the sum of the widths of the
fields plus the extra spaces was bigger than it actually was.

Second problem, fixed here.  The code to put '+' in the far right
column of the last status line when there is at least one condition
all the way off the display wasn't working right when windowborders
were displayed.  That's down to curses wrapping to the next line but
user can't see it due to the window border overwriting.  Single char
overflow stayed on same line, but two or more wrapped and then the
'x' coordinate didn't match tests for 'too wide'.  Perform explicit
truncation instead of leaving that up to curses.  Also truncate
encumbrance when warranted since it's feasible for it to overflow.
Anyone using a display narrower than 80 columns might still run
into odd status behavior because other fields than conditions and
encumbrance could go past the end of line.  But they shouldn't be
wasting screen real estate with windowborders, and without borders,
curses will keep the cursor in the bottom right corner when the
program tries to go past, which should keep things reasonably sane.
2019-03-25 16:54:51 -07:00
PatR
2960042a9f curses msg_window:f
Simplify.  Support routine was already prepared to do what's wanted
without jumping throuhg any hoops.
2019-03-25 12:04:14 -07:00
PatR
59ab965863 curses ^P - support msg_window:full
curses uses 'reversed' (LIFO) style when displaying previous messages.
Use the existing (previously tty-only) 'msg_window' option to also
support 'full' (FIFO).  The actual code needed as just a couple of
lines; tweaking options parsing and the documentation was more work.
2019-03-24 19:20:21 -07:00
PatR
ee53a9fea6 curses message recall, memory leaks
Using ^P right after resize or 'O' of align_message, align_status,
statuslines, or windowborders would result in
'curses_display_nhmenu: attempt to display empty menu'
because some memory cleanup I added several weeks back was being
executed when the curses interface tore down and recreated its
internal windows.

This fixes ^P handling by making sure that that menu (which is just
text but uses a menu to support '>'/'<'/'^'/'|' scrolling) will never
be empty and it also fixes the window deletion to not throw away
message history until it's final deletion at exit time.

^P uses a popup window to display previous messages and it was never
deleting that window, just creating a new one each time.  Same with
the routine which displays an external help file.  Using either or
combination of both close to 5000 times would probably make internal
window creation get stuck in an infinite loop.  Delete those windows
after they're used so it'll never be put to the test.

The memory cleanup I added for map/status/messages/invent was only
being preformed at end of game, not when saving.  Fix that too.
2019-03-24 17:50:26 -07:00
nhmall
804a4f1846 warning fix
..\win\curses\cursstat.c(302): warning C4101: 'colon': unreferenced local variable
2019-03-24 12:50:31 -04:00
PatR
d989b36763 revamped curses status display
I've overhauled the status display for curses.  Horizontal layout
supports both 2 lines and 3 lines which can be changed dynamically
via using 'O' to set 'statuslines'.  Fields are spread out a little
more than they used to be, making it more readable--at least to me--
but the extra spaces get squeezed out when lines become too long.
If 'showexp' is on and either conditions or hunger+encumbrance go
off the right edge, experience points are suppressed (but the option
is left on, so they'll come back once there is room).

For traditional 2-line hozizontal status, if hunger+encumbrance+
conditions go off the right edge even after experience points are
knocked out, there will be a '+' in the rightmost column if there
are any conditions that are all the way off.  At present it doesn't
use the tty method of switching to abbreviated condition names to
reduce their legnth.  I'll probably tackle that eventually if no one
beats me to it.

For 3-line horizonal status, there was an older implementation (but
disabled via #if 0) with gold and score moving to the third line.
(I'm not sure how status conditions were handled.)  This one ignored
that and modified 2-line from scratch, moving alignment from line one
to line 2 and level description, time, and conditions from line 2 to
line 3.  It looks like this (view with a fixed-width font...).

Wizard the Hatamoto            St:16 Dx:15 Co:18 In:8 Wi:11 Ch:7    S:25
Lawful  $:21  HP:25(25)  Pw:6(6)  AC:4  Xp:2/21  Hungry Burdened
Dlvl:1  T:36                                     Blind Lev

Score is actually right aligned with the edge but I've deleted several
spaces to keep the line shorter here.  The status conditions line up
with the hunger slot as that shifts due to changes in gold/HP/power/AC/
experience, and conditions prefer that column even when hunger and/or
encumbrance are blank.  Howver, if the number of conditions increase to
the point where they would go off the edge, the whole list shifts left
instead of trying to stay lined up with hunger.  (It's just coincidence
that the lefthand parts of lines 2 and 3 seem to line up in this sample.
In general, they don't.)

The vertical layout has reordered most of the fields and now has a few
blank lines to separate those fields into some groups for readability.
Lines have the form of
Field-name  : Value
and when highlights apply, now they only affect the value portion.
Single digit characteristics are padded with a leading space so that
all six of them line up (for "18/xx", "/xx" protrudes to the right).
HP and Pw are aligned with each other.  Hunger and encumbrance share a
line.  When there are more than three conditions, they're shown three
per line instead of wrapping across lines.  And if too many lines are
present, it will squeeze out enough blank ones to fit.

To see the vertical status, you need a display size of at least 106
columns with 'windowborders' explicitly off, or 110 with them on; also
set option 'align_status' to 'right' or 'left'.  (With borders on,
including the default 'auto' setting, the vertical status appears at
width of 108 columns, but does so by hiding 2 columns of the map; using
110 columns avoids that.)  Resizing from outside the game or changing
align_status via 'O' both cause dynamic reconfiguration of the layout;
there's no need to save, make config changes, then restore.
2019-03-23 17:38:23 -07:00
PatR
5efea7115a curses options and status groundwork
More groundwork for overhauling the status display for curses, plus
a few functional changes.  It was doing a full status update for
every changed field (except conditions), instead of waiting for a
flush directive after gathering multiple changes at a time.  Since
it already does gather every change, the fix to wait is trivial.

This decouples 'hitpointbar' from 'statushilites'.  When highlighting
is off, it uses inverse video only.  When on, it behaves as before:
using inverse video plus the most recent color used to highlight HP
(which can vary if that has rules to highlight changes or percentage
thresholds) but ignoring any HP attribute(s).  This also enables the
latent 'statuslines' option and changes 'windowborders' option from
being settable at startup only to changeable during play.

'statuslines' can have a value of 2 (the default) or 3 and applies to
'align_status:bottom' or 'top'; it's ignored for 'left' and 'right'.
At the moment, setting it to 3 only allows status condition overflow
to wrap from the end of line to 2 to the beginning of line 3, and if
window borders are drawn they'll clobber the last character on line 2
and first one on line 3.  There's no point in trying to fix that
because it will go away when the main status overhaul changes go in.
Condition wrapping for vertical orientation (left or right placement)
was already subject to the same phenomenon and will be superseded too.

This also changes the meaning of the 'windowborders' value so could
impact players using source from git (or possibly beta binaries for
Windows, but not for OSX where curses interface wasn't included).
Old:
 0 = unspecified, 1 = On, 2 = Off, 3 = Auto (On if display is big
     enough, Off otherwise; reevaluated after dynamic resizing);
 Unspecified got changed to 3 during curses windowing initialization.
New:
 0 = Off, 1 = On, 2 = Auto;
 0 gets changed to 2 for default value at start of options processing.
So old value of 2 is changing meaning and explicit old value of 3 is
becoming invalid.  Implicit 3 changes to default 2.  Explicit 3 could
be the subject of a fixup but there isn't much point since 2 can't
have a similar fix.  Users who are using old 2 or explicit 3 will need
to update their run-time config files.

This adds 'statuslines' to the Guidebook and moves some other recently
added documentation of curses options from among the general options
(section 9.4) to "Window Port Customization options" (section 9.5).
None of them have been added to dat/opthelp which seems to be missing
all the wincap options.

Originally I made a lot of changes (mostly moving C99 declarations to
start of their blocks) to the old '#if 0' code at end of cursstat.c,
but have tossed those, except for one subtle bug that assumed 'int'
and 'long' are the same size.
2019-03-21 14:33:39 -07:00
PatR
7049145712 curses update
Miscellaenous stuff either groundwork for or noticed while updating
curses status.  The status changes themselves need some more testing.
One or two of the comments refer to that revised status which hasn't
been checked in yet.
2019-03-18 15:08:01 -07:00
PatR
3d4164bcce curses STATUS_HILITES
Honor hilite_status rules specifying color even if curses-specific
option 'guicolor' is off.

Update status from scratch when 'O' is used to manipulate hilite_status
rules.
2019-03-15 01:12:59 -07:00
nhmall
963cb352bc Merge branch 'NetHack-3.6.2-beta01' of https://rodney.nethack.org:20040/git/NHsource into NetHack-3.6.2-beta01 2019-03-13 20:04:50 -04:00
nhmall
acc92bcacb yet more mingw w64 build
Fix:
../sys/winnt/nhraykey.c: In function 'CheckInput':
../sys/winnt/nhraykey.c:459:37: warning: type of 'mode' defaults to 'int' [-Wimplicit-int]
 int __declspec(dllexport) __stdcall CheckInput(hConIn, ir, count, numpad,
                                     ^~~~~~~~~~
2019-03-13 19:55:43 -04:00
PatR
ccd6d1407e curses: hilite_pet, hilite_pile without color
The curses interface was ignoring video attributes (bold, inverse, &c)
when color is toggled off or if built with TEXTCOLOR disabled.  Honor
attributes regardless of whether color is displayed.

Also, toggling 'hilite_pet' On during play wouldn't do anything if the
curses-specific 'petattr' option had been left as None.  (It worked as
intended if set in starting options.)
2019-03-13 16:50:56 -07:00
PatR
53777fa03a win/curses comment
Twice I've gone through the curses code to deal with CHAR_P, BOOLEAN_P,
and so forth.  Both times I eventually changed my mind.  This time I'm
just adding an explanatory comment instead.
2019-03-10 16:06:29 -07:00
PatR
683226c3c5 curses vs extended commands
Extend the earlier support for Delete/Rubout in getline() to the
text entry for extended commands.  In other words, treat <delete>
and <backspace> as synonyms in both places.

Some reformatting too, but only in a couple of the files.
2019-03-10 14:53:31 -07:00
PatR
1a028d1197 curses run-time options
This started out as an attempt to document the curses options in the
Guidebook, but I didn't actually get that far.  Instead, integrate
the curses options better via more consistent WC/WC2 usage.  This
prevents 'guicolor' from showing up as a boolean option for non-curses
interface in curses+other binary.

For curses itself, let 'petattr' be set/reset via 'O'.  Also, accept
'Dim' as a possible pet highlight attribute since it already handles
all the other ordinary attributes.  I'm not sure what leftline and
rightline highlighting are supposed to do.  They were missing for
ncurses (or maybe they're misspelled for PDcurses?) but adding them
didn't produce any visible effect (using TERM=xterm-256color on OSX
with default font/character set).

Not addressed:
1) general confusion about compile-time vs run-time option filtering;
2) curses pet highlighting only works if 'color' option is enabled.
2019-02-26 15:16:42 -08:00
PatR
d80fd8a014 curses status cleanup
Stop the last of the memory leaks occuring during basic usage.
2019-02-09 15:30:53 -08:00
PatR
d4d7901eff more curses memory
Message history now cleaned up at game end.  Status window cleanup is
not taking place because the core is suppressing it #if STATUS_HILITES.
2019-02-08 16:51:33 -08:00
PatR
f3072cdb43 curses: plug most memory leaks
This takes care of a lot of the leaked memory in the curses interface.
It still needs to free memory allocated for status fields when the
status window is destroyed at game end; likewise for message history
when the message window is destroyed.
2019-02-08 15:50:59 -08:00
PatR
e991dd1b0c curses: getline vs DEL, ESC
Support <delete> (aka <rubout>) during getline().  It doesn't actually
honor the current erase_char value set up for the terminal, just
treats DEL the same as ^H.  (The previous lack of support had nothing
to do with terminfo specifying ^H; the handling is hard-coded.)

tty treats escape while there's already some input as kill_char (erase
the input but get more from scratch) and returns ESC if there isn't.
curses was doing the first half but not the second, so not providing
any way to communicate "cancel" back to the core.  Fix is simple.

Other getline() bug fixes:
1] there was a wprintw("%*something") which was passing the value from
strlen (type 'size_t') to the "%*" argument (type 'int').  That's
always wrong (size_t is guaranteed to be unsigned) and could be severe
(if size_t is different width than int--as on current OSX systems--
depending upon the internals of argument passing).
2] strncpy() only supplies a terminating '\0' if the input is shorter
than the number of characters specified.

A lot of reformatting is warranted but I only did the getline routine
(manually, so might have missed stuff).
2019-02-08 14:54:40 -08:00
PatR
1d5b59ab7e curses memory: 'anything identifier'
Three or four instances of one simple memory leak.  Allocating a union
'anything' to pass to add_menu(), then not doing anything with it.  The
value gets copied so there's no reason for the original to stick around.

[There are still lots of other memory leaks.]
2019-02-07 17:10:55 -08:00
PatR
19d737951e curses: change from malloc() to nethack's alloc()
There was no provision for malloc() potentially returning Null and it
wasn't integrated with nethack's MONITOR_HEAP.  'heaputil' shows that
the curses interface is leaking like a sieve.  If some things are
actually being allocated separately and then freed from within curses,
those need to be thoroughly documented and maybe switched back to
malloc().
2019-02-07 16:48:37 -08:00
PatR
b1de94f922 custompline(SUPPRESS_HISTORY,...) for curses
The curses interface already has a hack to keep 'Count: 12', 'Count:
123' intermediate multi-digit counts out of its message recall history
for ^P, but it was flushing real messages when getpos()'s 'autodescribe'
reported what the cursor moved over.  Overload the count hack to support
 putstr(WIN_MESSAGE, ATR_NOHISTORY, text)
(which is what custompline(SUPPRESS_HISTORY, ...) eventually calls).

The conditional logic for when to create the 'count_window' was pretty
convoluted.  This simplification has the same semantics but I don't
have PDCURSES to actually verify that.
2019-02-07 16:04:24 -08:00
PatR
37e5a9cad2 randrole() fix
Give all the calls to randrole() its new argument.
2019-01-29 17:14:55 -08:00
PatR
d418008b31 curses splash/copyright screen, role prompt
Back out '#include "date.h"' so that cursinit.c won't be recompiled
every time any other file(s) need to be compiled.  It doesn't need
patchlevel.h either.  There is already a straightforward way to fetch
the copyright banner lines from version.c.

The splash screen (ascii art spelling "NetHack" preceding the normal
copyright lines) was invisible when showing white text on white-ish
background.  Make it honor !guicolor.

"Shall I pick a character's role, race, gender and alignment for you?
 [ynaq] (y) " was too wide to accept the answer on the same line on
an 80-column display so "(y) " was placed on the second line.  That's
constructed in the core; change the construction to omit " a" when
using "character" rather than a role name.  (tty shortens it by omitting
the default " (y)"; with " a" gone, it could revert to normal prompt.)

Also a bit of lint cleanup and some reformatting of cursinit.c....
2018-12-29 18:38:30 -08:00
Pasi Kallinen
45e06d638f Curses: Remove useless inventory label
The inventory window used a line to say "Inventory:", which is pretty
useless, and that was the only window showing such a label.

Also don't duplicate the "Not carrying anything" text from core.
2018-12-29 13:16:51 +02:00
nhmall
a5f154d925 a couple of source spelling consistencies for /*FALLTHRU*/ 2018-12-28 10:08:56 -05:00
Tangles
9fd28fb852 curses - fix count selection not working for PICK_ONE menus.
eg: d2b would drop 2 of item b, but using d* to pick from a menu
and then selecting 2b would ignore the count and just drop the
whole stack.
2018-12-28 15:42:32 +01:00
Pasi Kallinen
ca336bbf4b curses: include date.h
This way the curses port will show the version and compile date
on the startup banner, just like tty does.
2018-12-28 11:34:01 +02:00
PatR
ceb446eaea curses lint 2018-12-26 01:45:17 -08:00
nhmall
16cda0882c fix up PDCurses cursor placement for prompts 2018-12-14 23:08:41 -05:00
nhmall
1baa20dfc5 header update on cursstat.c 2018-12-05 23:43:59 -05:00
nhmall
c4930c6782 update header on curswins 2018-12-05 17:45:40 -05:00
nhmall
9c873712b6 update header on cursstat 2018-12-05 17:45:15 -05:00
nhmall
2458281d42 update header on cursmisc 2018-12-05 17:44:08 -05:00
nhmall
c260911f38 update header on cursmesg 2018-12-05 17:43:33 -05:00
nhmall
661ffb0133 update header on cursmain 2018-12-05 17:42:49 -05:00
nhmall
86281c5555 update header on cursinvt 2018-12-05 17:42:11 -05:00
nhmall
14335ea90c update header on cursinit 2018-12-05 17:41:30 -05:00