]> granicus.if.org Git - nethack/commitdiff
status_update distinguish new BL_RESET from BL_FLUSH
authornhmall <nhmall@nethack.org>
Mon, 3 Sep 2018 12:18:18 +0000 (08:18 -0400)
committernhmall <nhmall@nethack.org>
Mon, 3 Sep 2018 12:18:18 +0000 (08:18 -0400)
This adds BL_RESET to status_update to send a flag to a window
port that every field should be updated because something has
happened in the core to make current values shown to be
untrustworthy or potentially obliterated.

That is now distinguished from BL_FLUSH, which now has no
bearing on whether every field needs to be redone, and instead
can be used by a window port indicator that it is time to render
any buffered status field changes to the display.

tty port now sets WC2_FLUSH_STATUS indicator for BL_FLUSH support
and now does one rendering per bot() call, instead of up to 22.

Side note: The tty hitpoint bar code was relying on the old
behavior of redrawing everything upon BL_FLUSH apparently, so it
initially had some color change lag issues, corrected by marking
BL_STATUS as dirty (in need of updating) in tty_status_update()
whenever BL_HP was marked as dirty.

doc/fixes36.2
doc/window.doc
include/botl.h
src/botl.c
win/tty/wintty.c
win/win32/mswproc.c

index 89c6129ace6307f29e214d2a4c9113faa47e6c8c..c200e88f36dbc4ba0fc9273fa7eea41652a26ae1 100644 (file)
@@ -107,9 +107,10 @@ wizard mode #wizidentify didn't disclose extra information for unID'd items if
 make transformation message of a deliberate apply of a figurine seem a bit 
        less definite when blind and place unseen monster marker at the spot
        you think it should be
-ensure BL_FLUSH always gets sent down to the window port whenever bot() is
-       called with context.botlx set so that status updates work as
-       expected after full screen clear after a level change
+add window port status_update() value BL_RESET to use as a flag to 
+       redraw all status fields, distinguished from BL_FLUSH which now only
+       specifies that the bot() call has completed so any buffered changes
+       should now be rendered
 
 
 Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
@@ -125,7 +126,8 @@ tty: turn off an optimization that is the suspected cause of Windows reported
 Platform- and/or Interface-Specific Fixes
 -----------------------------------------
 windows-gui: In nethackw, there could be conflicts between menu accelerators 
-       and an extra choice accelerator to fix H7132.  
+       and an extra choice accelerator to fix H7132.
+windows-gui: recognize new BL_RESET in status_update; behavior currently the same
 windows-tty: Specify both width and height when creating font for width testing
 windows-tty: To counter lag problems that were occuring with the Win32 console
        port, implement a console back buffer to reduce the number of calls
@@ -142,6 +144,8 @@ windows-tty: Use nhraykey by default if the players keyboard layout is
 windows-tty: We now support changing altkeyhandler in game
 windows: Added ntassert() mechanism for Windows based port use
 tty: significant optimizations for performance and per field rendering
+tty: use WC2_FLUSH_STATUS to buffer changes until BL_FLUSH is received
+tty: support BL_RESET in status_update to force an update to all status fields
 unix: Makefile.src and Makefile.utl inadvertently relied on a 'gnu make'
        extension when using $(VERBOSEMAKE) to reduce build-time feedback;
        replace with $(QUIETCC) which operates the same but defaults to
