]> granicus.if.org Git - nethack/commitdiff
rework TTY_PERM_INVENT; update window port interface
authornhmall <nhmall@nethack.org>
Sun, 3 Jul 2022 04:34:08 +0000 (00:34 -0400)
committernhmall <nhmall@nethack.org>
Sun, 3 Jul 2022 04:35:32 +0000 (00:35 -0400)
Change the inner workings of the experimental TTY_PERM_INVENT.

Switch to delivering the content to tty for the experimental perm_invent
via the existing window port interface (start_menu(), add_menu(), end_menu).

This also adds a new window port interface call ctrl_nhwindow() for
delivering information to the window port, and/or obtaining specific
information from the window port. The information and requests can
be extended as required. To be documented later once the changes settle
down.

Due to the intrusive nature of these changes and the possibility of
some bugs in the new code, I'm going to leave TTY_PERM_INVENT commented
out in the repository for a day or two.  Anyone wishing to test it out
can do so by uncommenting TTY_PERM_INVENT in config.h.

28 files changed:
include/config.h
include/decl.h
include/extern.h
include/winX.h
include/wincurs.h
include/winprocs.h
include/wintty.h
include/wintype.h
src/allmain.c
src/decl.c
src/display.c
src/invent.c
src/mdlib.c
src/options.c
src/windows.c
sys/windows/win32api.h
sys/windows/windmain.c
win/Qt/qt_bind.cpp
win/Qt/qt_bind.h
win/X11/winX.c
win/chain/wc_chainin.c
win/chain/wc_chainout.c
win/curses/cursmain.c
win/share/safeproc.c
win/shim/winshim.c
win/tty/wintty.c
win/win32/mswproc.c
win/win32/winMS.h

index 2e9df46d7d562c2bcec3fc4670b7ea419a9eddac..9ed4e3273fcb8b70c8f08a05143f6f7db8e37bef 100644 (file)
@@ -562,7 +562,7 @@ typedef unsigned char uchar;
 
 /* An experimental minimalist inventory list capability under tty if you have
  * at least 28 additional rows beneath the status window on your terminal  */
-#define TTY_PERM_INVENT
+/* #define TTY_PERM_INVENT */
 
 /* NetHack will execute an external program whenever a new message-window
  * message is shown.  The program to execute is given in environment variable
index 140cde5f9050b10c454d6d3d45fded910a50fa73..5e6ee46e39f024cf54d247d3ab6339de60795d5e 100644 (file)
@@ -972,8 +972,10 @@ 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;
-    winid perm_invent_win;
     int core_invent_state;
+    int in_sync_perminvent;
+    int perm_invent_toggling_direction;
+    long glyph_reset_timestamp;
 
     /* query objlist callback: return TRUE if obj type matches "this_type" */
     int this_type;
index b114cf6bcdd358ed9aa9a4b182bda845e167f08d..5efb5aa0bbc04b5311306a8936d66de23546706a 100644 (file)
@@ -1176,6 +1176,7 @@ extern const char *currency(long);
 extern void silly_thing(const char *, struct obj *);
 extern void sync_perminvent(void);
 extern void perm_invent_toggled(boolean negated);
+extern void prepare_perminvent(winid window);
 
 /* ### ioctl.c ### */
 
index 725d4e9023bac1057887d0fb5092d10db2dd1c92..94b89ce3521ae85dd3cdcc4eabf74fe42e3940c7 100644 (file)
@@ -487,6 +487,6 @@ extern void genl_outrip(winid, int, time_t);
 
 extern void X11_preference_update(const char *);
 extern void X11_update_inventory(int);
-extern perminvent_info *X11_update_invent_slot(winid, int, perminvent_info *);
+extern win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *);
 
 #endif /* WINX_H */
index 83df0113b74b27069d32f1a664e1968a20106a16..580ad3adfa5e675da8529b5cf7f3612e69ce9c3a 100644 (file)
@@ -113,7 +113,7 @@ extern void genl_outrip(winid tmpwin, int how, time_t when);
 extern void curses_preference_update(const char *pref);
 extern void curs_reset_windows(boolean, boolean);
 extern void curses_update_inventory(int);
-extern perminvent_info *curses_update_invent_slot(winid, int, perminvent_info *);
+extern win_request_info *curses_ctrl_nhwindow(winid, int, win_request_info *);
 
 /* curswins.c */
 
index 9ad5667a6e077f17d8775279c0f716165e59e6f4..8d7ee6164e8bcd6338ee3a6583cebc939f36aca5 100644 (file)
@@ -92,7 +92,7 @@ struct window_procs {
                               unsigned long *);
     boolean (*win_can_suspend)(void);
     void (*win_update_inventory)(int);
-    perminvent_info *(*win_update_invent_slot)(winid, int, perminvent_info *);
+    win_request_info *(*win_ctrl_nhwindow)(winid, int, win_request_info *);
 };
 
 extern
@@ -174,7 +174,7 @@ extern
  */
 #define status_enablefield (*windowprocs.win_status_enablefield)
 #define status_update (*windowprocs.win_status_update)
-#define update_invent_slot (*windowprocs.win_update_invent_slot)
+#define ctrl_nhwindow (*windowprocs.win_ctrl_nhwindow)
 
 /*
  * 
@@ -491,7 +491,7 @@ extern void stdio_nonl_raw_print(const char *);
 extern void stdio_raw_print_bold(const char *);
 extern void stdio_wait_synch(void);
 extern void safe_update_inventory(int);
-extern perminvent_info *safe_update_invent_slot(winid, int, perminvent_info *);
+extern win_request_info *safe_ctrl_nhwindow(winid, int, win_request_info *);
 extern int stdio_nhgetch(void);
 #endif /* SAFEPROCS */
 #endif /* WINPROCS_H */
index e6cbe68aece8b8dee1b95dd1e643fde1281d82cc..e59cf6a50beb7adecc5619180c021cb76a50f10a 100644 (file)
@@ -12,7 +12,7 @@
 
 #ifdef TTY_PERM_INVENT
 
