status_update distinguish new BL_RESET from BL_FLUSH

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.
This commit is contained in:
nhmall
2018-09-03 08:18:18 -04:00
parent 0b32735ff8
commit a417d67572
6 changed files with 97 additions and 53 deletions
+51 -30
View 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 */
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++;
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;
+9 -5
View 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;