From 811fb0174b4c484e4b71c05a84f4e94298c54203 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 19 May 2019 11:48:20 -0400 Subject: [PATCH 1/7] Makefile.msc bit for Windows --- sys/winnt/Makefile.msc | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 3544d8198..060b8c7a1 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -91,9 +91,13 @@ DEBUGINFO = Y # #============================================================================== +# +# The version of the game this Makefile was designed for +NETHACK_VERSION="3.6.3" -# Set the gamedir according to your preference. -# If not present prior to compilation it gets created. +# A brief version for use in macros +NHV=$(NETHACK_VERSION:.=) +NHV=$(NHV:"=) # # Source directories. Makedefs hardcodes these, don't change them. @@ -549,7 +553,7 @@ lflagsBuild = $(lflags) $(conlibs) $(MACHINE) LIBS= user32.lib winmm.lib $(ZLIB) $(CURSESLIB) ! IF ("$(USE_DLB)"=="Y") -DLB = nhdat +DLB = nhdat$(NHV) ! ELSE DLB = ! ENDIF @@ -672,8 +676,9 @@ install: $(O)envchk.tag $(O)obj.tag $(O)utility.tag $(GAMEDIR)\NetHack.exe $(GAM $(O)install.tag: $(DAT)\data $(DAT)\rumors $(DAT)\dungeon \ $(DAT)\oracles $(DAT)\quest.dat $(O)sp_lev.tag $(DLB) + set ! IF ("$(USE_DLB)"=="Y") - copy nhdat* $(GAMEDIR) + copy nhdat$(NHV) $(GAMEDIR) copy $(DAT)\license $(GAMEDIR) copy $(DAT)\opthelp $(GAMEDIR) ! ELSE @@ -1100,7 +1105,7 @@ $(O)envchk.tag: $(O)obj.tag #========================================== #========================================== -# DLB utility and nhdat file creation +# DLB utility and nhdatNNN file creation #========================================== $(U)dlb_main.exe: $(DLBOBJ) $(O)dlb.o @@ -1121,7 +1126,7 @@ $(O)dlb_main.o: $(UTIL)\dlb_main.c $(INCL)\config.h $(INCL)\dlb.h $(DAT)\porthelp: $(MSWSYS)\porthelp @copy $(MSWSYS)\porthelp $@ >nul -nhdat: $(U)dlb_main.exe $(DAT)\data $(DAT)\oracles $(OPTIONS_FILE) \ +nhdat$(NHV): $(U)dlb_main.exe $(DAT)\data $(DAT)\oracles $(OPTIONS_FILE) \ $(DAT)\quest.dat $(DAT)\rumors $(DAT)\help $(DAT)\hh $(DAT)\cmdhelp $(DAT)\keyhelp \ $(DAT)\history $(DAT)\opthelp $(DAT)\wizhelp $(DAT)\dungeon $(DAT)\porthelp \ $(DAT)\license $(DAT)\engrave $(DAT)\epitaph $(DAT)\bogusmon $(DAT)\tribute $(O)sp_lev.tag @@ -1281,7 +1286,7 @@ spotless: clean if exist $(GAMEDIR)\nhraykey.dll del $(GAMEDIR)\nhraykey.dll if exist $(GAMEDIR)\NetHack.exe del $(GAMEDIR)\NetHack.exe if exist $(GAMEDIR)\NetHack.pdb del $(GAMEDIR)\NetHack.pdb - if exist $(GAMEDIR)\nhdat* del $(GAMEDIR)\nhdat* + if exist $(GAMEDIR)\nhdat$(NHV) del $(GAMEDIR)\nhdat$(NHV) ! ENDIF if exist $(INCL)\date.h del $(INCL)\date.h if exist $(INCL)\onames.h del $(INCL)\onames.h @@ -1334,7 +1339,7 @@ spotless: clean if exist $(DAT)\porthelp del $(DAT)\porthelp if exist $(O)sp_lev.tag del $(O)sp_lev.tag if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c - if exist nhdat*. del nhdat*. + if exist nhdat$(NHV). del nhdat$(NHV). if exist $(O)obj.tag del $(O)obj.tag if exist $(O)gamedir.tag del $(O)gamedir.tag if exist $(O)nh*key.lib del $(O)nh*key.lib From 46d85db233c4394a63f3e2321c65d11c4df5727e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 19 May 2019 11:55:05 -0400 Subject: [PATCH 2/7] remove a debug bit from Makefile.msc --- sys/winnt/Makefile.msc | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 060b8c7a1..74f5fe812 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -676,7 +676,6 @@ install: $(O)envchk.tag $(O)obj.tag $(O)utility.tag $(GAMEDIR)\NetHack.exe $(GAM $(O)install.tag: $(DAT)\data $(DAT)\rumors $(DAT)\dungeon \ $(DAT)\oracles $(DAT)\quest.dat $(O)sp_lev.tag $(DLB) - set ! IF ("$(USE_DLB)"=="Y") copy nhdat$(NHV) $(GAMEDIR) copy $(DAT)\license $(GAMEDIR) From e65386883339afd86a633fab3022cd2e01459a94 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 19 May 2019 23:35:21 -0400 Subject: [PATCH 3/7] fix a botl status display issue Reported as #H8609 (1679) Some code recently added to render_status() for BL_CONDITION: if (!tty_condition_bits) continue; was short-circuiting the required copy of NOW values to BEFORE values for later comparison further down in the for-loop. tty_status[BEFORE][idx] = tty_status[NOW][idx]; This caused some fields to be bypassed for rendering once no more tty_condition_bits were set because the length comparisons would match. --- doc/fixes36.3 | 2 ++ win/tty/wintty.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 8d5c22376..871143897 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -16,6 +16,8 @@ when examining the map with '/' or ';', picking a symbol which is used for billing and payment issue as a result of glob coalescing glob pricing did not consider weight properly glob shop interaction improved to handle more of the expected scenarios +remove the for-loop short circuit in render_status() that was preventing + the copy of BL_CONDITION tty_status values from NOW to BEFORE Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/win/tty/wintty.c b/win/tty/wintty.c index cc191fb65..831e5326b 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -4345,8 +4345,6 @@ render_status(VOID_ARGS) * | Condition Codes | * +-----------------+ */ - if (!tty_condition_bits) - continue; if (num_rows == 3) { int k; char *dat = &cw->data[y][0]; From cbb3dbb5f5a7c001082042bd4c2bfb35d15ac71c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 20 May 2019 01:33:33 -0400 Subject: [PATCH 4/7] make it tougher for incomplete render_status() to go unnoticed Adds a sanity check that will write a paniclog message if a code change prevents completion of render_status() for each dirty (changed) field. --- include/wintty.h | 4 ++-- win/tty/wintty.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/include/wintty.h b/include/wintty.h index 1a609de2a..4863d6e10 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintty.h $NHDT-Date: 1553858470 2019/03/29 11:21:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 3.6 wintty.h $NHDT-Date: 1558330405 2019/05/20 05:33:25 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.34 $ */ /* Copyright (c) David Cohrs, 1991,1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -79,7 +79,7 @@ struct tty_status_fields { boolean valid; boolean dirty; boolean redraw; - boolean _not_used; /* was 'last_in_row' */ + boolean sanitycheck; /* was 'last_in_row' */ }; #endif diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 831e5326b..d1ab86446 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintty.c $NHDT-Date: 1557088734 2019/05/05 20:38:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.203 $ */ +/* NetHack 3.6 wintty.c $NHDT-Date: 1558330407 2019/05/20 05:33:27 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.205 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -210,6 +210,7 @@ STATIC_DCL int NDECL(condition_size); STATIC_DCL int FDECL(make_things_fit, (BOOLEAN_P)); STATIC_DCL void FDECL(shrink_enc, (int)); STATIC_DCL void FDECL(shrink_dlvl, (int)); +STATIC_DCL void NDECL(status_sanity_check); #endif /* @@ -3622,6 +3623,8 @@ char *posbar; * Goes through each of the two status row's fields and * calls tty_putstatusfield() to place them on the display. * ->tty_putstatusfield() + * At the end of the for-loop, the NOW values get copied + * to BEFORE values. * * tty_putstatusfield() * @@ -3748,6 +3751,7 @@ tty_status_init() tty_status[NOW][i].valid = FALSE; tty_status[NOW][i].dirty = FALSE; tty_status[NOW][i].redraw = FALSE; + tty_status[NOW][i].sanitycheck = FALSE; tty_status[BEFORE][i] = tty_status[NOW][i]; } tty_condition_bits = 0L; @@ -3851,8 +3855,10 @@ unsigned long *colormasks; reset_state = FORCE_RESET; /*FALLTHRU*/ case BL_FLUSH: - if (make_things_fit(reset_state) || truncation_expected) + if (make_things_fit(reset_state) || truncation_expected) { render_status(); + status_sanity_check(); + } return; case BL_CONDITION: tty_status[NOW][fldidx].idx = fldidx; @@ -3860,6 +3866,7 @@ unsigned long *colormasks; tty_colormasks = colormasks; tty_status[NOW][fldidx].valid = TRUE; tty_status[NOW][fldidx].dirty = TRUE; + tty_status[NOW][fldidx].sanitycheck = TRUE; truncation_expected = FALSE; break; case BL_GOLD: @@ -3887,6 +3894,7 @@ unsigned long *colormasks; tty_status[NOW][fldidx].lth = strlen(status_vals[fldidx]); tty_status[NOW][fldidx].valid = TRUE; tty_status[NOW][fldidx].dirty = TRUE; + tty_status[NOW][fldidx].sanitycheck = TRUE; break; } @@ -4110,6 +4118,50 @@ int sz[3]; return valid; } +STATIC_OVL void +status_sanity_check(VOID_ARGS) +{ + int i; + static boolean in_sanity_check = FALSE; + static const char *idxtext[] = { + "BL_TITLE", "BL_STR", "BL_DX", "BL_CO", "BL_IN", "BL_WI", /* 0.. 5 */ + "BL_CH","BL_ALIGN", "BL_SCORE", "BL_CAP", "BL_GOLD", /* 6.. 10 */ + "BL_ENE", "BL_ENEMAX", "BL_XP", "BL_AC", "BL_HD", /* 11.. 15 */ + "BL_TIME", "BL_HUNGER", "BL_HP", "BL_HPMAX", /* 16.. 19 */ + "BL_LEVELDESC", "BL_EXP", "BL_CONDITION" /* 20.. 22 */ + }; + + if (in_sanity_check) + return; + in_sanity_check = TRUE; + /* + * Make sure that every field made it down to the + * bottom of the render_status() for-loop. + */ + for (i = 0; i < MAXBLSTATS; ++i) { + if (tty_status[NOW][i].sanitycheck) { + char panicmsg[BUFSZ]; + + Sprintf(panicmsg, "failed on tty_status[NOW][%s].", idxtext[i]); + paniclog("status_sanity_check", panicmsg); + tty_status[NOW][i].sanitycheck = FALSE; + /* + * Attention developers: If you encounter the above + * message in paniclog, it almost certainly means that + * a recent code change has caused a failure to reach + * the bottom of render_status(), at least for the BL_ + * field identified in the impossible() message. + + * That could be because of the addition of a continue + * statement within the render_status() for-loop, or a + * premature return from render_status() before it finished + * its housekeeping chores. + */ + } + } + in_sanity_check = FALSE; +} + /* * This is what places a field on the tty display. */ @@ -4504,6 +4556,7 @@ render_status(VOID_ARGS) /* reset .redraw and .dirty now that they're rendered */ tty_status[NOW][idx].dirty = FALSE; tty_status[NOW][idx].redraw = FALSE; + tty_status[NOW][idx].sanitycheck = FALSE; /* * For comparison of current and previous: * - Copy the entire tty_status struct. From 4c93e1fa215e391b561faed5efc9298c49ac1777 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 20 May 2019 05:26:19 -0700 Subject: [PATCH 5/7] more #H8609 - tty status condition rendering The earlier fix removed a valid optimization which happened to be implemented incorrectly. Put that back. It also left an invalid optimization when applied to conditions. Remove that one. I don't think either of these explains truncating 'y' off of "Hungry" which was shown in one of the reports. --- doc/fixes36.3 | 8 +++++--- win/tty/wintty.c | 36 ++++++++++++++++++++---------------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 871143897..aff1c56f2 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.8 $ $NHDT-Date: 1558248715 2019/05/19 06:51:55 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.10 $ $NHDT-Date: 1558355176 2019/05/20 12:26:16 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -16,8 +16,6 @@ when examining the map with '/' or ';', picking a symbol which is used for billing and payment issue as a result of glob coalescing glob pricing did not consider weight properly glob shop interaction improved to handle more of the expected scenarios -remove the for-loop short circuit in render_status() that was preventing - the copy of BL_CONDITION tty_status values from NOW to BEFORE Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository @@ -37,6 +35,10 @@ curses: if message window is only one line, cancelling some prompts with ESC left the prompts visible on the message line instead of erasing them curses: support EDIT_GETLIN (but like with tty, it's disabled by default) to pre-load an earlier response as the default answer for some prompts +tty: re-do one optimization used when status conditions have all been removed + and remove another that tried to check whether condition text to be + displayed next was the same as the existing value; sometimes new + status condition wouldn't be shown unless a screen redraw was forced Windows: some startup error messages were not being delivered successfully diff --git a/win/tty/wintty.c b/win/tty/wintty.c index d1ab86446..5622606a2 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintty.c $NHDT-Date: 1558330407 2019/05/20 05:33:27 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.205 $ */ +/* NetHack 3.6 wintty.c $NHDT-Date: 1558355176 2019/05/20 12:26:16 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.206 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -4065,10 +4065,10 @@ int sz[3]; * - Is the additional processing time for this worth it? */ if (do_field_opt - /* These color/attr checks aren't right for - 'condition'; is it safe to assume that same text - means same highlighting for that field? If not, - we'd end up redrawing conditions every time. */ + /* color/attr checks aren't right for 'condition' + and neither is examining status_vals[BL_CONDITION] + so skip same-contents optimization for conditions */ + && idx != BL_CONDITION && (tty_status[NOW][idx].color == tty_status[BEFORE][idx].color) && (tty_status[NOW][idx].attr @@ -4123,7 +4123,7 @@ status_sanity_check(VOID_ARGS) { int i; static boolean in_sanity_check = FALSE; - static const char *idxtext[] = { + static const char *const idxtext[] = { "BL_TITLE", "BL_STR", "BL_DX", "BL_CO", "BL_IN", "BL_WI", /* 0.. 5 */ "BL_CH","BL_ALIGN", "BL_SCORE", "BL_CAP", "BL_GOLD", /* 6.. 10 */ "BL_ENE", "BL_ENEMAX", "BL_XP", "BL_AC", "BL_HD", /* 11.. 15 */ @@ -4151,7 +4151,7 @@ status_sanity_check(VOID_ARGS) * a recent code change has caused a failure to reach * the bottom of render_status(), at least for the BL_ * field identified in the impossible() message. - + * * That could be because of the addition of a continue * statement within the render_status() for-loop, or a * premature return from render_status() before it finished @@ -4384,8 +4384,8 @@ render_status(VOID_ARGS) if (!status_activefields[idx]) continue; x = tty_status[NOW][idx].x; - text = status_vals[idx]; - tlth = (int) tty_status[NOW][idx].lth; + text = status_vals[idx]; /* always "" for BL_CONDITION */ + tlth = (int) tty_status[NOW][idx].lth; /* valid for BL_CONDITION */ if (tty_status[NOW][idx].redraw || !do_field_opt) { boolean hitpointbar = (idx == BL_TITLE @@ -4397,7 +4397,11 @@ render_status(VOID_ARGS) * | Condition Codes | * +-----------------+ */ - if (num_rows == 3) { + bits = tty_condition_bits; + /* if no bits are set, we can fall through condition + rendering code to finalx[] handling (and subsequent + rest-of-line erasure if line is shorter than before) */ + if (num_rows == 3 && bits != 0L) { int k; char *dat = &cw->data[y][0]; @@ -4424,8 +4428,7 @@ render_status(VOID_ARGS) tty_status[NOW][BL_CONDITION].x = x; tty_curs(WIN_STATUS, x, y); } - bits = tty_condition_bits; - for (c = 0; c < SIZE(conditions); ++c) { + for (c = 0; c < SIZE(conditions) && bits != 0L; ++c) { mask = conditions[c].mask; if (bits & mask) { const char *condtext; @@ -4441,8 +4444,10 @@ render_status(VOID_ARGS) condtext = conditions[c].text[cond_shrinklvl]; if (x >= cw->cols && !truncation_expected) { impossible( - "Unexpected condition placement overflow"); + "Unexpected condition placement overflow for \"%s\"", + condtext); condtext = ""; + bits = 0L; /* skip any remaining conditions */ } tty_putstatusfield(condtext, x, y); x += (int) strlen(condtext); @@ -4451,8 +4456,7 @@ render_status(VOID_ARGS) term_end_color(); End_Attr(attrmask); } - if (!(bits &= ~mask)) - break; + bits &= ~mask; } } /* 'x' is 1-based and 'cols' and 'data' are 0-based, @@ -4553,7 +4557,7 @@ render_status(VOID_ARGS) x += tlth; } finalx[row][NOW] = x - 1; - /* reset .redraw and .dirty now that they're rendered */ + /* reset .redraw and .dirty now that field has been rendered */ tty_status[NOW][idx].dirty = FALSE; tty_status[NOW][idx].redraw = FALSE; tty_status[NOW][idx].sanitycheck = FALSE; From 7d7111ec03d16360f2c3ff94cae7344a1c03233c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 20 May 2019 12:08:51 -0400 Subject: [PATCH 6/7] status_sanity_check is most useful in WIP and beta so restrict it --- win/tty/wintty.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 5622606a2..037d9da6c 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -210,7 +210,9 @@ STATIC_DCL int NDECL(condition_size); STATIC_DCL int FDECL(make_things_fit, (BOOLEAN_P)); STATIC_DCL void FDECL(shrink_enc, (int)); STATIC_DCL void FDECL(shrink_dlvl, (int)); +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) STATIC_DCL void NDECL(status_sanity_check); +#endif /* NH_DEVEL_STATUS */ #endif /* @@ -3857,7 +3859,9 @@ unsigned long *colormasks; case BL_FLUSH: if (make_things_fit(reset_state) || truncation_expected) { render_status(); +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) status_sanity_check(); +#endif } return; case BL_CONDITION: @@ -4118,6 +4122,7 @@ int sz[3]; return valid; } +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) STATIC_OVL void status_sanity_check(VOID_ARGS) { @@ -4161,6 +4166,7 @@ status_sanity_check(VOID_ARGS) } in_sanity_check = FALSE; } +#endif /* NHDEVEL_STATUS */ /* * This is what places a field on the tty display. From cd6c2ebcdfad35c459896476266f653057fa088a Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 20 May 2019 15:16:57 -0400 Subject: [PATCH 7/7] status line count (word two) bit --- win/tty/wintty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 037d9da6c..fee720054 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -3622,7 +3622,7 @@ char *posbar; * * render_status * - * Goes through each of the two status row's fields and + * Goes through each of the status row's fields and * calls tty_putstatusfield() to place them on the display. * ->tty_putstatusfield() * At the end of the for-loop, the NOW values get copied