-enum { tty_pi_minrow = 28, tty_pi_mincol = 79 };
+enum { tty_perminv_minrow = 28, tty_perminv_mincol = 79 };
 /* for static init of zerottycell, put pointer first */
 union ttycellcontent {
     glyph_info *gi;
@@ -283,7 +283,7 @@ E void genl_outrip(winid, int, time_t);
 E char *tty_getmsghistory(boolean);
 E void tty_putmsghistory(const char *, boolean);
 E void tty_update_inventory(int);
-E perminvent_info *tty_update_invent_slot(winid, int, perminvent_info *);
+E win_request_info *tty_ctrl_nhwindow(winid, int, win_request_info *);
 
 #ifdef TTY_PERM_INVENT
 E void tty_refresh_inventory(int start, int stop, int y);
index 3ebb3db56c70ad5ffab0daa86c871870886f6cb7..dd69b9446074317b4b6bb6b49745b4914c12f296 100644 (file)
@@ -169,6 +169,9 @@ typedef struct gi {
  */
 
 #define MENU_BEHAVE_STANDARD      0x0000000U
+#define MENU_BEHAVE_PERMINV       0x0000001U
+
+enum perm_invent_toggles {toggling_off = -1, toggling_not = 0, toggling_on = 1 };
 
 /* inventory modes */
 enum inv_modes { InvNormal = 0, InvShowGold = 1, InvSparse = 2, InvInUse = 4 };
@@ -180,9 +183,8 @@ enum to_core_flags {
 };
 
 enum from_core_requests {
-    request_settings = 1,
-    update_slot      = 2,
-    render           = 3
+    set_mode         = 1,
+    request_settings = 2,
 };
 
 struct to_core {
@@ -197,24 +199,16 @@ struct to_core {
 struct from_core {
     enum from_core_requests core_request;
     enum inv_modes invmode;
-    boolean force_redraw;
-    int slot;           /* which inventory slot + 1; 0 indicates request */
-    int invlet;
-    char text[BUFSZ];
-    int32_t clr;        /* adjusted color 0 = ignore
-                         * 1-16             = NetHack color + 1
-                         * 17..16,777,233   = 24-bit color  + 17
-                         */
 };
 
-struct perminvent_info_t {
+struct win_request_info_t {
     struct to_core tocore;
     struct from_core fromcore;
 };
 
-typedef struct perminvent_info_t perminvent_info;
+typedef struct win_request_info_t win_request_info;
 
-#define CORE_INVENT
+/* #define CORE_INVENT */
 
 /* clang-format on */
 
index 34219054547b9423f1c89ab201694c8073e3aa0c..a10faacacdecf2c816b9ad7162f537de02c5c80d 100644 (file)
@@ -619,6 +619,8 @@ stop_occupation(void)
 void
 display_gamewindows(void)
 {
+    int menu_behavior = MENU_BEHAVE_STANDARD;
+
     WIN_MESSAGE = create_nhwindow(NHW_MESSAGE);
     if (VIA_WINDOWPORT()) {
         status_initialize(0);
@@ -627,9 +629,15 @@ display_gamewindows(void)
     }
     WIN_MAP = create_nhwindow(NHW_MAP);
     WIN_INVEN = create_nhwindow(NHW_MENU);
+#ifdef TTY_PERM_INVENT
+    if (WINDOWPORT(tty) && WIN_INVEN != WIN_ERR) {
+        menu_behavior = MENU_BEHAVE_PERMINV;
+        prepare_perminvent(WIN_INVEN);
+    }
+#endif
     /* in case of early quit where WIN_INVEN could be destroyed before
        ever having been used, use it here to pacify the Qt interface */
-    start_menu(WIN_INVEN, 0U), end_menu(WIN_INVEN, (char *) 0);
+    start_menu(WIN_INVEN, menu_behavior), end_menu(WIN_INVEN, (char *) 0);
 
 #ifdef MAC
     /* This _is_ the right place for this - maybe we will
index f724786325472795379e87dd80fb051fcea1bbb2..70260c017168c2cdf492bd94df44cbaef6bb823e 100644 (file)
@@ -435,8 +435,10 @@ const struct instance_globals g_init = {
     NULL, /* invbuf */
     0, /* inbufsize */
     WIN_ERR, /* cached_pickinv_win */
-    WIN_ERR, /* perm_invent_win */
     0,       /* core_invent_state */
+    0,       /* in_sync_perminvent */
+    0,       /* perm_invent_toggling_direction */
+    0L,      /* glyph_reset_timestamp */
     0, /* this_type */
     NULL, /* this_title */
     UNDEFINED_VALUES, /* only (coord) */
index 1b83021c66f73a268c1b9e842e49d953a971345b..228028f2ccd13e4912cc0864082dd4bf80d5b60a 100644 (file)
@@ -2775,6 +2775,7 @@ reset_glyphmap(enum glyphmap_change_triggers trigger)
             color = NO_COLOR;
         gmap->sym.color = color;
     }
+    g.glyph_reset_timestamp = g.moves;
 }
 
 /* ------------------------------------------------------------------------ */
index b91e6c192921df4622a0c4852f38a24e2e8d58d4..07c74ca3cd4b9116d818115f2c8756370a138ce1 100644 (file)
@@ -42,6 +42,12 @@ static boolean item_naming_classification(struct obj *, char *, char *);
 static int item_reading_classification(struct obj *, char *);
 static void mime_action(const char *);
 
+/* enum and structs are defined in wintype.h */
+static win_request_info zerowri = { { 0L, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0 } };
+static win_request_info wri_info;
+static int done_setting_perminv_flags = 0;
+static boolean in_perm_invent_toggled;
+
 /* wizards can wish for venom, which will become an invisible inventory
  * item without this.  putting it in inv_order would mean venom would
  * suddenly become a choice for all the inventory-class commands, which
@@ -2440,7 +2446,7 @@ update_inventory(void)
      */
     save_suppress_price = iflags.suppress_price;
     iflags.suppress_price = 0;
-#if defined(TTY_PERM_INVENT) && defined(CORE_INVENT)
+#if defined(TTY_PERM_INVENT)
     if (WINDOWPORT(tty))
         sync_perminvent();
     else
@@ -3183,27 +3189,40 @@ display_pickinv(
     char ilet, ret, *formattedobj;
     const char *invlet = flags.inv_order;
     int n, classcount;
-    winid win;                        /* windows being used */
+    winid win; /* windows being used */
     anything any;
     menu_item *selected;
     unsigned sortflags;
     Loot *sortedinvent, *srtinv;
     boolean wizid = (wizard && iflags.override_ID), gotsomething = FALSE;
-    int clr = 0;
+    int clr = 0, menu_behavior = MENU_BEHAVE_STANDARD;
+    boolean show_gold = TRUE, sparse = FALSE, inuse_only = FALSE,
+            doing_perm_invent = FALSE, save_flags_sortpack = flags.sortpack;
 
     if (lets && !*lets)
         lets = 0; /* simplify tests: (lets) instead of (lets && *lets) */
 
-    if (iflags.perm_invent && (lets || xtra_choice || wizid)) {
+    if ((iflags.perm_invent && (lets || xtra_choice || wizid))
+#ifdef TTY_PERM_INVENT
+        || !g.in_sync_perminvent
+#endif
+        || WIN_INVEN == WIN_ERR) {
         /* partial inventory in perm_invent setting; don't operate on
            full inventory window, use an alternate one instead; create
            the first time needed and keep it for re-use as needed later */
         if (g.cached_pickinv_win == WIN_ERR)
             g.cached_pickinv_win = create_nhwindow(NHW_MENU);
         win = g.cached_pickinv_win;
-    } else
+    } else {
         win = WIN_INVEN;
-
+        menu_behavior = MENU_BEHAVE_PERMINV;
+        prepare_perminvent(win);
+        show_gold = ((wri_info.fromcore.invmode & InvShowGold) != 0);
+        sparse = ((wri_info.fromcore.invmode & InvSparse) != 0);
+        inuse_only = ((wri_info.fromcore.invmode & InvInUse) != 0);
+        doing_perm_invent = TRUE;
+       nhUse(sparse);
+    }
     /*
      * Exit early if no inventory -- but keep going if we are doing
      * a permanent inventory update.  We need to keep going so the
@@ -3266,10 +3285,18 @@ display_pickinv(
     sortflags = (flags.sortloot == 'f') ? SORTLOOT_LOOT : SORTLOOT_INVLET;
     if (flags.sortpack)
         sortflags |= SORTLOOT_PACK;
+#ifdef TTY_PERM_INVENT
+    if (doing_perm_invent && WINDOWPORT(tty)) {
+        sortflags = SORTLOOT_INVLET;
+        save_flags_sortpack = flags.sortpack;
+        flags.sortpack = FALSE;
+    }
+#else
+    nhUse(save_flags_sortpack);
+#endif
     sortedinvent = sortloot(&g.invent, sortflags, FALSE,
                             (boolean (*)(OBJ_P)) 0);
-
-    start_menu(win, MENU_BEHAVE_STANDARD);
+    start_menu(win, menu_behavior);
     any = cg.zeroany;
     if (wizid) {
         int unid_cnt;
@@ -3327,6 +3354,11 @@ display_pickinv(
         if (!flags.sortpack || otmp->oclass == *invlet) {
             if (wizid && !not_fully_identified(otmp))
                 continue;
+            if (doing_perm_invent
+                && ((otmp->invlet == GOLD_SYM && !show_gold)
+                    || ((otmp->invlet != GOLD_SYM)
+                        && (!otmp->owornmask && inuse_only))))
+                continue;
             any = cg.zeroany; /* all bits zero */
             ilet = otmp->invlet;
             if (flags.sortpack && !classcount) {
@@ -3387,6 +3419,10 @@ display_pickinv(
                  not_carrying_anything, MENU_ITEMFLAGS_NONE);
         want_reply = FALSE;
     }
+#ifdef TTY_PERM_INVENT
+    if (doing_perm_invent && WINDOWPORT(tty))
+        flags.sortpack = save_flags_sortpack;
+#endif
     end_menu(win, (query && *query) ? query : (char *) 0);
 
     n = select_menu(win,
@@ -5361,47 +5397,39 @@ display_binventory(coordxy x, coordxy y, boolean as_if_seen)
     return n;
 }
 
-#if defined(CORE_INVENT)
-/* enum and structs are defined in wintype.h */
-static perminvent_info zeropi = { {0L,0,0,0,0,0,0,0}, {0,0,0,0,0,{0},0} };
-static perminvent_info pi_info;
-static char Empty[1] = { '\0' };
-static int done_environment_var = 0;
-#ifdef TTY_PERM_INVENT
-extern void tty_perm_invent_toggled(boolean negated);
-static boolean in_perm_invent_toggled;
-#endif
+void
+prepare_perminvent(winid window)
+{
+    win_request_info *wri UNUSED;
+
+    if (!done_setting_perminv_flags) {
+        wri_info = zerowri;
+        /*TEMPORARY*/
+        char *envtmp = nh_getenv("TTYINV");
+        wri_info.fromcore.invmode = envtmp ? atoi(envtmp) : InvNormal;
+        /*  relay the mode settings to the window port */
+        wri = ctrl_nhwindow(window, set_mode, &wri_info);
+        done_setting_perminv_flags = 1;
+    }
+}
 
 void
 sync_perminvent(void)
 {
-    static perminvent_info *pi = 0;
-    char *text, nxtlet;
-    int slot;
-    boolean show_gold, inuse_only, sparse;
+    static win_request_info *wri = 0;
     const char *wport_id;
-    struct obj *obj;
-
-    if (!done_environment_var) {
-       pi_info = zeropi;
-       /*TEMPORARY*/
-       char *envtmp = nh_getenv("TTYINV");
-       pi_info.fromcore.invmode = envtmp ? atoi(envtmp) : InvNormal;
-       done_environment_var = 1;
-    }
-    show_gold = (pi_info.fromcore.invmode & InvShowGold) != 0;
-    inuse_only = (pi_info.fromcore.invmode & InvInUse) != 0;
-    sparse = (pi_info.fromcore.invmode & InvSparse) != 0;
 
-    if ((g.perm_invent_win == WIN_ERR && g.core_invent_state)
-        || (pi_info.tocore.tocore_flags & prohibited))
+    if (WIN_INVEN == WIN_ERR) {
+        if ((g.core_invent_state
+             || (wri_info.tocore.tocore_flags & prohibited))
+            && !(in_perm_invent_toggled
+                 && g.perm_invent_toggling_direction == toggling_on))
             return;
+    }
+    if (!done_setting_perminv_flags && WIN_INVEN != WIN_ERR)
+        prepare_perminvent(WIN_INVEN);
 
-    if ((!iflags.perm_invent && g.core_invent_state)
-#ifdef TTY_PERM_INVENT
-        && !in_perm_invent_toggled
-#endif
-                                                     ){
+    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.
@@ -5413,157 +5441,81 @@ sync_perminvent(void)
         (void) doredraw();
         return;
     }
-    if (!iflags.perm_invent
-#ifdef TTY_PERM_INVENT
-&& !in_perm_invent_toggled
-#endif
-                            )
-        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 following conditions can bring us to here:
+     * 1. iflags.perm_invent is on
+     *      AND
+     *    g.core_invent_state is still zero.
      *
-     * The core requests the window port when to render, after
-     * all the content has been updated.
+     * OR
      *
-     * 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.
+     * 2. iflags.perm_invent is off, but we're in the
+     *    midst of toggling it on.
      */
 
-    if (WINDOWPORT(tty) && iflags.perm_invent)
-        wport_id = "tty perm_invent";
-    else
-        wport_id = "perm_invent";
-
-    pi_info.fromcore.core_request = 0;
     if ((iflags.perm_invent && !g.core_invent_state)
-#ifdef TTY_PERM_INVENT
-        || in_perm_invent_toggled
-#endif
-                                                    ) {
-        /* 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;
+        || ((!iflags.perm_invent
+            && (in_perm_invent_toggled
+                && g.perm_invent_toggling_direction == toggling_on)))) {
+
+        /* Send windowport a request to return the related settings to us */
+        if ((iflags.perm_invent && !g.core_invent_state)
+            || in_perm_invent_toggled) {
+            if ((wri = ctrl_nhwindow(WIN_INVEN, request_settings, &wri_info))) {
+                if ((wri->tocore.tocore_flags & prohibited) != 0) {
+                    /* sizes aren't good enough */
+                    set_option_mod_status("perm_invent", set_gameview);
+                    iflags.perm_invent = FALSE;
+                    if (WIN_INVEN != WIN_ERR)
+                        destroy_nhwindow(WIN_INVEN), WIN_INVEN = WIN_ERR;
+                    if (WINDOWPORT(tty) && iflags.perm_invent)
+                        wport_id = "tty perm_invent";
+                    else
+                        wport_id = "perm_invent";
+                    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, wri->tocore.needrows,
+                          wri->tocore.needcols, wri->tocore.haverows,
+                          wri->tocore.havecols);
+                    wait_synch();
+                    return;
+                }
             }
+            g.core_invent_state++;
         }
-        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++;
     }
-    if (!pi || pi->tocore.maxslot == 0)
+
+    if (!wri || wri->tocore.maxslot == 0)
         return;
 
-    text = Empty; /* lint suppression */
-    pi_info.fromcore.core_request = update_slot;
-    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);
+    if (in_perm_invent_toggled && g.perm_invent_toggling_direction == toggling_on) {
+        WIN_INVEN = create_nhwindow(NHW_MENU);
     }
-    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);
 
-    pi_info.fromcore.core_request = 0;
+    if (WIN_INVEN != WIN_ERR && g.program_state.beyond_savefile_load) {
+        g.in_sync_perminvent = 1;
+        (void) display_inventory((char *) 0, FALSE);
+        g.in_sync_perminvent = 0;
+    }
 }
 
 void
 perm_invent_toggled(boolean negated)
 {
-#ifdef TTY_PERM_INVENT
     in_perm_invent_toggled = TRUE;
-#endif
     if (negated) {
-        if (g.perm_invent_win != WIN_ERR)
-            destroy_nhwindow(g.perm_invent_win), g.perm_invent_win = WIN_ERR;
+        g.perm_invent_toggling_direction = toggling_off;
+        if (WIN_INVEN != WIN_ERR)
+            destroy_nhwindow(WIN_INVEN), WIN_INVEN = WIN_ERR;
         g.core_invent_state = 0;
     } else {
+        g.perm_invent_toggling_direction = toggling_on;
         sync_perminvent();
     }
-#ifdef TTY_PERM_INVENT
+    g.perm_invent_toggling_direction = toggling_not;
     in_perm_invent_toggled = FALSE;
-#endif
 }
 
-#endif  /* CORE_INVENT */
-
 /*invent.c*/
index ec5ac9f6c25664f34440b7ad04d392b6254ca274..7f889914d23e78ec227489b5d272885a49f16e7d 100644 (file)
@@ -96,13 +96,13 @@ char optbuf[COLBUFSZ];
 static struct version_info version;
 static const char opt_indent[] = "    ";
 
-struct win_info {
+struct win_information {
     const char *id, /* DEFAULT_WINDOW_SYS string */
         *name;      /* description, often same as id */
     boolean valid;
 };
 
-static struct win_info window_opts[] = {
+static struct win_information window_opts[] = {
 #ifdef TTY_GRAPHICS
     { "tty",
       /* testing 'USE_TILES' here would bring confusion because it could
index 07fe3598b14d06a9e69213a1df8e8216a6dbfeee..81ad50f493f5c8baafaa2055fc93bdd3b7e09ba6 100644 (file)
@@ -4415,7 +4415,7 @@ optfn_boolean(int optidx, int req, boolean negated, char *opts, char *op)
                    -> sync_perminvent()
                           -> tty_create_nhwindow(NHW_PERMINVENT)
                    gives feedback for failure (terminal too small) */
-                if (g.perm_invent_win == WIN_ERR)
+                if (WIN_INVEN == WIN_ERR)
                     return optn_silenterr;
             }
 #endif
@@ -8964,6 +8964,10 @@ enhance_menu_text(
         if (thisopt->setwhere == set_gameview)
             Snprintf(eos(buf), availsz, " *terminal size is too small");
     }
+#else
+    nhUse(availsz);
+    nhUse(bool_p);
+    nhUse(thisopt);
 #endif
     return;
 }
index 7fccf5b12182a9048ac2504e5846ac43f112889e..6a1d525474ef4ab03931607c72e6e3776f472c08 100644 (file)
@@ -536,7 +536,7 @@ static void hup_void_fdecl_int(int);
 static void hup_void_fdecl_winid(winid);
 static void hup_void_fdecl_winid_ulong(winid, unsigned long);
 static void hup_void_fdecl_constchar_p(const char *);
-static perminvent_info *hup_update_invent_slot(winid, int, perminvent_info *);
+static win_request_info *hup_ctrl_nhwindow(winid, int, win_request_info *);
 
 static struct window_procs hup_procs = {
     WPID(hup), 0L, 0L,
@@ -585,7 +585,7 @@ static struct window_procs hup_procs = {
     genl_status_enablefield, hup_status_update,
     genl_can_suspend_no,
     hup_void_fdecl_int,                                /* update_inventory */
-    hup_update_invent_slot,                            /* update_invent_slot */
+    hup_ctrl_nhwindow,
 };
 
 static void (*previnterface_exit_nhwindows)(const char *) = 0;
@@ -841,15 +841,13 @@ hup_void_fdecl_constchar_p(const char *string UNUSED)
 }
 
 /*ARGUSED*/
-perminvent_info *
-hup_update_invent_slot(
+win_request_info *
+hup_ctrl_nhwindow(
     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)
+    int request UNUSED,
+    win_request_info *wri UNUSED)
 {
-    return (perminvent_info *) 0;
+    return (win_request_info *) 0;
 }
 
 #endif /* HANGUPHANDLING */
index 3d59fa30c7f0c03fc936314a295f13b69652c653..ba19ec91255582a5f74d385ffc75aeda80c22501 100644 (file)
 #pragma pack(8)
 #endif
 
+#ifdef DEBUG
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+
 #define WIN32_LEAN_AND_MEAN
 
 #include <windows.h>
index 4fc5261c7e9117d5ebd63bfed81b7d7447ab1145..db1fdc46c54836d0b25b3aa37fb27dd5aec9d9ae 100644 (file)
@@ -5,6 +5,7 @@
 /* main.c - Windows */
 
 #include "win32api.h" /* for GetModuleFileName */
+
 #include "hack.h"
 #ifdef DLB
 #include "dlb.h"
@@ -424,6 +425,10 @@ mingw_main(int argc, char *argv[])
     char fnamebuf[BUFSZ], encodedfnamebuf[BUFSZ];
     char failbuf[BUFSZ];
 
+#ifdef _MSC_VER
+    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
+#endif
+
     /*
      * Get a set of valid safe windowport function
      * pointers during early startup initialization.
index 277383cad23225852ab581a6ad2952942e0c9e84..d75e32dc896eb90309f625b330818c17f257e76b 100644 (file)
@@ -490,15 +490,13 @@ void NetHackQtBind::qt_update_inventory(int arg UNUSED)
     */
 }
 
-perminvent_info *NetHackQtBind::qt_update_invent_slot(
-    winid wid 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)
+win_request_info *NetHackQtBind::qt_ctrl_nhwindow(
+    winid wid UNUSED,
+    int request UNUSED,
+    win_request_info *wri UNUSED)
 {
     NetHackQtWindow* window UNUSED =id_to_window[(int)wid];
-    return (perminvent_info *) 0;
+    return (win_request_info *) 0;
 }
 
 void NetHackQtBind::qt_mark_synch()
@@ -1111,7 +1109,7 @@ struct window_procs Qt_procs = {
 #endif
     genl_can_suspend_yes,
     nethack_qt_::NetHackQtBind::qt_update_inventory,
-    nethack_qt_::NetHackQtBind::qt_update_invent_slot,
+    nethack_qt_::NetHackQtBind::qt_ctrl_nhwindow,
 };
 
 #ifndef WIN32
index 522532c46d6f77198573c3de213796edf1f8fb1e..2044838387d5e35e993445ed4ea094160f274c48 100644 (file)
@@ -89,7 +89,7 @@ public:
        static void qt_outrip(winid wid, int how, time_t when);
        static int qt_kbhit();
        static void qt_update_inventory(int);
-        static perminvent_info *qt_update_invent_slot(winid, int, perminvent_info *);
+        static win_request_info *qt_ctrl_nhwindow(winid, int, win_request_info *);
 
        static QWidget *mainWidget() { return main; }
 
index ea4c77147ff3829524a5a0b9a2f1907eddf54426..4d8d923f4be7f7e2ff6918983d0cfafc137c1f07 100644 (file)
@@ -142,7 +142,7 @@ struct window_procs X11_procs = {
     X11_status_update,
     genl_can_suspend_no, /* XXX may not always be correct */
     X11_update_inventory,
-    X11_update_invent_slot,
+    X11_ctrl_nhwindow,
 };
 
 /*
@@ -1272,15 +1272,13 @@ X11_update_inventory(int arg)
     return;
 }
 
-perminvent_info *
-X11_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)
+win_request_info *
+X11_ctrl_nhwindow(
+    winid window UNUSED,
+    int request UNUSED,
+    win_request_info *wri UNUSED)
 {
-    return (perminvent_info *) 0;
+    return (win_request_info *) 0;
 }
 
 /* The current implementation has all of the saved lines on the screen. */
index 27e1f1061cf5ff69839c2eb9efa53dff4788538d..7b8b6a419a812a1281cc01344aa840c6f4a559c1 100644 (file)
@@ -75,7 +75,7 @@ void chainin_status_update(int, genericptr_t, int, int, int,
 
 boolean chainin_can_suspend(void);
 void chainin_update_inventory(int);
-perminvent_info *chainin_update_invent_slot(winid, int, perminvent_info *);
+win_request_info *chainin_ctrl_nhwindow(winid, int, win_request_info *);
 
 void *chainin_procs_chain(int cmd, int n, void *me, void *nextprocs, void *nextdata);
 void chainin_procs_init(int dir);
@@ -578,18 +578,16 @@ chainin_can_suspend(void)
     return rv;
 }
 
-perminvent_info *
-chainin_update_invent_slot(
-    winid window,  /* window to use, must be of type NHW_MENU */
-    int inventory_slot,                 /* slot id: 0 - info return to core */
-                                        /*          1 - gold slot */
-                                        /*          2 - 29 obj slots */
-    perminvent_info *pi)
+win_request_info *
+chainin_ctrl_nhwindow(
+    winid window,
+    int request,
+    win_request_info *wri)
 {
     boolean rv;
 
-    rv = (*cibase->nprocs->win_update_invent_slot)(cibase->ndata, window,
-                                                   inventory_slot, pi);
+    rv = (*cibase->nprocs->win_ctrl_nhwindow)(cibase->ndata, window,
+                                                   request, wri);
     return rv;
 }
 
@@ -639,5 +637,5 @@ struct window_procs chainin_procs = {
     chainin_status_update,
     chainin_can_suspend,
     chainin_update_inventory,
-    chainin_update_invent_slot,
+    chainin_ctrl_nhwindow,
 };
index 0ebcd72be2fec732944fb4fb15d1794fbbb9d684..71e9603b8e2bf65be0bfadbe42e2155f8da7de69 100644 (file)
@@ -75,7 +75,7 @@ void chainout_status_update(void *,int, genericptr_t, int, int, int,
 
 boolean chainout_can_suspend(void *);
 void chainout_update_inventory(void *, int);
-perminvent_info *chainout_update_invent_slot(void *, winid, int, perminvent_info *);
+win_request_info *chainout_ctrl_nhwindow(void *, winid, int, win_request_info *);
 
 void chainout_procs_init(int dir);
 void *chainout_procs_chain(int cmd, int n, void *me, void *nextprocs, void *nextdata);
@@ -700,19 +700,17 @@ chainout_can_suspend(void *vp)
     return rv;
 }
 
-perminvent_info *
-chainout_update_invent_slot(
-    winid window,  /* window to use, must be of type NHW_MENU */
-    int inventory_slot,                 /* slot id: 0 - info return to core */
-                                        /*          1 - gold slot */
-                                        /*          2 - 29 obj slots */
-    perminvent_info *pi)
+win_request_info *
+chainout_ctrl_nhwindow(
+    winid window,
+    int request,
+    win_request_info *wri)
 {
     struct chainout_data *tdp = vp;
     boolean rv;
 
-    rv = (*tdp->nprocs->win_update_invent_slot)(window,
-                                                inventory_slot, pi);
+    rv = (*tdp->nprocs->win_ctrl_nhwindow)(window,
+                                           request, wri);
     return rv;
 }
 
@@ -763,5 +761,5 @@ struct chain_procs chainout_procs = {
     chainout_status_update,
     chainout_can_suspend,
     chainout_update_inventory,
-    chainout_update_invent_slot,
+    chainout_ctrl_nhwindow,
 };
index fd1865c0016eca8d93257c1ec40cb622905b0294..a1ce682235775e3d257cdec8dd3d0f73a19de966 100644 (file)
@@ -117,7 +117,7 @@ struct window_procs curses_procs = {
     curses_status_update,
     genl_can_suspend_yes,
     curses_update_inventory,
-    curses_update_invent_slot,
+    curses_ctrl_nhwindow,
 };
 
 /*
@@ -695,15 +695,13 @@ curses_update_inventory(int arg)
     }
 }
 
-perminvent_info *
-curses_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)
+win_request_info *
+curses_ctrl_nhwindow(
+    winid window UNUSED,
+    int request UNUSED,
+    win_request_info *wri UNUSED)
 {
-    return (perminvent_info *) 0;
+    return (win_request_info *) 0;
 }
 
 /*
index e3f655ee7650a9dc323601cb86fec0aefc3b6950..6e497ee5cf752e90d652d6cdde521f4e42ebab5f 100644 (file)
@@ -101,7 +101,7 @@ struct window_procs safe_procs = {
     safe_status_update,
     safe_can_suspend,
     safe_update_inventory,
-    safe_update_invent_slot,
+    safe_ctrl_nhwindow,
 };
 
 struct window_procs *
@@ -479,15 +479,13 @@ safe_update_inventory(int arg UNUSED)
     return;
 }
 
-perminvent_info *
-safe_update_invent_slot(
-    winid window,  /* window to use, must be of type NHW_MENU */
-    int inventory_slot,                 /* slot id: 0 - info return to core */
-                                        /*          1 - gold slot */
-                                        /*          2 - 29 obj slots */
-    perminvent_info *pi)
+win_request_info *
+safe_ctrl_nhwindow(
+    winid window,
+    int request,
+    win_request_info *wri)
 {
-    return (perminvent_info *) 0;
+    return (win_request_info *) 0;
 }
 
 /**************************************************************
index 49e74dc88cc2d346bfba2336d0bfd0155ad97e7f..59046fd5b88006e114035e96450a2f7393f89d37 100644 (file)
@@ -183,21 +183,19 @@ void shim_update_inventory(int a1 UNUSED) {
         display_inventory(NULL, FALSE);
     }
 }
-perminvent_info *
-shim_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) {
-    return (perminvent_info *) 0;
+win_request_info *
+shim_ctrl_nhwindow(
+    winid window UNUSED,
+    int request,
+    win_request_info *wri UNUSED) {
+    return (win_request_info *) 0;
 }
 #else /* !__EMSCRIPTEN__ */
 VDECLCB(shim_update_inventory,(int a1 UNUSED)
-DECLB(perminvent_info *, shim_update_invent_slot,
-    (winid window, int inventory_slot, perminvent_info *pi),
+DECLB(win_request_info *, shim_ctrl_nhwindow,
+    (winid window, int request, win_request_info *wri),
     "viip",
-    A2P window UNUSED, A2P inventory_slot UNUSED, P2V pi UNUSED)
+    A2P window UNUSED, A2P request UNUSED, P2V wri UNUSED)
 #endif
 
 /* Interface definition used in windows.c */
@@ -257,7 +255,7 @@ struct window_procs shim_procs = {
 #endif
     genl_can_suspend_yes,
     shim_update_inventory,
-    shim_update_invent_slot,
+    shim_ctrl_nhwindow,
 };
 
 #ifdef __EMSCRIPTEN__
index 83d4a6e329722b40b3da46343ffcab2e25f838f3..df49869034a0da2382b9f563762ba3630800011d 100644 (file)
@@ -167,7 +167,7 @@ struct window_procs tty_procs = {
 #endif
     genl_can_suspend_yes,
     tty_update_inventory,
-    tty_update_invent_slot,
+    tty_ctrl_nhwindow,
 };
 
 winid BASE_WINDOW;
@@ -254,28 +254,32 @@ void g_pututf8(uint8 *utf8str);
 #endif
 
 #ifdef TTY_PERM_INVENT
-void tty_perm_invent_toggled(boolean negated);
+static char Empty[1] = { '\0' };
 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 */
 static int ttyinvmode = InvNormal; /* enum is in wintype.h */
+static int inuse_only_start = 0;
 static boolean done_tty_perm_invent_init = FALSE;
+enum { tty_slots = 52 + 1 + 1 };
+static boolean slot_tracker[tty_slots];
+static long last_glyph_reset_when;
 #ifndef NOINVSYM /* invent.c */
 #define NOINVSYM '#'
 #endif
-/* not static, core_update_invent_slot() needs to see it from invent.c */
-boolean in_tty_perm_invent_toggled = FALSE;
+static boolean calling_from_update_inventory = FALSE;
 static int ttyinv_create_window(int, struct WinDesc *);
-
+static void ttyinv_add_menu(winid, struct WinDesc *, char ch, int attr,
+                            int clr, const char *str);
+static void ttyinv_render(winid window, struct WinDesc *cw);
 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 *, int32_t);
+                         long *, long *, long *, long *, long *);
+static void ttyinv_populate_slot(struct WinDesc *, int, int,
+                                 const char *, int32_t);
+static int selector_to_slot(char ch, const int invflags, boolean *ignore);
 #endif
 
 /*
@@ -564,8 +568,8 @@ tty_preference_update(const char *pref)
        the way to render them might change too (Handling: DEC/UTF8/&c) */
     if ((!strcmp(pref, "symset") || !strcmp(pref, "perm_invent"))
         && iflags.window_inited) {
-       if (g.perm_invent_win != WIN_ERR)
-           tty_invent_box_glyph_init(wins[g.perm_invent_win]);
+        if (WIN_INVEN != WIN_ERR)
+           tty_invent_box_glyph_init(wins[WIN_INVEN]);
     }
 #endif
     return;
@@ -1617,10 +1621,6 @@ tty_create_nhwindow(int type)
         newwin->cols = ttyDisplay->cols;
         newwin->maxrow = newwin->maxcol = 0;
         break;
-#ifdef TTY_PERM_INVENT
-    case NHW_PERMINVENT:
-        return ttyinv_create_window(newid, newwin);
-#endif
     default:
         panic("Tried to create window type %d\n", (int) type);
         /*NOTREACHED*/
@@ -1651,100 +1651,6 @@ tty_create_nhwindow(int type)
     return newid;
 }
 
