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
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 evolves and hopefully eases the game-build requirements by
removing game-compile dependencies on any header files generated
by the makedefs utility, including:
date.h dependency and its inclusion is removed and comparable functionality
is produced at runtime via new file src/date.c.
pm.h dependency and its inclusion is removed and comparable functionality is
produced by moving the monster definitions from monst.c into new header
file called monsters.h and altering them slightly. The former pm.h header
file #define PM_ values are now replaced with appropriate emitted enum
entries during the compiler preprocessing.
onames.h dependency and its inclusion is removed and comparable functionality
is produced by moving the object definitions from objects.c into new header
file called objects.h and altering them slightly. The former onames.h header
file #define values are now replaced with appropriate emitted enum entries
during the compiler preprocessing.
artilist.h has been slightly altered, and the former onames.h artifact-related
header file #define ART_ values are now replaced with appropriate emitted enum
entries during the compiler preprocessing.
makedefs can still produce date.h (makedefs -v), pm.h (makedefs -p), and
onames.h (makedefs -o) for reference purposes. They won't be used during
the compiler.
The other uses for makedefs remain. They are used to prepare external
file content that the game utilizes, not prerequisite code for the
compile:
makedefs -d (database)
makedefs -r (rumors)
makedefs -h (oracles)
makedefs -s (epitaphs, engravings, bogusmons)
date.c
Pull the code for date/time stamping from mdlib.c into date.c.
Set date.o to be dependent on source files, header files, and .o files
so that date.o is rebuilt from date.c when any of those changes, thus
ensuring an accurate date/time stamp. It also includes git sha
functionality formerly done by makedefs writing #define directives
into include/date.h. For unix it passes the git info on
the compile line for date.c (via sys/unix/hints/linux.2020, macOS.2020)
nethack --dumpenums (optional, but on by default)
Allow developer to obtain some internal enum values from NetHack
without having to resort to an external utility such as
makedefs.
Uncomment #define NODUMPENUMS in config.h to disable this.
The updates to sys/windows/Makefile.gcc have not been tested yet.
Some support of new code #defines to faciliate cross-compiling:
OPTIONS_AT_RUNTIME If this is defined, code to support obtaining
the compile time options and features is
included. If you define this, you'll also have
to compile sys/mdlib.c and link the resulting
object file into your game binary/executable.
CROSSCOMPILE Flags that this is a cross-compiled NetHack build,
where there are two stages:
1. makedefs and some other utilities are compiled
on the host platform and executed there to generate
some output files and header files needed by the
game.
2. the NetHack game files are compiled by a
cross-compiler to generate binary/executables for
a different platform than the one the build is
being run on. The executables produced for the
target platform may not be able to execute on the
build platform, except perhaps via a software
emulator.
The 2-stage process (1. host, 2.target) can be done
on the same platform to test the cross-compile
process. In that case, the host and target platforms
would be the same.
CROSSCOMPILE_HOST Separates/identifies code paths that should only be
be included in the compile on the host side, for
utilities that will be run on the host as part of
stage 1 to produce output files needed to build the
game. Examples are the code for makedefs, tile
conversion utilities, uudecode, dlb, etc.
CROSSCOMPILE_TARGET Separates/identifies code paths that should be
included on the build for the target platform
during stage 2, the cross-compiler stage. That
includes most of the pieces of the game itself
but the code is only flagged as such if it must
not execute on the host.
If you don't define any of those, things should build as before.
One follow-on change that is likely required is setting the new dependency
makedefs has on src/mdlib.c in Makefiles etc.
More information about the changes:
makedefs
- splinter off some of makedefs functionality into a separate file
called src/mdlib.c.
- src/mdlib.c, while included during the compile of makedefs.c
for producing the makedefs utility, can also be compiled
as a stand-alone object file for inclusion in the link step
of your NetHack game build. The src/mdlib.c code can then
deliver the same functionality that it provided to makedefs
right to your NetHack game code at run-time.
For example, do_runtime_info() will provide the caller with
the features and options that were built into the game.
Previously, that information was produced at build time on the
host and stored in a dat file. Under a cross-compile situation,
those values are highly suspect and might not even reflect the
correct options and setting for the cross-compiled target
platform's binary/executable. The compile of those values and
the functionality to obtain them needs to move to the target
cross-compiler stage of the build (stage 2).
- date information on the target-side binary is produced from
the cross-compiler preprocessor pre-defined macros __DATE__
and __TIME__, as they reflect the actual compile time of the
cross-compiled target and not host-side execution of a utility
to produce them. The cross-compiler itself, through those
pre-defined preprocessor macros, provides them to the target
platform binary/executable. They reflect the actual build
time of the target binary/executable (not values produced
at the time the makefiles utility was built and the
appropriate option selected to store them in a text file.)
- most Makefiles should not require adding the new file
src/mdlib.c because util/makedefs.c has a preprocessor
include "../src/mdlib.c" to draw in its contents. As previously
stated though, the Makefile dependency may be required:
makedefs.o: ../util/makedefs.c ../src/mdlib.c
^^^^^^^^^^^^^^^
Bug report #H7156 listed three items, all relating to perm_invent:
1) it shouldn't persist across save/restore since restore might be
on a system which doesn't have enough room to display it (report
actually complained that config file setting was ignored when
restoring old games, which is an expected side-effect for options
that persist across save/restore);
2) permanent inventory wasn't updated when using scroll of charging;
3) attempts to update permanent inventory during restore could lead
to crash if it tries to access shop cost for unpaid items.
Items (2) and (3) have already been fixed. This fixes (1).
Replace 'flags.perm_invent' with a dummy flag, preserving save files
while removing it from flags. Add 'iflags.perm_invent' to hold the
value of the perm_invent option.
The win32 files that are updated here haven't been tested. Whichever
branch contains the curses interface needs to be updated; ditto for
any other pending/potential interfaces which support perm_invent.
Black is a better choice given that the map background
will always be black. This also creates a better polished
experience when all window backgrounds are set to black.
I'll push a formatting guide at some point. There may still be
outstanding changes, but please feel free to resolve those as you arrive
a them.
To the best of my knowledge, there is no changes to the actual code
content, but the formatter does have the occasional bug. If you run into
an issue, please fix it!
There is a lot of code affected by this, and Pat Rankin correctly
observes that it would be better to store roguelike as a level flag
rather than just using Is_rogue_level. A note for the future.
Pat noted that I neglected to drop the SCCS lines on the files I've been
committing, so clean up those and any others I could find where the SCCS
line date is out of date.
Tested on the unix port; I've updated as many other ports as I can figure
out but they're not tested. See window.doc for info on the changed banner
lines. Also adds the ability to override the generic "Unix" port - used now to get
"MacOSX" into the version line instead of "Unix" (so we don't scare people who don't
know what's going on).