diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 89c6129ac..c200e88f3 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -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 diff --git a/doc/window.doc b/doc/window.doc index e648b23a4..59b90255d 100644 --- a/doc/window.doc +++ b/doc/window.doc @@ -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. diff --git a/include/botl.h b/include/botl.h index 4d9347088..9e4e36595 100644 --- a/include/botl.h +++ b/include/botl.h @@ -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 */ diff --git a/src/botl.c b/src/botl.c index dc862ab0e..784438a14 100644 --- a/src/botl.c +++ b/src/botl.c @@ -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; } diff --git a/win/tty/wintty.c b/win/tty/wintty.c index a0e2f66ed..5ad7a3dcc 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -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; diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 8f3e1ae1f..165efd34a 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -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;