-#ifdef TTY_PERM_INVENT
-
-static int
-ttyinv_create_window(int newid, struct WinDesc *newwin)
-{
-    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?
-     * 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.]
-     *
-     */
-
-    /* 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 (!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.",
-              (int) (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 = 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);
-
-    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;
-                newwin->cells[r][c].glyph = 1;
-            }
-        }
-    if (!done_tty_perm_invent_init)
-        tty_invent_box_glyph_init(newwin);
-    return newid;
-}
-#endif  /* TTY_PERM_INVENT */
-
 static void
 erase_menu_or_text(winid window, struct WinDesc *cw, boolean clear)
 {
@@ -2764,7 +2670,7 @@ tty_destroy_nhwindow(winid window)
             cw->rows = cw->cols = 0;
         }
         cw->maxrow = cw->maxcol = 0;
-        g.perm_invent_win = WIN_ERR;
+        WIN_INVEN = WIN_ERR;
         done_tty_perm_invent_init = FALSE;
     }
 #endif
@@ -2961,7 +2867,7 @@ tty_putstr(winid window, int attr, const char *str)
         return;
     if (cw->type != NHW_MESSAGE
 #ifdef TTY_PERM_INVENT
-        && window != g.perm_invent_win
+        && window != WIN_INVEN
 #endif
        )
         str = compress_str(str);
