tty perm_invent fixes

Modify the error message delivery when too-small so that it works for
both NETHACKOPTIONS or .nethackrc and for 'O'.  "Early failure" isn't
very early; using pline() instead of raw_print() ends up writing to
the base window but also works normally when used for failed attempt
to set perm_invent with 'O'.

Fix the off by one error in height which required an extra line that
ended up going unused.

Fix an off by one error in the middle divider.  Forcing the same item
from the left column to the right column, I was seeing
 "f - an uncursed +0 pair of leather glove" ["s (being worn)" truncated]
 "F - an uncursed +0 pair of leather gl"
After the fix I get
 "f - an uncursed +0 pair of leather glov"
 "F - an uncursed +0 pair of leather glo"
(When terminal width is even, the left side is one character wider
than the right.)

Split the invent window creation code out of tty_create_nhwwindow() to
new routine tty_create_invent().  I came across
  if (r == 0 || (newwin->maxrow - 1)
in the process (note lack of 'r ==' in the second part).  I'm not sure
what the initialization code is intended to accomplish but missing
that init for the bottom (boundary box) row didn't seem to be causing
any problem.

This forces the required size to be big enough to handle statuslines:3
regardless of what the setting for that is at the time the perm_invent
window is created.  When the value is 2, there will be a blank line
between status and the boundary box of perm_invent.  When it is 3, the
third line will use that line and the only separator will be the top
boundary box line.  Toggling back and forth with 'O' works as expected.
This commit is contained in:
PatR
2022-06-22 14:21:57 -07:00
parent 5caae51234
commit 295a8523f5
2 changed files with 124 additions and 125 deletions
+6 -9
View File
@@ -1,4 +1,4 @@
/* NetHack 3.7 options.c $NHDT-Date: 1651887695 2022/05/07 01:41:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.555 $ */ /* NetHack 3.7 options.c $NHDT-Date: 1655932898 2022/06/22 21:21:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.569 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */ /*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -4413,15 +4413,12 @@ optfn_boolean(int optidx, int req, boolean negated, char *opts, char *op)
hasn't been executed yet */ hasn't been executed yet */
if (WINDOWPORT("tty") && !g.opt_initial && !negated) { if (WINDOWPORT("tty") && !g.opt_initial && !negated) {
tty_perm_invent_toggled(FALSE); tty_perm_invent_toggled(FALSE);
/* tty_perm_invent_toggled()
if (g.tty_invent_win == WIN_ERR) { -> tty_create_nhwindow(WIN_TTYINVENT)
/* FIXME: there is some confusion between this and -> tty_create_invent()
tty_create_nhwindow(NHW_TTYINVENT) over when this gives feedback for failure (terminal too small) */
should be done */ if (g.tty_invent_win == WIN_ERR)
set_option_mod_status("perm_invent", set_gameview);
config_error_add("Enabling perm_invent failed");
return optn_silenterr; return optn_silenterr;
}
} }
#endif #endif
break; /* from opt_perm_invent */ break; /* from opt_perm_invent */
+118 -116
View File
@@ -1,4 +1,4 @@
/* NetHack 3.7 wintty.c $NHDT-Date: 1644531502 2022/02/10 22:18:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.283 $ */ /* NetHack 3.7 wintty.c $NHDT-Date: 1655932905 2022/06/22 21:21:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.303 $ */
/* Copyright (c) David Cohrs, 1991 */ /* Copyright (c) David Cohrs, 1991 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -253,9 +253,12 @@ void g_pututf8(uint8 *utf8str);
#ifdef TTY_PERM_INVENT #ifdef TTY_PERM_INVENT
void tty_perm_invent_toggled(boolean negated); void tty_perm_invent_toggled(boolean negated);
static int tty_create_invent(int, struct WinDesc *);
static void tty_invent_box_glyph_init(struct WinDesc *cw); static void tty_invent_box_glyph_init(struct WinDesc *cw);
static boolean calling_from_update_inventory = FALSE; static boolean calling_from_update_inventory = FALSE;
/* this could/should be static */
struct tty_perminvent_cell zerottycell = { 0, 0, 0, 0, { 0 } }; struct tty_perminvent_cell zerottycell = { 0, 0, 0, 0, { 0 } };
static glyph_info zerogi = { 0 };
enum { border_left, border_middle, border_right, border_elements }; enum { border_left, border_middle, border_right, border_elements };
static int bordercol[border_elements] = { 0, 0, 0 }; /* left, middle, right */ static int bordercol[border_elements] = { 0, 0, 0 }; /* left, middle, right */
#endif #endif
@@ -1587,99 +1590,7 @@ tty_create_nhwindow(int type)
break; break;
#ifdef TTY_PERM_INVENT #ifdef TTY_PERM_INVENT
case NHW_TTYINVENT: case NHW_TTYINVENT:
/* Is there enough real estate to do this beyond the status line? return tty_create_invent(newid, newwin);
* Rows:
* Top border line (1)
* 26 inventory rows (26)
* Bottom border line (1)
* 1 + 26 + 1 = 28
*
* Cols:
* Left border (1)
* Left inventory items (38)
* Middle separation (1)
* Right inventory items (38)
* Right border (1)
* 1 + 38 + 1 + 38 + 1 = 79
*
* The topline + map rows + status lines require:
* 1 + 21 + 2 (or 3) = 24 (or 25 depending on status line count).
* So we can only present a full inventory on tty if there are
* 28 + 24 (or 25) available (52 or 53 rows on the terminal).
* Correspondingly ttyDisplay->rows has to be at least 52 (or 53).
*
*/
newwin->offx = 0;
/* topline + map rows + status lines */
newwin->offy = 1 + ROWNO + ((iflags.wc2_statuslines > 2) ? 3 : 2);
newwin->rows = (ttyDisplay->rows - newwin->offy) - 1;
newwin->cols = ttyDisplay->cols;
newwin->maxrow = 0;
newwin->maxcol = 79; /* bhaak */
/* these weren't initialized as of yet, and as such could
be non-zero which would cause tty_destroy_window()
and friends to try and free non-malloc'd memory */
newwin->data = (char **) 0;
newwin->datlen = (short *) 0;
newwin->cells = (struct tty_perminvent_cell **) 0;
if ((newwin->rows < tty_pi_minrow)
|| (newwin->cols < tty_pi_mincol)) {
tty_destroy_nhwindow(newid);
if (!g.program_state.beyond_savefile_load) {
raw_printf("tty perm_invent could not be enabled.");
if (newwin->cols < tty_pi_mincol)
raw_printf("tty perm_invent requires %d columns, your "
"terminal has %d.",
tty_pi_mincol, ttyDisplay->cols);
else
raw_printf("tty perm_invent requires %d rows, your "
"terminal has %d.",
(iflags.wc2_statuslines > 2) ? 54 : 53,
ttyDisplay->rows);
}
set_option_mod_status("perm_invent", set_gameview);
iflags.perm_invent = FALSE;
return WIN_ERR;
} else {
int r, c;
newwin->maxrow = tty_pi_minrow;
newwin->maxcol = newwin->cols;
/* establish the borders */
bordercol[border_left] = 0;
bordercol[border_middle] = (newwin->maxcol / 2) + 1;
bordercol[border_right] = newwin->maxcol - 1;
if (newwin->maxrow) {
newwin->cells = (struct tty_perminvent_cell **) alloc(
(unsigned) (newwin->maxrow
* sizeof(struct tty_perminvent_cell *)));
for (i = 0; i < newwin->maxrow; i++) {
if (newwin->maxcol) {
newwin->cells[i] =
(struct tty_perminvent_cell *) alloc(
(unsigned) (newwin->maxcol
* sizeof(struct tty_perminvent_cell)));
}
}
}
for (r = 0; r < newwin->maxrow; r++)
for (c = 0; c < newwin->maxcol; c++) {
newwin->cells[r][c] = zerottycell;
if (r == 0 || (newwin->maxrow - 1)
|| c == bordercol[border_left]
|| c == bordercol[border_middle]
|| c == bordercol[border_right]) {
newwin->cells[r][c].content.gi = (glyph_info *) alloc(
(unsigned) sizeof(glyph_info));
}
}
return newid;
}
/*NOTREACHED*/
break;
#endif #endif
default: default:
panic("Tried to create window type %d\n", (int) type); panic("Tried to create window type %d\n", (int) type);
@@ -1711,6 +1622,100 @@ tty_create_nhwindow(int type)
return newid; return newid;
} }
#ifdef TTY_PERM_INVENT
static int
tty_create_invent(int newid, struct WinDesc *newwin)
{
int i, r, c;
unsigned n;
/* Is there enough real estate to do this beyond the status line?
* Rows:
* Top border line (1)
* 26 inventory rows (26)
* [should be 27 to have room for '$' and '#']
* Bottom border line (1)
* 1 + 26 + 1 = 28
*
* Cols:
* Left border (1)
* Left inventory items (38)
* Middle separation (1)
* Right inventory items (38)
* Right border (1)
* 1 + 38 + 1 + 38 + 1 = 79
*
* The topline + map rows + status lines require:
* 1 + 21 + 2 (or 3) = 24 (or 25 depending on status line count).
* So we can only present a full inventory on tty if there are
* 28 + 24 (or 25) available (52 or 53 rows on the terminal).
* Correspondingly ttyDisplay->rows has to be at least 52 (or 53).
* [The top and bottom borderlines aren't necessary. Suppressing
* them would reduce the number of rows needed by 2.]
*
*/
newwin->offx = 0;
/* topline + map rows + status lines */
newwin->offy = 1 + ROWNO + 3; /* 3: + 2 + (iflags.wc2_statuslines > 2) */
newwin->rows = (ttyDisplay->rows - newwin->offy);
newwin->cols = ttyDisplay->cols;
newwin->maxrow = 0;
newwin->maxcol = 79; /* bhaak */
/* these weren't initialized as of yet, and as such could
be non-zero which would cause tty_destroy_window()
and friends to try and free non-malloc'd memory */
newwin->data = (char **) 0;
newwin->datlen = (short *) 0;
newwin->cells = (struct tty_perminvent_cell **) 0;
if (newwin->rows < tty_pi_minrow || newwin->cols < tty_pi_mincol) {
tty_destroy_nhwindow(newid); /* sets g.tty_invent_win to WIN_ERR */
pline("%s.", "tty perm_invent could not be enabled");
pline(
"tty perm_invent needs a terminal that is at least %dx%d, yours is %dx%d.",
tty_pi_minrow + 1 + ROWNO + 3, tty_pi_mincol,
ttyDisplay->rows, ttyDisplay->cols);
tty_wait_synch();
set_option_mod_status("perm_invent", set_gameview);
iflags.perm_invent = FALSE;
return WIN_ERR;
}
/*
* Terminal/window/screen is big enough.
*/
newwin->maxrow = tty_pi_minrow;
newwin->maxcol = newwin->cols;
/* establish the borders */
bordercol[border_left] = 0;
bordercol[border_middle] = (newwin->maxcol + 1) / 2;
bordercol[border_right] = newwin->maxcol - 1;
n = (unsigned) (newwin->maxrow * sizeof (struct tty_perminvent_cell *));
newwin->cells = (struct tty_perminvent_cell **) alloc(n);
n = (unsigned) (newwin->maxcol * sizeof (struct tty_perminvent_cell));
for (i = 0; i < newwin->maxrow; i++)
newwin->cells[i] = (struct tty_perminvent_cell *) alloc(n);
n = (unsigned) sizeof (glyph_info);
for (r = 0; r < newwin->maxrow; r++)
for (c = 0; c < newwin->maxcol; c++) {
newwin->cells[r][c] = zerottycell;
if (r == 0 || r == newwin->maxrow - 1
|| c == bordercol[border_left]
|| c == bordercol[border_middle]
|| c == bordercol[border_right]) {
newwin->cells[r][c].content.gi = (glyph_info *) alloc(n);
*newwin->cells[r][c].content.gi = zerogi;
}
}
return newid;
}
#endif
static void static void
erase_menu_or_text(winid window, struct WinDesc *cw, boolean clear) erase_menu_or_text(winid window, struct WinDesc *cw, boolean clear)
{ {
@@ -2715,10 +2720,10 @@ tty_destroy_nhwindow(winid window)
} }
void void
tty_curs(winid window, tty_curs(
register int x, register int y) /* not xchar: perhaps xchar is winid window,
unsigned and curx-x would be register int x, register int y) /* not xchar: perhaps xchar is unsigned
unsigned as well */ * then curx-x would be unsigned too */
{ {
struct WinDesc *cw = 0; struct WinDesc *cw = 0;
int cx = ttyDisplay->curx; int cx = ttyDisplay->curx;
@@ -3174,15 +3179,16 @@ tty_start_menu(winid window, unsigned long mbehavior)
* later. * later.
*/ */
void void
tty_add_menu(winid window, /* window to use, must be of type NHW_MENU */ tty_add_menu(
const glyph_info *glyphinfo UNUSED, /* glyph info with glyph to winid window, /* window to use, must be of type NHW_MENU */
display with item */ const glyph_info *glyphinfo UNUSED, /* glyph info with glyph to
const anything *identifier, /* what to return if selected */ * display with item */
char ch, /* keyboard accelerator (0 = pick our own) */ const anything *identifier, /* what to return if selected */
char gch, /* group accelerator (0 = no group) */ char ch, /* selector letter (0 = pick our own) */
int attr, /* attribute for string (like tty_putstr()) */ char gch, /* group accelerator (0 = no group) */
const char *str, /* menu string */ int attr, /* attribute for string (like tty_putstr()) */
unsigned int itemflags) /* itemflags such as MENU_ITEMFLAGS_SELECTED */ const char *str, /* menu string */
unsigned int itemflags) /* itemflags such as MENU_ITEMFLAGS_SELECTED */
{ {
boolean preselected = ((itemflags & MENU_ITEMFLAGS_SELECTED) != 0); boolean preselected = ((itemflags & MENU_ITEMFLAGS_SELECTED) != 0);
register struct WinDesc *cw = 0; register struct WinDesc *cw = 0;
@@ -3453,12 +3459,6 @@ tty_update_inventory(int arg UNUSED)
: FALSE; : FALSE;
struct tty_perminvent_cell *cell; struct tty_perminvent_cell *cell;
/*
1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789012345678901234567890123456789
x x x
01234567890123456789012345678901234567890123456789012345678901234567890123456789
*/
/* we just return if the window creation failed, probably due to /* we just return if the window creation failed, probably due to
not meeting size requirements */ not meeting size requirements */
if (window == WIN_ERR) if (window == WIN_ERR)
@@ -3897,9 +3897,11 @@ tty_cliparound(int x, int y)
*/ */
void void
tty_print_glyph(winid window, xchar x, xchar y, tty_print_glyph(
const glyph_info *glyphinfo, winid window,
const glyph_info *bkglyphinfo UNUSED) xchar x, xchar y,
const glyph_info *glyphinfo,
const glyph_info *bkglyphinfo UNUSED)
{ {
boolean inverse_on = FALSE, colordone = FALSE, glyphdone = FALSE; boolean inverse_on = FALSE, colordone = FALSE, glyphdone = FALSE;
int ch, color; int ch, color;