From e4f3559acc2e56eec552ce635f486888364d7e25 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 9 Oct 2019 13:18:34 -0700 Subject: [PATCH 01/24] curses on unix - terminal reset needed after abort Noticed while investigating the message loop. If I had level files from an interrupted game and was asked "Destroy old game?" when starting a new one, answering 'n' left the terminal in an unusable state. Executing 'stty sane' (invisibly since input echo was off) repaired things but the user shouldn't have to do that. Change unixtty.c's error() to shut down windowing if that has been initialized. This might need some tweaking for tty, which will now clear the screen before showing the startup error message. Other systems besides unix use unixtty.c so are affected, but I think the change doesn't introduce anything that should cause trouble (aside from the potential screen erasure). --- doc/fixes36.3 | 8 +++++--- sys/share/unixtty.c | 6 +++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 71572a441..49c49674c 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.126 $ $NHDT-Date: 1570408209 2019/10/07 00:30:09 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.128 $ $NHDT-Date: 1570652307 2019/10/09 20:18:27 $ 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, @@ -210,8 +210,6 @@ tty: revert the attempt to fix "message line anomaly: if autodecribe feedback wrapped to second line, the wrapped portion wasn't erased when a shorter line was shown or getpos was dismissed" because it disrupted prompts that spanned more than one line, a more significant issue -unix: sysconf CHECK_PLNAME=1 wouldn't work if attempt to obtain unix username - failed even though it didn't need that username Platform- and/or Interface-Specific Fixes or Features @@ -302,6 +300,10 @@ tty: take two, if/when autodecribe feedback wraps past top line, clear ['exposed by git' section has an entry for reversal of 'take one'] tty: video attributes (bold, inverse, &c) for status highlighting sometimes were scrambled +unix: sysconf CHECK_PLNAME=1 wouldn't work if attempt to obtain unix username + failed even though it didn't need that username +unix+curses: startup error only reset terminal for tty; one noticeable + example was answering 'n' to "Destroy old game?" Windows: some startup error messages were not being delivered successfully diff --git a/sys/share/unixtty.c b/sys/share/unixtty.c index dafbc8f44..3196f3b3d 100644 --- a/sys/share/unixtty.c +++ b/sys/share/unixtty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 unixtty.c $NHDT-Date: 1548372343 2019/01/24 23:25:43 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.25 $ */ +/* NetHack 3.6 unixtty.c $NHDT-Date: 1570652308 2019/10/09 20:18:28 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.26 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -243,6 +243,7 @@ const char *s; iflags.cbreak = (CBRKON(inittyb.cbrkflgs & CBRKMASK)) ? ON : OFF; curttyb.inputflags |= STRIPHI; setioctls(); + settty_needed = FALSE; } void @@ -471,6 +472,9 @@ VA_DECL(const char *, s) { VA_START(s); VA_INIT(s, const char *); + + if (iflags.window_inited) + exit_nhwindows((char *) 0); /* for tty, will call settty() */ if (settty_needed) settty((char *) 0); Vprintf(s, VA_ARGS); From ad302fb8a99a5795c4d206870ea6573349b2d92a Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 10 Oct 2019 17:43:31 -0700 Subject: [PATCH 02/24] mksobj failure If mksobj() was told to initialize the object it's creating and the object class was something it didn't understand, it would issue a warning and return Null. But an unknown object class is a severe internal error and very few callers were prepared to deal with a Null result, so change mksobj() to panic instead. Also eliminate the few attempts to deal with Null result that are present in mkobj.c; I didn't go looking elsewhere. --- src/mkobj.c | 126 +++++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 61 deletions(-) diff --git a/src/mkobj.c b/src/mkobj.c index 24124f706..a92deceb6 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1570569798 2019/10/08 21:23:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.153 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1570754586 2019/10/11 00:43:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.154 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -235,15 +235,14 @@ boolean init, artif; struct obj *otmp; otmp = mksobj(otyp, init, artif); - if (otmp) { - add_to_migration(otmp); - otmp->owornmask = (long) MIGR_TO_SPECIES; - otmp->corpsenm = mflags2; - } + add_to_migration(otmp); + otmp->owornmask = (long) MIGR_TO_SPECIES; + otmp->corpsenm = mflags2; return otmp; } -/* mkobj(): select a type of item from a class, use mksobj() to create it */ +/* mkobj(): select a type of item from a class, use mksobj() to create it; + result is always non-Null */ struct obj * mkobj(oclass, artif) char oclass; @@ -309,8 +308,7 @@ struct obj *box; for (n = rn2(n + 1); n > 0; n--) { if (box->otyp == ICE_BOX) { - if (!(otmp = mksobj(CORPSE, TRUE, TRUE))) - continue; + otmp = mksobj(CORPSE, TRUE, TRUE); /* Note: setting age to 0 is correct. Age has a different * from usual meaning for objects stored in ice boxes. -KAA */ @@ -768,7 +766,7 @@ static const char dknowns[] = { WAND_CLASS, RING_CLASS, POTION_CLASS, SCROLL_CLASS, GEM_CLASS, SPBOOK_CLASS, WEAPON_CLASS, TOOL_CLASS, 0 }; -/* mksobj(): create a specific type of object */ +/* mksobj(): create a specific type of object; result it always non-Null */ struct obj * mksobj(otyp, init, artif) int otyp; @@ -1062,10 +1060,12 @@ boolean artif; case COIN_CLASS: break; /* do nothing */ default: - impossible("impossible mkobj %d, sym '%c'.", otmp->otyp, - objects[otmp->otyp].oc_class); - dealloc_obj(otmp); /* free() would suffice here */ - return (struct obj *) 0; + /* 3.6.3: this used to be impossible() followed by return 0 + but most callers aren't prepared to deal with Null result + and cluttering them up to do so is pointless */ + panic("mksobj tried to make type %d, class %d.", + (int) otmp->otyp, (int) objects[otmp->otyp].oc_class); + /*NOTREACHED*/ } } @@ -1473,6 +1473,7 @@ register struct obj *obj; static int treefruits[] = { APPLE, ORANGE, PEAR, BANANA, EUCALYPTUS_LEAF }; +/* called when a tree is kicked; never returns Null */ struct obj * rnd_treefruit_at(x, y) int x, y; @@ -1480,15 +1481,17 @@ int x, y; return mksobj_at(treefruits[rn2(SIZE(treefruits))], x, y, TRUE, FALSE); } +/* create a stack of N gold pieces; never returns Null */ struct obj * mkgold(amount, x, y) long amount; int x, y; { - register struct obj *gold = g_at(x, y); + struct obj *gold = g_at(x, y); if (amount <= 0L) { long mul = rnd(30 / max(12-depth(&u.uz), 2)); + amount = (long) (1 + rnd(level_difficulty() + 2) * mul); } if (gold) { @@ -1501,12 +1504,14 @@ int x, y; return gold; } -/* return TRUE if the corpse has special timing */ -#define special_corpse(num) \ - (((num) == PM_LIZARD) || ((num) == PM_LICHEN) || (is_rider(&mons[num])) \ - || (mons[num].mlet == S_TROLL)) +/* return TRUE if the corpse has special timing; + lizards and lichen don't rot, trolls and Riders auto-revive */ +#define special_corpse(num) \ + (((num) == PM_LIZARD || (num) == PM_LICHEN) \ + || (mons[num].mlet == S_TROLL || is_rider(&mons[num]))) -/* +/* mkcorpstat: make a corpse or statue; never returns Null. + * * OEXTRA note: Passing mtmp causes mtraits to be saved * even if ptr passed as well, but ptr is always used for * the corpse type (corpsenm). That allows the corpse type @@ -1523,40 +1528,37 @@ struct permonst *ptr; int x, y; unsigned corpstatflags; { - register struct obj *otmp; + struct obj *otmp; boolean init = ((corpstatflags & CORPSTAT_INIT) != 0); if (objtype != CORPSE && objtype != STATUE) impossible("making corpstat type %d", objtype); if (x == 0 && y == 0) { /* special case - random placement */ otmp = mksobj(objtype, init, FALSE); - if (otmp) - (void) rloco(otmp); - } else + (void) rloco(otmp); + } else { otmp = mksobj_at(objtype, x, y, init, FALSE); - if (otmp) { - if (mtmp) { - struct obj *otmp2; + } - if (!ptr) - ptr = mtmp->data; - /* save_mtraits frees original data pointed to by otmp */ - otmp2 = save_mtraits(otmp, mtmp); - if (otmp2) - otmp = otmp2; - } - /* use the corpse or statue produced by mksobj() as-is - unless `ptr' is non-null */ - if (ptr) { - int old_corpsenm = otmp->corpsenm; + /* when 'mtmp' is non-null make a corpse or statue of that monster, + otherwise keep the random type chosen by mksobj() */ + if (mtmp) { + int old_corpsenm = otmp->corpsenm; - otmp->corpsenm = monsndx(ptr); - otmp->owt = weight(otmp); - if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm) - || special_corpse(otmp->corpsenm))) { - obj_stop_timers(otmp); - start_corpse_timeout(otmp); - } + /* save_mtraits updates otmp->oextra->omonst in place */ + (void) save_mtraits(otmp, mtmp); + + /* when 'ptr' is non-null use the type specified by our caller, + otherwise use the monster's species for the corpse */ + if (!ptr) + ptr = mtmp->data; + + otmp->corpsenm = monsndx(ptr); + otmp->owt = weight(otmp); + if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm) + || special_corpse(otmp->corpsenm))) { + obj_stop_timers(otmp); + start_corpse_timeout(otmp); } } return otmp; @@ -1574,15 +1576,14 @@ int corpse_revive_type(obj) struct obj *obj; { - int revivetype; + int revivetype = obj->corpsenm; struct monst *mtmp; - if (has_omonst(obj) - && ((mtmp = get_mtraits(obj, FALSE)) != (struct monst *) 0)) { + + if (has_omonst(obj) && ((mtmp = get_mtraits(obj, FALSE)) != 0)) { /* mtmp is a temporary pointer to a monster's stored attributes, not a real monster */ revivetype = mtmp->mnum; - } else - revivetype = obj->corpsenm; + } return revivetype; } @@ -1658,26 +1659,29 @@ boolean copyof; return mnew; } -/* make an object named after someone listed in the scoreboard file */ +/* make an object named after someone listed in the scoreboard file; + never returns Null */ struct obj * mk_tt_object(objtype, x, y) int objtype; /* CORPSE or STATUE */ -register int x, y; +int x, y; { - register struct obj *otmp, *otmp2; + struct obj *otmp; boolean initialize_it; /* player statues never contain books */ initialize_it = (objtype != STATUE); - if ((otmp = mksobj_at(objtype, x, y, initialize_it, FALSE)) != 0) { - /* tt_oname will return null if the scoreboard is empty */ - if ((otmp2 = tt_oname(otmp)) != 0) - otmp = otmp2; - } + otmp = mksobj_at(objtype, x, y, initialize_it, FALSE); + /* tt_oname() will return null if the scoreboard is empty; + assigning an object name used to allocate a new obj but + doesn't any more so we can safely ignore the return value */ + (void) tt_oname(otmp); + return otmp; } -/* make a new corpse or statue, uninitialized if a statue (i.e. no books) */ +/* make a new corpse or statue, uninitialized if a statue (i.e. no books); + never returns Null */ struct obj * mk_named_object(objtype, ptr, x, y, nm) int objtype; /* CORPSE or STATUE */ @@ -1686,8 +1690,8 @@ int x, y; const char *nm; { struct obj *otmp; - unsigned corpstatflags = - (objtype != STATUE) ? CORPSTAT_INIT : CORPSTAT_NONE; + unsigned corpstatflags = (objtype != STATUE) ? CORPSTAT_INIT + : CORPSTAT_NONE; otmp = mkcorpstat(objtype, (struct monst *) 0, ptr, x, y, corpstatflags); if (nm) From 02b9368dbaab631466fcb3f5aba5c1691cc15aa7 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 11 Oct 2019 20:00:17 +0300 Subject: [PATCH 03/24] Fix fired iron ball sanity error When hero was punished and swallowed, and fired the attached iron ball from a quiver, thrownobj was not cleared. --- doc/fixes36.3 | 1 + src/dothrow.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 49c49674c..c62dfc1d1 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -178,6 +178,7 @@ avoid 'object lost' panic when polymorph causes loss of levitation boots or wasn't possible to tell where they were, unlike all other forms of multiple movement; stop running if/when an engraving is reached fix exploding land mine moving ball or chain and causing a sanity error +fix firing attached iron ball when swallowed causing a sanity error Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/dothrow.c b/src/dothrow.c index a2d12c93a..1b2a80184 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1294,7 +1294,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ || !index(in_rooms(mon->mx, mon->my, SHOPBASE), *u.ushops))) hot_pursuit(mon); - if (obj_gone) + if (obj_gone || obj == uball) thrownobj = (struct obj *) 0; } From ab30c3d79d7ba7b058f5ce68663bdb561060e4d5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 11 Oct 2019 20:11:24 +0300 Subject: [PATCH 04/24] Fix vault guard impossible ... when the guard is angry, and he's in the vault or in his corridor, you're not in the vault nor in his corridor, and the level is full so the guard cannot relocate. --- doc/fixes36.3 | 1 + src/vault.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index c62dfc1d1..32a45e720 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -179,6 +179,7 @@ avoid 'object lost' panic when polymorph causes loss of levitation boots or multiple movement; stop running if/when an engraving is reached fix exploding land mine moving ball or chain and causing a sanity error fix firing attached iron ball when swallowed causing a sanity error +fix vault guard impossible when he could not relocate in certain situation Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/vault.c b/src/vault.c index 6ff80fa76..00369fd61 100644 --- a/src/vault.c +++ b/src/vault.c @@ -775,9 +775,10 @@ register struct monst *grd; if (!u_in_vault && (grd_in_vault || (in_fcorridor(grd, grd->mx, grd->my) && !in_fcorridor(grd, u.ux, u.uy)))) { - (void) rloc(grd, FALSE); + (void) rloc(grd, TRUE); wallify_vault(grd); - (void) clear_fcorr(grd, TRUE); + if (!in_fcorridor(grd, grd->mx, grd->my)) + (void) clear_fcorr(grd, TRUE); goto letknow; } if (!in_fcorridor(grd, grd->mx, grd->my)) From 46adb312e748d3ede72a134f763ba5b4f3d62b52 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 11 Oct 2019 20:24:17 +0300 Subject: [PATCH 05/24] Fix priests and shopkeepers moving on other monsters --- doc/fixes36.3 | 1 + src/priest.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 32a45e720..2fdd04027 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -180,6 +180,7 @@ avoid 'object lost' panic when polymorph causes loss of levitation boots or fix exploding land mine moving ball or chain and causing a sanity error fix firing attached iron ball when swallowed causing a sanity error fix vault guard impossible when he could not relocate in certain situation +fix temple priests or shopkeepers moving over other monsters Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/priest.c b/src/priest.c index d97886c73..ab20a8d7a 100644 --- a/src/priest.c +++ b/src/priest.c @@ -118,6 +118,8 @@ pick_move: } if (nix != omx || niy != omy) { + if (MON_AT(nix, niy)) + return 0; remove_monster(omx, omy); place_monster(mtmp, nix, niy); newsym(nix, niy); From 6cbf10d97447970daa3e1e75a1ccece11bd5a2ed Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 11 Oct 2019 18:33:32 -0700 Subject: [PATCH 06/24] South Park reference - gnomes' business plan If you chat with a peaceful gnome while hallucinating, you might get a silly message from the TV show South Park. To make it work for non-gnome characters, I changed the speech of monsters who normally just grunt (gnomes, orcs, ogres, a couple of other groups) to full humanoid when the hero is hallucinating. (It already does that for orcs if the hero--hallucinating or not-- is an orc and for gnomes when the hero is a gnome.) --- src/sounds.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/sounds.c b/src/sounds.c index 505a10e56..1bf77165f 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sounds.c $NHDT-Date: 1542765362 2018/11/21 01:56:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.81 $ */ +/* NetHack 3.6 sounds.c $NHDT-Date: 1570844005 2019/10/12 01:33:25 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.83 $ */ /* Copyright (c) 1989 Janet Walz, Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -496,7 +496,7 @@ register struct monst *mtmp; *verbl_msg = 0, /* verbalize() */ *verbl_msg_mcan = 0; /* verbalize() if cancelled */ struct permonst *ptr = mtmp->data; - int msound = ptr->msound; + int msound = ptr->msound, gnomeplan = 0; /* presumably nearness and sleep checks have already been made */ if (Deaf) @@ -512,8 +512,9 @@ register struct monst *mtmp; msound = mons[genus(monsndx(ptr), 1)].msound; /* some normally non-speaking types can/will speak if hero is similar */ else if (msound == MS_ORC /* note: MS_ORC is same as MS_GRUNT */ - && (same_race(ptr, youmonst.data) /* current form, */ - || same_race(ptr, &mons[Race_switch]))) /* unpoly'd form */ + && ((same_race(ptr, youmonst.data) /* current form, */ + || same_race(ptr, &mons[Race_switch])) /* unpoly'd form */ + || Hallucination)) msound = MS_HUMANOID; /* silliness, with slight chance to interfere with shopping */ else if (Hallucination && mon_is_gecko(mtmp)) @@ -588,13 +589,14 @@ register struct monst *mtmp; } else verbl_msg = "I only drink... potions."; } else { - int vampindex; static const char *const vampmsg[] = { /* These first two (0 and 1) are specially handled below */ "I vant to suck your %s!", "I vill come after %s without regret!", /* other famous vampire quotes can follow here if desired */ }; + int vampindex; + if (kindred) verbl_msg = "This is my hunting ground that you dare to prowl!"; @@ -803,6 +805,18 @@ register struct monst *mtmp; pline_msg = "talks about spellcraft."; else if (ptr->mlet == S_CENTAUR) pline_msg = "discusses hunting."; + else if (is_gnome(ptr) && Hallucination && (gnomeplan = rn2(4)) % 2) + /* skipped for rn2(4) result of 0 or 2; + gag from an early episode of South Park called "Gnomes"; + initially, Tweek (introduced in that episode) is the only + one aware of the tiny gnomes after spotting them sneaking + about; they are embarked upon a three-step business plan; + a diagram of the plan shows: + Phase 1 Phase 2 Phase 3 + Collect underpants ? Profit + and they never verbalize step 2 so we don't either */ + verbl_msg = (gnomeplan == 1) ? "Phase one, collect underpants." + : "Phase three, profit!"; else switch (monsndx(ptr)) { case PM_HOBBIT: From 1fc8d7528ced1f519f67e6365530deda390ffeca Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 12 Oct 2019 02:31:47 -0700 Subject: [PATCH 07/24] fix #H9298 - corpse mismatch Corpses for dying monsters were being created with the wrong type, caused by incorrect block nesting for 'if (ptr)' from commit ad302fb8a99a5795c4d206870ea6573349b2d92a (Oct 10). --- doc/fixes36.3 | 3 ++- src/mkobj.c | 16 +++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 2fdd04027..a2467729c 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.128 $ $NHDT-Date: 1570652307 2019/10/09 20:18:27 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.132 $ $NHDT-Date: 1570872701 2019/10/12 09:31:41 $ 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, @@ -201,6 +201,7 @@ monster throwing from stack of missiles (darts, daggers, spears) would cause crash if it wasn't wielding a weapon (bug in multi-shot shooting fix) surviving death while polymorphed would yield "You are a " without terminating period +'mksobj failure' commit resulted in wrong corpse types for dying monsters curses: sometimes the message window would show a blank line after a prompt curses: the change to show map in columns 1..79 instead of 2..80 made the highlight for '@' show up in the wrong place if clipped map had been diff --git a/src/mkobj.c b/src/mkobj.c index a92deceb6..6975ca966 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1570754586 2019/10/11 00:43:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.154 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1570872702 2019/10/12 09:31:42 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.155 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1540,18 +1540,20 @@ unsigned corpstatflags; otmp = mksobj_at(objtype, x, y, init, FALSE); } - /* when 'mtmp' is non-null make a corpse or statue of that monster, - otherwise keep the random type chosen by mksobj() */ + /* when 'mtmp' is non-null save the monster's details with the + corpse or statue; it will also force the 'ptr' override below */ if (mtmp) { - int old_corpsenm = otmp->corpsenm; - /* save_mtraits updates otmp->oextra->omonst in place */ (void) save_mtraits(otmp, mtmp); - /* when 'ptr' is non-null use the type specified by our caller, - otherwise use the monster's species for the corpse */ if (!ptr) ptr = mtmp->data; + } + + /* when 'ptr' is non-null it comes from our caller or from 'mtmp'; + override mkobjs()'s initialization of a random monster type */ + if (ptr) { + int old_corpsenm = otmp->corpsenm; otmp->corpsenm = monsndx(ptr); otmp->owt = weight(otmp); From d058b9679c043b42c880f2b70138d1e9be0cc983 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 12 Oct 2019 15:33:57 -0700 Subject: [PATCH 08/24] fix part of #H9299 - DECgraphics symset comments For the DECgraphics symbol set, down ladder is the greater-than-or- equal-to character as intended and up ladder is less-than-or-equal-to, but comments in dat/symbols had their descriptions transposed. --- dat/symbols | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dat/symbols b/dat/symbols index d9e1ecef6..be27dad5d 100644 --- a/dat/symbols +++ b/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.6 symbols $NHDT-Date: 1524689580 2018/04/25 20:53:00 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.16 $ +# NetHack 3.6 symbols $NHDT-Date: 1570919632 2019/10/12 22:33:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.17 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -35,8 +35,8 @@ start: DECgraphics S_bars: \xfb # meta-{, small pi S_tree: \xe7 # meta-g, plus-or-minus S_room: \xfe # meta-~, centered dot - S_upladder: \xf9 # meta-y, greater-than-or-equals - S_dnladder: \xfa # meta-z, less-than-or-equals + S_upladder: \xf9 # meta-y, less-than-or-equals + S_dnladder: \xfa # meta-z, greater-than-or-equals S_pool: \xe0 # meta-\, diamond S_ice: \xfe # meta-~, centered dot S_lava: \xe0 # meta-\, diamond From 9e9ee59ca7f8652702554ddb3cec23bd90be50cc Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 13 Oct 2019 19:16:38 +0300 Subject: [PATCH 09/24] Fix hero hiding under a statue shattered by land mine Trigger a land mine while being polymorphed into a monster that automatically hides (eg. scorpion). Have the statue on the land mine shatter and all items on that square scatter away. Avoid falling into the pit left by the land mine. --- doc/fixes36.3 | 1 + src/explode.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index a2467729c..8182bfea8 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -181,6 +181,7 @@ fix exploding land mine moving ball or chain and causing a sanity error fix firing attached iron ball when swallowed causing a sanity error fix vault guard impossible when he could not relocate in certain situation fix temple priests or shopkeepers moving over other monsters +fix hero still hiding under a statue shattered by a land mine Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/explode.c b/src/explode.c index 2c46178fd..31ba7c763 100644 --- a/src/explode.c +++ b/src/explode.c @@ -771,6 +771,9 @@ struct obj *obj; /* only scatter this obj */ newsym(x, y); } newsym(sx, sy); + if (sx == u.ux && sy == u.uy && u.uundetected + && hides_under(youmonst.data)) + (void) hideunder(&youmonst); return total; } From 1f7095e226c96fcdf1e06a52a7ff86ced76b0f12 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 13 Oct 2019 19:57:05 +0300 Subject: [PATCH 10/24] Fix addressing deleted trap when helping monster out of a pit Move reward_untrap before fill_pit, as the trap may get deleted. --- doc/fixes36.3 | 1 + src/trap.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 8182bfea8..e87280bdd 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -182,6 +182,7 @@ fix firing attached iron ball when swallowed causing a sanity error fix vault guard impossible when he could not relocate in certain situation fix temple priests or shopkeepers moving over other monsters fix hero still hiding under a statue shattered by a land mine +fix helping a monster out of a pit addressing a deleted trap Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/trap.c b/src/trap.c index 994cbede0..8d0dddb6a 100644 --- a/src/trap.c +++ b/src/trap.c @@ -4346,8 +4346,8 @@ struct trap *ttmp; You("pull %s out of the pit.", mon_nam(mtmp)); mtmp->mtrapped = 0; - fill_pit(mtmp->mx, mtmp->my); reward_untrap(ttmp, mtmp); + fill_pit(mtmp->mx, mtmp->my); return 1; } From 346ebbce10854ba70e28778ac4852936a68e5967 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 13 Oct 2019 20:40:54 +0300 Subject: [PATCH 11/24] Fix launched object accessing a deleted trap In launch_obj, the code first got the trap, then called ohitmon (which can delete the trap by doing mondied -> fill_pit -> flooreffects -> deltrap), then after that used the trap variable. --- doc/fixes36.3 | 1 + src/trap.c | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index e87280bdd..94af43996 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -183,6 +183,7 @@ fix vault guard impossible when he could not relocate in certain situation fix temple priests or shopkeepers moving over other monsters fix hero still hiding under a statue shattered by a land mine fix helping a monster out of a pit addressing a deleted trap +fix launched rolling boulder code accessing deleted trap Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/trap.c b/src/trap.c index 8d0dddb6a..6b9884ea6 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1840,7 +1840,6 @@ int style; bhitpos.x += dx; bhitpos.y += dy; - t = t_at(bhitpos.x, bhitpos.y); if ((mtmp = m_at(bhitpos.x, bhitpos.y)) != 0) { if (otyp == BOULDER && throws_rocks(mtmp->data)) { @@ -1875,7 +1874,7 @@ int style; break; } } - if (t && otyp == BOULDER) { + if ((t = t_at(bhitpos.x, bhitpos.y)) != 0 && otyp == BOULDER) { switch (t->ttyp) { case LANDMINE: if (rn2(10) > 2) { From f200397689fbd31c65346c19e1ac646c6d9c4ed7 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 13 Oct 2019 20:52:34 +0300 Subject: [PATCH 12/24] Fix monster triggering land mine accessing deleted trap mintrap -> thitm -> mondied -> relobj -> mdrop_obj -> flooreffects -> deltrap after calling thitm, the mintrap code was trying to access the trap. --- doc/fixes36.3 | 1 + src/trap.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 94af43996..ee3964155 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -184,6 +184,7 @@ fix temple priests or shopkeepers moving over other monsters fix hero still hiding under a statue shattered by a land mine fix helping a monster out of a pit addressing a deleted trap fix launched rolling boulder code accessing deleted trap +fix monster stepping on a land mine code accessing deleted trap Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/trap.c b/src/trap.c index 6b9884ea6..cb025e514 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2167,6 +2167,7 @@ register struct monst *mtmp; inescapable = force_mintrap || ((tt == HOLE || tt == PIT) && Sokoban && !trap->madeby_u); const char *fallverb; + xchar tx = trap->tx, ty = trap->ty; /* true when called from dotrap, inescapable is not an option */ if (mtmp == u.usteed) @@ -2649,7 +2650,7 @@ register struct monst *mtmp; trapkilled = TRUE; } /* a boulder may fill the new pit, crushing monster */ - fill_pit(trap->tx, trap->ty); + fill_pit(tx, ty); /* thitm may have already destroyed the trap */ if (DEADMONSTER(mtmp)) trapkilled = TRUE; if (unconscious()) { From 027ce7c8b9c04f2ad64632a107536cd173dfb07f Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 13 Oct 2019 17:41:24 -0700 Subject: [PATCH 13/24] pull request 229/#H9299 - DECgraphics for curses Fixes #230 Incorporate github pull request #230, support for DECgraphics-style line drawing in the curses interface. I've rewritten the curses_convert_glyph() part so that it doesn't require C99 and doesn't reinitialize its pair of arrays for every character written to the map. The DECgraphics conversion is now a straight char for char one, DEC line drawing code to ACS, without regard to what map symbol is intended or what 'cursesgraphics' uses for that symbol. --- include/wincurs.h | 2 +- win/curses/cursinit.c | 9 -- win/curses/cursmain.c | 8 +- win/curses/cursmisc.c | 186 ++++++++++++++++++++++++++++++++---------- win/curses/cursmisc.h | 2 +- 5 files changed, 150 insertions(+), 57 deletions(-) diff --git a/include/wincurs.h b/include/wincurs.h index 8ae45e10e..c7d16f9e5 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -152,7 +152,7 @@ extern char *curses_break_str(const char *str, int width, int line_num); extern char *curses_str_remainder(const char *str, int width, int line_num); extern boolean curses_is_menu(winid wid); extern boolean curses_is_text(winid wid); -extern int curses_convert_glyph(int ch, int glyph); +extern int curses_convert_glyph(boolean decgraphics, int ch, int glyph); extern void curses_move_cursor(winid wid, int x, int y); extern void curses_prehousekeeping(void); extern void curses_posthousekeeping(void); diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 594849ae2..2555e71de 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -782,17 +782,8 @@ curses_init_options() set_wc_option_mod_status(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS, SET_IN_GAME); /* Remove a few options that are irrelevant to this windowport */ - /*set_option_mod_status("DECgraphics", SET_IN_FILE); */ set_option_mod_status("eight_bit_tty", SET_IN_FILE); - /* Make sure that DECgraphics is not set to true via the config - file, as this will cause display issues. We can't disable it in - options.c in case the game is compiled with both tty and curses. */ - if (!symset[PRIMARY].name - || !strcmpi(symset[PRIMARY].name, "DECgraphics")) { - load_symset("curses", PRIMARY); - load_symset("default", ROGUESET); - } #ifdef PDCURSES /* PDCurses for SDL, win32 and OS/2 has the ability to set the terminal size programatically. If the user does not specify a diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index c87f68a89..91a5ffac1 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -658,9 +658,11 @@ curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, if ((special & MG_DETECT) && iflags.use_inverse) { attr = A_REVERSE; } - if (!symset[PRIMARY].name || !strcmpi(symset[PRIMARY].name, "curses")) { - ch = curses_convert_glyph(ch, glyph); - } + if (SYMHANDLING(H_DEC)) + ch = curses_convert_glyph(TRUE, ch, glyph); + else if (!symset[PRIMARY].name || !strcmpi(symset[PRIMARY].name, "curses")) + ch = curses_convert_glyph(FALSE, ch, glyph); + if (wid == NHW_MAP) { /* hilite stairs not in 3.6, yet if ((special & MG_STAIRS) && iflags.hilite_hidden_stairs) { diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index e435f2211..aed91e84c 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -463,65 +463,165 @@ curses_is_text(winid wid) } } - /* Replace certain characters with portable drawing characters if -cursesgraphics option is enabled */ - + cursesgraphics option is enabled, or special curses handling for + DECgraphics */ int -curses_convert_glyph(int ch, int glyph) +curses_convert_glyph(boolean decgraphics, int ch, int glyph) { - int symbol; + static int cursesglyphs[MAXPCHARS], cursesglyphsinited = 0; + int retch, symbol; - if (Is_rogue_level(&u.uz)) { + /* FIXME? we don't support any special characters in roguesymset */ + if (Is_rogue_level(&u.uz)) return ch; - } /* Save some processing time by returning if the glyph represents an object that we don't have custom characters for */ - if (!glyph_is_cmap(glyph)) { + if (!glyph_is_cmap(glyph)) return ch; - } symbol = glyph_to_cmap(glyph); - /* If user selected a custom character for this object, don't - override this. */ - if (((glyph_is_cmap(glyph)) && (ch != showsyms[symbol]))) { + /* + * FIXME: + * 'cursesgraphics' should be a symbol set so that users can + * modify it without having to edit this source file and rebuild + * the program. Unfortunately these ACS values are 32-bit ones + * and not user-friendly. + */ + if (!cursesglyphsinited) { /* one-time initialization */ + cursesglyphsinited = 1; + cursesglyphs[S_vwall] = ACS_VLINE; + cursesglyphs[S_hwall] = ACS_HLINE; + cursesglyphs[S_tlcorn] = ACS_ULCORNER; + cursesglyphs[S_trcorn] = ACS_URCORNER; + cursesglyphs[S_blcorn] = ACS_LLCORNER; + cursesglyphs[S_brcorn] = ACS_LRCORNER; + cursesglyphs[S_crwall] = ACS_PLUS; + cursesglyphs[S_tuwall] = ACS_BTEE; + cursesglyphs[S_tdwall] = ACS_TTEE; + /* yes, the left/right Ts are inverted nethack vs curses */ + cursesglyphs[S_tlwall] = ACS_RTEE; + cursesglyphs[S_trwall] = ACS_LTEE; + cursesglyphs[S_tree] = ACS_PLMINUS; + cursesglyphs[S_corr] = ACS_CKBOARD; + cursesglyphs[S_litcorr] = ACS_CKBOARD; + } + + /* Curses has complete access to all characters that DECgraphics uses. + However, their character value isn't consistent between terminals + and implementations. For actual DEC terminals and faithful emulators, + line-drawing characters are specified as lowercase letters (mostly) + and a control code is sent to the terminal telling it to switch + character sets (that's how the tty interface handles them). + Curses remaps the characters instead. */ + if (decgraphics) { + /* the DEC line drawing characters use 0x5f through 0x7e instead + of the much more straightforward 0x60 though 0x7f, possibly + because 0x7f is effectively a control character (Rubout); + nethack ORs 0x80 to flag line drawing--that's stripped below */ + static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */ + + /* one-time initialization; some ACS_x aren't compile-time constant */ + if (!decchars[0]) { + /* [0] is non-breakable space; irrelevant to nethack */ + decchars[0x5f - 0x5f] = ' '; /* NBSP */ + decchars[0x60 - 0x5f] = ACS_DIAMOND; /* [1] solid diamond */ + decchars[0x61 - 0x5f] = ACS_CKBOARD; /* [2] checkerboard */ + /* several "line drawing" characters are two-letter glyphs + which could be substituted for invisible control codes; + nethack's DECgraphics doesn't use any of them so we're + satisfied with conversion to a simple letter; + [3] "HT" as one char, with small raised upper case H over + and/or preceding small lowered upper case T */ + decchars[0x62 - 0x5f] = 'H'; /* "HT" (horizontal tab) */ + decchars[0x63 - 0x5f] = 'F'; /* "FF" as one char (form feed) */ + decchars[0x64 - 0x5f] = 'C'; /* "CR" as one (carriage return) */ + decchars[0x65 - 0x5f] = 'L'; /* [6] "LF" as one (line feed) */ + decchars[0x66 - 0x5f] = ACS_DEGREE; /* small raised circle */ + /* [8] plus or minus sign, '+' with horizontal line below */ + decchars[0x67 - 0x5f] = ACS_PLMINUS; + decchars[0x68 - 0x5f] = 'N'; /* [9] "NL" as one char (new line) */ + decchars[0x69 - 0x5f] = 'V'; /* [10] "VT" as one (vertical tab) */ + decchars[0x6a - 0x5f] = ACS_LRCORNER; /* lower right corner */ + decchars[0x6b - 0x5f] = ACS_URCORNER; /* upper right corner */ + decchars[0x6c - 0x5f] = ACS_ULCORNER; /* upper left corner */ + decchars[0x6d - 0x5f] = ACS_LLCORNER; /* lower left corner, 'L' */ + /* [15] center cross, like big '+' sign */ + decchars[0x6e - 0x5f] = ACS_PLUS; + decchars[0x6f - 0x5f] = ACS_S1; /* very high horizontal line */ + decchars[0x70 - 0x5f] = ACS_S3; /* medium high horizontal line */ + decchars[0x71 - 0x5f] = ACS_HLINE; /* centered horizontal line */ + decchars[0x72 - 0x5f] = ACS_S7; /* medium low horizontal line */ + decchars[0x73 - 0x5f] = ACS_S9; /* very low horizontal line */ + /* [21] left tee, 'H' with right-hand vertical stroke removed; + note on left vs right: the ACS name (also DEC's terminal + documentation) refers to vertical bar rather than cross stroke, + nethack's left/right refers to direction of the cross stroke */ + decchars[0x74 - 0x5f] = ACS_LTEE; /* ACS left tee, NH right tee */ + /* [22] right tee, 'H' with left-hand vertical stroke removed */ + decchars[0x75 - 0x5f] = ACS_RTEE; /* ACS right tee, NH left tee */ + /* [23] bottom tee, '+' with lower half of vertical stroke + removed and remaining stroke pointed up (unside-down 'T'); + nethack is inconsistent here--unlike with left/right, its + bottom/top directions agree with ACS */ + decchars[0x76 - 0x5f] = ACS_BTEE; /* bottom tee, stroke up */ + /* [24] top tee, '+' with upper half of vertical stroke removed */ + decchars[0x77 - 0x5f] = ACS_TTEE; /* top tee, stroke down, 'T' */ + decchars[0x78 - 0x5f] = ACS_VLINE; /* centered vertical line */ + decchars[0x79 - 0x5f] = ACS_LEQUAL; /* less than or equal to */ + /* [27] greater than or equal to, '>' with underscore */ + decchars[0x7a - 0x5f] = ACS_GEQUAL; + /* [28] Greek pi ('n'-like; case is ambiguous: small size + suggests lower case but flat top suggests upper case) */ + decchars[0x7b - 0x5f] = ACS_PI; + /* [29] not equal sign, combination of '=' and '/' */ + decchars[0x7c - 0x5f] = ACS_NEQUAL; + /* [30] British pound sign (curly 'L' with embellishments) */ + decchars[0x7d - 0x5f] = ACS_STERLING; + decchars[0x7e - 0x5f] = ACS_BULLET; /* [31] centered dot */ + /* [32] is not used for DEC line drawing but is a potential + value for someone who assumes that 0x60..0x7f is the valid + range, so we're prepared to accept--and sanitize--it */ + decchars[0x7f - 0x5f] = '?'; + } + + /* high bit set means special handling */ + if (ch & 0x80) { + int convindx; + + ch &= ~0x80; /* force plain ASCII for last resort */ + convindx = ch - 0x5f; + /* if it's in the lower case block of ASCII (which includes + a few punctuation characters), use the conversion table */ + if (convindx >= 0 && convindx <= SIZE(decchars)) { + ch = decchars[convindx]; + /* in case ACS_foo maps to 0 when current terminal is unable + to handle a particular character; if so, revert to default + rather than using DECgr value with high bit stripped */ + if (!ch) + ch = (int) defsyms[symbol].sym; + } + } return ch; } - switch (symbol) { - case S_vwall: - return ACS_VLINE; - case S_hwall: - return ACS_HLINE; - case S_tlcorn: - return ACS_ULCORNER; - case S_trcorn: - return ACS_URCORNER; - case S_blcorn: - return ACS_LLCORNER; - case S_brcorn: - return ACS_LRCORNER; - case S_crwall: - return ACS_PLUS; - case S_tuwall: - return ACS_BTEE; - case S_tdwall: - return ACS_TTEE; - case S_tlwall: - return ACS_RTEE; - case S_trwall: - return ACS_LTEE; - case S_tree: - return ACS_PLMINUS; - case S_corr: - return ACS_CKBOARD; - case S_litcorr: - return ACS_CKBOARD; + /* + * [Is this correct? How did mapglyph() supply the value if it + * isn't coming from showsyms[]? glyph_is_cmap() test commented + * out because of the nothing-else-gets-here optimization above.] + */ + /* If user selected a custom character for this object, don't + override this. */ + if (/*glyph_is_cmap(glyph) &&*/ ch != showsyms[symbol]) { + retch = ch; + } else { + retch = (symbol >= 0 && symbol < MAXPCHARS) ? cursesglyphs[symbol] : 0; + if (!retch) + retch = ch; } - - return ch; + return retch; } diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index d76346184..9a5b8033b 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -19,7 +19,7 @@ char *curses_break_str(const char *str, int width, int line_num); char *curses_str_remainder(const char *str, int width, int line_num); boolean curses_is_menu(winid wid); boolean curses_is_text(winid wid); -int curses_convert_glyph(int ch, int glyph); +int curses_convert_glyph(boolean decgraphics, int ch, int glyph); void curses_move_cursor(winid wid, int x, int y); void curses_prehousekeeping(void); void curses_posthousekeeping(void); From 32e2d7cfc5ec367fcf12b3e6aff10bc08298d74c Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 14 Oct 2019 02:28:27 -0700 Subject: [PATCH 14/24] fix use_inverse (aka wc_inverse) for curses Highlighting for monsters shown due to extended monster detection and for lava shown in black and white didn't work because that keys off of 'iflags.use_inverse' (actually a macro for 'iflags.wc_inverse') and curses wasn't enabling that window-capability option. To be fair, it was probably unconditional at the time the curses interface was first developed. It checked for whether a monster was supposed to be drawn with inverse highlighting but wouldn't draw it that way because the flag was always false. Inverse b&w lava is relatively new and curses hadn't been taught about it. Various other things such as pets (if hilite_pet is on) and object piles (if hilite_pile is on) get highlighted with inverse video when use_color is off, regardless of whether use_inverse is on or off. That's probably a bug. --- doc/fixes36.3 | 6 +++++- src/options.c | 5 +++-- win/curses/cursinit.c | 3 +++ win/curses/cursmain.c | 8 +++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index ee3964155..2cc6a5b6e 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.132 $ $NHDT-Date: 1570872701 2019/10/12 09:31:41 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.137 $ $NHDT-Date: 1571045295 2019/10/14 09:28:15 $ 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, @@ -276,6 +276,10 @@ curses: disable the attempt to support Ctrl+Left_click as an alternate way OSX 10.11) documentation and things didn't work as intended curses: menu coloring required that both 'menucolors' and 'guicolor' be On; for menus, override guicolor with more-specific menucolors +curses: support symset:DECgraphics for map display +curses: enable the 'use_inverse' boolean option (via wincap WC_INVERSE flag) + for extended monster detection and black&white lava; forced to True + to override default of False (for tty's benefit) curses+'perm_invent': entries were wrapping without any control; usually not noticeable because next entry overwrote, but visible for final entry when whole inventory fit within the available height; looked ok with diff --git a/src/options.c b/src/options.c index 2e494948a..cc39f585b 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1567240693 2019/08/31 08:38:13 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.369 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1571045295 2019/10/14 09:28:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.376 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -826,8 +826,9 @@ initoptions_init() iflags.wc_align_message = ALIGN_TOP; iflags.wc_align_status = ALIGN_BOTTOM; - /* these are currently only used by curses */ + /* used by tty and curses */ iflags.wc2_statuslines = 2; + /* only used by curses */ iflags.wc2_windowborders = 2; /* 'Auto' */ /* since this is done before init_objects(), do partial init here */ diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 2555e71de..7c5ac185b 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -810,6 +810,9 @@ curses_init_options() */ #endif /* PDCURSES */ + /* FIXME: this overrides explicit OPTIONS=!use_inverse */ + iflags.wc_inverse = TRUE; /* aka iflags.use_inverse; default is False */ + /* fix up pet highlighting */ if (iflags.wc2_petattr == -1) /* shouldn't happen */ iflags.wc2_petattr = A_NORMAL; diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 91a5ffac1..d252b5b6d 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -29,7 +29,8 @@ extern long curs_mesg_suppress_turn; /* from cursmesg.c */ /* Interface definition, for windows.c */ struct window_procs curses_procs = { "curses", - (WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | WC_HILITE_PET + (WC_ALIGN_MESSAGE | WC_ALIGN_STATUS | WC_COLOR | WC_INVERSE + | WC_HILITE_PET #ifdef NCURSES_MOUSE_VERSION /* (this macro name works for PDCURSES too) */ | WC_MOUSE_SUPPORT #endif @@ -675,6 +676,11 @@ curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, else attr = A_REVERSE; } + /* water and lava look the same except for color; when color is off, + render lava in inverse video so that they look different */ + if ((special & MG_BW_LAVA) && iflags.use_inverse) { + attr = A_REVERSE; /* mapglyph() only sets this if color is off */ + } } curses_putch(wid, x, y, ch, color, attr); From d550a33167d9b1bf841d58a2f7ce7427e3d30595 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 14 Oct 2019 02:53:19 -0700 Subject: [PATCH 15/24] curses decgraphics bit Array bounds error; thinko rather than typo. --- win/curses/cursmisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index aed91e84c..ba3ff1bc8 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -595,7 +595,7 @@ curses_convert_glyph(boolean decgraphics, int ch, int glyph) convindx = ch - 0x5f; /* if it's in the lower case block of ASCII (which includes a few punctuation characters), use the conversion table */ - if (convindx >= 0 && convindx <= SIZE(decchars)) { + if (convindx >= 0 && convindx < SIZE(decchars)) { ch = decchars[convindx]; /* in case ACS_foo maps to 0 when current terminal is unable to handle a particular character; if so, revert to default From 7c53077eb7777dbd16d194287c23c186a36bc9e6 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 14 Oct 2019 16:02:30 -0700 Subject: [PATCH 16/24] comment typo --- win/curses/cursmisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index ba3ff1bc8..2a2dd8a7b 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -518,7 +518,7 @@ curses_convert_glyph(boolean decgraphics, int ch, int glyph) Curses remaps the characters instead. */ if (decgraphics) { /* the DEC line drawing characters use 0x5f through 0x7e instead - of the much more straightforward 0x60 though 0x7f, possibly + of the much more straightforward 0x60 through 0x7f, possibly because 0x7f is effectively a control character (Rubout); nethack ORs 0x80 to flag line drawing--that's stripped below */ static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */ From d0c4d27a507b390cc13d85a49d5876c3f2428109 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 16 Oct 2019 15:52:00 -0700 Subject: [PATCH 17/24] githib pull request #232 - curses symset This time I'm putting things in as-is before making a few tweaks. The pull request was three or four separate changes. I used the patch instead so they've been collected into one commit. --- dat/symbols | 34 +++++++ include/rm.h | 3 +- include/wincurs.h | 2 +- src/drawing.c | 1 + src/options.c | 4 + win/curses/cursinit.c | 5 + win/curses/cursmain.c | 4 +- win/curses/cursmisc.c | 224 +++++++++++++++++------------------------- win/curses/cursmisc.h | 2 +- 9 files changed, 137 insertions(+), 142 deletions(-) diff --git a/dat/symbols b/dat/symbols index be27dad5d..364c6db21 100644 --- a/dat/symbols +++ b/dat/symbols @@ -15,6 +15,11 @@ # NetHack encodes the request to use the alternate font here by # having the high bit set (in hexadecimal, \x80 is combined with # a character code between \x60 and \x7f). +# +# curses is an approximation of IBMgraphics which relies on DEC +# mode of operation, with a few characters missing. It is based +# on an old graphics mode for the Curses mode and is the default +# on that windowport if no symset is specified. start: DECgraphics Handling: DEC @@ -55,6 +60,35 @@ start: DECgraphics S_explode8: \xf3 # meta-s, low horizontal line finish +start: curses + Handling: DEC + S_vwall: \xf8 # meta-x, vertical rule + S_hwall: \xf1 # meta-q, horizontal rule + S_tlcorn: \xec # meta-l, top left corner + S_trcorn: \xeb # meta-k, top right corner + S_blcorn: \xed # meta-m, bottom left + S_brcorn: \xea # meta-j, bottom right + S_crwall: \xee # meta-n, cross + S_tuwall: \xf6 # meta-v, T up + S_tdwall: \xf7 # meta-w, T down + S_tlwall: \xf5 # meta-u, T left + S_trwall: \xf4 # meta-t, T right + S_ndoor: \xfe # meta-z, centered dot + S_tree: \xf1 # plus or minus symbol + S_room: \xfe # meta-z, centered dot + S_corr: \xe1 # meta-a, solid block + S_litcorr: \xe1 # meta-a, solid block + S_ice: \xfe # meta-z, centered dot + S_vodbridge: \xfe # meta-z, centered dot + S_hodbridge: \xfe # meta-z, centered dot + S_vbeam: \xf8 # meta-3, vertical rule + S_hbeam: \xf1 # meta-D, horizontal rule + S_sw_ml: \xf8 # meta-3, vertical rule + S_sw_mr: \xf8 # meta-3, vertical rule + S_explode4: \xf8 # meta-3, vertical rule + S_explode6: \xf8 # meta-3, vertical rule +finish + start: IBMgraphics Handling: IBM S_vwall: \xb3 # meta-3, vertical rule diff --git a/include/rm.h b/include/rm.h index 1190a355b..becdd21a0 100644 --- a/include/rm.h +++ b/include/rm.h @@ -278,7 +278,8 @@ struct symsetentry { Bitfield(nocolor, 1); /* don't use color if set */ Bitfield(primary, 1); /* restricted for use as primary set */ Bitfield(rogue, 1); /* restricted for use as rogue lev set */ - /* 5 free bits */ + Bitfield(fallback, 1); /* no explicit symset set */ + /* 4 free bits */ }; /* diff --git a/include/wincurs.h b/include/wincurs.h index c7d16f9e5..8ae45e10e 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -152,7 +152,7 @@ extern char *curses_break_str(const char *str, int width, int line_num); extern char *curses_str_remainder(const char *str, int width, int line_num); extern boolean curses_is_menu(winid wid); extern boolean curses_is_text(winid wid); -extern int curses_convert_glyph(boolean decgraphics, int ch, int glyph); +extern int curses_convert_glyph(int ch, int glyph); extern void curses_move_cursor(winid wid, int x, int y); extern void curses_prehousekeeping(void); extern void curses_posthousekeeping(void); diff --git a/src/drawing.c b/src/drawing.c index e9a1e08e1..f29dbf3a2 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -543,6 +543,7 @@ boolean name_too; /* initialize restriction bits */ symset[which_set].primary = 0; symset[which_set].rogue = 0; + symset[which_set].fallback = TRUE; if (name_too) { if (symset[which_set].name) diff --git a/src/options.c b/src/options.c index cc39f585b..220f8f483 100644 --- a/src/options.c +++ b/src/options.c @@ -2315,6 +2315,7 @@ boolean tinitial, tfrom_file; } else { if (!initial && Is_rogue_level(&u.uz)) assign_graphics(ROGUESET); + symset[ROGUESET].fallback = FALSE; need_redraw = TRUE; } } else @@ -2339,6 +2340,7 @@ boolean tinitial, tfrom_file; return FALSE; } else { switch_symbols(symset[PRIMARY].name != (char *) 0); + symset[PRIMARY].fallback = FALSE; need_redraw = TRUE; } } else @@ -6008,8 +6010,10 @@ int which_set; if (read_sym_file(which_set)) { switch_symbols(TRUE); + symset[which_set].fallback = FALSE; } else { clear_symsetentry(which_set, TRUE); + symset[which_set].fallback = TRUE; return 0; } return 1; diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 7c5ac185b..773334855 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -784,6 +784,11 @@ curses_init_options() /* Remove a few options that are irrelevant to this windowport */ set_option_mod_status("eight_bit_tty", SET_IN_FILE); + /* If we don't have a symset defined, load the curses symset by default */ + if (symset[PRIMARY].fallback) { + load_symset("curses", PRIMARY); + load_symset("default", ROGUESET); + } #ifdef PDCURSES /* PDCurses for SDL, win32 and OS/2 has the ability to set the terminal size programatically. If the user does not specify a diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index d252b5b6d..e0b69b42c 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -660,9 +660,7 @@ curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, attr = A_REVERSE; } if (SYMHANDLING(H_DEC)) - ch = curses_convert_glyph(TRUE, ch, glyph); - else if (!symset[PRIMARY].name || !strcmpi(symset[PRIMARY].name, "curses")) - ch = curses_convert_glyph(FALSE, ch, glyph); + ch = curses_convert_glyph(ch, glyph); if (wid == NHW_MAP) { /* hilite stairs not in 3.6, yet diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 2a2dd8a7b..df3316679 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -74,7 +74,7 @@ curses_read_char() #ifdef KEY_RESIZE /* Handle resize events via get_nh_event, not this code */ if (ch == KEY_RESIZE) { - ch = '\033'; /* NetHack doesn't know what to do with KEY_RESIZE */ + ch = C('r'); /* NetHack doesn't know what to do with KEY_RESIZE */ } #endif @@ -467,161 +467,113 @@ curses_is_text(winid wid) cursesgraphics option is enabled, or special curses handling for DECgraphics */ int -curses_convert_glyph(boolean decgraphics, int ch, int glyph) +curses_convert_glyph(int ch, int glyph) { - static int cursesglyphs[MAXPCHARS], cursesglyphsinited = 0; int retch, symbol; /* FIXME? we don't support any special characters in roguesymset */ if (Is_rogue_level(&u.uz)) return ch; - /* Save some processing time by returning if the glyph represents - an object that we don't have custom characters for */ - if (!glyph_is_cmap(glyph)) - return ch; - symbol = glyph_to_cmap(glyph); - /* - * FIXME: - * 'cursesgraphics' should be a symbol set so that users can - * modify it without having to edit this source file and rebuild - * the program. Unfortunately these ACS values are 32-bit ones - * and not user-friendly. - */ - if (!cursesglyphsinited) { /* one-time initialization */ - cursesglyphsinited = 1; - cursesglyphs[S_vwall] = ACS_VLINE; - cursesglyphs[S_hwall] = ACS_HLINE; - cursesglyphs[S_tlcorn] = ACS_ULCORNER; - cursesglyphs[S_trcorn] = ACS_URCORNER; - cursesglyphs[S_blcorn] = ACS_LLCORNER; - cursesglyphs[S_brcorn] = ACS_LRCORNER; - cursesglyphs[S_crwall] = ACS_PLUS; - cursesglyphs[S_tuwall] = ACS_BTEE; - cursesglyphs[S_tdwall] = ACS_TTEE; - /* yes, the left/right Ts are inverted nethack vs curses */ - cursesglyphs[S_tlwall] = ACS_RTEE; - cursesglyphs[S_trwall] = ACS_LTEE; - cursesglyphs[S_tree] = ACS_PLMINUS; - cursesglyphs[S_corr] = ACS_CKBOARD; - cursesglyphs[S_litcorr] = ACS_CKBOARD; - } - /* Curses has complete access to all characters that DECgraphics uses. However, their character value isn't consistent between terminals and implementations. For actual DEC terminals and faithful emulators, line-drawing characters are specified as lowercase letters (mostly) and a control code is sent to the terminal telling it to switch character sets (that's how the tty interface handles them). - Curses remaps the characters instead. */ - if (decgraphics) { - /* the DEC line drawing characters use 0x5f through 0x7e instead - of the much more straightforward 0x60 through 0x7f, possibly - because 0x7f is effectively a control character (Rubout); - nethack ORs 0x80 to flag line drawing--that's stripped below */ - static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */ + Curses remaps the characters instead. - /* one-time initialization; some ACS_x aren't compile-time constant */ - if (!decchars[0]) { - /* [0] is non-breakable space; irrelevant to nethack */ - decchars[0x5f - 0x5f] = ' '; /* NBSP */ - decchars[0x60 - 0x5f] = ACS_DIAMOND; /* [1] solid diamond */ - decchars[0x61 - 0x5f] = ACS_CKBOARD; /* [2] checkerboard */ - /* several "line drawing" characters are two-letter glyphs - which could be substituted for invisible control codes; - nethack's DECgraphics doesn't use any of them so we're - satisfied with conversion to a simple letter; - [3] "HT" as one char, with small raised upper case H over - and/or preceding small lowered upper case T */ - decchars[0x62 - 0x5f] = 'H'; /* "HT" (horizontal tab) */ - decchars[0x63 - 0x5f] = 'F'; /* "FF" as one char (form feed) */ - decchars[0x64 - 0x5f] = 'C'; /* "CR" as one (carriage return) */ - decchars[0x65 - 0x5f] = 'L'; /* [6] "LF" as one (line feed) */ - decchars[0x66 - 0x5f] = ACS_DEGREE; /* small raised circle */ - /* [8] plus or minus sign, '+' with horizontal line below */ - decchars[0x67 - 0x5f] = ACS_PLMINUS; - decchars[0x68 - 0x5f] = 'N'; /* [9] "NL" as one char (new line) */ - decchars[0x69 - 0x5f] = 'V'; /* [10] "VT" as one (vertical tab) */ - decchars[0x6a - 0x5f] = ACS_LRCORNER; /* lower right corner */ - decchars[0x6b - 0x5f] = ACS_URCORNER; /* upper right corner */ - decchars[0x6c - 0x5f] = ACS_ULCORNER; /* upper left corner */ - decchars[0x6d - 0x5f] = ACS_LLCORNER; /* lower left corner, 'L' */ - /* [15] center cross, like big '+' sign */ - decchars[0x6e - 0x5f] = ACS_PLUS; - decchars[0x6f - 0x5f] = ACS_S1; /* very high horizontal line */ - decchars[0x70 - 0x5f] = ACS_S3; /* medium high horizontal line */ - decchars[0x71 - 0x5f] = ACS_HLINE; /* centered horizontal line */ - decchars[0x72 - 0x5f] = ACS_S7; /* medium low horizontal line */ - decchars[0x73 - 0x5f] = ACS_S9; /* very low horizontal line */ - /* [21] left tee, 'H' with right-hand vertical stroke removed; - note on left vs right: the ACS name (also DEC's terminal - documentation) refers to vertical bar rather than cross stroke, - nethack's left/right refers to direction of the cross stroke */ - decchars[0x74 - 0x5f] = ACS_LTEE; /* ACS left tee, NH right tee */ - /* [22] right tee, 'H' with left-hand vertical stroke removed */ - decchars[0x75 - 0x5f] = ACS_RTEE; /* ACS right tee, NH left tee */ - /* [23] bottom tee, '+' with lower half of vertical stroke - removed and remaining stroke pointed up (unside-down 'T'); - nethack is inconsistent here--unlike with left/right, its - bottom/top directions agree with ACS */ - decchars[0x76 - 0x5f] = ACS_BTEE; /* bottom tee, stroke up */ - /* [24] top tee, '+' with upper half of vertical stroke removed */ - decchars[0x77 - 0x5f] = ACS_TTEE; /* top tee, stroke down, 'T' */ - decchars[0x78 - 0x5f] = ACS_VLINE; /* centered vertical line */ - decchars[0x79 - 0x5f] = ACS_LEQUAL; /* less than or equal to */ - /* [27] greater than or equal to, '>' with underscore */ - decchars[0x7a - 0x5f] = ACS_GEQUAL; - /* [28] Greek pi ('n'-like; case is ambiguous: small size - suggests lower case but flat top suggests upper case) */ - decchars[0x7b - 0x5f] = ACS_PI; - /* [29] not equal sign, combination of '=' and '/' */ - decchars[0x7c - 0x5f] = ACS_NEQUAL; - /* [30] British pound sign (curly 'L' with embellishments) */ - decchars[0x7d - 0x5f] = ACS_STERLING; - decchars[0x7e - 0x5f] = ACS_BULLET; /* [31] centered dot */ - /* [32] is not used for DEC line drawing but is a potential - value for someone who assumes that 0x60..0x7f is the valid - range, so we're prepared to accept--and sanitize--it */ - decchars[0x7f - 0x5f] = '?'; - } + The DEC line drawing characters use 0x5f through 0x7e instead + of the much more straightforward 0x60 through 0x7f, possibly + because 0x7f is effectively a control character (Rubout); + nethack ORs 0x80 to flag line drawing--that's stripped below */ + static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */ - /* high bit set means special handling */ - if (ch & 0x80) { - int convindx; - - ch &= ~0x80; /* force plain ASCII for last resort */ - convindx = ch - 0x5f; - /* if it's in the lower case block of ASCII (which includes - a few punctuation characters), use the conversion table */ - if (convindx >= 0 && convindx < SIZE(decchars)) { - ch = decchars[convindx]; - /* in case ACS_foo maps to 0 when current terminal is unable - to handle a particular character; if so, revert to default - rather than using DECgr value with high bit stripped */ - if (!ch) - ch = (int) defsyms[symbol].sym; - } - } - return ch; + /* one-time initialization; some ACS_x aren't compile-time constant */ + if (!decchars[0]) { + /* [0] is non-breakable space; irrelevant to nethack */ + decchars[0x5f - 0x5f] = ' '; /* NBSP */ + decchars[0x60 - 0x5f] = ACS_DIAMOND; /* [1] solid diamond */ + decchars[0x61 - 0x5f] = ACS_CKBOARD; /* [2] checkerboard */ + /* several "line drawing" characters are two-letter glyphs + which could be substituted for invisible control codes; + nethack's DECgraphics doesn't use any of them so we're + satisfied with conversion to a simple letter; + [3] "HT" as one char, with small raised upper case H over + and/or preceding small lowered upper case T */ + decchars[0x62 - 0x5f] = 'H'; /* "HT" (horizontal tab) */ + decchars[0x63 - 0x5f] = 'F'; /* "FF" as one char (form feed) */ + decchars[0x64 - 0x5f] = 'C'; /* "CR" as one (carriage return) */ + decchars[0x65 - 0x5f] = 'L'; /* [6] "LF" as one (line feed) */ + decchars[0x66 - 0x5f] = ACS_DEGREE; /* small raised circle */ + /* [8] plus or minus sign, '+' with horizontal line below */ + decchars[0x67 - 0x5f] = ACS_PLMINUS; + decchars[0x68 - 0x5f] = 'N'; /* [9] "NL" as one char (new line) */ + decchars[0x69 - 0x5f] = 'V'; /* [10] "VT" as one (vertical tab) */ + decchars[0x6a - 0x5f] = ACS_LRCORNER; /* lower right corner */ + decchars[0x6b - 0x5f] = ACS_URCORNER; /* upper right corner */ + decchars[0x6c - 0x5f] = ACS_ULCORNER; /* upper left corner */ + decchars[0x6d - 0x5f] = ACS_LLCORNER; /* lower left corner, 'L' */ + /* [15] center cross, like big '+' sign */ + decchars[0x6e - 0x5f] = ACS_PLUS; + decchars[0x6f - 0x5f] = ACS_S1; /* very high horizontal line */ + decchars[0x70 - 0x5f] = ACS_S3; /* medium high horizontal line */ + decchars[0x71 - 0x5f] = ACS_HLINE; /* centered horizontal line */ + decchars[0x72 - 0x5f] = ACS_S7; /* medium low horizontal line */ + decchars[0x73 - 0x5f] = ACS_S9; /* very low horizontal line */ + /* [21] left tee, 'H' with right-hand vertical stroke removed; + note on left vs right: the ACS name (also DEC's terminal + documentation) refers to vertical bar rather than cross stroke, + nethack's left/right refers to direction of the cross stroke */ + decchars[0x74 - 0x5f] = ACS_LTEE; /* ACS left tee, NH right tee */ + /* [22] right tee, 'H' with left-hand vertical stroke removed */ + decchars[0x75 - 0x5f] = ACS_RTEE; /* ACS right tee, NH left tee */ + /* [23] bottom tee, '+' with lower half of vertical stroke + removed and remaining stroke pointed up (unside-down 'T'); + nethack is inconsistent here--unlike with left/right, its + bottom/top directions agree with ACS */ + decchars[0x76 - 0x5f] = ACS_BTEE; /* bottom tee, stroke up */ + /* [24] top tee, '+' with upper half of vertical stroke removed */ + decchars[0x77 - 0x5f] = ACS_TTEE; /* top tee, stroke down, 'T' */ + decchars[0x78 - 0x5f] = ACS_VLINE; /* centered vertical line */ + decchars[0x79 - 0x5f] = ACS_LEQUAL; /* less than or equal to */ + /* [27] greater than or equal to, '>' with underscore */ + decchars[0x7a - 0x5f] = ACS_GEQUAL; + /* [28] Greek pi ('n'-like; case is ambiguous: small size + suggests lower case but flat top suggests upper case) */ + decchars[0x7b - 0x5f] = ACS_PI; + /* [29] not equal sign, combination of '=' and '/' */ + decchars[0x7c - 0x5f] = ACS_NEQUAL; + /* [30] British pound sign (curly 'L' with embellishments) */ + decchars[0x7d - 0x5f] = ACS_STERLING; + decchars[0x7e - 0x5f] = ACS_BULLET; /* [31] centered dot */ + /* [32] is not used for DEC line drawing but is a potential + value for someone who assumes that 0x60..0x7f is the valid + range, so we're prepared to accept--and sanitize--it */ + decchars[0x7f - 0x5f] = '?'; } - /* - * [Is this correct? How did mapglyph() supply the value if it - * isn't coming from showsyms[]? glyph_is_cmap() test commented - * out because of the nothing-else-gets-here optimization above.] - */ - /* If user selected a custom character for this object, don't - override this. */ - if (/*glyph_is_cmap(glyph) &&*/ ch != showsyms[symbol]) { - retch = ch; - } else { - retch = (symbol >= 0 && symbol < MAXPCHARS) ? cursesglyphs[symbol] : 0; - if (!retch) - retch = ch; + /* high bit set means special handling */ + if (ch & 0x80) { + int convindx; + + ch &= ~0x80; /* force plain ASCII for last resort */ + convindx = ch - 0x5f; + /* if it's in the lower case block of ASCII (which includes + a few punctuation characters), use the conversion table */ + if (convindx >= 0 && convindx < SIZE(decchars)) { + ch = decchars[convindx]; + /* in case ACS_foo maps to 0 when current terminal is unable + to handle a particular character; if so, revert to default + rather than using DECgr value with high bit stripped */ + if (!ch) + ch = (int) defsyms[symbol].sym; + } } - return retch; + + return ch; } diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index 9a5b8033b..d76346184 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -19,7 +19,7 @@ char *curses_break_str(const char *str, int width, int line_num); char *curses_str_remainder(const char *str, int width, int line_num); boolean curses_is_menu(winid wid); boolean curses_is_text(winid wid); -int curses_convert_glyph(boolean decgraphics, int ch, int glyph); +int curses_convert_glyph(int ch, int glyph); void curses_move_cursor(winid wid, int x, int y); void curses_prehousekeeping(void); void curses_posthousekeeping(void); From 33d33fcf193ec0a187df7c25a3c717d044cf737b Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 16 Oct 2019 16:19:51 -0700 Subject: [PATCH 18/24] fix curses build warning and update fixes36.3 Move a declaration that became mid-block when a preceding 'if () {' got removed to top of block suppress warning about C99 feature. Add new entry for the curses symset change to fixes36.3. --- doc/fixes36.3 | 5 ++++- win/curses/cursmisc.c | 19 ++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 2cc6a5b6e..809ddab65 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.137 $ $NHDT-Date: 1571045295 2019/10/14 09:28:15 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.138 $ $NHDT-Date: 1571267989 2019/10/16 23:19:49 $ 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, @@ -346,6 +346,9 @@ curses: give menus and text windows a minimum size of 5x25 since tiny ones can curses+'perm_invent': since persistent inventory is narrow, strip off "a", "an", or "the" prefix on inventory entries shown there so that a tiny bit more of the interesting portion is visible +curses+'curses': change the curses map display to use new symbol set 'curses' + instead of hard-coded values; it attempts to show IBMgraphics-style + map using DECgraphics characters; DECgraphics can also be used as-is NetHack Community Patches (or Variation) Included diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index df3316679..ab6a3bd45 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -463,13 +463,16 @@ curses_is_text(winid wid) } } -/* Replace certain characters with portable drawing characters if - cursesgraphics option is enabled, or special curses handling for - DECgraphics */ +/* convert nethack's DECgraphics encoding into curses' ACS encoding */ int curses_convert_glyph(int ch, int glyph) { - int retch, symbol; + /* The DEC line drawing characters use 0x5f through 0x7e instead + of the much more straightforward 0x60 through 0x7f, possibly + because 0x7f is effectively a control character (Rubout); + nethack ORs 0x80 to flag line drawing--that's stripped below */ + static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */ + int symbol; /* FIXME? we don't support any special characters in roguesymset */ if (Is_rogue_level(&u.uz)) @@ -483,13 +486,7 @@ curses_convert_glyph(int ch, int glyph) line-drawing characters are specified as lowercase letters (mostly) and a control code is sent to the terminal telling it to switch character sets (that's how the tty interface handles them). - Curses remaps the characters instead. - - The DEC line drawing characters use 0x5f through 0x7e instead - of the much more straightforward 0x60 through 0x7f, possibly - because 0x7f is effectively a control character (Rubout); - nethack ORs 0x80 to flag line drawing--that's stripped below */ - static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */ + Curses remaps the characters instead. */ /* one-time initialization; some ACS_x aren't compile-time constant */ if (!decchars[0]) { From 3e368b9a51c496ab2ae35c247fa7d0e23aeafe66 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Oct 2019 05:00:58 -0700 Subject: [PATCH 19/24] symbol set reorganization Change the way symbol sets are loaded to make them have the same order as they appear in the symbols file rather than being reversed. Revise dat/symbols so that the new ordering yields a result similar to the old ordering, more or less. I've added a few set descriptions. The only substantive change is marking DECgraphics as primary-only (not available on rogue level) and adding new set DECgraphics_2 which is commented out near the end. Define symbol handling H_MAC since one of the sets specifies 'handling: MAC'. All H_MAC is used for now is to avoid showing MACgraphics as a symset when compiled without MAC_GRAPHICS_ENV (which was used for pre-OSX Mac by the old code in sys/mac/), so it will be hidden for everyone. I left handling H_CURS even though curses doesn't implement anything for it. It could do something when rendering the map or assign a function to 'cursesgraphics_mode_callback' for special init or both but hasn't needed to. Since curses is now supporting DECgraphics, define 'decgraphics_mode_callback' for it. No value is being assigned so that doesn't do anything; curses seems to be setting up the primary character set as text and secondary one as line-drawing without the need for that hook. With the added set descriptions, 'O's symset menu looked horrible for curses due to the way curses decides to set the width of menus and the resulting line wrapping which took place because of a too-narrow menu. I've added a chunk of code to the options handling code which shouldn't really be there but makes the menu much easier to read. Lastly, do some formatting cleanup in files.c. --- dat/symbols | 712 ++++++++++++++++++++++++++------------------------ doc/fixes36.3 | 6 +- include/rm.h | 4 +- src/drawing.c | 18 +- src/files.c | 37 ++- src/options.c | 61 ++++- 6 files changed, 474 insertions(+), 364 deletions(-) diff --git a/dat/symbols b/dat/symbols index 364c6db21..8e8a6349f 100644 --- a/dat/symbols +++ b/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.6 symbols $NHDT-Date: 1570919632 2019/10/12 22:33:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.17 $ +# NetHack 3.6 symbols $NHDT-Date: 1571313649 2019/10/17 12:00:49 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.19 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -14,325 +14,35 @@ # of ordinary printable characters in the lowercase letter range. # NetHack encodes the request to use the alternate font here by # having the high bit set (in hexadecimal, \x80 is combined with -# a character code between \x60 and \x7f). +# a character code between \x5f and \x7e) (not 0x60 to 0x7f as was +# previously claimed). # # curses is an approximation of IBMgraphics which relies on DEC -# mode of operation, with a few characters missing. It is based -# on an old graphics mode for the Curses mode and is the default -# on that windowport if no symset is specified. +# mode of operation, with a few characters missing. It is based +# on an old graphics mode for the Curses interface and is the default +# on that windowport if no symset is specified. The Curses interface +# can also use DECgraphics as-is; IBMgraphics probably won't work. -start: DECgraphics - Handling: DEC - S_vwall: \xf8 # meta-x, vertical rule - S_hwall: \xf1 # meta-q, horizontal rule - S_tlcorn: \xec # meta-l, top left corner - S_trcorn: \xeb # meta-k, top right corner - S_blcorn: \xed # meta-m, bottom left - S_brcorn: \xea # meta-j, bottom right - S_crwall: \xee # meta-n, cross - S_tuwall: \xf6 # meta-v, T up - S_tdwall: \xf7 # meta-w, T down - S_tlwall: \xf5 # meta-u, T left - S_trwall: \xf4 # meta-t, T right - S_ndoor: \xfe # meta-~, centered dot - S_vodoor: \xe1 # meta-a, solid block - S_hodoor: \xe1 # meta-a, solid block - S_bars: \xfb # meta-{, small pi - S_tree: \xe7 # meta-g, plus-or-minus - S_room: \xfe # meta-~, centered dot - S_upladder: \xf9 # meta-y, less-than-or-equals - S_dnladder: \xfa # meta-z, greater-than-or-equals - S_pool: \xe0 # meta-\, diamond - S_ice: \xfe # meta-~, centered dot - S_lava: \xe0 # meta-\, diamond - S_vodbridge: \xfe # meta-~, centered dot - S_hodbridge: \xfe # meta-~, centered dot - S_water: \xe0 # meta-\, diamond - S_vbeam: \xf8 # meta-x, vertical rule - S_hbeam: \xf1 # meta-q, horizontal rule - S_sw_tc: \xef # meta-o, high horizontal line - S_sw_ml: \xf8 # meta-x, vertical rule - S_sw_mr: \xf8 # meta-x, vertical rule - S_sw_bc: \xf3 # meta-s, low horizontal line - S_explode2: \xef # meta-o, high horizontal line - S_explode4: \xf8 # meta-x, vertical rule - S_explode6: \xf8 # meta-x, vertical rule - S_explode8: \xf3 # meta-s, low horizontal line -finish +# plain looks decent for wall+corridor levels where there aren't a lot +# of room corners and ones present tend to be spread out, but it looks +# awful for wallified mazes +start: plain + Description: same as default symbols, except '+' for corner walls + S_tlcorn: '+' + S_trcorn: '+' + S_blcorn: '+' + S_brcorn: '+' + S_crwall: '+' + S_tuwall: '+' + S_tdwall: '+' + S_tlwall: '+' + S_trwall: '+' +finish #plain -- other symbols implicitly retain their default values -start: curses - Handling: DEC - S_vwall: \xf8 # meta-x, vertical rule - S_hwall: \xf1 # meta-q, horizontal rule - S_tlcorn: \xec # meta-l, top left corner - S_trcorn: \xeb # meta-k, top right corner - S_blcorn: \xed # meta-m, bottom left - S_brcorn: \xea # meta-j, bottom right - S_crwall: \xee # meta-n, cross - S_tuwall: \xf6 # meta-v, T up - S_tdwall: \xf7 # meta-w, T down - S_tlwall: \xf5 # meta-u, T left - S_trwall: \xf4 # meta-t, T right - S_ndoor: \xfe # meta-z, centered dot - S_tree: \xf1 # plus or minus symbol - S_room: \xfe # meta-z, centered dot - S_corr: \xe1 # meta-a, solid block - S_litcorr: \xe1 # meta-a, solid block - S_ice: \xfe # meta-z, centered dot - S_vodbridge: \xfe # meta-z, centered dot - S_hodbridge: \xfe # meta-z, centered dot - S_vbeam: \xf8 # meta-3, vertical rule - S_hbeam: \xf1 # meta-D, horizontal rule - S_sw_ml: \xf8 # meta-3, vertical rule - S_sw_mr: \xf8 # meta-3, vertical rule - S_explode4: \xf8 # meta-3, vertical rule - S_explode6: \xf8 # meta-3, vertical rule -finish - -start: IBMgraphics - Handling: IBM - S_vwall: \xb3 # meta-3, vertical rule - S_hwall: \xc4 # meta-D, horizontal rule - S_tlcorn: \xda # meta-Z, top left corner - S_trcorn: \xbf # meta-?, top right corner - S_blcorn: \xc0 # meta-@, bottom left - S_brcorn: \xd9 # meta-Y, bottom right - S_crwall: \xc5 # meta-E, cross - S_tuwall: \xc1 # meta-A, T up - S_tdwall: \xc2 # meta-B, T down - S_tlwall: \xb4 # meta-4, T left - S_trwall: \xc3 # meta-C, T right - S_ndoor: \xfa # meta-z, centered dot - S_vodoor: \xfe # meta-~, small centered square - S_hodoor: \xfe # meta-~, small centered square - S_bars: \xf0 # equivalence symbol - S_tree: \xf1 # plus or minus symbol - S_room: \xfa # meta-z, centered dot - S_corr: \xb0 # meta-0, light shading - S_litcorr: \xb1 # meta-1, medium shading - S_fountain: \xf4 # meta-t, integral top half - S_pool: \xf7 # meta-w, approx. equals - S_ice: \xfa # meta-z, centered dot - S_lava: \xf7 # meta-w, approx. equals - S_vodbridge: \xfa # meta-z, centered dot - S_hodbridge: \xfa # meta-z, centered dot - S_water: \xf7 # meta-w, approx. equals - S_vbeam: \xb3 # meta-3, vertical rule - S_hbeam: \xc4 # meta-D, horizontal rule - S_sw_ml: \xb3 # meta-3, vertical rule - S_sw_mr: \xb3 # meta-3, vertical rule - S_explode4: \xb3 # meta-3, vertical rule - S_explode6: \xb3 # meta-3, vertical rule -finish - -start: IBMGraphics_1 - Handling: IBM - S_vwall: \xb3 # meta-3, vertical rule - S_hwall: \xc4 # meta-D, horizontal rule - S_tlcorn: \xda # meta-Z, top left corner - S_trcorn: \xbf # meta-?, top right corner - S_blcorn: \xc0 # meta-@, bottom left - S_brcorn: \xd9 # meta-Y, bottom right - S_crwall: \xc5 # meta-E, cross - S_tuwall: \xc1 # meta-A, T up - S_tdwall: \xc2 # meta-B, T down - S_tlwall: \xb4 # meta-4, T left - S_trwall: \xc3 # meta-C, T right - S_vbeam: \xb3 # meta-3, vertical rule - S_hbeam: \xc4 # meta-D, horizontal rule - S_sw_ml: \xb3 # meta-3, vertical rule - S_sw_mr: \xb3 # meta-3, vertical rule - S_explode4: \xb3 # meta-3, vertical rule - S_explode6: \xb3 # meta-3, vertical rule -finish - -start: IBMGraphics_2 - Handling: IBM - S_vwall: \xb3 # meta-3, vertical rule - S_hwall: \xc4 # meta-D, horizontal rule - S_tlcorn: \xda # meta-Z, top left corner - S_trcorn: \xbf # meta-?, top right corner - S_blcorn: \xc0 # meta-@, bottom left - S_brcorn: \xd9 # meta-Y, bottom right - S_crwall: \xc5 # meta-E, cross - S_tuwall: \xc1 # meta-A, T up - S_tdwall: \xc2 # meta-B, T down - S_tlwall: \xb4 # meta-4, T left - S_trwall: \xc3 # meta-C, T right - S_vodoor: \xfe # meta-~, small centered square - S_hodoor: \xfe # meta-~, small centered square - S_corr: \xb0 # meta-0, light shading - S_litcorr: \xb1 # meta-1, medium shading - S_vbeam: \xb3 # meta-3, vertical rule - S_hbeam: \xc4 # meta-D, horizontal rule - S_sw_ml: \xb3 # meta-3, vertical rule - S_sw_mr: \xb3 # meta-3, vertical rule - S_explode4: \xb3 # meta-3, vertical rule - S_explode6: \xb3 # meta-3, vertical rule -finish - -start: MACgraphics - Handling: MAC - S_vwall: \xba - S_hwall: \xcd - S_tlcorn: \xc9 - S_trcorn: \xbb - S_blcorn: \xc8 - S_brcorn: \xbc - S_crwall: \xce - S_tuwall: \xca - S_tdwall: \xcb - S_tlwall: \xb9 - S_trwall: \xcc - S_ndoor: \xb0 - S_vodoor: \xee - S_hodoor: \xee - S_vcdoor: \xef - S_hcdoor: \xef - S_bars: \xf0 # equivalency symbol - S_tree: \xf1 # plus-or-minus - S_corr: \xb0 - S_grave: \xef # same as open door - S_pool: \xe0 -finish - -start: RogueIBM - Handling: IBM - Restrictions: rogue - S_weapon: \x29 - S_amulet: \x2c - S_food: \x3a - S_potion: \xad - S_scroll: \x3f - S_book: \x2b - S_wand: \xe7 - S_vwall: \xba # all walls now use - S_hwall: \xcd # double line graphics - S_tlcorn: \xc9 - S_trcorn: \xbb - S_blcorn: \xc8 - S_brcorn: \xbc - S_crwall: \xce - S_tuwall: \xca - S_tdwall: \xcb - S_tlwall: \xb9 - S_trwall: \xcc - S_ndoor: \xce - S_vodoor: \xce - S_hodoor: \xce - S_room: \xfa # centered dot - S_corr: \xb1 - S_litcorr: \xb2 - S_upstair: \xf0 # Greek Xi - S_dnstair: \xf0 -finish - -start: RogueEpyx - Description: Rogue level color symbol set like Epyx Rogue - Restrictions: rogue - Handling: IBM - Color: Yes - S_vwall: \xba # all walls now use - S_hwall: \xcd # double line graphics - S_tlcorn: \xc9 - S_trcorn: \xbb - S_blcorn: \xc8 - S_brcorn: \xbc - S_crwall: \xce - S_tuwall: \xca - S_tdwall: \xcb - S_tlwall: \xb9 - S_trwall: \xcc - S_ndoor: \xce - S_vodoor: \xce - S_hodoor: \xce - S_room: \xfa # centered dot - S_corr: \xb1 - S_litcorr: \xb2 - S_upstair: \xf0 # Greek Xi - S_dnstair: \xf0 - S_arrow_trap: \x04 # diamond (cards) - S_dart_trap: \x04 - S_falling_rock_trap: \x04 - S_squeaky_board: \x04 - S_bear_trap: \x04 - S_land_mine: \x04 - S_rolling_boulder_trap: \x04 - S_sleeping_gas_trap: \x04 - S_rust_trap: \x04 - S_fire_trap: \x04 - S_pit: \x04 - S_spiked_pit: \x04 - S_hole: \x04 - S_trap_door: \x04 - S_teleportation_trap: \x04 - S_level_teleporter: \x04 - S_magic_portal: \x04 - S_web: \x04 - S_statue_trap: \x04 - S_magic_trap: \x04 - S_anti_magic_trap: \x04 - S_polymorph_trap: \x04 - S_weapon: \x18 # up arrow -# ^J S_armor: \x0a # Vert rect with o - S_armor: \x5b # default: '[' -# ^I S_ring: \x09 # circle with arrow - S_ring: \x3d # default: '=' - S_amulet: \x0c # "female" symbol - S_tool: \x28 # default: '(' - S_food: \x05 # club (as in cards) - S_potion: \xad # upside down '!' - S_scroll: \x0e # musical note - S_book: \x2b # default: '+' - S_wand: \xe7 # greek tau - S_coin: \x0f # yes it's the same as gems - S_gem: \x0f # fancy '*' - S_rock: \x60 - S_ball: \x30 - S_chain: \x5f - S_venom: \x2e - S_rock: \x60 - S_ball: \x30 - S_chain: \x5f - S_venom: \x2e - S_human: \x01 -finish - -start: RogueWindows - Restrictions: rogue - Handling: IBM - S_weapon: \x29 - S_amulet: \x2c - S_food: \x3a - S_potion: \xad - S_scroll: \x3f - S_book: \x2b - S_wand: \xe7 - S_vwall: \xba # all walls now use - S_hwall: \xcd # double line graphics - S_tlcorn: \xc9 - S_trcorn: \xbb - S_blcorn: \xc8 - S_brcorn: \xbc - S_crwall: \xce - S_tuwall: \xca - S_tdwall: \xcb - S_tlwall: \xb9 - S_trwall: \xcc - S_ndoor: \xce - S_vodoor: \xce - S_hodoor: \xce - S_room: \xfa # centered dot - S_corr: \xb1 - S_litcorr: \xb2 - S_upstair: \xf0 # Greek Xi - S_dnstair: \xf0 -finish - -# Recommended symset for blind players +# Recommended symset for blind players # courtesy Michael Feir start: NHAccess - Description: Recommended for blind players + Description: recommended for blind players S_stone: \032 S_vwall: \124 S_hwall: \045 @@ -342,7 +52,7 @@ start: NHAccess S_brcorn: \124 S_crwall: \045 S_tuwall: \045 - S_tdwall: \045 + S_tdwall: \045 S_tlwall: \124 S_trwall: \124 S_ndoor: \046 @@ -354,7 +64,7 @@ start: NHAccess S_tree: \035 S_room: \035 S_corr: \060 - S_litcorr: \062 + S_litcorr: \062 S_upstair: \060 S_dnstair: \062 S_upladder: \095 @@ -363,35 +73,35 @@ start: NHAccess S_grave: \126 S_throne: \126 S_sink: \126 - S_fountain: \126 + S_fountain: \126 S_pool: \042 S_ice: \042 S_lava: \035 S_vodbridge: \035 - S_hodbridge: \032 + S_hodbridge: \032 S_vcdbridge: \035 S_hcdbridge: \126 S_arrow_trap: \094 S_dart_trap: \094 - S_falling_rock_trap: \094 + S_falling_rock_trap: \094 S_squeaky_board: \094 S_bear_trap: \094 S_land_mine: \094 - S_rolling_boulder_trap: \094 + S_rolling_boulder_trap: \094 S_sleeping_gas_trap: \094 S_rust_trap: \094 S_fire_trap: \094 S_pit: \094 S_spiked_pit: \094 S_hole: \094 - S_trap_door: \094 + S_trap_door: \094 S_teleportation_trap: \094 S_level_teleporter: \094 S_magic_portal: \094 S_web: \094 - S_statue_trap: \094 + S_statue_trap: \094 S_magic_trap: \094 - S_anti_magic_trap: \094 + S_anti_magic_trap: \094 S_polymorph_trap: \094 S_vbeam: \124 S_hbeam: \095 @@ -413,7 +123,7 @@ start: NHAccess S_sw_bl: \092 S_sw_bc: \045 S_sw_br: \047 - S_explode1: \047 + S_explode1: \047 S_explode2: \045 S_explode3: \092 S_explode4: \058 @@ -426,7 +136,7 @@ finish # All symbols are spaces start: Blank - Description: Completely blank symbols + Description: completely blank symbols S_air: \032 S_altar: \032 S_amulet: \032 @@ -603,15 +313,343 @@ start: Blank S_zruty: \032 finish -start: plain - Description: Same as Default symbols, except '+' for corner walls - S_tlcorn: '+' - S_trcorn: '+' - S_blcorn: '+' - S_brcorn: '+' - S_crwall: '+' - S_tuwall: '+' - S_tdwall: '+' - S_tlwall: '+' - S_trwall: '+' -finish #plain -- other symbols implicitly retain their default values +start: IBMgraphics + Description: special line-drawing characters used for walls +# Restrictions: primary + Handling: IBM + S_vwall: \xb3 # meta-3, vertical rule + S_hwall: \xc4 # meta-D, horizontal rule + S_tlcorn: \xda # meta-Z, top left corner + S_trcorn: \xbf # meta-?, top right corner + S_blcorn: \xc0 # meta-@, bottom left + S_brcorn: \xd9 # meta-Y, bottom right + S_crwall: \xc5 # meta-E, cross + S_tuwall: \xc1 # meta-A, T up + S_tdwall: \xc2 # meta-B, T down + S_tlwall: \xb4 # meta-4, T left + S_trwall: \xc3 # meta-C, T right + S_ndoor: \xfa # meta-z, centered dot + S_vodoor: \xfe # meta-~, small centered square + S_hodoor: \xfe # meta-~, small centered square + S_bars: \xf0 # equivalence symbol + S_tree: \xf1 # plus or minus symbol + S_room: \xfa # meta-z, centered dot + S_corr: \xb0 # meta-0, light shading + S_litcorr: \xb1 # meta-1, medium shading + S_fountain: \xf4 # meta-t, integral top half + S_pool: \xf7 # meta-w, approx. equals + S_ice: \xfa # meta-z, centered dot + S_lava: \xf7 # meta-w, approx. equals + S_vodbridge: \xfa # meta-z, centered dot + S_hodbridge: \xfa # meta-z, centered dot + S_water: \xf7 # meta-w, approx. equals + S_vbeam: \xb3 # meta-3, vertical rule + S_hbeam: \xc4 # meta-D, horizontal rule + S_sw_ml: \xb3 # meta-3, vertical rule + S_sw_mr: \xb3 # meta-3, vertical rule + S_explode4: \xb3 # meta-3, vertical rule + S_explode6: \xb3 # meta-3, vertical rule +finish + +start: IBMGraphics_1 +# Restrictions: primary + Handling: IBM + S_vwall: \xb3 # meta-3, vertical rule + S_hwall: \xc4 # meta-D, horizontal rule + S_tlcorn: \xda # meta-Z, top left corner + S_trcorn: \xbf # meta-?, top right corner + S_blcorn: \xc0 # meta-@, bottom left + S_brcorn: \xd9 # meta-Y, bottom right + S_crwall: \xc5 # meta-E, cross + S_tuwall: \xc1 # meta-A, T up + S_tdwall: \xc2 # meta-B, T down + S_tlwall: \xb4 # meta-4, T left + S_trwall: \xc3 # meta-C, T right + S_vbeam: \xb3 # meta-3, vertical rule + S_hbeam: \xc4 # meta-D, horizontal rule + S_sw_ml: \xb3 # meta-3, vertical rule + S_sw_mr: \xb3 # meta-3, vertical rule + S_explode4: \xb3 # meta-3, vertical rule + S_explode6: \xb3 # meta-3, vertical rule +finish + +start: IBMGraphics_2 +# Restrictions: primary + Handling: IBM + S_vwall: \xb3 # meta-3, vertical rule + S_hwall: \xc4 # meta-D, horizontal rule + S_tlcorn: \xda # meta-Z, top left corner + S_trcorn: \xbf # meta-?, top right corner + S_blcorn: \xc0 # meta-@, bottom left + S_brcorn: \xd9 # meta-Y, bottom right + S_crwall: \xc5 # meta-E, cross + S_tuwall: \xc1 # meta-A, T up + S_tdwall: \xc2 # meta-B, T down + S_tlwall: \xb4 # meta-4, T left + S_trwall: \xc3 # meta-C, T right + S_vodoor: \xfe # meta-~, small centered square + S_hodoor: \xfe # meta-~, small centered square + S_corr: \xb0 # meta-0, light shading + S_litcorr: \xb1 # meta-1, medium shading + S_vbeam: \xb3 # meta-3, vertical rule + S_hbeam: \xc4 # meta-D, horizontal rule + S_sw_ml: \xb3 # meta-3, vertical rule + S_sw_mr: \xb3 # meta-3, vertical rule + S_explode4: \xb3 # meta-3, vertical rule + S_explode6: \xb3 # meta-3, vertical rule +finish + +start: RogueIBM + Handling: IBM + Restrictions: rogue + S_weapon: \x29 + S_amulet: \x2c + S_food: \x3a + S_potion: \xad + S_scroll: \x3f + S_book: \x2b + S_wand: \xe7 + S_vwall: \xba # all walls now use + S_hwall: \xcd # double line graphics + S_tlcorn: \xc9 + S_trcorn: \xbb + S_blcorn: \xc8 + S_brcorn: \xbc + S_crwall: \xce + S_tuwall: \xca + S_tdwall: \xcb + S_tlwall: \xb9 + S_trwall: \xcc + S_ndoor: \xce + S_vodoor: \xce + S_hodoor: \xce + S_room: \xfa # centered dot + S_corr: \xb1 + S_litcorr: \xb2 + S_upstair: \xf0 # Greek Xi + S_dnstair: \xf0 +finish + +start: RogueEpyx + Description: rogue level color symbol set like Epyx Rogue + Restrictions: rogue + Handling: IBM + Color: Yes + S_vwall: \xba # all walls now use + S_hwall: \xcd # double line graphics + S_tlcorn: \xc9 + S_trcorn: \xbb + S_blcorn: \xc8 + S_brcorn: \xbc + S_crwall: \xce + S_tuwall: \xca + S_tdwall: \xcb + S_tlwall: \xb9 + S_trwall: \xcc + S_ndoor: \xce + S_vodoor: \xce + S_hodoor: \xce + S_room: \xfa # centered dot + S_corr: \xb1 + S_litcorr: \xb2 + S_upstair: \xf0 # Greek Xi + S_dnstair: \xf0 + S_arrow_trap: \x04 # diamond (cards) + S_dart_trap: \x04 + S_falling_rock_trap: \x04 + S_squeaky_board: \x04 + S_bear_trap: \x04 + S_land_mine: \x04 + S_rolling_boulder_trap: \x04 + S_sleeping_gas_trap: \x04 + S_rust_trap: \x04 + S_fire_trap: \x04 + S_pit: \x04 + S_spiked_pit: \x04 + S_hole: \x04 + S_trap_door: \x04 + S_teleportation_trap: \x04 + S_level_teleporter: \x04 + S_magic_portal: \x04 + S_web: \x04 + S_statue_trap: \x04 + S_magic_trap: \x04 + S_anti_magic_trap: \x04 + S_polymorph_trap: \x04 + S_weapon: \x18 # up arrow +# ^J S_armor: \x0a # Vert rect with o + S_armor: \x5b # default: '[' +# ^I S_ring: \x09 # circle with arrow + S_ring: \x3d # default: '=' + S_amulet: \x0c # "female" symbol + S_tool: \x28 # default: '(' + S_food: \x05 # club (as in cards) + S_potion: \xad # upside down '!' + S_scroll: \x0e # musical note + S_book: \x2b # default: '+' + S_wand: \xe7 # greek tau + S_coin: \x0f # yes it's the same as gems + S_gem: \x0f # fancy '*' + S_rock: \x60 + S_ball: \x30 + S_chain: \x5f + S_venom: \x2e + S_rock: \x60 + S_ball: \x30 + S_chain: \x5f + S_venom: \x2e + S_human: \x01 +finish + +start: RogueWindows + Restrictions: rogue + Handling: IBM + S_weapon: \x29 + S_amulet: \x2c + S_food: \x3a + S_potion: \xad + S_scroll: \x3f + S_book: \x2b + S_wand: \xe7 + S_vwall: \xba # all walls now use + S_hwall: \xcd # double line graphics + S_tlcorn: \xc9 + S_trcorn: \xbb + S_blcorn: \xc8 + S_brcorn: \xbc + S_crwall: \xce + S_tuwall: \xca + S_tdwall: \xcb + S_tlwall: \xb9 + S_trwall: \xcc + S_ndoor: \xce + S_vodoor: \xce + S_hodoor: \xce + S_room: \xfa # centered dot + S_corr: \xb1 + S_litcorr: \xb2 + S_upstair: \xf0 # Greek Xi + S_dnstair: \xf0 +finish + +start: curses + Description: approximation of IBMgraphics using DECgraphics + Restrictions: primary + Handling: DEC + S_vwall: \xf8 # meta-x, vertical rule + S_hwall: \xf1 # meta-q, horizontal rule + S_tlcorn: \xec # meta-l, top left corner + S_trcorn: \xeb # meta-k, top right corner + S_blcorn: \xed # meta-m, bottom left + S_brcorn: \xea # meta-j, bottom right + S_crwall: \xee # meta-n, cross + S_tuwall: \xf6 # meta-v, T up + S_tdwall: \xf7 # meta-w, T down + S_tlwall: \xf5 # meta-u, T left + S_trwall: \xf4 # meta-t, T right + S_ndoor: \xfe # meta-z, centered dot + S_tree: \xf1 # plus or minus symbol + S_room: \xfe # meta-z, centered dot + S_corr: \xe1 # meta-a, solid block + S_litcorr: \xe1 # meta-a, solid block + S_ice: \xfe # meta-z, centered dot + S_vodbridge: \xfe # meta-z, centered dot + S_hodbridge: \xfe # meta-z, centered dot + S_vbeam: \xf8 # meta-3, vertical rule + S_hbeam: \xf1 # meta-D, horizontal rule + S_sw_ml: \xf8 # meta-3, vertical rule + S_sw_mr: \xf8 # meta-3, vertical rule + S_explode4: \xf8 # meta-3, vertical rule + S_explode6: \xf8 # meta-3, vertical rule +finish + +start: DECgraphics + Description: special line-drawing characters used for walls + Restrictions: primary + Handling: DEC + S_vwall: \xf8 # meta-x, vertical rule + S_hwall: \xf1 # meta-q, horizontal rule + S_tlcorn: \xec # meta-l, top left corner + S_trcorn: \xeb # meta-k, top right corner + S_blcorn: \xed # meta-m, bottom left + S_brcorn: \xea # meta-j, bottom right + S_crwall: \xee # meta-n, cross + S_tuwall: \xf6 # meta-v, T up + S_tdwall: \xf7 # meta-w, T down + S_tlwall: \xf5 # meta-u, T left + S_trwall: \xf4 # meta-t, T right + S_ndoor: \xfe # meta-~, centered dot + S_vodoor: \xe1 # meta-a, solid block + S_hodoor: \xe1 # meta-a, solid block + S_bars: \xfb # meta-{, small pi + S_tree: \xe7 # meta-g, plus-or-minus + S_room: \xfe # meta-~, centered dot + S_upladder: \xf9 # meta-y, less-than-or-equals + S_dnladder: \xfa # meta-z, greater-than-or-equals + S_pool: \xe0 # meta-\, diamond + S_ice: \xfe # meta-~, centered dot + S_lava: \xe0 # meta-\, diamond + S_vodbridge: \xfe # meta-~, centered dot + S_hodbridge: \xfe # meta-~, centered dot + S_water: \xe0 # meta-\, diamond + S_vbeam: \xf8 # meta-x, vertical rule + S_hbeam: \xf1 # meta-q, horizontal rule + S_sw_tc: \xef # meta-o, high horizontal line + S_sw_ml: \xf8 # meta-x, vertical rule + S_sw_mr: \xf8 # meta-x, vertical rule + S_sw_bc: \xf3 # meta-s, low horizontal line + S_explode2: \xef # meta-o, high horizontal line + S_explode4: \xf8 # meta-x, vertical rule + S_explode6: \xf8 # meta-x, vertical rule + S_explode8: \xf3 # meta-s, low horizontal line +finish + +# +# This is commented out because specifying alternate default set isn't +# implemented. +# +# DECgraphics_2: underscore (default for altar) can be hard to see if +# hero or highlighted pet is on the spot below (south of) it, making +# it look like part of slightly bigger block cursor. Bars are usually +# within walls and we have something else for doorless doorway so '#' +# for bars shouldn't be mistaken for the corridor symbol even by someone +# used to DECgraphics, at least not often enough to pose a problem. +# The pi symbol is small like lowercase but flat-topped like uppercase +# so could represent a side view of a raised platform or table. +# +# start: DECgraphics_2 +# Defaults: DECgraphics # includes 'Handling: DEC' +# Description: variation of DECgraphics (iron bars:#, altar:pi) +# S_bars: '#' # (switch from pi to plain '#') +# S_altar: \xfb # meta-{, pi (switch from underscore) +# finish +# + +start: MACgraphics +# Description: (pre-OSX: obsolete?) +# Restrictions: primary + Handling: MAC + S_vwall: \xba + S_hwall: \xcd + S_tlcorn: \xc9 + S_trcorn: \xbb + S_blcorn: \xc8 + S_brcorn: \xbc + S_crwall: \xce + S_tuwall: \xca + S_tdwall: \xcb + S_tlwall: \xb9 + S_trwall: \xcc + S_ndoor: \xb0 + S_vodoor: \xee + S_hodoor: \xee + S_vcdoor: \xef + S_hcdoor: \xef + S_bars: \xf0 # equivalency symbol + S_tree: \xf1 # plus-or-minus + S_corr: \xb0 + S_grave: \xef # same as open door + S_pool: \xe0 +finish + +# symbols EOF diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 809ddab65..50d7d97c8 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.138 $ $NHDT-Date: 1571267989 2019/10/16 23:19:49 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.139 $ $NHDT-Date: 1571313651 2019/10/17 12:00:51 $ 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, @@ -185,6 +185,8 @@ fix hero still hiding under a statue shattered by a land mine fix helping a monster out of a pit addressing a deleted trap fix launched rolling boulder code accessing deleted trap fix monster stepping on a land mine code accessing deleted trap +revise 'O' to show symbol sets in the same order they appear in the symbols + file and order the sets in dat/symbols to yield a sensible symset menu Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository @@ -280,6 +282,8 @@ curses: support symset:DECgraphics for map display curses: enable the 'use_inverse' boolean option (via wincap WC_INVERSE flag) for extended monster detection and black&white lava; forced to True to override default of False (for tty's benefit) +curses: force 'O' command's menus for 'symset' and 'roguesymset' options to + be wider so that fewer entries with set descriptions will wrap curses+'perm_invent': entries were wrapping without any control; usually not noticeable because next entry overwrote, but visible for final entry when whole inventory fit within the available height; looked ok with diff --git a/include/rm.h b/include/rm.h index becdd21a0..de1c8cfda 100644 --- a/include/rm.h +++ b/include/rm.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 rm.h $NHDT-Date: 1559994624 2019/06/08 11:50:24 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.61 $ */ +/* NetHack 3.6 rm.h $NHDT-Date: 1571313651 2019/10/17 12:00:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.63 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -299,6 +299,8 @@ struct symsetentry { #define H_IBM 1 #define H_DEC 2 #define H_CURS 3 +#define H_MAC 4 /* obsolete; needed so that the listing of available + * symsets by 'O' can skip it for !MAC_GRAPHICS_ENV */ extern const struct symdef defsyms[MAXPCHARS]; /* defaults */ extern const struct symdef def_warnsyms[WARNCOUNT]; diff --git a/src/drawing.c b/src/drawing.c index f29dbf3a2..2ac8ad28e 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 drawing.c $NHDT-Date: 1546656404 2019/01/05 02:46:44 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.59 $ */ +/* NetHack 3.6 drawing.c $NHDT-Date: 1571313651 2019/10/17 12:00:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.61 $ */ /* Copyright (c) NetHack Development Team 1992. */ /* NetHack may be freely redistributed. See license for details. */ @@ -255,9 +255,9 @@ static const uchar def_r_oc_syms[MAXOCLASSES] = { #undef C -#ifdef TERMLIB +#if defined(TERMLIB) || defined(CURSES_GRAPHICS) void NDECL((*decgraphics_mode_callback)) = 0; /* set in tty_start_screen() */ -#endif /* TERMLIB */ +#endif /* TERMLIB || CURSES */ #ifdef PC9800 void NDECL((*ibmgraphics_mode_callback)) = 0; /* set in tty_start_screen() */ @@ -496,17 +496,22 @@ int nondefault; #ifdef PC9800 if (SYMHANDLING(H_IBM) && ibmgraphics_mode_callback) (*ibmgraphics_mode_callback)(); - else if (!symset[currentgraphics].name && ascgraphics_mode_callback) + else if (SYMHANDLING(H_UNK) && ascgraphics_mode_callback) (*ascgraphics_mode_callback)(); #endif -#ifdef TERMLIB +#if defined(TERMLIB) || defined(CURSES_GRAPHICS) + /* curses doesn't assign any routine to dec..._callback but + probably does the expected initialization under the hood + for terminals capable of rendering DECgraphics */ if (SYMHANDLING(H_DEC) && decgraphics_mode_callback) (*decgraphics_mode_callback)(); -#endif # ifdef CURSES_GRAPHICS + /* there aren't any symbol sets with CURS handling, and the + curses interface never assigns a routine to curses..._callback */ if (SYMHANDLING(H_CURS) && cursesgraphics_mode_callback) (*cursesgraphics_mode_callback)(); # endif +#endif } else { init_l_symbols(); init_showsyms(); @@ -563,6 +568,7 @@ const char *known_handling[] = { "IBM", /* H_IBM */ "DEC", /* H_DEC */ "CURS", /* H_CURS */ + "MAC", /* H_MAC -- pre-OSX MACgraphics */ (const char *) 0, }; diff --git a/src/files.c b/src/files.c index 930d36ea2..f9d2dee8e 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 files.c $NHDT-Date: 1562719337 2019/07/10 00:42:17 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.252 $ */ +/* NetHack 3.6 files.c $NHDT-Date: 1571313652 2019/10/17 12:00:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.253 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2111,7 +2111,7 @@ const char *name; /* name of option for error message */ break; default: - gi_error: + gi_error: raw_printf("Syntax error in %s", name); wait_synch(); return count; @@ -3063,9 +3063,10 @@ boolean FDECL((*proc), (char *)); } ep = inbuf; - while (*ep == ' ' || *ep == '\t') ep++; + while (*ep == ' ' || *ep == '\t') + ++ep; - /* lines beginning with '#' are comments. ignore empty lines. */ + /* ingore empty lines and full-line comment lines */ if (!*ep || *ep == '#') ignoreline = TRUE; @@ -3074,9 +3075,9 @@ boolean FDECL((*proc), (char *)); /* merge now read line with previous ones, if necessary */ if (!ignoreline) { - len = strlen(inbuf) + 1; + len = (int) strlen(inbuf) + 1; if (buf) - len += strlen(buf); + len += (int) strlen(buf); tmpbuf = (char *) alloc(len); if (buf) { Sprintf(tmpbuf, "%s %s", buf, inbuf); @@ -3100,6 +3101,7 @@ boolean FDECL((*proc), (char *)); if (match_varname(buf, "CHOOSE", 6)) { char *section; char *bufp = find_optparam(buf); + if (!bufp) { config_error_add( "Format is CHOOSE=section1,section2,..."); @@ -3259,13 +3261,19 @@ int which_set; building a pick-list of possible symset values from the file, so only do that */ if (symp->range == SYM_CONTROL) { - struct symsetentry *tmpsp; + struct symsetentry *tmpsp, *lastsp; + for (lastsp = symset_list; lastsp; lastsp = lastsp->next) + if (!lastsp->next) + break; switch (symp->idx) { case 0: tmpsp = (struct symsetentry *) alloc(sizeof *tmpsp); - tmpsp->next = symset_list; - symset_list = tmpsp; + tmpsp->next = (struct symsetentry *) 0; + if (!lastsp) + symset_list = tmpsp; + else + lastsp->next = tmpsp; tmpsp->idx = symset_count++; tmpsp->name = dupstr(bufp); tmpsp->desc = (char *) 0; @@ -3277,21 +3285,22 @@ int which_set; break; case 2: /* handler type identified */ - tmpsp = symset_list; /* most recent symset */ + tmpsp = lastsp; /* most recent symset */ for (i = 0; known_handling[i]; ++i) if (!strcmpi(known_handling[i], bufp)) { tmpsp->handling = i; break; /* for loop */ } break; - case 3: /* description:something */ - tmpsp = symset_list; /* most recent symset */ + case 3: + /* description:something */ + tmpsp = lastsp; /* most recent symset */ if (tmpsp && !tmpsp->desc) tmpsp->desc = dupstr(bufp); break; case 5: /* restrictions: xxxx*/ - tmpsp = symset_list; /* most recent symset */ + tmpsp = lastsp; /* most recent symset */ for (i = 0; known_restrictions[i]; ++i) { if (!strcmpi(known_restrictions[i], bufp)) { switch (i) { @@ -4103,7 +4112,7 @@ unsigned oid; /* book identifier */ } } -cleanup: + cleanup: (void) dlb_fclose(fp); if (nowin_buf) { /* one-line buffer */ diff --git a/src/options.c b/src/options.c index 220f8f483..019a4544f 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1571045295 2019/10/14 09:28:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.376 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1571313653 2019/10/17 12:00:53 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.378 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -5336,8 +5336,8 @@ boolean setinitial, setfromfile; MENU_UNSELECTED); for (i = 0; i < numapes && ape; i++) { any.a_void = (opt_idx == 1) ? 0 : ape; - /* length of pattern plus quotes (plus '<'/'>') is less than - BUFSZ */ + /* length of pattern plus quotes (plus '<'/'>') is + less than BUFSZ */ Sprintf(apebuf, "\"%c%s\"", ape->grab ? '<' : '>', ape->pattern); add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, apebuf, @@ -5383,18 +5383,27 @@ boolean setinitial, setfromfile; symset[which_set].name = symset_name; if (res && symset_list) { - int thissize, biggest = 0; + int thissize, + biggest = (int) (sizeof "Default Symbols" - sizeof ""), + big_desc = 0; for (sl = symset_list; sl; sl = sl->next) { /* check restrictions */ if (rogueflag ? sl->primary : sl->rogue) continue; +#ifndef MAC_GRAPHICS_ENV + if (sl->handling == H_MAC) + continue; +#endif setcount++; /* find biggest name */ thissize = sl->name ? (int) strlen(sl->name) : 0; if (thissize > biggest) biggest = thissize; + thissize = sl->desc ? (int) strlen(sl->desc) : 0; + if (thissize > big_desc) + big_desc = thissize; } if (!setcount) { pline("There are no appropriate %s symbol sets available.", @@ -5402,10 +5411,48 @@ boolean setinitial, setfromfile; return TRUE; } - Sprintf(fmtstr, "%%-%ds %%s", biggest + 5); + Sprintf(fmtstr, "%%-%ds %%s", biggest + 2); tmpwin = create_nhwindow(NHW_MENU); start_menu(tmpwin); any = zeroany; +#ifdef CURSES_GRAPHICS /* this ought to be handled within curses... */ + /* + * Symbol sets are formatted in two columns, "name description", + * on selectable lines. curses bases menu width on the length + * of non-selectable lines (main header, separators if present, + * with trailing spaces ignored) and defaults to half the map. + * Without something like this separator (shown after the menu + * title and a blank line which follows that) to force a wider + * menu, entries with long descriptions wrap. That would be + * ok if wrapping operated on the same two columns, but the + * menu doesn't know anything about those and the description + * is wrapping into the next line's name column, making long + * descriptions--and menus containing them--hard to read. + */ + if (WINDOWPORT("curses")) { + char tmp1[BUFSZ], tmp2[BUFSZ], bigbuf[BUFSZ + 1 + BUFSZ]; + + /* 4: room for space+letter+paren+space, fake selector; + 2: added to 'biggest' when constructing 'fmtstr'; + 1: space between symset name+2 and symset description */ + if (4 + biggest + 2 + 1 > (int) sizeof tmp1 - 1) + biggest = (int) sizeof tmp1 - 1 - (4 + 2 + 1); + (void) memset((genericptr_t) tmp1, '-', biggest); + tmp1[biggest] = '\0'; + if (big_desc > (int) sizeof tmp2 - 1) + big_desc = (int) sizeof tmp2 - 1; + (void) memset((genericptr_t) tmp2, '-', big_desc); + tmp2[big_desc] = '\0'; + Sprintf(bigbuf, "%4s", ""); + Sprintf(eos(bigbuf), fmtstr, tmp1, tmp2); + bigbuf[BUFSZ - 1] = '\0'; + any.a_int = 0; + add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + bigbuf, MENU_UNSELECTED); + } +#else + nhUse(big_desc); +#endif any.a_int = 1; add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "Default Symbols", MENU_UNSELECTED); @@ -5414,6 +5461,10 @@ boolean setinitial, setfromfile; /* check restrictions */ if (rogueflag ? sl->primary : sl->rogue) continue; +#ifndef MAC_GRAPHICS_ENV + if (sl->handling == H_MAC) + continue; +#endif if (sl->name) { any.a_int = sl->idx + 2; From 61b976e0d57a5b818b4264f149b06e3119b95ae3 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Oct 2019 05:07:03 -0700 Subject: [PATCH 20/24] couple of curses symbol handling bits Primary and rogue symbols were being set to default if primary hadn't been given a value, possibly clobbering rogue symbols if those had been given a value. Initialize them independenly. Return early from curses_convert_glyph() if the value doesn't have the 8th bit set since it now deals exclusively with DECgraphics handling. Force a sane value for returning early on rogue level. --- win/curses/cursinit.c | 5 +++-- win/curses/cursmisc.c | 40 +++++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 773334855..e5a74128b 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -785,10 +785,11 @@ curses_init_options() set_option_mod_status("eight_bit_tty", SET_IN_FILE); /* If we don't have a symset defined, load the curses symset by default */ - if (symset[PRIMARY].fallback) { + if (symset[PRIMARY].fallback) load_symset("curses", PRIMARY); + if (symset[ROGUESET].fallback) load_symset("default", ROGUESET); - } + #ifdef PDCURSES /* PDCurses for SDL, win32 and OS/2 has the ability to set the terminal size programatically. If the user does not specify a diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index ab6a3bd45..75e127332 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -472,21 +472,29 @@ curses_convert_glyph(int ch, int glyph) because 0x7f is effectively a control character (Rubout); nethack ORs 0x80 to flag line drawing--that's stripped below */ static int decchars[33]; /* for chars 0x5f through 0x7f (95..127) */ - int symbol; - /* FIXME? we don't support any special characters in roguesymset */ - if (Is_rogue_level(&u.uz)) + ch &= 0xff; /* 0..255 only */ + if (!(ch & 0x80)) + return ch; /* no conversion needed */ + + /* this conversion routine is only called for SYMHANDLING(H_DEC) and + we decline to support special graphics symbols on the rogue level */ + if (Is_rogue_level(&u.uz)) { + /* attempting to use line drawing characters will end up being + rendered as lowercase gibberish */ + ch &= ~0x80; return ch; + } - symbol = glyph_to_cmap(glyph); - - /* Curses has complete access to all characters that DECgraphics uses. - However, their character value isn't consistent between terminals - and implementations. For actual DEC terminals and faithful emulators, - line-drawing characters are specified as lowercase letters (mostly) - and a control code is sent to the terminal telling it to switch - character sets (that's how the tty interface handles them). - Curses remaps the characters instead. */ + /* + * Curses has complete access to all characters that DECgraphics uses. + * However, their character value isn't consistent between terminals + * and implementations. For actual DEC terminals and faithful emulators, + * line-drawing characters are specified as lowercase letters (mostly) + * and a control code is sent to the terminal telling it to switch + * character sets (that's how the tty interface handles them). + * Curses remaps the characters instead. + */ /* one-time initialization; some ACS_x aren't compile-time constant */ if (!decchars[0]) { @@ -510,7 +518,7 @@ curses_convert_glyph(int ch, int glyph) decchars[0x68 - 0x5f] = 'N'; /* [9] "NL" as one char (new line) */ decchars[0x69 - 0x5f] = 'V'; /* [10] "VT" as one (vertical tab) */ decchars[0x6a - 0x5f] = ACS_LRCORNER; /* lower right corner */ - decchars[0x6b - 0x5f] = ACS_URCORNER; /* upper right corner */ + decchars[0x6b - 0x5f] = ACS_URCORNER; /* upper right corner, 7-ish */ decchars[0x6c - 0x5f] = ACS_ULCORNER; /* upper left corner */ decchars[0x6d - 0x5f] = ACS_LLCORNER; /* lower left corner, 'L' */ /* [15] center cross, like big '+' sign */ @@ -554,7 +562,7 @@ curses_convert_glyph(int ch, int glyph) /* high bit set means special handling */ if (ch & 0x80) { - int convindx; + int convindx, symbol; ch &= ~0x80; /* force plain ASCII for last resort */ convindx = ch - 0x5f; @@ -565,8 +573,10 @@ curses_convert_glyph(int ch, int glyph) /* in case ACS_foo maps to 0 when current terminal is unable to handle a particular character; if so, revert to default rather than using DECgr value with high bit stripped */ - if (!ch) + if (!ch) { + symbol = glyph_to_cmap(glyph); ch = (int) defsyms[symbol].sym; + } } } From 0c86965d5e7b3dd3ed950114c869406491357364 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Oct 2019 05:17:08 -0700 Subject: [PATCH 21/24] another thinko --- dat/symbols | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dat/symbols b/dat/symbols index 8e8a6349f..ae22419c5 100644 --- a/dat/symbols +++ b/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.6 symbols $NHDT-Date: 1571313649 2019/10/17 12:00:49 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.19 $ +# NetHack 3.6 symbols $NHDT-Date: 1571314611 2019/10/17 12:16:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.20 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -23,8 +23,8 @@ # on that windowport if no symset is specified. The Curses interface # can also use DECgraphics as-is; IBMgraphics probably won't work. -# plain looks decent for wall+corridor levels where there aren't a lot -# of room corners and ones present tend to be spread out, but it looks +# plain looks decent for room+corridor levels where there aren't a lot +# of wall corners and ones present tend to be spread out, but it looks # awful for wallified mazes start: plain Description: same as default symbols, except '+' for corner walls From 6182b014ca6f69a3b8e2f133a912719ed3810b6b Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Oct 2019 14:38:45 -0700 Subject: [PATCH 22/24] github pull request #235 - curses symbol set init Fixes #235 For initial options under curses, specifying 'DECgraphics' as a boolean rather than as 'symset:DECgraphics' wasn't overriding the new default 'symset:curses'. Since previously DECgraphics was rejected for curses, it's possible that no one noticed. --- include/rm.h | 4 ++-- src/drawing.c | 3 +-- src/files.c | 13 +++++++++++-- src/options.c | 6 +----- win/curses/cursinit.c | 4 ++-- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/rm.h b/include/rm.h index de1c8cfda..87d7566a2 100644 --- a/include/rm.h +++ b/include/rm.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 rm.h $NHDT-Date: 1571313651 2019/10/17 12:00:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.63 $ */ +/* NetHack 3.6 rm.h $NHDT-Date: 1571347960 2019/10/17 21:32:40 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.64 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -278,7 +278,7 @@ struct symsetentry { Bitfield(nocolor, 1); /* don't use color if set */ Bitfield(primary, 1); /* restricted for use as primary set */ Bitfield(rogue, 1); /* restricted for use as rogue lev set */ - Bitfield(fallback, 1); /* no explicit symset set */ + Bitfield(explicitly, 1); /* explicit symset set */ /* 4 free bits */ }; diff --git a/src/drawing.c b/src/drawing.c index 2ac8ad28e..072485fb6 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 drawing.c $NHDT-Date: 1571313651 2019/10/17 12:00:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.61 $ */ +/* NetHack 3.6 drawing.c $NHDT-Date: 1571347973 2019/10/17 21:32:53 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.62 $ */ /* Copyright (c) NetHack Development Team 1992. */ /* NetHack may be freely redistributed. See license for details. */ @@ -548,7 +548,6 @@ boolean name_too; /* initialize restriction bits */ symset[which_set].primary = 0; symset[which_set].rogue = 0; - symset[which_set].fallback = TRUE; if (name_too) { if (symset[which_set].name) diff --git a/src/files.c b/src/files.c index f9d2dee8e..77b279077 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 files.c $NHDT-Date: 1571313652 2019/10/17 12:00:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.253 $ */ +/* NetHack 3.6 files.c $NHDT-Date: 1571347976 2019/10/17 21:32:56 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.254 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3168,9 +3168,11 @@ int which_set; { FILE *fp; + symset[which_set].explicitly = FALSE; if (!(fp = fopen_sym_file())) return 0; + symset[which_set].explicitly = TRUE; symset_count = 0; chosen_symset_start = chosen_symset_end = FALSE; symset_which_set = which_set; @@ -3190,7 +3192,14 @@ int which_set; || !strcmpi(symset[which_set].name, "default"))) clear_symsetentry(which_set, TRUE); config_error_done(); - return (symset[which_set].name == 0) ? 1 : 0; + + /* If name was defined, it was invalid... Then we're loading fallback */ + if (symset[which_set].name) { + symset[which_set].explicitly = FALSE; + return 0; + } + + return 1; } if (!chosen_symset_end) config_error_add("Missing finish for symset \"%s\"", diff --git a/src/options.c b/src/options.c index 019a4544f..ddbe794f8 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1571313653 2019/10/17 12:00:53 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.378 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1571347977 2019/10/17 21:32:57 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.379 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2315,7 +2315,6 @@ boolean tinitial, tfrom_file; } else { if (!initial && Is_rogue_level(&u.uz)) assign_graphics(ROGUESET); - symset[ROGUESET].fallback = FALSE; need_redraw = TRUE; } } else @@ -2340,7 +2339,6 @@ boolean tinitial, tfrom_file; return FALSE; } else { switch_symbols(symset[PRIMARY].name != (char *) 0); - symset[PRIMARY].fallback = FALSE; need_redraw = TRUE; } } else @@ -6061,10 +6059,8 @@ int which_set; if (read_sym_file(which_set)) { switch_symbols(TRUE); - symset[which_set].fallback = FALSE; } else { clear_symsetentry(which_set, TRUE); - symset[which_set].fallback = TRUE; return 0; } return 1; diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index e5a74128b..3d4f977d6 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -785,9 +785,9 @@ curses_init_options() set_option_mod_status("eight_bit_tty", SET_IN_FILE); /* If we don't have a symset defined, load the curses symset by default */ - if (symset[PRIMARY].fallback) + if (!symset[PRIMARY].explicitly) load_symset("curses", PRIMARY); - if (symset[ROGUESET].fallback) + if (!symset[ROGUESET].explicitly) load_symset("default", ROGUESET); #ifdef PDCURSES From 70c9b801bd8eb0e73623bc1cbf5ef4119d940e8a Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Oct 2019 14:58:16 -0700 Subject: [PATCH 23/24] github pull request #233 - plural of Nazgul Fixes #233 makeplural() and makesingular() know that the plural of Nazgul is Nazgul, but one of the hard-coded rumors didn't. --- dat/rumors.tru | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dat/rumors.tru b/dat/rumors.tru index 8181c5abc..0a6ff45b0 100644 --- a/dat/rumors.tru +++ b/dat/rumors.tru @@ -299,7 +299,7 @@ They say that the Leprechaun King is rich as Croesus. They say that the Wizard of Yendor is schizophrenic and suicidal. They say that the experienced character knows how to convert an altar. They say that the gods are happy when they drop objects at your feet. -They say that the idea of invisible Nazguls has a certain ring to it. +They say that the idea of invisible Nazgul has a certain ring to it. They say that the lady of the lake now lives in a fountain somewhere. They say that the local shopkeeper frowns upon the rude tourist. They say that the only door to the vampire's tower is on its lowest level. From 389c4960552442ceebd415fe4b2a48a026aa975c Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Oct 2019 15:50:33 -0700 Subject: [PATCH 24/24] zap colors One of the comments for pull request #234 mentions that the colors for sleep and poison are backwards. Yellow dragons had green breath. Green dragons would have had yellow breath if they used the normal zap symbols, but they use the poison cloud one which is green so they had green breath. I rarely have color enabled and had never noticed. (At the moment I can't find where the switch from zap to cloud is being done.) Pull request #234 is based on #231, about control of the shield effect animation when resisting. But it changes struct flags so would break 3.6.x save file compatibility. --- doc/fixes36.3 | 3 ++- src/decl.c | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 50d7d97c8..b1b3b3e2c 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.139 $ $NHDT-Date: 1571313651 2019/10/17 12:00:51 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.140 $ $NHDT-Date: 1571352531 2019/10/17 22:48:51 $ 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, @@ -187,6 +187,7 @@ fix launched rolling boulder code accessing deleted trap fix monster stepping on a land mine code accessing deleted trap revise 'O' to show symbol sets in the same order they appear in the symbols file and order the sets in dat/symbols to yield a sensible symset menu +yellow dragons had green breath Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/decl.c b/src/decl.c index c6e6c6039..a42cad2a0 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.c $NHDT-Date: 1547025164 2019/01/09 09:12:44 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.141 $ */ +/* NetHack 3.6 decl.c $NHDT-Date: 1571352532 2019/10/17 22:48:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.146 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -168,6 +168,7 @@ NEARDATA struct obj #ifdef TEXTCOLOR /* * This must be the same order as used for buzz() in zap.c. + * (They're only used in mapglyph.c so probably shouldn't be here.) */ const int zapcolors[NUM_ZAP] = { HI_ZAP, /* 0 - missile */ @@ -176,8 +177,10 @@ const int zapcolors[NUM_ZAP] = { HI_ZAP, /* 3 - sleep */ CLR_BLACK, /* 4 - death */ CLR_WHITE, /* 5 - lightning */ - CLR_YELLOW, /* 6 - poison gas */ - CLR_GREEN, /* 7 - acid */ + /* 3.6.3: poison gas zap used to be yellow and acid zap was green, + which conflicted with the corresponding dragon colors */ + CLR_GREEN, /* 6 - poison gas */ + CLR_YELLOW, /* 7 - acid */ }; #endif /* text color */