@@ -3221,12 +3127,37 @@ tty_display_file(const char *fname, boolean complain)
 void
 tty_start_menu(winid window, unsigned long mbehavior)
 {
-    wins[window]->mbehavior = mbehavior;
+    struct WinDesc *cw = 0;
+
+    if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0)
+        panic(winpanicstr, window);
+
+#ifdef TTY_PERM_INVENT
+    if (window != WIN_ERR && cw->mbehavior == MENU_BEHAVE_PERMINV) {
+        /* PERMINV is ready to go already; not much to do here */
+        inuse_only_start = 0;
+        return;
+    }
+    if (mbehavior == MENU_BEHAVE_PERMINV
+             && (iflags.perm_invent
+                 || g.perm_invent_toggling_direction == toggling_on)) {
+        winid w = ttyinv_create_window(window, wins[window]);
+        if (w == WIN_ERR) {
+            /* something went wrong, so add clean up code here */
+        } else {
+            cw->mbehavior = mbehavior;
+        }
+        return;
+    }
+#else
+    nhUse(mbehavior);
+#endif
+
     tty_clear_nhwindow(window);
     return;
 }
 
-/*ARGSUSED*/
+    /*ARGSUSED*/
 /*
  * Add a menu item to the beginning of the menu list.  This list is reversed
  * later.
@@ -3259,6 +3190,13 @@ tty_add_menu(
         || cw->type != NHW_MENU)
         panic(winpanicstr, window);
 
+#ifdef TTY_PERM_INVENT
+    if (cw->mbehavior == MENU_BEHAVE_PERMINV) {
+        ttyinv_add_menu(window, cw, ch, attr, clr, str);
+        return;
+    }
+#endif
+
     cw->nitems++;
     if (identifier->a_void) {
         int len = (int) strlen(str);
@@ -3322,8 +3260,23 @@ tty_end_menu(winid window,       /* menu to use */
     int clr = 0;
 
     if (window == WIN_ERR || (cw = wins[window]) == (struct WinDesc *) 0
-        || cw->type != NHW_MENU)
+        || cw->type != NHW_MENU) {
+        /* this can happen if start_menu failed due to size requirements
+           for the tty perm inventory window. It isn't a situation that
+           requires a panic, just an early return. */
+        if (window == WIN_INVEN && !cw)
+            return;
         panic(winpanicstr, window);
+    }
+#ifdef TTY_PERM_INVENT
+    if (cw->mbehavior == MENU_BEHAVE_PERMINV
+        && (iflags.perm_invent || g.perm_invent_toggling_direction == toggling_on)
+        && window == WIN_INVEN) {
+        if (g.program_state.in_moveloop)
+            ttyinv_render(window, cw);
+        return;
+    }
+#endif
 
     /* Reverse the list so that items are in correct order. */
     cw->mlist = reverse(cw->mlist);
