The g? structs had a mix of variables that were written to
the savefile, and those that were not.
For better clarity and to distinguish those that end up in
the savefile, relocate some g? variables that get written
directly to the savefile into different structs.
This updates EDITLEVEL, although technically it probably
didn't need to, since savefile contents are not changing.
Details:
gb.bases -> svb.bases
gb.bbubbles -> svb.bbubbles
gb.branches -> svb.branches
gc.context -> svc.context
gd.disco -> svd.disco
gd.dndest -> svd.dndest
gd.doors -> svd.doors
gd.doors_alloc -> svd.doors_alloc
gd.dungeon_topology -> svd.dungeon_topology
gd.dungeons -> svd.dungeons
ge.exclusion_zones -> sve.exclusion_zones
gh.hackpid -> svh.hackpid
gi.inv_pos -> svi.inv_pos
gk.killer -> svk.killer
gl.lastseentyp -> svl.lastseentyp
gl.level -> svl.level
gl.level_info -> svl.level_info
gm.mapseenchn -> svm.mapseenchn
gm.moves -> svm.moves
gm.mvitals -> svm.mvitals
gn.n_dgns -> svn.n_dgns
gn.n_regions -> svn.n_regions
gn.nroom -> svn.nroom
go.oracle_cnt -> svo.oracle_cnt
gp.pl_character -> svp.pl_character
gp.pl_fruit -> svp.pl_fruit
gp.plname -> svp.plname
gp.program_state -> svp.program_state
gq.quest_status -> svq.quest_status
gr.rooms -> svr.rooms
gs.sp_levchn -> svs.sp_levchn
gs.spl_book -> svs.spl_book
gt.timer_id -> svt.timer_id
gt.tune -> svt.tune
gu.updest -> svu.updest
gx.xmax -> svx.xmax
gx.xmin -> svx.xmin
gy.ymax -> svy.ymax
gy.ymin -> svy.ymin
Related note:
There are some pointer variables that are heads of chains that were not
moved from 'g?' to 'sv?', because they are not actually written to the
savefile directly, but the objects/monst/trap/lightsource/timer in the
chains they point to are. That can be changed, if desired.
Examples: gi.invent, gm.migrating_objs, gb.billobjs, gm.migrating_mons,
gf.ftrap, gl.light_base, gt.timer_base
Pull request from mkuoppal: avoid integer overflow when user types
digits and they're combined into a number by successively multiplying
intermediate value by 10 and adding new digit. Needed to avoid
triggering undefined behavior if the value overflows the largest
signed integer (actually long int).
This is a much more general fix than the code in the pull request,
which imposed an arbitrary limit for one aspect of tty input.
I'm not convinced that integer.h was the right place to add the new
AppendLongDigit() macro. I may not have caught all the places where
it is needed. files.c accumulates a value from digits but uses
unsigned int, so overflow won't trigger undefined behavior (although
it presumably ends up with a different value than what was intended).
options.c and coloratt.c accumulate smaller integers and have a limit
on the number of digits they'll use, so can't overflow.
Fixes#1254
It was too early to call the windowport change_color() routine
while processing the config file. The windowport was not yet
fully operational.
Now the palette option processing will just place the rgb
value into the appropriate ga.altpalette[CLR_MAX] entry.
init_sound_disp_gamewindows(void) [allmain.c] calls
change_palette() [coloratt.c] and it will call the windowport
change_color() function for each ga.altpalette[] entry that
has been set.
Notes:
The rgb values stored in ga.altpalette[] have the NH_ALTPALETTE bit set
so that the rgb value of 0 can be stored and be distinguishable from
a "not set" entry.
The NH_ALTPALETTE bit is cleared from the rgb value in change_palette()
prior to calling the windowport change_color() function.
The syntax for palette is colorname/r-g-b.
For example: palette:black/12-12-12
colorname must be one of the NH_BASIC_COLOR names or a suitable
alias for one of those 16 entries.
Some of the windowport CHANGE_COLOR functions had the wrong parameters,
perhaps due to bitrot. Those have been corrected to match the prototype.
move the custom color data into its own field in the glyphmap
and disassociate it from the unicode/utf8 stuff.
move the glyphcache stuff during options processing and parsing
into new file glyphs.c and out of utf8map.c, and make it
general, and not part of ENHANCED_SYMBOLS.
Do the groundwork for allowing glyph color customizations to
work when any symset is loaded and not restrict it only to
the enhanced1 H_UTF8 symsets.
The customizations in effect are still affiliated with a particular
symset.
Also closes#1224, but the PR itself references a data structure
made obsolete by this commit. The curses comment from the PR was
added into the code.
The PR also made several suggestions, but only the first
one has been included in this commit (and no longer based on
the handler), that being:
"allow defining colors if other symbol handling modes are used
(possibly limited to the standard 16 colors)."
FredrIQ also wrote the following suggestions in PR#1224:
Something I was also contemplating, unrelated to implementation of this
support in curses, would be the ability for the following:
allow defining colors if other symbol handling modes are used (possibly limited to the standard 16 colors)
allow defining attributes (for example: glyph:G_pet_female_kitten:U+0066/red/underline)
allow specifying glyphs as wildcards for defining global color/attribute changes
Something I also want to see are keywords for "don't change the current defined data". If this
were to be added, you could for example do this:
OPTIONS=glyph:G_*_fox:U+0064/blue
OPTIONS=glyph:G_statue_*:basechar/gray/underline
for "make all foxes use a blue color, make all statues gray with underline" without needing
to specify the relevant character for every statue. This ("basechar", "basefg", etc)
should perhaps also be added for MENUCOLORS and statushilites, so that you can, for
example, underline all items being worn without needing to specify a bunch of
near-duplicate rules for combining BUC colors + underline worn items
as per #1064
Make sure the windowcolors option can be specified more than
once without a config file warning.
Make the struct holding the details a little more extendable.
The 0x1000000 bit (NH_BASIC_COLOR bit) was used to mark
CLR_BLACK when storing it in u->ucolor. Now, all of the basic CLR_*
colors are stored that way.
The NH_BASIC_COLOR bit indicates that the value in u->ucolor is
not an rgb value, rather it is one of the 0-15 basic NetHack colors.
The window-ports need to strip the NH_BASIC_COLOR bit off before using
it for color changes.
The menus in nethackw.exe were being spaced according to the vertical
tile size of custom tiles, but the tiles were being rendered in menus
at the default size anyway, resulting in unnecessary gaps between menu
rows.
Use the default size of 16 for the vertical spacing calculation.
This implements the mechanics to use the ctrl_nhwindow() interface
capability to pass down a setting change from the core to the active
window port, without resorting to accessing a core global variable
from within the window port, and without altering the interface..
The passed setting is honored in the tty and curses window ports.
X11 and mswin receive and store the values, but no implementation
to change the menu prompt style is there yet.
Qt does not store the values or have an implementation.
The setting change is done in allmain.c immediately after
creating the WIN_INVEN window.
Remove menu_color support from the window port side of the interface.
The window port just has to honor the color parameter that was added
to the add_menu() interface definition in June 2022 commit
2770223d10, and let the core-side of
the interface handle things.
To that end, this does the following:
Removes the #define of add_menu() from include/winprocs.h and add a
real core-side add_menu() function to windows.c which acts as a
trampoline to the window port win_add_menu() function, while providing
a single location to adjust the parameters passed to the window port
function. get_menu_coloring() is now called in there.
Moves get_menu_coloring() from options.c into windows.c and makes it
static.
Removes all the calls to get_menu_coloring() from the tty, Qt, X11,
curses, and win32 interfaces and adjusts their code to simply honor
the color parameter in add_menu, similar to what the menu_headings
change from earlier today did.
Instead of just accepting an attribute, it's now possible to
use a color, or both color and attribute, for example:
OPTIONS=menu_headings:inverse
OPTIONS=menu_headings:red
OPTIONS=menu_headings:red&underline
Default is still just inverse.
This lets the player change the menu heading color without
needing to use menu colors for them.
Also makes it so the core uses NO_COLOR instead of 0, for all
the menu lines which don't have any prefedefined color.
Tested for tty, curses, x11, qt, and win32
The default engraving-in-corridor character is the same as the default
corridor symbol (and also default lit corridor one), distinguished by
color. Show it differently (in inverse vidoe, like lava vs water and
sink vs fountain) if color is Off.
It might be better to change the engraving-in-room symbol to be the
same as the room one so that they'll be more consistent with corridors;
color is probably sufficient without resorting to back-tick. But this
update hasn't done that.
When calling panic() or impossible(), create the option
of opening a browser window with most of the fields
already populated. Code for MacOS and linux is included;
other ports are affected by argument change to early_init
which are done but not tested.
To enable, define CRASHREPORT in config.h and set
CRASHREPORTURL in sysconf to (for the moment at least)
http[s]://www.nethack.org/common/contactcr.html
Adds --grep-defined option to makedefs for Makefiles.
Adds "bid" (binary identifier), an MD4 of the main nethack
binary. This is ONLY for helping (in the future) contact.html
to set the "NetHack from" field automatically for our own
binaries. This can be faked, but the user can lie so nothing
lost. There's nothing magic about MD4; other ports can use
anything that prodcues a long apparently random string we can
match against.
- new option --bidshow for us to get the MD4 of a
released binary so I can add it to the website.
Only available in wizard mode and not in nethack.6.
- typo macos -> macosx in hints file
No support for packaging builds as I'm not sure what that
would look like.
Adds a javascript helper for MacOS.
Adds a lua helper for linux (and builds and installs
nhlua).
remove a couple of extraneous files from visual studio project
remove several trailing whitespace at end of line
remove an address sanitizer bounds error during player dialog init
rework fix for darkened lit tiles (fix issue #997)
Start to add supporting code to windsound and macsound. The latter
remains commented out because I haven't had a chance to try
it on macOS yet.
In order to test it out, I added two more stock sounds:
sa2_xplevelup and sa2_xpleveldown.
Having a hardcoded relative path worked okay with the nmake Makefile
build but cause problems on a visual studio build. The CI caught that
right away.
Remove the relative paths, and add additional include directories for
the resouce compiler to search in the Makefile and in visual studio.
Expand windsound to support SNDCAP_USERSOUNDS (existing),
SNDCAP_SOUNDEFFECTS, SNDCAP_HEROMUSIC.
Place a small number of wav files into sound/wav that are considered
more specific to some game stuff in the core, namely: playing
instruments by the hero, squeaky board traps. The intention is that
those ones can be integrated into the game without requiring user
file deposits or mappings. Building soundlib support for sound/windsound
searches for them as resources, so they should "just work."
No actual instrument playback is available in the base sound/windsound
soundlib implementation (yet, at least), so it works around that in
a cheap way by using the note-variant wav sounds to concoct the
notes. There are better ways of doing music generation than that,
of course, but this will do in the early going. Any other soundlib
port (such as Qt) can probably easily do the exact same thing. If it
can play USER_SOUNDS, it can almost certainly use the
sound/wav/se_squeak*.wav and sound/wav/sound_*.wav files for
SND_HEROMUSIC and squeaky board sounds soundeffects.
A few of the se_ sounds in sound/wav are free yet licensed, and
there is a file called attributions.txt to meticulously attempt
to comply with the two license variations involved.
SND_SOUNDEFFECTS_AUTOMAP
If SND_SOUNDEFFECTS_AUTOMAP is defined, and a SND_LIB_ interface
that supports SNDPROC_SOUNDEFFECTS is also defined to integrate
soundlib support, the following gets added:
o If sounddir is defined (existing longstanding feature that's
been used with USER_SOUNDS for many, many years) any wav file
present in SOUNDDIR with a name that matches one of the defined
sound effects in include/sndproc.h will get played each time
that soundeffect comes up. So, just drop appropriate wav files
into sounddir and rename it to match.
No tedious config file entries are required to get soundeffects.
[ The only config file change required is to
set SOUNDDIR to point to your directory with the wav files.
Note: SOUNDDIR only works in your config file if NetHack
was built with USER_SOUNDS defined. ]
This is new so there may certainly be some bugs in here.
Please kindly report them if you encounter any.
For those that don't read C very well, these are the file names
that should trigger the SOUNDEFFECTS_AUTOMAP, assuming it is working.
se_faint_splashing.wav
se_crackling_of_hellfire.wav
se_heart_beat.wav
se_typing_noise.wav
se_hollow_sound.wav
se_rustling_paper.wav
se_crushing_sound.wav
se_splash.wav
se_chains_rattling_gears_turning.wav
se_smashing_and_crushing.wav
se_gears_turning_chains_rattling.wav
se_loud_splash.wav
se_lound_crash.wav
se_crashing_rock.wav
se_sizzling.wav
se_crashing_boulder.wav
se_boulder_drop.wav
se_item_tumble_downwards.wav
se_drain_noises.wav
se_ring_in_drain.wav
se_groans_and_moans.wav
se_scratching.wav
se_glass_shattering.wav
se_egg_cracking.wav
se_gushing_sound.wav
se_glass_crashing.wav
se_egg_splatting.wav
se_sinister_laughter.wav
se_blast.wav
se_stone_breaking.wav
se_stone_crumbling.wav
se_snakes_hissing.wav
se_loud_pop.wav
se_clanking_pipe.wav
se_sewer_song.wav
se_monster_behind_boulder.wav
se_wailing_of_the_banshee.wav
se_swoosh.wav
se_explosion.wav
se_crashing_sound.wav
se_someone_summoning.wav
se_rushing_wind_noise.wav
se_splat_from_engulf.wav
se_faint_sloshing.wav
se_crunching_sound.wav
se_slurping_sound.wav
se_masticating_sound.wav
se_distant_thunder.wav
se_applause.wav
se_shrill_whistle.wav
se_someone_yells.wav
se_door_unlock_and_open.wav
se_door_open.wav
se_door_crash_open.wav
se_dry_throat_rattle.wav
se_cough.wav
se_angry_snakes.wav
se_zap_then_explosion.wav
se_zap.wav
se_horn_being_played.wav
se_mon_chugging_potion.wav
se_bugle_playing_reveille.wav
se_crash_through_floor.wav
se_thump.wav
se_scream.wav
se_tumbler_click.wav
se_gear_turn.wav
se_divine_music.wav
se_thunderclap.wav
se_sad_wailing.wav
se_maniacal_laughter.wav
se_rumbling_of_earth.wav
se_clanging_sound.wav
se_mutter_imprecations.wav
se_mutter_incantation.wav
se_angry_voice.wav
se_sceptor_pounding.wav
se_courtly_conversation.wav
se_low_buzzing.wav
se_angry_drone.wav
se_bees.wav
se_someone_searching.wav
se_guards_footsteps.wav
se_faint_chime.wav
se_loud_click.wav
se_soft_click.wav
se_squeak.wav
se_squeak_C.wav
se_squeak_D_flat.wav
se_squeak_D.wav
se_squeak_E_flat.wav
se_squeak_E.wav
se_squeak_F.wav
se_squeak_F_sharp.wav
se_squeak_G.wav
se_squeak_G_sharp.wav
se_squeak_A.wav
se_squeak_B_flat.wav
se_squeak_B.wav
se_someone_bowling.wav
se_rumbling.wav
se_loud_crash.wav
se_deafening_roar_atmospheric.wav
se_low_hum.wav
se_laughter.wav
se_cockatrice_hiss.wav
se_chant.wav
se_cracking_sound.wav
se_ripping_sound.wav
se_thud.wav
se_clank.wav
se_crumbling_sound.wav
se_soft_crackling.wav
se_crackling.wav
se_sharp_crack.wav
se_wall_of_force.wav
se_alarm.wav
se_kick_door_it_shatters.wav
se_kick_door_it_crashes_open.wav
se_bubble_rising.wav
se_bolt_of_lightning.wav
se_board_squeak.wav
se_board_squeaks_loudly.wav
se_boing.wav
se_crashed_ceiling.wav
se_clash.wav
se_crash_door.wav
se_crash.wav
se_crash_throne_destroyed.wav
se_crash_something_broke.wav
se_kadoom_boulder_falls_in.wav
se_klunk_pipe.wav
se_kerplunk_boulder_gone.wav
se_klunk.wav
se_klick.wav
se_kaboom_door_explodes.wav
se_kaboom_boom_boom.wav
se_kaablamm_of_mine.wav
se_kaboom.wav
se_splat_egg.wav
se_destroy_web.wav
se_iron_ball_dragging_you.wav
se_iron_ball_hits_you.wav
se_lid_slams_open_falls_shut.wav
se_chain_shatters.wav
se_furious_bubbling.wav
se_air_crackles.wav
se_potion_crash_and_break.wav
se_hiss.wav
se_growl.wav
se_canine_bark.wav
se_canine_growl.wav
se_canine_whine.wav
se_canine_yip.wav
se_canine_howl.wav
se_feline_yowl.wav
se_feline_meow.wav
se_feline_purr.wav
se_feline_yip.wav
se_feline_mew.wav
se_roar.wav
se_snarl.wav
se_buzz.wav
se_squeek.wav
se_squawk.wav
se_squeal.wav
se_screech.wav
se_equine_neigh.wav
se_equine_whinny.wav
se_equine_whicker.wav
se_bovine_moo.wav
se_bovine_bellow.wav
se_wail.wav
se_groan.wav
se_grunt.wav
se_gurgle.wav
se_elephant_trumpet.wav
se_snake_rattle.wav
se_hallu_growl.wav
This needs further testing. At the moment only windsound has
this.
If nobody else looks into it for Qt, I'll take a look in a
few days.
A recent commit to alloc.c by Keni drew attention to the fact that
there are extern prototypes scattered around in various .c files.
Those can make use of ATTRNORETURN (non-gcc compilers and C23) the
same way the prototypes in extern.h can, and they were overlooked
when ATTRNORETURN was first added.
bkglyph variable gets initialized to GLYPH_UNEXPLORED so ends
up being returned by get_bk_glyph() if something more interesting
wasn't chosen in the switch statement.
The Windows win32 interface will then use the tile mapped to
GLYPH_UNEXPLORED as a background. The tile is 16x16 all black
pixels. That looked very odd.
Treat GLYPH_UNEXPLORED as an out-of-range value.
Closes#929
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
^ ^
Instead of using index() macro defined to strchr, use C99 strchr.
Instead of using rindex() macro defined to strrchr, use C99 strrchr.
If you want to try building on a platform that doesn't offer those
two functions, these are available:
define NOT_C99 /* to make some non-C99 code available */
define NEED_INDEX /* to define a macro for index() */
define NEED_RINDX /* to define a macro for rindex() */
This replaces the old pushq/saveq arrays (which were used to save
the keys pressed by the user for repeating a previous command)
with a new command queue. This means there's no hard-coded limit
to the saved keys, and it can repeat extended commands which are
not bound to any key.
Change the inner workings of the experimental TTY_PERM_INVENT.
Switch to delivering the content to tty for the experimental perm_invent
via the existing window port interface (start_menu(), add_menu(), end_menu).
This also adds a new window port interface call ctrl_nhwindow() for
delivering information to the window port, and/or obtaining specific
information from the window port. The information and requests can
be extended as required. To be documented later once the changes settle
down.
Due to the intrusive nature of these changes and the possibility of
some bugs in the new code, I'm going to leave TTY_PERM_INVENT commented
out in the repository for a day or two. Anyone wishing to test it out
can do so by uncommenting TTY_PERM_INVENT in config.h.
One of the drivers of this change was that screen coordinates require a
type that can hold values greater than 127. Parameters to the window
port routines require a large type in order to be able to have values
a fair bit larger than COLNO and ROWNO passed to them, particularly for
their use to the right of the map window.
This splits the uses of xchar into 3 different situations, and adjusts
their type and size:
xchar
|
-----------------------
| | |
coordxy xint16 xint8
coordxy: Actual x or y coordinates for various things (moved to 16-bits).
xint16: Same data size as coordxy, but for non-coordinate use (16-bits).
xint8: There are only a few use cases initially, where it was very
plain to see that the variable could remain as 8-bits, rather
than be bumped to 16-bits. There are probably more such cases
that could be changed after additional review.
Note: This first changed all xchar variables to coordxy. Some were
reviewed and got changed to xint16 or xint8 when it became apparent that
their usage was not for coordinates.
This increments EDITLEVEL in patchlevel.h
Add a non-string identifier to window_procs for use in runtime
identification of the current window port being used.
Use a macro WPID to add the identification at the top of the
various existing window_procs declarations. It expands to the
existing text string, as well as the newly added field wp_id
with a wp_ identifier.
For example, WPID(tty) expands to: "tty", wp_tty
The generated wp_tty must be present in the wp_ids enum at
the top of include/winprocs.h.
The WINDOWPORT(x) macro has been updated to expand to a simple
value comparison (port.wp_id == wp_x), instead of a
string comparison.