experimental change for tty perm_invent

This checks for 'TTYINV' in the environment and if found, it uses that
as a number describing a bit mask for how to show the perm_invent.
 0 = current behavior, a-zA-Z in two columns (I've started referring
     to those as panels because "column" is already used a lot);
 1 = "show gold" => $a-zA-Z# in two columns; requires 1 more line;
 2 = "sparse" => list all letters a-z in the left panel and A-Z in
     the right whether there is an item in the slot or not, so that
     open slots will be obvious;
 3 = 1|2, "sparse" with $a-zA-Z$ instead of just letters;
 4 = "in use" => full lines instead of side-by-side panels, listing
     only items with non-zero obj->owornmask; currently requires 17
     lines instead of 28 (or 29 for show-gold):  room for top border,
     15 lines of worn/wielded items, and bottom border; normal usage
     would be capped at 3 weapon slots, 7 armor slots, and 4 accessory
     slots, but it is possible to have more items in use (simplest
     case is to pick up the iron ball while punished).
The #4 case isn't displaying its bottom border correctly and I haven't
figured out why.

If this turns out to be useful, perm_invent can become a compound or
some new option for perminv mode could be added.
This commit is contained in:
PatR
2022-06-23 02:05:52 -07:00
parent 295a8523f5
commit da3c5dfe87

View File