@@ -3433,6 +3386,9 @@ tty_select_menu(winid window, int how, menu_item **menu_list)
         || cw->type != NHW_MENU)
         panic(winpanicstr, window);
 
+    if (cw->mbehavior == MENU_BEHAVE_PERMINV) {
+        return 0;
+    }
     *menu_list = (menu_item *) 0;
     cw->how = (short) how;
     morc = 0;
@@ -3493,129 +3449,287 @@ tty_message_menu(char let, int how, const char *mesg)
     return ((how == PICK_ONE && morc == let) || morc == '\033') ? morc : '\0';
 }
 
-/* update persistent inventory window */
-void
-tty_update_inventory(int arg UNUSED)
+RESTORE_WARNING_FORMAT_NONLITERAL
+
+win_request_info *
+tty_ctrl_nhwindow(winid window UNUSED, int request, win_request_info *wri)
 {
-#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.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;
+#if !defined(TTY_PERM_INVENT)
+    return (win_request_info *) 0;
+    nhUse(window);
+    nhUse(request);
+    nhUse(wri);
+#else
+    boolean tty_ok /*, show_gold */, inuse_only;
+    int maxslot;
+    /* 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 (!wri)
+        return (win_request_info *) 0;
+
+    switch (request) {
+    case set_mode:
+    case request_settings:
+        ttyinvmode = wri->fromcore.invmode;
+        /* show_gold = (ttyinvmode & InvShowGold) != 0; */
+        inuse_only = ((ttyinvmode & InvInUse) != 0);
+        if (request == set_mode)
+            break;
+        wri->tocore = zero_tocore;
+        tty_ok = assesstty(ttyinvmode, &offx, &offy, &rows, &cols, &maxcol,
+                           &minrow, &maxrow);
+        wri->tocore.needrows = (int) (minrow + 1 + ROWNO + 3);
+        wri->tocore.needcols = (int) tty_perminv_mincol;
+        wri->tocore.haverows = (int) ttyDisplay->rows;
+        wri->tocore.havecols = (int) ttyDisplay->cols;
+        if (!tty_ok) {
+            wri->tocore.tocore_flags |= prohibited; /* prohibited */
+            return wri;
         }
-        display_nhwindow(g.perm_invent_win, FALSE);
-        window = g.perm_invent_win;
+        maxslot = (maxrow - 2) * (!inuse_only ? 2 : 1);
+        wri->tocore.maxslot = maxslot;
+        return wri;
+        break;
+    default:
+        impossible("invalid request to tty_update_invent_slot %u", request);
     }
