The consolidation of global variables from scattered source
files into decl.c and declared in decl.h was begun in 3.7.0.
Their placement in common files was done for centralized
initialization and potential re-initialization during a
"play again" scenario.
It wasn't really necessary for all of them to be housed in a
single huge structure to meet the "play again" requirement,
and the single huge structure has been a little unwieldy when
it comes to maintenance.
Following this commit, instead of one single extremely large structure
named 'g' to house all of the relocated global variables, they
are distributed into several ga through gz.
To make things easy for the developer, each variable is placed
into the struct corresponding to the starting letter of the variable.
That way, no lookup is required in order to know which struct houses
a particular variable, it is a simple match to the starting letter
for all the centralized global variables.
A global variable named 'amulets', would be found in ga.
ga.amulets
^ ^
A global varable named 'move', would be found in gm.
gm.moves
^ ^
A global variable named 'val_for_n_or_more' would be found in gv.
gv.val_for_n_or_more
^ ^
A global variable named 'youmonst' would be found in gy.
gy.youmonst
^ ^
Change Qt's 6x3 grid of worn/wielded equipment so that it is facing
the player: hero's right hand side is shown in the grid's left column
and left hand side is shown in its right column. Middle column is
unchanged.
I forced a test compile to -std=c++20 mostly to see what we would
be up against. There was only a small number of things and they
are corrected in this commit.
c++20 has some issues with comparisons and bit twiddling between
different enums.
The vendor-supplied Qt5 header files triggered some of those issues as
well, so the qt_pre.h and qt_post.h NetHack header files were adjusted
to make those new warnings go away. I have not tested Qt6 under the
new compiler and c++ version yet.
Because there are multiple pragmas in qt_pre.h now, the conditional
ifdef structure in there was modified a little to make maintenance
simpler and have a single pragma push at the top. The pragma pop
comes after the Qt vendor-supplied header files, and is done
in qt_post.h.
The display.h macro cmap_to_glyph() was used in
a Qt c++ file and triggered a series of warnings because of that.
Rather than write c++20-friendly versions of those macros, the
simple fix is to provide a function on the C side of things
to front the cmap_to_glyph() macro, so fn_cmap_to_glyph()
was added.
Also thrown into this commit, PatR picked up on the fact that for
yesterday's new warning in qt_menu.cpp, the compiler had correctly
picked up on the fact that the format range of the variable 'cash'
had been correctly upper-capped at 999999999L in the warning message
because of an assignment prior. He suggested that perhaps by also adding
if (cash < 0)
cash = 0;
the warning might be eliminated altogether.
After a test, that was proven to be correct, so yesterday's
more-kludgy change is reverted and replaced with that variable
variable restriction ahead of the snprintf().
When tiles fail to load, the Qt interface switches to the text map.
But it wasn't inhibiting the player from trying to switch to tiles
map. Also, when the text map was in use it was forcing the paper
doll inventory subset to be disabled regardless of whether the map
was by choice or because tiles wouldn't load. Allow the paper doll
in combination with the text map if tiles got loaded successfully.
Our C() macro conflicts with Qt6 usage, so #undef C has added. Move
that from nearly every qt_*.cpp into qt_pre.h where other similar
fixups are handled.
The Qt paper doll highlights known blessed/uncursed/cursed items with
a color border. It was trying to force obj->bknown for non-blinded
priest[ess] but passed the old role letter argument to Role_if()
instead of the monster number that's used these days. It was also
potentially modifying an invent item in a way that's observable to
the player but not updating persistent inventory to show that.
Probably didn't matter though; I don't think the situation it checks
for can occur anymore. On the off chance that it could, move the
check-and-set out of #if ENHANCED_PAPERDOLL so that same inventory
update would occur for ordinary paper doll even though that doesn't
care about displayed items' bless/curse state.
This fixes the broken paper doll display. Changes for new glyphs
added code to an 'if' but not to the corresponding 'else'.
Showing map column 0 as something other than blank is still a problem.
The splash window shows a red dragon and says "loading". I'm pretty
sure that that used to be a crisp image but it is now a fuzzy one.
It doesn't use glyphs or their tiles so shouldn't have been affected
by changes to them.
The walls for the mines, gehennom, knox, and sokoban had been
changed at the "tile"-level, with no awareness of the core game,
or non-tile interfaces.
- Expand the glyphs to include a set of walls for the main level
as well as each of those mentioned above.
Altars had been adjusted at the map_glyphinfo() level to substitute
some color variations on-the-fly for unaligned, chaotic, neutral,
lawful altars, and shrines. The tile interface had no awareness of
the feature.
- Expand the glyphs to include each of the altar variations that
had been implemented in the display code for tty-only. This required
the addition of four placeholder tiles in other.txt. Someone with
artistic skill will hopefully alter the additional tiles to better
reflect their intended purpose.
Explosions had unique tiles in the tile window port, and the display
code for tty tinkered with the colors, but the game had very little
awareness of the different types of explosions.
- Expand the glyphs to include each of the explosion types: dark,
noxious, muddy, wet, magical, fiery and frosty.
Pile-markers to represent a pile had been introduced at the
display-level, without little to no awareness by the core game.
- Expand the glyphs to include piletops, including objects,
bodys, and statues.
Recently male and female variations of tiles and monsters had been
had been introduced, but the mechanics had been mostly done at the
display-level through a marker flag. The window port interface then
had to increment the tile mapped to the glyph to get the female version
of the tile.
- Expand the glyphs to include the male and female versions of the
monsters, and their corresponding pet versions, ridden, detected
versions and statues of them.
Direct references to GLYPH_BODY_OFF and GLYPH_STATUE_OFF
in object_from_map() in pager.c were getting incomplete results.
- Add macros glyph_to_body_corpsenm(glyph) and
glyph_to_statue_corpsenm(glyph) macros for obtaining the corpsenm
value after passing the glyph_is_body() or glyph_is_statue() test.
Other relevant notes:
- The tile ordering in the win/share/*.txt tile files has been altered,
other.txt in particular.
- tilemap.c has had a lot of alterations to accommodate the expanded
glyphs. Output that is useful for troubleshooting will end up in
tilemappings.lst if OBTAIN_TILEMAP is defined during build.
It lists all of the glyphs and which tile it gets mapped to, and also
lists each tile and some of the references to it by various glyphs.
- An array glyphmap[MAXGLYPH] is now used. It has an entry for each
glyph, ordered by glyph, and once reset_glyphs(glyph) has been run, it
contains the mapped symindex, default color, glyphflags, and tile
index.
If USE_TILES is defined during build, the tile.c produced from the
tilemap utility populates the tileidx field of each array element with
a glyph-to-tile mapping for the glyph. Later on, when reset_glyphmap()
is run, the other fields of each element will get populated.
- The glyph-to-tile mapping is an added field available to a window
port via the glyphinfo struct passed in the documented interface. The
old glyph2tile[] array is gone. The various active window ports that
had been using glyph2tile[] have been updated to use the new interface
mechanism. Disclaimer: There may be some bug fixing or tidying
required in the window port code.
- reset_glyphmap() is called after config file options parsing
has finished, because some config file settings can impact the results
produced by reset_glyphmap().
- Everything that passes the glyph_is_cmap(glyph) test must
return a valid cmap value from glyph_to_cmap(glyph).
- An 'extern glyph_info glyphmap[MAX_GLYPH];' is inserted into the
top of only the files which need awareness of it, not inserted into
display.h. Presently, the only files that actually need to directly
reference the glyphmap[] array are display.c, o_init.c (for shuffling
the tiles), and the generated tile.c (if USE_TILES is defined).
- Added an MG_MALE glyphflag to complement the MG_FEMALE glyphflag.
- Provide an array for wall colorizations. reset_glyphmap() will draw
the colors from this array: int array wallcolors[sokoban_walls + 1];
The indices of the wallcolors array are main_walls (0), mines_walls
(1), gehennom_walls (2), knox_walls (3), and sokoban_walls (4).
In future, a config file option for adjusting the wall colors and/or
an 'O' option menu to do the same could be added. Right now, the
initializaton of the wallcolors[] array entries in display.c leaves the
walls at CLR_GRAY, matching the defsym color.
- Most of the display-level kludges for some of the on-the-fly
interface features have been removed from map_glyphinfo() as they
aren't needed any longer. These glyph expansions adhere more closely to
the original glyph mechanics of the game.
- Because the glyphs are re-ordered and expanded, an update to
editlevel will be required upon merge of these changes.
Override the 'implicit_uncursed' option when formatting an item
of equipment for its paper doll tool tip. Each tile is outlined
in yellow if known to be uncursed; force "uncursed" in the tool
tip text for the same situation.
Also add or revise some comments.
For the tool tips shown if you let the mouse pointer hover over
any of the cells in the paperdoll (inventory subset showing
worn and wielded items), remove the trailing period and add a
leading space and a trailing space. Improves readability.
Simplify a recent change to the screen layout. Qt can calculate
the details and the recent code resulted in a slight amount of
blank space between the paperdoll and its resize hotspot.
Fix an off-by-one bug in the paperdoll resize routine. (The one
pixel margin at the top was being overlooked.)
When wielding a two-handed weapon, Qt's paper doll shows uwep
in the shield slot as well as in the weapon slot to reflect
that it's occupying both hands. Make the shield slot's copy
be a mirror image of the weapon's tile so that it looks less
like wielding two weapons.
Three-way swap: move blindfold to alt-weapon slot, alt-weapon to
quiver slot, and quiver to former blindfold slot. Affects first
and third rows of the 6x3 grid.
Before |After
x H b | b H q
S a w | S a w
G C q | G C x
[x=alt-weapon, H=helmet, b=blindfold, S=shield, a=amulet, w=weapon,
G=gloves, C=cloak, q=quiver; bottom three rows not changed so not
shown.]
New for Qt, moving the mouse over one of the slots in the paperdoll
inventory subset and letting it pause there will use Qt's tool tip
mechanism to give a description of the item under the pointer, if
there is one, or of what the slot would contain when there isn't.
So "e - uncursed leather gloves (being worn)" or "no gloves" when
the pointer is over the glove slot. If you do something with the
keyboard to make the paperdoll change while the mouse is still
hovering, you'll need to move the pointer slightly to have Qt
recheck for tool tip at that spot. It may be feasible to force
an immediate update, but I'm satisfied with how it's working.
Interestingly, you can move pointer and hover while yn_function()
has asked you to pick an inventory item and is waiting for an
answer. Mostly useful for Take-off/Remove or #adjust.
Clicking on the paper doll inventory subset window will cause
the '*' command (#seeall) to execute. They convey the same
information (unless multiple leashes or multiple light sources
are in use; seeall lists all of them instead of just the first
of each) but the doll shows the info with a small grid of map
tiles and seeall shows it with an inventory display of worn and
wielded items plus tools in active use.
Ideally it should show information about a specific item as a
"tool tip" when the mouse hovers over one of the doll slots.
I don't know whether I'll ever attempt to tackle that or even
if that's feasible with Qt. Perhaps use right click instead.
Qt is capable of using an ascii map, and does so on the rogue level.
So failing to load tiles doesn't need to quit; it can continue in
text mode.
Not extensively tested. This disables the paper doll when the ascii
map is forced (either via options settings or due to tiles loading
failure, but not when simply on the rogue level) rather than trying
to display it with object class characters.
When items in the paper doll inventory subset (primary worn and
wielded items) have known BUC state, indicate what that is. It
now draws a one pixel wide white border around each doll tile,
and if BUC is known, that border gets its color changed (red for
known cursed, yellow for known uncursed, cyan for known blessed).
That isn't very visual so the first pixel inside the tile is
overwritten with the same color, and alternating pixels are also
overwritten for the second rectangle within. The 2..3 pixel wide
border is visible without cluttering the tile for 'normal' sized
paper doll. The tiles are allowed to be scrunched down to as
small as 6x6 so there won't be much left after 1 or 2 around the
edge are replaced.
Initially I was going to try to highlight welded items but the
more general BUC highlighting is simpler and usually more useful
to the player.
The qt_map.* bits are just reformatting. I was looking at pet
and pile annotations as a way to do BUC annotations but decided
not to attempt that.
During hallucination, actions which triggered update of persistent
inventory made Qt's display of map tiles for equipped objects have
those tiles switch randomly, but ordinary move-by-move fluctations
applied to floor objects left them alone.
Initially I took out hallucination of inventory items altogether,
but ended up putting that back and changing the floor hallucination
to affect Qt's paper doll too. The display.h change isn't needed
but I've left it in.
Enhance the "Qt Settings" dialog box to provide control over the
paper doll subset of inventory displayed between the message and
status windows (above the map). A ton of flailing about for a
fairly small but useful change in functionality.
Old dialog (no title):
| [ ] Zoomed -- check box
| "Width:" [ ] -- number entry spinner
| "Height:" [ ] -- ditto
| "Font:" [ ] -- Huge:18pt, Large:14, Medium:12, Small:10, Tiny:8
| [ Dismiss ] -- button
New dialog:
| "Qt NetHack Settings"
|
| "Map:" [ ] "Zoomed" -- check box
| "Tile Width" [ ] -- number entry spinner
| "Tile Height" [ ] -- ditto
| "Invent:" [ ] "Shown" -- check box
| "Doll Width" [ ] -- number entry spinner
| "Doll Height" [ ] -- ditto
| "Font:" [ ] -- Huge:18pt, Large:14, Medium:12, Small:10, Tiny:8
| [ Dismiss ] -- button
The inventory subset can now be suppressed. When shown (the default),
its size can be set independently of the map tiles' size. I've set
the default to be 32x32 tiles instead of 16x16 used for the map.
The settings are saved and restored automatically by Qt, and persist
not just across save/restore cycles but into new games. (That's not
a change, just a reminder.)
Move the nine #undef's common to all qt_*.cpp sources into qt_pre.h.
Make "hack.h" usage consistent; always enclose withing 'extern "C {'
and '}' even though only some of the sources care.
In case you haven't seen it, the Qt screen layout is (a bigger
instance of):
+--------------------+------+--------------------------------+
| messages |invent| status |
| |subset| |
| | | |
| | | |
+------------------------------------------------------------+
| map |
| |
...
| |
+------------------------------------------------------------+
where some status fields include an icon and the inventory subset is
a miniature map showing a paper doll-style display of object tiles
for worn and wielded items. The two separating lines in the top half
can be dragged to resize the three windows there. The default message
window width to too small to see full text of some messages but can
be scrolled left and right. The window for the equipped subset of
inventory is unconditionally present; 'perm_invent' is a no-op.
Paper doll inventory layout (view with fixed-width font...):
Old New two-hand dual-wield
x H b x H b x H b . H b
S " w S " w W " W X " w
G C G G C q G C q G C q
= A = = A = = A = = A =
. U . l U L l U L l U L
. F . . F . . F . . F .
Legend:
'.' = blank, b = blindfold, '"' = amulet, '=' = left and right rings,
w/W = primary weapon, x/X = alternate/secondary weapon, q = quiver,
H = helmet, S = shield, G = gloves, C = cloak, A = suit, U = shirt,
F = boots, l = leash, L = active light source (lamp/candle/Sunsword).
Slots which don't have something equipped are shown blank.
'q' was missing; 'G' used to be shown on both sides. 'l' and 'L' are
new; for either, it picks the first one in inventory that's in active
use. The 'S' and 'x' slots vary depending upon weapon situation
since wearing a shield, wielding a two-handed weapon, and engaging in
two-weapon combat are all mutually exclusive.
In file included from ../win/Qt/qt_bind.cpp:20:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:3:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGuiDepends:3:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/QtCore:4:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qglobal.h:1302:
/usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qflags.h:121:41: warning: declaration shadows a
variable in the global namespace [-Wshadow]
Q_DECL_CONSTEXPR inline QFlags(Enum flags) noexcept : i(Int(flags)) {}
^
[…]
../include/flag.h:390:29: note: previous declaration is here
extern NEARDATA struct flag flags;
^
In file included from ../win/Qt/qt_click.cpp:18:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:3:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGuiDepends:3:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/QtCore:36:
/usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qcache.h:191:15: warning: declaration shadows a
variable in the global namespace [-Wshadow]
Node *u = n;
^
../include/decl.h:219:23: note: previous declaration is here
E NEARDATA struct you u;
^
[…]
In file included from ../win/Qt/qt_click.cpp:18:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:5:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qabstracttextdocumentlayout.h:45:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qtextlayout.h:47:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qcolor.h:44:
/usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qrgb.h:66:46: warning: declaration shadows a
variable in the global namespace [-Wshadow]
inline Q_DECL_CONSTEXPR QRgb qRgb(int r, int g, int b)// set RGB value
^
../include/decl.h:1208:27: note: previous declaration is here
E struct instance_globals g;
^
[…]
In file included from ../win/Qt/qt_glyph.cpp:21:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:5:
In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qabstracttextdocumentlayout.h:48:
/usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qpalette.h:107:49: warning: declaration shadows a
variable in the global namespace [-Wshadow]
inline void setCurrentColorGroup(ColorGroup cg) { data.current_group = cg; }
^
../include/decl.h:1216:30: note: previous declaration is here
E const struct const_globals cg;
^