From 1cb5dc04605daa45f1c6a647c17442ed7ff2fe4e Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 4 Jan 2022 08:24:08 -0500 Subject: [PATCH 01/11] work around ubuntu 20.10 build issue NetHack was trying to suppress warn_unused_result in include/tradstdc.h, by defining warn_unused_result to an empty string. That began causing a build error in a system-supplied header file cdefs.h when using 20.10 ubuntu impish. Try skipping that in tradstdc.h for any linux, unless the NetHack build defines GCC_URWARN to force it into play. --- include/tradstdc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/tradstdc.h b/include/tradstdc.h index 09decb4b1..8c33d55e0 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -405,12 +405,14 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ #if __GNUC__ >= 3 #define UNUSED __attribute__((unused)) #define NORETURN __attribute__((noreturn)) +#if !defined(__linux__) || defined(GCC_URWARN) /* disable gcc's __attribute__((__warn_unused_result__)) since explicitly discarding the result by casting to (void) is not accepted as a 'use' */ #define __warn_unused_result__ /*empty*/ #define warn_unused_result /*empty*/ #endif #endif +#endif #ifndef PRINTF_F #define PRINTF_F(f, v) From 565ed29cafc2716dc298276d9d9c6d6b52fa2cf6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 4 Jan 2022 08:48:21 -0500 Subject: [PATCH 02/11] fixes entry for ubuntu 21.10 change Note: Previous commit incorrectly stated 20.10 when it should have stated 21.10 for impish. --- doc/fixes37.0 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 885b9cd01..d84be9cdd 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1136,6 +1136,9 @@ Unix: when user name is used as default character name, keep hyphenated value intact instead stripping off dash and whatever follows as if that specified role/race/&c (worked once upon a time; broken since 3.3.0) Unix: add "ec2-user" to the list of user names 'sysconf' classifies as generic +Unix: work-around a build issue in ubuntu 21.10 by using ifdef to skip the + define of warn_unused_result to empty string in tradstdc.h whenever + __linux__ is defined during build unless GCC_URWARN is also defined user_sounds: move the message hook from inside individual window display ports to the core where it allows MSGTYP_NOSHOW msgtyp's to still trigger sounds to correct a reported github issue; also fixes a past reported From f065cf01c131eba104492a7dd5e959498f87c9eb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 4 Jan 2022 19:29:15 +0200 Subject: [PATCH 03/11] Mark extended commands accepting m-prefix in the command flags --- include/func_tab.h | 1 + src/cmd.c | 61 ++++++++++++++++------------------------------ 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/include/func_tab.h b/include/func_tab.h index 878b12817..ca2c07c3d 100644 --- a/include/func_tab.h +++ b/include/func_tab.h @@ -14,6 +14,7 @@ #define CMD_NOT_AVAILABLE 0x10 /* recognized but non-functional (!SHELL,&c) */ #define NOFUZZERCMD 0x20 /* fuzzer cannot execute this command */ #define INTERNALCMD 0x40 /* only for internal use, not for user */ +#define CMD_M_PREFIX 0x80 /* accepts menu prefix */ struct ext_func_tab { uchar key; diff --git a/src/cmd.c b/src/cmd.c index 624fa35fa..ec3f62544 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -146,7 +146,7 @@ static void mon_chain(winid, const char *, struct monst *, boolean, long *, long *); static void contained_stats(winid, const char *, long *, long *); static void misc_stats(winid, long *, long *); -static boolean accept_menu_prefix(int (*)(void)); +static boolean accept_menu_prefix(const struct ext_func_tab *); static void add_herecmd_menuitem(winid, int (*)(void), const char *); static char here_cmd_menu(boolean); @@ -387,7 +387,7 @@ doextcmd(void) func = extcmdlist[idx].ef_funct; if (!can_do_extcmd(&extcmdlist[idx])) return 0; - if (iflags.menu_requested && !accept_menu_prefix(func)) { + if (iflags.menu_requested && !accept_menu_prefix(&extcmdlist[idx])) { pline("'%s' prefix has no effect for the %s command.", visctrl(g.Cmd.spkeys[NHKF_REQMENU]), extcmdlist[idx].ef_txt); @@ -421,7 +421,7 @@ doc_extcmd_flagstr(winid menuwin, MENU_ITEMFLAGS_NONE); return (char *) 0; } else { - boolean mprefix = accept_menu_prefix(efp->ef_funct), + boolean mprefix = accept_menu_prefix(efp), autocomplete = (efp->flags & AUTOCOMPLETE) != 0; char *p = Abuf; @@ -1852,15 +1852,15 @@ doterrain(void) such as ^O/#overview and C/N/#name */ struct ext_func_tab extcmdlist[] = { { '#', "#", "perform an extended command", - doextcmd, IFBURIED | GENERALCMD, NULL }, + doextcmd, IFBURIED | GENERALCMD | CMD_M_PREFIX, NULL }, { M('?'), "?", "list all extended commands", - doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD, NULL }, + doextlist, IFBURIED | AUTOCOMPLETE | GENERALCMD | CMD_M_PREFIX, NULL }, { M('a'), "adjust", "adjust inventory letters", doorganize, IFBURIED | AUTOCOMPLETE, NULL }, { M('A'), "annotate", "name current level", donamelevel, IFBURIED | AUTOCOMPLETE, NULL }, { 'a', "apply", "apply (use) a tool (pick-axe, key, lamp...)", - doapply, 0, NULL }, + doapply, CMD_M_PREFIX, NULL }, { C('x'), "attributes", "show your attributes", doattributes, IFBURIED, NULL }, { '@', "autopickup", "toggle the 'autopickup' option on/off", @@ -1884,7 +1884,7 @@ struct ext_func_tab extcmdlist[] = { { 'D', "droptype", "drop specific item types", doddrop, 0, NULL }, { 'e', "eat", "eat something", - doeat, 0, NULL }, + doeat, CMD_M_PREFIX, NULL }, { 'E', "engrave", "engrave writing on the floor", doengrave, 0, NULL }, { M('e'), "enhance", "advance or check weapon and spell skills", @@ -1916,9 +1916,9 @@ struct ext_func_tab extcmdlist[] = { { C('d'), "kick", "kick something", dokick, 0, NULL }, { '\\', "known", "show what object types have been discovered", - dodiscovered, IFBURIED | GENERALCMD, NULL }, + dodiscovered, IFBURIED | GENERALCMD | CMD_M_PREFIX, NULL }, { '`', "knownclass", "show discovered types for one class of objects", - doclassdisco, IFBURIED | GENERALCMD, NULL }, + doclassdisco, IFBURIED | GENERALCMD | CMD_M_PREFIX, NULL }, { '\0', "levelchange", "change experience level", wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { '\0', "lightsources", "show mobile light sources", @@ -1926,7 +1926,7 @@ struct ext_func_tab extcmdlist[] = { { ':', "look", "look at what is here", dolook, IFBURIED, NULL }, { M('l'), "loot", "loot a box on the floor", - doloot, AUTOCOMPLETE, NULL }, + doloot, AUTOCOMPLETE | CMD_M_PREFIX, NULL }, #ifdef DEBUG_MIGRATING_MONS { '\0', "migratemons", "migrate N random monsters", wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, @@ -1936,7 +1936,7 @@ struct ext_func_tab extcmdlist[] = { { 'N', "name", "same as call; name a monster or object or object type", docallcmd, IFBURIED | AUTOCOMPLETE, NULL }, { M('o'), "offer", "offer a sacrifice to the gods", - dosacrifice, AUTOCOMPLETE, NULL }, + dosacrifice, AUTOCOMPLETE | CMD_M_PREFIX, NULL }, { 'o', "open", "open a door", doopen, 0, NULL }, { 'O', "options", "show option settings, possibly change them", @@ -1953,7 +1953,7 @@ struct ext_func_tab extcmdlist[] = { { '|', "perminv", "scroll persistent inventory display", doperminv, IFBURIED | GENERALCMD | NOFUZZERCMD, NULL }, { ',', "pickup", "pick up things at the current location", - dopickup, 0, NULL }, + dopickup, CMD_M_PREFIX, NULL }, { '\0', "polyself", "polymorph self", wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { M('p'), "pray", "pray to the gods for help", @@ -1984,7 +1984,7 @@ struct ext_func_tab extcmdlist[] = { { 'S', "save", "save the game and exit", dosave, IFBURIED | GENERALCMD | NOFUZZERCMD, NULL }, { 's', "search", "search for traps and secret doors", - dosearch, IFBURIED, "searching" }, + dosearch, IFBURIED | CMD_M_PREFIX, "searching" }, { '*', "seeall", "show all equipment in use", doprinuse, IFBURIED, NULL }, { AMULET_SYM, "seeamulet", "show the amulet currently worn", @@ -2027,7 +2027,7 @@ struct ext_func_tab extcmdlist[] = { { 'A', "takeoffall", "remove all armor", doddoremarm, 0, NULL }, { C('t'), "teleport", "teleport around the level", - dotelecmd, IFBURIED, NULL }, + dotelecmd, IFBURIED | CMD_M_PREFIX, NULL }, /* \177 == aka aka ; some terminals have an option to swap it with so if there's a key labeled it may or may not actually invoke the #terrain command */ @@ -2043,9 +2043,9 @@ struct ext_func_tab extcmdlist[] = { { '\0', "timeout", "look at timeout queue and hero's timed intrinsics", wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { M('T'), "tip", "empty a container", - dotip, AUTOCOMPLETE, NULL }, + dotip, AUTOCOMPLETE | CMD_M_PREFIX, NULL }, { '_', "travel", "travel to a specific location on the map", - dotravel, 0, NULL }, + dotravel, CMD_M_PREFIX, NULL }, { M('t'), "turn", "turn undead away", doturn, IFBURIED | AUTOCOMPLETE, NULL }, { 'X', "twoweapon", "toggle two-weapon combat", @@ -2064,7 +2064,7 @@ struct ext_func_tab extcmdlist[] = { { '\0', "vision", "show vision array", wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { '.', "wait", "rest one move while doing nothing", - donull, IFBURIED, "waiting" }, + donull, IFBURIED | CMD_M_PREFIX, "waiting" }, { 'W', "wear", "wear a piece of armor", dowear, 0, NULL }, { '&', "whatdoes", "tell what a command does", @@ -2093,7 +2093,7 @@ struct ext_func_tab extcmdlist[] = { { '\0', "wizintrinsic", "set an intrinsic", wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { C('v'), "wizlevelport", "teleport to another level", - wiz_level_tele, IFBURIED | WIZMODECMD, NULL }, + wiz_level_tele, IFBURIED | WIZMODECMD | CMD_M_PREFIX, NULL }, { '\0', "wizloaddes", "load and execute a des-file lua script", wiz_load_splua, IFBURIED | WIZMODECMD | NOFUZZERCMD, NULL }, { '\0', "wizloadlua", "load and execute a lua script", @@ -3296,28 +3296,9 @@ reset_commands(boolean initial) /* non-movement commands which accept 'm' prefix to request menu operation */ static boolean -accept_menu_prefix(int (*cmd_func)(void)) +accept_menu_prefix(const struct ext_func_tab *ec) { - if (cmd_func == dopickup || cmd_func == dotip - /* eat, #offer, and apply tinning-kit all use floorfood() to pick - an item on floor or in invent; 'm' skips picking from floor - (ie, inventory only) rather than request use of menu operation */ - || cmd_func == doeat || cmd_func == dosacrifice || cmd_func == doapply - /* 'm' for removing saddle from adjacent monster without checking - for containers at */ - || cmd_func == doloot - /* offer menu to choose discoveries sort order */ - || cmd_func == dodiscovered || cmd_func == doclassdisco - /* travel: pop up a menu of interesting targets in view */ - || cmd_func == dotravel - /* wait and search: allow even if next to a hostile monster */ - || cmd_func == donull || cmd_func == dosearch - /* wizard mode ^V and ^T */ - || cmd_func == wiz_level_tele || cmd_func == dotelecmd - /* 'm' prefix allowed for some extended commands */ - || cmd_func == doextcmd || cmd_func == doextlist) - return TRUE; - return FALSE; + return (ec && ((ec->flags & CMD_M_PREFIX) != 0)); } char @@ -3551,7 +3532,7 @@ rhack(char *cmd) const struct ext_func_tab *ft = g.Cmd.commands[cmd[1] & 0xff]; int (*func)(void) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0; - if (func && accept_menu_prefix(func)) { + if (func && accept_menu_prefix(ft)) { iflags.menu_requested = TRUE; ++cmd; prefix_seen = FALSE; From 07451ca32c43eabd506977d308590a2bfb5741e2 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 4 Jan 2022 21:29:06 +0200 Subject: [PATCH 04/11] Update lua api docs --- doc/lua.adoc | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/doc/lua.adoc b/doc/lua.adoc index 1e605bc85..3410cb02b 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -14,6 +14,22 @@ Example: local str = nh.an("unicorn"); + +=== debug_flags + +Set debugging flags. + +|=== +| mongen | boolean | Do monsters generate +| hunger | boolean | Does hero's hunger-state increase +| overwrite_stairs | boolean | Allow special-file commands overwrite the stairs +|=== + +Example: + + nh.debug_flags({ mongen = false, hunger = false }); + + === dnum_name Returns the full dungeon name (as defined in dungeon.lua) for the dungeon @@ -23,6 +39,17 @@ Example: local dungeon_name = nh.dnum_name(u.dnum); + +=== doturn + +Execute gameloop once, or until multi-turn action is done if +optional boolean parameter is true. + +Example: + + nh.doturn(); + + === dump_fmtstr Returns a string replacing special format chars with game data. @@ -140,7 +167,6 @@ Example: nh.deltrap(x, y); - === ing_suffix Construct a gerund (a verb formed by appending "ing" to a noun). @@ -159,6 +185,7 @@ Example: local diff = nh.level_difficulty(); + === makeplural Pluralize the given string. @@ -227,6 +254,14 @@ Example: nh.pline("Message text to show."); +=== pushkey + +Push a key into the command queue. + +Example: + + nh.pushkey("i"); + === random Generate a random number. @@ -958,3 +993,13 @@ Example: | `"x"` | "transparent" - used for <<_map>> parts. | `"w"` | "any wall" - see <<_match>> |=== + +== Constants + +These constants are in the `nhc` table. + +|=== +| COLNO | Number of map columns +| ROWNO | Number of map rows +| DLB | 1 or 0, depending if NetHack is compiled with DLB +|=== From 9d34b727e282e2bfa3cbf7200391d2aaa3f3c882 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 4 Jan 2022 11:54:05 -0800 Subject: [PATCH 05/11] Qt: more ant extermination After the fairly recent glyph changes, the icons shown for roles and races during the character selection dialog all were all depicted by the giant ant tile. I might have noticed this sooner but usually have '-@' on the command line to bypass selection. --- doc/fixes37.0 | 2 ++ win/Qt/qt_plsel.cpp | 28 ++++++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d84be9cdd..2def97986 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -972,6 +972,8 @@ Qt: searching a text window for something that wasn't found and then searching for some other target could crash Qt: changes in glyph handling in the core introduced a bug in the "paper doll" display for inventory subset +Qt: during role selection, icons for role and race showed giant ant tile after + the glyph overhaul changes tty: redraw unexplored locations as S_unexplored rather than after map has been partially overwritten by popup menu or text display tty: previous change resulted in remnants of previous level being shown on diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index c9fd09756..4650cbdf9 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -270,11 +270,15 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) ; role->setRowCount(nrole); for (i=0; roles[i].name.m; i++) { - QTableWidgetItem *item = new QTableWidgetItem( - QIcon(qt_settings->glyphs().glyph(roles[i].malenum, fem)), - roles[i].name.m); - item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable); - role->setItem(i, 0, item); + glyph_info gi; + int glyph = monnum_to_glyph(roles[i].malenum, fem); + map_glyphinfo(0, 0, glyph, 0, &gi); + + QTableWidgetItem *item = new QTableWidgetItem( + QIcon(qt_settings->glyphs().glyph(glyph, gi.gm.tileidx, fem)), + (fem && roles[i].name.f) ? roles[i].name.f : roles[i].name.m); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + role->setItem(i, 0, item); } connect(role, SIGNAL(currentCellChanged(int, int, int, int)), this, SLOT(selectRole(int, int, int, int))); @@ -286,11 +290,15 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) ; race->setRowCount(nrace); for (i=0; races[i].noun; i++) { - QTableWidgetItem *item = new QTableWidgetItem( - QIcon(qt_settings->glyphs().glyph(races[i].malenum, fem)), - races[i].noun); - item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable); - race->setItem(i, 0, item); + glyph_info gi; + int glyph = monnum_to_glyph(races[i].malenum, fem); + map_glyphinfo(0, 0, glyph, 0, &gi); + + QTableWidgetItem *item = new QTableWidgetItem( + QIcon(qt_settings->glyphs().glyph(glyph, gi.gm.tileidx, fem)), + races[i].noun); + item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + race->setItem(i, 0, item); } connect(race, SIGNAL(currentCellChanged(int, int, int, int)), this, SLOT(selectRace(int, int, int, int))); From 0870fb32ac8fbbf49fa20a5a114d4e26e342efe7 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 4 Jan 2022 12:23:06 -0800 Subject: [PATCH 06/11] Qt tile rendering Get rid of the no longer used 'fem' argument for Qt's tile drawing routines. It's incorporated in the tile index these days. --- win/Qt/qt_glyph.cpp | 50 +++++++++++++++++++++++++++++---------------- win/Qt/qt_glyph.h | 10 ++++----- win/Qt/qt_map.cpp | 9 ++++---- win/Qt/qt_plsel.cpp | 12 +++++------ 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 75bc234d9..abb1a7254 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -103,15 +103,18 @@ NetHackQtGlyphs::NetHackQtGlyphs() setSize(tilefile_tile_W, tilefile_tile_H); } -void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int tileidx, - int x, int y, bool fem, bool reversed) +// display a map tile somewhere other than the map; +// used for paper doll and also role/race selection +void +NetHackQtGlyphs::drawGlyph( + QPainter& painter, + int glyph, int tileidx, + int x, int y, + bool reversed) { if (!reversed) { #if 0 int tile = glyph2tile[glyph]; - /* this is not required with the new glyph representation */ - if (fem) - ++tile; #else int tile = tileidx; #endif @@ -121,21 +124,29 @@ void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int tileidx, painter.drawPixmap(x, y, pm, px, py, width(), height()); } else { // for paper doll; mirrored image for left side of two-handed weapon - painter.drawPixmap(x, y, reversed_pixmap(glyph, tileidx, fem), + painter.drawPixmap(x, y, reversed_pixmap(glyph, tileidx), 0, 0, width(), height()); } } -void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph, int tileidx, - int cellx, int celly, bool fem) +// draw a tile into the paper doll +void +NetHackQtGlyphs::drawCell( + QPainter& painter, + int glyph, int tileidx, + int cellx, int celly) { drawGlyph(painter, glyph, tileidx, cellx * width(), celly * height(), - fem, false); + false); } -void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, - int tileidx, int cellx, int celly, - int border, bool reversed, bool fem) +// draw a tile into the paper doll and then draw a BUC border around it +void +NetHackQtGlyphs::drawBorderedCell( + QPainter& painter, + int glyph, int tileidx, + int cellx, int celly, + int border, bool reversed) { int wd = width(), ht = height(), @@ -143,7 +154,7 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, lox = cellx * (wd + 2), loy = celly * (ht + 2) + yoffset; - drawGlyph(painter, glyph, tileidx, lox + 1, loy + 1, fem, reversed); + drawGlyph(painter, glyph, tileidx, lox + 1, loy + 1, reversed); #ifdef TEXTCOLOR if (border != NO_BORDER) { @@ -194,12 +205,13 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, } // mis-named routine to get the pixmap for a particular glyph -QPixmap NetHackQtGlyphs::glyph(int glyphindx UNUSED, int tileidx, bool fem UNUSED) +QPixmap +NetHackQtGlyphs::glyph( + int glyphindx UNUSED, + int tileidx) { #if 0 int tile = glyph2tile[glyphindx]; - if (fem) - ++tile; #else int tile = tileidx; #endif @@ -211,9 +223,11 @@ QPixmap NetHackQtGlyphs::glyph(int glyphindx UNUSED, int tileidx, bool fem UNUSE } // transpose a glyph's tile horizontally, scaled for use in paper doll -QPixmap NetHackQtGlyphs::reversed_pixmap(int glyphindx, int tileidx, bool fem) +QPixmap +NetHackQtGlyphs::reversed_pixmap( + int glyphindx, int tileidx) { - QPixmap pxmp = glyph(glyphindx, tileidx, fem); + QPixmap pxmp = glyph(glyphindx, tileidx); #ifdef ENHANCED_PAPERDOLL qreal wid = (qreal) pxmp.width(), //hgt = (qreal) pxmp.height(), diff --git a/win/Qt/qt_glyph.h b/win/Qt/qt_glyph.h index c00a11214..8f5e9c65a 100644 --- a/win/Qt/qt_glyph.h +++ b/win/Qt/qt_glyph.h @@ -27,14 +27,14 @@ public: void drawGlyph(QPainter &, int glyph, int tileidx, int pixelx, int pixely, - bool fem, bool reversed = false); + bool reversed = false); void drawCell(QPainter &, int glyph, int tileidx, - int cellx, int celly, bool fem); + int cellx, int celly); void drawBorderedCell(QPainter &, int glyph, int tileidx, int cellx, int celly, int bordercode, - bool reversed, bool fem = false); - QPixmap glyph(int glyphindx, int tileidx, bool fem = false); - QPixmap reversed_pixmap(int glyphindx, int tileidx, bool fem = false); + bool reversed); + QPixmap glyph(int glyphindx, int tileidx); + QPixmap reversed_pixmap(int glyphindx, int tileidx); private: QImage img; diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index 85d78da64..f25067fb0 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -217,8 +217,8 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) unsigned short g = Glyph(i,j); unsigned special = Glyphflags(i, j); unsigned tileidx = Glyphtileidx(i, j); - bool femflag = (special & MG_FEMALE) ? true : false; - glyphs.drawCell(painter, g, tileidx, i, j, femflag); + + glyphs.drawCell(painter, g, tileidx, i, j); if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { painter.drawPixmap(QPoint(i * gW, j * gH), @@ -906,9 +906,8 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event) int ch = Glyphttychar(i,j); unsigned special = Glyphflags(i,j); unsigned short tileidx = Glyphtileidx(i,j); - bool femflag = (special & MG_FEMALE) ? true : false; - qt_settings->glyphs().drawCell(painter, g, tileidx, - i, j, femflag); + + qt_settings->glyphs().drawCell(painter, g, tileidx, i, j); #ifdef TEXTCOLOR if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index 4650cbdf9..f3ca26933 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -82,14 +82,14 @@ public: { } - void setGlyph(int g, int tileidx, bool fem) + void setGlyph(int g, int tileidx) { NetHackQtGlyphs& glyphs = qt_settings->glyphs(); int gw = glyphs.width(); int gh = glyphs.height(); QPixmap pm(gw,gh); QPainter p(&pm); - glyphs.drawGlyph(p, g, tileidx, 0, 0, fem); + glyphs.drawGlyph(p, g, tileidx, 0, 0, false); p.end(); setIcon(QIcon(pm)); //RLC setHeight(std::max(pm.height()+1,height())); @@ -127,7 +127,7 @@ public: glyph_info gi; int glyph = monnum_to_glyph(roles[id].malenum, MALE); map_glyphinfo(0, 0, glyph, 0, &gi); - setGlyph(glyph, gi.gm.tileidx, false); + setGlyph(glyph, gi.gm.tileidx); } }; @@ -145,7 +145,7 @@ public: glyph_info gi; int glyph = monnum_to_glyph(races[id].malenum, MALE); map_glyphinfo(0, 0, glyph, 0, &gi); - setGlyph(glyph, gi.gm.tileidx, false); + setGlyph(glyph, gi.gm.tileidx); } }; @@ -275,7 +275,7 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) map_glyphinfo(0, 0, glyph, 0, &gi); QTableWidgetItem *item = new QTableWidgetItem( - QIcon(qt_settings->glyphs().glyph(glyph, gi.gm.tileidx, fem)), + QIcon(qt_settings->glyphs().glyph(glyph, gi.gm.tileidx)), (fem && roles[i].name.f) ? roles[i].name.f : roles[i].name.m); item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); role->setItem(i, 0, item); @@ -295,7 +295,7 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) map_glyphinfo(0, 0, glyph, 0, &gi); QTableWidgetItem *item = new QTableWidgetItem( - QIcon(qt_settings->glyphs().glyph(glyph, gi.gm.tileidx, fem)), + QIcon(qt_settings->glyphs().glyph(glyph, gi.gm.tileidx)), races[i].noun); item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); race->setItem(i, 0, item); From 84af696627d7ac8c4e32ae2e9823cec7f9730c7a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 4 Jan 2022 22:28:00 +0200 Subject: [PATCH 07/11] Fix X11 tombstone string overflow --- win/X11/wintext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/X11/wintext.c b/win/X11/wintext.c index c3ce45f29..ee96a3234 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -464,7 +464,7 @@ calculate_rip_text(int how, time_t when) long cash; /* Put name on stone */ - Sprintf(rip_line[NAME_LINE], "%s", g.plname); + Sprintf(rip_line[NAME_LINE], "%.16s", g.plname); /* STONE_LINE_LEN */ /* Put $ on stone */ cash = max(g.done_money, 0L); From 723862262124d5494a3d77bf6ac0759618ac69ca Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 5 Jan 2022 13:51:44 +0200 Subject: [PATCH 08/11] Fix segfault in hypothetical case of huge COLNO --- src/mdlib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mdlib.c b/src/mdlib.c index 66cc2b893..ceb43643b 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -90,7 +90,7 @@ static void build_savebones_compat_string(void); static int idxopttext, done_runtime_opt_init_once = 0; #define MAXOPT 40 static char *opttext[120] = { 0 }; -char optbuf[BUFSZ]; +char optbuf[COLBUFSZ]; static struct version_info version; static const char opt_indent[] = " "; @@ -660,7 +660,7 @@ opt_out_words(char *str, /* input, but modified during processing */ void build_options(void) { - char buf[BUFSZ]; + char buf[COLBUFSZ]; int i, length, winsyscnt, cnt = 0; const char *defwinsys = DEFAULT_WINDOW_SYS; From e5ee580961570bd9622881ec9ee7b4b6a966a06c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 5 Jan 2022 17:35:30 +0200 Subject: [PATCH 09/11] Allocate rects dynamically ... instead of hard-coding them to 50. New allocated value is (COLNO*ROWNO)/30, which is slightly higher (56), and that formula seems to work for hypothetical larger maps too. --- include/extern.h | 1 + src/rect.c | 25 ++++++++++++++++++++----- src/save.c | 1 + 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/include/extern.h b/include/extern.h index 7c6bac9c1..de0294635 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2171,6 +2171,7 @@ extern boolean create_particular(void); /* ### rect.c ### */ extern void init_rect(void); +extern void free_rect(void); extern NhRect *get_rect(NhRect *); extern NhRect *rnd_rect(void); extern void remove_rect(NhRect *); diff --git a/src/rect.c b/src/rect.c index 26d7a1167..5aaf4a688 100644 --- a/src/rect.c +++ b/src/rect.c @@ -13,11 +13,11 @@ static boolean intersect(NhRect *, NhRect *, NhRect *); * need for room generation. */ -#define MAXRECT 50 #define XLIM 4 #define YLIM 3 -static NhRect rect[MAXRECT + 1]; +static NhRect *rect = (NhRect *) 0; +static int n_rects = 0; static int rect_cnt; /* @@ -28,12 +28,28 @@ static int rect_cnt; void init_rect(void) { + if (!rect) { + n_rects = (COLNO * ROWNO) / 30; + rect = (NhRect *) alloc(sizeof(NhRect) * n_rects); + if (!rect) + panic("Could not alloc rect"); + } + rect_cnt = 1; rect[0].lx = rect[0].ly = 0; rect[0].hx = COLNO - 1; rect[0].hy = ROWNO - 1; } +void +free_rect(void) +{ + if (rect) + free(rect); + n_rects = rect_cnt = 0; +} + + /* * Search Index of one precise NhRect. * @@ -133,9 +149,8 @@ remove_rect(NhRect* r) void add_rect(NhRect* r) { - if (rect_cnt >= MAXRECT) { - if (wizard) - pline("MAXRECT may be too small."); + if (rect_cnt >= n_rects) { + impossible("n_rects may be too small."); return; } /* Check that this NhRect is not included in another one */ diff --git a/src/save.c b/src/save.c index 3fa32a431..27106c908 100644 --- a/src/save.c +++ b/src/save.c @@ -1082,6 +1082,7 @@ freedynamicdata(void) free_waterlevel(); free_dungeons(); free_CapMons(); + free_rect(); /* some pointers in iflags */ if (iflags.wc_font_map) From 66368d7ea2c370e4f0d3de82542acb96d5aebcbc Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 5 Jan 2022 18:00:28 +0200 Subject: [PATCH 10/11] Add missing article --- src/pickup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pickup.c b/src/pickup.c index dfaa5e09f..e0e62c98f 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -3421,7 +3421,7 @@ tipcontainer(struct obj *box) /* or bag */ */ if (targetbox) pline("%s into %s.", - box->cobj->nobj ? "Objects tumble" : "Object tumbles", + box->cobj->nobj ? "Objects tumble" : "An object tumbles", the(xname(targetbox))); else pline("%s out%c", From 7205d9a417afe01752f92ed29ef45d268700a71c Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 5 Jan 2022 12:50:21 -0800 Subject: [PATCH 11/11] makedefs revision This started out as fix for a comment but ended up redoing 'limit()' and its 'temp[]' because they seemed likely to someday interfere with other uses of such generic names. No change to observable behavior. --- util/makedefs.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/util/makedefs.c b/util/makedefs.c index 09d49d84e..d2ab162d5 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -158,7 +158,7 @@ static void opt_out_words(char *, int *); static char *fgetline(FILE*); static char *tmpdup(const char *); -static char *limit(char *, int); +static char *macronamelimit(char *, int); static void windowing_sanity(void); static boolean get_gitinfo(char *, char *); @@ -1817,7 +1817,7 @@ do_dungeon(void) * for the monstr field; * run 'makedefs -m' to create src/monstr.c; ignore the complaints * about it being deprecated; - * transfer relevant generated monstr values to src/monst.c; + * transfer relevant generated monstr values to include/monsters.h; * delete src/monstr.c. */ static int mstrength(struct permonst *); @@ -2034,13 +2034,21 @@ do_questtxt(void) return; } -static char temp[32]; - -static char *limit(char* name, int pref) /* limit a name to 30 characters */ +/* limit a name to 30 characters (26 if "xyz_" prefix precedes it) */ +static char * +macronamelimit(char *name, int pref) { - (void) strncpy(temp, name, pref ? 26 : 30); - temp[pref ? 26 : 30] = 0; - return temp; + static char macronametemp[32]; + unsigned len = pref ? 26 : 30; + +#if 0 /* avoid potential warning about strncpy() not guaranteeing '\0' */ + (void) strncpy(macronametemp, name, len); + macronametemp[len] = '\0'; +#else /* strncat() does guarantee terminating '\0' */ + macronametemp[0] = '\0'; + (void) strncat(macronametemp, name, len); +#endif + return macronametemp; } void @@ -2152,7 +2160,7 @@ do_objs(void) break; } if (prefix >= 0) - Fprintf(ofp, "%s\t%d\n", limit(objnam, prefix), i); + Fprintf(ofp, "%s\t%d\n", macronamelimit(objnam, prefix), i); prefix = 0; sum += objects[i].oc_prob; @@ -2190,7 +2198,7 @@ do_objs(void) /* fudge _platinum_ YENDORIAN EXPRESS CARD */ if (!strncmp(objnam, "PLATINUM_", 9)) objnam += 9; - Fprintf(ofp, "#define\tART_%s\t%d\n", limit(objnam, 1), i); + Fprintf(ofp, "#define\tART_%s\t%d\n", macronamelimit(objnam, 1), i); } Fprintf(ofp, "#define\tNROFARTIFACTS\t%d\n", i - 1);