-    /* we just return if the window creation failed, probably due to
-       not meeting size requirements */
-    if (window == WIN_ERR)
-        return;
+    return wri;
+#endif
+}
 
-    if (!iflags.perm_invent) {
-        if (done_tty_perm_invent_init) {
-            /* Odd - but this could be end-of-game disclosure
-             * which just sets boolean iflag.perm_invent to
-             * FALSE without actually doing anything else.
-             */
-            tty_perm_invent_toggled(TRUE); /* TRUE means negated */
-            (void) doredraw();
-        }
-        return;
+#ifdef TTY_PERM_INVENT
+
+static int
+ttyinv_create_window(int newid, struct WinDesc *newwin)
+{
+    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?
+     * 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.]
+     *
+     */
+
+    /* 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 (!assesstty(ttyinvmode, &newwin->offx, &newwin->offy, &newwin->rows,
+                   &newwin->cols, &newwin->maxcol, &minrow,
+                   &newwin->maxrow)) {
+        tty_destroy_nhwindow(newid); /* sets WIN_INVEN 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.",
+              (int) (minrow + 1 + ROWNO + 3), tty_perminv_mincol,
+              ttyDisplay->rows, ttyDisplay->cols);
+        tty_wait_synch();
+        set_option_mod_status("perm_invent", set_gameview);
+        iflags.perm_invent = FALSE;
+        return WIN_ERR;
     }
-    if ((cw = wins[window]) == (struct WinDesc *) 0)
-        panic(winpanicstr, window);
 
-    if (!done_tty_perm_invent_init) {
-        tty_invent_box_glyph_init(cw);
+    /*
+     * Terminal/window/screen is big enough.
+     */
+    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);
+
+    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;
+                newwin->cells[r][c].glyph = 1;
+            }
+        }
+    newwin->active = 1;
+    tty_invent_box_glyph_init(newwin);
+    return newid;
+}
+
+static void
+ttyinv_add_menu(winid window UNUSED, struct WinDesc *cw, char ch,
+                int attr UNUSED, int clr UNUSED, const char *str)
+{
+    char invbuf[BUFSZ];
+    const char *text;
+    boolean inuse_only = (ttyinvmode & InvInUse) != 0,
+            show_gold = (ttyinvmode & InvShowGold) != 0,
+            /* sparse = (ttyinvmode & InvSparse) != 0, */
+            ignore = FALSE;
+    int row, side, slot = 0, rows_per_side = (!show_gold ? 26 : 27);
+
+    if (!g.program_state.in_moveloop)
+        return;
+    slot = selector_to_slot(ch, ttyinvmode, &ignore);
+    if (!ignore) {
+        /* inuse_only = ((ttyinvmode & InvInUse) != 0); */
+        slot_tracker[slot] = TRUE;
+        text = Empty; /* lint suppression */
+        /*            maxslot = ((int) cw->maxrow - 2) * (!inuse_only ? 2 :
+         * 1); */
+
+        /* TODO: check for MENUCOLORS match */
+        text = str; /* '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", ch, text);
+        text = invbuf;
+        row = (slot % rows_per_side) + 1; /* +1: top border */
+        /* side: left side panel or right side panel, not a window column */
+        side = slot < rows_per_side ? 0 : 1;
+        if (!(inuse_only && side == 1))
+            ttyinv_populate_slot(cw, row, side, text, 0);
     }
+    return;
+}
+static int
+selector_to_slot(char ch, const int invflags, boolean *ignore)
+{
+    int slot = 0;
+    boolean show_gold = (invflags & InvShowGold) != 0,
+            inuse_only = (invflags & InvInUse) != 0;
+#if 0
+            sparse = (invflags & InvSparse) != 0,
+#endif
 
-    text = Empty; /* lint suppression */
-    maxslot = ((int) cw->maxrow - 2) * (!inuse_only ? 2 : 1);
-    obj = g.invent;
-    for (slot = 0; slot < 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;
+    *ignore = FALSE;
+    switch (ch) {
+    case '$':
+        if (!show_gold)
+            *ignore = TRUE;
+        slot = 0;
+        break;
+    case '#':
+        slot = 52 + (show_gold ? 1 : 0);
+        break;
+    case 0:
+        *ignore = TRUE;
+        break;
+    default:
+        if (!inuse_only) {
+            if (ch >= 'a' && ch <= 'z')
+                slot = (ch - 'a') + (show_gold ? 1 : 0);
+            if (ch >= 'A' && ch <= 'Z')
+                slot = (ch - 'A') + (show_gold ? 1 : 0) + 26;
         } 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 ((ch >= 'a' && ch <= 'z')
+                || (ch >= 'A' && ch <= 'Z'))
+                slot = (show_gold ? 1 : 0) + inuse_only_start++;
         }
+    }
+    return slot;
+}
 
