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:
208
win/tty/wintty.c
208
win/tty/wintty.c
@@ -253,7 +253,7 @@ 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 int ttyinv_create_window(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 */
|
/* this could/should be static */
|
||||||
@@ -261,6 +261,8 @@ struct tty_perminvent_cell zerottycell = { 0, 0, 0, 0, { 0 } };
|
|||||||
static glyph_info zerogi = { 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 */
|
||||||
|
enum { InvNormal = 0, InvShowGold = 1, InvSparse = 2, InvInUse = 4 };
|
||||||
|
static int ttyinvmode = InvNormal;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1590,7 +1592,12 @@ tty_create_nhwindow(int type)
|
|||||||
break;
|
break;
|
||||||
#ifdef TTY_PERM_INVENT
|
#ifdef TTY_PERM_INVENT
|
||||||
case NHW_TTYINVENT:
|
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
|
#endif
|
||||||
default:
|
default:
|
||||||
panic("Tried to create window type %d\n", (int) type);
|
panic("Tried to create window type %d\n", (int) type);
|
||||||
@@ -1625,9 +1632,9 @@ tty_create_nhwindow(int type)
|
|||||||
#ifdef TTY_PERM_INVENT
|
#ifdef TTY_PERM_INVENT
|
||||||
|
|
||||||
static int
|
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;
|
unsigned n;
|
||||||
|
|
||||||
/* Is there enough real estate to do this beyond the status line?
|
/* 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->cols = ttyDisplay->cols;
|
||||||
newwin->maxrow = 0;
|
newwin->maxrow = 0;
|
||||||
newwin->maxcol = 79; /* bhaak */
|
newwin->maxcol = 79; /* bhaak */
|
||||||
/* these weren't initialized as of yet, and as such could
|
/* preliminary init in case tty_desctroy_nhwindow() gets called */
|
||||||
be non-zero which would cause tty_destroy_window()
|
|
||||||
and friends to try and free non-malloc'd memory */
|
|
||||||
newwin->data = (char **) 0;
|
newwin->data = (char **) 0;
|
||||||
newwin->datlen = (short *) 0;
|
newwin->datlen = (short *) 0;
|
||||||
newwin->cells = (struct tty_perminvent_cell **) 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 */
|
tty_destroy_nhwindow(newid); /* sets g.tty_invent_win to WIN_ERR */
|
||||||
pline("%s.", "tty perm_invent could not be enabled");
|
pline("%s.", "tty perm_invent could not be enabled");
|
||||||
pline(
|
pline(
|
||||||
"tty perm_invent needs a terminal that is at least %dx%d, yours is %dx%d.",
|
"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);
|
ttyDisplay->rows, ttyDisplay->cols);
|
||||||
tty_wait_synch();
|
tty_wait_synch();
|
||||||
set_option_mod_status("perm_invent", set_gameview);
|
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.
|
* Terminal/window/screen is big enough.
|
||||||
*/
|
*/
|
||||||
newwin->maxrow = tty_pi_minrow;
|
newwin->maxrow = minrow;
|
||||||
newwin->maxcol = newwin->cols;
|
newwin->maxcol = newwin->cols;
|
||||||
/* establish the borders */
|
/* establish the borders */
|
||||||
bordercol[border_left] = 0;
|
bordercol[border_left] = 0;
|
||||||
bordercol[border_middle] = (newwin->maxcol + 1) / 2;
|
bordercol[border_middle] = (newwin->maxcol + 1) / 2;
|
||||||
bordercol[border_right] = newwin->maxcol - 1;
|
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 *));
|
n = (unsigned) (newwin->maxrow * sizeof (struct tty_perminvent_cell *));
|
||||||
newwin->cells = (struct tty_perminvent_cell **) alloc(n);
|
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
|
#ifdef TTY_PERM_INVENT
|
||||||
static boolean done_tty_perm_invent_init = FALSE;
|
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
|
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3450,14 +3475,17 @@ void
|
|||||||
tty_update_inventory(int arg UNUSED)
|
tty_update_inventory(int arg UNUSED)
|
||||||
{
|
{
|
||||||
#ifdef TTY_PERM_INVENT
|
#ifdef TTY_PERM_INVENT
|
||||||
int row, col, pass, ccnt;
|
static char Empty[1] = { '\0' };
|
||||||
struct WinDesc *cw = 0;
|
struct WinDesc *cw;
|
||||||
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;
|
|
||||||
struct tty_perminvent_cell *cell;
|
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
|
/* we just return if the window creation failed, probably due to
|
||||||
not meeting size requirements */
|
not meeting size requirements */
|
||||||
@@ -3482,57 +3510,68 @@ tty_update_inventory(int arg UNUSED)
|
|||||||
tty_invent_box_glyph_init(cw);
|
tty_invent_box_glyph_init(cw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
text = Empty; /* lint suppression */
|
||||||
|
maxslot = cw->maxrow - 1;
|
||||||
obj = g.invent;
|
obj = g.invent;
|
||||||
text = null;
|
for (slot = 0; slot < maxslot; ++slot) {
|
||||||
ccnt = 0;
|
if (!sparse) {
|
||||||
if (obj) {
|
while (obj && ((obj->invlet == GOLD_SYM && !show_gold)
|
||||||
if (obj->invlet == '$')
|
|| (!obj->owornmask && inuse_only)))
|
||||||
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) {
|
|
||||||
obj = obj->nobj;
|
obj = obj->nobj;
|
||||||
if (obj) {
|
} else {
|
||||||
if (obj->invlet == '$')
|
if (!show_gold)
|
||||||
obj = obj->nobj;
|
nxtlet = (slot < 26) ? ('a' + slot) : ('A' + slot - 26);
|
||||||
if (obj) {
|
else
|
||||||
Snprintf(invbuf, sizeof invbuf, "%c - %s",
|
nxtlet = (slot == 0) ? GOLD_SYM
|
||||||
obj->invlet, doname(obj));
|
: (slot < 27) ? ('a' + slot - 1)
|
||||||
text = invbuf;
|
: (slot < 53) ? ('A' + slot - 27)
|
||||||
ccnt = 0;
|
: 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 {
|
} 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;
|
calling_from_update_inventory = TRUE;
|
||||||
/* now render to the display */
|
/* now render to the display */
|
||||||
for (row = 0; row < cw->maxrow; ++row)
|
for (row = 0; row < cw->maxrow; ++row)
|
||||||
@@ -3541,8 +3580,7 @@ tty_update_inventory(int arg UNUSED)
|
|||||||
if (cell->refresh || force_redraw) {
|
if (cell->refresh || force_redraw) {
|
||||||
if (cell->glyph) {
|
if (cell->glyph) {
|
||||||
tty_print_glyph(window, col + 1, row,
|
tty_print_glyph(window, col + 1, row,
|
||||||
cell->content.gi,
|
cell->content.gi, &nul_glyphinfo);
|
||||||
&nul_glyphinfo);
|
|
||||||
end_glyphout();
|
end_glyphout();
|
||||||
} else {
|
} else {
|
||||||
if (col != cw->curx || row != cw->cury)
|
if (col != cw->curx || row != cw->cury)
|
||||||
@@ -3561,6 +3599,38 @@ tty_update_inventory(int arg UNUSED)
|
|||||||
|
|
||||||
#ifdef TTY_PERM_INVENT
|
#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
|
void
|
||||||
tty_refresh_inventory(int start, int stop, int y)
|
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;
|
int row, col, glyph;
|
||||||
struct tty_perminvent_cell *cell;
|
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 (row = 0; row < cw->maxrow; ++row)
|
||||||
for (col = 0; col < cw->maxcol; ++col) {
|
for (col = 0; col < cw->maxcol; ++col) {
|
||||||
cell = &cw->cells[row][col];
|
cell = &cw->cells[row][col];
|
||||||
|
|||||||
Reference in New Issue
Block a user