@@ -253,7 +253,7 @@ void g_pututf8(uint8 *utf8str);
#ifdef TTY_PERM_INVENT
void tty_perm_invent_toggled(boolean negated);
static int tty_create_invent(int, struct WinDesc *);
static int ttyinv_create_window(int, struct WinDesc *);
static void tty_invent_box_glyph_init(struct WinDesc *cw);
static boolean calling_from_update_inventory = FALSE;
/* this could/should be static */
@@ -261,6 +261,8 @@ struct tty_perminvent_cell zerottycell = { 0, 0, 0, 0, { 0 } };
static glyph_info zerogi = { 0 };
enum { border_left, border_middle, border_right, border_elements };
static int bordercol[border_elements] = { 0, 0, 0 }; /* left, middle, right */
enum { InvNormal = 0, InvShowGold = 1, InvSparse = 2, InvInUse = 4 };
static int ttyinvmode = InvNormal;
#endif
/*
@@ -1590,7 +1592,12 @@ tty_create_nhwindow(int type)
break;
#ifdef TTY_PERM_INVENT
case NHW_TTYINVENT:
return tty_create_invent(newid, newwin);
{
/*TEMPORARY*/
char *envtmp = nh_getenv("TTYINV");
ttyinvmode = envtmp ? atoi(envtmp) : InvNormal;
}
return ttyinv_create_window(newid, newwin);
#endif
default:
panic("Tried to create window type %d\n", (int) type);
@@ -1625,9 +1632,9 @@ tty_create_nhwindow(int type)
#ifdef TTY_PERM_INVENT
static int
tty_create_invent(int newid, struct WinDesc *newwin)
ttyinv_create_window(int newid, struct WinDesc *newwin)
{
int i, r, c;
int i, r, c, minrow;
unsigned n;
/* Is there enough real estate to do this beyond the status line?
@@ -1662,19 +1669,30 @@ tty_create_invent(int newid, struct WinDesc *newwin)
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 */
/* preliminary init in case tty_desctroy_nhwindow() gets called */
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) {
minrow = tty_pi_minrow;
if ((ttyinvmode & InvShowGold) != 0)
minrow += 1;
/* "normal" max for items in use would be 3 weapon + 7 armor + 4
accessories == 14, but being punished and picking up the ball will
add 1, and some quest artifacts have an an #invoke property that's
tracked via obj->owornmask so could add more; if hero ends up with
more than 15 in-use items, some will be left out;
Qt's "paper doll" adds first lit lamp/candle and first active
leash; those aren't tracked via owornmask so we don't notice them */
if ((ttyinvmode & InvInUse) != 0)
minrow = 1 + 15 + 1; /* top border + 15 lines + border border */
if (newwin->rows < 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,
minrow + 1 + ROWNO + 3, tty_pi_mincol,
ttyDisplay->rows, ttyDisplay->cols);
tty_wait_synch();
set_option_mod_status("perm_invent", set_gameview);
@@ -1685,12 +1703,15 @@ tty_create_invent(int newid, struct WinDesc *newwin)
/*
* Terminal/window/screen is big enough.
*/
newwin->maxrow = tty_pi_minrow;
newwin->maxrow = 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;
/* for in-use mode, use full lines */
if ((ttyinvmode & InvInUse) != 0)
bordercol[border_middle] = bordercol[border_right];
n = (unsigned) (newwin->maxrow * sizeof (struct tty_perminvent_cell *));
newwin->cells = (struct tty_perminvent_cell **) alloc(n);
@@ -3442,6 +3463,10 @@ tty_message_menu(char let, int how, const char *mesg)
#ifdef TTY_PERM_INVENT
static boolean done_tty_perm_invent_init = FALSE;
static void ttyinv_populate_slot(struct WinDesc *, int, int, const char *);
#ifndef NOINVSYM /* invent.c */
#define NOINVSYM '#'
#endif
DISABLE_WARNING_FORMAT_NONLITERAL
#endif
@@ -3450,14 +3475,17 @@ void
tty_update_inventory(int arg UNUSED)
{
#ifdef TTY_PERM_INVENT
int row, col, pass, ccnt;
struct WinDesc *cw = 0;
winid window = g.tty_invent_win;
struct obj *obj;
char invbuf[BUFSZ], *text, null[1] = {'\0'};
boolean force_redraw = g.program_state.in_docrt ? TRUE
: FALSE;
static char Empty[1] = { '\0' };
struct WinDesc *cw;
struct tty_perminvent_cell *cell;
struct obj *obj;
char invbuf[BUFSZ], *text, nxtlet;
int row, col, side, slot, maxslot;
winid window = g.tty_invent_win;
boolean force_redraw = g.program_state.in_docrt ? TRUE : FALSE,
show_gold = (ttyinvmode & InvShowGold) != 0,
inuse_only = (ttyinvmode & InvInUse) != 0,
sparse = (ttyinvmode & InvSparse) != 0;
/* we just return if the window creation failed, probably due to
not meeting size requirements */
@@ -3482,57 +3510,68 @@ tty_update_inventory(int arg UNUSED)
tty_invent_box_glyph_init(cw);
}
text = Empty; /* lint suppression */
maxslot = cw->maxrow - 1;
obj = g.invent;
text = null;
ccnt = 0;
if (obj) {
if (obj->invlet == '$')
obj = obj->nobj;
if (obj) {
Snprintf(invbuf, sizeof invbuf, "%c - %s", obj->invlet,
doname(obj));
text = invbuf;
}
}
for (pass = 0; pass < 2; ++pass) {
for (row = 1; row < (cw->maxrow - 1); ++row) { /* row below top border */
for (col = (pass ? bordercol[border_middle] + 1
: bordercol[border_left] + 1);
col < (pass ? bordercol[border_right]
: bordercol[border_middle]);
++col) {
cell = &cw->cells[row][col];
if (obj && *text && ccnt < (bordercol[border_middle] - 1)) {
if (cell->content.ttychar != *text)
cell->refresh = 1;
cell->content.ttychar = *text;
text++;
ccnt++;
} else {
if (cell->content.ttychar != ' ')
cell->refresh = 1;
cell->content.ttychar = ' ';
}
cell->text = 1;
cell->glyph = 0;
}
if (obj) {
for (slot = 0; slot < maxslot; ++slot) {
if (!sparse) {
while (obj && ((obj->invlet == GOLD_SYM && !show_gold)
|| (!obj->owornmask && inuse_only)))
obj = obj->nobj;
if (obj) {
if (obj->invlet == '$')
obj = obj->nobj;
if (obj) {
Snprintf(invbuf, sizeof invbuf, "%c - %s",
obj->invlet, doname(obj));
text = invbuf;
ccnt = 0;
}
}
} else {
if (!show_gold)
nxtlet = (slot < 26) ? ('a' + slot) : ('A' + slot - 26);
else
nxtlet = (slot == 0) ? GOLD_SYM
: (slot < 27) ? ('a' + slot - 1)
: (slot < 53) ? ('A' + slot - 27)
: NOINVSYM;
for (obj = g.invent; obj; obj = obj->nobj)
if (obj->invlet == nxtlet)
break;
}
if (obj) {
/* TODO: check for MENUCOLORS match */
text = doname(obj); /* 'text' will switch to invbuf[] below */
/* strip away "a"/"an"/"the" prefix to show a bit more of the
interesting part of the object's description;
this is inline version of pi_article_skip() from cursinvt.c;
should move that to hacklib.c and use it here */
if (text[0] == 'a') {
if (text[1] == ' ')
text += 2;
else if (text[1] == 'n' && text[2] == ' ')
text += 3;
} else if (text[0] == 't') {
if (text[1] == 'h' && text[2] == 'e' && text[3] == ' ')
text += 4;
}
Snprintf(invbuf, sizeof invbuf, "%c - %s", obj->invlet, text);
text = invbuf;
obj = obj->nobj; /* set up for next iteration */
} else if (sparse) {
Sprintf(invbuf, "%c", nxtlet); /* empty slot */
text = invbuf;
} else {
if (slot == 0) {
Sprintf(invbuf, "%-4s[%s]", "",
!g.invent ? "empty"
: inuse_only ? "no items are in use"
: "only gold");
text = invbuf;
} else {
text = null;
text = Empty; /* "" => fill slot with spaces */
}
}
row = (slot % (!show_gold ? 26 : 27)) + 1; /* +1: top border */
/* side: left side panel or right side panel, not a window column */
side = slot < (!show_gold ? 26 : 27) ? 0 : 1;
ttyinv_populate_slot(cw, row, side, text);
}
calling_from_update_inventory = TRUE;
/* now render to the display */
for (row = 0; row < cw->maxrow; ++row)
@@ -3541,8 +3580,7 @@ tty_update_inventory(int arg UNUSED)
if (cell->refresh || force_redraw) {
if (cell->glyph) {
tty_print_glyph(window, col + 1, row,
cell->content.gi,
&nul_glyphinfo);
cell->content.gi, &nul_glyphinfo);
end_glyphout();
} else {
if (col != cw->curx || row != cw->cury)
@@ -3561,6 +3599,38 @@ tty_update_inventory(int arg UNUSED)
#ifdef TTY_PERM_INVENT
/* put the formatted object description for one item into a particular row
and left/right panel, truncating if long or padding with spaces if short */
static void
ttyinv_populate_slot(
struct WinDesc *cw,
int row, /* 'row' within the window, not within screen */
int side, /* 'side'==0 is left panel or ==1 is right panel */
const char *text)
{
struct tty_perminvent_cell *cell;
char c;
int ccnt, col, endcol;
col = bordercol[side] + 1;
endcol = bordercol[side + 1] - 1;
cell = &cw->cells[row][col];
for (ccnt = col; ccnt <= endcol; ++ccnt, ++cell) {
if ((c = *text) != '\0') {
if (cell->content.ttychar != c)
cell->refresh = 1;
cell->content.ttychar = c;
++text;
} else {
if (cell->content.ttychar != ' ')
cell->refresh = 1;
cell->content.ttychar = ' ';
}
cell->text = 1;
cell->glyph = 0;
}
}
void
tty_refresh_inventory(int start, int stop, int y)
{
@@ -3599,18 +3669,12 @@ tty_refresh_inventory(int start, int stop, int y)
}
}
static void tty_invent_box_glyph_init(struct WinDesc *cw)
static void
tty_invent_box_glyph_init(struct WinDesc *cw)
{
int row, col, glyph;
struct tty_perminvent_cell *cell;
/*
1 2 3 4 5 6 7
01234567890123456789012345678901234567890123456789012345678901234567890123456789
x x x
01234567890123456789012345678901234567890123456789012345678901234567890123456789
*/
for (row = 0; row < cw->maxrow; ++row)
for (col = 0; col < cw->maxcol; ++col) {
cell = &cw->cells[row][col];