index e648b23a42d852bca1f33ef0c95ee271e5588f27..59b90255d6437ccfa46046367600019c32ea4763 100644 (file)
@@ -412,6 +412,10 @@ status_update(int fldindex, genericptr_t ptr, int chg, int percentage, int color
                   BL_LEVELDESC, BL_EXP, BL_CONDITION
                -- fldindex could also be BL_FLUSH (-1), which is not really
                   a field index, but is a special trigger to tell the 
+                  windowport that it should output all changes received
+                   to this point. It marks the end of a bot() cycle.
+               -- fldindex could also be BL_RESET (-2), which is not really
+                  a field index, but is a special advisory to to tell the 
                   windowport that it should redisplay all its status fields,
                   even if no changes have been presented to it.
                -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
index 4d93470882da6f3238b75845934b6e4a28bb3fa8..9e4e365952cf8acf59f55c5dd36f822065952b4e 100644 (file)
@@ -28,8 +28,10 @@ Astral Plane \GXXXXNNNN:123456 HP:1234(1234) Pw:1234(1234) AC:-127
 #endif
 
 enum statusfields {
-    BL_CHARACTERISTICS = -2, /* alias for BL_STR..BL_CH */
-    BL_FLUSH = -1, BL_TITLE = 0,
+    BL_CHARACTERISTICS = -3, /* alias for BL_STR..BL_CH */
+    BL_RESET = -2,           /* Force everything to redisplay */
+    BL_FLUSH = -1,           /* Finished cycling through bot fields */
+    BL_TITLE = 0,
     BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH,  /* 1..6 */
     BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX, /* 7..12 */
     BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, /* 13..18 */
index dc862ab0eefc2e643d2c640b7e83d46b342710b9..784438a14d82f3f42c1527cc4f36bae07b406eb1 100644 (file)
@@ -736,7 +736,7 @@ boolean *valsetlist;
 
     if (update_all || chg || reset) {
         idxmax = curr->idxmax;
-        pc = (idxmax > BL_FLUSH) ? percentage(curr, &blstats[idx][idxmax]) : 0;
+        pc = (idxmax >= 0) ? percentage(curr, &blstats[idx][idxmax]) : 0;
 
         if (!valsetlist[fld])
             (void) anything_to_s(curr->val, &curr->a, anytype);
@@ -796,19 +796,27 @@ boolean *valsetlist;
      *     fields that have changed since the previous update.
      *
      * In both of those situations, we need to force updates to
-     * all of the fields when context.botlx is set.
+     * all of the fields when context.botlx is set. The tty port in
+     * particular has a problem if that isn't done, since the core sets
+     * context.botlx when a menu or text display obliterates the status
+     * line. 
      *
-     * The tty port in particular has a problem
-     * if that isn't done, since it sets context.botlx when a menu or
-     * text display obliterates the status line. 
+     * For those situations, to trigger the full update of every field
+     * whether changed or not, call status_update() with BL_RESET.
+     *
+     * For regular processing and to notify the window port that a
+     * bot() round has finished and it's time to trigger a flush of
+     * all buffered changes received thus far but not reflected in
+     * the display, call status_update() with BL_FLUSH.
      *
-     * To trigger the full update we call status_update() with fictitious
-     * index of BL_FLUSH (-1).
      */
-    if (context.botlx || (windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
+    if (context.botlx)
+        status_update(BL_RESET, (genericptr_t) 0, 0, 0,
+                      NO_COLOR, &cond_hilites[0]);
+    else if ((windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
         status_update(BL_FLUSH, (genericptr_t) 0, 0, 0,
                       NO_COLOR, &cond_hilites[0]);
-
+    
     context.botl = context.botlx = 0;
     update_all = FALSE;
 }
@@ -1943,7 +1951,7 @@ boolean from_configfile;
         }
 
         if (percent) {
-            if (initblstats[fld].idxmax <= BL_FLUSH) {
+            if (initblstats[fld].idxmax < 0) {
                 config_error_add("Cannot use percent with '%s'",
                                  initblstats[fld].fldname);
                 return FALSE;
@@ -2681,7 +2689,7 @@ int fld;
     int at;
     int onlybeh = BL_TH_NONE, nopts = 0;
 
-    if (fld <= BL_FLUSH || fld >= MAXBLSTATS)
+    if (fld < 0 || fld >= MAXBLSTATS)
         return BL_TH_NONE;
 
     at = initblstats[fld].anytype;
@@ -2724,7 +2732,7 @@ int fld;
         nopts++;
     }
 
-    if (initblstats[fld].idxmax > BL_FLUSH) {
+    if (initblstats[fld].idxmax >= 0) {
         any = zeroany;
         any.a_int = onlybeh = BL_TH_VAL_PERCENTAGE;
         add_menu(tmpwin, NO_GLYPH, &any, 'p', 0, ATR_NONE,
@@ -2856,6 +2864,7 @@ choose_field:
     fld = origfld;
     if (fld == BL_FLUSH) {
         fld = status_hilite_menu_choose_field();
+        /* isn't this redundant given what follows? */
         if (fld == BL_FLUSH)
             return FALSE;
     }
index a0e2f66ed7d797a105ec2c08ebcbe22a013a5711..5ad7a3dcce89842702f50a1d2951a1edc3dbcd7b 100644 (file)
@@ -66,7 +66,7 @@ struct window_procs tty_procs = {
      | WC2_SELECTSAVED
 #endif
 #if defined(STATUS_HILITES)
-     | WC2_HILITE_STATUS | WC2_HITPOINTBAR
+     | WC2_HILITE_STATUS | WC2_HITPOINTBAR | WC2_FLUSH_STATUS
 #endif
      | WC2_DARKGRAY),
     tty_init_nhwindows, tty_player_selection, tty_askname, tty_get_nh_event,
@@ -3543,6 +3543,8 @@ static int cond_shrinklvl = 0, cond_width_at_shrink = 0;
 static int enclev = 0, enc_shrinklvl = 0;
 /* static int dl_shrinklvl = 0; */
 static boolean truncation_expected = FALSE;
+#define FORCE_RESET TRUE
+#define NO_RESET FALSE
 
 /* This controls whether to skip fields that aren't
  * flagged as requiring updating during the current
@@ -3553,10 +3555,10 @@ static boolean truncation_expected = FALSE;
  * setting below can be removed.
  */
 static int do_field_opt = 
-#if defined(ENABLE_TTY_FIELD_OPT)
-    1;
-#else
+#if defined(DISABLE_TTY_FIELD_OPT)
     0;
+#else
+    1;
 #endif
 
 #endif  /* STATUS_HILITES */
@@ -3573,7 +3575,7 @@ tty_status_init()
     int i;
 
     for (i = 0; i < MAXBLSTATS; ++i) {
-        tty_status[NOW][i].idx = -1;
+        tty_status[NOW][i].idx = BL_FLUSH;
         tty_status[NOW][i].color = NO_COLOR; /* no color */
         tty_status[NOW][i].attr = ATR_NONE;
         tty_status[NOW][i].x = 0;
@@ -3604,7 +3606,11 @@ tty_status_init()
  *         BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX,
  *         BL_LEVELDESC, BL_EXP, BL_CONDITION
  *      -- fldindex could also be BL_FLUSH (-1), which is not really
- *         a field index, but is a special trigger to tell the
+ *         a field index, but is a special trigger to tell the 
+ *         windowport that it should output all changes received
+ *         to this point. It marks the end of a bot() cycle.
+ *      -- fldindex could also be BL_RESET (-3), which is not really
+ *         a field index, but is a special advisory to to tell the 
  *         windowport that it should redisplay all its status fields,
  *         even if no changes have been presented to it.
  *      -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
@@ -3657,9 +3663,9 @@ unsigned long *colormasks;
     char *text = (char *) ptr;
     char *lastchar = (char *) 0;
     char *fval = (char *) 0;
-    boolean force_update = FALSE;
+    boolean reset_state = NO_RESET;
 
-    if (fldidx != BL_FLUSH && !status_activefields[fldidx])
+    if ((fldidx >= 0 && fldidx < MAXBLSTATS) && !status_activefields[fldidx])
         return;
 
 #ifndef TEXTCOLOR
@@ -3667,9 +3673,13 @@ unsigned long *colormasks;
 #endif
 
     switch (fldidx) {
+    case BL_RESET:
+        reset_state = FORCE_RESET;
+        /* FALLTHRU */
     case BL_FLUSH:
-        force_update = TRUE;
-        break;
+        if (make_things_fit(reset_state) || truncation_expected)
+            render_status();
+        return;
     case BL_CONDITION:
         tty_status[NOW][fldidx].idx = fldidx;
         tty_condition_bits = *condptr;
@@ -3693,7 +3703,7 @@ unsigned long *colormasks;
 
     /* The core botl engine sends a single blank to the window port
        for carrying-capacity when its unused. Let's suppress that */
-    if (fldidx != BL_FLUSH &&
+    if (fldidx >= 0 && fldidx < MAXBLSTATS &&
             tty_status[NOW][fldidx].lth == 1 && status_vals[fldidx][0] == ' ') {
         status_vals[fldidx][0] = '\0';
         tty_status[NOW][fldidx].lth = 0;
@@ -3707,6 +3717,10 @@ unsigned long *colormasks;
             hpbar_percent = percent;
             hpbar_color = (color & 0x00FF);
         }
+        if (iflags.wc2_hitpointbar && (tty_procs.wincap2 & WC2_FLUSH_STATUS) != 0L) {
+            tty_status[NOW][BL_TITLE].color = hpbar_color;
+            tty_status[NOW][BL_TITLE].dirty = TRUE;
+        }
         break;
     case BL_LEVELDESC:
     case BL_HUNGER:
@@ -3740,8 +3754,7 @@ unsigned long *colormasks;
         }
         break;
     }
-    if (make_things_fit(force_update) || truncation_expected)
-        render_status();
+    /* 3.6.2 we only render on BL_FLUSH (or BL_RESET) */
     return;
 }
 
@@ -3805,7 +3818,7 @@ boolean forcefields;
 int *topsz, *bottomsz;
 {
     int c, i, row, col, trackx, idx;
-    boolean valid = TRUE, matchprev = FALSE, update_right;
+    boolean valid = TRUE, matchprev = FALSE, update_right, disregard;
 
     if (!windowdata_init && !check_windowdata())
         return FALSE;
@@ -3833,25 +3846,32 @@ int *topsz, *bottomsz;
                  * Check values against those already on the dislay.
                  *  - Is the additional processing time for this worth it?
                  */
-                matchprev = FALSE;
-                if (do_field_opt && tty_status[NOW][idx].dirty) {
-                    /* compare values */
-                    const char *ob, *nb;     /* old byte, new byte */
-
-                    c = col - 1;
-                    ob = &wins[WIN_STATUS]->data[row][c];
-                    nb = status_vals[idx];
-                    while (*nb && c < wins[WIN_STATUS]->cols) {
-                        if (*nb != *ob)
-                            break;
-                        nb++;
-                        ob++;
-                        c++;
+                if (do_field_opt) {
+                    matchprev = FALSE;
+                    disregard = (tty_status[NOW][idx].lth == 0);
+                    if (do_field_opt && !disregard
+                            && tty_status[NOW][idx].dirty) {
+                        /* compare values */
+                        const char *ob, *nb;     /* old byte, new byte */
+
+                        c = col - 1;
+                        ob = &wins[WIN_STATUS]->data[row][c];
+                        nb = status_vals[idx];
+                        while (*nb && c < wins[WIN_STATUS]->cols) {
+                            if (*nb != *ob)
+                                break;
+                            nb++;
+                            ob++;
+                            c++;
+                        }
+                        if (!*nb && c > col - 1)
+                            matchprev = TRUE;
                     }
-                    if (!*nb && c > col - 1)
-                        matchprev = TRUE;
+                } else {
+                    matchprev = FALSE;
                 }
             }
+
             /*
              * With STATUS_HILITES, it is possible that the color
              * needs to change even if the text is the same, so
@@ -3861,7 +3881,8 @@ int *topsz, *bottomsz;
              * After the field has been updated, render_status()
              * will also clear .redraw and .dirty.
              */
-            if (forcefields || update_right || !matchprev
+            if (forcefields || update_right
+                || (!matchprev && tty_status[NOW][idx].dirty && !disregard)
                 || tty_status[NOW][idx].color != tty_status[BEFORE][idx].color
                 || tty_status[NOW][idx].attr  != tty_status[BEFORE][idx].attr)
                 tty_status[NOW][idx].redraw = TRUE;
index 8f3e1ae1f49c40fde03b219650937d196235ff5d..165efd34aa478e48a894348792246cacffee8951 100644 (file)
@@ -2857,10 +2857,14 @@ status_update(int fldindex, genericptr_t ptr, int chg, int percent, int color, u
                    BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX,
                    BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX,
                    BL_LEVELDESC, BL_EXP, BL_CONDITION
-                -- fldindex could also be BL_FLUSH (-1), which is not really
-                   a field index, but is a special trigger to tell the
-                   windowport that it should redisplay all its status fields,
-                   even if no changes have been presented to it.
+               -- fldindex could also be BL_FLUSH (-1), which is not really
+                  a field index, but is a special trigger to tell the 
+                  windowport that it should output all changes received
+                   to this point. It marks the end of a bot() cycle.
+               -- fldindex could also be BL_RESET (-3), which is not really
+                  a field index, but is a special advisory to to tell the 
+                  windowport that it should redisplay all its status fields,
+                  even if no changes have been presented to it.
                 -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
                    If fldindex is BL_CONDITION, then ptr is a long value with
                    any or none of the following bits set (from botl.h):
@@ -2898,7 +2902,7 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color,
 
     logDebug("mswin_status_update(%d, %p, %d, %d, %x, %p)\n", idx, ptr, chg, percent, color, colormasks);
 
-    if (idx != BL_FLUSH) {
+    if (idx != BL_FLUSH || idx == BL_RESET) {
         if (!_status_activefields[idx])
             return;
         _status_percents[idx] = percent;