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
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
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
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.
#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 */
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);
* 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;
}
}
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;
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;
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,
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;
}
| 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,
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
* 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 */
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;
* 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.
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
#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;
/* 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;
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:
}
break;
}
- if (make_things_fit(force_update) || truncation_expected)
- render_status();
+ /* 3.6.2 we only render on BL_FLUSH (or BL_RESET) */
return;
}
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;
* 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
* 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;
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):
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;