-        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 */
+static void
+ttyinv_render(winid window, struct WinDesc *cw)
+{
+    int row, col, slot, side, filled_count = 0, slot_limit;
+    struct tty_perminvent_cell *cell;
+    char invbuf[BUFSZ], *text;
+    boolean force_redraw = g.program_state.in_docrt ? TRUE : FALSE,
+            show_gold = (ttyinvmode & InvShowGold) != 0,
+            inuse_only = (ttyinvmode & InvInUse) != 0;
+    int rows_per_side = (!show_gold ? 26 : 27);
+
+    slot_limit = SIZE(slot_tracker);
+    if (inuse_only) {
+        rows_per_side = cw->maxrow - 2; /* -2 top and bottom borders */
+    }
+    for (slot = 0; slot < slot_limit; ++slot)
+        if (slot_tracker[slot])
+            filled_count++;
+    for (slot = 0; slot < slot_limit; ++slot) {
+        if (slot_tracker[slot])
+           continue;
+        if (slot == 0 && !filled_count) {
+            Sprintf(invbuf, "%-4s[%s]", "",
+                    !filled_count ? "empty"
+                    : inuse_only  ? "no items are in use"
+                                  : "only gold");
             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 = Empty; /* "" => fill slot with spaces */
-            }
+            text = Empty; /* "" => fill slot with spaces */
         }
-
-        row = (slot % (!show_gold ? 26 : 27)) + 1; /* +1: top border */
+        row = (slot % rows_per_side) + 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, 0);
+        side = slot < rows_per_side ? 0 : 1;
+        if (!(inuse_only && side == 1))
+            ttyinv_populate_slot(cw, row, side, text, 0);
     }
