diff --git a/include/decl.h b/include/decl.h index 67598d852..c66a98c11 100644 --- a/include/decl.h +++ b/include/decl.h @@ -972,9 +972,9 @@ struct instance_globals { persistent one doesn't get shrunk during filtering for item selection then regrown to full inventory, possibly being resized in the process */ winid cached_pickinv_win; -#ifdef TTY_PERM_INVENT - winid tty_invent_win; -#endif + winid perm_invent_win; + int core_invent_state; + /* query objlist callback: return TRUE if obj type matches "this_type" */ int this_type; const char *this_title; /* title for inventory list of specific type */ diff --git a/include/extern.h b/include/extern.h index f9525d6fd..e3ebc56ef 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1174,6 +1174,7 @@ extern long count_contents(struct obj *, boolean, boolean, boolean, boolean); extern void carry_obj_effects(struct obj *); extern const char *currency(long); extern void silly_thing(const char *, struct obj *); +extern void core_update_invent_slot(void); /* ### ioctl.c ### */ diff --git a/include/wintty.h b/include/wintty.h index 552684d4c..39f8dddd9 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -11,6 +11,7 @@ #define WINDOW_STRUCTS #ifdef TTY_PERM_INVENT + enum { tty_pi_minrow = 28, tty_pi_mincol = 79 }; /* for static init of zerottycell, put pointer first */ union ttycellcontent { @@ -123,11 +124,7 @@ struct tty_status_fields { #ifdef NHW_BASE #undef NHW_BASE #endif -#define NHW_BASE (NHW_TEXT + 1) - -#ifdef TTY_PERM_INVENT -#define NHW_TTYINVENT (NHW_BASE + 1) -#endif +#define NHW_BASE (NHW_LAST_TYPE + 1) extern struct window_procs tty_procs; diff --git a/include/wintype.h b/include/wintype.h index e262b1aa9..010ea2dbb 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -111,6 +111,8 @@ typedef struct gi { #define NHW_MAP 3 #define NHW_MENU 4 #define NHW_TEXT 5 +#define NHW_PERMINVENT 6 +#define NHW_LAST_TYPE NHW_PERMINVENT /* attribute types for putstr; the same as the ANSI value, for convenience */ #define ATR_NONE 0 @@ -162,19 +164,37 @@ typedef struct gi { #define MENU_BEHAVE_STANDARD 0x0000000U +/* inventory modes */ +enum inv_modes { InvNormal = 0, InvShowGold = 1, InvSparse = 2, InvInUse = 4 }; + +enum to_core_flags { + active = 0x001, + prohibited = 0x002, + no_init_done = 0x004 +}; + +enum from_core_requests { + request_settings = 1, + update_slot = 2, + render = 3 +}; + struct to_core { + long tocore_flags; boolean active; boolean use_update_inventory; /* disable the newer slot interface */ - int slotcount; - int low_slot_num, high_slot_num; - int max_slot_text; + int maxslot; + int needrows, needcols; + int haverows, havecols; }; struct from_core { - long piflags; - int slot; /* which inventory slot; 0 means info exchange only */ + enum from_core_requests core_request; + enum inv_modes invmode; + boolean force_redraw; + int slot; /* which inventory slot; 0 indicates request */ int invlet; - const char *text; /* the text to display */ + char text[BUFSZ]; }; struct perminvent_info_t { @@ -184,6 +204,8 @@ struct perminvent_info_t { typedef struct perminvent_info_t perminvent_info; +#define CORE_INVENT + /* clang-format on */ #endif /* WINTYPE_H */ diff --git a/src/allmain.c b/src/allmain.c index a39f5d216..c255ba18a 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -12,10 +12,6 @@ #include #endif -#ifdef TTY_PERM_INVENT -#include "wintty.h" /* just for define of NHW_TTYINVENT */ -#endif - static void moveloop_preamble(boolean); static void u_calc_moveamt(int); #ifdef POSITIONBAR @@ -635,11 +631,6 @@ display_gamewindows(void) ever having been used, use it here to pacify the Qt interface */ start_menu(WIN_INVEN, 0U), end_menu(WIN_INVEN, (char *) 0); -#ifdef TTY_PERM_INVENT - if (WINDOWPORT("tty") && iflags.perm_invent) { - g.tty_invent_win = create_nhwindow(NHW_TTYINVENT); - } -#endif #ifdef MAC /* This _is_ the right place for this - maybe we will * have to split display_gamewindows into create_gamewindows @@ -659,11 +650,7 @@ display_gamewindows(void) display_nhwindow(WIN_MESSAGE, FALSE); clear_glyph_buffer(); display_nhwindow(WIN_MAP, FALSE); -#ifdef TTY_PERM_INVENT - if (g.tty_invent_win != WIN_ERR) - display_nhwindow(g.tty_invent_win, FALSE); -#endif -} + } void newgame(void) diff --git a/src/decl.c b/src/decl.c index f0c032d05..f72478632 100644 --- a/src/decl.c +++ b/src/decl.c @@ -435,9 +435,8 @@ const struct instance_globals g_init = { NULL, /* invbuf */ 0, /* inbufsize */ WIN_ERR, /* cached_pickinv_win */ -#ifdef TTY_PERM_INVENT - WIN_ERR, /* tty_invent_win */ -#endif + WIN_ERR, /* perm_invent_win */ + 0, /* core_invent_state */ 0, /* this_type */ NULL, /* this_title */ UNDEFINED_VALUES, /* only (coord) */ diff --git a/src/invent.c b/src/invent.c index 7d3677b41..44090afe0 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2429,9 +2429,13 @@ update_inventory(void) */ save_suppress_price = iflags.suppress_price; iflags.suppress_price = 0; - - (*windowprocs.win_update_inventory)(0); - +#if defined(TTY_PERM_INVENT) && defined(CORE_INVENT) + if (WINDOWPORT("tty")) + core_update_invent_slot(); + else +#else + (*windowprocs.win_update_inventory)(0); +#endif iflags.suppress_price = save_suppress_price; } @@ -5333,4 +5337,188 @@ display_binventory(int x, int y, boolean as_if_seen) return n; } +#if defined(CORE_INVENT) +/* enum and structs are defined in wintype.h */ +static perminvent_info zeropi = { 0 }; +static perminvent_info pi_info; +static int invmode = InvNormal; +static char Empty[1] = { '\0' }; +#ifdef TTY_PERM_INVENT +extern void tty_perm_invent_toggled(boolean negated); +#endif + +void +core_update_invent_slot() +{ + static perminvent_info *pi = 0; + char *text, nxtlet; + int slot; + boolean show_gold = (invmode & InvShowGold) != 0, + inuse_only = (invmode & InvInUse) != 0, + sparse = (invmode & InvSparse) != 0; + const char *wport_id; + struct obj *obj; + + if (g.perm_invent_win == WIN_ERR && g.core_invent_state) + return; + + if (!iflags.perm_invent && g.core_invent_state) { + /* Odd - but this could be end-of-game disclosure + * which just sets boolean iflag.perm_invent to + * FALSE without actually doing anything else. + */ +#ifdef TTY_PERM_INVENT + if (WINDOWPORT("tty")) + tty_perm_invent_toggled(TRUE); /* TRUE means negated */ +#endif + (void) doredraw(); + return; + } + + /* + * The core looks after what content goes into the + * inventory slots, and deals with things like obj + * chains etc, so the window port doesn't have to. + * + * The window port informs the core of the number of + * slots that it will process. + * + * The core tells the window port what the contents of the + * inventory slots should be. + * + * The core requests the window port when to render, after + * all the content has been updated. + * + * The window port looks after the placement of an inventory + * slot's contents onto the display in an appropriate fashion, + * The core doesn't care, and leaves that up to the window port. + * + * The core slot handling is no longer tied to TTY_PERM_INVENT, + * although at this point that's the only window port to utilize + * it. The rest are still rolling their own via the basic + * [port]_update_inventory() mechanism. + */ + + if (WINDOWPORT("tty") && iflags.perm_invent) + wport_id = "tty perm_invent"; + else + wport_id = "perm_invent"; + + pi_info.fromcore.core_request = 0; + if (!g.core_invent_state) { + { + /*TEMPORARY*/ + char *envtmp = nh_getenv("TTYINV"); + invmode = envtmp ? atoi(envtmp) : InvNormal; + } + pi_info.fromcore.invmode = invmode; + pi_info = zeropi; + /* Send the wport a request to get the related settings. */ + pi_info.fromcore.core_request = request_settings; + if ((pi = update_invent_slot(g.perm_invent_win, (slot = 0), &pi_info))) { + if ((pi->tocore.tocore_flags & prohibited) != 0) { + /* sizes aren't good enough */ + set_option_mod_status("perm_invent", set_gameview); + iflags.perm_invent = FALSE; + pline("%s could not be enabled.", wport_id); + pline("%s needs a terminal that is at least %dx%d, yours is %dx%d.", + wport_id, + pi->tocore.needrows, pi->tocore.needcols, + pi->tocore.haverows, pi->tocore.havecols); + wait_synch(); + return; + } + } + g.perm_invent_win = create_nhwindow(NHW_PERMINVENT); + if (g.perm_invent_win == WIN_ERR) + return; + display_nhwindow(g.perm_invent_win, FALSE); + g.core_invent_state++; + } + text = Empty; /* lint suppression */ + pi_info.fromcore.core_request = update_slot; + pi_info.fromcore.force_redraw = g.program_state.in_docrt ? TRUE : FALSE, + + obj = g.invent; + for (slot = 0; slot < pi->tocore.maxslot; ++slot) { + nxtlet = '?'; /* always gets set to something else if actually used */ + if (!sparse) { + while (obj && ((obj->invlet == GOLD_SYM && !show_gold) + || (!obj->owornmask && inuse_only))) + obj = obj->nobj; + } 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 fromcore.text 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(pi_info.fromcore.text, + sizeof pi_info.fromcore.text, + "%c - %s", obj->invlet, text); + text = pi_info.fromcore.text; + obj = obj->nobj; /* set up for next iteration */ + } else if (sparse) { + Sprintf(pi_info.fromcore.text, "%c", nxtlet); /* empty slot */ + text = pi_info.fromcore.text; + } else { + if (slot == 0) { + Sprintf(pi_info.fromcore.text, "%-4s[%s]", "", + !g.invent ? "empty" + : inuse_only ? "no items are in use" + : "only gold"); + text = pi_info.fromcore.text; + } else { + text = Empty; /* "" => fill slot with spaces */ + } + } + if (!*text) + pi_info.fromcore.text[0] = Empty[0]; + pi = update_invent_slot(g.perm_invent_win, slot + 1, &pi_info); + } + pi_info.fromcore.force_redraw = g.program_state.in_docrt ? TRUE : FALSE, + pi_info.fromcore.core_request = render; + pi = update_invent_slot(g.perm_invent_win, (slot = 0), &pi_info); +} + +#if 0 +RESTORE_WARNING_FORMAT_NONLITERAL + +void +tty_perm_invent_toggled(boolean negated) +{ + if (negated) { + if (g.perm_invent_win != WIN_ERR) + destroy_nhwindow(g.perm_invent_win), g.perm_invent_win = WIN_ERR; + done_tty_perm_invent_init = FALSE; + } else { + g.perm_invent_win = create_nhwindow(NHW_PERMINVENT); + if (g.perm_invent_win != WIN_ERR) + display_nhwindow(g.perm_invent_win, FALSE); + } +} +#endif +#endif /* CORE_INVENT */ + /*invent.c*/ diff --git a/src/options.c b/src/options.c index edcc6b8bc..71dd7258d 100644 --- a/src/options.c +++ b/src/options.c @@ -4417,7 +4417,7 @@ optfn_boolean(int optidx, int req, boolean negated, char *opts, char *op) -> tty_create_nhwindow(WIN_TTYINVENT) -> tty_create_invent() gives feedback for failure (terminal too small) */ - if (g.tty_invent_win == WIN_ERR) + if (g.perm_invent_win == WIN_ERR) return optn_silenterr; } #endif diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 193aada84..89ad5baeb 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -255,15 +255,25 @@ void g_pututf8(uint8 *utf8str); #ifdef TTY_PERM_INVENT void tty_perm_invent_toggled(boolean negated); -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; static struct tty_perminvent_cell zerottycell = { 0, 0, 0, 0, { 0 } }; static glyph_info zerogi = { 0 }; +#ifdef CORE_INVENT +static struct to_core zero_tocore = { 0 }; +#endif 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; +static int ttyinvmode = InvNormal; /* enum is in wintype.h */ +static boolean done_tty_perm_invent_init = FALSE; +#ifndef NOINVSYM /* invent.c */ +#define NOINVSYM '#' +#endif +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; +static boolean assesstty(enum inv_modes, short *, short *, + long *, long *, long *, long *, long *); +static void ttyinv_populate_slot(struct WinDesc *, int, int, const char *); #endif /* @@ -551,8 +561,8 @@ tty_preference_update(const char *pref) only might individual symbols change (punctuation vs line drawing), the way to render them might change too (Handling: DEC/UTF8/&c) */ if (!strcmp(pref, "symset") && iflags.window_inited) { - if (g.tty_invent_win != WIN_ERR) - tty_invent_box_glyph_init(wins[g.tty_invent_win]); + if (g.perm_invent_win != WIN_ERR) + tty_invent_box_glyph_init(wins[g.perm_invent_win]); } #endif return; @@ -1597,12 +1607,7 @@ tty_create_nhwindow(int type) newwin->maxrow = newwin->maxcol = 0; break; #ifdef TTY_PERM_INVENT - case NHW_TTYINVENT: - { - /*TEMPORARY*/ - char *envtmp = nh_getenv("TTYINV"); - ttyinvmode = envtmp ? atoi(envtmp) : InvNormal; - } + case NHW_PERMINVENT: return ttyinv_create_window(newid, newwin); #endif default: @@ -1640,7 +1645,8 @@ tty_create_nhwindow(int type) static int ttyinv_create_window(int newid, struct WinDesc *newwin) { - int i, r, c, minrow; + int i, r, c; + long minrow; /* long to match maxrow declaration */ unsigned n; /* Is there enough real estate to do this beyond the status line? @@ -1668,37 +1674,20 @@ ttyinv_create_window(int newid, struct WinDesc *newwin) * 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 */ + /* preliminary init in case tty_desctroy_nhwindow() gets called */ newwin->data = (char **) 0; newwin->datlen = (short *) 0; newwin->cells = (struct tty_perminvent_cell **) 0; - 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 + bottom border */ - - if (newwin->rows < minrow || newwin->cols < tty_pi_mincol) { - tty_destroy_nhwindow(newid); /* sets g.tty_invent_win to WIN_ERR */ + if (!assesstty(ttyinvmode, + &newwin->offx, &newwin->offy, &newwin->rows, &newwin->cols, + &newwin->maxcol, &minrow, &newwin->maxrow)) { + tty_destroy_nhwindow(newid); /* sets g.perm_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.", - minrow + 1 + ROWNO + 3, tty_pi_mincol, + (int) (minrow + 1 + ROWNO + 3), tty_pi_mincol, ttyDisplay->rows, ttyDisplay->cols); tty_wait_synch(); set_option_mod_status("perm_invent", set_gameview); @@ -1739,10 +1728,11 @@ ttyinv_create_window(int newid, struct WinDesc *newwin) newwin->cells[r][c].glyph = 1; } } - + if (!done_tty_perm_invent_init) + tty_invent_box_glyph_init(newwin); return newid; } -#endif +#endif /* TTY_PERM_INVENT */ static void erase_menu_or_text(winid window, struct WinDesc *cw, boolean clear) @@ -2739,7 +2729,7 @@ tty_destroy_nhwindow(winid window) if (cw->type == NHW_MAP) clear_screen(); #ifdef TTY_PERM_INVENT - if (cw->type == NHW_TTYINVENT) { + if (cw->type == NHW_PERMINVENT) { int r, c; if (cw->cells) { @@ -2762,7 +2752,7 @@ tty_destroy_nhwindow(winid window) cw->rows = cw->cols = 0; } cw->maxrow = cw->maxcol = 0; - g.tty_invent_win = WIN_ERR; + g.perm_invent_win = WIN_ERR; } #endif free_window_info(cw, TRUE); @@ -2887,7 +2877,7 @@ tty_putsym(winid window, int x, int y, char ch) case NHW_STATUS: #endif #ifdef TTY_PERM_INVENT - case NHW_TTYINVENT: + case NHW_PERMINVENT: #endif case NHW_MAP: case NHW_BASE: @@ -2959,7 +2949,7 @@ tty_putstr(winid window, int attr, const char *str) return; if (cw->type != NHW_MESSAGE #ifdef TTY_PERM_INVENT - && window != g.tty_invent_win + && window != g.perm_invent_win #endif ) str = compress_str(str); @@ -3457,8 +3447,6 @@ tty_select_menu(winid window, int how, menu_item **menu_list) return n; } -RESTORE_WARNING_FORMAT_NONLITERAL - /* special hack for treating top line --More-- as a one item menu */ char tty_message_menu(char let, int how, const char *mesg) @@ -3491,32 +3479,34 @@ tty_message_menu(char let, int how, const char *mesg) return ((how == PICK_ONE && morc == let) || morc == '\033') ? morc : '\0'; } -#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 - /* update persistent inventory window */ void tty_update_inventory(int arg UNUSED) { #ifdef TTY_PERM_INVENT +#ifndef CORE_INVENT 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; + winid window = g.perm_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; + if (g.perm_invent_win == WIN_ERR + && !done_tty_perm_invent_init && iflags.perm_invent) { + g.perm_invent_win = create_nhwindow(NHW_PERMINVENT); + if (g.perm_invent_win == WIN_ERR) { + tty_perm_invent_toggled(TRUE); /* TRUE means negated */ + return; + } + display_nhwindow(g.perm_invent_win, FALSE); + window = g.perm_invent_win; + } /* we just return if the window creation failed, probably due to not meeting size requirements */ if (window == WIN_ERR) @@ -3624,29 +3614,155 @@ tty_update_inventory(int arg UNUSED) } } calling_from_update_inventory = FALSE; -#endif +#endif /* CORE_INVENT */ +#endif /* TTY_PERM_INVENT */ return; } perminvent_info * tty_update_invent_slot( - winid window UNUSED, /* window to use, must be of type NHW_MENU */ - int inventory_slot UNUSED, /* slot id: 0 - info return to core */ - /* 1 - gold slot */ - /* 2 - 29 obj slots */ - perminvent_info *pi UNUSED) + winid window, /* window to use, must be of type NHW_MENU */ + int slot, + perminvent_info *pi) { +#if !defined(TTY_PERM_INVENT) || !defined(CORE_INVENT) return (perminvent_info *) 0; + nhUse(window); + nhUse(slot); + nhUse(pi); +#else + boolean force_redraw, tty_ok, show_gold, inuse_only; + int row, col, side, maxslot; + /* winid window = g.perm_invent_win; */ + struct WinDesc *cw; + struct tty_perminvent_cell *cell; + /* these types are set match the wintty.h field declarations */ + long minrow; /* long to match maxrow declaration in wintty.h */ + short offx, offy; + long rows, cols, maxrow, maxcol; + + if (!pi) + return (perminvent_info *) 0; + if (!done_tty_perm_invent_init + && pi->fromcore.core_request != request_settings) { + pi->tocore.tocore_flags |= no_init_done; + return pi; + } + + switch(pi->fromcore.core_request) { + case request_settings: { + pi->tocore = zero_tocore; + ttyinvmode = pi->fromcore.invmode; + inuse_only = (ttyinvmode & InvInUse) != 0; + tty_ok = assesstty(pi->fromcore.invmode, + &offx, &offy, &rows, &cols, + &maxcol, &minrow, &maxrow); + pi->tocore.needrows = (int) (minrow + 1 + ROWNO + 3); + pi->tocore.needcols = (int) tty_pi_mincol; + pi->tocore.haverows = (int) ttyDisplay->rows; + pi->tocore.havecols = (int) ttyDisplay->cols; + if (!tty_ok) { + pi->tocore.tocore_flags |= prohibited; /* prohibited */ + return pi; + } + maxslot = (maxrow - 2) * (!inuse_only ? 2 : 1); + pi->tocore.maxslot = maxslot; + return pi; + break; + } + case update_slot: + if ((cw = wins[window]) == (struct WinDesc *) 0) + panic(winpanicstr, window); + slot -= 1; /* 0 is used for commands */ + show_gold = (ttyinvmode & InvShowGold) != 0; + 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, pi->fromcore.text); + break; + case render: + if ((cw = wins[window]) == (struct WinDesc *) 0) + panic(winpanicstr, window); + /* render to the display */ + force_redraw = pi->fromcore.force_redraw; +// show_gold = (ttyinvmode & InvShowGold) != 0; +// inuse_only = (ttyinvmode & InvInUse) != 0; +// sparse = (ttyinvmode & InvSparse) != 0; +// if (!done_tty_perm_invent_init) + calling_from_update_inventory = TRUE; + for (row = 0; row < cw->maxrow; ++row) + for (col = 0; col < cw->maxcol; ++col) { + cell = &cw->cells[row][col]; + if (cell->refresh || force_redraw) { + if (cell->glyph) { + tty_print_glyph(window, col + 1, row, + cell->content.gi, &nul_glyphinfo); + end_glyphout(); + } else { + if (col != cw->curx || row != cw->cury) + tty_curs(window, col + 1, row); + (void) putchar(cell->content.ttychar); + ttyDisplay->curx++; + cw->curx++; + } + cell->refresh = 0; + } + } + calling_from_update_inventory = FALSE; + break; + default: + impossible("invalid request to tty_update_invent_slot %u", + pi->fromcore.core_request); + } + return pi; +#endif } +RESTORE_WARNING_FORMAT_NONLITERAL + #ifdef TTY_PERM_INVENT +/* + * returns TRUE if things are ok + */ +static boolean +assesstty( + enum inv_modes invmode, + short *offx, short *offy, long *rows, long *cols, + long *maxcol, long *minrow, long *maxrow) +{ + boolean show_gold, inuse_only; + + show_gold = (invmode & InvShowGold) != 0; + inuse_only = (invmode & InvInUse) != 0; + + *offx = 0; + /* topline + map rows + status lines */ + *offy = 1 + ROWNO + 3; /* 3: + 2 + (iflags.wc2_statuslines > 2) */ + *rows = (ttyDisplay->rows - (*offy)); + *cols = ttyDisplay->cols; + *minrow = tty_pi_minrow; + if (show_gold) + *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 (inuse_only) + *minrow = 1 + 15 + 1; /* top border + 15 lines + bottom border */ + *maxrow = *minrow; + *maxcol = *cols; + return !(*rows < *minrow || *cols < tty_pi_mincol); +} /* 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 row, /* 'row' within the window, not within screen */ int side, /* 'side'==0 is left panel or ==1 is right panel */ const char *text) { @@ -3680,12 +3796,14 @@ ttyinv_populate_slot( } } +DISABLE_WARNING_FORMAT_NONLITERAL + void tty_refresh_inventory(int start, int stop, int y) { int row = y, col, col_limit = stop; struct WinDesc *cw = 0; - winid window = g.tty_invent_win; + winid window = g.perm_invent_win; struct tty_perminvent_cell *cell; if (window == WIN_ERR || !iflags.perm_invent || y < 0) @@ -3718,6 +3836,8 @@ tty_refresh_inventory(int start, int stop, int y) } } +RESTORE_WARNING_FORMAT_NONLITERAL + static void tty_invent_box_glyph_init(struct WinDesc *cw) { @@ -3789,22 +3909,20 @@ tty_invent_box_glyph_init(struct WinDesc *cw) done_tty_perm_invent_init = TRUE; } -RESTORE_WARNING_FORMAT_NONLITERAL - void tty_perm_invent_toggled(boolean negated) { if (negated) { - if (g.tty_invent_win != WIN_ERR) - destroy_nhwindow(g.tty_invent_win), g.tty_invent_win = WIN_ERR; + if (g.perm_invent_win != WIN_ERR) + destroy_nhwindow(g.perm_invent_win), g.perm_invent_win = WIN_ERR; done_tty_perm_invent_init = FALSE; } else { - g.tty_invent_win = create_nhwindow(NHW_TTYINVENT); - if (g.tty_invent_win != WIN_ERR) - display_nhwindow(g.tty_invent_win, FALSE); + g.perm_invent_win = create_nhwindow(NHW_PERMINVENT); + if (g.perm_invent_win != WIN_ERR) + display_nhwindow(g.perm_invent_win, FALSE); } } -#endif +#endif /* TTY_PERM_INVENT */ void tty_mark_synch(void) @@ -3848,8 +3966,8 @@ docorner(register int xmin, register int ymax, int ystart_between_menu_pages) #ifdef TTY_PERM_INVENT struct WinDesc *icw = 0; - if (g.tty_invent_win != WIN_ERR) - icw = wins[g.tty_invent_win]; + if (g.perm_invent_win != WIN_ERR) + icw = wins[g.perm_invent_win]; #endif HUPSKIP(); @@ -3902,7 +4020,8 @@ docorner(register int xmin, register int ymax, int ystart_between_menu_pages) } end_glyphout(); - if (ymax >= (int) wins[WIN_STATUS]->offy) { + if (ymax >= (int) wins[WIN_STATUS]->offy + && !ystart_between_menu_pages) { /* we have wrecked the bottom line */ g.context.botlx = 1; bot();