-
+    /* has there been a glyph reset since we last got here? */
+    if (g.glyph_reset_timestamp > last_glyph_reset_when) {
+        //        tty_invent_box_glyph_init(wins[WIN_INVEN]);
+        last_glyph_reset_when = g.glyph_reset_timestamp;
+        force_redraw = TRUE;
+    }
+    /* render to the display */
     calling_from_update_inventory = TRUE;
-    /* now render to the display */
     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);
+                    tty_print_glyph(window, col + 1, row, cell->content.gi,
+                                    &nul_glyphinfo);
                     end_glyphout();
                 } else {
                     if (col != cw->curx || row != cw->cury)
@@ -3627,113 +3741,13 @@ tty_update_inventory(int arg UNUSED)
                 cell->refresh = 0;
             }
         }
+    tty_curs(window, 1, 0);
+    for (slot = 0; slot < SIZE(slot_tracker); ++slot)
+        slot_tracker[slot] = 0;
     calling_from_update_inventory = FALSE;
-#endif  /* CORE_INVENT */
-#endif  /* TTY_PERM_INVENT */
     return;
 }
 
-perminvent_info *
-tty_update_invent_slot(
-    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;
-    }
-    ttyinvmode = pi->fromcore.invmode;
-    show_gold = (ttyinvmode & InvShowGold) != 0;
-    inuse_only = (ttyinvmode & InvInUse) != 0;
-    /* sparse isn't needed port-side */
-
-    switch(pi->fromcore.core_request) {
-    case request_settings:
-        pi->tocore = zero_tocore;
-        tty_ok = assesstty(ttyinvmode,
-                           &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 */
-        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, pi->fromcore.clr);
-        break;
-    case render:
-        if ((cw = wins[window]) == (struct WinDesc *) 0)
-            panic(winpanicstr, window);
-        /* render to the display */
-        force_redraw = pi->fromcore.force_redraw;
-        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;
-                }
-            }
-        tty_curs(window, 1, 0);
-        ttyDisplay->curx = 1;
-        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
  */
@@ -3753,7 +3767,7 @@ assesstty(
     *offy = 1 + ROWNO + 3; /* 3: + 2 + (iflags.wc2_statuslines > 2) */
     *rows = (ttyDisplay->rows - (*offy));
     *cols = ttyDisplay->cols;
-    *minrow = tty_pi_minrow;
+    *minrow = tty_perminv_minrow;
     if (show_gold)
         *minrow += 1;
     /* "normal" max for items in use would be 3 weapon + 7 armor + 4
@@ -3767,7 +3781,7 @@ assesstty(
         *minrow = 1 + 15 + 1; /* top border + 15 lines + bottom border */
     *maxrow = *minrow;
     *maxcol = *cols;
-    return !(*rows < *minrow || *cols < tty_pi_mincol);
+    return !(*rows < *minrow || *cols < tty_perminv_mincol);
 }
 
 /* put the formatted object description for one item into a particular row
@@ -3783,7 +3797,12 @@ ttyinv_populate_slot(
     char c;
     int ccnt, col, endcol;
 
-    col = bordercol[side] + 1;
+    /* FIXME: this needs a review. Crashed under InvInUse without */
+    if ((ttyinvmode & InvInUse) != 0)
+        col = bordercol[0] + 1;
+    else
+        col = bordercol[side] + 1;
+
     endcol = bordercol[side + 1] - 1;
     cell = &cw->cells[row][col];
     if (cell->color != color)
@@ -3819,7 +3838,7 @@ tty_refresh_inventory(int start, int stop, int y)
 {
     int row = y, col, col_limit = stop;
     struct WinDesc *cw = 0;
-    winid window = g.perm_invent_win;
+    winid window = WIN_INVEN;
     struct tty_perminvent_cell *cell;
 
     if (window == WIN_ERR || !iflags.perm_invent || y < 0)
@@ -3856,11 +3875,14 @@ RESTORE_WARNING_FORMAT_NONLITERAL
 
 static void
 tty_invent_box_glyph_init(struct WinDesc *cw)
-{
+        {
     int row, col;
     uchar sym;
     struct tty_perminvent_cell *cell;
 
+    if (cw == 0 || !cw->active)
+        return;
+
     for (row = 0; row < cw->maxrow; ++row)
         for (col = 0; col < cw->maxcol; ++col) {
             cell = &cw->cells[row][col];
@@ -3927,9 +3949,16 @@ tty_invent_box_glyph_init(struct WinDesc *cw)
         }
     done_tty_perm_invent_init = TRUE;
 }
-
 #endif  /* TTY_PERM_INVENT */
 
+/* update persistent inventory window */
+void
+tty_update_inventory(int arg UNUSED)
+{
+    /* currently not used */
+    return;
+}
+
 void
 tty_mark_synch(void)
 {
@@ -3972,8 +4001,8 @@ docorner(register int xmin, register int ymax, int ystart_between_menu_pages)
 #ifdef TTY_PERM_INVENT
     struct WinDesc *icw = 0;
 
-    if (g.perm_invent_win != WIN_ERR)
-        icw = wins[g.perm_invent_win];
+    if (WIN_INVEN != WIN_ERR)
+        icw = wins[WIN_INVEN];
 #endif
 
     HUPSKIP();
index 8876dae459e2a605f116c49935e061f5c3fece02..35667ce8c9a8315429613ab06859161da29d7f12 100644 (file)
@@ -120,7 +120,7 @@ struct window_procs mswin_procs = {
     mswin_status_update,
     genl_can_suspend_yes,
     mswin_update_inventory,
-    mswin_update_invent_slot,
+    mswin_ctrl_nhwindow,
 };
 
 /*
@@ -1245,15 +1245,13 @@ mswin_update_inventory(int arg)
         display_inventory(NULL, FALSE);
 }
 
-perminvent_info *
-mswin_update_invent_slot(
-    winid window,  /* window to use, must be of type NHW_MENU */
-    int inventory_slot,                 /* slot id: 0 - info return to core */
-                                        /*          1 - gold slot */
-                                        /*          2 - 29 obj slots */
-    perminvent_info *pi)
+win_request_info *
+mswin_ctrl_nhwindow(
+    winid window,
+    int request,
+    win_request_info *wri)
 {
-    return (perminvent_info *) 0;
+    return (win_request_info *) 0;
 }
 
 /*
index 940f089d399c0b2ef9225bc70105e5a82b18a2c9..23d98b73695314d22f1aa15ae4eae3971b4440df 100644 (file)
@@ -193,7 +193,7 @@ void mswin_status_enablefield(int fieldidx, const char *nm, const char *fmt,
                               boolean enable);
 void mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks);
 void mswin_update_inventory(int);
-perminvent_info *mswin_update_invent_slot(winid, int, perminvent_info *);
+win_request_info *mswin_ctrl_nhwindow(winid, int, win_request_info *);
 
 /* helper function */
 HWND mswin_hwnd_from_winid(winid wid);