diff --git a/.gitattributes b/.gitattributes index 4abc1c90b..7ea33e5c1 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,6 +2,7 @@ *.cpp NHSUBST *.sh NHSUBST *.pl NHSUBST +*.md NHSUBST Porting NHSUBST README NHSUBST * text=auto diff --git a/.gitignore b/.gitignore index 5615fe332..ab0e33e93 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ Makefile.gcc Makefile-orig Makefile.bcc-orig Makefile.gcc-orig +make.prefs *.suo *.pdb *.ilk diff --git a/Contributing.md b/Contributing.md new file mode 100644 index 000000000..c304499ad --- /dev/null +++ b/Contributing.md @@ -0,0 +1,15 @@ +If you are making a GitHub pull request for NetHack, please follow these guidelines: + +1. The 50/72 Rule: Keep the subject line (the first line) under 50 characters +for readability in git log --oneline. If you need a more detailed description +(the body), wrap it at 72 characters. + +2. Separate Subject from Body: Always include a blank line between the subject +and the body. This helps Git tools correctly parse the message. + + + + + + + diff --git a/Cross-compiling b/Cross-compiling index 285e824b5..cc54fdc79 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -1,6 +1,6 @@ -Cross-compiling NetHack 3.7 Last edit: February 18, 2023 +Cross-compiling NetHack 5.0 Last edit: April 26, 2026 -The NetHack 3.7 build process differs from the build process of previous +The NetHack 5.0 build process differs from the build process of previous versions in some important ways. Those differences make it possible to use a cross-compiler running on one platform (the "host" platform of the build) to produce a binary NetHack package that can execute on an entirely different @@ -9,7 +9,7 @@ platform. Part A Contents: A1. Why cross-compile? A2. Building NetHack 3.6 (before) - A3. Building NetHack 3.7 (going forward) + A3. Building NetHack 5.0 (going forward) A4. How was the build procedure reduced to 5 steps? A5. How can I help with the cross-compiling initiative? @@ -18,7 +18,7 @@ Part B Contents: B2. What needs to be built and executed on the HOST? B3. What needs to be built for the TARGET? B4. Case sample: msdos - B5. Case sample: amiga (started but incomplete) + B5. Case sample: amiga B6. Case sample: Web Assembly, libnh B7. Case sample: mips @@ -118,10 +118,10 @@ might, just might, be usable across platforms, but the chances are against it, and that certainly cannot be counted on. +------------------------------------------+ - | A3. Building NetHack 3.7 (going forward) | + | A3. Building NetHack 5.0 (going forward) | +------------------------------------------+ -Again, very generally, the build of NetHack in 3.7 requires the following +Again, very generally, the build of NetHack in 5.0 requires the following steps to be carried out: 1. Compile and link util/makedefs. @@ -152,7 +152,7 @@ executing the native compiler. | A4. How was the build procedure reduced to 5 steps? | +-----------------------------------------------------+ -The following are among several design changes planned in NetHack 3.7, +The following are among several design changes planned in NetHack 5.0, and these specific changes are what altered the build process to make cross-compiling possible: @@ -412,7 +412,7 @@ Using the cross-compiler, build the following targets: system support in *sys.c as well as others sources pertaining to your specific target platform(s). - b) Lua (mandatory in 3.7) + b) Lua (mandatory in 5.0) lib/lua-5.4.8/src @@ -479,7 +479,7 @@ Cross-compiler pre-built binary downloads: bash sys/msdos/fetch-cross-compiler.sh That script won't install anything, it just does file fetches and stores - them in subfolders of lib. The linux.370 and macOS.370 hints files are + them in subfolders of lib. The linux.500 and macOS.500 hints files are configured to find the cross-compiler there if you add CROSS_TO_MSDOS=1 on your make command line. @@ -490,12 +490,12 @@ Cross-compiler pre-built binary downloads: On your linux host: - cd sys/unix ; sh setup.sh hints/linux.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/linux.500 ; cd ../.. make fetch-lua On your macOS host: - cd sys/unix ; sh setup.sh hints/macOS.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/macOS.500 ; cd ../.. make fetch-lua The MSDOS cross-compile can then be carried out by specifying @@ -532,7 +532,7 @@ Disclaimer: This is a minimal recipe, just to help someone else get Cross-compiler used: bebbo's amiga-gcc Cross-compiler url: https://github.com/AmigaPorts/m68k-amigaos-gcc -Author of 3.7 support: Ingo Paschke +Author of 5.0 support: Ingo Paschke To our knowledge, a pre-built copy of the cross-compiler isn't available, so you will likely have to obtain the cross-compiler sources via git and @@ -577,22 +577,22 @@ Author of 3.7 support: Ingo Paschke On your linux host: - # Clone NetHack 3.7 source + # Clone NetHack 5.0 source cd NetHack - sys/unix/setup.sh sys/unix/hints/linux.370 + sys/unix/setup.sh sys/unix/hints/linux.500 make fetch-lua make CROSS_TO_AMIGA=1 fetch-regex make CROSS_TO_AMIGA=1 all make CROSS_TO_AMIGA=1 package - The distribution ZIP is created at targets/amiga/NH370AMI.ZIP. + The distribution ZIP is created at targets/amiga/NH500AMI.ZIP. On your macOS host, the Amiga cross-compile can be carried out by specifying CROSS_TO_AMIGA=1 on the make command line: - # Clone NetHack 3.7 source + # Clone NetHack 5.0 source cd NetHack - sys/unix/setup.sh sys/unix/hints/macOS.370 + sys/unix/setup.sh sys/unix/hints/macOS.500 make fetch-lua make CROSS_TO_AMIGA=1 fetch-regex make CROSS_TO_AMIGA=1 all @@ -642,7 +642,7 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html sudo apt-get install python3 cmake default-jre - For macOS, you will need to install Xcode, git, cmake, Python 3.5 or new + For macOS, you will need to install Xcode, git, cmake, Python 3.5 or newer (at time of this writing). After installing the prerequisite packages above, obtain the cross-compiler @@ -665,12 +665,12 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html On your linux host, prepare to cross-compile NetHack as follows: - cd sys/unix ; sh setup.sh hints/linux.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/linux.500 ; cd ../.. make fetch-lua On your macOS host, prepare to cross-compile NetHack as follows: - cd sys/unix ; sh setup.sh hints/macOS.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/macOS.500 ; cd ../.. make fetch-lua Then, cross-compile to targets/wasm as follows: @@ -693,7 +693,7 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html The cross-compiler hints additions are enclosed inside ifdef sections and shouldn't interfere with the non-cross-compile builds using - hints/linux.370 or hints/macOS.370. + hints/linux.500 or hints/macOS.500. +--------------------------------+ @@ -712,7 +712,7 @@ Cross-compiler url: sudo apt install g++-mipsel-linux-gnu On your linux host, prepare to cross-compile NetHack as follows: - cd sys/unix ; sh setup.sh hints/linux.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/linux.500 ; cd ../.. make fetch-lua Then, cross-compile to targets/mips as follows: @@ -725,7 +725,7 @@ Cross-compiler url: The cross-compiler hints additions are enclosed inside ifdef sections and shouldn't interfere with the non-cross-compile builds using - hints/linux.370 or hints/macOS.370. + hints/linux.500 or hints/macOS.500. --- diff --git a/DEVEL/VERSION b/DEVEL/VERSION index 3788cb6d5..382eb85f0 100644 --- a/DEVEL/VERSION +++ b/DEVEL/VERSION @@ -1,4 +1,5 @@ -5 -Please see "git log DEVEL" for previous changes. -Make documentation of nhgitset.pl easier to find and -find out about. +6 +PRE and POST hooks will be dropped at some future date - +see https://www.nethack.org/devel/deprecation.html for details. + +See "git log DEVEL" for previous changes. diff --git a/DEVEL/code_features.txt b/DEVEL/code_features.txt index 6c7100096..1377515a8 100644 --- a/DEVEL/code_features.txt +++ b/DEVEL/code_features.txt @@ -1,4 +1,4 @@ -# NetHack 3.7 code_features.txt $NHDT-Date: 1596498264 2020/08/03 23:44:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ +# NetHack 5.0 code_features.txt $NHDT-Date: 1596498264 2020/08/03 23:44:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ # Copyright (c) 2015 by Michael Allison # NetHack may be freely redistributed. See license for details. @@ -115,7 +115,7 @@ and available to all NetHack source files. decl.c variable definitions are generally laid out in much the same order as their corresponding declarations in decl.h. -A new header file cstd.h was added to coincide with 3.7's switch to +A new header file cstd.h was added to coincide with 5.0's switch to C99. It contains calls to some C99 standard header files. =================== NEXT FEATURE ========================== diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 065fcd60a..5b90193aa 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -109,7 +109,7 @@ sub version_in_devel { my $version; my $verfile = "$path${PDS}DEVEL${PDS}VERSION"; - open VERFH,"<",$verfile or die "xCan't open $verfile: $!"; + open VERFH,"<",$verfile or die "Can't open $verfile: $!"; $version = 0+; my $message = join('',); close VERFH; @@ -250,7 +250,17 @@ sub do_hook { my($p) = @_; my $hname = $0; $hname =~ s!^((.*$DS)|())(.*)!$1$p-$4!; + my $vig = version_in_git; if(-x $hname){ + if(`git config --bool nethack.NoDepWarn` ne "true\n"){ + print STDERR <<~E_O_M; + WARNING: $p hooks will be going away. See + https://www.nethack.org/devel/deprecation.html + To stop seeing this message, run + git config --bool nethack.NoDepWarn true + E_O_M + } + print TRACE "START $p: $hname\n" if($trace); open TOHOOK, "|-", $hname or die "open $hname: $!"; @@ -370,6 +380,17 @@ Perl module for infrastructure of NetHack Git hooks. Buffers call information so multiple independent actions may be coded for Git hooks and similar Git callouts. +=over 4 + +=item ==> + +As of Git 2.54, multiple actions may be specified for each hook +event - that makes this redundant for hooks and will be removed at +some future time when Git 2.54 (or later) is better distributed. +This should speed up hook processing. + +=back 4 + Maintains C. Common routines for dealing with nethack.setupversion git config variable. diff --git a/DEVEL/hooksdir/NHsubst b/DEVEL/hooksdir/NHsubst index 0c7aeb067..93ce45fc0 100755 --- a/DEVEL/hooksdir/NHsubst +++ b/DEVEL/hooksdir/NHsubst @@ -392,9 +392,9 @@ $TEST-Branch: theirs $ TEST 8: <<< d1 -/* NetHack 3.7 objnam.c $TEST-Date$ $TEST-Branch$:$TEST-Revision$ */ +/* NetHack 5.0 objnam.c $TEST-Date$ $TEST-Branch$:$TEST-Revision$ */ === -/* NetHack 3.7 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */ +/* NetHack 5.0 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */ >>> d3 =for nhgitset NHsubst NetHack merge driver diff --git a/DEVEL/hooksdir/nhsub b/DEVEL/hooksdir/nhsub index b5b90704b..aeff30b27 100644 --- a/DEVEL/hooksdir/nhsub +++ b/DEVEL/hooksdir/nhsub @@ -1,5 +1,5 @@ #!/usr/bin/perl -# $NHDT-Date: 1524689646 2018/04/25 20:54:06 $ Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +# $NHDT-Date: 1524689646 2018/04/25 20:54:06 $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/nhgitset.pl b/DEVEL/nhgitset.pl index 2c4977895..d1f587b04 100755 --- a/DEVEL/nhgitset.pl +++ b/DEVEL/nhgitset.pl @@ -93,6 +93,16 @@ if($version_old > 0){ if(length $message_new){ print STDERR "Additional information:\n$message_new\n"; } +# This list and the code below will need to be updated if other changes occur +# before this progression is finished. +# 6 announce eventual deprecation of PRE and POST hooks +# 6->7 unset nethack.NoDepWarn, change message, docs in NHgithook.pm +# 7 deprecation of PRE and POST hooks +# 7->8 unset nethack.NoDepWarn, change message, docs in NHgithook.pm and make fail +# 8 PRE and POST throw errors +# 8->9 unset nethack.NoDepWarn, remove code, docs +# 9 removal of PRE and POST code + system('git','config','--unset','nethack.NoDepWarn') unless($opt_n); } } @@ -358,7 +368,7 @@ sub do_file_nhgitset { open IN, "<", $infile or die "Can't open $infile:$!"; open OUT, ">", $outfile or die "Can't open $outfile:$!"; my $started; - print IN "die \"DO NOT RUN THIS FILE\n\""; + print OUT "=pod\n"; while(){ m/^__END__/ && do {$started =1; next}; print OUT if($started); diff --git a/Files b/Files index a91ef523d..4b1a0c08e 100644 --- a/Files +++ b/Files @@ -1,4 +1,4 @@ -This is a listing of all files in a full NetHack 3.7 distribution, organized +This is a listing of all files in a full NetHack 5.0 distribution, organized in their standard manner on a UNIX system. It indicates which files are necessary for which versions, so that you can tell which files may be deleted from or not transferred to your system if you wish. @@ -7,8 +7,9 @@ from or not transferred to your system if you wish. .: (files in top directory) -.clang-format Cross-compiling Files -Porting README azure-pipelines.yml +.clang-format Contributing.md Cross-compiling +Files Porting README +azure-pipelines.yml DEVEL: (files for people developing changes to NetHack) @@ -76,11 +77,11 @@ fixes3-2-2.txt fixes3-2-3.txt fixes3-3-0.txt fixes3-3-1.txt fixes3-4-0.txt fixes3-4-1.txt fixes3-4-2.txt fixes3-4-3.txt fixes3-5-0.txt fixes3-6-0.txt fixes3-6-1.txt fixes3-6-2.txt fixes3-6-3.txt fixes3-6-4.txt fixes3-6-5.txt fixes3-6-6.txt -fixes3-6-7.txt fixes3-7-0.txt fixesX-X-X.txt lua.adoc -makedefs.6 makedefs.txt mn.7 mn.txt -mnh.7 mnh.txt nethack.6 nethack.txt -options.txt recover.6 recover.txt sound.txt -tmac.n tmac.nh window.txt +fixes3-6-7.txt fixes5-0-0.txt fixes5-0-1.txt fixesX-X-X.txt +lua.adoc makedefs.6 makedefs.txt mn.7 +mn.txt mnh.7 mnh.txt nethack.6 +nethack.txt options.txt recover.6 recover.txt +sound.txt tmac.n tmac.nh window.txt include: (files for X versions) @@ -97,13 +98,13 @@ mcastu.h mextra.h mfndpos.h micro.h mkroom.h monattk.h mondata.h monflag.h monst.h monsters.h nhmd4.h nhregex.h obj.h objclass.h objects.h optlist.h patchlevel.h pcconf.h permonst.h prop.h -quest.h rect.h region.h rm.h savefile.h -seffects.h selvar.h sfmacros.h sfprocs.h skills.h -sndprocs.h sp_lev.h spell.h stairs.h sym.h -sys.h tcap.h tileset.h timeout.h tradstdc.h -trap.h unixconf.h vision.h vmsconf.h warnings.h -weight.h winami.h wincurs.h windconf.h winprocs.h -wintype.h you.h youprop.h +quest.h rect.h region.h revision.h rm.h +savefile.h seffects.h selvar.h sfmacros.h sfprocs.h +skills.h sndprocs.h sp_lev.h spell.h stairs.h +sym.h sys.h tcap.h tileset.h timeout.h +tradstdc.h trap.h unixconf.h vision.h vmsconf.h +warnings.h weight.h winami.h wincurs.h windconf.h +winprocs.h wintype.h you.h youprop.h (file for tty versions) wintty.h @@ -131,18 +132,13 @@ wceconf.h mac-carbon.h mac-qt.h mac-term.h macconf.h macpopup.h mactty.h macwin.h mttypriv.h -outdated/sys/amiga: -(files for Amiga versions - untested for 3.7) -Build.ami Install.ami Makefile.agc Makefile.ami NetHack.cnf -ifchange mkdmake txt2iff.c xpm2iff.c - outdated/sys/atari: -(files for Atari version - untested for 3.7) +(files for Atari version - untested for 5.0) Install.tos atarifnt.uue nethack.mnu setup.g tos.c unx2atar.sed outdated/sys/be: -(files for BeOS version - untested for 3.7) +(files for BeOS version - untested for 5.0) README bemain.c outdated/sys/mac: @@ -159,7 +155,7 @@ Makefile.BC Makefile.MSC SCHEMA35.MSC moveinit.pat ovlinit.c schema1.BC schema2.BC schema3.MSC outdated/sys/os2: -(files for OS/2 version - untested for 3.7) +(files for OS/2 version - untested for 5.0) Install.os2 Makefile.os2 nhpmico.uu os2.c outdated/sys/unix: @@ -182,7 +178,7 @@ outdated/sys/vms: lev_lex.h outdated/sys/wince: -(files for Windows CE and PocketPC - untested for 3.7) +(files for Windows CE and PocketPC - untested for 5.0) Install.ce bootstrp.mak celib.c cesetup.bat cesound.c defaults.nh keypad.uu menubar.uu mhaskyn.c mhaskyn.h mhcmd.c mhcmd.h mhcolor.c mhcolor.h mhdlg.c @@ -195,21 +191,13 @@ resource.h winMS.h winhack.c winhack.rc winhcksp.rc winmain.c outdated/sys/wince/ceinc: -(header files for Windows CE and PocketPC - untested for 3.7) +(header files for Windows CE and PocketPC - untested for 5.0) assert.h errno.h fcntl.h outdated/sys/wince/ceinc/sys: (sys/stat.h for Windows CE and PocketPC - untested for 3.6.2) stat.h -outdated/sys/windows: -(files that are no longer maintained for current game code) -travis-gcc.sh - -outdated/sys/windows/vs: -(files that are no longer maintained for current game code) -travisci.sh - outdated/win/Qt3: (files for the Qt 3 widget library - X11, Windows, Mac OS X, or Qtopia) Info.plist Install.Qt knethack.lnk @@ -220,12 +208,12 @@ qt3tableview.cpp qt3tableview.h tileedit.cpp tileedit.h outdated/win/gem: -(files for GEM versions - untested for 3.7) +(files for GEM versions - untested for 5.0) Install.gem bitmfile.c gem_rsc.uu gem_rso.uu gr_rect.c gr_rect.h load_img.c tile2img.c title.uu wingem.c wingem1.c xpm2img.c outdated/win/gnome: -(files for GNOME versions - untested for 3.7) +(files for GNOME versions - untested for 5.0) README gn_xpms.h gnaskstr.c gnaskstr.h gnbind.c gnbind.h gnglyph.c gnglyph.h gnmain.c gnmain.h gnmap.c gnmap.h gnmenu.c gnmenu.h gnmesg.c gnmesg.h gnomeprv.h gnopts.c @@ -301,14 +289,14 @@ mondata.c monmove.c monst.c mplayer.c mthrowu.c muse.c music.c nhlobj.c nhlsel.c nhlua.c nhmd4.c o_init.c objects.c objnam.c options.c pager.c pickup.c pline.c polyself.c potion.c pray.c priest.c quest.c questpgr.c -read.c rect.c region.c report.c restore.c rip.c -rnd.c role.c rumors.c save.c selvar.c sfbase.c -sfstruct.c shk.c shknam.c sit.c sounds.c sp_lev.c -spell.c stairs.c steal.c steed.c strutil.c symbols.c -sys.c teleport.c timeout.c topten.c track.c trap.c -u_init.c uhitm.c utf8map.c vault.c version.c vision.c -weapon.c were.c wield.c windows.c wizard.c wizcmds.c -worm.c worn.c write.c zap.c +read.c rect.c region.c report.c restore.c revision.c +rip.c rnd.c role.c rumors.c save.c selvar.c +sfbase.c sfstruct.c shk.c shknam.c sit.c sounds.c +sp_lev.c spell.c stairs.c steal.c steed.c strutil.c +symbols.c sys.c teleport.c timeout.c topten.c track.c +trap.c u_init.c uhitm.c utf8map.c vault.c version.c +vision.c weapon.c were.c wield.c windows.c wizard.c +wizcmds.c worm.c worn.c write.c zap.c submodules: (files in top directory) @@ -316,14 +304,14 @@ CHKSUMS lua pdcurses pdcursesmod sys/amiga: (files for Amiga versions) -README.amiga amidos.c amidos.p amifont.uu -amifont8.uu amigst.c amii.hlp amimenu.c -amirip.c amistack.c amitty.c amiwind.c -amiwind.p bmp2iff_host.c clipwin.c colorwin.c -grave16.xpm nethack.cnf winamenu.c winami.c -winami.p winchar.c windefs.h winext.h -winfuncs.c winkey.c winproto.h winreq.c -winstr.c xpm2iff_host.c +NHinfo.uu README.amiga amidos.c amifont.uu +amifont8.uu amii.hlp amimenu.c amirip.c +amistack.c amiwind.c bmp2iff_host.c clipwin.c +cnf-info.uu colorwin.c drawer-info.uu grave16.xpm +license-info.uu nethack.cnf readme-info.uu txt-info.uu +winamenu.c winami.c winchar.c windefs.h +winext.h winfuncs.c winkey.c winproto.h +winreq.c winstr.c xpm2iff_host.c sys/libnh: (files in top directory) @@ -359,11 +347,8 @@ random.c (Berkeley uudecode file, which may be used in build process of any version) uudecode.c -(file for MSDOS, OS/2, Amiga, and Atari versions - only MSDOS tested for 3.7) -pcmain.c - -(file for MSDOS, OS/2, and Atari versions - only MSDOS tested for 3.7) -NetHack.cnf pctty.c +(file for MSDOS, Amiga versions) +NetHack.cnf pcmain.c pctty.c (file for MSDOS, OS/2, and VMS versions) termcap @@ -371,10 +356,10 @@ termcap (file for VMS version) tclib.c -(files for MSDOS, OS/2 and Atari versions - only MSDOS tested for 3.7) +(files for MSDOS, Amiga versions) pcsys.c pcunix.c -(files for OS/2 version - untested for 3.7) +(files for OS/2 version - untested for 5.0) Makefile.lib termcap.uu (files for UNIX and Be versions) @@ -393,9 +378,10 @@ sys/unix: (files for UNIX versions) Install.unx Makefile.check Makefile.dat Makefile.doc Makefile.src Makefile.top Makefile.utl NewInstall.unx -README-hints README.xcode XCode.xcconfig depend.awk -gitinfo.sh mkmkfile.sh nethack.sh setup.sh -sysconf unixmain.c unixres.c unixunix.c +README.hints README.xcode XCode.xcconfig depend.awk +gitinfo.sh macuuid.m mkmkfile.sh nethack.sh +setup.sh sysconf unixmain.c unixres.c +unixunix.c sys/unix/NetHack.xcodeproj: (file for macOS Xcode) @@ -415,16 +401,16 @@ NetHack.xcscheme makedefs.xcscheme recover.xcscheme sys/unix/hints: (files for configuring UNIX NetHack versions) -linux-minimal linux.370 macOS.370 -macosx.sh solaris solaris-playground -unix +bsd.500 linux-minimal linux.500 +macOS.500 macosx.sh solaris +solaris-playground unix sys/unix/hints/include: (files for configuring UNIX NetHack versions) -compiler.370 cross-post.370 cross-pre1.370 cross-pre2.370 -gbdates-post.370 gbdates-pre.370 misc.370 multisnd-post.370 -multisnd1-pre.370 multisnd2-pre.370 multiw-1.370 multiw-2.370 -response.370 +compiler.500 cross-post.500 cross-pre1.500 cross-pre2.500 +dirs-perms.500 gbdates-post.500 gbdates-pre.500 linuxdistro.500 +misc.500 multisnd-post.500 multisnd1-pre.500 multisnd2-pre.500 +multiw-1.500 multiw-2.500 response.500 whichbsd.500 sys/vms: (files for VMS version) @@ -620,8 +606,9 @@ Install.X11 NetHack.ad Window.c X11-issues.txt dialogs.c ibm.bdf nethack.rc nh10.bdf nh32icon nh56icon nh72icon nh_icon.xpm pet_mark.xbm pilemark.xbm rip.xpm tile2x11.c -winX.c winmap.c winmenu.c winmesg.c -winmisc.c winstat.c wintext.c winval.c +winX.c winlabel.c winmap.c winmenu.c +winmesg.c winmisc.c winstat.c wintext.c +winval.c win/chain: (files for stacking window systems) @@ -640,10 +627,10 @@ NetHackTerm.applescript recover.pl win/share: (files for versions using optional tiles) -bmptiles.c gifread.c giftiles.c monsters.txt nhicns.uu -nhsplash.xpm objects.txt other.txt ppmwrite.c renumtiles.pl -thintile.c tile.doc tile.h tile2bmp.c tilemap.c -tileset.c tiletext.c tiletxt.c +bmptiles.c decals.txt gifread.c giftiles.c monsters.txt +nhicns.uu nhsplash.xpm objects.txt other.txt ppmwrite.c +renumtiles.pl thintile.c tile.doc tile.h tile2bmp.c +tilemap.c tileset.c tiletext.c tiletxt.c win/shim: (file in top directory) @@ -701,7 +688,7 @@ GNUmakefile Makefile qt_kde0.moc qt_main.moc qt_map.moc qt_menu.moc qt_msg.moc qt_plsel.moc qt_set.moc qt_stat.moc qt_xcmd.moc qt_yndlg.moc -(file generated by makedefs -m but unused in 3.7) +(file generated by makedefs -m but unused in 5.0) monstr.c (file optionally generated by tilemap at compile time) diff --git a/Porting b/Porting index 45aa1bfc5..277304df7 100644 --- a/Porting +++ b/Porting @@ -1,4 +1,4 @@ - NetHack Porting Guidelines v 3.7 2023-04-23 + NetHack Porting Guidelines v 5.0 2023-04-23 1.0 Introduction @@ -229,7 +229,7 @@ libraries. 5.0 Design Updates -The following design updates were introduced in NetHack 3.7. +The following design updates were introduced in NetHack 5.0. 5.1 Quest text files diff --git a/README b/README index e6bf764f8..76722294b 100644 --- a/README +++ b/README @@ -1,67 +1,42 @@ - NetHack 3.7.0 work-in-progress -- General information + NetHack 5.0.0 -- General information -NetHack 3.7 is an enhancement to the dungeon exploration game NetHack, -which is a distant descendent of Rogue and Hack, and a direct descendent of -NetHack 3.6. +NetHack 5.0 is an enhancement to the dungeon exploration game NetHack, +which is a distant descendent of Rogue and Hack, and a direct descendent +of NetHack 3.6. -NetHack 3.7.0 work-in-progress is not a release of NetHack. As a .0 version, -and still very early in its development cycle, there has already been changes -made, and there will continue to be many more prior to an eventual release. -The file doc/fixes3-7-0.txt in the source distribution will be updated with -a list of fixes as they are committed. +NetHack 5.0.0 is a release of NetHack. As a .0 version, there may be some +bugs encountered. Constructive suggestions, GitHub pull requests, and bug +reports are all welcome and encouraged. -In short -- there are likely to be bugs. Don't treat NetHack-3.7 branch as -released code, and if stability is paramount, then the most recent -NetHack 3.6.7 release is safest for you. +The file doc/fixes5-0-0.txt in the source distribution contains a full list +of fixes and changes as they were committed. The text in there was written +for the development team's own use and is provided "as is", so please do +not ask us to further explain the entries in that file. Some entries might +be considered "spoilers", particularly in the "new features" section. -We're making the .0 work-in-progress available so that you can observe, test -out, and contribute to its development. Constructive suggestions, GitHub pull -requests, and bug reports are all welcome and encouraged. - -The file doc/fixes3-7-0.txt in the source distribution has a full list of -bug-fixes included so far, as well as brief mentions of some of the other code -changes. The text in there was written for the development team's own use and is -provided "as is", so please do not ask us to further explain the entries in -that file. Some entries might be considered "spoilers", particularly in the -"new features" section. - -Along with the game improvements and bug fixes, NetHack 3.7 strives to make +Along with the game improvements and bug fixes, NetHack 5.0 strives to make some general architectural improvements to the game or to its building -process. Among them: +process. Among them, 5.0 has: - * Remove barriers to building NetHack on one platform and operating system, + * The source code is compliant with the C99 standard. + + * removes barriers to building NetHack on one platform and operating system, for later execution on another (possibly quite different) platform and/or operating system. That capability is generally known as "cross-compiling." See the file "Cross-compiling" in the top-level folder for more information on that. - * Replace the build-time "yacc and lex"-based level compiler, the "yacc and - lex"-based dungeon compiler, and the quest text file processing done - by NetHack's "makedefs" utility, with Lua text alternatives that are - loaded and processed by the game during play. + * The build-time "yacc and lex"-based level compiler, the + "yacc and lex"-based dungeon compiler, and the quest text file processing + previously done by NetHack's "makedefs" utility, have been replaced with + Lua text alternatives that are loaded and processed by the game during play. - * Write game savefiles and bonesfiles in a more portable and consistent way - to open up the possibility of utilizing them between different platforms, - such as between your desktop computer and your hand-held device. - - * Add support to make the game restartable without exit (a.k.a. "play again" - support). Toward that end, many previously scattered and separate variables - have been gathered into central 'ga' through 'gz' structures in - decl.h/decl.c. That central ability to reinitialize the variables will - benefit the porting effort to some platforms that are under consideration - where "play again" is typical. - -Here are some other general notes on the changes in NetHack 3.7 that were not +Here are some other general notes on the changes in NetHack 5.0 that were not considered spoilers: - automatic annotation "gateway to Moloch's Sanctum" for vibrating square level once that square's location becomes known (found or magic mapped); goes away once sanctum temple is found (entered or high altar mapped) - - savefile: add support for a tool to deconstruct data structures, - that get stored in a savefile, down into their individual fields and - save those individual fields instead of the entire struct. The - intention is to provide a way to export and transport savefiles - between platforms, architectures and data models. - - - - - - - - - - - @@ -98,75 +73,36 @@ Please read items (1), (2) and (3) BEFORE doing anything with your new code. that the default configuration is SysV/Sun/Solaris2.x (simply because the code was housed on such a system). - The files sys/*/Install.* were written to guide you in configuring the - program for your operating system. The files win/*/Install.* are - available, where necessary, to help you in configuring the program - for particular windowing environments. Reading them, and the man pages, - should answer most of your questions. + The files sys/*/Install.*, or sys/*/NewInstall.* were written to guide + you in configuring the program for your operating system. The files + win/*/Install.* are available, where necessary, to help you in + configuring the program for particular windowing environments. + Reading them, and the man pages, should answer most of your questions. - At the time of the most recent official release, NetHack 3.6, it had - been tested to run/compile on: + At the time of the most recent official release, NetHack 5.0, it had + been tested to run and/or compile on: Intel Pentium or better running Linux, BSDI + [compiles, runs] Intel Pentium or better running Windows 10 or 11 + [compiles, runs] Intel-based, or Apple M1, M2, M3, M4, M5 Macs running macOS 10.11 (El Capitan) to macOS 26 (Tahoe) + [compiles, runs] (follow the instructions in sys/unix/NewInstall.unx) Intel 80386 or greater running MS-DOS with DPMI + [cross-compiles on Linux, runs on MS-DOS, emulator/dosbox] built via djgpp compiler (native or Linux-hosted cross-compiler) + AmigaOS 3.0 or later + [cross-compiles on Linux or macOS, runs on Amiga or emulator] + Running requires Kickstart 39+ + 6 MB free RAM minimum (8 MB recommended) + Hard drive with ~5 MB free space + + There has also been some success runing/comiling on: OpenVMS (aka VMS) V8.4 on Alpha and on Integrity/Itanium/IA64 - - Previous versions of NetHack were tested and known to run on the - following systems, but it is unknown if they can still build and - execute NetHack 3.6 or NetHack 3.7: - - Apple Macintosh running MacOS 7.5 or higher, LinuxPPC, BeOS 4.0 - Atari ST/TT/Falcon running TOS (or MultiTOS) with GCC - AT&T 3B1 running System V (3.51) - AT&T 3B2/600 & 3B2/622 running System V R3.2.1 - AT&T 3B2/1000 Model 80 running System V R3.2.2 - AT&T 3B4000 running System V - AT&T 6386 running System V R3.2 - Commodore Amiga running AmigaDOS 3.0 or higher with SAS/C 6.x - (but see Makefile.ami about DICE and Manx) - Data General AViiON systems running DG/UX - DEC Alpha/VMS (aka OpenVMS AXP), running V1.x through V7.1 - DEC VAX/VMS, running V4.6 through V7.1 - DEC vaxen running BSD, Ultrix - Decstations running Ultrix 3.1, 4.x - Encore Multimax running UMAX 4.2 - Gould NP1 running UTX 3/2 - HP 9000s300 running HP-UX - HP 9000s700 running HP-UX 9.x, 10.x, 11.x - H/PC Pro devices running Windows CE 2.11 and higher. - IBM PC/RT and RS/6000 running AIX 3.x - IBM PS/2 and AT compatibles running OS/2 - 2.0 and up with GCC emx - IBM PS/2 and AT compatibles running OS/2 1.1 - 2.0 (and probably - Warp) with Microsoft 6.0, and OS/2 2.0 and up with IBM CSet++ 2.0. - Intel 80386 or greater (or clone) running 386BSD - Intel x86 running a version of Windows 7 or 8 or prior to XP. - Mips M2000 running RiscOS 4.1 - NeXT running Mach (using BSD configuration) - Palm Size PC 1.1 devices running Windows CE 2.11 - Pocket PC devices running Windows CE 3.0 and higher - Pyramid 9820x running OSx 4.4c - SGI Iris running IRIX - Stardent Vistra 800 running SysV R4.0 - Stride 460 running UniStride 2.1 - Sun-3s, -4s, and -386is running SunOS 3.x - Sun-3s and -386is running SunOS 4.x - "Sun SPARC"-based machine running SunOS 4.x, Solaris 2.x, or Solaris 7 - Valid Logic Systems SCALD-System - - Previous versions, using a cross-compiler hosted on another platform, - such as win32, could also build the following from source: - Pocket PC devices running Windows CE 3.0 and higher - H/PC Pro devices running Windows CE 2.11 and higher - Palm Size PC 1.1 devices running Windows CE 2.11 - - Unless otherwise mentioned, the compiler used was the OS-vendor's - C compiler. + OpenVMS (ask VMS) V9.2-3 on x86-64 - - - - - - - - - - - @@ -206,13 +142,13 @@ If a feature is not accepted you are free, of course, to post the patches to the net yourself and let the marketplace decide their worth. All of this amounts to the following: If you decide to apply a free-lanced -patch to your 3.6 code, you are welcome to do so, of course, but we won't -be able to provide support or receive bug reports for it. +patch to your NetHack 5.0 code, you are welcome to do so, of course, but we +won't be able to provide support or receive bug reports for it. In our own patches, we will assume that your code is synchronized with ours. -- Good luck, and happy Hacking -- -# $NHDT-Date: 1652133501 2022/05/09 21:58:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ +# $NHDT-Date: 1779926755 2026/05/28 00:05:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.113 $ # Copyright (c) 2012 by Michael Allison # NetHack may be freely redistributed. See license for details. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7c7eea340..3378224e7 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -4,18 +4,14 @@ strategy: imageName: 'ubuntu-latest' toolchainName: gcc14 buildTargetName: minimal - linux_noble_clang_all: - imageName: 'ubuntu-24.04' + linux_latest_gcc14: + imageName: 'ubuntu-latest' + toolchainName: gcc14 + buildTargetName: all + linux_latest_clang_all: + imageName: 'ubuntu-latest' toolchainName: clang buildTargetName: all - linux_jammy_gcc9_all: - imageName: 'ubuntu-22.04' - toolchainName: gcc9 - buildTargetName: all - linux_noble_gcc13_all: - imageName: 'ubuntu-24.04' - toolchainName: gcc13 - buildTargetName: all macOS_latest_clang_all: imageName: 'macOS-latest' toolchainName: clang @@ -41,8 +37,8 @@ strategy: imageName: 'ubuntu-latest' toolchainName: cross buildTargetName: msdos - linux_noble_docs: - imageName: 'ubuntu-24.04' + linux_latest_docs: + imageName: 'ubuntu-latest' toolchainName: docs buildTargetName: all continueOnError: true @@ -65,16 +61,6 @@ variables: steps: - bash: | - if [ "$(toolchain)" == "gcc9" ] - then - echo "##vso[task.setvariable variable=CC]gcc-9" - echo "##vso[task.setvariable variable=CXX]g++-9" - fi - if [ "$(toolchain)" == "gcc13" ] - then - echo "##vso[task.setvariable variable=CC]gcc-13" - echo "##vso[task.setvariable variable=CXX]g++-13" - fi if [ "$(toolchain)" == "gcc14" ] then echo "##vso[task.setvariable variable=CC]gcc-14" @@ -100,7 +86,7 @@ steps: echo "CXX: $CXX" displayName: 'Echoing variables' -- checkout: git://NetHack/NetHack@NetHack-3.7 +- checkout: git://NetHack/NetHack@NetHack-5.0 submodules: true path: $(netHackPath) # $(Agent.BuildDirectory)/$(netHackPath) @@ -172,14 +158,14 @@ steps: - bash: | sudo apt-get -qq -y update sudo apt-get -qq -y install libncurses-dev - sudo apt-get -qq -y install libx11-dev libxaw7-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools + sudo apt-get -qq -y install libx11-dev libxaw7-dev libxft-dev fontconfig xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildTarget, 'all')) workingDirectory: $(Agent.BuildDirectory)/$(netHackPath) displayName: 'Getting linux build dependencies' - bash: | cd sys/unix - sh setup.sh hints/linux.370 + sh setup.sh hints/linux.500 cd ../.. make fetch-lua make WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc all @@ -221,7 +207,7 @@ steps: - bash: | brew install groff cd sys/unix - sh setup.sh hints/macos.370 + sh setup.sh hints/macos.500 cd ../.. make fetch-lua make WANT_MACSOUND=1 all @@ -234,7 +220,7 @@ steps: export GCCVER=gcc1220 export IN_CI=SKIP_FONTS_IN_CI=1 cd sys/unix - sh setup.sh hints/linux.370 + sh setup.sh hints/linux.500 cd ../.. make fetch-lua sys/msdos/fetch-cross-compiler.sh diff --git a/dat/.gitattributes b/dat/.gitattributes index cf71f9633..a15ea206f 100644 --- a/dat/.gitattributes +++ b/dat/.gitattributes @@ -2,6 +2,7 @@ *.des NHSUBST *.txt NHSUBST *.lua NHSUBST +luahelper NHSUBST data.base NHSUBST symbols NHSUBST tribute NHSUBST diff --git a/dat/Arc-fila.lua b/dat/Arc-fila.lua index 1a869dd0f..94c94c624 100644 --- a/dat/Arc-fila.lua +++ b/dat/Arc-fila.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-fila.lua $NHDT-Date: 1652195998 2022/05/10 15:19:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Archeologist Arc-fila.lua $NHDT-Date: 1781994863 2026/06/20 22:34:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-filb.lua b/dat/Arc-filb.lua index a5334874b..37df5acc1 100644 --- a/dat/Arc-filb.lua +++ b/dat/Arc-filb.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-filb.lua $NHDT-Date: 1652195998 2022/05/10 15:19:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Archeologist Arc-filb.lua $NHDT-Date: 1781994863 2026/06/20 22:34:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-goal.lua b/dat/Arc-goal.lua index 0561d1a85..4fadb5b15 100644 --- a/dat/Arc-goal.lua +++ b/dat/Arc-goal.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-goal.lua $NHDT-Date: 1652195998 2022/05/10 15:19:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Archeologist Arc-goal.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-loca.lua b/dat/Arc-loca.lua index ec08e9849..f436c2d46 100644 --- a/dat/Arc-loca.lua +++ b/dat/Arc-loca.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-loca.lua $NHDT-Date: 1652195999 2022/05/10 15:19:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Archeologist Arc-loca.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-strt.lua b/dat/Arc-strt.lua index cad40375b..b36c5d707 100644 --- a/dat/Arc-strt.lua +++ b/dat/Arc-strt.lua @@ -1,4 +1,4 @@ --- NetHack Archeologist Arc-strt.lua $NHDT-Date: 1652195999 2022/05/10 15:19:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Archeologist Arc-strt.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-fila.lua b/dat/Bar-fila.lua index 64ea97e54..9488b43a1 100644 --- a/dat/Bar-fila.lua +++ b/dat/Bar-fila.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-fila.lua $NHDT-Date: 1652195999 2022/05/10 15:19:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Barbarian Bar-fila.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-filb.lua b/dat/Bar-filb.lua index 9764c3128..8af6ea40c 100644 --- a/dat/Bar-filb.lua +++ b/dat/Bar-filb.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-filb.lua $NHDT-Date: 1652196000 2022/05/10 15:20:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Barbarian Bar-filb.lua $NHDT-Date: 1781994864 2026/06/20 22:34:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-goal.lua b/dat/Bar-goal.lua index 760f36ad9..e065156ff 100644 --- a/dat/Bar-goal.lua +++ b/dat/Bar-goal.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-goal.lua $NHDT-Date: 1652196000 2022/05/10 15:20:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Barbarian Bar-goal.lua $NHDT-Date: 1781994865 2026/06/20 22:34:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-loca.lua b/dat/Bar-loca.lua index a11a896e5..04d95ba10 100644 --- a/dat/Bar-loca.lua +++ b/dat/Bar-loca.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-loca.lua $NHDT-Date: 1652196000 2022/05/10 15:20:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Barbarian Bar-loca.lua $NHDT-Date: 1781994865 2026/06/20 22:34:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Bar-strt.lua b/dat/Bar-strt.lua index 28cacf028..e165cd34f 100644 --- a/dat/Bar-strt.lua +++ b/dat/Bar-strt.lua @@ -1,4 +1,4 @@ --- NetHack Barbarian Bar-strt.lua $NHDT-Date: 1652196001 2022/05/10 15:20:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Barbarian Bar-strt.lua $NHDT-Date: 1781994865 2026/06/20 22:34:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-fila.lua b/dat/Cav-fila.lua index d1b0b2000..a914d937c 100644 --- a/dat/Cav-fila.lua +++ b/dat/Cav-fila.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-fila.lua $NHDT-Date: 1652196001 2022/05/10 15:20:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Caveman Cav-fila.lua $NHDT-Date: 1781994865 2026/06/20 22:34:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-filb.lua b/dat/Cav-filb.lua index a18fed77c..991740221 100644 --- a/dat/Cav-filb.lua +++ b/dat/Cav-filb.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-filb.lua $NHDT-Date: 1652196001 2022/05/10 15:20:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Caveman Cav-filb.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-goal.lua b/dat/Cav-goal.lua index 871579f9d..134fa6c78 100644 --- a/dat/Cav-goal.lua +++ b/dat/Cav-goal.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-goal.lua $NHDT-Date: 1652196002 2022/05/10 15:20:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Caveman Cav-goal.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-loca.lua b/dat/Cav-loca.lua index d779d601a..3089663f1 100644 --- a/dat/Cav-loca.lua +++ b/dat/Cav-loca.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-loca.lua $NHDT-Date: 1652196002 2022/05/10 15:20:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Caveman Cav-loca.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Cav-strt.lua b/dat/Cav-strt.lua index 224ed7455..ba3cb5685 100644 --- a/dat/Cav-strt.lua +++ b/dat/Cav-strt.lua @@ -1,4 +1,4 @@ --- NetHack Caveman Cav-strt.lua $NHDT-Date: 1652196002 2022/05/10 15:20:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack Caveman Cav-strt.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/GENFILES b/dat/GENFILES index 2613ad90e..056dde16d 100755 --- a/dat/GENFILES +++ b/dat/GENFILES @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.7 GENFILES $NHDT-Date: 1596498242 2020/08/03 23:44:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +# NetHack 5.0 GENFILES $NHDT-Date: 1596498242 2020/08/03 23:44:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2018 by Kenneth Lorber # NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-fila.lua b/dat/Hea-fila.lua index 7fa038ddc..8dd58756f 100644 --- a/dat/Hea-fila.lua +++ b/dat/Hea-fila.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-fila.lua $NHDT-Date: 1652196003 2022/05/10 15:20:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-fila.lua $NHDT-Date: 1781994866 2026/06/20 22:34:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-filb.lua b/dat/Hea-filb.lua index 778402363..55cb12cb4 100644 --- a/dat/Hea-filb.lua +++ b/dat/Hea-filb.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-filb.lua $NHDT-Date: 1652196003 2022/05/10 15:20:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-filb.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-goal.lua b/dat/Hea-goal.lua index 0499a1248..f2183efeb 100644 --- a/dat/Hea-goal.lua +++ b/dat/Hea-goal.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-goal.lua $NHDT-Date: 1652196003 2022/05/10 15:20:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-goal.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-loca.lua b/dat/Hea-loca.lua index a05020f17..950ae0f0a 100644 --- a/dat/Hea-loca.lua +++ b/dat/Hea-loca.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-loca.lua $NHDT-Date: 1652196004 2022/05/10 15:20:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-loca.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Hea-strt.lua b/dat/Hea-strt.lua index 9e9e35247..fc2f11248 100644 --- a/dat/Hea-strt.lua +++ b/dat/Hea-strt.lua @@ -1,4 +1,4 @@ --- NetHack Healer Hea-strt.lua $NHDT-Date: 1652196004 2022/05/10 15:20:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Healer Hea-strt.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991, 1993 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-fila.lua b/dat/Kni-fila.lua index 362d0674b..d24ef18a4 100644 --- a/dat/Kni-fila.lua +++ b/dat/Kni-fila.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-fila.lua $NHDT-Date: 1652196004 2022/05/10 15:20:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Knight Kni-fila.lua $NHDT-Date: 1781994867 2026/06/20 22:34:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-filb.lua b/dat/Kni-filb.lua index 14a414f4e..4d6c7279a 100644 --- a/dat/Kni-filb.lua +++ b/dat/Kni-filb.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-filb.lua $NHDT-Date: 1652196005 2022/05/10 15:20:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Knight Kni-filb.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-goal.lua b/dat/Kni-goal.lua index 08a8dff78..fe42e601d 100644 --- a/dat/Kni-goal.lua +++ b/dat/Kni-goal.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-goal.lua $NHDT-Date: 1652196005 2022/05/10 15:20:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Knight Kni-goal.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-loca.lua b/dat/Kni-loca.lua index 91d557a70..cd11949c6 100644 --- a/dat/Kni-loca.lua +++ b/dat/Kni-loca.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-loca.lua $NHDT-Date: 1652196005 2022/05/10 15:20:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Knight Kni-loca.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Kni-strt.lua b/dat/Kni-strt.lua index 9873fb42e..ba199bd01 100644 --- a/dat/Kni-strt.lua +++ b/dat/Kni-strt.lua @@ -1,4 +1,4 @@ --- NetHack Knight Kni-strt.lua $NHDT-Date: 1652196006 2022/05/10 15:20:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Knight Kni-strt.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-fila.lua b/dat/Mon-fila.lua index c62801a83..ba0f2c8d7 100644 --- a/dat/Mon-fila.lua +++ b/dat/Mon-fila.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-fila.lua $NHDT-Date: 1652196006 2022/05/10 15:20:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Monk Mon-fila.lua $NHDT-Date: 1781994868 2026/06/20 22:34:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-filb.lua b/dat/Mon-filb.lua index 98e98f12d..aff195eb3 100644 --- a/dat/Mon-filb.lua +++ b/dat/Mon-filb.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-filb.lua $NHDT-Date: 1652196006 2022/05/10 15:20:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Monk Mon-filb.lua $NHDT-Date: 1781994869 2026/06/20 22:34:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-goal.lua b/dat/Mon-goal.lua index c19bfef54..e2ca412e0 100644 --- a/dat/Mon-goal.lua +++ b/dat/Mon-goal.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-goal.lua $NHDT-Date: 1652196007 2022/05/10 15:20:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Monk Mon-goal.lua $NHDT-Date: 1781994869 2026/06/20 22:34:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-loca.lua b/dat/Mon-loca.lua index 598b364eb..67b971412 100644 --- a/dat/Mon-loca.lua +++ b/dat/Mon-loca.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-loca.lua $NHDT-Date: 1652196007 2022/05/10 15:20:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Monk Mon-loca.lua $NHDT-Date: 1781994869 2026/06/20 22:34:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Mon-strt.lua b/dat/Mon-strt.lua index 0396c56f7..d027fa4de 100644 --- a/dat/Mon-strt.lua +++ b/dat/Mon-strt.lua @@ -1,4 +1,4 @@ --- NetHack Monk Mon-strt.lua $NHDT-Date: 1652196007 2022/05/10 15:20:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Monk Mon-strt.lua $NHDT-Date: 1781994869 2026/06/20 22:34:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-fila.lua b/dat/Pri-fila.lua index c65683cf1..bd2d5f117 100644 --- a/dat/Pri-fila.lua +++ b/dat/Pri-fila.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-fila.lua $NHDT-Date: 1652196008 2022/05/10 15:20:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Priest Pri-fila.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-filb.lua b/dat/Pri-filb.lua index ad0a84ec9..ce04e70c2 100644 --- a/dat/Pri-filb.lua +++ b/dat/Pri-filb.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-filb.lua $NHDT-Date: 1652196008 2022/05/10 15:20:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Priest Pri-filb.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-goal.lua b/dat/Pri-goal.lua index 1e29d9713..d9a5a3515 100644 --- a/dat/Pri-goal.lua +++ b/dat/Pri-goal.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-goal.lua $NHDT-Date: 1687033651 2023/06/17 20:27:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Priest Pri-goal.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-loca.lua b/dat/Pri-loca.lua index 6c8909721..080db9647 100644 --- a/dat/Pri-loca.lua +++ b/dat/Pri-loca.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-loca.lua $NHDT-Date: 1652196009 2022/05/10 15:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Priest Pri-loca.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Pri-strt.lua b/dat/Pri-strt.lua index 29edb6d15..cbbd8543c 100644 --- a/dat/Pri-strt.lua +++ b/dat/Pri-strt.lua @@ -1,4 +1,4 @@ --- NetHack Priest Pri-strt.lua $NHDT-Date: 1652196009 2022/05/10 15:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack Priest Pri-strt.lua $NHDT-Date: 1781994870 2026/06/20 22:34:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-fila.lua b/dat/Ran-fila.lua index c9c02cfdd..a6b2417bd 100644 --- a/dat/Ran-fila.lua +++ b/dat/Ran-fila.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-fila.lua $NHDT-Date: 1652196009 2022/05/10 15:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Ranger Ran-fila.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-filb.lua b/dat/Ran-filb.lua index 48275fa95..7813cb5a5 100644 --- a/dat/Ran-filb.lua +++ b/dat/Ran-filb.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-filb.lua $NHDT-Date: 1652196010 2022/05/10 15:20:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Ranger Ran-filb.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-goal.lua b/dat/Ran-goal.lua index a28b0c10b..8d543539b 100644 --- a/dat/Ran-goal.lua +++ b/dat/Ran-goal.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-goal.lua $NHDT-Date: 1652196010 2022/05/10 15:20:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Ranger Ran-goal.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-loca.lua b/dat/Ran-loca.lua index 386c3e785..1c62e0193 100644 --- a/dat/Ran-loca.lua +++ b/dat/Ran-loca.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-loca.lua $NHDT-Date: 1652196010 2022/05/10 15:20:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Ranger Ran-loca.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Ran-strt.lua b/dat/Ran-strt.lua index 8628bcc39..7827fb130 100644 --- a/dat/Ran-strt.lua +++ b/dat/Ran-strt.lua @@ -1,4 +1,4 @@ --- NetHack Ranger Ran-strt.lua $NHDT-Date: 1652196011 2022/05/10 15:20:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Ranger Ran-strt.lua $NHDT-Date: 1781994871 2026/06/20 22:34:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Rog-fila.lua b/dat/Rog-fila.lua index 6b4a80fa2..0c31e7f69 100644 --- a/dat/Rog-fila.lua +++ b/dat/Rog-fila.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-fila.lua $NHDT-Date: 1652196011 2022/05/10 15:20:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Rogue Rog-fila.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Rog-filb.lua b/dat/Rog-filb.lua index 83b5969f1..5af7735d4 100644 --- a/dat/Rog-filb.lua +++ b/dat/Rog-filb.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-filb.lua $NHDT-Date: 1652196011 2022/05/10 15:20:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Rogue Rog-filb.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Rog-goal.lua b/dat/Rog-goal.lua index 4eb58f30b..23e839260 100644 --- a/dat/Rog-goal.lua +++ b/dat/Rog-goal.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-goal.lua $NHDT-Date: 1652196012 2022/05/10 15:20:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Rogue Rog-goal.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Rog-loca.lua b/dat/Rog-loca.lua index 3a88e11fe..4020f33d4 100644 --- a/dat/Rog-loca.lua +++ b/dat/Rog-loca.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-loca.lua $NHDT-Date: 1652196012 2022/05/10 15:20:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Rogue Rog-loca.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Rog-strt.lua b/dat/Rog-strt.lua index 1e4700d49..7c3c60dc3 100644 --- a/dat/Rog-strt.lua +++ b/dat/Rog-strt.lua @@ -1,4 +1,4 @@ --- NetHack Rogue Rog-strt.lua $NHDT-Date: 1652196012 2022/05/10 15:20:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Rogue Rog-strt.lua $NHDT-Date: 1781994872 2026/06/20 22:34:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1992 by Dean Luick -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Sam-fila.lua b/dat/Sam-fila.lua index 53d23d5f6..c3f60e91f 100644 --- a/dat/Sam-fila.lua +++ b/dat/Sam-fila.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-fila.lua $NHDT-Date: 1652196013 2022/05/10 15:20:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Samurai Sam-fila.lua $NHDT-Date: 1781994873 2026/06/20 22:34:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Sam-filb.lua b/dat/Sam-filb.lua index 69e61032d..7646149ac 100644 --- a/dat/Sam-filb.lua +++ b/dat/Sam-filb.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-filb.lua $NHDT-Date: 1652196013 2022/05/10 15:20:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Samurai Sam-filb.lua $NHDT-Date: 1781994873 2026/06/20 22:34:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Sam-goal.lua b/dat/Sam-goal.lua index eb3f95608..e875e9e65 100644 --- a/dat/Sam-goal.lua +++ b/dat/Sam-goal.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-goal.lua $NHDT-Date: 1652196013 2022/05/10 15:20:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Samurai Sam-goal.lua $NHDT-Date: 1781994873 2026/06/20 22:34:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Sam-loca.lua b/dat/Sam-loca.lua index 95bf247f2..248f29ca3 100644 --- a/dat/Sam-loca.lua +++ b/dat/Sam-loca.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-loca.lua $NHDT-Date: 1652196014 2022/05/10 15:20:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Samurai Sam-loca.lua $NHDT-Date: 1781994873 2026/06/20 22:34:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Sam-strt.lua b/dat/Sam-strt.lua index e6cac093c..221ae4a21 100644 --- a/dat/Sam-strt.lua +++ b/dat/Sam-strt.lua @@ -1,4 +1,4 @@ --- NetHack Samurai Sam-strt.lua $NHDT-Date: 1695932714 2023/09/28 20:25:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Samurai Sam-strt.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-fila.lua b/dat/Tou-fila.lua index 6465b5d78..d77e3f154 100644 --- a/dat/Tou-fila.lua +++ b/dat/Tou-fila.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-fila.lua $NHDT-Date: 1652196014 2022/05/10 15:20:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Tourist Tou-fila.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-filb.lua b/dat/Tou-filb.lua index 54855015c..7c4d05d3d 100644 --- a/dat/Tou-filb.lua +++ b/dat/Tou-filb.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-filb.lua $NHDT-Date: 1652196015 2022/05/10 15:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Tourist Tou-filb.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-goal.lua b/dat/Tou-goal.lua index f0f3ca8ef..8dccaa01d 100644 --- a/dat/Tou-goal.lua +++ b/dat/Tou-goal.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-goal.lua $NHDT-Date: 1652196015 2022/05/10 15:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack Tourist Tou-goal.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-loca.lua b/dat/Tou-loca.lua index 68885a91e..f53f15f32 100644 --- a/dat/Tou-loca.lua +++ b/dat/Tou-loca.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-loca.lua $NHDT-Date: 1652196015 2022/05/10 15:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Tourist Tou-loca.lua $NHDT-Date: 1781994874 2026/06/20 22:34:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Tou-strt.lua b/dat/Tou-strt.lua index 5c3a0bc32..7f7304162 100644 --- a/dat/Tou-strt.lua +++ b/dat/Tou-strt.lua @@ -1,4 +1,4 @@ --- NetHack Tourist Tou-strt.lua $NHDT-Date: 1652196016 2022/05/10 15:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack Tourist Tou-strt.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991,92 by M. Stephenson, P. Winner -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-fila.lua b/dat/Val-fila.lua index 8047f7957..52f7b138c 100644 --- a/dat/Val-fila.lua +++ b/dat/Val-fila.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-fila.lua $NHDT-Date: 1652196016 2022/05/10 15:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Valkyrie Val-fila.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-filb.lua b/dat/Val-filb.lua index ede6f1e52..321b5ad6c 100644 --- a/dat/Val-filb.lua +++ b/dat/Val-filb.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-filb.lua $NHDT-Date: 1652196016 2022/05/10 15:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Valkyrie Val-filb.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-goal.lua b/dat/Val-goal.lua index 43179a390..9dacbe095 100644 --- a/dat/Val-goal.lua +++ b/dat/Val-goal.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-goal.lua $NHDT-Date: 1652196017 2022/05/10 15:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack Valkyrie Val-goal.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-loca.lua b/dat/Val-loca.lua index a2875839a..44ff6bd38 100644 --- a/dat/Val-loca.lua +++ b/dat/Val-loca.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-loca.lua $NHDT-Date: 1652196017 2022/05/10 15:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Valkyrie Val-loca.lua $NHDT-Date: 1781994875 2026/06/20 22:34:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Val-strt.lua b/dat/Val-strt.lua index 906500fcf..3e0b0f43e 100644 --- a/dat/Val-strt.lua +++ b/dat/Val-strt.lua @@ -1,4 +1,4 @@ --- NetHack Valkyrie Val-strt.lua $NHDT-Date: 1652196017 2022/05/10 15:20:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Valkyrie Val-strt.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1991-2 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/Wiz-fila.lua b/dat/Wiz-fila.lua index 401067e74..9371a77f4 100644 --- a/dat/Wiz-fila.lua +++ b/dat/Wiz-fila.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-fila.lua $NHDT-Date: 1652196018 2022/05/10 15:20:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Wizard Wiz-fila.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Wiz-filb.lua b/dat/Wiz-filb.lua index 28dc5e366..fbc28a771 100644 --- a/dat/Wiz-filb.lua +++ b/dat/Wiz-filb.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-filb.lua $NHDT-Date: 1652196018 2022/05/10 15:20:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack Wizard Wiz-filb.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Wiz-goal.lua b/dat/Wiz-goal.lua index 8bf86626f..e5a92e92f 100644 --- a/dat/Wiz-goal.lua +++ b/dat/Wiz-goal.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-goal.lua $NHDT-Date: 1652196018 2022/05/10 15:20:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Wizard Wiz-goal.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Wiz-loca.lua b/dat/Wiz-loca.lua index 4522d61c2..5f8eb3080 100644 --- a/dat/Wiz-loca.lua +++ b/dat/Wiz-loca.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-loca.lua $NHDT-Date: 1652196019 2022/05/10 15:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack Wizard Wiz-loca.lua $NHDT-Date: 1781994876 2026/06/20 22:34:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/Wiz-strt.lua b/dat/Wiz-strt.lua index 96a04bae1..f03176afb 100644 --- a/dat/Wiz-strt.lua +++ b/dat/Wiz-strt.lua @@ -1,4 +1,4 @@ --- NetHack Wizard Wiz-strt.lua $NHDT-Date: 1652196019 2022/05/10 15:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack Wizard Wiz-strt.lua $NHDT-Date: 1781994877 2026/06/20 22:34:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1992 by David Cohrs -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/air.lua b/dat/air.lua index af27b86ac..93ba58d59 100644 --- a/dat/air.lua +++ b/dat/air.lua @@ -1,4 +1,4 @@ --- NetHack endgame air.lua $NHDT-Date: 1652196019 2022/05/10 15:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack endgame air.lua $NHDT-Date: 1781994877 2026/06/20 22:34:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/asmodeus.lua b/dat/asmodeus.lua index c860e3cbc..72fd97a30 100644 --- a/dat/asmodeus.lua +++ b/dat/asmodeus.lua @@ -1,4 +1,4 @@ --- NetHack gehennom asmodeus.lua $NHDT-Date: 1652196020 2022/05/10 15:20:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack gehennom asmodeus.lua $NHDT-Date: 1781994877 2026/06/20 22:34:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/astral.lua b/dat/astral.lua index 6d6f0808b..0f6498b31 100644 --- a/dat/astral.lua +++ b/dat/astral.lua @@ -1,4 +1,4 @@ --- NetHack endgame astral.lua $NHDT-Date: 1652196020 2022/05/10 15:20:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +-- NetHack endgame astral.lua $NHDT-Date: 1781994877 2026/06/20 22:34:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/baalz.lua b/dat/baalz.lua index 233c26c5c..360449a85 100644 --- a/dat/baalz.lua +++ b/dat/baalz.lua @@ -1,4 +1,4 @@ --- NetHack gehennom baalz.lua $NHDT-Date: 1652196020 2022/05/10 15:20:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack gehennom baalz.lua $NHDT-Date: 1781994878 2026/06/20 22:34:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-1.lua b/dat/bigrm-1.lua index 2c734a5ac..2d048b786 100644 --- a/dat/bigrm-1.lua +++ b/dat/bigrm-1.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-1.lua $NHDT-Date: 1652196021 2022/05/10 15:20:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack bigroom bigrm-1.lua $NHDT-Date: 1781994878 2026/06/20 22:34:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-10.lua b/dat/bigrm-10.lua index dc51c1e02..90626100e 100644 --- a/dat/bigrm-10.lua +++ b/dat/bigrm-10.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-10.lua $NHDT-Date: 1652196024 2022/05/10 15:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack bigroom bigrm-10.lua $NHDT-Date: 1781994878 2026/06/20 22:34:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-11.lua b/dat/bigrm-11.lua index db9bcdccd..67df8d063 100644 --- a/dat/bigrm-11.lua +++ b/dat/bigrm-11.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-11.lua $NHDT-Date: 1652196024 2022/05/10 15:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +-- NetHack bigroom bigrm-11.lua $NHDT-Date: 1781994878 2026/06/20 22:34:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1 $ -- Copyright (c) 2021 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/bigrm-12.lua b/dat/bigrm-12.lua index 0e41bd9e4..cb9a6e100 100644 --- a/dat/bigrm-12.lua +++ b/dat/bigrm-12.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-12.lua $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $ +-- NetHack bigroom bigrm-12.lua $NHDT-Date: $ $NHDT-Branch: NetHack-5.0 $ -- Copyright (c) 2024 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/bigrm-13.lua b/dat/bigrm-13.lua index ff834a666..94b473eed 100644 --- a/dat/bigrm-13.lua +++ b/dat/bigrm-13.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-13.lua $NHDT-Date: 1652196024 2022/05/10 15:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +-- NetHack bigroom bigrm-13.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 2026 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/bigrm-2.lua b/dat/bigrm-2.lua index 53c3e100a..fc99ec540 100644 --- a/dat/bigrm-2.lua +++ b/dat/bigrm-2.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-2.lua $NHDT-Date: 1652196021 2022/05/10 15:20:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-2.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-3.lua b/dat/bigrm-3.lua index ee7e0f310..315a0aa30 100644 --- a/dat/bigrm-3.lua +++ b/dat/bigrm-3.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-3.lua $NHDT-Date: 1652196021 2022/05/10 15:20:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-3.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-4.lua b/dat/bigrm-4.lua index a6b9340d1..b38b31047 100644 --- a/dat/bigrm-4.lua +++ b/dat/bigrm-4.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-4.lua $NHDT-Date: 1652196022 2022/05/10 15:20:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-4.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-5.lua b/dat/bigrm-5.lua index 3e40812e6..1e63e7851 100644 --- a/dat/bigrm-5.lua +++ b/dat/bigrm-5.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-5.lua $NHDT-Date: 1652196022 2022/05/10 15:20:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-5.lua $NHDT-Date: 1781994879 2026/06/20 22:34:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-6.lua b/dat/bigrm-6.lua index c6063a818..e4d9a2b6d 100644 --- a/dat/bigrm-6.lua +++ b/dat/bigrm-6.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-6.lua $NHDT-Date: 1652196022 2022/05/10 15:20:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-6.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-7.lua b/dat/bigrm-7.lua index 07038d8d6..58154a466 100644 --- a/dat/bigrm-7.lua +++ b/dat/bigrm-7.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-7.lua $NHDT-Date: 1652196023 2022/05/10 15:20:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +-- NetHack bigroom bigrm-7.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-8.lua b/dat/bigrm-8.lua index f851411a8..fa6a7e181 100644 --- a/dat/bigrm-8.lua +++ b/dat/bigrm-8.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-8.lua $NHDT-Date: 1652196023 2022/05/10 15:20:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-8.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bigrm-9.lua b/dat/bigrm-9.lua index e46543619..f7c33e879 100644 --- a/dat/bigrm-9.lua +++ b/dat/bigrm-9.lua @@ -1,4 +1,4 @@ --- NetHack bigroom bigrm-9.lua $NHDT-Date: 1652196023 2022/05/10 15:20:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack bigroom bigrm-9.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/bogusmon.txt b/dat/bogusmon.txt index 8b5335296..8a418ff50 100644 --- a/dat/bogusmon.txt +++ b/dat/bogusmon.txt @@ -1,4 +1,4 @@ -# NetHack 3.7 bogusmon.txt $NHDT-Date: 1596498237 2020/08/03 23:43:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 bogusmon.txt $NHDT-Date: 1596498237 2020/08/03 23:43:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2016 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # @@ -97,6 +97,22 @@ voussoir barking spider frog cloud toothsayer +third eye +owlpug +pugasus +acorn +red dot +robot chicken +doozer +poison cackler +lhurgoyf +phelddagrif +tiktaalik +weremoustache +rapier tapir +choplet +pommelbug +quest sprout # Quendor (Zork, &c.) grue @@ -301,6 +317,7 @@ wiki peer COBOL wire shark +stray tab # bugs bohrbug @@ -384,9 +401,6 @@ little green man # Portal weighted Companion Cube -# /b/ -/b/tard - # South Park manbearpig diff --git a/dat/castle.lua b/dat/castle.lua index 0a2b7f243..9d4fa355a 100644 --- a/dat/castle.lua +++ b/dat/castle.lua @@ -1,4 +1,4 @@ --- NetHack castle castle.lua $NHDT-Date: 1652196024 2022/05/10 15:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +-- NetHack castle castle.lua $NHDT-Date: 1781994880 2026/06/20 22:34:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/data.base b/dat/data.base index d43307f33..f5008be1f 100644 --- a/dat/data.base +++ b/dat/data.base @@ -1,4 +1,4 @@ -# NetHack 3.7 data.base +# NetHack 5.0 data.base # $NHDT-Date: 1737609388 2025/01/22 21:16:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ # Copyright (c) 1994, 1995, 1996 by the NetHack Development Team # Copyright (c) 1994 by Boudewijn Wayers @@ -182,7 +182,7 @@ angel* shall come forth, and sever the wicked from among the just, and shall cast them into the furnace of fire; there shall be wailing and gnashing of teeth. - [ The Gospel According to Matthew, 13:37-42, 49-50 ] + [ The Gospel According to Matthew, 13:37-40, 49-50 ] angry god* Cold wind blows. The gods look down in anger on this poor child. @@ -1384,7 +1384,7 @@ dispater Wealth". It refers to the wealth of precious stone below the earth. [ Encyclopedia Mythica, ed. M.F. Lindemans ] -# 3.7; monster adapted from slash'em based on an AD&D Monster Manual entry; +# 5.0; monster adapted from slash'em based on an AD&D Monster Manual entry; # slash'em lacked a description so this entry has been created from scratch; # the puma comparison is how the AD&D monster is described (except that # that creature has six legs and two tentacles!) but the actual monster's @@ -2048,7 +2048,7 @@ gem or rock same as for jewels: it is always the false ones that look the most real, the most brilliant. [ Salvador Dali ] -# 3.7; monster derived from slash'em which lacked a description so this +# 5.0; monster derived from slash'em which lacked a description so this # entry has been created from scratch genetic engineer These very odd people have mastered the ability to insert gene @@ -2418,7 +2418,7 @@ helm of caution A helmet which confers the "warning" property, sensing the strength of threats posed by unseen hostile creatures. # note: this quotation had "high of steel" but we're going to cheat--it is -# now deliberately mistranslated as "high of crystal" to match nethack 3.7's +# now deliberately mistranslated as "high of crystal" to match nethack 5.0's # change to helm of brilliance and become more useful to players. # PR #1109 wanted to change it to be for all helms but being covered with # gems and gold is not appropriate for ordinary helmets (plus it states that diff --git a/dat/dungeon.lua b/dat/dungeon.lua index d90eb9214..5b1d23d2e 100644 --- a/dat/dungeon.lua +++ b/dat/dungeon.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 dungeon dungeon.lua $NHDT-Date: 1652196135 2022/05/10 15:22:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack 3.6 dungeon dungeon.lua $NHDT-Date: 1781994881 2026/06/20 22:34:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ -- Copyright (c) 1990-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. -- @@ -185,7 +185,7 @@ dungeon = { }, { name = "minend", --- 3.7.0: minend changed to no-bones to simplify achievement tracking +-- 5.0.0: minend changed to no-bones to simplify achievement tracking -- bonetag = "E" base = -1, nlevels = 3 diff --git a/dat/earth.lua b/dat/earth.lua index 4d7527e07..f052b4b08 100644 --- a/dat/earth.lua +++ b/dat/earth.lua @@ -1,4 +1,4 @@ --- NetHack endgame earth.lua $NHDT-Date: 1652196025 2022/05/10 15:20:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack endgame earth.lua $NHDT-Date: 1781994881 2026/06/20 22:34:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/engrave.txt b/dat/engrave.txt index ff473b610..cd62963a8 100644 --- a/dat/engrave.txt +++ b/dat/engrave.txt @@ -1,4 +1,4 @@ -# NetHack 3.7 engrave.txt $NHDT-Date: 1596498240 2020/08/03 23:44:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +# NetHack 5.0 engrave.txt $NHDT-Date: 1596498240 2020/08/03 23:44:00 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ # Copyright (c) 2015 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # Random engravings on the floor diff --git a/dat/epitaph.txt b/dat/epitaph.txt index d559d1fb3..2d80d1741 100644 --- a/dat/epitaph.txt +++ b/dat/epitaph.txt @@ -1,4 +1,4 @@ -# NetHack 3.7 epitaph.txt $NHDT-Date: 1596498241 2020/08/03 23:44:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +# NetHack 5.0 epitaph.txt $NHDT-Date: 1596498241 2020/08/03 23:44:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ # Copyright (c) 2015 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # Epitaphs for random headstones diff --git a/dat/fakewiz1.lua b/dat/fakewiz1.lua index abee299d7..1ab3bd05f 100644 --- a/dat/fakewiz1.lua +++ b/dat/fakewiz1.lua @@ -1,4 +1,4 @@ --- NetHack yendor fakewiz1.lua $NHDT-Date: 1652196025 2022/05/10 15:20:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack yendor fakewiz1.lua $NHDT-Date: 1781994881 2026/06/20 22:34:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/fakewiz2.lua b/dat/fakewiz2.lua index 4b81ae338..731b84813 100644 --- a/dat/fakewiz2.lua +++ b/dat/fakewiz2.lua @@ -1,4 +1,4 @@ --- NetHack yendor fakewiz2.lua $NHDT-Date: 1652196026 2022/05/10 15:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack yendor fakewiz2.lua $NHDT-Date: 1781994881 2026/06/20 22:34:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/fire.lua b/dat/fire.lua index 1cd3db7a2..01fc3c93a 100644 --- a/dat/fire.lua +++ b/dat/fire.lua @@ -1,4 +1,4 @@ --- NetHack endgame fire.lua $NHDT-Date: 1700398454 2023/11/19 12:54:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack endgame fire.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/hellfill.lua b/dat/hellfill.lua index 3a9b4ed9f..9808837fc 100644 --- a/dat/hellfill.lua +++ b/dat/hellfill.lua @@ -1,4 +1,4 @@ --- NetHack 3.7 hellfill.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 5.0 hellfill.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- Copyright (c) 2022 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/history b/dat/history index 3d4b6e9bc..dfc073372 100644 --- a/dat/history +++ b/dat/history @@ -1,4 +1,4 @@ -NetHack History file for release 3.7 +NetHack History file for release 5.0 Behold, mortal, the origins of NetHack... @@ -274,6 +274,70 @@ some bug fixes. NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. +Development work for the major release to follow NetHack 3.6 began in 2015 +around the same time as NetHack 3.6.0 was being released. That development +work continued in parallel to each of the NetHack 3.6 releases from 2015 +through 2023, and continued until the end of April 2026. For the first time, +that development was shared publicly on GitHub and SourceForge as it occurred. +It was done under the label NetHack-3.7 work-in-progress (WIP), although the +version number for the next release had not yet been solidified. + +Exposure of the development to the public brought many good things, and some +challenges. People were able to observe and criticize changes and new features +almost immediately, and they often did. The GitHub pull request system made +it straightforward for people to contribute directly to development. +Contributions resolved many, many bugs in the game and we thank all the +contributors. + +In early 2026, with the game development getting stable enough to consider +initiating an official release, the devteam reviewed the nature and number of +changes in the game. It was clear that there was sufficient depth and +breadth to warrant a major release and version 5.0 was decided on. +That's a new major release over 3.x, without opening up any ambiguity +or confusion with existing variants that there might have been had it +been released as version 4.0. + +NetHack 5.0.0 was released on May 2, 2026. + +The source code for NetHack 5.0.0 was modified and modernized to be compliant +with the C99 standard. The 5.0.0 release contained over 3100 fixes,changes, +and updated features. + +NetHack 5.0 was the first version to replace the lex and yacc level +and dungeon compilers of past versions, with a new Lua interpreter-based +approach to provide those elements. Lua is also used for the quest texts +in NetHack 5.0.0. The entire development team acknowledges the work +done by Pasi Kallinen to make that happen. + +At the time of the NetHack 5.0 release, the core development team, +active and erstwhile, included Warwick Allison, Michael Allison, +Ken Arromdee, David Cohrs, Jessie Collet, Bart House, Kevin Hugo, +Pasi Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, +Alex Smith, Patric Mueller, Mike Stephenson, Janet Walz, Paul Winner. + +Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison helped ensure +that NetHack 5.0 would run on macOS. + +Ingo Paschke somehow managed to revive a NetHack 5.0 port for the Amiga, +using a cross-compiler on a modern platform to do so. His work was shared +so others can straightforwardly produce NetHack 5.0 for the Amiga thanks +to his efforts. + +Ray Chason contributed the majority of maintenance work for the NetHack 5.0 +MS-DOS port, including porting the curses interface to it. +Michael Allison ensured that NetHack 5.0 core changes continued to work +with the msdos port and keep it alive. Cross-compiling the MS-DOS port +has helped make that possible and mostly painless. + +People that contributed to the Windows port of NetHack 5.0 since the +development of NetHack 5.0 began over eleven years ago, included +Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, +Dion Nicolaas, Derek S. Ray and Yitzhak Sapir. + +With sadness, the devteam would like to acknowledge and remember the past +contributions from the late Ron Van Iwaarden, who was the sole maintainer +of NetHack for OS/2 for several past NetHack releases. Ron will be missed. + The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. @@ -292,45 +356,46 @@ particularly intriguing modification to help out with the game. The NetHack Development Team sometimes makes note of the names of the worst of these miscreants in this, the list of Dungeoneers: - Adam Aronow J. Ali Harlow Mikko Juola - Alex Kompel Janet Walz Nathan Eady - Alex Smith Janne Salmijarvi Norm Meluch - Andreas Dorn Jean-Christophe Collet Olaf Seibert - Andy Church Jeff Bailey Pasi Kallinen - Andy Swanson Jochen Erwied Pat Rankin - Andy Thomson John Kallen Patric Mueller - Ari Huttunen John Rupley Paul Winner - Bart House John S. Bien Pierre Martineau - Benson I. Margulies Johnny Lee Ralf Brown - Bill Dyer Jon W{tte Ray Chason - Boudewijn Waijers Jonathan Handler Richard Addison - Bruce Cox Joshua Delahunty Richard Beigel - Bruce Holloway Karl Garrison Richard P. Hughey - Bruce Mewborne Keizo Yamamoto Rob Menke - Carl Schelin Keith Simpson Robin Bandy - Chris Russo Ken Arnold Robin Johnson - David Cohrs Ken Arromdee Roderick Schertler - David Damerell Ken Lorber Roland McGrath - David Gentzel Ken Washikita Ron Van Iwaarden - David Hairston Kevin Darcy Ronnen Miller - Dean Luick Kevin Hugo Ross Brown - Del Lamb Kevin Sitze Sascha Wostmann - Derek S. Ray Kevin Smolkowski Scott Bigham - Deron Meranda Kevin Sweet Scott R. Turner - Dion Nicolaas Lars Huttar Sean Hunt - Dylan O'Donnell Leon Arnott Stephen Spackman - Eric Backus M. Drew Streib Stefan Thielscher - Eric Hendrickson Malcolm Ryan Stephen White - Eric R. Smith Mark Gooderum Steve Creps - Eric S. Raymond Mark Modrall Steve Linhart - Erik Andersen Marvin Bressler Steve VanDevender - Fredrik Ljungdahl Matthew Day Teemu Suikki - Frederick Roeber Merlyn LeRoy Tim Lennan - Gil Neiger Michael Allison Timo Hakulinen - Greg Laskin Michael Feir Tom Almy - Greg Olson Michael Hamel Tom West - Gregg Wonderly Michael Sokolov Warren Cheung - Hao-yang Wang Mike Engber Warwick Allison - Helge Hafting Mike Gallop Yitzhak Sapir - Irina Rempt-Drijfhout Mike Passaretti - Izchak Miller Mike Stephenson + Adam Aronow Irina Rempt-Drijfhout Mike Gallop + Alex Kompel Izchak Miller Mike Passaretti + Alex Smith J. Ali Harlow Mike Stephenson + Andreas Dorn Janet Walz Mikko Juola + Andy Church Janne Salmijarvi Nathan Eady + Andy Swanson Jean-Christophe Collet Norm Meluch + Andy Thomson Jeff Bailey Olaf Seibert + Ari Huttunen Jochen Erwied Pasi Kallinen + Bart House John Kallen Pat Rankin + Benson I. Margulies John Rupley Patric Mueller + Bill Dyer John S. Bien Paul Winner + Boudewijn Waijers Johnny Lee Pierre Martineau + Bruce Cox Jon W{tte Ralf Brown + Bruce Holloway Jonathan Handler Ray Chason + Bruce Mewborne Joshua Delahunty Richard Addison + Cameron Root Karl Garrison Richard Beigel + Carl Schelin Keizo Yamamoto Richard P. Hughey + Chris Russo Keith Simpson Rob Menke + David Cohrs Ken Arnold Robin Bandy + David Damerell Ken Arromdee Robin Johnson + David Gentzel Ken Lorber Roderick Schertler + David Hairston Ken Washikita Roland McGrath + Dean Luick Kestrel Gregorich-Trevor Ron Van Iwaarden + Del Lamb Kevin Darcy Ronnen Miller + Derek S. Ray Kevin Hugo Ross Brown + Deron Meranda Kevin Sitze Sascha Wostmann + Dion Nicolaas Kevin Smolkowski Scott Bigham + Dylan O'Donnell Kevin Sweet Scott R. Turner + Eric Backus Lars Huttar Sean Hunt + Eric Hendrickson Leon Arnott Stephen Spackman + Eric R. Smith M. Drew Streib Stefan Thielscher + Eric S. Raymond Malcolm Ryan Stephen White + Erik Andersen Mark Gooderum Steve Creps + Fredrik Ljungdahl Mark Modrall Steve Linhart + Frederick Roeber Marvin Bressler Steve VanDevender + G. Branden Robinson Matthew Day Teemu Suikki + Gil Neiger Merlyn LeRoy Tim Lennan + Greg Laskin Michael Allison Timo Hakulinen + Greg Olson Michael Feir Tom Almy + Gregg Wonderly Michael Hamel Tom West + Hao-yang Wang Michael Meyer Warren Cheung + Helge Hafting Michael Sokolov Warwick Allison + Ingo Paschke Mike Engber Yitzhak Sapir diff --git a/dat/juiblex.lua b/dat/juiblex.lua index 56c02f9a5..cbf8620cd 100644 --- a/dat/juiblex.lua +++ b/dat/juiblex.lua @@ -1,4 +1,4 @@ --- NetHack gehennom juiblex.lua $NHDT-Date: 1652196026 2022/05/10 15:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack gehennom juiblex.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/knox.lua b/dat/knox.lua index 2b58f2ae4..ed947743f 100644 --- a/dat/knox.lua +++ b/dat/knox.lua @@ -1,4 +1,4 @@ --- NetHack knox knox.lua $NHDT-Date: 1652196027 2022/05/10 15:20:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack knox knox.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/luahelper b/dat/luahelper index 7f8a653fa..5db4f831b 100644 --- a/dat/luahelper +++ b/dat/luahelper @@ -1,4 +1,4 @@ -# NetHack 3.7 luahelper $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 luahelper $NHDT-Date: 1777237994 2026/04/26 16:13:14 $ $NHDT-Branch: NetHack-5.0 $ # # Makefile to assist developers in adding lines to various build # Makefiles, or project files, as lua files are added or removed. diff --git a/dat/medusa-1.lua b/dat/medusa-1.lua index 3c5e50c66..6763abb4c 100644 --- a/dat/medusa-1.lua +++ b/dat/medusa-1.lua @@ -1,4 +1,4 @@ --- NetHack medusa medusa-1.lua $NHDT-Date: 1652196027 2022/05/10 15:20:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack medusa medusa-1.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990, 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/medusa-2.lua b/dat/medusa-2.lua index d270616ae..d3adcbfb7 100644 --- a/dat/medusa-2.lua +++ b/dat/medusa-2.lua @@ -1,4 +1,4 @@ --- NetHack medusa medusa-2.lua $NHDT-Date: 1652196027 2022/05/10 15:20:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack medusa medusa-2.lua $NHDT-Date: 1781994882 2026/06/20 22:34:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990, 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/medusa-3.lua b/dat/medusa-3.lua index 282d3668b..84da3dee0 100644 --- a/dat/medusa-3.lua +++ b/dat/medusa-3.lua @@ -1,4 +1,4 @@ --- NetHack medusa medusa-3.lua $NHDT-Date: 1716152250 2024/05/19 20:57:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +-- NetHack medusa medusa-3.lua $NHDT-Date: 1781994883 2026/06/20 22:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990, 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/medusa-4.lua b/dat/medusa-4.lua index acf6c6d3f..22fbd91f6 100644 --- a/dat/medusa-4.lua +++ b/dat/medusa-4.lua @@ -1,4 +1,4 @@ --- NetHack medusa medusa-4.lua $NHDT-Date: 1716152274 2024/05/19 20:57:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +-- NetHack medusa medusa-4.lua $NHDT-Date: 1781994883 2026/06/20 22:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1990, 1991 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minefill.lua b/dat/minefill.lua index 2992690e6..eab601b23 100644 --- a/dat/minefill.lua +++ b/dat/minefill.lua @@ -1,4 +1,4 @@ --- NetHack mines minefill.lua $NHDT-Date: 1652196028 2022/05/10 15:20:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minefill.lua $NHDT-Date: 1781994883 2026/06/20 22:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minend-1.lua b/dat/minend-1.lua index 5d690c32c..f32f27c62 100644 --- a/dat/minend-1.lua +++ b/dat/minend-1.lua @@ -1,4 +1,4 @@ --- NetHack mines minend-1.lua $NHDT-Date: 1652196029 2022/05/10 15:20:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minend-1.lua $NHDT-Date: 1781994883 2026/06/20 22:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minend-2.lua b/dat/minend-2.lua index e85e45870..061e00aa6 100644 --- a/dat/minend-2.lua +++ b/dat/minend-2.lua @@ -1,4 +1,4 @@ --- NetHack mines minend-2.lua $NHDT-Date: 1652196029 2022/05/10 15:20:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack mines minend-2.lua $NHDT-Date: 1781994884 2026/06/20 22:34:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minend-3.lua b/dat/minend-3.lua index 411e1ac67..21f25a6a0 100644 --- a/dat/minend-3.lua +++ b/dat/minend-3.lua @@ -1,4 +1,4 @@ --- NetHack mines minend-3.lua $NHDT-Date: 1652196029 2022/05/10 15:20:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack mines minend-3.lua $NHDT-Date: 1781994884 2026/06/20 22:34:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-1.lua b/dat/minetn-1.lua index ef10d70b7..c0bf0f68d 100644 --- a/dat/minetn-1.lua +++ b/dat/minetn-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.7 mines minetn-1.lua $NHDT-Date: 1652196030 2022/05/10 15:20:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +-- NetHack 5.0 mines minetn-1.lua $NHDT-Date: 1781994884 2026/06/20 22:34:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-2.lua b/dat/minetn-2.lua index 133285f93..60784f7a4 100644 --- a/dat/minetn-2.lua +++ b/dat/minetn-2.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-2.lua $NHDT-Date: 1652196030 2022/05/10 15:20:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minetn-2.lua $NHDT-Date: 1781994884 2026/06/20 22:34:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-3.lua b/dat/minetn-3.lua index 910293868..e8b308ef9 100644 --- a/dat/minetn-3.lua +++ b/dat/minetn-3.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-3.lua $NHDT-Date: 1652196030 2022/05/10 15:20:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack mines minetn-3.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-4.lua b/dat/minetn-4.lua index 6d5804133..57625fdf4 100644 --- a/dat/minetn-4.lua +++ b/dat/minetn-4.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-4.lua $NHDT-Date: 1652196031 2022/05/10 15:20:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack mines minetn-4.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-5.lua b/dat/minetn-5.lua index a0d16ea0a..c995d2f55 100644 --- a/dat/minetn-5.lua +++ b/dat/minetn-5.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-5.lua $NHDT-Date: 1652196031 2022/05/10 15:20:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack mines minetn-5.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-6.lua b/dat/minetn-6.lua index 2827d1947..9f37d76e3 100644 --- a/dat/minetn-6.lua +++ b/dat/minetn-6.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-6.lua $NHDT-Date: 1652196031 2022/05/10 15:20:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minetn-6.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/minetn-7.lua b/dat/minetn-7.lua index 31a1d3d80..024c3389d 100644 --- a/dat/minetn-7.lua +++ b/dat/minetn-7.lua @@ -1,4 +1,4 @@ --- NetHack mines minetn-7.lua $NHDT-Date: 1652196032 2022/05/10 15:20:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack mines minetn-7.lua $NHDT-Date: 1781994885 2026/06/20 22:34:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989-95 by Jean-Christophe Collet -- Copyright (c) 1991-95 by M. Stephenson -- NetHack may be freely redistributed. See license for details. diff --git a/dat/nhcore.lua b/dat/nhcore.lua index 0fc778f6c..41c718dc0 100644 --- a/dat/nhcore.lua +++ b/dat/nhcore.lua @@ -1,4 +1,4 @@ --- NetHack core nhcore.lua $NHDT-Date: 1652196284 2022/05/10 15:24:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +-- NetHack core nhcore.lua $NHDT-Date: 1781994886 2026/06/20 22:34:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 2021 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- This file contains lua code used by NetHack core. diff --git a/dat/nhlib.lua b/dat/nhlib.lua index f4fab68fb..f8fc93072 100644 --- a/dat/nhlib.lua +++ b/dat/nhlib.lua @@ -1,4 +1,4 @@ --- NetHack nhlib.lua $NHDT-Date: 1652196140 2022/05/10 15:22:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack nhlib.lua $NHDT-Date: 1781994886 2026/06/20 22:34:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ -- Copyright (c) 2021 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- compatibility shim diff --git a/dat/oracle.lua b/dat/oracle.lua index 16ee2ff4e..b77562ce3 100644 --- a/dat/oracle.lua +++ b/dat/oracle.lua @@ -1,4 +1,4 @@ --- NetHack oracle oracle.lua $NHDT-Date: 1652196033 2022/05/10 15:20:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack oracle oracle.lua $NHDT-Date: 1781994886 2026/06/20 22:34:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 2015 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/orcus.lua b/dat/orcus.lua index 67406d8e2..b3d286c2c 100644 --- a/dat/orcus.lua +++ b/dat/orcus.lua @@ -1,4 +1,4 @@ --- NetHack gehennom orcus.lua $NHDT-Date: 1652196033 2022/05/10 15:20:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack gehennom orcus.lua $NHDT-Date: 1781994886 2026/06/20 22:34:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/quest.lua b/dat/quest.lua index c3bad692d..298b6bb60 100644 --- a/dat/quest.lua +++ b/dat/quest.lua @@ -1,4 +1,4 @@ --- NetHack quest.lua $NHDT-Date: 1726894904 2024/09/21 05:01:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +-- NetHack quest.lua $NHDT-Date: 1781994887 2026/06/20 22:34:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ -- Copyright (c) 2021 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- TODO: diff --git a/dat/sanctum.lua b/dat/sanctum.lua index fe5a85eb0..803ce73c2 100644 --- a/dat/sanctum.lua +++ b/dat/sanctum.lua @@ -1,4 +1,4 @@ --- NetHack gehennom sanctum.lua $NHDT-Date: 1652196034 2022/05/10 15:20:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +-- NetHack gehennom sanctum.lua $NHDT-Date: 1781994887 2026/06/20 22:34:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/soko1-1.lua b/dat/soko1-1.lua index ac9bcdf31..4d9886b3a 100644 --- a/dat/soko1-1.lua +++ b/dat/soko1-1.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko1-1.lua $NHDT-Date: 1652196034 2022/05/10 15:20:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ +-- NetHack sokoban soko1-1.lua $NHDT-Date: 1781994887 2026/06/20 22:34:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko1-2.lua b/dat/soko1-2.lua index 36ab90721..34bffdb96 100644 --- a/dat/soko1-2.lua +++ b/dat/soko1-2.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko1-2.lua $NHDT-Date: 1652196034 2022/05/10 15:20:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ +-- NetHack sokoban soko1-2.lua $NHDT-Date: 1781994887 2026/06/20 22:34:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko2-1.lua b/dat/soko2-1.lua index e8b56efef..475323984 100644 --- a/dat/soko2-1.lua +++ b/dat/soko2-1.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko2-1.lua $NHDT-Date: 1652196035 2022/05/10 15:20:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack sokoban soko2-1.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko2-2.lua b/dat/soko2-2.lua index f11702c1e..18c07c1e9 100644 --- a/dat/soko2-2.lua +++ b/dat/soko2-2.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko2-2.lua $NHDT-Date: 1652196035 2022/05/10 15:20:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack sokoban soko2-2.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko3-1.lua b/dat/soko3-1.lua index 1c7715858..1675ed09c 100644 --- a/dat/soko3-1.lua +++ b/dat/soko3-1.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko3-1.lua $NHDT-Date: 1652196035 2022/05/10 15:20:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack sokoban soko3-1.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko3-2.lua b/dat/soko3-2.lua index 24236efe2..e445fffa9 100644 --- a/dat/soko3-2.lua +++ b/dat/soko3-2.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko3-2.lua $NHDT-Date: 1652196036 2022/05/10 15:20:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack sokoban soko3-2.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko4-1.lua b/dat/soko4-1.lua index 3768c1cf7..39b35e30a 100644 --- a/dat/soko4-1.lua +++ b/dat/soko4-1.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko4-1.lua $NHDT-Date: 1652196036 2022/05/10 15:20:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack sokoban soko4-1.lua $NHDT-Date: 1781994888 2026/06/20 22:34:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/soko4-2.lua b/dat/soko4-2.lua index d0606dc6a..df830b32d 100644 --- a/dat/soko4-2.lua +++ b/dat/soko4-2.lua @@ -1,4 +1,4 @@ --- NetHack sokoban soko4-2.lua $NHDT-Date: 1652196036 2022/05/10 15:20:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack sokoban soko4-2.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/symbols b/dat/symbols index 6233c83f5..39ea0ce6a 100644 --- a/dat/symbols +++ b/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.7 symbols $NHDT-Date: 1725052751 2024/08/30 21:19:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ +# NetHack 5.0 symbols $NHDT-Date: 1725052751 2024/08/30 21:19:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.36 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -894,28 +894,28 @@ start: Enhanced1 G_tdwall_gehennom: U+252C/red # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL G_tlwall_gehennom: U+2524/red # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT G_trwall_gehennom: U+251C/red # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT - G_vwall_knox: U+2502/150-75-0 # │ BOX DRAWINGS LIGHT VERTICAL - G_hwall_knox: U+2500/150-75-0 # ─ BOX DRAWINGS LIGHT HORIZONTAL - G_tlcorn_knox: U+250c/150-75-0 # ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT - G_trcorn_knox: U+2510/150-75-0 # â” BOX DRAWINGS LIGHT DOWN AND LEFT - G_blcorn_knox: U+2514/150-75-0 # â”” BOX DRAWINGS LIGHT UP AND RIGHT - G_brcorn_knox: U+2518/150-75-0 # ┘ BOX DRAWINGS LIGHT UP AND LEFT - G_crwall_knox: U+253C/150-75-0 # ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - G_tuwall_knox: U+2534/150-75-0 # â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL - G_tdwall_knox: U+252C/150-75-0 # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - G_tlwall_knox: U+2524/150-75-0 # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT - G_trwall_knox: U+251C/150-75-0 # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT - G_vwall_mines: U+2502/113-126-142 # │ BOX DRAWINGS LIGHT VERTICAL - G_hwall_mines: U+2500/113-126-142 # ─ BOX DRAWINGS LIGHT HORIZONTAL - G_tlcorn_mines: U+250c/113-126-142 # ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT - G_trcorn_mines: U+2510/113-126-142 # â” BOX DRAWINGS LIGHT DOWN AND LEFT - G_blcorn_mines: U+2514/113-126-142 # â”” BOX DRAWINGS LIGHT UP AND RIGHT - G_brcorn_mines: U+2518/113-126-142 # ┘ BOX DRAWINGS LIGHT UP AND LEFT - G_crwall_mines: U+253C/113-126-142 # ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - G_tuwall_mines: U+2534/113-126-142 # â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL - G_tdwall_mines: U+252C/113-126-142 # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - G_tlwall_mines: U+2524/113-126-142 # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT - G_trwall_mines: U+251C/113-126-142 # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT + G_vwall_knox: U+2502/126-230-230 # │ BOX DRAWINGS LIGHT VERTICAL + G_hwall_knox: U+2500/126-230-230 # ─ BOX DRAWINGS LIGHT HORIZONTAL + G_tlcorn_knox: U+250c/126-230-230 # ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT + G_trcorn_knox: U+2510/126-230-230 # â” BOX DRAWINGS LIGHT DOWN AND LEFT + G_blcorn_knox: U+2514/126-230-230 # â”” BOX DRAWINGS LIGHT UP AND RIGHT + G_brcorn_knox: U+2518/126-230-230 # ┘ BOX DRAWINGS LIGHT UP AND LEFT + G_crwall_knox: U+253C/126-230-230 # ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + G_tuwall_knox: U+2534/126-230-230 # â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL + G_tdwall_knox: U+252C/126-230-230 # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + G_tlwall_knox: U+2524/126-230-230 # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT + G_trwall_knox: U+251C/126-230-230 # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT + G_vwall_mines: U+2502/190-126-0 # │ BOX DRAWINGS LIGHT VERTICAL + G_hwall_mines: U+2500/190-126-0 # ─ BOX DRAWINGS LIGHT HORIZONTAL + G_tlcorn_mines: U+250c/190-126-0 # ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT + G_trcorn_mines: U+2510/190-126-0 # â” BOX DRAWINGS LIGHT DOWN AND LEFT + G_blcorn_mines: U+2514/190-126-0 # â”” BOX DRAWINGS LIGHT UP AND RIGHT + G_brcorn_mines: U+2518/190-126-0 # ┘ BOX DRAWINGS LIGHT UP AND LEFT + G_crwall_mines: U+253C/190-126-0 # ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + G_tuwall_mines: U+2534/190-126-0 # â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL + G_tdwall_mines: U+252C/190-126-0 # ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + G_tlwall_mines: U+2524/190-126-0 # ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT + G_trwall_mines: U+251C/190-126-0 # ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT finish start: Enhanced2 @@ -997,28 +997,28 @@ start: Enhanced2 G_tdwall_gehennom: U+252C/red G_tlwall_gehennom: U+2524/red G_trwall_gehennom: U+251C/red - G_vwall_knox: U+2502/150-75-0 - G_hwall_knox: U+2500/150-75-0 - G_tlcorn_knox: U+250c/150-75-0 - G_trcorn_knox: U+2510/150-75-0 - G_blcorn_knox: U+2514/150-75-0 - G_brcorn_knox: U+2518/150-75-0 - G_crwall_knox: U+253C/150-75-0 - G_tuwall_knox: U+2534/150-75-0 - G_tdwall_knox: U+252C/150-75-0 - G_tlwall_knox: U+2524/150-75-0 - G_trwall_knox: U+251C/150-75-0 - G_vwall_mines: U+2502/113-126-142 - G_hwall_mines: U+2500/113-126-142 - G_tlcorn_mines: U+250c/113-126-142 - G_trcorn_mines: U+2510/113-126-142 - G_blcorn_mines: U+2514/113-126-142 - G_brcorn_mines: U+2518/113-126-142 - G_crwall_mines: U+253C/113-126-142 - G_tuwall_mines: U+2534/113-126-142 - G_tdwall_mines: U+252C/113-126-142 - G_tlwall_mines: U+2524/113-126-142 - G_trwall_mines: U+251C/113-126-142 + G_vwall_knox: U+2502/126-230-230 + G_hwall_knox: U+2500/126-230-230 + G_tlcorn_knox: U+250c/126-230-230 + G_trcorn_knox: U+2510/126-230-230 + G_blcorn_knox: U+2514/126-230-230 + G_brcorn_knox: U+2518/126-230-230 + G_crwall_knox: U+253C/126-230-230 + G_tuwall_knox: U+2534/126-230-230 + G_tdwall_knox: U+252C/126-230-230 + G_tlwall_knox: U+2524/126-230-230 + G_trwall_knox: U+251C/126-230-230 + G_vwall_mines: U+2502/190-126-0 + G_hwall_mines: U+2500/190-126-0 + G_tlcorn_mines: U+250c/190-126-0 + G_trcorn_mines: U+2510/190-126-0 + G_blcorn_mines: U+2514/190-126-0 + G_brcorn_mines: U+2518/190-126-0 + G_crwall_mines: U+253C/190-126-0 + G_tuwall_mines: U+2534/190-126-0 + G_tdwall_mines: U+252C/190-126-0 + G_tlwall_mines: U+2524/190-126-0 + G_trwall_mines: U+251C/190-126-0 finish start: AmigaFont diff --git a/dat/themerms.lua b/dat/themerms.lua index 6aff95286..c29d66ce0 100644 --- a/dat/themerms.lua +++ b/dat/themerms.lua @@ -1,4 +1,4 @@ --- NetHack themerms.lua $NHDT-Date: 1744445274 2025/04/12 00:07:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ +-- NetHack themerms.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.43 $ -- Copyright (c) 2020 by Pasi Kallinen -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/tower1.lua b/dat/tower1.lua index eae3016b3..2a7c98e23 100644 --- a/dat/tower1.lua +++ b/dat/tower1.lua @@ -1,4 +1,4 @@ --- NetHack tower tower1.lua $NHDT-Date: 1717178759 2024/05/31 18:05:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack tower tower1.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/tower2.lua b/dat/tower2.lua index 57b5d6003..958f8c104 100644 --- a/dat/tower2.lua +++ b/dat/tower2.lua @@ -1,4 +1,4 @@ --- NetHack tower tower2.lua $NHDT-Date: 1652196037 2022/05/10 15:20:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack tower tower2.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/tower3.lua b/dat/tower3.lua index fe1484db2..dc9623917 100644 --- a/dat/tower3.lua +++ b/dat/tower3.lua @@ -1,4 +1,4 @@ --- NetHack tower tower3.lua $NHDT-Date: 1652196038 2022/05/10 15:20:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack tower tower3.lua $NHDT-Date: 1781994889 2026/06/20 22:34:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/tribute b/dat/tribute index 5438d48be..097bdc3b5 100644 --- a/dat/tribute +++ b/dat/tribute @@ -1,4 +1,4 @@ -# NetHack 3.7 tribute $NHDT-Date: 1726809275 2024/09/20 05:14:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ +# NetHack 5.0 tribute $NHDT-Date: 1726809275 2024/09/20 05:14:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.118 $ # Copyright (c) 2017 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # A tribute introduced in NetHack 3.6.0 to: @@ -1263,7 +1263,7 @@ They are not necessarily very good at it. [Sourcery, by Terry Pratchett] %e passage # -# additional passage added for 3.7 +# additional passage added for 5.0 # # p. 164 (passage begins mid-sentence) %passage 11 @@ -2464,7 +2464,7 @@ Dibbler removed his cigar. [Moving Pictures, by Terry Pratchett] %e passage # -# New for 3.7 - these are worthy but 16 passages are already more than enough. +# New for 5.0 - these are worthy but 16 passages are already more than enough. #-# #-# p. 304 #-%passage 17 @@ -3201,7 +3201,7 @@ But, on the whole, there are worse places to be buried than inside a lion. [Small Gods, by Terry Pratchett] %e passage # -# 3 more passages added for 3.7 +# 3 more passages added for 5.0 # # p. 7 (Brother Nhumrod is in charge of a group of novices; he's thinking # about one of them, Brutha, the main character of the story) @@ -3463,7 +3463,7 @@ kingdom. [Lords and Ladies, by Terry Pratchett] %e passage # -# passage added for 3.7 +# passage added for 5.0 # # p. 60 (passage starts mid-paragraph; "paddlin'" is accurate but unclear; # "ooh-jar" is accurate for ouija after having been butchered by @@ -3962,7 +3962,7 @@ The Chair came down slowly, occasionally glancing fearfully up the stairs. [Soul Music, by Terry Pratchett] %e passage # -# 2 more passages added for 3.7 +# 2 more passages added for 5.0 # # p. 242 (passage starts and ends mid-paragraph; "the Old" rather than "the # Old " is accurate) @@ -4138,7 +4138,7 @@ followed by long periods of being dead." [Interesting Times, by Terry Pratchett] %e passage # -# 3 new passages for 3.7 +# 3 new passages for 5.0 # # p. 45 %passage 11 @@ -4467,7 +4467,7 @@ Come on. I want to try a leg of the elephant that bit me." [Maskerade, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # pp. 51-52 (Granny Weatherwax and Nanny Ogg are traveling to Ankh-Morpork # and Nanny feels that the weather is too chilly for flying; @@ -5044,7 +5044,7 @@ Death. OR THE FAME. OR BECAUSE THEY SHOULDN'T. [Hogfather, by Terry Pratchett] %e passage # -# 3 new passages added for 3.7 +# 3 new passages added for 5.0 # # pp. 2-3 (the door turns out to lead to a bathroom designed by Bergholt # Stuttly "Bloody Stupid" Johnson, an infamous architect and @@ -5373,7 +5373,7 @@ him and he's warm for the rest of his life.' See my point?" [Jingo, by Terry Pratchett] %e passage # -# 2 new passages added for 3.7 +# 2 new passages added for 5.0 # # p. 90 (second line beginning with "Sir." rather than "Sir," is accurate) %passage 13 @@ -5595,7 +5595,7 @@ of clothes, often with the same sort of insignia. [The Last Continent, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # pp. 113-114 (passage ends mid-paragraph) %passage 11 @@ -5787,7 +5787,7 @@ saw what happened to the others! /You/ got your fingers burned!." [Carpe Jugulum, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # p. 24 (ellipsis occurs at start of paragraph; Quite Reverend Oats has opened # /The Book of Om/ at random and is reading the passage found there) @@ -5987,7 +5987,7 @@ Been there, done that, bought the doublet... [The Fifth Elephant, by Terry Pratchett] %e passage # -# 3 new passages added for 3.7 +# 3 new passages added for 5.0 # # pp. 34-35 (a footnote about Cpl Nobbs lately dressing as a woman omitted) %passage 10 @@ -6173,7 +6173,7 @@ EYES... [The Truth, by Terry Pratchett] %e passage # -# 5 new passages added for 3.7 +# 5 new passages added for 5.0 # # p. 3 (two paragraphs in the middle skipped) %passage 9 @@ -6467,7 +6467,7 @@ there to make you think before you broke them. [Thief of Time, by Terry Pratchett] %e passage # -# 6 new passages added for 3.7 +# 6 new passages added for 5.0 # # p. 80 (passage ends mid-paragraph) %passage 9 @@ -6682,7 +6682,7 @@ betray 'em, quick as a wink. 'Cos that's villaining.' [The Last Hero, written by Terry Pratchett, illustrated by Paul Kidby] %e passage # -# 6 new passages added for 3.7 +# 6 new passages added for 5.0 # # p. 16 %passage 8 @@ -7013,7 +7013,7 @@ I'll promise to pretend that humans can think, too." [The Amazing Maurice and His Educated Rodents, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # p. 19 (passage begins mid-paragraph) %passage 11 @@ -7687,7 +7687,7 @@ girls of seven are magnetically attracted to the color pink. [Monstrous Regiment, by Terry Pratchett] %e passage # -# 4 new passages added for 3.7 +# 4 new passages added for 5.0 # # p. 114 (the sergeant known as "Threeparts" is a bit daft, but Polly does # eventually walk with Death--not die, just walk and talk with him) @@ -7894,7 +7894,7 @@ is 'me'?" [A Hat Full of Sky, by Terry Pratchett] %e passage # -# 2 new passages added for 3.7 +# 2 new passages added for 5.0 # # p. 124 (first speaker is Tiffany) %passage 12 diff --git a/dat/valley.lua b/dat/valley.lua index 96bceb997..56c339537 100644 --- a/dat/valley.lua +++ b/dat/valley.lua @@ -1,4 +1,4 @@ --- NetHack gehennom valley.lua $NHDT-Date: 1652196038 2022/05/10 15:20:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack gehennom valley.lua $NHDT-Date: 1781994890 2026/06/20 22:34:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/water.lua b/dat/water.lua index 760c83eb5..fc3678e7f 100644 --- a/dat/water.lua +++ b/dat/water.lua @@ -1,4 +1,4 @@ --- NetHack endgame water.lua $NHDT-Date: 1652196038 2022/05/10 15:20:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +-- NetHack endgame water.lua $NHDT-Date: 1781994890 2026/06/20 22:34:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/wizard1.lua b/dat/wizard1.lua index f1d4be198..612f67be8 100644 --- a/dat/wizard1.lua +++ b/dat/wizard1.lua @@ -1,4 +1,4 @@ --- NetHack yendor wizard1.lua $NHDT-Date: 1652196039 2022/05/10 15:20:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +-- NetHack yendor wizard1.lua $NHDT-Date: 1781994890 2026/06/20 22:34:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/wizard2.lua b/dat/wizard2.lua index 34f48005d..75ce9f92a 100644 --- a/dat/wizard2.lua +++ b/dat/wizard2.lua @@ -1,4 +1,4 @@ --- NetHack yendor wizard2.lua $NHDT-Date: 1652196039 2022/05/10 15:20:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +-- NetHack yendor wizard2.lua $NHDT-Date: 1781994890 2026/06/20 22:34:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/dat/wizard3.lua b/dat/wizard3.lua index 3166d799c..c302b1ac3 100644 --- a/dat/wizard3.lua +++ b/dat/wizard3.lua @@ -1,4 +1,4 @@ --- NetHack yendor wizard3.lua $NHDT-Date: 1652196040 2022/05/10 15:20:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ +-- NetHack yendor wizard3.lua $NHDT-Date: 1781994891 2026/06/20 22:34:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992 by M. Stephenson and Izchak Miller -- NetHack may be freely redistributed. See license for details. diff --git a/doc/.gitignore b/doc/.gitignore index 2cb6f5896..801e06728 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -10,6 +10,7 @@ Guidebook.dat Guidebook.aux Guidebook.dvi Guidebook.log +Guidebook.out Guidebook.pdf Guidebook.ps Guidebook.dated.* diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index cb9b023c2..1494ad7cf 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.614 $ $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ +.\" $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.652 $ $NHDT-Date: 1782274458 2026/06/23 23:14:18 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\"+-- @@ -56,11 +56,11 @@ .ds h0 NetHack Guidebook .ds h1 \" empty .ds h2 % -.ds vr NetHack 3.7.0 +.ds vr NetHack 5.0.0 .ds f0 \*(vr .ds f1 \" empty .\"DO NOT REMOVE NH_DATESUB .ds f2 Date(%B %-d, %Y) -.ds f2 April 16, 2026 +.ds f2 July 4, 2026 . .\" A note on some special characters: .\" \(lq = left double quote @@ -1034,9 +1034,16 @@ choices but will accept an item of armor and attempt to take it off.) .lp \(haT Teleport, if you have the ability. .lp v -Display version number. +Display a list of significant events in the current game, also shown by +\f(CR#chronicle\fP. +.lp "" +\(oq\f(CRv\fP\(cq used to display the game's version number. +Use \(oq\f(CRV\fP\(cq for that now. .lp V -Display the game history. +Display version number. +.lp "" +\(oq\f(CRV\fP\(cq used to display a summary of the game's history. +Still available via \f(CR#history\fP. .lp w Wield weapon. .sd @@ -1385,7 +1392,7 @@ If mouse support is enabled and the option is On, clicking on the hero (or steed when mounted) will execute this command. .lp "#history " -Show long version and game history. +Show a summary of the game's development. .lp #inventory Show your inventory. Default key is \(oqi\(cq. @@ -3671,22 +3678,34 @@ OPTIONS=!legacy,autopickup,pickup_types:$\(dq=/!?+ .ft .ed .lp HACKDIR +[not available on Unix] +.br Default location of files NetHack needs. On Windows HACKDIR defaults to the location of the NetHack.exe or NetHackw.exe file so setting HACKDIR to override that is not usually necessary or recommended. .lp LEVELDIR +[not available on Unix] +.br The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. .lp SAVEDIR +[not available on Unix] +.br The location where saved games are kept. Defaults to HACKDIR, must be writable. .lp BONESDIR +[not available on Unix] +.br The location that bones files are kept. Defaults to HACKDIR, must be writable. .lp LOCKDIR +[not available on Unix] +.br The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. .lp TROUBLEDIR +[not available on Unix] +.br The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. .\" @@ -3933,7 +3952,7 @@ and also .op autopickup_exception for ways to refine the behavior. .lp "" -Note: prior to version 3.7.0, the default for +Note: prior to version 5.0.0, the default for .op autopickup was \fIon\fP. .lp autoquiver @@ -4407,8 +4426,10 @@ is used for the role, then a random one will be automatically chosen. .lp "" On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. -The former can made to behave like the latter by specifying a generic name +The former can be made to behave like the latter by specifying a generic name such as ``player''. +The GENERICUSERS= setting in sysconf controls which +names are considered generic. Cannot be set with the \(oq\f(CRO\fP\(cq command. .lp "news " Read the NetHack news file, if present (default on). @@ -4803,6 +4824,12 @@ option is recommended so that there will be more room available for status information, unless you're using NetHack's \fIQt\fP interface or your terminal emulator window displays fewer than 25 lines. Persistent. +.lp "" +The +.op versinfo +option provides limited control over what information +.op showvers +displays. .lp "silent " Suppress terminal beeps (default on). Persistent. @@ -4943,6 +4970,10 @@ Play a tutorial level at the start of the game. Setting this option on or off in the config file will skip the query. .lp "verbose " Provide more commentary during the game (default on). Persistent. +.lp versinfo +Controls what the +.op showvers +option displays on the status lines. .lp weaponstatus Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). @@ -5670,7 +5701,7 @@ An entry that maps a sound file to a user-specified message pattern. Each SOUND entry is broken down into the following parts: .PS "sound index" .PL MESG -message window mapping (the only one supported in 3.7.0); +message window mapping (the only one supported in 5.0.0); .PL msgtype optional; message type to use, see \(lqConfiguring Message Types\(rq .PL pattern @@ -6132,13 +6163,13 @@ If your platform or terminal supports the display of UTF-8 character sequences, you can customize your game display by assigning Unicode codepoint values and \fIred-green-blue\fP colors to glyph representations. The customizations can be specified for use with a symset that -has a UTF8 handler within the symbols file such as the enhanced1 set, or +has a UTF8 handler within the symbols file such as the enhanced1 set, or individually within your nethack.rc file. .pg The format for defining a glyph representation is: .SD n .ft CR -OPTIONS=glyph:\fIglyphid\fP/\fIU+nnnn\fP/\fIR-G-B\fP +OPTIONS=glyph:\fIglyphname\fP/\fIU+nnnn\fP/\fIR-G-B\fP .ft .ED .pg @@ -6146,17 +6177,17 @@ The window port that is active needs to provide support for displaying UTF-8 character sequences and explicit red-green-blue colors in order for the glyph representation to be visible. For example, the following line in your configuration file will cause -the glyph representation for glyphid G_pool to use Unicode codepoint +the glyph representation for glyphname G_pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160: .SD n .ft CR OPTIONS=glyph:G_pool/U+224B/0-0-160 .ft .ED -The list of acceptable glyphid's can be produced by -\fBnethack \-\-dumpglyphids\fP. +The list of acceptable glyphnames can be produced by +\fBnethack \-\-dumpglyphnames\fP. Individual NetHack glyphs can be specified using the G_ prefix, -or you can use an S_ symbol for a glyphid and store the custom +or you can use an S_ symbol for a glyphname and store the custom representation for all NetHack glyphs that would map to that particular symbol. .pg @@ -6267,6 +6298,9 @@ escape command (!). The syntax is the same as WIZARDS. EXPLORERS\ =\ A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. .lp +GENERICUSERS\ =\ A list of user names that should prompt ``Who are you?'' +rather than become a character's name. +.lp MSGHANDLER\ =\ A path and filename of executable. Whenever a message-window message is shown, NetHack runs this program. The program will get the message as the only parameter. @@ -6326,7 +6360,7 @@ Allows the following placeholders: .PL \f(CR%%\fP literal \(oq\f(CR%\fP\(cq .PL \f(CR%v\fP -version (eg. \(lq\f(CR3.7.0\-0\fP\(rq) +version (eg. \(lq\f(CR5.0.0\-0\fP\(rq) .PL \f(CR%u\fP game UID .PL \f(CR%t\fP @@ -6358,7 +6392,7 @@ large unless it is actively maintained. . .lp CRASHREPORTURL\ =\ If set to -\f(CRhttps://www.nethack.org/links/cr-37BETA.html\fP +\f(CRhttps://www.nethack.org/links/cr-5.0.0.html\fP and support is compiled in, brings up a browser window pre-populated with the information needed to report a problem if the game panics or ends up in an internally inconsistent state, or if the #bugreport command is @@ -6532,7 +6566,7 @@ developed NetHack 3.1 for the Amiga. \fBCarl Schelin\fP, \fBStephen Spackman\fP, \fBSteve VanDevender\fP, and \fBPaul Winner\fP, ported NetHack 3.1 to the PC. .pg -\fBJon W{tte\fP and \fBHao-yang Wang\fP, with help from \fBRoss Brown\fP, +\fB\*(JW\fP and \fBHao-yang Wang\fP, with help from \fBRoss Brown\fP, \fBMike Engber\fP, \fBDavid Hairston\fP, \fBMichael Hamel\fP, \fBJonathan Handler\fP, \fBJohnny Lee\fP, \fBTim Lennan\fP, \fBRob Menke\fP, and \fBAndy Swanson\fP, developed NetHack 3.1 for the Macintosh, @@ -6699,7 +6733,7 @@ and had not gone through the process of debugging it as a suitable release, it was decided that the version numbers present on that code snapshot would be retired and never used in an official NetHack release. An announcement was posted on the NetHack Development Team's official -.UR nethack.org +.UR https://www.nethack.org website to that effect, stating that there would never be a 3.4.4, 3.5, or 3.5.0 official release version. @@ -6777,6 +6811,73 @@ some bug fixes. NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. .pg +Development work for the major release to follow NetHack 3.6 began in 2015 +around the same time as NetHack 3.6.0 was being released. That development +work continued in parallel to each of the NetHack 3.6 releases from 2015 +through 2023, and continued until the end of April 2026. For the first time, +that development was shared publicly on GitHub and SourceForge as it occurred. +It was done under the label NetHack-3.7 work-in-progress (WIP), although the +version number for the next release had not yet been solidified. +.pg +Exposure of the development to the public brought many good things, and some +challenges. People were able to observe and criticize changes and new features +almost immediately, and they often did. The GitHub pull request system made +it straightforward for people to contribute directly to development. +Contributions resolved many, many bugs in the game and we thank all the +contributors. +.pg +In early 2026, with the game development getting stable enough to consider +initiating an official release, the devteam reviewed the nature and number of +changes in the game. It was clear that there was sufficient depth and +breadth to warrant a major release and version 5.0 was decided on. +That's a new major release over 3.x, without opening up any ambiguity +or confusion with existing variants that there might have been had it +been released as version 4.0. +.pg +NetHack 5.0.0 was released on May 2, 2026. +.pg +The source code for NetHack 5.0.0 was modified and modernized to be +compliant with the C99 standard. The 5.0.0 release contained over 3100 fixes, +changes, and updated features. +.pg +NetHack 5.0 was the first version to replace the lex and yacc level +and dungeon compilers of past versions, with a new Lua interpreter-based +approach to provide those elements. Lua is also used for the quest texts +in NetHack 5.0.0. The entire development team acknowledges the work +done by \fBPasi Kallinen\fP to make that happen. +.pg +At the time of the NetHack 5.0 release, the core development team, +active and erstwhile, included \fBWarwick Allison\fP, \fBMichael Allison\fP, +\fBKen Arromdee\fP, \fBDavid Cohrs\fP, \fBJessie Collet\fP, \fBBart House\fP, +\fBKevin Hugo\fP, \fBPasi Kallinen\fP, \fBKen Lorber\fP, \fBDean Luick\fP, +\fBPat Rankin\fP, \fBDerek S. Ray\fP, \fBAlex Smith\fP, \fBPatric Mueller\fP, +\fBMike Stephenson\fP, \fBJanet Walz\fP, \fBPaul Winner\fP. +.pg +\fBKen Lorber\fP, \fBPat Rankin\fP, \fBPatrick Mueller\fP and +\fBMichael Allison\fP helped ensure that NetHack 5.0 would run +on macOS. +.pg +\fBIngo Paschke\fP somehow managed to revive a NetHack 5.0 port for the Amiga, +using a cross-compiler on a modern platform to do so. His work was shared so +others can straightforwardly produce NetHack 5.0 for the Amiga thanks to his +efforts. +.pg +\fBRay Chason\fP contributed the majority of maintenance work for the +NetHack 5.0 MS-DOS port, including porting the curses interface to it. +\fBMichael Allison\fP ensured that NetHack 5.0 core changes continued to +work with the msdos port and keep it alive. Cross-compiling the MS-DOS +port has helped make that possible and mostly painless. +.pg +People that contributed to the Windows port of NetHack 5.0 since the +development of NetHack 5.0 began over eleven years ago, included +\fBMichael Allison\fP, \fBDavid Cohrs\fP, \fBBart House\fP, +\fBPasi Kallinen\fP, \fBAlex Kompel\fP, \fBDion Nicolaas\fP, +\fBDerek S. Ray\fP and \fBYitzhak Sapir\fP. +.pg +With sadness, the devteam would like to acknowledge and remember the past +contributions from the late \fBRon Van Iwaarden\fP, who was the sole maintainer +of NetHack for OS/2 for several past NetHack releases. Ron will be missed. +.pg The official NetHack web site is maintained by \fBKen Lorber\fP at .UR https://www.nethack.org/ . @@ -6811,48 +6912,49 @@ miscreants in this, the list of Dungeoneers: center; c2 c2 c. .\"TABLE_START -Adam Aronow J. Ali Harlow Mikko Juola -Alex Kompel Janet Walz Nathan Eady -Alex Smith Janne Salmijarvi Norm Meluch -Andreas Dorn Jean-Christophe Collet Olaf Seibert -Andy Church Jeff Bailey Pasi Kallinen -Andy Swanson Jochen Erwied Pat Rankin -Andy Thomson John Kallen Patric Mueller -Ari Huttunen John Rupley Paul Winner -Bart House John S. Bien Pierre Martineau -Benson I. Margulies Johnny Lee Ralf Brown -Bill Dyer Jon W{tte Ray Chason -Boudewijn Waijers Jonathan Handler Richard Addison -Bruce Cox Joshua Delahunty Richard Beigel -Bruce Holloway Karl Garrison Richard P. Hughey -Bruce Mewborne Keizo Yamamoto Rob Menke -Carl Schelin Keith Simpson Robin Bandy -Chris Russo Ken Arnold Robin Johnson -David Cohrs Ken Arromdee Roderick Schertler -David Damerell Ken Lorber Roland McGrath -David Gentzel Ken Washikita Ron Van Iwaarden -David Hairston Kevin Darcy Ronnen Miller -Dean Luick Kevin Hugo Ross Brown -Del Lamb Kevin Sitze Sascha Wostmann -Derek S. Ray Kevin Smolkowski Scott Bigham -Deron Meranda Kevin Sweet Scott R. Turner -Dion Nicolaas Lars Huttar Sean Hunt -Dylan O'Donnell Leon Arnott Stephen Spackman -Eric Backus M. Drew Streib Stefan Thielscher -Eric Hendrickson Malcolm Ryan Stephen White -Eric R. Smith Mark Gooderum Steve Creps -Eric S. Raymond Mark Modrall Steve Linhart -Erik Andersen Marvin Bressler Steve VanDevender -Fredrik Ljungdahl Matthew Day Teemu Suikki -Frederick Roeber Merlyn LeRoy Tim Lennan -Gil Neiger Michael Allison Timo Hakulinen -Greg Laskin Michael Feir Tom Almy -Greg Olson Michael Hamel Tom West -Gregg Wonderly Michael Sokolov Warren Cheung -Hao-yang Wang Mike Engber Warwick Allison -Helge Hafting Mike Gallop Yitzhak Sapir -Irina Rempt-Drijfhout Mike Passaretti -Izchak Miller Mike Stephenson +Adam Aronow Irina Rempt-Drijfhout Mike Gallop +Alex Kompel Izchak Miller Mike Passaretti +Alex Smith J. Ali Harlow Mike Stephenson +Andreas Dorn Janet Walz Mikko Juola +Andy Church Janne Salmijarvi Nathan Eady +Andy Swanson Jean-Christophe Collet Norm Meluch +Andy Thomson Jeff Bailey Olaf Seibert +Ari Huttunen Jochen Erwied Pasi Kallinen +Bart House John Kallen Pat Rankin +Benson I. Margulies John Rupley Patric Mueller +Bill Dyer John S. Bien Paul Winner +Boudewijn Waijers Johnny Lee Pierre Martineau +Bruce Cox \*(JW Ralf Brown +Bruce Holloway Jonathan Handler Ray Chason +Bruce Mewborne Joshua Delahunty Richard Addison +Cameron Root Karl Garrison Richard Beigel +Carl Schelin Keizo Yamamoto Richard P. Hughey +Chris Russo Keith Simpson Rob Menke +David Cohrs Ken Arnold Robin Bandy +David Damerell Ken Arromdee Robin Johnson +David Gentzel Ken Lorber Roderick Schertler +David Hairston Ken Washikita Roland McGrath +Dean Luick Kestrel Gregorich-Trevor Ron Van Iwaarden +Del Lamb Kevin Darcy Ronnen Miller +Derek S. Ray Kevin Hugo Ross Brown +Deron Meranda Kevin Sitze Sascha Wostmann +Dion Nicolaas Kevin Smolkowski Scott Bigham +Dylan O'Donnell Kevin Sweet Scott R. Turner +Eric Backus Lars Huttar Sean Hunt +Eric Hendrickson Leon Arnott Stephen Spackman +Eric R. Smith M. Drew Streib Stefan Thielscher +Eric S. Raymond Malcolm Ryan Stephen White +Erik Andersen Mark Gooderum Steve Creps +Fredrik Ljungdahl Mark Modrall Steve Linhart +Frederick Roeber Marvin Bressler Steve VanDevender +G. Branden Robinson Matthew Day Teemu Suikki +Gil Neiger Merlyn LeRoy Tim Lennan +Greg Laskin Michael Allison Timo Hakulinen +Greg Olson Michael Feir Tom Almy +Gregg Wonderly Michael Hamel Tom West +Hao-yang Wang Michael Meyer Warren Cheung +Helge Hafting Michael Sokolov Warwick Allison +Ingo Paschke Mike Engber Yitzhak Sapir .\"TABLE_END Do not delete this line. .TE .BR 1 diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 54807f77d..804df47ec 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1,4 +1,4 @@ -% NetHack 3.7 Guidebook.tex $NHDT-Date: 1770881338 2026/02/11 23:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.596 $ */ +% NetHack 5.0 Guidebook.tex $NHDT-Date: 1782274458 2026/06/23 23:14:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.630 $ */ \documentclass[titlepage]{article} \usepackage[hidelinks]{hyperref} \usepackage{longtable} @@ -23,9 +23,9 @@ %.au \author{Original version - Eric S. Raymond\\ -(Edited and expanded for 3.7.0 by Mike Stephenson and others)} +(Edited and expanded for 5.0.0 by Mike Stephenson and others)} %DO NOT REMOVE NH_DATESUB \date{Date(%B %-d, %Y)} -\date{April 16, 2026} +\date{July 4, 2026} \maketitle @@ -97,7 +97,8 @@ will vary with your background and training: \item[Archeologists] understand dungeons pretty well; this enables them to move quickly and sneak up on the local nasties. They start equipped -with the tools for a proper scientific expedition. +with the tools for a proper scientific expedition, and are able to read +ancient languages. %.pg % \item[Barbarians] @@ -1066,10 +1067,20 @@ choices but will accept an item of armor and attempt to take it off.) Teleport, if you have the ability. %.lp \item[v] -Display version number. +Display a list of significant events in the current game, also shown by +\texttt{\#chronicle}. +\\ +%.lp "" +`\texttt{v}' used to display the game's version number. +Use `\texttt{V}' for that now. + %.lp \item[V] -Display the game history. +Display version number. +\\ +%.lp "" +`\texttt{V}' used to display a summary of the game's history. +Still available via \texttt{\#history}. %.lp \item[w] Wield weapon.\\ @@ -1429,7 +1440,7 @@ option is On, clicking on the hero (or steed when mounted) will execute this command. %.lp \item[\#history] -Show long version and game history. +Show a summary of the game's development. %.lp \item[\#inventory] Show your inventory. Default key is `\texttt{i}'. @@ -3969,27 +3980,33 @@ Example: %.lp \item[HACKDIR] +{[}Not available on Unix]\\ Default location of files \textit{NetHack} needs. On Windows HACKDIR defaults to the location of the \textit{NetHack.exe} or \textit{NetHackw.exe} file so setting HACKDIR to override that is not usually necessary or recommended. %.lp \item[LEVELDIR] +{[}Not available on Unix]\\ The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. %.lp \item[SAVEDIR] +{[}Not available on Unix]\\ The location where saved games are kept. Defaults to HACKDIR, must be writable. %.lp \item[BONESDIR] +{[}Not available on Unix]\\ The location that bones files are kept. Defaults to HACKDIR, must be writable. %.lp \item[LOCKDIR] +{[}Not available on Unix]\\ The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. %.lp \item[TROUBLEDIR] +{[}Not available on Unix]\\ The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. % @@ -4263,7 +4280,7 @@ See ``\textit{pickup\textunderscore types}'' and also ``\textit{autopickup\textunderscore exception}'' for ways to refine the behavior. \\ %.lp "" -Note: prior to version 3.7.0, the default for \textit{autopickup} was \textit{on}. +Note: prior to version 5.0.0, the default for \textit{autopickup} was \textit{on}. %.lp \item[autoquiver] This option controls what happens when you attempt the `\texttt{f}' (fire) @@ -4806,7 +4823,8 @@ automatically chosen. On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can made to behave like the latter by specifying a generic name -such as ``player''. +such as ``player''. The GENERICUSERS= setting in sysconf controls which +names are considered generic. Cannot be set with the `\texttt{O}' command. %.lp \item[news] @@ -5069,6 +5087,16 @@ name (on single-user systems) or it might be disabled entirely. Requesting it when not allowed or not possible results in explore mode instead. Default is normal play. %.lp +\item[price\textunderscore quotes] +Whenever the game mentions the name of an object you haven't identified yet, +it also mentions the range of buy and sell prices you have seen for that +item (to help narrow down what it could be). +The price shown is the unit price for one item (even when you are looking at +a stack of multiple items). +Many players may want to turn this on while identifying objects, and then +turn it back off again for general play. +Default is off. +%.lp \item[pushweapon] Using the `\texttt{w}' (wield) command when already wielding something pushes the old item into your alternate weapon slot (default off). @@ -5096,9 +5124,20 @@ for a description of how to use negation to exclude choices. \\ If \texttt{race} is not specified, there is no default value; player will be prompted unless role forces a choice for race. -unless role forces a choice for race. Cannot be set with the `\texttt{O}' command. Persistent. %.lp +\item[reroll] +Allows rerolling your character's starting inventory and attributes (default +false). Persistent. +%.lp "" +\\ +Note that rerolling your character is not a recommended way to play if aiming +merely to win (a lucky start has a much smaller influence on whether or not +you win the game than your actions later in the game). This option exists +partly as an acknowledgement that some players will insist on doing so anyway, +and partly because rerolling may be necessary for certain types of challenge +games. +%.lp \item[rest\textunderscore on\textunderscore space] Make the space bar a synonym for the `\texttt{.}' (\#wait) command (default off). Persistent. @@ -5212,6 +5251,11 @@ option is recommended so that there will be more room available for status information, unless you're using NetHack's \textit{Qt} interface or your terminal emulator window displays fewer than 25 lines. Persistent. +\\ +%.lp "" +The \textit{versinfo} +option provides limited control over what information +\textit{showvers} displays. %.lp \item[silent] Suppress terminal beeps (default on). Persistent. @@ -5376,6 +5420,9 @@ Setting this option on or off in the config file will skip the query. \item[verbose] Provide more commentary during the game (default on). Persistent. %.lp +\item[versinfo] +Controls what the \textit{showvers} option displays on the status lines. +%.lp \item[weaponstatus] Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). @@ -5752,7 +5799,7 @@ computer unless you manually click submit on a form. %.ei \end{description} These options are used only to save you some typing on the crash -report and \#bugreport forms. +report and \#bugreport forms. %.si \begin{description} %.lp @@ -6250,7 +6297,7 @@ Each SOUND entry is broken down into the following parts: %.sd %.si -\texttt{MESG} --- message window mapping (the only one supported in 3.7.0);\\ +\texttt{MESG} --- message window mapping (the only one supported in 5.0.0);\\ \texttt{msgtype} --- optional; message type to use, see ``Configuring User Sounds''\\ \texttt{pattern} --- the pattern to match;\\ \texttt{sound file} --- the sound file to play;\\ @@ -6715,7 +6762,7 @@ individually within your own nethack.rc file. The format for defining a glyph representation is:\\ \begin{verbatim} -OPTIONS=glyph:glyphid/U+nnnn/R-G-B +OPTIONS=glyph:glyphname/U+nnnn/R-G-B \end{verbatim} The window port that is active needs to provide support for displaying UTF-8 @@ -6723,18 +6770,18 @@ character sequences and explicit 24-bit red-green-blue colors in order for the g representation to be visible as specified. For example, the following line in your configuration file will cause -the glyph representation for glyphid G\textunderscore pool to use Unicode codepoint +the glyph representation for glyphname G\textunderscore pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160:\\ \begin{verbatim} OPTIONS=glyph:G_pool/U+224B/0-0-160 \end{verbatim} -The list of acceptable glyphid's can be produced by +The list of acceptable glyphnames can be produced by \begin{verbatim} - nethack --glyphids + nethack --dumpglyphnames \end{verbatim} Individual NetHack glyphs can be specified using the G\textunderscore prefix, -or you can use an S\textunderscore symbol for a glyphid and store the custom +or you can use an S\textunderscore symbol for a glyphname and store the custom representation for all NetHack glyphs that would map to that particular symbol. @@ -6869,9 +6916,13 @@ The syntax is the same as WIZARDS. A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. %.lp +\item[GENERICUSERS] +A list of user names that should prompt ``Who are you?'' +rather than become a character's name. +%.lp \item[MSGHANDLER] A path and filename of executable. Whenever a message-window -message is shown, NetHack runs this program. The program will get +message is shown, \textit{NetHack} runs this program. The program will get the message as the only parameter. %.lp \item[MAXPLAYERS] @@ -6925,12 +6976,12 @@ random statue names (default is 10). %.lp \item[ACCESSIBILITY] 0 or 1 to disable or enable, respectively, the ability for players -to set S\textunderscore pet\textunderscore override and S\textunderscore hero\textunderscore override +to set S\textunderscore pet\textunderscore override and S\textunderscore hero\textunderscore override symbols in their configuration file. %.lp \item[PORTABLE\textunderscore DEVICE\textunderscore PATHS] 0 or 1 Windows OS only, the game will look for all of its external -files, and write to all of its output files in one place +files, and write to all of its output files in one place rather than at the standard locations. %.lp \item[DUMPLOGFILE] @@ -6940,7 +6991,7 @@ Only available if your game is compiled with DUMPLOG. Allows the following placeholders: % FIXME: this should be changed to a nested list or else be forcibly indented \texttt{\%\%} --- literal `\texttt{\%}'\\ -\texttt{\%v} --- version (eg. ``\texttt{3.7.0-0}'')\\ +\texttt{\%v} --- version (eg. ``\texttt{5.0.0-0}'')\\ \texttt{\%u} --- game UID\\ \texttt{\%t} --- game start time, UNIX timestamp format\\ \texttt{\%T} --- current time, UNIX timestamp format\\ @@ -6964,7 +7015,7 @@ large unless it is actively maintained. %.lp \item[CRASHREPORTURL] If set to -\url{https://www.nethack.org/links/cr-37BETA.html} +\url{https://www.nethack.org/links/cr-5.0.0.html} and support is compiled in, brings up a browser window populated with the information needed to report a problem if the game panics or ends up in an internally inconsistent state, or if the \#bugreport command is @@ -7130,8 +7181,8 @@ subsequent revisions of 3.0. \medskip \noindent \textit{Olaf Seibert} ported \textit{NetHack} 2.3 and 3.0 to the Amiga. {\it Norm Meluch}, \textit{Stephen Spackman} and \textit{Pierre Martineau} designed -overlay code for \textit{PC NetHack} 3.0. \textit{Johnny Lee} ported {\it -NetHack} 3.0 to the Macintosh. Along with various other Dungeoneers, they +overlay code for \textit{PC NetHack} 3.0. \textit{Johnny Lee} ported +\textit{NetHack} 3.0 to the Macintosh. Along with various other Dungeoneers, they continued to enhance the PC, Macintosh, and Amiga ports through the later revisions of 3.0. @@ -7397,7 +7448,7 @@ official release version. %.pg \medskip -In January 2015, preparation began for the release of NetHack 3.6. +In January 2015, preparation began for the release of \textit{NetHack} 3.6. %.pg \medskip @@ -7409,7 +7460,7 @@ At the beginning of development for what would eventually get released as \textit{Mike Stephenson}, \textit{Janet Walz}, and \textit{Paul Winner}. In early 2015, ahead of the release of 3.6.0, new members \textit{Sean Hunt}, \textit{Pasi Kallinen}, and \textit{Derek S. Ray} -joined the \textit{NetHack} development team. +joined the \textit{NetHack Development Team}. %.pg \medskip @@ -7444,7 +7495,7 @@ maintained the port of \textit{NetHack} 3.6 for Microsoft Windows. %.pg \medskip -\textit{Pat Rankin} attempted to keep the VMS port running for NetHack 3.6, +\textit{Pat Rankin} attempted to keep the VMS port running for \textit{NetHack} 3.6, hindered by limited access. \textit{Kevin Smolkowski} has updated and tested it for the most recent version of OpenVMS (V8.4 as of this writing) on Alpha and Integrity (aka Itanium aka IA64) but not VAX. @@ -7457,7 +7508,7 @@ necessary updates to the community at large. %.pg \medskip In late April 2018, several hundred bug fixes for 3.6.0 and some new features -were assembled and released as NetHack 3.6.1. +were assembled and released as \textit{NetHack} 3.6.1. The \textit{NetHack Development Team} at the time of release of 3.6.1 consisted of \textit{Warwick Allison}, \textit{Michael Allison}, \textit{Ken Arromdee}, @@ -7479,29 +7530,121 @@ for decades, joined the \textit{NetHack Development Team} in late May 2019. %.pg \medskip -NetHack 3.6.3 was released on December 5, 2019 containing over 190 bug -fixes to NetHack 3.6.2. +\textit{NetHack} 3.6.3 was released on December 5, 2019 containing over 190 bug +fixes to \textit{NetHack} 3.6.2. %.pg \medskip -NetHack 3.6.4 was released on December 18, 2019 containing a security fix and +\textit{NetHack} 3.6.4 was released on December 18, 2019 containing a security fix and a few bug fixes. %.pg \medskip -NetHack 3.6.5 was released on January 27, 2020 containing some security fixes +\textit{NetHack} 3.6.5 was released on January 27, 2020 containing some security fixes and a small number of bug fixes. %.pg \medskip -NetHack 3.6.6 was released on March 8, 2020 containing a security fix and +\textit{NetHack} 3.6.6 was released on March 8, 2020 containing a security fix and some bug fixes. %.pg \medskip -NetHack 3.6.7 was released on February 16, 2023 containing a security fix and +\textit{NetHack} 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. +%.pg +\medskip +Development work for the major release to follow \textit{NetHack} 3.6 began in 2015 +around the same time as \textit{NetHack} 3.6.0 was being released. That development +work continued in parallel to each of the \textit{NetHack} 3.6 releases from 2015 +through 2023, and continued until the end of April 2026. For the first time, +that development was shared publicly on GitHub and SourceForge as it occurred. +It was done under the label NetHack-3.7 work-in-progress (WIP), although the +version number for the next release had not yet been solidified. + +%.pg +\medskip +Exposure of the development to the public brought many good things, and some +challenges. People were able to observe and criticize changes and new features +almost immediately, and they often did. The GitHub pull request system made +it straightforward for people to contribute directly to development. +Contributions resolved many, many bugs in the game and we thank all the +contributors. + +%.pg +\medskip +In early 2026, with the game development getting stable enough to consider +initiating an official release, the devteam reviewed the nature and number of +changes in the game. It was clear that there was sufficient depth and +breadth to warrant a major release and version 5.0 was decided on. +That's a new major release over 3.x, without opening up any ambiguity +or confusion with existing variants that there might have been had it +been released as version 4.0. + +%.pg +\medskip +\textit{NetHack} 5.0.0 was released on May 2, 2026. + +%.pg +\medskip +The source code for \textit{NetHack} 5.0.0 was modified and modernized to be +compliant with the C99 standard. The 5.0.0 release contained over 3100 fixes, +changes, and updated features. + +%.pg +\medskip +\textit{NetHack} 5.0 was the first version to replace the lex and yacc level +and dungeon compilers of past versions, with a new Lua interpreter-based +approach to provide those elements. Lua is also used for the quest texts +in \textit{NetHack} 5.0.0. The entire development team acknowledges the work +done by \textit{Pasi Kallinen} to make that happen. + +%.pg +\medskip +At the time of the \textit{NetHack} 5.0 release, the core +\textit{NetHack Development Team}, +active and erstwhile, included \textit{Warwick Allison}, \textit{Michael Allison}, +\textit{Ken Arromdee}, \textit{David Cohrs}, \textit{Jessie Collet}, \textit{Bart House}, +\textit{Kevin Hugo}, \textit{Pasi Kallinen}, \textit{Ken Lorber}, \textit{Dean Luick}, +\textit{Pat Rankin}, \textit{Derek S. Ray}, \textit{Alex Smith}, \textit{Patric Mueller}, +\textit{Mike Stephenson}, \textit{Janet Walz}, \textit{Paul Winner}. + +%.pg +\medskip +\textit{Ken Lorber}, \textit{Pat Rankin}, \textit{Patrick Mueller} and +\textit{Michael Allison} helped ensure that \textit{NetHack} 5.0 would run +on macOS. + +%.pg +\medskip +\textit{Ingo Paschke} somehow managed to revive a \textit{NetHack} 5.0 port for the Amiga, +using a cross-compiler on a modern platform to do so. His work was shared so +others can straightforwardly produce \textit{NetHack} 5.0 for the Amiga thanks to his +efforts. + +%.pg +\medskip +\textit{Ray Chason} contributed the majority of maintenance work for the +\textit{NetHack} 5.0 MS-DOS port, including porting the curses interface to it. +\textit{Michael Allison} ensured that \textit{NetHack} 5.0 core changes continued to +work with the msdos port and keep it alive. Cross-compiling the MS-DOS +port has helped make that possible and mostly painless. + +%.pg +\medskip +People that contributed to the Windows port of \textit{NetHack} 5.0 since the +development of \textit{NetHack} 5.0 began over eleven years ago, included +\textit{Michael Allison}, \textit{David Cohrs}, \textit{Bart House}, +\textit{Pasi Kallinen}, \textit{Alex Kompel}, \textit{Dion Nicolaas}, +\textit{Derek S. Ray} and \textit{Yitzhak Sapir}. + +%.pg +\medskip +With sadness, the devteam would like to acknowledge and remember the past +contributions from the late \textit{Ron Van Iwaarden}, who was the sole maintainer +of \textit{NetHack} for OS/2 for several past \textit{NetHack} releases. Ron will be missed. + %.pg \medskip \noindent The official \textit{NetHack} web site is maintained by \textit{Ken Lorber} at @@ -7513,7 +7656,7 @@ some bug fixes. \subsection*{Special Thanks} \noindent On behalf of the \textit{NetHack} community, thank you very much once again to \textit{M. Drew Streib} and \textit{Pasi Kallinen} for providing a -public NetHack server at nethack.alt.org. Thanks to \textit{Keith Simpson} +public \textit{NetHack} server at nethack.alt.org. Thanks to \textit{Keith Simpson} and \textit{Andy Thomson} for hardfought.org. Thanks to all those unnamed dungeoneers who invest their time and effort into annual \textit{NetHack} tournaments such as \textit{Junethack}, @@ -7533,48 +7676,49 @@ of these miscreants in this, the list of Dungeoneers: \begin{center} \begin{tabular}{llll} %TABLE_START -Adam Aronow & J. Ali Harlow & Mikko Juola\\ -Alex Kompel & Janet Walz & Nathan Eady\\ -Alex Smith & Janne Salmij\"{a}rvi & Norm Meluch\\ -Andreas Dorn & Jean-Christophe Collet & Olaf Seibert\\ -Andy Church & Jeff Bailey & Pasi Kallinen\\ -Andy Swanson & Jochen Erwied & Pat Rankin\\ -Andy Thomson & John Kallen & Patric Mueller\\ -Ari Huttunen & John Rupley & Paul Winner\\ -Bart House & John S. Bien & Pierre Martineau\\ -Benson I. Margulies & Johnny Lee & Ralf Brown\\ -Bill Dyer & Jon W\textbraceleft tte & Ray Chason\\ -Boudewijn Waijers & Jonathan Handler & Richard Addison\\ -Bruce Cox & Joshua Delahunty & Richard Beigel\\ -Bruce Holloway & Karl Garrison & Richard P. Hughey\\ -Bruce Mewborne & Keizo Yamamoto & Rob Menke\\ -Carl Schelin & Keith Simpson & Robin Bandy\\ -Chris Russo & Ken Arnold & Robin Johnson\\ -David Cohrs & Ken Arromdee & Roderick Schertler\\ -David Damerell & Ken Lorber & Roland McGrath\\ -David Gentzel & Ken Washikita & Ron Van Iwaarden\\ -David Hairston & Kevin Darcy & Ronnen Miller\\ -Dean Luick & Kevin Hugo & Ross Brown\\ -Del Lamb & Kevin Sitze & Sascha Wostmann\\ -Derek S. Ray & Kevin Smolkowski & Scott Bigham\\ -Deron Meranda & Kevin Sweet & Scott R. Turner\\ -Dion Nicolaas & Lars Huttar & Sean Hunt\\ -Dylan O'Donnell & Leon Arnott & Stephen Spackman\\ -Eric Backus & M. Drew Streib & Stefan Thielscher\\ -Eric Hendrickson & Malcolm Ryan & Stephen White\\ -Eric R. Smith & Mark Gooderum & Steve Creps\\ -Eric S. Raymond & Mark Modrall & Steve Linhart\\ -Erik Andersen & Marvin Bressler & Steve VanDevender\\ -Fredrik Ljungdahl & Matthew Day & Teemu Suikki\\ -Frederick Roeber & Merlyn LeRoy & Tim Lennan\\ -Gil Neiger & Michael Allison & Timo Hakulinen\\ -Greg Laskin & Michael Feir & Tom Almy\\ -Greg Olson & Michael Hamel & Tom West\\ -Gregg Wonderly & Michael Sokolov & Warren Cheung\\ -Hao-yang Wang & Mike Engber & Warwick Allison\\ -Helge Hafting & Mike Gallop & Yitzhak Sapir\\ -Irina Rempt-Drijfhout & Mike Passaretti\\ -Izchak Miller & Mike Stephenson +Adam Aronow & Irina Rempt-Drijfhout & Mike Gallop\\ +Alex Kompel & Izchak Miller & Mike Passaretti\\ +Alex Smith & J. Ali Harlow & Mike Stephenson\\ +Andreas Dorn & Janet Walz & Mikko Juola\\ +Andy Church & Janne Salmij\"{a}rvi & Nathan Eady\\ +Andy Swanson & Jean-Christophe Collet & Norm Meluch\\ +Andy Thomson & Jeff Bailey & Olaf Seibert\\ +Ari Huttunen & Jochen Erwied & Pasi Kallinen\\ +Bart House & John Kallen & Pat Rankin\\ +Benson I. Margulies & John Rupley & Patric Mueller\\ +Bill Dyer & John S. Bien & Paul Winner\\ +Boudewijn Waijers & Johnny Lee & Pierre Martineau\\ +Bruce Cox & Jon W\{tte & Ralf Brown\\ +Bruce Holloway & Jonathan Handler & Ray Chason\\ +Bruce Mewborne & Joshua Delahunty & Richard Addison\\ +Cameron Root & Karl Garrison & Richard Beigel\\ +Carl Schelin & Keizo Yamamoto & Richard P. Hughey\\ +Chris Russo & Keith Simpson & Rob Menke\\ +David Cohrs & Ken Arnold & Robin Bandy\\ +David Damerell & Ken Arromdee & Robin Johnson\\ +David Gentzel & Ken Lorber & Roderick Schertler\\ +David Hairston & Ken Washikita & Roland McGrath\\ +Dean Luick & Kestrel Gregorich-Trevor & Ron Van Iwaarden\\ +Del Lamb & Kevin Darcy & Ronnen Miller\\ +Derek S. Ray & Kevin Hugo & Ross Brown\\ +Deron Meranda & Kevin Sitze & Sascha Wostmann\\ +Dion Nicolaas & Kevin Smolkowski & Scott Bigham\\ +Dylan O'Donnell & Kevin Sweet & Scott R. Turner\\ +Eric Backus & Lars Huttar & Sean Hunt\\ +Eric Hendrickson & Leon Arnott & Stephen Spackman\\ +Eric R. Smith & M. Drew Streib & Stefan Thielscher\\ +Eric S. Raymond & Malcolm Ryan & Stephen White\\ +Erik Andersen & Mark Gooderum & Steve Creps\\ +Fredrik Ljungdahl & Mark Modrall & Steve Linhart\\ +Frederick Roeber & Marvin Bressler & Steve VanDevender\\ +G. Branden Robinson & Matthew Day & Teemu Suikki\\ +Gil Neiger & Merlyn LeRoy & Tim Lennan\\ +Greg Laskin & Michael Allison & Timo Hakulinen\\ +Greg Olson & Michael Feir & Tom Almy\\ +Gregg Wonderly & Michael Hamel & Tom West\\ +Hao-yang Wang & Michael Meyer & Warren Cheung\\ +Helge Hafting & Michael Sokolov & Warwick Allison\\ +Ingo Paschke & Mike Engber & Yitzhak Sapir %TABLE_END Do not delete this line. \end{tabular} \end{center} diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 885dafdd5..618fdac8f 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -13,9 +13,9 @@ Original version - Eric S. Raymond - (Edited and expanded for NetHack 3.7.0 by Mike Stephenson and others) + (Edited and expanded for NetHack 5.0.0 by Mike Stephenson and others) - April 16, 2026 + July 4, 2026 @@ -126,7 +126,7 @@ employ to great advantage. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -192,7 +192,7 @@ NetHack continues this fine tradition. Unlike text adventure games - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -258,7 +258,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -324,7 +324,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -390,7 +390,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -456,7 +456,7 @@ The number of turns elapsed so far, displayed if you have the - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -522,7 +522,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -588,7 +588,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -654,7 +654,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -720,7 +720,7 @@ instead. Only these one-step movement commands cause you to - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -786,7 +786,7 @@ ing . ^ is used as shorthand elsewhere in the - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -852,7 +852,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -918,7 +918,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -984,7 +984,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1050,7 +1050,7 @@ at an adjacent "remembered, unseen monster" marker. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1102,21 +1102,21 @@ ^T Teleport, if you have the ability. - v Display version number. + v Display a list of significant events in the current game, also + shown by #chronicle. - V Display the game history. + `v' used to display the game's version number. Use `V' for that + now. - w Wield weapon. + V Display version number. - w- - wield nothing, use your bare (or gloved) hands. - - Some characters can wield two weapons at once; use the `X' com- - mand (or the "#twoweapon" extended command) to do so. + `V' used to display a summary of the game's history. Still + available via #history. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1126,40 +1126,47 @@ + w Wield weapon. + + w- - wield nothing, use your bare (or gloved) hands. + + Some characters can wield two weapons at once; use the `X' com- + mand (or the "#twoweapon" extended command) to do so. + W Wear armor. - This command may also be used to put on an accessory (ring, - amulet, or blindfold). The prompt for which inventory item to + This command may also be used to put on an accessory (ring, + amulet, or blindfold). The prompt for which inventory item to use will only list armor, but choosing an unlisted accessory will - attempt to put it on. (See the `P' command above. It lists - accessories as the inventory choices but will accept an item of + attempt to put it on. (See the `P' command above. It lists + accessories as the inventory choices but will accept an item of armor and attempt to wear it.) - x Exchange your wielded weapon with the item in your alternate + x Exchange your wielded weapon with the item in your alternate weapon slot. The latter is used as your secondary weapon when engaging in two- - weapon combat. Note that if one of these slots is empty, the + weapon combat. Note that if one of these slots is empty, the exchange still takes place. - X Toggle two-weapon combat, if your character can do it. Also + X Toggle two-weapon combat, if your character can do it. Also available via the "#twoweapon" extended command. - (In versions prior to 3.6 this keystroke ran the command to + (In versions prior to 3.6 this keystroke ran the command to switch from normal play to "explore mode", also known as "discov- ery mode", which has now been moved to "#exploremode" and M-X.) ^X Display basic information about your character. - Displays name, role, race, gender (unless role name makes that - redundant, such as Caveman or Priestess), and alignment, along - with your patron deity and his or her opposition. It also shows - most of the various items of information from the status line(s) - in a less terse form, including several additional things which + Displays name, role, race, gender (unless role name makes that + redundant, such as Caveman or Priestess), and alignment, along + with your patron deity and his or her opposition. It also shows + most of the various items of information from the status line(s) + in a less terse form, including several additional things which don't appear in the normal status display due to space considera- tions. - In normal play, that's all that `^X' displays. In explore mode, + In normal play, that's all that `^X' displays. In explore mode, the role and status feedback is augmented by the information pro- vided by enlightenment magic. @@ -1171,18 +1178,11 @@ Z. - to cast at yourself, use `.' for the direction. - ^Z Suspend the game (UNIX(R) versions with job control only). See - "#suspend" below for more details. - - : Look at what is here. - __________ - (R)UNIX is a registered trademark of The Open Group. - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1192,6 +1192,11 @@ + ^Z Suspend the game (UNIX(R) versions with job control only). See + "#suspend" below for more details. + + : Look at what is here. + ; Show what type of thing a visible symbol corresponds to. , Pick up some things from the floor beneath you. @@ -1221,15 +1226,15 @@ + List the spells you know. - Using this command, you can also rearrange the order in which - your spells are listed, either by sorting the entire list or by - picking one spell from the menu then picking another to swap - places with it. Swapping pairs of spells changes their casting - letters, so the change lasts after the current `+' command fin- - ishes. Sorting the whole list is temporary. To make the most - recent sort order persist beyond the current `+' command, choose - the sort option again and then pick "reassign casting letters". - (Any spells learned after that will be added to the end of the + Using this command, you can also rearrange the order in which + your spells are listed, either by sorting the entire list or by + picking one spell from the menu then picking another to swap + places with it. Swapping pairs of spells changes their casting + letters, so the change lasts after the current `+' command fin- + ishes. Sorting the whole list is temporary. To make the most + recent sort order persist beyond the current `+' command, choose + the sort option again and then pick "reassign casting letters". + (Any spells learned after that will be added to the end of the list rather than be inserted into the sorted ordering.) \ Show what types of objects have been discovered. @@ -1238,17 +1243,12 @@ ` Show discovered types for one class of objects. - May be preceded by `m' to select preferred display order. - | If persistent inventory display is supported and enabled (with - the perm_invent option), interact with it instead of with the - map. - - Allows scrolling with the menu_first_page, menu_previous_page, - menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by + __________ + (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1258,8 +1258,16 @@ + May be preceded by `m' to select preferred display order. + + | If persistent inventory display is supported and enabled (with + the perm_invent option), interact with it instead of with the + map. + + Allows scrolling with the menu_first_page, menu_previous_page, + menu_next_page, and menu_last_page keys (`^', `<', `>', `|' by default). Some interfaces also support menu_shift_left and - menu_shift_right keys (`{' and `}' by default). Use the Return + menu_shift_right keys (`{' and `}' by default). Use the Return (aka Enter) or Escape key to resume play. ! Escape to a shell. See "#shell" below for more details. @@ -1268,53 +1276,45 @@ of the current level's map without monsters; without monsters and objects; or without monsters, objects, and traps. - The key is also shown as on some keyboards or - on others. It is sometimes displayed as ^? even though + The key is also shown as on some keyboards or + on others. It is sometimes displayed as ^? even though that is not an actual control character. - Many terminals have an option to swap the and - keys, so typing the key might not execute this - command. If that happens, you can use the extended command + Many terminals have an option to swap the and + keys, so typing the key might not execute this + command. If that happens, you can use the extended command "#terrain" instead. # Perform an extended command. - As you can see, the authors of NetHack used up all the letters, + As you can see, the authors of NetHack used up all the letters, so this is a way to introduce the less frequently used commands. What - extended commands are available depends on what features the game was + extended commands are available depends on what features the game was compiled with. #adjust - Adjust inventory letters (most useful when the fixinv option is + Adjust inventory letters (most useful when the fixinv option is "on"). Autocompletes. Default key is `M-a'. - This command allows you to move an item from one particular - inventory slot to another so that it has a letter which is more - meaningful for you or that it will appear in a particular loca- - tion when inventory listings are displayed. You can move to a - currently empty slot, or if the destination is occupied--and - won't merge--the item there will swap slots with the one being - moved. "#adjust" can also be used to split a stack of objects; + This command allows you to move an item from one particular + inventory slot to another so that it has a letter which is more + meaningful for you or that it will appear in a particular loca- + tion when inventory listings are displayed. You can move to a + currently empty slot, or if the destination is occupied--and + won't merge--the item there will swap slots with the one being + moved. "#adjust" can also be used to split a stack of objects; when choosing the item to adjust, enter a count prior to its let- ter. - Adjusting without a count used to collect all compatible stacks - when moving to the destination. That behavior has been changed; - to gather compatible stacks, "#adjust" a stack into its own + Adjusting without a count used to collect all compatible stacks + when moving to the destination. That behavior has been changed; + to gather compatible stacks, "#adjust" a stack into its own inventory slot. If it has a name assigned, other stacks with the - same name or with no name will merge provided that all their - other attributes match. If it does not have a name, only other - stacks with no name are eligible. In either case, otherwise com- - patible stacks with a different name will not be merged. This - contrasts with using "#adjust" to move from one slot to a differ- - ent slot. In that situation, moving (no count given) a compati- - ble stack will merge if either stack has a name when the other - doesn't and give that name to the result, while splitting (count - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1324,16 +1324,24 @@ - given) will ignore the source stack's name when deciding whether + same name or with no name will merge provided that all their + other attributes match. If it does not have a name, only other + stacks with no name are eligible. In either case, otherwise com- + patible stacks with a different name will not be merged. This + contrasts with using "#adjust" to move from one slot to a differ- + ent slot. In that situation, moving (no count given) a compati- + ble stack will merge if either stack has a name when the other + doesn't and give that name to the result, while splitting (count + given) will ignore the source stack's name when deciding whether to merge with the destination stack. #annotate Allows you to specify one line of text to associate with the cur- rent dungeon level. All levels with annotations are displayed by - the "#overview" command. Autocompletes. Default key is `M-A', + the "#overview" command. Autocompletes. Default key is `M-A', and also `^N' if number_pad is on. - Preceding #annotate with the `m' prefix is the same as #overview + Preceding #annotate with the `m' prefix is the same as #overview with the prefix. #apply @@ -1343,7 +1351,7 @@ If the tool used acts on items on the floor, using the `m' prefix skips those items. - If used on a wand, that wand will be broken, releasing its magic + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. #attributes @@ -1353,14 +1361,14 @@ Toggle the autopickup option on/off. Default key is `@'. #bugreport - Bring up a browser window to submit a report to the NetHack - Development Team. Can be disabled at the time the program is - built; when enabled, CRASHREPORTURL must be set in the system + Bring up a browser window to submit a report to the NetHack + Development Team. Can be disabled at the time the program is + built; when enabled, CRASHREPORTURL must be set in the system configuration file. #call - Call (name) a monster, or an object in inventory, on the floor, - or in the discoveries list, or add an annotation for the current + Call (name) a monster, or an object in inventory, on the floor, + or in the discoveries list, or add an annotation for the current level (same as "#annotate"). Default key is `C'. #cast @@ -1369,18 +1377,10 @@ #chat Talk to someone. Default key is `M-c'. - #chronicle - Show a list of important game events. Default key is `v'. - - #close - Close a door. Default key is `c'. - - #conduct - List voluntary challenges you have maintained. Autocompletes. - Default key is `M-C'. - NetHack 3.7.0 April 16, 2026 + + NetHack 5.0.0 July 4, 2026 @@ -1390,6 +1390,16 @@ + #chronicle + Show a list of important game events. Default key is `v'. + + #close + Close a door. Default key is `c'. + + #conduct + List voluntary challenges you have maintained. Autocompletes. + Default key is `M-C'. + See the section below entitled "Conduct" for details. #debugfuzzer @@ -1399,7 +1409,7 @@ Dip an object into something. Autocompletes. Default key is `M- d'. - The `m' prefix skips dipping into a fountain or pool if there is + The `m' prefix skips dipping into a fountain or pool if there is one at your location. #down @@ -1412,22 +1422,22 @@ Drop specific item types. Default key is `D'. #eat - Eat something. Default key is `e'. The `m' prefix skips eating + Eat something. Default key is `e'. The `m' prefix skips eating items on the floor. #engrave Engrave writing on the floor. Default key is `E'. #enhance - Advance or check weapon and spell skills. Autocompletes. + Advance or check weapon and spell skills. Autocompletes. Default key is `M-e'. #exploremode Switch from normal play to non-scoring explore mode. Default key is `M-X'. - Requires confirmation; default response is n (no). To really - switch to explore mode, respond with y. You can set the para- + Requires confirmation; default response is n (no). To really + switch to explore mode, respond with y. You can set the para- noid_confirmation:quit option to require a response of yes instead. @@ -1435,18 +1445,8 @@ Prefix key to force fight a direction, even if you see nothing to fight there. Default key is `F', or `-' with number_pad - #fire - Fire ammunition from quiver, possibly autowielding a launcher, or - hit with a wielded polearm. Default key is `f'. - #force - Force a lock. Autocompletes. Default key is `M-f'. - - #genocided - List any monster types which have been genocided. In explore - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1456,17 +1456,26 @@ - mode and debug mode it also shows types which have become + #fire + Fire ammunition from quiver, possibly autowielding a launcher, or + hit with a wielded polearm. Default key is `f'. + + #force + Force a lock. Autocompletes. Default key is `M-f'. + + #genocided + List any monster types which have been genocided. In explore + mode and debug mode it also shows types which have become extinct. The display order is the same as is used by #vanquished. The `m' - prefix brings up a menu of available sorting orders, and doing - that for either #genocided or #vanquished changes the order for + prefix brings up a menu of available sorting orders, and doing + that for either #genocided or #vanquished changes the order for both. - If the sorting order is "count high to low" or "count low to - high" (which are applicable for #vanquished), that will be - ignored for #genocided and alphabetical will be used instead. + If the sorting order is "count high to low" or "count low to + high" (which are applicable for #vanquished), that will be + ignored for #genocided and alphabetical will be used instead. The menu omits those two choices when used for #genocide. Autocompletes. Default key is `M-g'. @@ -1476,20 +1485,20 @@ is `;'. #help - Show the help menu. Default key is `?', and also `h' if num- + Show the help menu. Default key is `?', and also `h' if num- ber_pad is on. #herecmdmenu - Show a menu of possible actions directed at your current loca- - tion. The menu is limited to a subset of the likeliest actions, + Show a menu of possible actions directed at your current loca- + tion. The menu is limited to a subset of the likeliest actions, not an exhaustive set of all possibilities. Autocompletes. - If mouse support is enabled and the herecmd_menu option is On, - clicking on the hero (or steed when mounted) will execute this + If mouse support is enabled and the herecmd_menu option is On, + clicking on the hero (or steed when mounted) will execute this command. #history - Show long version and game history. + Show a summary of the game's development. #inventory Show your inventory. Default key is `i'. @@ -1498,21 +1507,12 @@ Inventory specific item types. Default key is `I'. #invoke - Invoke an object's special powers. Autocompletes. Default key + Invoke an object's special powers. Autocompletes. Default key is `M-i'. - #jump - Jump to another location. Autocompletes. Default key is `M-j', - and also `j' if number_pad is on. - - #kick - Kick something. Default key is `^D', and `k' if number_pad is - on. - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1522,15 +1522,23 @@ + #jump + Jump to another location. Autocompletes. Default key is `M-j', + and also `j' if number_pad is on. + + #kick + Kick something. Default key is `^D', and `k' if number_pad is + on. + #known Show what object types have been discovered. Default key is `\'. - The `m' prefix allows assigning a new value to the sortdiscover- + The `m' prefix allows assigning a new value to the sortdiscover- ies option to control the order in which the discoveries are dis- played. #knownclass - Show discovered types for one class of objects. Default key is + Show discovered types for one class of objects. Default key is ``'. The `m' prefix operates the same as for "#known". @@ -1548,37 +1556,29 @@ Describe what you can see, or remember, of your surroundings. #loot - Loot a box or bag on the floor beneath you, or the saddle from a + Loot a box or bag on the floor beneath you, or the saddle from a steed standing next to you. Autocompletes. Precede with the `m' - prefix to skip containers at your location and go directly to - removing a saddle. Default key is `M-l', and also `l' if num- + prefix to skip containers at your location and go directly to + removing a saddle. Default key is `M-l', and also `l' if num- ber_pad is on. #monster - Use a monster's special ability (when polymorphed into monster + Use a monster's special ability (when polymorphed into monster form). Autocompletes. Default key is `M-m'. #name - Name a monster, an individual object, or a type of object. Same + Name a monster, an individual object, or a type of object. Same as "#call". Autocompletes. Default keys are `N', `M-n', and `M- N'. #offer - Offer a sacrifice to the gods. Autocompletes. Default key is + Offer a sacrifice to the gods. Autocompletes. Default key is `M-o'. - You'll need to find an altar to have any chance at success. - Corpses of recently killed monsters are the fodder of choice. - - The `m' prefix skips offering any items which are on the altar. - - #open - Open a door. Default key is `o'. - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1588,37 +1588,45 @@ + You'll need to find an altar to have any chance at success. + Corpses of recently killed monsters are the fodder of choice. + + The `m' prefix skips offering any items which are on the altar. + + #open + Open a door. Default key is `o'. + #options - Show and change option settings. Default key is `O'. Precede + Show and change option settings. Default key is `O'. Precede with the `m' prefix to show advanced options. #optionsfull - Show advanced game option settings. No default key. Precede - with the `m' prefix to execute the simpler options command. - (Mainly useful if you use BINDING=O:optionsfull to switch `O' + Show advanced game option settings. No default key. Precede + with the `m' prefix to execute the simpler options command. + (Mainly useful if you use BINDING=O:optionsfull to switch `O' from simple options back to traditional advanced options.) #overview - Display information you've discovered about the dungeon. Any - visited level with an annotation is included, and many things - (altars, thrones, fountains, and so on; extra stairs leading to + Display information you've discovered about the dungeon. Any + visited level with an annotation is included, and many things + (altars, thrones, fountains, and so on; extra stairs leading to another dungeon branch) trigger an automatic annotation. If dun- geon overview is chosen during end-of-game disclosure, every vis- ited level will be included regardless of annotations. - Precede #overview with the `m' prefix to display the dungeon - overview as a menu where you can select any visited level to add - or remove an annotation without needing to return to that level. - This will also force all visited levels to be displayed rather + Precede #overview with the `m' prefix to display the dungeon + overview as a menu where you can select any visited level to add + or remove an annotation without needing to return to that level. + This will also force all visited levels to be displayed rather than just the "interesting" subset. Autocompletes. Default keys are `^O', and `M-O'. #panic - Test the panic routine. Terminates the current game. Autocom- + Test the panic routine. Terminates the current game. Autocom- pletes. Debug mode only. - Asks for confirmation; default is n (no); continue playing. To + Asks for confirmation; default is n (no); continue playing. To really panic, respond with y. You can set the paranoid_confirma- tion:quit option to require a response of yes instead. @@ -1626,25 +1634,17 @@ Pay your shopping bill. Default key is `p'. #perminv - If persistent inventory display is supported and enabled (with - the perm_invent option), interact with it instead of with the - map. You'll be prompted for menu scrolling keystrokes such as - `>' and `<'. Press Return or Escape to resume normal play. + If persistent inventory display is supported and enabled (with + the perm_invent option), interact with it instead of with the + map. You'll be prompted for menu scrolling keystrokes such as + `>' and `<'. Press Return or Escape to resume normal play. Default key is `|'. #pickup Pick up things at the current location. Default key is `,'. The - `m' prefix forces use of a menu. - - #polyself - Polymorph self. Autocompletes. Debug mode only. - - #pray - Pray to the gods for help. Autocompletes. Default key is `M-p'. - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1654,12 +1654,20 @@ - Praying too soon after receiving prior help is a bad idea. - (Hint: entering the dungeon alive is treated as having received - help. You probably shouldn't start off a new game by praying - right away.) Since using this command by accident can cause - trouble, there is an option to make you confirm your intent - before praying. It is enabled by default, and you can reset the + `m' prefix forces use of a menu. + + #polyself + Polymorph self. Autocompletes. Debug mode only. + + #pray + Pray to the gods for help. Autocompletes. Default key is `M-p'. + + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having received + help. You probably shouldn't start off a new game by praying + right away.) Since using this command by accident can cause + trouble, there is an option to make you confirm your intent + before praying. It is enabled by default, and you can reset the paranoid_confirmation option to disable it. #prevmsg @@ -1678,20 +1686,20 @@ Quit the program without saving your game. Autocompletes. Since using this command by accident would throw away the current - game, you are asked to confirm your intent before quitting. - Default response is n (no); continue playing. To really quit, - respond with y. You can set the paranoid_confirmation:quit + game, you are asked to confirm your intent before quitting. + Default response is n (no); continue playing. To really quit, + respond with y. You can set the paranoid_confirmation:quit option to require a response of yes instead. #quiver Select ammunition for quiver. Default key is `Q'. #read - Read a scroll, a spellbook, or something else. Default key is + Read a scroll, a spellbook, or something else. Default key is `r'. #redraw - Redraw the screen. Default key is `^R', and also `^L' if num- + Redraw the screen. Default key is `^R', and also `^L' if num- ber_pad is on. #remove @@ -1700,17 +1708,9 @@ #repeat Repeat the previous command. Default key is `^A'. - #reqmenu - Prefix key to modify the behavior or request menu from some com- - mands. Prevents autopickup when used with movement commands. - Default key is `m'. - - #retravel - Travel to a previously selected travel destination. Default key - is `C-_'. See also #travel. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1720,16 +1720,25 @@ + #reqmenu + Prefix key to modify the behavior or request menu from some com- + mands. Prevents autopickup when used with movement commands. + Default key is `m'. + + #retravel + Travel to a previously selected travel destination. Default key + is `C-_'. See also #travel. + #ride - Ride (or stop riding) a saddled creature. Autocompletes. + Ride (or stop riding) a saddled creature. Autocompletes. Default key is `M-R'. #rub Rub a lamp or a stone. Autocompletes. Default key is `M-r'. #run - Prefix key to run towards a direction. Default key is `G' when - number_pad is off, `5' when number_pad is set to 1 or 3, other- + Prefix key to run towards a direction. Default key is `G' when + number_pad is off, `5' when number_pad is set to 1 or 3, other- wise `M-5' when it is set to 2 or 4. #rush @@ -1741,12 +1750,12 @@ Save the game and exit the program. Default key is `S'. #saveoptions - Save configuration options to the config file. This will over- - write the file, removing all comments, so if you have manually + Save configuration options to the config file. This will over- + write the file, removing all comments, so if you have manually edited the config file, don't use this. #search - Search for traps and secret doors around you. Default key is + Search for traps and secret doors around you. Default key is `s'. #seeall @@ -1763,20 +1772,11 @@ #seearmor Show the armor currently worn. Default key is `['. - Will display worn armor in a menu even when there is only thing + Will display worn armor in a menu even when there is only thing worn. - #seerings - Show the ring(s) currently worn. Default key is `='. - Will display worn rings in a menu if there are two (or there is - just one and is a meat ring rather than a "real" ring). Use the - `m' prefix to force a menu for one ring. - - - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1786,10 +1786,17 @@ + #seerings + Show the ring(s) currently worn. Default key is `='. + + Will display worn rings in a menu if there are two (or there is + just one and is a meat ring rather than a "real" ring). Use the + `m' prefix to force a menu for one ring. + #seetools Show the tools currently in use. Default key is `('. - Will display the result in a message if there is one tool in use + Will display the result in a message if there is one tool in use (worn blindfold or towel or lenses, lit lamp(s) and/or candle(s), leashes attached to pets). Will display a menu if there are more than one or if the command is preceded by the `m' prefix. @@ -1797,32 +1804,32 @@ #seeweapon Show the weapon currently wielded. Default key is `)'. - If dual-wielding, a separate message about the secondary weapon - will be given. Using the `m' prefix will force a menu and it + If dual-wielding, a separate message about the secondary weapon + will be given. Using the `m' prefix will force a menu and it will include primary weapon, alternate weapon even when not dual- - wielding, and also whatever is currently assigned to the quiver + wielding, and also whatever is currently assigned to the quiver slot. #shell - Do a shell escape, switching from NetHack to a subprocess. Can - be disabled at the time the program is built. When enabled, + Do a shell escape, switching from NetHack to a subprocess. Can + be disabled at the time the program is built. When enabled, access for specific users can be controlled by the system config- - uration file. Use the shell command `exit' to return to the + uration file. Use the shell command `exit' to return to the game. Default key is `!'. #showgold - Report the gold in your inventory, including gold you know about - in containers you're carrying. If you are inside a shop, report + Report the gold in your inventory, including gold you know about + in containers you're carrying. If you are inside a shop, report any credit or debt you have in that shop. Default key is `$'. #showspells List and reorder known spells. Default key is `+'. #showtrap - Describe an adjacent trap, possibly covered by objects or a mon- + Describe an adjacent trap, possibly covered by objects or a mon- ster. To be eligible, the trap must already be discovered. (The "#terrain" command can display your map with all objects and mon- - sters temporarily removed, making it possible to see all discov- + sters temporarily removed, making it possible to see all discov- ered traps.) Default key is `^'. #sit @@ -1832,17 +1839,10 @@ Show memory usage statistics. Autocompletes. Debug mode only. #suspend - Suspend the game, switching from NetHack to the terminal it was - started from without performing save-and-exit. Can be disabled - at the time the program is built. When enabled, mainly useful - for tty and curses interfaces on UNIX. Use the shell command - `fg' to return to the game. Default key is `^Z'. - - #swap - Swap wielded and secondary weapons. Default key is `x'. + Suspend the game, switching from NetHack to the terminal it was - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1852,6 +1852,14 @@ + started from without performing save-and-exit. Can be disabled + at the time the program is built. When enabled, mainly useful + for tty and curses interfaces on UNIX. Use the shell command + `fg' to return to the game. Default key is `^Z'. + + #swap + Swap wielded and secondary weapons. Default key is `x'. + #takeoff Take off one piece of armor. Default key is `T'. @@ -1862,25 +1870,25 @@ Teleport around the level. Default key is `^T'. #terrain - Show map without obstructions. In normal play you can view the - explored portion of the current level's map without monsters; - without monsters and objects; or without monsters, objects, and + Show map without obstructions. In normal play you can view the + explored portion of the current level's map without monsters; + without monsters and objects; or without monsters, objects, and traps. If there are visible clouds of gas in view, they are treated like - traps when deciding whether to show them or the floor underneath + traps when deciding whether to show them or the floor underneath them. - In explore mode, you can choose to view the full map rather than - just its explored portion. In debug mode there are additional + In explore mode, you can choose to view the full map rather than + just its explored portion. In debug mode there are additional choices. - Autocompletes. Default key is `' or `' (see Del + Autocompletes. Default key is `' or `' (see Del above). #therecmdmenu - Show a menu of possible actions directed at a location next to - you. The menu is limited to a subset of the likeliest actions, + Show a menu of possible actions directed at a location next to + you. The menu is limited to a subset of the likeliest actions, not an exhaustive set of all possibilities. Autocompletes. #throw @@ -1891,24 +1899,16 @@ #tip Tip over a container (bag or box) to pour out its contents. When - there are containers on the floor, the game will prompt to pick - one of them or "tip something being carried". If the latter is - chosen, there will be another prompt for which item from inven- + there are containers on the floor, the game will prompt to pick + one of them or "tip something being carried". If the latter is + chosen, there will be another prompt for which item from inven- tory to tip. The `m' prefix makes the command skip containers on the floor and - pick one from inventory, except for the special case of - menustyle:traditional with two or more containers present; that - situation will start with the floor container menu. - - Autocompletes. Default key is `M-T'. - - #toggle - Toggle a boolean option on or off. Requires a parameter in - parenthesis, the name of the option to toggle. The option must + pick one from inventory, except for the special case of - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1918,6 +1918,14 @@ + menustyle:traditional with two or more containers present; that + situation will start with the floor container menu. + + Autocompletes. Default key is `M-T'. + + #toggle + Toggle a boolean option on or off. Requires a parameter in + parenthesis, the name of the option to toggle. The option must be settable in-game. For example: @@ -1926,10 +1934,10 @@ BIND=@:toggle(autopickup) #travel - Travel to a specific location on the map. Default key is `_'. - Using the "request menu" prefix shows a menu of interesting tar- - gets in sight without asking to move the cursor. When picking a - target with cursor and the autodescribe option is on, the top + Travel to a specific location on the map. Default key is `_'. + Using the "request menu" prefix shows a menu of interesting tar- + gets in sight without asking to move the cursor. When picking a + target with cursor and the autodescribe option is on, the top line will show "(no travel path)" if your character does not know of a path to that location. See also #retravel. @@ -1937,17 +1945,17 @@ Turn undead away. Autocompletes. Default key is `M-t'. #twoweapon - Toggle two-weapon combat on or off. Autocompletes. Default key + Toggle two-weapon combat on or off. Autocompletes. Default key is `X', and also `M-2' if number_pad is off. - Note that you must use suitable weapons for this type of combat, + Note that you must use suitable weapons for this type of combat, or it will be automatically turned off. #untrap - Untrap something (trap, door, or chest). Default key is `M-u', + Untrap something (trap, door, or chest). Default key is `M-u', and `u' if number_pad is on. - In some circumstances it can also be used to rescue trapped mon- + In some circumstances it can also be used to rescue trapped mon- sters. #up @@ -1956,25 +1964,17 @@ #vanquished List vanquished monsters by type and count. - Note that the vanquished monsters list includes all monsters - killed by traps and each other as well as by you, and omits any - which got removed from the game without being killed (perhaps by - genocide, or by a mollified shopkeeper dismissing summoned Kops) + Note that the vanquished monsters list includes all monsters + killed by traps and each other as well as by you, and omits any + which got removed from the game without being killed (perhaps by + genocide, or by a mollified shopkeeper dismissing summoned Kops) or were already corpses when placed on the map. - Using the "request menu" prefix prior to #vanquished brings up a - menu of sorting orders available (provided that the vanquished - monsters list contains at least two types of monsters). Which- - ever ordering is picked gets assigned to the sortvanquished - option so is remembered for subsequent #vanquished requests. The - "#genocided" command shares this sorting order. - - During end-of-game disclosure, when asked whether to show van- - quished monsters answering `a' will let you choose from the sort - menu. + Using the "request menu" prefix prior to #vanquished brings up a + menu of sorting orders available (provided that the vanquished - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -1984,6 +1984,15 @@ + monsters list contains at least two types of monsters). Which- + ever ordering is picked gets assigned to the sortvanquished + option so is remembered for subsequent #vanquished requests. The + "#genocided" command shares this sorting order. + + During end-of-game disclosure, when asked whether to show van- + quished monsters answering `a' will let you choose from the sort + menu. + Autocompletes. Default key is `M-V'. #version @@ -1991,21 +2000,21 @@ The second paragraph lists the user interface(s) that are included. If there are more than one, you can use the windowtype - option in your run-time configuration file to select the one you + option in your run-time configuration file to select the one you want. Autocompletes. Default key is `M-v'. #versionshort - Show the program's version number, plus the date and time that - the running copy was built from sources (not the version's + Show the program's version number, plus the date and time that + the running copy was built from sources (not the version's release date). Default key is `V'. #vision Show vision array. Autocompletes. Debug mode only. #wait - Rest one move while doing nothing. Default key is `.', and also + Rest one move while doing nothing. Default key is `.', and also ` ' if rest_on_space is on. #wear @@ -2015,7 +2024,7 @@ Tell what a key does. Default key is `&'. #whatis - Show what type of thing a symbol corresponds to. Default key is + Show what type of thing a symbol corresponds to. Default key is `/'. #wield @@ -2025,22 +2034,13 @@ Wipe off your face. Autocompletes. Default key is `M-w'. #wizborn - Show monster birth, death, genocide, and extinct statistics. + Show monster birth, death, genocide, and extinct statistics. Debug mode only. - #wizbury - Bury objects under and around you. Autocompletes. Debug mode - only. - - #wizcast - Cast any spell. Debug mode only. - - #wizdetect - Reveal hidden things (secret doors or traps or unseen monsters) - within a modest radius. No time elapses. Autocompletes. Debug - NetHack 3.7.0 April 16, 2026 + + NetHack 5.0.0 July 4, 2026 @@ -2050,6 +2050,16 @@ + #wizbury + Bury objects under and around you. Autocompletes. Debug mode + only. + + #wizcast + Cast any spell. Debug mode only. + + #wizdetect + Reveal hidden things (secret doors or traps or unseen monsters) + within a modest radius. No time elapses. Autocompletes. Debug mode only. Default key is `^E'. #wizgenesis @@ -2057,7 +2067,7 @@ one. Autocompletes. Debug mode only. Default key is `^G'. #wizidentify - Identify all items in inventory. Autocompletes. Debug mode + Identify all items in inventory. Autocompletes. Debug mode only. Default key is `^I'. #wizintrinsic @@ -2065,48 +2075,38 @@ only. #wizkill - Remove monsters from play by just pointing at them. By default - the hero gets credit or blame for killing the targets. Precede - this command with the `m' prefix to override that. Autocom- + Remove monsters from play by just pointing at them. By default + the hero gets credit or blame for killing the targets. Precede + this command with the `m' prefix to override that. Autocom- pletes. Debug mode only. #wizlevelport - Teleport to another level. Autocompletes. Debug mode only. + Teleport to another level. Autocompletes. Debug mode only. Default key is `^V'. #wizmap - Map the level. Autocompletes. Debug mode only. Default key is + Map the level. Autocompletes. Debug mode only. Default key is `^F'. #wizrumorcheck - Verify rumor boundaries by displaying first and last true rumors + Verify rumor boundaries by displaying first and last true rumors and first and last false rumors. - Also displays first, second, and last random engravings, epi- + Also displays first, second, and last random engravings, epi- taphs, and hallucinatory monsters. Autocompletes. Debug mode only. #wizseenv - Show map locations' seen vectors. Autocompletes. Debug mode + Show map locations' seen vectors. Autocompletes. Debug mode only. #wizsmell Smell monster. Autocompletes. Debug mode only. - #wizwhere - Show locations of special levels. Autocompletes. Debug mode - only. - - #wizwish - Wish for something. Autocompletes. Debug mode only. Default - key is `^W'. Precede this command with the `m' prefix to show a - wish history menu. - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2116,6 +2116,15 @@ + #wizwhere + Show locations of special levels. Autocompletes. Debug mode + only. + + #wizwish + Wish for something. Autocompletes. Debug mode only. Default + key is `^W'. Precede this command with the `m' prefix to show a + wish history menu. + #wmode Show wall modes. Autocompletes. Debug mode only. @@ -2127,23 +2136,23 @@ - If your keyboard has a meta key (which, when pressed in combina- - tion with another key, modifies it by setting the "meta" [8th, or - "high"] bit), you can invoke many extended commands by meta-ing the + If your keyboard has a meta key (which, when pressed in combina- + tion with another key, modifies it by setting the "meta" [8th, or + "high"] bit), you can invoke many extended commands by meta-ing the first letter of the command. On Windows and MS-DOS, the "Alt" key can be used in this fashion. - On other systems, if typing "Alt" plus another key transmits a two - character sequence consisting of an Escape followed by the other key, - you may set the altmeta option to have NetHack combine them into - meta+. (This combining action only takes place when NetHack is + On other systems, if typing "Alt" plus another key transmits a two + character sequence consisting of an Escape followed by the other key, + you may set the altmeta option to have NetHack combine them into + meta+. (This combining action only takes place when NetHack is expecting a command to execute, not when accepting input to name some- thing or to make a wish.) Unlike control characters, where ^x and ^X denote the same thing, - meta characters are case-sensitive: M-x and M-X represent different - things. Some commands which can be run via a meta character require - that the letter be capitalized because the lower-case equivalent is + meta characters are case-sensitive: M-x and M-X represent different + things. Some commands which can be run via a meta character require + that the letter be capitalized because the lower-case equivalent is used for another command, so the three key combination meta+Shift+ is needed. @@ -2163,16 +2172,7 @@ - - - - - - - - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2238,7 +2238,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2252,7 +2252,7 @@ - If the number_pad option is on, some additional letter commands + If the number_pad option is on, some additional letter commands are available: h #help @@ -2304,7 +2304,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2316,61 +2316,61 @@ 5. Rooms and corridors - Rooms and corridors in the dungeon are either lit or dark. Any - lit areas within your line of sight will be displayed; dark areas are - only displayed if they are within one space of you. Walls and corri- + Rooms and corridors in the dungeon are either lit or dark. Any + lit areas within your line of sight will be displayed; dark areas are + only displayed if they are within one space of you. Walls and corri- dors remain on the map as you explore them. Secret corridors are hidden and appear to be solid rock. You can find them with the `s' (search) command when adjacent to them. Multi- - ple search attempts may be needed. When searching is successful, - secret corridors become ordinary open corridor locations. Mapping - magic reveals secret corridors, so converts them into ordinary corri- + ple search attempts may be needed. When searching is successful, + secret corridors become ordinary open corridor locations. Mapping + magic reveals secret corridors, so converts them into ordinary corri- dors and shows them as such. 5.1. Doorways - Doorways connect rooms and corridors. Some doorways have no - doors; you can walk right through. Others have doors in them, which - may be open, closed, or locked. To open a closed door, use the `o' - (open) command; to close it again, use the `c' (close) command. By - default the autoopen option is enabled, so simply attempting to walk - onto a closed door's location will attempt to open it without needing - `o'. Opening via autoopen will not work if you are confused or + Doorways connect rooms and corridors. Some doorways have no + doors; you can walk right through. Others have doors in them, which + may be open, closed, or locked. To open a closed door, use the `o' + (open) command; to close it again, use the `c' (close) command. By + default the autoopen option is enabled, so simply attempting to walk + onto a closed door's location will attempt to open it without needing + `o'. Opening via autoopen will not work if you are confused or stunned or suffer from the fumbling attribute. - Open doors cannot be entered diagonally; you must approach them - straight on, horizontally or vertically. Doorways without doors are + Open doors cannot be entered diagonally; you must approach them + straight on, horizontally or vertically. Doorways without doors are not restricted in this fashion except on one particular level (described by "#overview" as "a primitive area"). - Unlocking magic exists but usually won't be available early on. - You can get through a locked door without magic by first using an - unlocking tool with the `a' (apply) command, and then opening it. By - default the autounlock option is also enabled, so if you attempt to - open (via `o' or autoopen) a locked door while carrying an unlocking - tool, you'll be asked whether to use it on the door's lock. Alterna- - tively, you can break a closed door (whether locked or not) down by - kicking it via the `^D' (kick) command. Kicking down a door destroys + Unlocking magic exists but usually won't be available early on. + You can get through a locked door without magic by first using an + unlocking tool with the `a' (apply) command, and then opening it. By + default the autounlock option is also enabled, so if you attempt to + open (via `o' or autoopen) a locked door while carrying an unlocking + tool, you'll be asked whether to use it on the door's lock. Alterna- + tively, you can break a closed door (whether locked or not) down by + kicking it via the `^D' (kick) command. Kicking down a door destroys it and makes a lot of noise which might wake sleeping monsters. - Some closed doors are booby-trapped and will explode if an - attempt is made to open (when unlocked) or unlock (when locked) or - kick down. Like kicking, an explosion destroys the door and makes a - lot of noise. The "#untrap" command can be used to search a door for - traps but might take multiple attempts to find one. When one is - found, you'll be asked whether to try to disarm it. If you accede, - success will eliminate the trap but failure will set off the trap's - explosion. (If you decline, you effectively forget that a trap was + Some closed doors are booby-trapped and will explode if an + attempt is made to open (when unlocked) or unlock (when locked) or + kick down. Like kicking, an explosion destroys the door and makes a + lot of noise. The "#untrap" command can be used to search a door for + traps but might take multiple attempts to find one. When one is + found, you'll be asked whether to try to disarm it. If you accede, + success will eliminate the trap but failure will set off the trap's + explosion. (If you decline, you effectively forget that a trap was found there.) - Closed doors can be useful for shutting out monsters. Most mon- - sters cannot open closed doors, although a few don't need to (for - example, ghosts can walk through doors and fog clouds can flow under + Closed doors can be useful for shutting out monsters. Most mon- + sters cannot open closed doors, although a few don't need to (for + example, ghosts can walk through doors and fog clouds can flow under them). Some monsters who can open doors can also use unlocking tools. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2382,61 +2382,61 @@ And some (giants) can smash doors. - Secret doors are hidden and appear to be ordinary wall (from - inside a room) or solid rock (from outside). You can find them with - the `s' (search) command but it might take multiple tries (possibly - many tries if your luck is poor). Once found they are in all ways - equivalent to normal doors. Mapping magic does not reveal secret + Secret doors are hidden and appear to be ordinary wall (from + inside a room) or solid rock (from outside). You can find them with + the `s' (search) command but it might take multiple tries (possibly + many tries if your luck is poor). Once found they are in all ways + equivalent to normal doors. Mapping magic does not reveal secret doors. 5.2. Traps (`^') - There are traps throughout the dungeon to snare the unwary - intruder. For example, you may suddenly fall into a pit and be stuck + There are traps throughout the dungeon to snare the unwary + intruder. For example, you may suddenly fall into a pit and be stuck for a few turns trying to climb out (see below). A trap usually won't - appear on your map until you trigger it by moving onto it, you see + appear on your map until you trigger it by moving onto it, you see someone else trigger it, or you discover it with the `s' (search) com- - mand (multiple attempts are often needed; if your luck is poor, many - attempts might be needed). Wands of secret door detection and spell - of detect unseen also reveal traps within a modest radius but only if + mand (multiple attempts are often needed; if your luck is poor, many + attempts might be needed). Wands of secret door detection and spell + of detect unseen also reveal traps within a modest radius but only if the trap is also within line-of-sight (whether you can see at the time or not). There is also other magic which can reveal traps. - Monsters can fall prey to traps, too, which can potentially be - used as a defensive strategy. Unfortunately traps can be harmful to - your pet(s) as well. Monsters, including pets, usually will avoid + Monsters can fall prey to traps, too, which can potentially be + used as a defensive strategy. Unfortunately traps can be harmful to + your pet(s) as well. Monsters, including pets, usually will avoid moving onto a trap which is shown on your map if they have encountered that type of trap before. - Some traps such as pits, bear traps, and webs hold you in one - place. You can escape by simply trying to move to an adjacent spot + Some traps such as pits, bear traps, and webs hold you in one + place. You can escape by simply trying to move to an adjacent spot and repeat as needed; eventually you will get free. - Other traps can send you to different locations. Teleporters - send you elsewhere on the same dungeon level. Level teleporters send - you to a random dungeon level, the destination chosen from a few lev- - els lower all the way to the top. These traps choose a new destina- - tion each time they're activated. Trap doors and holes also send you - to another level, but one which is always below the current level. - Usually that will be the next level down but it can be farther. + Other traps can send you to different locations. Teleporters + send you elsewhere on the same dungeon level. Level teleporters send + you to a random dungeon level, the destination chosen from a few lev- + els lower all the way to the top. These traps choose a new destina- + tion each time they're activated. Trap doors and holes also send you + to another level, but one which is always below the current level. + Usually that will be the next level down but it can be farther. Unlike (level) teleporters, the destination level of a particular trap - door or hole is persistent, so falling into one will bring you to the - same level each time--though not necessarily the same spot on the + door or hole is persistent, so falling into one will bring you to the + same level each time--though not necessarily the same spot on the level. Magic portals behave similarly, but with some additional vari- - ation. Some portals are two-way and their remote destination is - always the same: another portal which can take you back. Others are + ation. Some portals are two-way and their remote destination is + always the same: another portal which can take you back. Others are one-way and send you to a specific destination level but not necessar- ily to a specific location there. - There is a special multi-level branch of the dungeon with pre- - mapped levels based on the classic computer game "Sokoban." In that - game, you operate as a warehouse worker who pushes crates around - obstacles to position them at designated locations. In NetHack, the + There is a special multi-level branch of the dungeon with pre- + mapped levels based on the classic computer game "Sokoban." In that + game, you operate as a warehouse worker who pushes crates around + obstacles to position them at designated locations. In NetHack, the goal is to push boulders into pits or holes until those traps have all - been nullified, giving access to whatever is beyond them. In the + been nullified, giving access to whatever is beyond them. In the - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2446,63 +2446,63 @@ - Sokoban game, you can only move in the four cardinal compass direc- - tions, and a crate in its final destination blocks further access to - that spot. In the Sokoban levels of NetHack, you can move diagonally - (unless that would let you pass between two neighboring boulders) but - you can only push boulders in the four cardinal directions, and a - boulder which fills a pit or hole removes both the boulder and the - trap so opens up normal access to that spot. With careful foresight, - it is possible to complete all of the levels according to the tradi- - tional rules of Sokoban. (Hint: to solve Sokoban puzzles, you often - need to move things away from their eventual destinations in order to - open up more room to maneuver.) Since NetHack does not support an - undo capability, some allowances are permitted in case you get stuck. - For example, each level has at least one extra boulder. Also, it is - possible to drop everything in order to be able to squeeze into the - same location as a boulder (and then presumably move past it), or to - destroy a boulder with magic or tools, or to create new boulders with - a scroll of earth. However, doing such things will lower your luck - without any specific message given about that. See the Conduct sec- - tion for information about getting feedback for your actions in + Sokoban game, you can only move in the four cardinal compass direc- + tions, and a crate in its final destination blocks further access to + that spot. In the Sokoban levels of NetHack, you can move diagonally + (unless that would let you pass between two neighboring boulders) but + you can only push boulders in the four cardinal directions, and a + boulder which fills a pit or hole removes both the boulder and the + trap so opens up normal access to that spot. With careful foresight, + it is possible to complete all of the levels according to the tradi- + tional rules of Sokoban. (Hint: to solve Sokoban puzzles, you often + need to move things away from their eventual destinations in order to + open up more room to maneuver.) Since NetHack does not support an + undo capability, some allowances are permitted in case you get stuck. + For example, each level has at least one extra boulder. Also, it is + possible to drop everything in order to be able to squeeze into the + same location as a boulder (and then presumably move past it), or to + destroy a boulder with magic or tools, or to create new boulders with + a scroll of earth. However, doing such things will lower your luck + without any specific message given about that. See the Conduct sec- + tion for information about getting feedback for your actions in Sokoban. 5.3. Stairs and ladders (`<', `>') In general, each level in the dungeon will have a staircase going - up (`<') to the previous level and another going down (`>') to the - next level. There are some exceptions though. For instance, fairly - early in the dungeon you will find a level with two down staircases, - one continuing into the dungeon and the other branching into an area + up (`<') to the previous level and another going down (`>') to the + next level. There are some exceptions though. For instance, fairly + early in the dungeon you will find a level with two down staircases, + one continuing into the dungeon and the other branching into an area known as the Gnomish Mines. Those mines eventually hit a dead end, so - after exploring them (if you choose to do so), you'll need to climb + after exploring them (if you choose to do so), you'll need to climb back up to the main dungeon. - When you traverse a set of stairs, or trigger a trap which sends + When you traverse a set of stairs, or trigger a trap which sends you to another level, the level you're leaving will be deactivated and - stored in a file on disk. If you're moving to a previously visited - level, it will be loaded from its file on disk and reactivated. If - you're moving to a level which has not yet been visited, it will be + stored in a file on disk. If you're moving to a previously visited + level, it will be loaded from its file on disk and reactivated. If + you're moving to a level which has not yet been visited, it will be created (from scratch for most random levels, from a template for some - "special" levels, or loaded from the remains of an earlier game for a - "bones" level as briefly described below). Monsters are only active - on the current level; those on other levels are essentially placed + "special" levels, or loaded from the remains of an earlier game for a + "bones" level as briefly described below). Monsters are only active + on the current level; those on other levels are essentially placed into stasis. Ordinarily when you climb a set of stairs, you will arrive on the - corresponding staircase at your destination. However, pets (see - below) and some other monsters will follow along if they're close - enough when you travel up or down stairs, and occasionally one of + corresponding staircase at your destination. However, pets (see + below) and some other monsters will follow along if they're close + enough when you travel up or down stairs, and occasionally one of these creatures will displace you during the climb. When that occurs, the pet or other monster will arrive on the staircase and you will end up nearby. - Ladders serve the same purpose as staircases, and the two types - of inter-level connections are nearly indistinguishable during game + Ladders serve the same purpose as staircases, and the two types + of inter-level connections are nearly indistinguishable during game play. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2514,36 +2514,36 @@ 5.4. Shops and shopping - Occasionally you will run across a room with a shopkeeper near - the door and many items lying on the floor. You can buy items by + Occasionally you will run across a room with a shopkeeper near + the door and many items lying on the floor. You can buy items by picking them up and then using the `p' command. You can inquire about - the price of an item prior to picking it up by using the "#chat" com- - mand while standing on it. Using an item prior to paying for it will - incur a charge, and the shopkeeper won't allow you to leave the shop + the price of an item prior to picking it up by using the "#chat" com- + mand while standing on it. Using an item prior to paying for it will + incur a charge, and the shopkeeper won't allow you to leave the shop until you have paid any debt you owe. - You can sell items to a shopkeeper by dropping them to the floor + You can sell items to a shopkeeper by dropping them to the floor while inside a shop. You will either be offered an amount of gold and asked whether you're willing to sell, or you'll be told that the shop- - keeper isn't interested (generally, your item needs to be compatible + keeper isn't interested (generally, your item needs to be compatible with the type of merchandise carried by the shop). - If you drop something in a shop by accident, the shopkeeper will - usually claim ownership without offering any compensation. You'll + If you drop something in a shop by accident, the shopkeeper will + usually claim ownership without offering any compensation. You'll have to buy it back if you want to reclaim it. Shopkeepers sometime run out of money. When that happens, you'll - be offered credit instead of gold when you try to sell something. - Credit can be used to pay for purchases, but it is only good in the + be offered credit instead of gold when you try to sell something. + Credit can be used to pay for purchases, but it is only good in the shop where it was obtained; other shopkeepers won't honor it. (If you - happen to find a "credit card" in the dungeon, don't bother trying to + happen to find a "credit card" in the dungeon, don't bother trying to use it in shops; shopkeepers will not accept it.) - The `$' command, which reports the amount of gold you are carry- - ing, will also show current shop debt or credit, if any. The "Iu" - command lists unpaid items (those which still belong to the shop) if - you are carrying any. The "Ix" command shows an inventory-like dis- - play of any unpaid items which have been used up, along with other + The `$' command, which reports the amount of gold you are carry- + ing, will also show current shop debt or credit, if any. The "Iu" + command lists unpaid items (those which still belong to the shop) if + you are carrying any. The "Ix" command shows an inventory-like dis- + play of any unpaid items which have been used up, along with other shop fees, if any. 5.4.1. Shop idiosyncrasies @@ -2552,23 +2552,23 @@ * The price of a given item can vary due to a variety of factors. - * A shopkeeper treats the spot immediately inside the door as if it + * A shopkeeper treats the spot immediately inside the door as if it were outside the shop. - * While the shopkeeper watches you like a hawk, he or she will gener- + * While the shopkeeper watches you like a hawk, he or she will gener- ally ignore any other customers. - * If a shop is "closed for inventory," it will not open of its own + * If a shop is "closed for inventory," it will not open of its own accord. - * Shops do not get restocked with new items, regardless of inventory + * Shops do not get restocked with new items, regardless of inventory depletion. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2580,61 +2580,61 @@ 5.5. Movement feedback - Moving around the map usually provides no feedback--other than - drawing the hero at the new location--unless you step on an object or - pile of objects, or on a trap, or attempt to move onto a spot where a - monster is located. There are several options which can be used to + Moving around the map usually provides no feedback--other than + drawing the hero at the new location--unless you step on an object or + pile of objects, or on a trap, or attempt to move onto a spot where a + monster is located. There are several options which can be used to augment the normal feedback. - The pile_limit option controls how many objects can be in a - pile--sharing the same map location--for the game to state "there are - objects here" instead of listing them. The default is 5. Setting it - to 1 would always give that message instead of listing any objects. - Setting it to 0 is a special case which will always list all objects + The pile_limit option controls how many objects can be in a + pile--sharing the same map location--for the game to state "there are + objects here" instead of listing them. The default is 5. Setting it + to 1 would always give that message instead of listing any objects. + Setting it to 0 is a special case which will always list all objects no matter how big a pile is. Note that the number refers to the count of separate stacks of objects present rather than the sum of the quan- - tities of those stacks (so 7 arrows or 25 gold pieces will each count - as 1 rather than as 7 and 25, respectively, and total to 2 when both + tities of those stacks (so 7 arrows or 25 gold pieces will each count + as 1 rather than as 7 and 25, respectively, and total to 2 when both are at the same location). - The "nopickup" command prefix (default `m') can be used before a - movement direction to step on objects without attempting auto-pickup + The "nopickup" command prefix (default `m') can be used before a + movement direction to step on objects without attempting auto-pickup and without giving feedback about them. The mention_walls option controls whether you get feedback if you - try to walk into a wall or solid stone or off the edge of the map. - Normally nothing happens (unless the hero is blind and no wall is - shown, then the wall that is being bumped into will be drawn on the - map). This option also gives feedback when rushing or running stops + try to walk into a wall or solid stone or off the edge of the map. + Normally nothing happens (unless the hero is blind and no wall is + shown, then the wall that is being bumped into will be drawn on the + map). This option also gives feedback when rushing or running stops for some non-obvious reason. - The mention_decor option controls whether you get feedback when - walking on "furniture." Normally stepping onto stairs or a fountain - or an altar or various other things doesn't elicit anything unless it - is covered by one or more objects so is obscured on the map. Setting - this option to true will describe such things even when they aren't - obscured. Doorless doorways and open doors aren't considered worthy + The mention_decor option controls whether you get feedback when + walking on "furniture." Normally stepping onto stairs or a fountain + or an altar or various other things doesn't elicit anything unless it + is covered by one or more objects so is obscured on the map. Setting + this option to true will describe such things even when they aren't + obscured. Doorless doorways and open doors aren't considered worthy of mention; closed doors (if you can move onto their spots) and broken - doors are. Assuming that you're able to do so, moving onto water or - lava or ice will give feedback if not yet on that type of terrain but - not repeat it (unless there has been some intervening message) when - moving from water to another water spot, or lava to lava, or ice to - ice. Moving off of any of those back onto "normal" terrain will give - one message too, unless there is feedback about one or more objects, + doors are. Assuming that you're able to do so, moving onto water or + lava or ice will give feedback if not yet on that type of terrain but + not repeat it (unless there has been some intervening message) when + moving from water to another water spot, or lava to lava, or ice to + ice. Moving off of any of those back onto "normal" terrain will give + one message too, unless there is feedback about one or more objects, in which case the back on land circumstance is implied. - The confirm and safe_pet options control what happens when you + The confirm and safe_pet options control what happens when you try to move onto a peaceful monster's spot or a tame one's spot. - The "nopickup" command prefix (default `m') is also the move- + The "nopickup" command prefix (default `m') is also the move- without-attacking prefix and can be used to try to step onto a visible - monster's spot without the move being considered an attack (see the - Fighting subsection of Monsters below). The "fight" command prefix - (default `F'; also `-' if number_pad is on) can be used to force an - attack, when guessing where an unseen monster is or when deliberately + monster's spot without the move being considered an attack (see the + Fighting subsection of Monsters below). The "fight" command prefix + (default `F'; also `-' if number_pad is on) can be used to force an + attack, when guessing where an unseen monster is or when deliberately - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2646,22 +2646,22 @@ attacking a peaceful or tame creature. - The run_mode option controls how frequently the map gets redrawn - when moving more than one step in a single command (so when rushing, + The run_mode option controls how frequently the map gets redrawn + when moving more than one step in a single command (so when rushing, running, or traveling). 5.6. Rogue level - One dungeon level (occurring in mid to late teens of the main + One dungeon level (occurring in mid to late teens of the main dungeon) is a tribute to the ancestor game hack's inspiration rogue. - It is usually displayed differently from other levels: possibly - in characters instead of tiles, or without line-drawing symbols if - already in characters; also, gold is shown as * rather than $ and - stairs are shown as % rather than < and >. There are some minor dif- - ferences in actual game play: doorways lack doors; a scroll, wand, or - spell of light used in a room lights up the whole room rather than - within a radius around your character. And monsters represented by + It is usually displayed differently from other levels: possibly + in characters instead of tiles, or without line-drawing symbols if + already in characters; also, gold is shown as * rather than $ and + stairs are shown as % rather than < and >. There are some minor dif- + ferences in actual game play: doorways lack doors; a scroll, wand, or + spell of light used in a room lights up the whole room rather than + within a radius around your character. And monsters represented by lower-case letters aren't randomly generated on the rogue level. The slight strangeness of this level is a feature, not a bug.... @@ -2669,38 +2669,38 @@ 6. Monsters Monsters you cannot see are not displayed on the screen. Beware! - You may suddenly come upon one in a dark place. Some magic items can - help you locate them before they locate you (which some monsters can + You may suddenly come upon one in a dark place. Some magic items can + help you locate them before they locate you (which some monsters can do very well). - The commands `/' and `;' may be used to obtain information about - those monsters who are displayed on the screen. The command "#name" - (by default bound to `C'), allows you to assign a name to a monster, + The commands `/' and `;' may be used to obtain information about + those monsters who are displayed on the screen. The command "#name" + (by default bound to `C'), allows you to assign a name to a monster, which may be useful to help distinguish one from another when multiple - monsters are present. Assigning a name which is just a space will + monsters are present. Assigning a name which is just a space will remove any prior name. - The extended command "#chat" can be used to interact with an - adjacent monster. There is no actual dialog (in other words, you - don't get to choose what you'll say), but chatting with some monsters - such as a shopkeeper or the Oracle of Delphi can produce useful + The extended command "#chat" can be used to interact with an + adjacent monster. There is no actual dialog (in other words, you + don't get to choose what you'll say), but chatting with some monsters + such as a shopkeeper or the Oracle of Delphi can produce useful results. 6.1. Fighting - If you see a monster and you wish to fight it, just attempt to - walk into it. Many monsters you find will mind their own business + If you see a monster and you wish to fight it, just attempt to + walk into it. Many monsters you find will mind their own business unless you attack them. Some of them are very dangerous when angered. Remember: discretion is the better part of valor. - In most circumstances, if you attempt to attack a peaceful mon- - ster by moving into its location, you'll be asked to confirm your - intent. By default an answer of `y' acknowledges that intent, which + In most circumstances, if you attempt to attack a peaceful mon- + ster by moving into its location, you'll be asked to confirm your + intent. By default an answer of `y' acknowledges that intent, which can be error prone if you're using `y' to move. You can set the para- - noid_confirmation:attack option to require a response of "yes" + noid_confirmation:attack option to require a response of "yes" - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2712,61 +2712,61 @@ instead. - If you can't see a monster (if it is invisible, or if you are + If you can't see a monster (if it is invisible, or if you are blinded), the symbol `I' will be shown when you learn of its presence. - If you attempt to walk into it, you will try to fight it just like a - monster that you can see; of course, if the monster has moved, you - will attack empty air. If you guess that the monster has moved and - you don't wish to fight, you can use the `m' command to move without - fighting; likewise, if you don't remember a monster but want to try + If you attempt to walk into it, you will try to fight it just like a + monster that you can see; of course, if the monster has moved, you + will attack empty air. If you guess that the monster has moved and + you don't wish to fight, you can use the `m' command to move without + fighting; likewise, if you don't remember a monster but want to try fighting anyway, you can use the `F' command. 6.2. Your pet You start the game with a little dog (`d'), kitten (`f'), or pony - (`u'), which follows you about the dungeon and fights monsters with + (`u'), which follows you about the dungeon and fights monsters with you. Like you, your pet needs food to survive. Dogs and cats usually feed themselves on fresh carrion and other meats; horses need vegetar- ian food which is harder to come by. If you're worried about your pet - or want to train it, you can feed it, too, by throwing it food. A + or want to train it, you can feed it, too, by throwing it food. A properly trained pet can be very useful under certain circumstances. - Your pet also gains experience from killing monsters, and can - grow over time, gaining hit points and doing more damage. Initially, - your pet may even be better at killing things than you, which makes + Your pet also gains experience from killing monsters, and can + grow over time, gaining hit points and doing more damage. Initially, + your pet may even be better at killing things than you, which makes pets useful for low-level characters. - Your pet will follow you up and down staircases if it is next to + Your pet will follow you up and down staircases if it is next to you when you move. Otherwise your pet will be stranded and may become - wild. Similarly, when you trigger certain types of traps which alter - your location (for instance, a trap door which drops you to a lower - dungeon level), any adjacent pet will accompany you and any non-adja- + wild. Similarly, when you trigger certain types of traps which alter + your location (for instance, a trap door which drops you to a lower + dungeon level), any adjacent pet will accompany you and any non-adja- cent pet will be left behind. Your pet may trigger such traps itself; you will not be carried along with it even if adjacent at the time. 6.3. Steeds - Some types of creatures in the dungeon can actually be ridden if - you have the right equipment and skill. Convincing a wild beast to + Some types of creatures in the dungeon can actually be ridden if + you have the right equipment and skill. Convincing a wild beast to let you saddle it up is difficult to say the least. Many a dungeoneer - has had to resort to magic and wizardry in order to forge the - alliance. Once you do have the beast under your control however, you - can easily climb in and out of the saddle with the "#ride" command. - Lead the beast around the dungeon when riding, in the same manner as - you would move yourself. It is the beast that you will see displayed + has had to resort to magic and wizardry in order to forge the + alliance. Once you do have the beast under your control however, you + can easily climb in and out of the saddle with the "#ride" command. + Lead the beast around the dungeon when riding, in the same manner as + you would move yourself. It is the beast that you will see displayed on the map. - Riding skill is managed by the "#enhance" command. See the sec- + Riding skill is managed by the "#enhance" command. See the sec- tion on Weapon proficiency for more information about that. - Use the `a' (apply) command and pick a saddle in your inventory + Use the `a' (apply) command and pick a saddle in your inventory to attempt to put that saddle on an adjacent creature. If successful, it will be transferred to that creature's inventory. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2776,63 +2776,63 @@ - Use the "#loot" command while adjacent to a saddled creature to - try to remove the saddle from that creature. If successful, it will + Use the "#loot" command while adjacent to a saddled creature to + try to remove the saddle from that creature. If successful, it will be transferred to your inventory. 6.4. Bones levels You may encounter the shades and corpses of other adventurers (or - even former incarnations of yourself!) and their personal effects. - Ghosts are hard to kill, but easy to avoid, since they're slow and do + even former incarnations of yourself!) and their personal effects. + Ghosts are hard to kill, but easy to avoid, since they're slow and do little damage. You can plunder the deceased adventurer's possessions; - however, they are likely to be cursed. Beware of whatever killed the - former player; it is probably still lurking around, gloating over its + however, they are likely to be cursed. Beware of whatever killed the + former player; it is probably still lurking around, gloating over its last victory. 6.5. Persistence of Monsters - Monsters (a generic reference which also includes humans and + Monsters (a generic reference which also includes humans and pets) are only shown while they can be seen or otherwise sensed. Mov- ing to a location where you can't see or sense a monster any more will - result in it disappearing from your map, similarly if it is the one + result in it disappearing from your map, similarly if it is the one who moved rather than you. - However, if you encounter a monster which you can't see or + However, if you encounter a monster which you can't see or sense--perhaps it is invisible and has just tapped you on the noggin-- a special "remembered, unseen monster" marker will be displayed at the - location where you think it is. That will persist until you have - proven that there is no monster there, even if the unseen monster - moves to another location or you move to a spot where the marker's + location where you think it is. That will persist until you have + proven that there is no monster there, even if the unseen monster + moves to another location or you move to a spot where the marker's location ordinarily wouldn't be seen any more. 7. Objects - When you find something in the dungeon, it is common to want to - pick it up. In NetHack, this is accomplished by using the `,' com- - mand. If autopickup option is on, you will automatically pick up the + When you find something in the dungeon, it is common to want to + pick it up. In NetHack, this is accomplished by using the `,' com- + mand. If autopickup option is on, you will automatically pick up the object by walking over, unless you move with the `m' prefix. - If you're carrying too many items, NetHack will tell you so and - you won't be able to pick up anything more. Otherwise, it will add + If you're carrying too many items, NetHack will tell you so and + you won't be able to pick up anything more. Otherwise, it will add the object(s) to your pack and tell you what you just picked up. - As you add items to your inventory, you also add the weight of - that object to your load. The amount that you can carry depends on - your strength and your constitution. The stronger and sturdier you - are, the less the additional load will affect you. There comes a - point, though, when the weight of all of that stuff you are carrying + As you add items to your inventory, you also add the weight of + that object to your load. The amount that you can carry depends on + your strength and your constitution. The stronger and sturdier you + are, the less the additional load will affect you. There comes a + point, though, when the weight of all of that stuff you are carrying around with you through the dungeon will encumber you. Your reactions - will get slower and you'll burn calories faster, requiring food more - frequently to cope with it. Eventually, you'll be so overloaded that + will get slower and you'll burn calories faster, requiring food more + frequently to cope with it. Eventually, you'll be so overloaded that you'll either have to discard some of what you're carrying or collapse under its weight. NetHack will tell you how badly you have loaded yourself. If you - are encumbered, one of the conditions Burdened, Stressed, Strained, + are encumbered, one of the conditions Burdened, Stressed, Strained, - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2842,63 +2842,63 @@ - Overtaxed, or Overloaded will be shown on the bottom line status dis- + Overtaxed, or Overloaded will be shown on the bottom line status dis- play. - When you pick up an object, it is assigned an inventory letter. - Many commands that operate on objects must ask you to find out which - object you want to use. When NetHack asks you to choose a particular - object you are carrying, you are usually presented with a list of + When you pick up an object, it is assigned an inventory letter. + Many commands that operate on objects must ask you to find out which + object you want to use. When NetHack asks you to choose a particular + object you are carrying, you are usually presented with a list of inventory letters to choose from (see Commands, above). - Some objects, such as weapons, are easily differentiated. Oth- - ers, like scrolls and potions, are given descriptions which vary - according to type. During a game, any two objects with the same - description are the same type. However, the descriptions will vary + Some objects, such as weapons, are easily differentiated. Oth- + ers, like scrolls and potions, are given descriptions which vary + according to type. During a game, any two objects with the same + description are the same type. However, the descriptions will vary from game to game. - When you use one of these objects, if its effect is obvious, - NetHack will remember what it is for you. If its effect isn't - extremely obvious, you will be asked what you want to call this type - of object so you will recognize it later. You can also use the + When you use one of these objects, if its effect is obvious, + NetHack will remember what it is for you. If its effect isn't + extremely obvious, you will be asked what you want to call this type + of object so you will recognize it later. You can also use the "#name" command, for the same purpose at any time, to name all objects - of a particular type or just an individual object. When you use - "#name" on an object which has already been named, specifying a space - as the value will remove the prior name instead of assigning a new + of a particular type or just an individual object. When you use + "#name" on an object which has already been named, specifying a space + as the value will remove the prior name instead of assigning a new one. 7.1. Curses and Blessings - Any object that you find may be cursed, even if the object is - otherwise helpful. The most common effect of a curse is being stuck - with (and to) the item. Cursed weapons weld themselves to your hand + Any object that you find may be cursed, even if the object is + otherwise helpful. The most common effect of a curse is being stuck + with (and to) the item. Cursed weapons weld themselves to your hand when wielded, so you cannot unwield them. Any cursed item you wear is - not removable by ordinary means. In addition, cursed arms and armor - usually, but not always, bear negative enchantments that make them - less effective in combat. Other cursed objects may act poorly or + not removable by ordinary means. In addition, cursed arms and armor + usually, but not always, bear negative enchantments that make them + less effective in combat. Other cursed objects may act poorly or detrimentally in other ways. - Objects can also be blessed instead. Blessed items usually work - better or more beneficially than normal uncursed items. For example, + Objects can also be blessed instead. Blessed items usually work + better or more beneficially than normal uncursed items. For example, a blessed weapon will do slightly more damage against demons. - Objects which are neither cursed nor blessed are referred to as + Objects which are neither cursed nor blessed are referred to as uncursed. They could just as easily have been described as unblessed, - but the uncursed designation is what you will see within the game. A + but the uncursed designation is what you will see within the game. A "glass half full versus glass half empty" situation; make of that what you will. - There are magical means of bestowing or removing curses upon - objects, so even if you are stuck with one, you can still have the - curse lifted and the item removed. Priests and Priestesses have an - innate sensitivity to this property in any object, so they can more - easily avoid cursed objects than other character roles. Dropping - objects onto an altar will reveal their bless or curse state provided + There are magical means of bestowing or removing curses upon + objects, so even if you are stuck with one, you can still have the + curse lifted and the item removed. Priests and Priestesses have an + innate sensitivity to this property in any object, so they can more + easily avoid cursed objects than other character roles. Dropping + objects onto an altar will reveal their bless or curse state provided that you can see them land. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2908,44 +2908,44 @@ - An item with unknown status will be reported in your inventory - with no prefix. An item which you know the state of will be distin- - guished in your inventory by the presence of the word cursed, - uncursed, or blessed in the description of the item. In some cases + An item with unknown status will be reported in your inventory + with no prefix. An item which you know the state of will be distin- + guished in your inventory by the presence of the word cursed, + uncursed, or blessed in the description of the item. In some cases uncursed will be omitted as being redundant when enough other informa- - tion is displayed. The implicit_uncursed option can be used to con- - trol this; toggle it off to have uncursed be displayed even when that + tion is displayed. The implicit_uncursed option can be used to con- + trol this; toggle it off to have uncursed be displayed even when that can be deduced from other attributes. - Sometimes the bless or curse state of objects is referred to as - their "BUC" attribute, for Blessed, Uncursed, or Cursed state, or + Sometimes the bless or curse state of objects is referred to as + their "BUC" attribute, for Blessed, Uncursed, or Cursed state, or "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term beatitude is occasionally used as well.) 7.2. Artifacts - Some objects have been imbued with special powers and are known - as Artifacts. They have specific types (such as long sword or orcish + Some objects have been imbued with special powers and are known + as Artifacts. They have specific types (such as long sword or orcish dagger) and distinct names such as Giantslayer or Grimtooth. Artifact - weapons typically do more damage than their ordinary counterparts. - Some do extra damage against all monsters, others only against spe- - cific types of monsters so aren't better than regular weapons against - other types. Some confer defensive capabilities when wielded or have + weapons typically do more damage than their ordinary counterparts. + Some do extra damage against all monsters, others only against spe- + cific types of monsters so aren't better than regular weapons against + other types. Some confer defensive capabilities when wielded or have other powers that aren't listed here. - You might find them simply lying on the floor, including but not - limited to inside shops, or be granted as a reward for "#offer" on an - altar to your patron deity. A few might be dropped by monsters, or - might be converted from an ordinary object of the same type via - assigning the right name. Or you might wish for them, if you happen + You might find them simply lying on the floor, including but not + limited to inside shops, or be granted as a reward for "#offer" on an + altar to your patron deity. A few might be dropped by monsters, or + might be converted from an ordinary object of the same type via + assigning the right name. Or you might wish for them, if you happen to be granted a wish, but such wishes can fail. - Some artifacts have a specific alignment, others don't. You - won't obtain aligned ones that have a different alignment from yours - via offering and might get a shock if you attempt to wish for any of + Some artifacts have a specific alignment, others don't. You + won't obtain aligned ones that have a different alignment from yours + via offering and might get a shock if you attempt to wish for any of those or find one and attempt to use it. - Each role has a distinct artifact that is contained in the Quest + Each role has a distinct artifact that is contained in the Quest dungeon branch. These are commonly known as quest artifacts. All are aligned and most are non-weapons. They won't be found randomly. @@ -2955,16 +2955,16 @@ 7.3. Relics There are three unique items that are named and have limited spe- - cial powers but aren't classified as artifacts. Each is guarded by a - particular monster and you'll need to collect all three for use late - in the game. They are the Bell of Opening, the Book of the Dead, and - the Candelabrum of Invocation. Their corresponding descriptions when - not yet identified are silver bell, papyrus spellbook, and cande- + cial powers but aren't classified as artifacts. Each is guarded by a + particular monster and you'll need to collect all three for use late + in the game. They are the Bell of Opening, the Book of the Dead, and + the Candelabrum of Invocation. Their corresponding descriptions when + not yet identified are silver bell, papyrus spellbook, and cande- labrum. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -2976,61 +2976,61 @@ 7.4. Weapons (`)') - Given a chance, most monsters in the Mazes of Menace will gratu- - itously try to kill you. You need weapons for self-defense (killing - them first). Without a weapon, you do only 1-2 hit points of damage - (plus bonuses, if any). Monk characters are an exception; they nor- - mally do more damage with bare (or gloved) hands than they do with + Given a chance, most monsters in the Mazes of Menace will gratu- + itously try to kill you. You need weapons for self-defense (killing + them first). Without a weapon, you do only 1-2 hit points of damage + (plus bonuses, if any). Monk characters are an exception; they nor- + mally do more damage with bare (or gloved) hands than they do with weapons. - There are wielded weapons, like maces and swords, and thrown - weapons, like arrows and spears. To hit monsters with a weapon, you - must wield it and attack them, or throw it at them. You can simply - elect to throw a spear. To shoot an arrow, you should first wield a - bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings + There are wielded weapons, like maces and swords, and thrown + weapons, like arrows and spears. To hit monsters with a weapon, you + must wield it and attack them, or throw it at them. You can simply + elect to throw a spear. To shoot an arrow, you should first wield a + bow, then throw the arrow. Crossbows shoot crossbow bolts. Slings hurl rocks and (other) stones (like gems). - Enchanted weapons have a "plus" (or "to hit enhancement" which - can be either positive or negative) that adds to your chance to hit - and the damage you do to a monster. The only way to determine a + Enchanted weapons have a "plus" (or "to hit enhancement" which + can be either positive or negative) that adds to your chance to hit + and the damage you do to a monster. The only way to determine a weapon's enchantment is to have it magically identified somehow. Most - weapons are subject to some type of damage like rust. Such "erosion" + weapons are subject to some type of damage like rust. Such "erosion" damage can be repaired. - The chance that an attack will successfully hit a monster, and - the amount of damage such a hit will do, depends upon many factors. - Among them are: type of weapon, quality of weapon (enchantment and/or + The chance that an attack will successfully hit a monster, and + the amount of damage such a hit will do, depends upon many factors. + Among them are: type of weapon, quality of weapon (enchantment and/or erosion), experience level, strength, dexterity, encumbrance, and pro- - ficiency (see below). The monster's armor class--a general defense - rating, not necessarily due to wearing of armor--is a factor too; - also, some monsters are particularly vulnerable to certain types of + ficiency (see below). The monster's armor class--a general defense + rating, not necessarily due to wearing of armor--is a factor too; + also, some monsters are particularly vulnerable to certain types of weapons. Many weapons can be wielded in one hand; some require both hands. When wielding a two-handed weapon, you can not wear a shield, and vice versa. When wielding a one-handed weapon, you can have another weapon - ready to use by setting things up with the `x' command, which - exchanges your primary (the one being wielded) and alternate weapons. - And if you have proficiency in the "two weapon combat" skill, you may - wield both weapons simultaneously as primary and secondary; use the - `X' command to engage or disengage that. Only some types of charac- - ters (barbarians, for instance) have the necessary skill available. - Even with that skill, using two weapons at once incurs a penalty in - the chance to hit your target compared to using just one weapon at a + ready to use by setting things up with the `x' command, which + exchanges your primary (the one being wielded) and alternate weapons. + And if you have proficiency in the "two weapon combat" skill, you may + wield both weapons simultaneously as primary and secondary; use the + `X' command to engage or disengage that. Only some types of charac- + ters (barbarians, for instance) have the necessary skill available. + Even with that skill, using two weapons at once incurs a penalty in + the chance to hit your target compared to using just one weapon at a time. - There might be times when you'd rather not wield any weapon at + There might be times when you'd rather not wield any weapon at all. To accomplish that, wield `-', or else use the `A' command which - allows you to unwield the current weapon in addition to taking off + allows you to unwield the current weapon in addition to taking off other worn items. - Those of you in the audience who are AD&D players, be aware that + Those of you in the audience who are AD&D players, be aware that each weapon which existed in AD&D does roughly the same damage to mon- - sters in NetHack. Some of the more obscure weapons (such as the + sters in NetHack. Some of the more obscure weapons (such as the aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3042,61 +3042,61 @@ Unearthed Arcana, an AD&D supplement. - Some interfaces support the weaponstatus option. When it is - enabled, an extra status condition is displayed, describing the cur- + Some interfaces support the weaponstatus option. When it is + enabled, an extra status condition is displayed, describing the cur- rently wielded weapon. - The commands to use weapons are `w' (wield), `t' (throw), `f' - (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" + The commands to use weapons are `w' (wield), `t' (throw), `f' + (fire), `Q' (quiver), `x' (exchange), `X' (twoweapon), and "#enhance" (see below). 7.4.1. Throwing and shooting - You can throw just about anything via the `t' command. It will - prompt for the item to throw; picking `?' will list things in your - inventory which are considered likely to be thrown, or picking `*' - will list your entire inventory. After you've chosen what to throw, - you will be prompted for a direction rather than for a specific tar- - get. The distance something can be thrown depends mainly on the type + You can throw just about anything via the `t' command. It will + prompt for the item to throw; picking `?' will list things in your + inventory which are considered likely to be thrown, or picking `*' + will list your entire inventory. After you've chosen what to throw, + you will be prompted for a direction rather than for a specific tar- + get. The distance something can be thrown depends mainly on the type of object and your strength. Arrows can be thrown by hand, but can be - thrown much farther and will be more likely to hit when thrown while + thrown much farther and will be more likely to hit when thrown while you are wielding a bow. - Some weapons will return when thrown. A boomerang--provided it - fails to hit anything--is an obvious example. If an aklys (thonged - club) is thrown while it is wielded, it will return even when it hits - something. A sufficiently strong hero can throw the warhammer Mjoll- - nir; when thrown by a Valkyrie it will return too. However, aklyses - and Mjollnir occasionally fail to return. Returning thrown objects - occasionally fail to be caught, sometimes even hitting the thrower, + Some weapons will return when thrown. A boomerang--provided it + fails to hit anything--is an obvious example. If an aklys (thonged + club) is thrown while it is wielded, it will return even when it hits + something. A sufficiently strong hero can throw the warhammer Mjoll- + nir; when thrown by a Valkyrie it will return too. However, aklyses + and Mjollnir occasionally fail to return. Returning thrown objects + occasionally fail to be caught, sometimes even hitting the thrower, but when caught they become re-wielded. - You can simplify the throwing operation by using the `Q' command - to select your preferred "missile", then using the `f' command to - throw it. You'll be prompted for a direction as above, but you don't - have to specify which item to throw each time you use `f'. There is - also an option, autoquiver, which has NetHack choose another item to - automatically fill your quiver (or quiver sack, or have at the ready) - when the inventory slot used for `Q' runs out. If your quiver is - empty, autoquiver is false, and you are wielding a weapon which + You can simplify the throwing operation by using the `Q' command + to select your preferred "missile", then using the `f' command to + throw it. You'll be prompted for a direction as above, but you don't + have to specify which item to throw each time you use `f'. There is + also an option, autoquiver, which has NetHack choose another item to + automatically fill your quiver (or quiver sack, or have at the ready) + when the inventory slot used for `Q' runs out. If your quiver is + empty, autoquiver is false, and you are wielding a weapon which returns when thrown, you will throw that weapon instead of filling the - quiver. The fire command also has extra assistance, if fireassist is + quiver. The fire command also has extra assistance, if fireassist is on it will try to wield a launcher matching the ammo in the quiver. - Some characters have the ability to throw or shoot a volley of - multiple items (from the same stack) in a single action. Knowing how + Some characters have the ability to throw or shoot a volley of + multiple items (from the same stack) in a single action. Knowing how to load several rounds of ammunition at once--or hold several missiles in your hand--and still hit a target is not an easy task. Rangers are among those who are adept at this task, as are those with a high level - of proficiency in the relevant weapon skill (in bow skill if you're + of proficiency in the relevant weapon skill (in bow skill if you're wielding one to shoot arrows, in crossbow skill if you're wielding one - to shoot bolts, or in sling skill if you're wielding one to shoot - stones). The number of items that the character has a chance to fire - varies from turn to turn. You can explicitly limit the number of - shots by using a numeric prefix before the `t' or `f' command. For + to shoot bolts, or in sling skill if you're wielding one to shoot + stones). The number of items that the character has a chance to fire + varies from turn to turn. You can explicitly limit the number of + shots by using a numeric prefix before the `t' or `f' command. For - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3108,61 +3108,61 @@ example, "2f" (or "n2f" if using number_pad mode) would ensure that at most 2 arrows are shot even if you could have fired 3. If you specify - a larger number than would have been shot ("4f" in this example), - you'll just end up shooting the same number (3, here) as if no limit - had been specified. Once the volley is in motion, all of the items - will travel in the same direction; if the first ones kill a monster, + a larger number than would have been shot ("4f" in this example), + you'll just end up shooting the same number (3, here) as if no limit + had been specified. Once the volley is in motion, all of the items + will travel in the same direction; if the first ones kill a monster, the others can still continue beyond that spot. 7.4.2. Weapon proficiency - You will have varying degrees of skill in the weapons available. + You will have varying degrees of skill in the weapons available. Weapon proficiency, or weapon skills, affect how well you can use par- ticular types of weapons, and you'll be able to improve your skills as - you progress through a game, depending on your role, your experience + you progress through a game, depending on your role, your experience level, and use of the weapons. - For the purposes of proficiency, weapons have been divided up - into various groups such as daggers, broadswords, and polearms. Each - role has a limit on what level of proficiency a character can achieve - for each group. For instance, wizards can become highly skilled in + For the purposes of proficiency, weapons have been divided up + into various groups such as daggers, broadswords, and polearms. Each + role has a limit on what level of proficiency a character can achieve + for each group. For instance, wizards can become highly skilled in daggers or staves but not in swords or bows. The "#enhance" extended command is used to review current weapons - proficiency (also spell proficiency) and to choose which skill(s) to - improve when you've used one or more skills enough to become eligible - to do so. The skill rankings are "none" (sometimes also referred to - as "restricted", because you won't be able to advance), "unskilled", - "basic", "skilled", and "expert". Restricted skills simply will not - appear in the list shown by "#enhance". (Divine intervention might - unrestrict a particular skill, in which case it will start at + proficiency (also spell proficiency) and to choose which skill(s) to + improve when you've used one or more skills enough to become eligible + to do so. The skill rankings are "none" (sometimes also referred to + as "restricted", because you won't be able to advance), "unskilled", + "basic", "skilled", and "expert". Restricted skills simply will not + appear in the list shown by "#enhance". (Divine intervention might + unrestrict a particular skill, in which case it will start at unskilled and be limited to basic.) Some characters can enhance their - barehanded combat or martial arts skill beyond expert to "master" or + barehanded combat or martial arts skill beyond expert to "master" or "grand master". - Use of a weapon in which you're restricted or unskilled will - incur a modest penalty in the chance to hit a monster and also in the - amount of damage done when you do hit; at basic level, there is no - penalty or bonus; at skilled level, you receive a modest bonus in the + Use of a weapon in which you're restricted or unskilled will + incur a modest penalty in the chance to hit a monster and also in the + amount of damage done when you do hit; at basic level, there is no + penalty or bonus; at skilled level, you receive a modest bonus in the chance to hit and amount of damage done; at expert level, the bonus is - higher. A successful hit has a chance to boost your training towards + higher. A successful hit has a chance to boost your training towards the next skill level (unless you've already reached the limit for this skill). Once such training reaches the threshold for that next level, - you'll be told that you feel more confident in your skills. At that - point you can use "#enhance" to increase one or more skills. Such - skills are not increased automatically because there is a limit to + you'll be told that you feel more confident in your skills. At that + point you can use "#enhance" to increase one or more skills. Such + skills are not increased automatically because there is a limit to your total overall skills, so you need to actively choose which skills to enhance and which to ignore. 7.4.3. Two-Weapon combat - Some characters can use two weapons at once. Setting things up - to do so can seem cumbersome but becomes second nature with use. To - wield two weapons, you need to use the "#twoweapon" command. But - first you need to have a weapon in each hand. (Note that your two + Some characters can use two weapons at once. Setting things up + to do so can seem cumbersome but becomes second nature with use. To + wield two weapons, you need to use the "#twoweapon" command. But + first you need to have a weapon in each hand. (Note that your two - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3172,44 +3172,44 @@ - weapons are not fully equal; the one in the hand you normally wield - with is considered primary and the other one is considered secondary. + weapons are not fully equal; the one in the hand you normally wield + with is considered primary and the other one is considered secondary. The most noticeable difference is after you stop--or before you begin, - for that matter--wielding two weapons at once. The primary is your - wielded weapon and the secondary is just an item in your inventory + for that matter--wielding two weapons at once. The primary is your + wielded weapon and the secondary is just an item in your inventory that's been designated as alternate weapon.) - If your primary weapon is wielded but your off hand is empty or - has the wrong weapon, use the sequence `x', `w', `x' to first swap - your primary into your off hand, wield whatever you want as secondary - weapon, then swap them both back into the intended hands. If your - secondary or alternate weapon is correct but your primary one is not, - simply use `w' to wield the primary. Lastly, if neither hand holds + If your primary weapon is wielded but your off hand is empty or + has the wrong weapon, use the sequence `x', `w', `x' to first swap + your primary into your off hand, wield whatever you want as secondary + weapon, then swap them both back into the intended hands. If your + secondary or alternate weapon is correct but your primary one is not, + simply use `w' to wield the primary. Lastly, if neither hand holds the correct weapon, use `w', `x', `w' to first wield the intended sec- ondary, swap it to off hand, and then wield the primary. - The whole process can be simplified via use of the pushweapon - option. When it is enabled, then using `w' to wield something causes - the currently wielded weapon to become your alternate weapon. So the - sequence `w', `w' can be used to first wield the weapon you intend to - be secondary, and then wield the one you want as primary which will + The whole process can be simplified via use of the pushweapon + option. When it is enabled, then using `w' to wield something causes + the currently wielded weapon to become your alternate weapon. So the + sequence `w', `w' can be used to first wield the weapon you intend to + be secondary, and then wield the one you want as primary which will push the first into secondary position. - When in two-weapon combat mode, using the `X' command toggles - back to single-weapon mode. Throwing or dropping either of the weap- - ons or having one of them be stolen or destroyed will also make you + When in two-weapon combat mode, using the `X' command toggles + back to single-weapon mode. Throwing or dropping either of the weap- + ons or having one of them be stolen or destroyed will also make you revert to single-weapon combat. 7.5. Armor (`[') - Lots of unfriendly things lurk about; you need armor to protect - yourself from their blows. Some types of armor offer better protec- - tion than others. Your armor class is a measure of this protection. - Armor class (AC) is measured as in AD&D, with 10 being the equivalent - of no armor, and lower numbers meaning better armor. Each suit of + Lots of unfriendly things lurk about; you need armor to protect + yourself from their blows. Some types of armor offer better protec- + tion than others. Your armor class is a measure of this protection. + Armor class (AC) is measured as in AD&D, with 10 being the equivalent + of no armor, and lower numbers meaning better armor. Each suit of armor which exists in AD&D gives the same protection in NetHack. - Here is a list of the armor class values provided by suits of + Here is a list of the armor class values provided by suits of armor: Dragon scale mail 1 Plate mail, Crystal plate mail 3 @@ -3223,12 +3223,12 @@ Leather jacket 9 none 10 - You can also wear other pieces of armor (cloak over suit, shirt - under suit, helmet, gloves, boots, shield) to lower your armor class + You can also wear other pieces of armor (cloak over suit, shirt + under suit, helmet, gloves, boots, shield) to lower your armor class even further. Most of these provide a one or two point improvement to - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3238,63 +3238,63 @@ - AC (making the overall value smaller and eventually negative) but can - also be enchanted. Shirts are an exception; they don't provide any - protection unless enchanted. Some cloaks also don't improve AC when - unenchanted but all cloaks offer some protection against rust or cor- - rosion to suits worn under them and against some monster touch + AC (making the overall value smaller and eventually negative) but can + also be enchanted. Shirts are an exception; they don't provide any + protection unless enchanted. Some cloaks also don't improve AC when + unenchanted but all cloaks offer some protection against rust or cor- + rosion to suits worn under them and against some monster touch attacks. - If a piece of armor is enchanted, its armor protection will be + If a piece of armor is enchanted, its armor protection will be better (or worse) than normal, and its "plus" (or minus) will subtract - from your armor class. For example, a +1 chain mail would give you - better protection than normal chain mail, lowering your armor class - one unit further to 4. When you put on a piece of armor, you immedi- - ately find out the armor class and any "plusses" it provides. Cursed - pieces of armor usually have negative enchantments (minuses) in addi- + from your armor class. For example, a +1 chain mail would give you + better protection than normal chain mail, lowering your armor class + one unit further to 4. When you put on a piece of armor, you immedi- + ately find out the armor class and any "plusses" it provides. Cursed + pieces of armor usually have negative enchantments (minuses) in addi- tion to being unremovable. Many types of armor are subject to some kind of damage like rust. - Such damage can be repaired. Some types of armor may inhibit spell + Such damage can be repaired. Some types of armor may inhibit spell casting. - The nudist option can be set (prior to game start) to attempt to - play the entire game without wearing any armor (a self-imposed chal- + The nudist option can be set (prior to game start) to attempt to + play the entire game without wearing any armor (a self-imposed chal- lenge which is extremely difficult to accomplish). - Some interfaces support the armorstatus option. When it is + Some interfaces support the armorstatus option. When it is enabled, an extra status condition is displayed, summarizing currently worn armor. The commands to use armor are `W' (wear) and `T' (take off). The `A' command can be used to take off armor as well as other worn items. Also, `P' (put on) and `R' (remove) which are normally for accessories - can be used for armor, but pieces of armor won't be shown as likely + can be used for armor, but pieces of armor won't be shown as likely candidates in a prompt for choosing what to put on or remove. 7.6. Food (`%') - Food is necessary to survive. If you go too long without eating - you will faint, and eventually die of starvation. Some types of food - will spoil, and become unhealthy to eat, if not protected. Food - stored in ice boxes or tins ("cans") will usually stay fresh, but ice + Food is necessary to survive. If you go too long without eating + you will faint, and eventually die of starvation. Some types of food + will spoil, and become unhealthy to eat, if not protected. Food + stored in ice boxes or tins ("cans") will usually stay fresh, but ice boxes are heavy, and tins take a while to open. When you kill monsters, they usually leave corpses which are also - "food." Many, but not all, of these are edible; some also give you - special powers when you eat them. A good rule of thumb is "you are + "food." Many, but not all, of these are edible; some also give you + special powers when you eat them. A good rule of thumb is "you are what you eat." - Some character roles and some monsters are vegetarian. Vegetar- + Some character roles and some monsters are vegetarian. Vegetar- ian monsters will typically never eat animal corpses, while vegetarian players can, but with some rather unpleasant side-effects. - You can name one food item after something you like to eat with + You can name one food item after something you like to eat with the fruit option. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3308,33 +3308,33 @@ 7.7. Scrolls (`?') - Scrolls are labeled with various titles, probably chosen by - ancient wizards for their amusement value (for example "READ ME," or - "THANX MAUD" backwards). Scrolls disappear after you read them + Scrolls are labeled with various titles, probably chosen by + ancient wizards for their amusement value (for example "READ ME," or + "THANX MAUD" backwards). Scrolls disappear after you read them (except for blank ones, without magic spells on them). - One of the most useful of these is the scroll of identify, which - can be used to determine what another object is, whether it is cursed - or blessed, and how many uses it has left. Some objects of subtle + One of the most useful of these is the scroll of identify, which + can be used to determine what another object is, whether it is cursed + or blessed, and how many uses it has left. Some objects of subtle enchantment are difficult to identify without these. - A scroll whose label is known can be read even when the hero is - blind. If a scroll has been discovered, it will be listed in inven- + A scroll whose label is known can be read even when the hero is + blind. If a scroll has been discovered, it will be listed in inven- tory by type rather than by label, but the label is known in that sit- uation even though it isn't shown. - Many scrolls produce a different effect from usual if they are + Many scrolls produce a different effect from usual if they are blessed or cursed, or read while the hero is confused. - A mail daemon may run up and deliver mail to you as a scroll of + A mail daemon may run up and deliver mail to you as a scroll of mail (on versions compiled with this feature). To use this feature on - versions where NetHack mail delivery is triggered by electronic mail - appearing in your system mailbox, you must let NetHack know where to - look for new mail by setting the "MAIL" environment variable to the - file name of your mailbox. You may also want to set the "MAILREADER" - environment variable to the file name of your favorite reader, so - NetHack can shell to it when you read the scroll. On versions of - NetHack where mail is randomly generated internal to the game, these + versions where NetHack mail delivery is triggered by electronic mail + appearing in your system mailbox, you must let NetHack know where to + look for new mail by setting the "MAIL" environment variable to the + file name of your mailbox. You may also want to set the "MAILREADER" + environment variable to the file name of your favorite reader, so + NetHack can shell to it when you read the scroll. On versions of + NetHack where mail is randomly generated internal to the game, these environment variables are ignored. You can disable the mail daemon by turning off the mail option. @@ -3342,13 +3342,13 @@ 7.8. Potions (`!') - Potions are distinguished by the color of the liquid inside the + Potions are distinguished by the color of the liquid inside the flask. They disappear after you quaff them. - Clear potions are potions of water. Sometimes these are blessed - or cursed, resulting in holy or unholy water. Holy water is the bane + Clear potions are potions of water. Sometimes these are blessed + or cursed, resulting in holy or unholy water. Holy water is the bane of the undead, so potions of holy water are good things to throw (`t') - at them. It is also sometimes very useful to dip ("#dip") an object + at them. It is also sometimes very useful to dip ("#dip") an object into a potion. The command to drink a potion is `q' (quaff). @@ -3356,11 +3356,11 @@ 7.9. Wands (`/') Wands usually have multiple magical charges. Some types of wands - require a direction in which to zap them. You can also zap them at - yourself (just give a `.' or `s' for the direction). Be warned, how- + require a direction in which to zap them. You can also zap them at + yourself (just give a `.' or `s' for the direction). Be warned, how- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3370,63 +3370,63 @@ - ever, for this is often unwise. Other types of wands don't require a + ever, for this is often unwise. Other types of wands don't require a direction. The number of charges in a wand is random and decreases by one whenever you use it. - When the number of charges left in a wand becomes zero, attempts - to use the wand will usually result in nothing happening. Occasion- - ally, however, it may be possible to squeeze the last few mana points - from an otherwise spent wand, destroying it in the process. A wand - may be recharged by using suitable magic, but doing so runs the risk + When the number of charges left in a wand becomes zero, attempts + to use the wand will usually result in nothing happening. Occasion- + ally, however, it may be possible to squeeze the last few mana points + from an otherwise spent wand, destroying it in the process. A wand + may be recharged by using suitable magic, but doing so runs the risk of causing it to explode. The chance for such an explosion starts out very small and increases each time the wand is recharged. - In a truly desperate situation, when your back is up against the - wall, you might decide to go for broke and break your wand. This is - not for the faint of heart. Doing so will almost certainly cause a + In a truly desperate situation, when your back is up against the + wall, you might decide to go for broke and break your wand. This is + not for the faint of heart. Doing so will almost certainly cause a catastrophic release of magical energies. - When you have fully identified a particular wand, inventory dis- + When you have fully identified a particular wand, inventory dis- play will include additional information in parentheses: the number of - times it has been recharged followed by a colon and then by its cur- - rent number of charges. A current charge count of -1 is a special + times it has been recharged followed by a colon and then by its cur- + rent number of charges. A current charge count of -1 is a special case indicating that the wand has been cancelled. - The command to use a wand is `z' (zap). To break one, use the + The command to use a wand is `z' (zap). To break one, use the `a' (apply) command. 7.10. Rings (`=') - Rings are very useful items, since they are relatively permanent - magic, unlike the usually fleeting effects of potions, scrolls, and + Rings are very useful items, since they are relatively permanent + magic, unlike the usually fleeting effects of potions, scrolls, and wands. - Putting on a ring activates its magic. You can wear at most two + Putting on a ring activates its magic. You can wear at most two rings at any time, one on the ring finger of each hand. - Most worn rings also cause you to grow hungry more rapidly, the + Most worn rings also cause you to grow hungry more rapidly, the rate varying with the type of ring. - When wearing gloves, rings are worn underneath. If the gloves - are cursed, rings cannot be put on and any already being worn cannot - be removed. When worn gloves aren't cursed, you don't have to manu- - ally take them off before putting on or removing a ring and then re- + When wearing gloves, rings are worn underneath. If the gloves + are cursed, rings cannot be put on and any already being worn cannot + be removed. When worn gloves aren't cursed, you don't have to manu- + ally take them off before putting on or removing a ring and then re- wear them after. That's done implicitly to avoid unnecessary tedium. - The commands to use rings are `P' (put on) and `R' (remove). + The commands to use rings are `P' (put on) and `R' (remove). `A', `W', and `T' can also be used; see Amulets. 7.11. Spellbooks (`+') - Spellbooks are tomes of mighty magic. When studied with the `r' - (read) command, they transfer to the reader the knowledge of a spell + Spellbooks are tomes of mighty magic. When studied with the `r' + (read) command, they transfer to the reader the knowledge of a spell (and therefore eventually become unreadable)--unless the attempt back- - fires. Reading a cursed spellbook or one with mystic runes beyond + fires. Reading a cursed spellbook or one with mystic runes beyond your ken can be harmful to your health! - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3436,63 +3436,63 @@ - A spell (even when learned) can also backfire when you cast it. + A spell (even when learned) can also backfire when you cast it. If you attempt to cast a spell well above your experience level, or if you have little skill with the appropriate spell type, or cast it at a - time when your luck is particularly bad, you can end up wasting both + time when your luck is particularly bad, you can end up wasting both the energy and the time required in casting. - Casting a spell calls forth magical energies and focuses them - with your naked mind. Some of the magical energy released comes from + Casting a spell calls forth magical energies and focuses them + with your naked mind. Some of the magical energy released comes from within you. Casting temporarily drains your magical power, which will - slowly be recovered, and causes you to need additional food. Casting - of spells also requires practice. With practice, your skill in each + slowly be recovered, and causes you to need additional food. Casting + of spells also requires practice. With practice, your skill in each category of spell casting will improve. Over time, however, your mem- ory of each spell will dim, and you will need to relearn it. Some spells require a direction in which to cast them, similar to wands. To cast one at yourself, just give a `.' or `s' for the direc- - tion. A few spells require you to pick a target location rather than - just specify a particular direction. Other spells don't require any + tion. A few spells require you to pick a target location rather than + just specify a particular direction. Other spells don't require any direction or target. - Just as weapons are divided into groups in which a character can - become proficient (to varying degrees), spells are similarly grouped. - Successfully casting a spell exercises its skill group; using the - "#enhance" command to advance a sufficiently exercised skill will - affect all spells within the group. Advanced skill may increase the - potency of spells, reduce their risk of failure during casting + Just as weapons are divided into groups in which a character can + become proficient (to varying degrees), spells are similarly grouped. + Successfully casting a spell exercises its skill group; using the + "#enhance" command to advance a sufficiently exercised skill will + affect all spells within the group. Advanced skill may increase the + potency of spells, reduce their risk of failure during casting attempts, and improve the accuracy of the estimate for how much longer - they will be retained in your memory. Skill slots are shared with + they will be retained in your memory. Skill slots are shared with weapons skills. (See also the section on "Weapon proficiency".) Casting a spell also requires flexible movement, and wearing var- ious types of armor may interfere with that. - The command to read a spellbook is the same as for scrolls, `r' - (read). The `+' command lists each spell you know along with its + The command to read a spellbook is the same as for scrolls, `r' + (read). The `+' command lists each spell you know along with its level, skill category, chance of failure when casting, and an estimate - of how strongly it is remembered. The `Z' (cast) command casts a + of how strongly it is remembered. The `Z' (cast) command casts a spell. 7.12. Tools (`(') - Tools are miscellaneous objects with various purposes. Some - tools have a limited number of uses, akin to wand charges. For exam- - ple, lamps burn out after a while. Other tools are containers, which + Tools are miscellaneous objects with various purposes. Some + tools have a limited number of uses, akin to wand charges. For exam- + ple, lamps burn out after a while. Other tools are containers, which objects can be placed into or taken out of. - Some tools (such as a blindfold) can be worn and can be put on - and removed like other accessories (rings, amulets); see Amulets. - Other tools (such as pick-axe) can be wielded as weapons in addition - to being applied for their usual purpose, and in some cases (again, + Some tools (such as a blindfold) can be worn and can be put on + and removed like other accessories (rings, amulets); see Amulets. + Other tools (such as pick-axe) can be wielded as weapons in addition + to being applied for their usual purpose, and in some cases (again, pick-axe) become wielded as a weapon even when applied. - The blind option can be set (prior to game start) to attempt to - play the entire game without being able to see (a self-imposed chal- + The blind option can be set (prior to game start) to attempt to + play the entire game without being able to see (a self-imposed chal- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3508,57 +3508,57 @@ 7.12.1. Containers - You may encounter bags, boxes, and chests in your travels. A + You may encounter bags, boxes, and chests in your travels. A tool of this sort can be opened with the "#loot" extended command when - you are standing on top of it (that is, on the same floor spot), or - with the `a' (apply) command when you are carrying it. However, - chests are often locked, and are in any case unwieldy objects. You - must set one down before unlocking it by using a key or lock-picking - tool with the `a' (apply) command, by kicking it with the `^D' com- - mand, or by using a weapon to force the lock with the "#force" + you are standing on top of it (that is, on the same floor spot), or + with the `a' (apply) command when you are carrying it. However, + chests are often locked, and are in any case unwieldy objects. You + must set one down before unlocking it by using a key or lock-picking + tool with the `a' (apply) command, by kicking it with the `^D' com- + mand, or by using a weapon to force the lock with the "#force" extended command. - Some chests are trapped, causing nasty things to happen when you - unlock or open them. You can check for and try to deactivate traps + Some chests are trapped, causing nasty things to happen when you + unlock or open them. You can check for and try to deactivate traps with the "#untrap" extended command. - When the contents of a container are known, that container will - be described as something like "a sack containing 3 items". In this - example, the 3 refers to number of stacks of compatible items, not to - the total number of individual items. So a sack holding 2 sky blue - potions, 7 arrows, and 350 gold pieces would be described as having 3 - items rather than 10 or 359. And you would need to have 3 unused - inventory slots available in order to take everything out (for the - case where the items you remove don't combine into bigger stacks with + When the contents of a container are known, that container will + be described as something like "a sack containing 3 items". In this + example, the 3 refers to number of stacks of compatible items, not to + the total number of individual items. So a sack holding 2 sky blue + potions, 7 arrows, and 350 gold pieces would be described as having 3 + items rather than 10 or 359. And you would need to have 3 unused + inventory slots available in order to take everything out (for the + case where the items you remove don't combine into bigger stacks with things you're already carrying). If a chest or large box is described as "broken", that means that - it can't be locked rather than that it no longer functions as a con- + it can't be locked rather than that it no longer functions as a con- tainer. - The apply and loot commands allow you to take out and/or put in - an arbitrary number of items in a single operation. If you want to - take everything out of a container, you can use the "#tip" command to - pour the contents onto the floor. This may be your only way to get - things out if your hands are stuck to a cursed two-handed weapon. - When your hands aren't stuck, you have the potential to pour the con- - tents into another container. (As of this writing, the other con- + The apply and loot commands allow you to take out and/or put in + an arbitrary number of items in a single operation. If you want to + take everything out of a container, you can use the "#tip" command to + pour the contents onto the floor. This may be your only way to get + things out if your hands are stuck to a cursed two-handed weapon. + When your hands aren't stuck, you have the potential to pour the con- + tents into another container. (As of this writing, the other con- tainer must be carried rather than on the floor.) 7.13. Amulets (`"') Amulets are very similar to rings, and often more powerful. Like - rings, amulets have various magical properties, some beneficial, some + rings, amulets have various magical properties, some beneficial, some harmful, which are activated by putting them on. - Only one amulet may be worn at a time, around your neck. Like - wearing rings, wearing an amulet affects your metabolism, causing you + Only one amulet may be worn at a time, around your neck. Like + wearing rings, wearing an amulet affects your metabolism, causing you to grow hungry more rapidly. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3568,63 +3568,63 @@ - The commands to use amulets are the same as for rings, `P' (put - on) and `R' (remove). `A' can be used to remove various worn items + The commands to use amulets are the same as for rings, `P' (put + on) and `R' (remove). `A' can be used to remove various worn items including amulets. Also, `W' (wear) and `T' (take off) which are nor- - mally for armor can be used for amulets and other accessories (rings + mally for armor can be used for amulets and other accessories (rings and eyewear), but accessories won't be shown as likely candidates in a prompt for choosing what to wear or take off. 7.14. Gems (`*') - Some gems are valuable, and can be sold for a lot of gold. They - are also a far more efficient way of carrying your riches. Valuable + Some gems are valuable, and can be sold for a lot of gold. They + are also a far more efficient way of carrying your riches. Valuable gems increase your score if you bring them with you when you exit. Other small rocks are also categorized as gems, but they are much - less valuable. All rocks, however, can be used as projectile weapons - (if you have a sling). In the most desperate of cases, you can still + less valuable. All rocks, however, can be used as projectile weapons + (if you have a sling). In the most desperate of cases, you can still throw them by hand. 7.15. Large rocks (``') - Statues and boulders are not particularly useful, and are gener- + Statues and boulders are not particularly useful, and are gener- ally heavy. It is rumored that some statues are not what they seem. - Boulders occasionally block your path. You can push one forward + Boulders occasionally block your path. You can push one forward (by attempting to walk onto its spot) when nothing blocks its path, or - you can smash it into a pile of small rocks with breaking magic or a + you can smash it into a pile of small rocks with breaking magic or a pick-axe. It is possible to move onto a boulder's location if certain conditions are met; ordinarily one of those conditions is that pushing - it any further be blocked. Using the move-without-picking-up prefix - (default key `m') prior to the direction of movement will attempt to - move to a boulder's location without pushing it in addition to the + it any further be blocked. Using the move-without-picking-up prefix + (default key `m') prior to the direction of movement will attempt to + move to a boulder's location without pushing it in addition to the prefix's usual action of suppressing auto-pickup at the destination. - Very large humanoids (giants and their ilk) have been known to + Very large humanoids (giants and their ilk) have been known to pick up boulders and use them as missile weapons. - Unlike boulders, statues can't be pushed, but don't need to be - because they don't block movement. They can be smashed into rocks + Unlike boulders, statues can't be pushed, but don't need to be + because they don't block movement. They can be smashed into rocks though. - For some configurations of the program, statues are no longer - shown as ``' but by the letter representing the monster they depict + For some configurations of the program, statues are no longer + shown as ``' but by the letter representing the monster they depict instead. 7.16. Gold (`$') Gold adds to your score, and you can buy things in shops with it. - There are a number of monsters in the dungeon that may be influenced + There are a number of monsters in the dungeon that may be influenced by the amount of gold you are carrying (shopkeepers aside). - Gold pieces are the only type of object where bless/curse state - does not apply. They're always uncursed but never described as - uncursed even if you turn off the implicit_uncursed option. You can - set the goldX option if you prefer to have gold pieces be treated as + Gold pieces are the only type of object where bless/curse state + does not apply. They're always uncursed but never described as + uncursed even if you turn off the implicit_uncursed option. You can + set the goldX option if you prefer to have gold pieces be treated as - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3634,63 +3634,63 @@ - bless/curse state unknown rather than as known to be uncursed. Only - matters when you're using an object selection prompt that can filter + bless/curse state unknown rather than as known to be uncursed. Only + matters when you're using an object selection prompt that can filter by "BUCX" state. 7.17. Persistence of Objects Normally, if you have seen an object at a particular map location - and move to another location where you can't directly see that object - any more, it will continue to be displayed on your map. That remains - the case even if it is not actually there any more--perhaps a monster + and move to another location where you can't directly see that object + any more, it will continue to be displayed on your map. That remains + the case even if it is not actually there any more--perhaps a monster has picked it up or it has rotted away--until you can see or feel that location again. One notable exception is that if the object gets cov- - ered by the "remembered, unseen monster" marker. When that marker is + ered by the "remembered, unseen monster" marker. When that marker is later removed after you've verified that no monster is there, you will - have forgotten that there was any object there regardless of whether - the unseen monster actually took the object. If the object is still - there, then once you see or feel that location again you will re-dis- + have forgotten that there was any object there regardless of whether + the unseen monster actually took the object. If the object is still + there, then once you see or feel that location again you will re-dis- cover the object and resume remembering it. The situation is the same for a pile of objects, except that only - the top item of the pile is displayed. The hilite_pile option can be + the top item of the pile is displayed. The hilite_pile option can be enabled in order to show an item differently when it is the top one of a pile. 8. Conduct - As if winning NetHack were not difficult enough, certain players - seek to challenge themselves by imposing restrictions on the way they - play the game. The game automatically tracks some of these chal- - lenges, which can be checked at any time with the #conduct command or - at the end of the game. When you perform an action which breaks a - challenge, it will no longer be listed. This gives players extra - "bragging rights" for winning the game with these challenges. Note - that it is perfectly acceptable to win the game without resorting to - these restrictions and that it is unusual for players to adhere to + As if winning NetHack were not difficult enough, certain players + seek to challenge themselves by imposing restrictions on the way they + play the game. The game automatically tracks some of these chal- + lenges, which can be checked at any time with the #conduct command or + at the end of the game. When you perform an action which breaks a + challenge, it will no longer be listed. This gives players extra + "bragging rights" for winning the game with these challenges. Note + that it is perfectly acceptable to win the game without resorting to + these restrictions and that it is unusual for players to adhere to challenges the first time they win the game. - Several of the challenges are related to eating behavior. The + Several of the challenges are related to eating behavior. The most difficult of these is the foodless challenge. Although creatures - can survive long periods of time without food, there is a physiologi- - cal need for water; thus there is no restriction on drinking bever- - ages, even if they provide some minor food benefits. Calling upon + can survive long periods of time without food, there is a physiologi- + cal need for water; thus there is no restriction on drinking bever- + ages, even if they provide some minor food benefits. Calling upon your god for help with starvation does not violate any food challenges either. - A strict vegan diet is one which avoids any food derived from - animals. The primary source of nutrition is fruits and vegetables. - The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') - are also considered to be vegetable matter. Certain human food is + A strict vegan diet is one which avoids any food derived from + animals. The primary source of nutrition is fruits and vegetables. + The corpses and tins of blobs (`b'), jellies (`j'), and fungi (`F') + are also considered to be vegetable matter. Certain human food is prepared without animal products; namely, lembas wafers, cram rations, - food rations (gunyoki), K-rations, and C-rations. Metal or another + food rations (gunyoki), K-rations, and C-rations. Metal or another normally indigestible material eaten while polymorphed into a creature - that can digest it is also considered vegan food. Note however that + that can digest it is also considered vegan food. Note however that eating such items still counts against foodless conduct. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3700,63 +3700,63 @@ - Vegetarians do not eat animals; however, they are less selective - about eating animal byproducts than vegans. In addition to the vegan - items listed above, they may eat any kind of pudding (`P') other than - the black puddings, eggs and food made from eggs (fortune cookies and - pancakes), food made with milk (cream pies and candy bars), and lumps + Vegetarians do not eat animals; however, they are less selective + about eating animal byproducts than vegans. In addition to the vegan + items listed above, they may eat any kind of pudding (`P') other than + the black puddings, eggs and food made from eggs (fortune cookies and + pancakes), food made with milk (cream pies and candy bars), and lumps of royal jelly. Monks are expected to observe a vegetarian diet. Eating any kind of meat violates the vegetarian, vegan, and food- - less conducts. This includes tripe rations, the corpses or tins of + less conducts. This includes tripe rations, the corpses or tins of any monsters not mentioned above, and the various other chunks of meat - found in the dungeon. Swallowing and digesting a monster while poly- - morphed is treated as if you ate the creature's corpse. Eating - leather, dragon hide, or bone items while polymorphed into a creature - that can digest it, or eating monster brains while polymorphed into a - mind flayer, is considered eating an animal, although wax is only an + found in the dungeon. Swallowing and digesting a monster while poly- + morphed is treated as if you ate the creature's corpse. Eating + leather, dragon hide, or bone items while polymorphed into a creature + that can digest it, or eating monster brains while polymorphed into a + mind flayer, is considered eating an animal, although wax is only an animal byproduct. - Regardless of conduct, there will be some items which are indi- + Regardless of conduct, there will be some items which are indi- gestible, and others which are hazardous to eat. Using a swallow-and- - digest attack against a monster is equivalent to eating the monster's - corpse. Please note that the term "vegan" is used here only in the - context of diet. You are still free to choose not to use or wear - items derived from animals (e.g. leather, dragon hide, bone, horns, - coral), but the game will not keep track of this for you. Also note - that "milky" potions may be a translucent white, but they do not con- - tain milk, so they are compatible with a vegan diet. Slime molds or - player-defined "fruits", although they could be anything from "cher- + digest attack against a monster is equivalent to eating the monster's + corpse. Please note that the term "vegan" is used here only in the + context of diet. You are still free to choose not to use or wear + items derived from animals (e.g. leather, dragon hide, bone, horns, + coral), but the game will not keep track of this for you. Also note + that "milky" potions may be a translucent white, but they do not con- + tain milk, so they are compatible with a vegan diet. Slime molds or + player-defined "fruits", although they could be anything from "cher- ries" to "pork chops", are also assumed to be vegan. An atheist is one who rejects religion. This means that you can- not #pray, #offer sacrifices to any god, #turn undead, or #chat with a priest. Particularly selective readers may argue that playing Monk or - Priest characters should violate this conduct; that is a choice left + Priest characters should violate this conduct; that is a choice left to the player. Offering the Amulet of Yendor to your god is necessary to win the game and is not counted against this conduct. You are also - not penalized for being spoken to by an angry god, priest(ess), or + not penalized for being spoken to by an angry god, priest(ess), or other religious figure; a true atheist would hear the words but attach no special meaning to them. - A pauper starts the game with no possessions, no spells, and no + A pauper starts the game with no possessions, no spells, and no weapon or spell skills (and if playing as a knight, your pony will not - have a saddle). Can only be initiated by starting a new game with - OPTIONS=pauper set in your run-time configurtion file or NETHACKOP- - TIONS environment variable. Once the game is underway, you can + have a saddle). Can only be initiated by starting a new game with + OPTIONS=pauper set in your run-time configurtion file or NETHACKOP- + TIONS environment variable. Once the game is underway, you can acquire and use items, spells, and skills in the usual way. - Most players fight with a wielded weapon (or tool intended to be - wielded as a weapon). Another challenge is to win the game without - using such a wielded weapon. You are still permitted to throw, fire, - and kick weapons; use a wand, spell, or other type of item; or fight + Most players fight with a wielded weapon (or tool intended to be + wielded as a weapon). Another challenge is to win the game without + using such a wielded weapon. You are still permitted to throw, fire, + and kick weapons; use a wand, spell, or other type of item; or fight with your hands and feet. - In NetHack, a pacifist refuses to cause the death of any other - monster (i.e. if you would get experience for the death). This is a + In NetHack, a pacifist refuses to cause the death of any other + monster (i.e. if you would get experience for the death). This is a - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3766,55 +3766,55 @@ - particularly difficult challenge, although it is still possible to + particularly difficult challenge, although it is still possible to gain experience by other means. - An illiterate character does not read or write. This includes + An illiterate character does not read or write. This includes reading a scroll, spellbook, fortune cookie message, or t-shirt; writ- - ing a scroll; or making an engraving of anything other than a single - "X" (the traditional signature of an illiterate person). Reading an - engraving, or any item that is absolutely necessary to win the game, - is not counted against this conduct. The identity of scrolls and - spellbooks (and knowledge of spells) in your starting inventory is - assumed to be learned from your teachers prior to the start of the + ing a scroll; or making an engraving of anything other than a single + "X" (the traditional signature of an illiterate person). Reading an + engraving, or any item that is absolutely necessary to win the game, + is not counted against this conduct. The identity of scrolls and + spellbooks (and knowledge of spells) in your starting inventory is + assumed to be learned from your teachers prior to the start of the game and isn't counted. - There is a side-branch to the main dungeon called "Sokoban," - briefly described in the earlier section about Traps. As mentioned - there, the goal is to push boulders into pits and/or holes to plug - those in order to both get the boulders out of the way and be able to - go past the traps. There are some special "rules" that are active - when in that branch of the dungeon. Some rules can't be bypassed, - such as being unable to push a boulder diagonally. Other rules can, + There is a side-branch to the main dungeon called "Sokoban," + briefly described in the earlier section about Traps. As mentioned + there, the goal is to push boulders into pits and/or holes to plug + those in order to both get the boulders out of the way and be able to + go past the traps. There are some special "rules" that are active + when in that branch of the dungeon. Some rules can't be bypassed, + such as being unable to push a boulder diagonally. Other rules can, such as not smashing boulders with magic or tools, but doing so causes - you to receive a luck penalty. No message about that is given at the + you to receive a luck penalty. No message about that is given at the time, but it is tracked as a conduct. The #conduct command and end of - game disclosure will report whether you have abided by the special - rules of Sokoban, and if not, how many times you violated them, pro- + game disclosure will report whether you have abided by the special + rules of Sokoban, and if not, how many times you violated them, pro- viding you with a way to discover which actions incur bad luck so that - you can be better informed about whether or not to avoid repeating + you can be better informed about whether or not to avoid repeating those actions in the future. (Note: the Sokoban conduct will only be displayed if you have entered the Sokoban branch of the dungeon during - the current game. Once that has happened, it becomes part of dis- - closed conduct even if you haven't done anything interesting there. - Ending the game with "never broke the Sokoban rules" conduct is most - meaningful if you also manage to perform the "obtained the Sokoban + the current game. Once that has happened, it becomes part of dis- + closed conduct even if you haven't done anything interesting there. + Ending the game with "never broke the Sokoban rules" conduct is most + meaningful if you also manage to perform the "obtained the Sokoban prize" achievement (see Achievements below).) - There are several other challenges tracked by the game. It is - possible to eliminate one or more species of monsters by genocide; + There are several other challenges tracked by the game. It is + possible to eliminate one or more species of monsters by genocide; playing without this feature is considered a challenge. When the game - offers you an opportunity to genocide monsters, you may respond with - the monster type "none" if you want to decline. You can change the - form of an item into another item of the same type ("polypiling") or - the form of your own body into another creature ("polyself") by wand, + offers you an opportunity to genocide monsters, you may respond with + the monster type "none" if you want to decline. You can change the + form of an item into another item of the same type ("polypiling") or + the form of your own body into another creature ("polyself") by wand, spell, or potion of polymorph; avoiding these effects are each consid- - ered challenges. Polymorphing monsters, including pets, does not - break either of these challenges. Finally, you may sometimes receive - wishes; a game without an attempt to wish for any items is a chal- + ered challenges. Polymorphing monsters, including pets, does not + break either of these challenges. Finally, you may sometimes receive + wishes; a game without an attempt to wish for any items is a chal- lenge, as is a game without wishing for an artifact (even if the arti- fact immediately disappears). When the game offers you an opportunity - to make a wish for an item, you may choose "nothing" if you want to + to make a wish for an item, you may choose "nothing" if you want to decline. @@ -3822,7 +3822,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3834,12 +3834,12 @@ 8.1. Achievements - End of game disclosure will also display various achievements - representing progress toward ultimate ascension, if any have been - attained. They aren't directly related to conduct but are grouped - with it because they fall into the same category of "bragging rights" - and to limit the number of questions during disclosure. Listed here - roughly in order of difficulty and not necessarily in the order in + End of game disclosure will also display various achievements + representing progress toward ultimate ascension, if any have been + attained. They aren't directly related to conduct but are grouped + with it because they fall into the same category of "bragging rights" + and to limit the number of questions during disclosure. Listed here + roughly in order of difficulty and not necessarily in the order in which you might accomplish them. Rank - Attained rank title Rank. @@ -3851,12 +3851,12 @@ Novel - Read a passage from a Discworld Novel. Sokoban - Entered Sokoban. Big Room - Entered the Big Room. - Soko-Prize - Explored to the top of Sokoban and found a + Soko-Prize - Explored to the top of Sokoban and found a special item there. - Mines' End - Explored to the bottom of the Gnomish Mines + Mines' End - Explored to the bottom of the Gnomish Mines and found a special item there. Medusa - Defeated Medusa. - Tune - Discovered the tune that can be used to open + Tune - Discovered the tune that can be used to open and close the drawbridge on the Castle level. Bell - Acquired the Bell of Opening. Gehennom - Entered Gehennom. @@ -3876,19 +3876,19 @@ Notes: - Achievements are recorded and subsequently reported in the order - in which they happen during your current game rather than the order + Achievements are recorded and subsequently reported in the order + in which they happen during your current game rather than the order listed here. - There are nine titles for each role, bestowed at experi- - ence levels 1, 3, 6, 10, 14, 18, 22, 26, and 30. The one for experi- - ence level 1 is not recorded as an achievement. Losing enough levels + There are nine titles for each role, bestowed at experi- + ence levels 1, 3, 6, 10, 14, 18, 22, 26, and 30. The one for experi- + ence level 1 is not recorded as an achievement. Losing enough levels to revert to lower rank(s) does not discard the corresponding achieve- ment(s). - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3898,63 +3898,63 @@ - There's no guaranteed Novel so the achievement to read one might - not always be attainable (except perhaps by wishing). Similarly, the - Big Room level is not always present. Unlike with the Novel, there's + There's no guaranteed Novel so the achievement to read one might + not always be attainable (except perhaps by wishing). Similarly, the + Big Room level is not always present. Unlike with the Novel, there's no way to wish for this opportunity. - The "special items" hidden in Mines' End and Sokoban are not - unique but are considered to be prizes or rewards for exploring those - levels since doing so is not necessary to complete the game. Finding - other instances of the same objects doesn't record the corresponding + The "special items" hidden in Mines' End and Sokoban are not + unique but are considered to be prizes or rewards for exploring those + levels since doing so is not necessary to complete the game. Finding + other instances of the same objects doesn't record the corresponding achievement. - The Medusa achievement is recorded if she dies for any reason, + The Medusa achievement is recorded if she dies for any reason, even if you are not directly responsible, and only if she dies. The 5-note tune can be learned via trial and error with a musical - instrument played closely enough--but not too close!--to the Castle + instrument played closely enough--but not too close!--to the Castle level's drawbridge or can be given to you via prayer boon. - Blind, Deaf, Nudist, and Pauper are also conducts, and they can - only be enabled by setting the correspondingly named option in + Blind, Deaf, Nudist, and Pauper are also conducts, and they can + only be enabled by setting the correspondingly named option in NETHACKOPTIONS or run-time configuration file prior to game start. In - the case of Blind and Deaf, the option also enforces the conduct. - They aren't really significant accomplishments unless/until you make + the case of Blind and Deaf, the option also enforces the conduct. + They aren't really significant accomplishments unless/until you make substantial progress into the dungeon. 9. Options - Due to variations in personal tastes and conceptions of how - NetHack should do things, there are options you can set to change how + Due to variations in personal tastes and conceptions of how + NetHack should do things, there are options you can set to change how NetHack behaves. 9.1. Setting the options Options may be set in a number of ways. Within the game, the `O' - command allows you to view all options and change most of them. You - can also set options automatically by placing them in a configuration + command allows you to view all options and change most of them. You + can also set options automatically by placing them in a configuration file, or in the NETHACKOPTIONS environment variable. Some versions of - NetHack also have front-end programs that allow you to set options + NetHack also have front-end programs that allow you to set options before starting the game or a global configuration for system adminis- trators. 9.2. Using a configuration file - The default name of the configuration file varies on different + The default name of the configuration file varies on different operating systems. - On UNIX, Linux, and macOS it is ".nethackrc" in the user's home + On UNIX, Linux, and macOS it is ".nethackrc" in the user's home directory. The file may not exist, but it is a normal ASCII text file and can be created with any text editor. - On Windows, the name is ".nethackrc" located in the folder - "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal - ASCII text file can can be created with any text editor. After run- - ning NetHack for the first time, you should find a default template + On Windows, the name is ".nethackrc" located in the folder + "%USERPROFILE%\NetHack\". The file may not exist, but it is a normal + ASCII text file can can be created with any text editor. After run- + ning NetHack for the first time, you should find a default template - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -3964,40 +3964,40 @@ - for the configuration file named ".nethackrc.template" in - "%USERPROFILE%\NetHack\". If you have not created the configuration + for the configuration file named ".nethackrc.template" in + "%USERPROFILE%\NetHack\". If you have not created the configuration file, NetHack will create one for you using the default template file. On MS-DOS, it is "defaults.nh" in the same folder as nethack.exe. - Any line in the configuration file starting with `#' is treated + Any line in the configuration file starting with `#' is treated as a comment and ignored. Empty lines are ignored. Any line beginning with `[' and ending in `]' is a section marker - (the closing `]' can be followed by whitespace and then an arbitrary - comment beginning with `#'). The text between the square brackets is - the section name. Section markers are only valid after a CHOOSE + (the closing `]' can be followed by whitespace and then an arbitrary + comment beginning with `#'). The text between the square brackets is + the section name. Section markers are only valid after a CHOOSE directive and their names are case-insensitive. Lines after a section - marker belong to that section up until another section starts or a - marker without a name is encountered or the file ends. Lines within - sections are ignored unless a CHOOSE directive has selected that sec- + marker belong to that section up until another section starts or a + marker without a name is encountered or the file ends. Lines within + sections are ignored unless a CHOOSE directive has selected that sec- tion. - You can use different configuration directives in the file, some - of which can be used multiple times. In general, the directives are - written in capital letters, followed by an equals sign, followed by + You can use different configuration directives in the file, some + of which can be used multiple times. In general, the directives are + written in capital letters, followed by an equals sign, followed by settings particular to that directive. Here is a list of allowed directives: OPTIONS There are two types of options, boolean and compound options. Bool- - ean options toggle a setting on or off, while compound options take - more diverse values. Prefix a boolean option with "no" or `!' to - turn it off. For compound options, the option name and value are - separated by a colon. Some options are persistent, and apply only + ean options toggle a setting on or off, while compound options take + more diverse values. Prefix a boolean option with "no" or `!' to + turn it off. For compound options, the option name and value are + separated by a colon. Some options are persistent, and apply only to new games. You can specify multiple OPTIONS directives, and mul- - tiple options separated by commas in a single OPTIONS directive. + tiple options separated by commas in a single OPTIONS directive. (Comma separated options are processed from right to left.) Example: @@ -4006,21 +4006,21 @@ OPTIONS=!legacy,autopickup,pickup_types:$"=/!?+ HACKDIR + [not available on Unix] Default location of files NetHack needs. On Windows HACKDIR defaults - to the location of the NetHack.exe or NetHackw.exe file so setting + to the location of the NetHack.exe or NetHackw.exe file so setting HACKDIR to override that is not usually necessary or recommended. LEVELDIR - The location that in-progress level files are stored. Defaults to + [not available on Unix] + The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. SAVEDIR - The location where saved games are kept. Defaults to HACKDIR, must - be writable. + [not available on Unix] - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4030,22 +4030,28 @@ + The location where saved games are kept. Defaults to HACKDIR, must + be writable. + BONESDIR + [not available on Unix] The location that bones files are kept. Defaults to HACKDIR, must be writable. LOCKDIR + [not available on Unix] The location that file synchronization locks are stored. Defaults to HACKDIR, must be writable. TROUBLEDIR - The location that a record of game aborts and self-diagnosed game + [not available on Unix] + The location that a record of game aborts and self-diagnosed game problems is kept. Defaults to HACKDIR, must be writable. AUTOCOMPLETE - Enable or disable an extended command autocompletion. Autocomple- + Enable or disable an extended command autocompletion. Autocomple- tion has no effect for the X11 windowport. You can specify multiple - autocompletions. To enable autocompletion, list the extended com- + autocompletions. To enable autocompletion, list the extended com- mand. Prefix the command with "!" to disable the autocompletion for that command. @@ -4054,13 +4060,13 @@ AUTOCOMPLETE=zap,!annotate AUTOPICKUP_EXCEPTION - Set exceptions to the pickup_types option. See the "Configuring + Set exceptions to the pickup_types option. See the "Configuring Autopickup Exceptions" section. BINDINGS - Change the key bindings of some special keys, menu accelerators, + Change the key bindings of some special keys, menu accelerators, extended commands, or mouse buttons. You can specify multiple bind- - ings. Format is key followed by the command, separated by a colon. + ings. Format is key followed by the command, separated by a colon. See the "Changing Key Bindings" section for more information. Example: @@ -4073,6 +4079,23 @@ Example: + + + + + + + + NetHack 5.0.0 July 4, 2026 + + + + + + NetHack Guidebook 63 + + + OPTIONS=color CHOOSE=char A,char B [char A] @@ -4083,23 +4106,11 @@ OPTIONS=!rest_on_space If [] is present, the preceding section is closed and no new section - begins; whatever follows will be common to all sections. Otherwise - - - NetHack 3.7.0 April 16, 2026 - - - - - - NetHack Guidebook 63 - - - + begins; whatever follows will be common to all sections. Otherwise the last section extends to the end of the options file. MENUCOLOR - Highlight menu lines with different colors. See the "Configuring + Highlight menu lines with different colors. See the "Configuring Menu Colors" section. MSGTYPE @@ -4113,12 +4124,12 @@ Define a sound mapping. See the "Configuring User Sounds" section. SOUNDDIR - Define the directory that contains the sound files. See the "Con- + Define the directory that contains the sound files. See the "Con- figuring User Sounds" section. SYMBOLS - Override one or more symbols in the symbol set used for all dungeon - levels except for the special rogue level. See the "Modifying + Override one or more symbols in the symbol set used for all dungeon + levels except for the special rogue level. See the "Modifying NetHack Symbols" section. Example: @@ -4128,9 +4139,9 @@ WIZKIT Debug mode only: extra items to add to initial inventory. Value is - the name of a text file containing a list of item names, one per - line, up to a maximum of 128 lines. Each line is processed by the - function that handles wishing. Entries are added to the wish his- + the name of a text file containing a list of item names, one per + line, up to a maximum of 128 lines. Each line is processed by the + function that handles wishing. Entries are added to the wish his- tory; see the wizwish-command. Example: @@ -4139,20 +4150,9 @@ - Here is an example of configuration file contents: - - - - - - - - - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4162,6 +4162,8 @@ + Here is an example of configuration file contents: + # Set your character's role, race, gender, and alignment. OPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful # @@ -4183,22 +4185,22 @@ 9.3. Using the NETHACKOPTIONS environment variable - The NETHACKOPTIONS variable is a comma-separated list of initial - values for the various options. Some can only be turned on or off. + The NETHACKOPTIONS variable is a comma-separated list of initial + values for the various options. Some can only be turned on or off. You turn one of these on by adding the name of the option to the list, - and turn it off by typing a `!' or "no" before the name. Others take - a character string as a value. You can set string options by typing - the option name, a colon or equals sign, and then the value of the - string. The value is terminated by the next comma or the end of + and turn it off by typing a `!' or "no" before the name. Others take + a character string as a value. You can set string options by typing + the option name, a colon or equals sign, and then the value of the + string. The value is terminated by the next comma or the end of string. - For example, to set up an environment variable so that color is - on, legacy is off, character name is set to "Blue Meanie", and named + For example, to set up an environment variable so that color is + on, legacy is off, character name is set to "Blue Meanie", and named fruit is set to "lime", you would enter the command % setenv NETHACKOPTIONS "color,\!leg,name:Blue Meanie,fruit:lime" - in csh (note the need to escape the `!' since it's special to that + in csh (note the need to escape the `!' since it's special to that shell), or the pair of commands $ NETHACKOPTIONS="color,!leg,name:Blue Meanie,fruit:lime" @@ -4206,19 +4208,17 @@ in sh, ksh, or bash. - The NETHACKOPTIONS value is effectively the same as a single - OPTIONS directive in a configuration file. The "OPTIONS=" prefix is - implied and comma separated options are processed from right to left. - Other types of configuration directives such as BIND or MSGTYPE are + The NETHACKOPTIONS value is effectively the same as a single + OPTIONS directive in a configuration file. The "OPTIONS=" prefix is + implied and comma separated options are processed from right to left. + Other types of configuration directives such as BIND or MSGTYPE are not allowed. - Instead of a comma-separated list of options, NETHACKOPTIONS can - be set to the full name of a configuration file you want to use. If - that full name doesn't start with a slash, precede it with `@' (at- - sign) to let NetHack know that the rest is intended as a file name. + Instead of a comma-separated list of options, NETHACKOPTIONS can + be set to the full name of a configuration file you want to use. If - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4228,15 +4228,17 @@ + that full name doesn't start with a slash, precede it with `@' (at- + sign) to let NetHack know that the rest is intended as a file name. If it does start with `/', the at-sign is optional. 9.4. Customization options - Here are explanations of what the various options do. Character - strings that are too long may be truncated. Some of the options + Here are explanations of what the various options do. Character + strings that are too long may be truncated. Some of the options listed may be inactive in your dungeon. - Some options are persistent, and are saved and reloaded along + Some options are persistent, and are saved and reloaded along with the game. Changing a persistent option in the configuration file applies only to new games. @@ -4244,25 +4246,25 @@ Add location or direction information to messages (default is off). acoustics - Enable messages about what your character hears (default on). Note + Enable messages about what your character hears (default on). Note that this has nothing to do with your computer's audio capabilities. Persistent. alignment - Your starting alignment (align:lawful, align:neutral, or - align:chaotic). You may specify just the first letter. Many roles - and the non-human races restrict which alignments are allowed. See + Your starting alignment (align:lawful, align:neutral, or + align:chaotic). You may specify just the first letter. Many roles + and the non-human races restrict which alignments are allowed. See role for a description of how to use negation to exclude choices. If align is not specified, there is no default value; player will be - prompted unless role and/or race forces a choice for alignment. + prompted unless role and/or race forces a choice for alignment. Cannot be set with the `O' command. Persistent. armorstatus - Display an extra status condition which summarizes currently worn + Display an extra status condition which summarizes currently worn armor (default off, not supported by all interfaces). - For the usual case where more than one piece of armor is worn, a + For the usual case where more than one piece of armor is worn, a list of letters is shown in the following order: G - gloves; @@ -4274,17 +4276,15 @@ S - shield. autodescribe - Automatically describe the terrain under cursor when asked to get a - location on the map (default true). The whatis_coord option con- + Automatically describe the terrain under cursor when asked to get a + location on the map (default true). The whatis_coord option con- trols whether the description includes map coordinates. autodig Automatically dig if you are wielding a digging tool and moving into - a place that can be dug (default false). Persistent. - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4294,63 +4294,63 @@ + a place that can be dug (default false). Persistent. + autoopen Walking into a closed door attempts to open it (default true). Per- sistent. autopickup - Automatically pick up things onto which you move (default off). + Automatically pick up things onto which you move (default off). Persistent. - See pickup_types and also autopickup_exception for ways to refine + See pickup_types and also autopickup_exception for ways to refine the behavior. - Note: prior to version 3.7.0, the default for autopickup was on. + Note: prior to version 5.0.0, the default for autopickup was on. autoquiver - This option controls what happens when you attempt the `f' (fire) - command when nothing is quivered or readied (default false). When - true, the computer will fill your quiver or quiver sack or make + This option controls what happens when you attempt the `f' (fire) + command when nothing is quivered or readied (default false). When + true, the computer will fill your quiver or quiver sack or make ready some suitable weapon. Note that it will not take into account - the blessed/cursed status, enchantment, damage, or quality of the - weapon; you are free to manually fill your quiver or quiver sack or - make ready with the `Q' command instead. If no weapon is found or - the option is false, the `t' (throw) command is executed instead. + the blessed/cursed status, enchantment, damage, or quality of the + weapon; you are free to manually fill your quiver or quiver sack or + make ready with the `Q' command instead. If no weapon is found or + the option is false, the `t' (throw) command is executed instead. Persistent. autounlock - Controls what action to take when attempting to walk into a locked - door or to loot a locked container. Takes a plus-sign separated + Controls what action to take when attempting to walk into a locked + door or to loot a locked container. Takes a plus-sign separated list of values: Untrap - prompt about whether to attempt to find a trap; it might fail to find one even when present; if it does find one, - it will ask whether you want to try to disarm the trap; + it will ask whether you want to try to disarm the trap; if you decline, your character will forget that the door or box is trapped; - Apply-Key - if carrying a key or other unlocking tool, prompt about + Apply-Key - if carrying a key or other unlocking tool, prompt about using it; - Kick - kick the door (if you omit untrap or decline to attempt - untrap and you omit apply-key or you lack a key or you - decline to use the key; has no effect on containers); - Force - try to force a container's lid with your currently - wielded weapon (if you omit untrap or decline to attempt + Kick - kick the door (if you omit untrap or decline to attempt untrap and you omit apply-key or you lack a key or you + decline to use the key; has no effect on containers); + Force - try to force a container's lid with your currently + wielded weapon (if you omit untrap or decline to attempt + untrap and you omit apply-key or you lack a key or you decline to use the key; has no effect on doors); - None - none of the above; can't be combined with the other + None - none of the above; can't be combined with the other choices. Omitting the value is treated as if autounlock:apply-key. Preceding autounlock with `!' or "no" is treated as autounlock:none. - Applying a key might set off a trap if the door or container is - trapped. Successfully kicking a door will break it and wake up - nearby monsters. Successfully forcing a container open will break - its lock and might also destroy some of its contents or damage your - weapon or both. + Applying a key might set off a trap if the door or container is + trapped. Successfully kicking a door will break it and wake up + nearby monsters. Successfully forcing a container open will break - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4360,6 +4360,9 @@ + its lock and might also destroy some of its contents or damage your + weapon or both. + The default is Apply-Key. Persistent. blind @@ -4369,15 +4372,15 @@ Allow saving and loading bones files (default true). Persistent. boulder - Set the character used to display boulders (default is the "large + Set the character used to display boulders (default is the "large rock" class symbol, ``'). catname - Name your starting cat (for example "catname:Morris"). Cannot be + Name your starting cat (for example "catname:Morris"). Cannot be set with the `O' command. character - Synonym for "role" to pick the type of your character (for example + Synonym for "role" to pick the type of your character (for example "character:Monk"). See role for more details. checkpoint @@ -4385,11 +4388,11 @@ program crash (default on). Persistent. cmdassist - Have the game provide some additional command assistance for new + Have the game provide some additional command assistance for new players if it detects some anticipated mistakes (default on). confirm - Have user confirm attacks on pets, shopkeepers, and other peaceable + Have user confirm attacks on pets, shopkeepers, and other peaceable creatures (default on). Persistent. dark_room @@ -4399,13 +4402,13 @@ Start the character permanently deaf (default false). Persistent. dropped_nopick - If this option is on, items you dropped will not be automatically - picked up, even if autopickup is also on and they are in - pickup_types or match a positive autopickup exception (default on). + If this option is on, items you dropped will not be automatically + picked up, even if autopickup is also on and they are in + pickup_types or match a positive autopickup exception (default on). Persistent. disclose - Controls what information the program reveals when the game ends. + Controls what information the program reveals when the game ends. Value is a space separated list of prompting/category pairs (default is "ni na nv ng nc no", prompt with default response of `n' for each candidate). Persistent. The possibilities are: @@ -4413,10 +4416,7 @@ - - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4433,7 +4433,7 @@ c - display your conduct; also achievements, if any; o - display dungeon overview. - Each disclosure possibility can optionally be preceded by a prefix + Each disclosure possibility can optionally be preceded by a prefix which lets you refine how it behaves. Here are the valid prefixes: y - prompt you and default to yes on the prompt; @@ -4441,48 +4441,48 @@ + - disclose it without prompting; - - do not disclose it and do not prompt. - The listings of vanquished monsters and of genocided types can be + The listings of vanquished monsters and of genocided types can be sorted, so there are two additional choices for `v' and `g': ? - prompt you and default to ask on the prompt; # - disclose it without prompting, ask for sort order. - Asking refers to picking one of the orderings from a menu. The `+' - disclose without prompting choice, or being prompted and answering - `y' rather than `a', will default to showing monsters in the order + Asking refers to picking one of the orderings from a menu. The `+' + disclose without prompting choice, or being prompted and answering + `y' rather than `a', will default to showing monsters in the order specified by the sortvanquished option. - Omitted categories are implicitly added with `n' prefix. Specified - categories with omitted prefix implicitly use `+' prefix. Order of - the disclosure categories does not matter, program display for end- + Omitted categories are implicitly added with `n' prefix. Specified + categories with omitted prefix implicitly use `+' prefix. Order of + the disclosure categories does not matter, program display for end- of-game disclosure follows a set sequence. (for example "disclose:yi na +v -g o") The example sets inventory to - prompt and default to yes, attributes to prompt and default to no, - vanquished to disclose without prompting, genocided to not disclose - and not prompt, conduct to implicitly prompt and default to no, and + prompt and default to yes, attributes to prompt and default to no, + vanquished to disclose without prompting, genocided to not disclose + and not prompt, conduct to implicitly prompt and default to no, and overview to disclose without prompting. - Note that the vanquished monsters list includes all monsters killed + Note that the vanquished monsters list includes all monsters killed by traps and each other as well as by you. And the dungeon overview - shows all levels you had visited but does not reveal things about + shows all levels you had visited but does not reveal things about them that you hadn't discovered. dogname - Name your starting dog (for example "dogname:Fang"). Cannot be set + Name your starting dog (for example "dogname:Fang"). Cannot be set with the `O' command. extmenu - Changes the extended commands interface to pop-up a menu of avail- - able commands. It is keystroke compatible with the traditional + Changes the extended commands interface to pop-up a menu of avail- + able commands. It is keystroke compatible with the traditional interface except that it does not require that you hit Enter. It is implemented for the tty interface (default off). - For the X11 interface, which always uses a menu for choosing an - extended command, it controls whether the menu shows all available + For the X11 interface, which always uses a menu for choosing an + extended command, it controls whether the menu shows all available - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4492,7 +4492,7 @@ - commands (on) or just the subset of commands which have tradition- + commands (on) or just the subset of commands which have tradition- ally been considered extended ones (off). female @@ -4500,55 +4500,55 @@ command. fireassist - This option controls what happens when you attempt the `f' (fire) - and don't have an appropriate launcher, such as a bow or a sling, - wielded. If on, you will automatically wield the launcher. Default + This option controls what happens when you attempt the `f' (fire) + and don't have an appropriate launcher, such as a bow or a sling, + wielded. If on, you will automatically wield the launcher. Default is on. fixinv An object's inventory letter sticks to it when it's dropped (default - on). If this is off, dropping an object shifts all the remaining + on). If this is off, dropping an object shifts all the remaining inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a text + Commands asking for an inventory item show a menu instead of a text query with possible menu letters. Default is off. fruit - Name a fruit after something you enjoy eating (for example + Name a fruit after something you enjoy eating (for example "fruit:mango") (default "slime mold"). Basically a nostalgic whimsy - that NetHack uses from time to time. You should set this to some- - thing you find more appetizing than slime mold. Apples, oranges, - pears, bananas, and melons already exist in NetHack, so don't use + that NetHack uses from time to time. You should set this to some- + thing you find more appetizing than slime mold. Apples, oranges, + pears, bananas, and melons already exist in NetHack, so don't use those. gender - Your starting gender (gender:male or gender:female). You may spec- - ify just the first letter. Although you can still denote your gen- - der using either of the deprecated male and female options, if the + Your starting gender (gender:male or gender:female). You may spec- + ify just the first letter. Although you can still denote your gen- + der using either of the deprecated male and female options, if the gender option is also present it will take precedence. See role for a description of how to use negation to exclude choices. - If gender is not specified, there is no default value; player will - be prompted unless role and/or race forces a choice for gender. + If gender is not specified, there is no default value; player will + be prompted unless role and/or race forces a choice for gender. Cannot be set with the `O' command. Persistent. goldX When filtering objects based on bless/curse state (BUCX), whether to - treat gold pieces as X (unknown bless/curse state, when "on") or U - (known to be uncursed, when "off", the default). Gold is never - blessed or cursed, but it is not described as "uncursed" even when + treat gold pieces as X (unknown bless/curse state, when "on") or U + (known to be uncursed, when "off", the default). Gold is never + blessed or cursed, but it is not described as "uncursed" even when the implicit_uncursed option is "off". help - If more information is available for an object looked at with the - `/' command, ask if you want to see it (default on). Turning help - off makes just looking at things faster, since you aren't inter- - rupted with the "More info?" prompt, but it also means that you - might miss some interesting and/or important information. Persis- + If more information is available for an object looked at with the + `/' command, ask if you want to see it (default on). Turning help + off makes just looking at things faster, since you aren't inter- + rupted with the "More info?" prompt, but it also means that you + might miss some interesting and/or important information. Persis- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4562,59 +4562,59 @@ herecmd_menu When using a windowport that supports mouse and clicking on yourself - or next to you, show a menu of possible actions for the location. + or next to you, show a menu of possible actions for the location. Same as "#herecmdmenu" and "#therecmdmenu" commands. hilite_pet - Visually distinguish pets from similar animals (default off). The - behavior of this option depends on the type of windowing you use. + Visually distinguish pets from similar animals (default off). The + behavior of this option depends on the type of windowing you use. In text windowing, text highlighting or inverse video is often used; with tiles, generally displays a heart symbol near pets. With the tty or curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option on or + highlight pets and setting it will turn the hilite_pet option on or off as warranted. hilite_pile Visually distinguish piles of objects from individual objects - (default off). The behavior of this option depends on the type of - windowing you use. In text windowing, text highlighting or inverse - video is often used; with tiles, generally displays a small plus- + (default off). The behavior of this option depends on the type of + windowing you use. In text windowing, text highlighting or inverse + video is often used; with tiles, generally displays a small plus- symbol beside the object on the top of the pile. hitpointbar - Show a hit point bar graph behind your name and title in the status + Show a hit point bar graph behind your name and title in the status display (default off). - The "curses" interface supports it even if the status highlighting - feature has been disabled when building the program. The "tty" and - "mswin" (aka "Windows GUI") interfaces support it only if status - highlighting is left enabled when building. You don't need to set - up any highlighting rules in order to display the bar. If there is - one for hitpoints in effect and it specifies color, that color will + The "curses" interface supports it even if the status highlighting + feature has been disabled when building the program. The "tty" and + "mswin" (aka "Windows GUI") interfaces support it only if status + highlighting is left enabled when building. You don't need to set + up any highlighting rules in order to display the bar. If there is + one for hitpoints in effect and it specifies color, that color will be used for the bar. However if it specifies video attributes, they will be ignored in favor of inverse. For tty and curses, blink will also be used if the current hitpoint value is at or below the criti- cal HP threshold. The "Qt" interface also supports hitpointbar, by drawing a solid bar - above the name and title with a hard-coded color scheme. (As of + above the name and title with a hard-coded color scheme. (As of this writing, having the bar enabled unintentionally inhibits resiz- - ing the status panel. To resize that, use the #optionsfull command - to toggle the hitpointbar option off, perform the resize while it's + ing the status panel. To resize that, use the #optionsfull command + to toggle the hitpointbar option off, perform the resize while it's off, then use the same command to toggle it back on.) horsename - Name your starting horse (for example "horsename:Trigger"). Cannot + Name your starting horse (for example "horsename:Trigger"). Cannot be set with the `O' command. ignintr - Ignore interrupt signals, including breaks (default off). Persis- + Ignore interrupt signals, including breaks (default off). Persis- tent. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4639,48 +4639,48 @@ your character as lit (default off). Persistent. lootabc - When using a menu to interact with a container, use the old `a', - `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', + When using a menu to interact with a container, use the old `a', + `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', and `b' (default off). Persistent. mail Enable mail delivery during the game (default on). Persistent. male - An obsolete synonym for "gender:male". Cannot be set with the `O' + An obsolete synonym for "gender:male". Cannot be set with the `O' command. mention_decor - Give feedback when walking onto various dungeon features such as - stairs, fountains, or altars which are ordinarily only described - when covered by one or more objects (default off). Cannot be set + Give feedback when walking onto various dungeon features such as + stairs, fountains, or altars which are ordinarily only described + when covered by one or more objects (default off). Cannot be set with the `O' command. Persistent. mention_map Give feedback when interesting map locations change (default off). mention_walls - Give feedback when walking against a wall (default off). Persis- + Give feedback when walking against a wall (default off). Persis- tent. menucolors - Enable coloring menu lines (default off). See "Configuring Menu + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle Controls the method used when you need to choose various objects (in - response to the Drop (aka droptype) command, for instance). The - value specified should be the first letter of one of the following: - traditional, combination, full, or partial. Default is full. Per- + response to the Drop (aka droptype) command, for instance). The + value specified should be the first letter of one of the following: + traditional, combination, full, or partial. Default is full. Per- sistent. - Traditional was the only method available for very early versions; - it consists of a prompt for object class characters, followed by an - object-by-object prompt for all items matching the selected object + Traditional was the only method available for very early versions; + it consists of a prompt for object class characters, followed by an + object-by-object prompt for all items matching the selected object class(es). Combination starts with a prompt for object class(es) of - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4690,12 +4690,12 @@ - interest, but then displays a menu of matching objects rather than + interest, but then displays a menu of matching objects rather than prompting one-by-one. Full displays a menu of object classes rather - than a character prompt, and then a menu of matching objects for + than a character prompt, and then a menu of matching objects for selection. (Choosing its `A' (Autoselect-All) choice skips the sec- - ond menu. To avoid choosing that by accident, set paranoid_con- - firm:AutoAll to require confirmation.) Partial skips the object + ond menu. To avoid choosing that by accident, set paranoid_con- + firm:AutoAll to require confirmation.) Partial skips the object class filtering and immediately displays a menu of all objects. menu_deselect_all @@ -4708,9 +4708,9 @@ Key to jump to the first page in a menu. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Takes a text - attribute, or text color and attribute separated by ampersand. For - allowed attributes and colors, see "Configuring Menu Colors". Not + Controls how the headings in a menu are highlighted. Takes a text + attribute, or text color and attribute separated by ampersand. For + allowed attributes and colors, see "Configuring Menu Colors". Not all ports can actually display all types. menu_invert_all @@ -4726,13 +4726,13 @@ Key to go to the next menu page. Default `>'. menu_objsyms - Inventory and other object menus are normally separated by object + Inventory and other object menus are normally separated by object class (weapons, armor, and so forth), with a menu header line at the - beginning of each group. You can have menus add the display symbol + beginning of each group. You can have menus add the display symbol for the class of objects for each header line. You can also add the - display symbol for the individual item in each menu entry. For a + display symbol for the individual item in each menu entry. For a tiles map, that would be a small rendition of an object's tile. For - a text map, it is the same character as is used for the object's + a text map, it is the same character as is used for the object's class, which would be most useful when there are no headers separat- ing objects among classes. Possible values are @@ -4741,12 +4741,12 @@ 1 - Headers - show symbols on header lines but not entries; 2 - Entries - show symbols on menu entry lines but not headers; 3 - Both - show symbols on headers and entries; - 4 - Conditional - only show symbols for entries if there are no + 4 - Conditional - only show symbols for entries if there are no headers; - 5 - One-or-other - show symbols on headers, or on entries if no + 5 - One-or-other - show symbols on headers, or on entries if no - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4758,8 +4758,8 @@ headers. - Supported by tty and curses. When setting the value, it can be - specified by digit or keyword. The default value is Conditional + Supported by tty and curses. When setting the value, it can be + specified by digit or keyword. The default value is Conditional (4). menu_overlay @@ -4770,7 +4770,7 @@ Key to go to the previous menu page. Default `<'. menu_search - Key to search for some text and toggle selection state of matching + Key to search for some text and toggle selection state of matching menu items. Default `:'. menu_select_all @@ -4781,20 +4781,20 @@ menu_shift_left Key to scroll a menu--one which has been scrolled right--back to the - left. Implemented for perm_invent only by curses and X11. Default + left. Implemented for perm_invent only by curses and X11. Default `{'. menu_shift_right - Key to scroll a menu which has text beyond the right edge to the + Key to scroll a menu which has text beyond the right edge to the right. Implemented for perm_invent only by curses and X11. Default `}'. mon_movement - Show a message when hero notices a monster movement (default is + Show a message when hero notices a monster movement (default is off). monpolycontrol - Prompt for new form whenever any monster changes shape (default + Prompt for new form whenever any monster changes shape (default off). Debug mode only. montelecontrol @@ -4812,7 +4812,7 @@ port is the same as specifying 0. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4823,12 +4823,12 @@ msghistory - The number of top line messages to keep (and be able to recall with + The number of top line messages to keep (and be able to recall with `^P') (default 20). Cannot be set with the `O' command. msg_window - Allows you to change the way recalled messages are displayed. Cur- - rently it is only supported for tty (all four choices) and for + Allows you to change the way recalled messages are displayed. Cur- + rently it is only supported for tty (all four choices) and for curses (`f' and `r' choices, default `r'). The possible values are: s - single message (default; only choice prior to 3.4.0); @@ -4836,21 +4836,22 @@ f - full window, oldest message first; r - full window reversed, newest message first. - For backward compatibility, no value needs to be specified (which - defaults to "full"), or it can be negated (which defaults to "sin- + For backward compatibility, no value needs to be specified (which + defaults to "full"), or it can be negated (which defaults to "sin- gle"). name - Set your character's name (defaults to your user name). You can - also set your character's role by appending a dash and one or more - letters of the role (that is, by suffixing one of -A -B -C -H -K -M - -P -Ra -Ro -S -T -V -W). If -@ is used for the role, then a random + Set your character's name (defaults to your user name). You can + also set your character's role by appending a dash and one or more + letters of the role (that is, by suffixing one of -A -B -C -H -K -M + -P -Ra -Ro -S -T -V -W). If -@ is used for the role, then a random one will be automatically chosen. - On some systems, the default is the player's user name; on others, + On some systems, the default is the player's user name; on others, there is no default and the player will be prompted. The former can - made to behave like the latter by specifying a generic name such as - ``player''. Cannot be set with the `O' command. + be made to behave like the latter by specifying a generic name such + as ``player''. The GENERICUSERS= setting in sysconf controls which + names are considered generic. Cannot be set with the `O' command. news Read the NetHack news file, if present (default on). Since the news @@ -4875,10 +4876,9 @@ -1 - by letters but use `z' to go northwest, `y' to zap wands For backward compatibility, omitting a value is the same as specify- - ing 1 and negating number_pad is the same as specifying 0. (Set- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4888,6 +4888,7 @@ + ing 1 and negating number_pad is the same as specifying 0. (Set- tings 2 and 4 are for compatibility with MS-DOS or old PC Hack; in addition to the different behavior for `5', `Alt-5' acts as `G' and `Alt-0' acts as `I'. Setting -1 is to accommodate some QWERTZ key- @@ -4941,10 +4942,9 @@ AutoAll - require confirmation when the `A' (Autoselect-All) choice is selected in object class filtering menus for menustyle:Full; (to require "yes" rather than just - `y', set Confirm too); - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -4954,6 +4954,7 @@ + `y', set Confirm too); Remove - require selection from inventory for `R' and `T' com- mands even when wearing just one applicable item; all - turn on all of the above. @@ -5007,10 +5008,9 @@ petattr Specifies one or more text highlighting attributes to use when show- - ing pets on the map. Effectively a superset of the hilite_pet bool- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5020,6 +5020,7 @@ + ing pets on the map. Effectively a superset of the hilite_pet bool- ean option. Curses or tty interface only; value is one of none, bold, dim, underline, italic, blink, and inverse. Some of those choices might not work, depending upon terminal hardware or terminal @@ -5075,8 +5076,7 @@ least that big; default value is 5. Persistent. - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5142,7 +5142,7 @@ game). This option exists partly as an acknowledgement that some - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5208,7 +5208,7 @@ sistent. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5264,17 +5264,17 @@ interface or your terminal emulator window displays fewer than 25 lines. Persistent. + The versinfo option provides limited control over what information + showvers displays. + silent Suppress terminal beeps (default on). Persistent. sortdiscoveries Controls the sorting behavior for the output of the `\' and ``' com- - mands. Persistent. - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5284,34 +5284,36 @@ + mands. Persistent. + The possible values are: - o - list object types by class, in discovery order within each + o - list object types by class, in discovery order within each class; default; - s - list object types by sortloot classification: by class, by sub- - class within class for classes which have substantial groupings - (like helmets, boots, gloves, and so forth for armor), with - object types partly-discovered via assigned name coming before + s - list object types by sortloot classification: by class, by sub- + class within class for classes which have substantial groupings + (like helmets, boots, gloves, and so forth for armor), with + object types partly-discovered via assigned name coming before fully identified types; c - list by class, alphabetically within each class; a - list alphabetically across all classes. - Can be interactively set via the `O' command or via using the `m' + Can be interactively set via the `O' command or via using the `m' prefix before the `\' or ``' command. sortloot - Controls the sorting behavior of the pickup lists for inventory and + Controls the sorting behavior of the pickup lists for inventory and #loot commands and some others. Persistent. The possible values are: full - always sort the lists; - loot - only sort the lists that don't use inventory letters, like + loot - only sort the lists that don't use inventory letters, like with the #loot and pickup commands; none - show lists the traditional way without sorting; default. sortpack - Sort the pack contents by type when displaying inventory (default + Sort the pack contents by type when displaying inventory (default on). Persistent. sortvanquished @@ -5322,25 +5324,23 @@ t - traditional--order by monster level; ties are broken by internal monster index; default; - d - order by monster difficulty rating; ties broken by internal + d - order by monster difficulty rating; ties broken by internal index; - a - order alphabetically, first any unique monsters then all the + a - order alphabetically, first any unique monsters then all the others; c - order by monster class, by low to high level within each class; n - order by count, high to low; ties are broken by internal monster index; z - order by count, low to high; ties broken by internal index. - Can be interactively set via the `m O' command or via using the `m' - prefix before either the #vanquished command or the #genocided com- + Can be interactively set via the `m O' command or via using the `m' + prefix before either the #vanquished command or the #genocided com- mand. - sounds - Allow sounds to be emitted from an integrated sound library (default - on). - NetHack 3.7.0 April 16, 2026 + + NetHack 5.0.0 July 4, 2026 @@ -5350,8 +5350,12 @@ + sounds + Allow sounds to be emitted from an integrated sound library (default + on). + sparkle - Display a sparkly effect when a monster (including yourself) is hit + Display a sparkly effect when a monster (including yourself) is hit by an attack to which it is resistant (default on). Persistent. spot_monsters @@ -5366,32 +5370,32 @@ ing Status Hilites" for further information. status_updates - Allow updates to the status lines at the bottom of the screen + Allow updates to the status lines at the bottom of the screen (default true). suppress_alert - This option may be set to a NetHack version level to suppress alert - notification messages about feature changes for that and prior ver- + This option may be set to a NetHack version level to suppress alert + notification messages about feature changes for that and prior ver- sions (for example "suppress_alert:3.3.1"). symset This option may be used to select one of the named symbol sets found - within "symbols" to alter the symbols displayed on the screen. Use + within "symbols" to alter the symbols displayed on the screen. Use "symset:default" to explicitly select the default symbols. terrainstatus - Display an extra status condition describing the spot beneath the + Display an extra status condition describing the spot beneath the hero's feet (default off, not supported by all interfaces). time - Show the elapsed game time in turns on bottom line (default off). + Show the elapsed game time in turns on bottom line (default off). Persistent. timed_delay When pausing momentarily for display effect, such as with explosions and moving objects, use a timer rather than sending extra characters - to the screen. (Applies to "tty" and "curses" interfaces only; - "X11" interface always uses a timer-based delay. The default is on + to the screen. (Applies to "tty" and "curses" interfaces only; + "X11" interface always uses a timer-based delay. The default is on if configured into the program.) Persistent. tips @@ -5400,13 +5404,9 @@ tombstone Draw a tombstone graphic upon your death (default on). Persistent. - toptenwin - Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visible - when a windowing version of NetHack is started without a parent win- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5416,13 +5416,17 @@ + toptenwin + Put the ending display in a NetHack window instead of on stdout + (default off). Setting this option makes the score list visible + when a windowing version of NetHack is started without a parent win- dow, but it no longer leaves the score list around after game end on a terminal or emulating window. travel Allow the travel command via mouse click (default on). Turning this option off will prevent the game from attempting unintended moves if - you make inadvertent mouse clicks on the map window. Does not + you make inadvertent mouse clicks on the map window. Does not affect traveling via the `_' ("#travel") command. Persistent. tutorial @@ -5432,8 +5436,11 @@ verbose Provide more commentary during the game (default on). Persistent. + versinfo + Controls what the showvers option displays on the status lines. + weaponstatus - Display an extra status condition which describes currently wielded + Display an extra status condition which describes currently wielded weapon (default off, not supported by all interfaces). Some possible displayed values are: @@ -5443,8 +5450,8 @@ dual-weps - wielding two weapons. whatis_coord - When using the `/' or `;' commands to look around on the map with - autodescribe on, display coordinates after the description. Also + When using the `/' or `;' commands to look around on the map with + autodescribe on, display coordinates after the description. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -5455,24 +5462,17 @@ s - screen [row,column] (row is offset to match tty usage); n - none (no coordinates shown) [default]. - The whatis_coord option is also used with the "/m", "/M", "/o", and - "/O" sub-commands of `/', where the "none" setting is overridden + The whatis_coord option is also used with the "/m", "/M", "/o", and + "/O" sub-commands of `/', where the "none" setting is overridden with "map". whatis_filter - When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possible + When getting a location on the map, and using the keys to cycle + through next and previous targets, allows filtering the possible targets. - n - no filtering [default] - v - in view only - a - in same area only - The area-filter tries to be slightly predictive--if you're standing - on a doorway, it will consider the area on the side of the door you - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5482,6 +5482,12 @@ + n - no filtering [default] + v - in view only + a - in same area only + + The area-filter tries to be slightly predictive--if you're standing + on a doorway, it will consider the area on the side of the door you were last moving towards. Filtering can also be changed when getting a location with the "get- @@ -5489,56 +5495,50 @@ whatis_menu When getting a location on the map, and using a key to cycle through - next and previous targets, use a menu instead to pick a target. + next and previous targets, use a menu instead to pick a target. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement keys - or meta-digit keys to fast-move, instead of moving 8 units at a + When getting a location on the map, and using shifted movement keys + or meta-digit keys to fast-move, instead of moving 8 units at a time, move by skipping the same glyphs. (default off) windowtype - When the program has been built to support multiple interfaces, - select which one to use, such as "tty" or "X11" (default depends on - build-time settings; use "#version" to check). Cannot be set with + When the program has been built to support multiple interfaces, + select which one to use, such as "tty" or "X11" (default depends on + build-time settings; use "#version" to check). Cannot be set with the `O' command. - When used, it should be the first option set since its value might - enable or disable the availability of various other options. For + When used, it should be the first option set since its value might + enable or disable the availability of various other options. For multiple lines in a configuration file, that would be the first non- - comment line. For a comma-separated list in NETHACKOPTIONS or an - OPTIONS line in a configuration file, that would be the rightmost + comment line. For a comma-separated list in NETHACKOPTIONS or an + OPTIONS line in a configuration file, that would be the rightmost option in the list. wizweight - Augment object descriptions with their objects' weight (default + Augment object descriptions with their objects' weight (default off). Debug mode only. zerocomp - When writing out a save file, perform zero-comp compression of the - contents. Not all ports support zero-comp compression. It has no + When writing out a save file, perform zero-comp compression of the + contents. Not all ports support zero-comp compression. It has no effect on reading an existing save file. 9.5. Window Port Customization options - Here are explanations of the various options that are used to - customize and change the characteristics of the windowtype that you - have chosen. Character strings that are too long may be truncated. - Not all window ports will adjust for all settings listed here. You + Here are explanations of the various options that are used to + customize and change the characteristics of the windowtype that you + have chosen. Character strings that are too long may be truncated. + Not all window ports will adjust for all settings listed here. You can safely add any of these options to your configuration file, and if - the window port is capable of adjusting to suit your preferences, it - will attempt to do so. If it can't it will silently ignore it. You + the window port is capable of adjusting to suit your preferences, it + will attempt to do so. If it can't it will silently ignore it. You can find out if an option is supported by the window port that you are currently using by checking to see if it shows up in the Options list. - Some options are dynamic and can be specified during the game with the - `O' command. - - align_message - Where to align or place the message window (top, bottom, left, or - right) - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5548,16 +5548,23 @@ + Some options are dynamic and can be specified during the game with the + `O' command. + + align_message + Where to align or place the message window (top, bottom, left, or + right) + align_status - Where to align or place the status window (top, bottom, left, or + Where to align or place the status window (top, bottom, left, or right). ascii_map - If NetHack can, it should display the map using simple characters - (letters and punctuation) rather than tiles graphics. In some - cases, characters can be augmented with line-drawing symbols; use - the symset option to select a symbol set such as DECgraphics or - IBMgraphics if your display supports them. Setting ascii_map to + If NetHack can, it should display the map using simple characters + (letters and punctuation) rather than tiles graphics. In some + cases, characters can be augmented with line-drawing symbols; use + the symset option to select a symbol set such as DECgraphics or + IBMgraphics if your display supports them. Setting ascii_map to True forces tiled_map to be False. color @@ -5566,15 +5573,15 @@ eight_bit_tty If NetHack can, it should pass eight-bit character values (for exam- - ple, specified with the traps option) straight through to your ter- + ple, specified with the traps option) straight through to your ter- minal (default off). font_map - if NetHack can, it should use a font by the chosen name for the map + if NetHack can, it should use a font by the chosen name for the map window. font_menu - If NetHack can, it should use a font by the chosen name for menu + If NetHack can, it should use a font by the chosen name for menu windows. font_message @@ -5586,7 +5593,7 @@ tus window. font_text - If NetHack can, it should use a font by the chosen name for text + If NetHack can, it should use a font by the chosen name for text windows. font_size_map @@ -5595,16 +5602,9 @@ font_size_menu If NetHack can, it should use this size font for menu windows. - font_size_message - If NetHack can, it should use this size font for the message window. - - font_size_status - If NetHack can, it should use this size font for the status window. - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5614,6 +5614,12 @@ + font_size_message + If NetHack can, it should use this size font for the message window. + + font_size_status + If NetHack can, it should use this size font for the status window. + font_size_text If NetHack can, it should use this size font for text windows. @@ -5622,8 +5628,8 @@ than in a window. guicolor - Use color text and/or highlighting attributes when displaying some - non-map data (such as menu selector letters). Curses interface + Use color text and/or highlighting attributes when displaying some + non-map data (such as menu selector letters). Curses interface only; default is on. large_font @@ -5633,17 +5639,17 @@ If NetHack can, it should display the map in the manner specified. player_selection - If NetHack can, it should pop up dialog boxes, or use prompts for + If NetHack can, it should pop up dialog boxes, or use prompts for character selection. popup_dialog If NetHack can, it should pop up dialog boxes for input. preload_tiles - If NetHack can, it should preload tiles into memory. For example, + If NetHack can, it should preload tiles into memory. For example, in the protected mode MS-DOS version, control whether tiles get pre- loaded into RAM at the start of the game. Doing so enhances perfor- - mance of the tile graphics, but uses more memory. (default on). + mance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. scroll_amount @@ -5660,17 +5666,11 @@ support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to support + Display an onscreen keyboard. Handhelds are most likely to support this option. - splash_screen - If NetHack can, it should display an opening splash screen when it - starts up (default yes). - - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5680,42 +5680,46 @@ + splash_screen + If NetHack can, it should display an opening splash screen when it + starts up (default yes). + statuslines Number of lines for traditional below-the-map status display. Acceptable values are 2 and 3 (default is 2). When set to 3, the tty interface moves some fields around and mainly - shows status conditions on their own line. A display capable of - showing at least 25 lines is recommended. The value can be toggled + shows status conditions on their own line. A display capable of + showing at least 25 lines is recommended. The value can be toggled back and forth during the game with the `O' command. The curses interface does likewise if the align_status option is set to top or bottom but ignores statuslines when set to left or right. - The Qt interface already displays more than 3 lines for status so + The Qt interface already displays more than 3 lines for status so uses the statuslines value differently. A value of 3 renders status in the Qt interface's original format, with the status window spread - out vertically. A value of 2 makes status be slightly condensed, - moving some fields to different lines to eliminate one whole line, + out vertically. A value of 2 makes status be slightly condensed, + moving some fields to different lines to eliminate one whole line, reducing the height needed. (If NetHack has been built using a ver- - sion of Qt older than qt-5.9, statuslines can only be set in the - run-time configuration file or via NETHACKOPTIONS, not during play + sion of Qt older than qt-5.9, statuslines can only be set in the + run-time configuration file or via NETHACKOPTIONS, not during play with the `O' command.) term_cols and term_rows - Curses interface only. Number of columns and rows to use for the - display. Curses will attempt to resize to the values specified but - will settle for smaller sizes if they are too big. Default is the + Curses interface only. Number of columns and rows to use for the + display. Curses will attempt to resize to the values specified but + will settle for smaller sizes if they are too big. Default is the current window size. tile_file - Specify the name of an alternative tile file to override the + Specify the name of an alternative tile file to override the default. - Note: the X11 interface uses X resources rather than NetHack's - options to select an alternate tile file. See NetHack.ad, the sam- + Note: the X11 interface uses X resources rather than NetHack's + options to select an alternate tile file. See NetHack.ad, the sam- ple X "application defaults" file. tile_height @@ -5725,18 +5729,14 @@ Specify the preferred width of each tile in a tile capable port tiled_map - If NetHack can, it should display the map using tiles graphics - rather than simple characters (letters and punctuation, possibly - augmented by line-drawing symbols). Setting tiled_map to True + If NetHack can, it should display the map using tiles graphics + rather than simple characters (letters and punctuation, possibly + augmented by line-drawing symbols). Setting tiled_map to True forces ascii_map to be False. - use_darkgray - Use bold black instead of blue for black glyphs (TTY only). - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5746,17 +5746,20 @@ + use_darkgray + Use bold black instead of blue for black glyphs (TTY only). + use_inverse - If NetHack can, it should display inverse when the game specifies + If NetHack can, it should display inverse when the game specifies it. vary_msgcount - If NetHack can, it should display this number of messages at a time + If NetHack can, it should display this number of messages at a time in the message window. windowborders Whether to draw boxes around the map, status area, message area, and - persistent inventory window if enabled. Curses interface only. + persistent inventory window if enabled. Curses interface only. Acceptable values are 0 - off, never show borders @@ -5765,11 +5768,11 @@ 3 - on, except forced off for perm_invent 4 - auto, except forced off for perm_invent - (The 26x82 size threshold for `2' refers to number of rows and col- + (The 26x82 size threshold for `2' refers to number of rows and col- umns of the display. A width of at least 110 columns (80+2+26+2) is needed to show borders if align_status is set to left or right.) - The persistent inventory window, when enabled, can grow until it is + The persistent inventory window, when enabled, can grow until it is too big to fit on most displays, resulting in truncation of its con- tents. If borders are forced on (1) or the display is big enough to show them (2), setting the value to 3 or 4 instead will keep borders @@ -5778,31 +5781,28 @@ umns. windowcolors - If NetHack can, it should display all windows of a particular style - with the specified foreground and background colors. Windows GUI + If NetHack can, it should display all windows of a particular style + with the specified foreground and background colors. Windows GUI and curses windowport only. The format is OPTION=windowcolors:style foreground/background - where style is one of "menu", "message", "status", or "text", and + where style is one of "menu", "message", "status", or "text", and foreground and background are colors, either numeric (hash sign fol- - lowed by three pairs of hexadecimal digits, #rrggbb), one of the + lowed by three pairs of hexadecimal digits, #rrggbb), one of the named colors (black, red, green, brown, blue, magenta, cyan, orange, - bright-green, yellow, bright-blue, bright-magenta, bright-cyan, - white, gray, purple, silver, maroon, fuchsia, lime, olive, navy, - teal, aqua), or (for Windows only) one of Windows UI colors (true- - black, activeborder, activecaption, appworkspace, background, btn- - face, btnshadow, btntext, captiontext, graytext, greytext, high- - light, highlighttext, inactiveborder, inactivecaption, menu, menu- + bright-green, yellow, bright-blue, bright-magenta, bright-cyan, + white, gray, purple, silver, maroon, fuchsia, lime, olive, navy, + teal, aqua), or (for Windows only) one of Windows UI colors (true- + black, activeborder, activecaption, appworkspace, background, btn- + face, btnshadow, btntext, captiontext, graytext, greytext, high- + light, highlighttext, inactiveborder, inactivecaption, menu, menu- text, scrollbar, window, windowframe, windowtext). - wraptext - If NetHack can, it should wrap long lines of text if they don't fit - in the visible area of the window. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5812,63 +5812,63 @@ + wraptext + If NetHack can, it should wrap long lines of text if they don't fit + in the visible area of the window. + 9.6. Crash Report Options - Please note that NetHack does not send any information off your + Please note that NetHack does not send any information off your computer unless you manually click submit on a form. OPTION=crash_email:email_address OPTION=crash_name:your_name - These options are used only to save you some typing on the + These options are used only to save you some typing on the crash report and #bugreport forms. OPTION=crash_urlmax:bytes - This option is used to limit the length of the URLs generated - and is only needed if your browser cannot handle arbitrarily + This option is used to limit the length of the URLs generated + and is only needed if your browser cannot handle arbitrarily long URLs. 9.7. Platform-specific Customization options - Here are explanations of options that are used by specific plat- + Here are explanations of options that are used by specific plat- forms or ports to customize and change the port behavior. altkeyhandling - Select an alternate way to handle keystrokes (Win32 tty NetHack - only). The name of the handling type is one of "default", "ray", + Select an alternate way to handle keystrokes (Win32 tty NetHack + only). The name of the handling type is one of "default", "ray", "340". altmeta - On systems where this option is available, it can be set to tell - NetHack to convert a two character sequence beginning with ESC into + On systems where this option is available, it can be set to tell + NetHack to convert a two character sequence beginning with ESC into a meta-shifted version of the second character (default off). - This conversion is only done for commands, not for other input - prompts. Note that typing one or more digits as a count prefix - prior to a command--preceded by n if the number_pad option is set-- + This conversion is only done for commands, not for other input + prompts. Note that typing one or more digits as a count prefix + prior to a command--preceded by n if the number_pad option is set-- is also subject to this conversion, so attempting to abort the count - by typing ESC will leave NetHack waiting for another character to - complete the two character sequence. Type a second ESC to finish + by typing ESC will leave NetHack waiting for another character to + complete the two character sequence. Type a second ESC to finish cancelling such a count. At other prompts a single ESC suffices. BIOS - Use BIOS calls to update the screen display quickly and to read the - keyboard (allowing the use of arrow keys to move) on machines with + Use BIOS calls to update the screen display quickly and to read the + keyboard (allowing the use of arrow keys to move) on machines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bulletproof - input (MS-DOS sometimes treats `^P' as a printer toggle without it) - (default off, OS/2, PC, and ST NetHack only). Note: DEC Rainbows + Force raw (non-cbreak) mode for faster output and more bulletproof + input (MS-DOS sometimes treats `^P' as a printer toggle without it) + (default off, OS/2, PC, and ST NetHack only). Note: DEC Rainbows hang if this is turned on. Cannot be set with the `O' command. - subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of key- - strokes that the operating system returns to NetHack to help compen- - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5878,19 +5878,22 @@ - sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 - will return 92 to NetHack, if 171 was originally going to be - returned. You can use multiple subkeyvalue assignments in the con- + subkeyvalue + (Win32 tty NetHack only). May be used to alter the value of key- + strokes that the operating system returns to NetHack to help compen- + sate for international keyboard issues. OPTIONS=subkeyvalue:171/92 + will return 92 to NetHack, if 171 was originally going to be + returned. You can use multiple subkeyvalue assignments in the con- figuration file if needed. Cannot be set with the `O' command. video Set the video mode used (PC NetHack only). Values are "autodetect", - "default", "vga", or "vesa". Setting "vesa" will cause the game to - display tiles, using the full capability of the VGA hardware. Set- + "default", "vga", or "vesa". Setting "vesa" will cause the game to + display tiles, using the full capability of the VGA hardware. Set- ting "vga" will cause the game to display tiles, fixed at 640x480 in - 16 colors, a mode that is compatible with all VGA hardware. Third - party tilesets will probably not work. Setting "autodetect" - attempts "vesa", then "vga", and finally sets "default" if neither + 16 colors, a mode that is compatible with all VGA hardware. Third + party tilesets will probably not work. Setting "autodetect" + attempts "vesa", then "vga", and finally sets "default" if neither of those modes works. Cannot be set with the `O' command. video_height @@ -5900,41 +5903,38 @@ Set the VGA mode resolution width (MS-DOS only, with video:vesa) videocolors - Set the color palette for PC systems using NO_TERMS (default - 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order of - colors is red, green, brown, blue, magenta, cyan, bright.white, - bright.red, bright.green, yellow, bright.blue, bright.magenta, and + Set the color palette for PC systems using NO_TERMS (default + 4-2-6-1-5-3-15-12-10-14-9-13-11, (PC NetHack only). The order of + colors is red, green, brown, blue, magenta, cyan, bright.white, + bright.red, bright.green, yellow, bright.blue, bright.magenta, and bright.cyan. Cannot be set with the `O' command. videoshades - Set the intensity level of the three gray scales available (default - dark normal light, PC NetHack only). If the game display is diffi- - cult to read, try adjusting these scales; if this does not correct + Set the intensity level of the three gray scales available (default + dark normal light, PC NetHack only). If the game display is diffi- + cult to read, try adjusting these scales; if this does not correct the problem, try !color. Cannot be set with the `O' command. 9.8. Regular Expressions - Regular expressions are normally POSIX extended regular expres- - sions. It is possible to compile NetHack without regular expression - support on a platform where there is no regular expression library. - While this is not true of any modern platform, if your NetHack was - built this way, patterns are instead glob patterns; regardless, this - document refers to both as `regular expressions.' This applies to + Regular expressions are normally POSIX extended regular expres- + sions. It is possible to compile NetHack without regular expression + support on a platform where there is no regular expression library. + While this is not true of any modern platform, if your NetHack was + built this way, patterns are instead glob patterns; regardless, this + document refers to both as `regular expressions.' This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. 9.9. Configuring Autopickup Exceptions - You can further refine the behavior of the autopickup option + You can further refine the behavior of the autopickup option beyond what is available through the pickup_types option. By placing autopickup_exception lines in your configuration file, - you can define patterns to be checked when the game is about to - autopickup something. + you can define patterns to be checked when the game is about to - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -5944,24 +5944,26 @@ + autopickup something. + autopickup_exception Sets an exception to the pickup_types option. The autopickup_excep- tion option should be followed by a regular expression to be used as - a pattern to match against the singular form of the description of + a pattern to match against the singular form of the description of an object at your location. - In addition, some characters are treated specially if they occur as + In addition, some characters are treated specially if they occur as the first character in the pattern, specifically: < - always pickup an object that matches rest of pattern; > - never pickup an object that matches rest of pattern. - The autopickup_exception rules are processed in the order in which - they appear in your configuration file, thus allowing a later rule + The autopickup_exception rules are processed in the order in which + they appear in your configuration file, thus allowing a later rule to override an earlier rule. Exceptions can be set with the `O' command, but because they are not - included in your configuration file, they won't be in effect if you + included in your configuration file, they won't be in effect if you save and then restore your game. autopickup_exception rules and not saved with the game. @@ -5971,18 +5973,18 @@ autopickup_exception=">*corpse" autopickup_exception=">* cursed*" - The first example above will result in autopickup of any type of + The first example above will result in autopickup of any type of arrow. The second example results in the exclusion of any corpse from - autopickup. The last example results in the exclusion of items known + autopickup. The last example results in the exclusion of items known to be cursed from autopickup. 9.10. Changing Key Bindings It is possible to change the default key bindings of some special - commands, menu accelerator keys, and extended commands, by using BIND - stanzas in the configuration file. Format is key, followed by the - command to bind to, separated by a colon. The key can be a single - character ("x"), a control key ("^X", "C-x"), a meta key ("M-x"), a + commands, menu accelerator keys, and extended commands, by using BIND + stanzas in the configuration file. Format is key, followed by the + command to bind to, separated by a colon. The key can be a single + character ("x"), a control key ("^X", "C-x"), a meta key ("M-x"), a mouse button, or a three-digit decimal ASCII code. For example: @@ -5992,15 +5994,13 @@ BIND=v:loot Extended command keys - You can bind multiple keys to the same extended command. Unbind a - key by using "nothing" as the extended command to bind to. You can + You can bind multiple keys to the same extended command. Unbind a + key by using "nothing" as the extended command to bind to. You can also bind the "", "", and "" keys. - Menu accelerator keys - The menu control or accelerator keys can also be rebound via OPTIONS - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6010,46 +6010,48 @@ - lines in the configuration file. You cannot bind object symbols or + Menu accelerator keys + The menu control or accelerator keys can also be rebound via OPTIONS + lines in the configuration file. You cannot bind object symbols or selection letters into menu accelerators. Some interfaces only sup- port some of the menu accelerators. Mouse buttons - You can bind "mouse1" or "mouse2" to "nothing", "therecmdmenu", + You can bind "mouse1" or "mouse2" to "nothing", "therecmdmenu", "clicklook", or "mouseaction". Special command keys - Below are the special commands you can rebind. Some of them can be - bound to same keys with no problems, others are in the same "con- + Below are the special commands you can rebind. Some of them can be + bound to same keys with no problems, others are in the same "con- text", and if bound to same keys, only one of those commands will be available. Special command can only be bound to a single key. count - Prefix key to start a count, to repeat a command this many times. + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. getdir.help - When asked for a direction, the key to show the help. Default is + When asked for a direction, the key to show the help. Default is `?'. getdir.mouse - When asked for a direction, the key to initiate a simulated mouse - click. You will be asked to pick a location. Use movement key- - strokes to move the cursor around the map, then type the get- + When asked for a direction, the key to initiate a simulated mouse + click. You will be asked to pick a location. Use movement key- + strokes to move the cursor around the map, then type the get- pos.pick.once key (default `,') or the getpos.pick key (default `.') - to finish as if performing a left or right click. Only useful when + to finish as if performing a left or right click. Only useful when using the #therecmdmenu command. Default is `_'. getdir.self - When asked for a direction, the key to target yourself. Default is + When asked for a direction, the key to target yourself. Default is `.'. getdir.self2 - When asked for a direction, an alternate key to target yourself. + When asked for a direction, an alternate key to target yourself. Default is `s'. getpos.autodescribe - When asked for a location, the key to toggle autodescribe. Default + When asked for a location, the key to toggle autodescribe. Default is `#'. getpos.all.next @@ -6057,16 +6059,14 @@ thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest inter- + When asked for a location, the key to go to previous closest inter- esting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door or - doorway. Default is `d'. + When asked for a location, the key to go to next closest door or - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6076,6 +6076,8 @@ + doorway. Default is `d'. + getpos.door.prev When asked for a location, the key to go to previous closest door or doorway. Default is `D'. @@ -6084,15 +6086,15 @@ When asked for a location, the key to show help. Default is `?'. getpos.mon.next - When asked for a location, the key to go to next closest monster. + When asked for a location, the key to go to next closest monster. Default is `m'. getpos.mon.prev - When asked for a location, the key to go to previous closest mon- + When asked for a location, the key to go to previous closest mon- ster. Default is `M'. getpos.obj.next - When asked for a location, the key to go to next closest object. + When asked for a location, the key to go to next closest object. Default is `o'. getpos.obj.prev @@ -6100,39 +6102,37 @@ Default is `O'. getpos.menu - When asked for a location, and using one of the next or previous - keys to cycle through targets, toggle showing a menu instead. + When asked for a location, and using one of the next or previous + keys to cycle through targets, toggle showing a menu instead. Default is `!'. getpos.moveskip - When asked for a location, and using the shifted movement keys or - meta-digit keys to fast-move around, move by skipping the same + When asked for a location, and using the shifted movement keys or + meta-digit keys to fast-move around, move by skipping the same glyphs instead of by 8 units. Default is `*'. getpos.filter - When asked for a location, change the filtering mode when using one - of the next or previous keys to cycle through targets. Toggles - between no filtering, in view only, and in the same area only. + When asked for a location, change the filtering mode when using one + of the next or previous keys to cycle through targets. Toggles + between no filtering, in view only, and in the same area only. Default is `"'. getpos.pick - When asked for a location, the key to choose the location, and pos- - sibly ask for more info. When simulating a mouse click after being - asked for a direction (see getdir.mouse above), the key to use to + When asked for a location, the key to choose the location, and pos- + sibly ask for more info. When simulating a mouse click after being + asked for a direction (see getdir.mouse above), the key to use to respond as right click. Default is `.'. getpos.pick.once - When asked for a location, the key to choose the location, and skip - asking for more info. When simulating a mouse click after being + When asked for a location, the key to choose the location, and skip + asking for more info. When simulating a mouse click after being asked for a direction, the key to respond as left click. Default is `,'. - getpos.pick.quick - When asked for a location, the key to choose the location, skip ask- - ing for more info, and exit the location asking loop. Default is - NetHack 3.7.0 April 16, 2026 + + NetHack 5.0.0 July 4, 2026 @@ -6142,26 +6142,29 @@ + getpos.pick.quick + When asked for a location, the key to choose the location, skip ask- + ing for more info, and exit the location asking loop. Default is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and show + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self - When asked for a location, the key to go to your location. Default + When asked for a location, the key to go to your location. Default is `@'. getpos.unexplored.next - When asked for a location, the key to go to next closest unexplored + When asked for a location, the key to go to next closest unexplored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest unex- + When asked for a location, the key to go to previous closest unex- plored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target loca- + When asked for a location, the key to go to show valid target loca- tions. Default is `$'. getpos.valid.next @@ -6169,15 +6172,15 @@ tion. Default is `z'. getpos.valid.prev - When asked for a location, the key to go to previous closest valid + When asked for a location, the key to go to previous closest valid location. Default is `Z'. 9.11. Configuring Message Types - You can change the way the messages are shown in the message + You can change the way the messages are shown in the message area, when the message matches a user-defined pattern. - In general, the configuration file entries to describe the mes- + In general, the configuration file entries to describe the mes- sage types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -6190,15 +6193,12 @@ show - show message normally; hide - never show the message; stop - wait for user with more-prompt; - norep - show the message once, but not again if no other message is + norep - show the message once, but not again if no other message is shown in between. - Here's an example of message types using NetHack's internal pattern - matching facility: - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6208,11 +6208,14 @@ + Here's an example of message types using NetHack's internal pattern + matching facility: + MSGTYPE=stop "You feel hungry." MSGTYPE=hide "You displaced *." - specifies that whenever a message "You feel hungry" is shown, the - user is prompted with more-prompt, and a message matching "You dis- + specifies that whenever a message "You feel hungry" is shown, the + user is prompted with more-prompt, and a message matching "You dis- placed ." is not shown at all. The order of the defined MSGTYPE lines is important; the last match- @@ -6221,50 +6224,47 @@ 9.12. Configuring Menu Colors Some platforms allow you to define colors used in menu lines when - the line matches a user-defined pattern. At this time the tty, + the line matches a user-defined pattern. At this time the tty, curses, win32tty and win32gui interfaces support this. - In general, the configuration file entries to describe the menu + In general, the configuration file entries to describe the menu color mappings look like this: MENUCOLOR="pattern"=color&attribute pattern - the pattern to match; color - the color to use for lines matching the pattern; - attribute - the attribute to use for lines matching the pat- - tern. The attribute is optional, and if left out, - you must also leave out the preceding ampersand. + attribute - the attribute to use for lines matching the pat- + tern. The attribute is optional, and if left out, + you must also leave out the preceding ampersand. If no attribute is defined, no attribute is used. The pattern should be a regular expression. - Allowed colors are black, red, green, brown, blue, magenta, cyan, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magenta, light- - cyan, and white. And no-color, the default foreground color, which + cyan, and white. And no-color, the default foreground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, italic, underline, blink, + Allowed attributes are none, bold, dim, italic, underline, blink, and inverse. "Normal" is a synonym for "none". Note that the plat- form used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pattern + Here's an example of menu colors using NetHack's internal pattern matching facility: MENUCOLOR="* blessed *"=green MENUCOLOR="* cursed *"=red MENUCOLOR="* cursed *(being worn)"=red&underline - specifies that any menu line with " blessed " contained in it will + specifies that any menu line with " blessed " contained in it will be shown in green color, lines with " cursed " will be shown in red, - and lines with " cursed " followed by "(being worn)" on the same + and lines with " cursed " followed by "(being worn)" on the same line will be shown in red color and underlined. You can have multi- ple MENUCOLOR entries in your configuration file, and the last MENU- - COLOR line that matches a menu line will be used for the line. - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6274,19 +6274,21 @@ - Note that if you intend to have one or more color specifications + COLOR line that matches a menu line will be used for the line. + + Note that if you intend to have one or more color specifications match " uncursed ", you will probably want to turn the - implicit_uncursed option off so that all items known to be uncursed + implicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.13. Configuring User Sounds - Some platforms allow you to define sound files to be played when + Some platforms allow you to define sound files to be played when a message that matches a user-defined pattern is delivered to the mes- - sage window. At this time the Qt port and the win32tty and win32gui + sage window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. - The following configuration file entries are relevant to mapping + The following configuration file entries are relevant to mapping user sounds to messages: SOUNDDIR @@ -6296,9 +6298,9 @@ An entry that maps a sound file to a user-specified message pattern. Each SOUND entry is broken down into the following parts: - MESG - message window mapping (the only one supported in - 3.7.0); - msgtype - optional; message type to use, see "Configuring Mes- + MESG - message window mapping (the only one supported in + 5.0.0); + msgtype - optional; message type to use, see "Configuring Mes- sage Types" pattern - the pattern to match; sound file - the sound file to play; @@ -6317,20 +6319,18 @@ 9.14. Configuring Status Hilites - Your copy of NetHack may have been compiled with support for - "Status Hilites". If so, you can customize your game display by set- - ting thresholds to change the color or appearance of fields in the + Your copy of NetHack may have been compiled with support for + "Status Hilites". If so, you can customize your game display by set- + ting thresholds to change the color or appearance of fields in the status display. The format for defining status colors is: OPTION=hilite_status:field-name/behavior/color&attributes - For example, the following line in your configuration file will - cause the hitpoints field to display in the color red if your hit- - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6340,40 +6340,42 @@ + For example, the following line in your configuration file will + cause the hitpoints field to display in the color red if your hit- points drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal - (That example is actually specifying red&normal for <=30% and no- + (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configuration + For another example, the following line in your configuration file will cause wisdom to be displayed red if it drops and green if it rises: OPTION=hilite_status:wisdom/down/red/up/green Allowed colors are black, red, green, brown, blue, magenta, cyan, - gray, orange, light-green, yellow, light-blue, light-magenta, light- - cyan, and white. And "no-color", the default foreground color on the + gray, orange, light-green, yellow, light-blue, light-magenta, light- + cyan, and white. And "no-color", the default foreground color on the display, which is not necessarily the same as black or white or any of the other colors. Allowed attributes are none, bold, dim, underline, italic, blink, - and inverse. "Normal" is a synonym for "none"; they should not be + and inverse. "Normal" is a synonym for "none"; they should not be used in combination with any of the other attributes. - To specify both a color and an attribute, use `&' to combine - them. To specify multiple attributes, use `+' to combine those. For + To specify both a color and an attribute, use `&' to combine + them. To specify multiple attributes, use `+' to combine those. For example: "magenta&inverse+dim". Note that the display may substitute or ignore particular - attributes depending upon its capabilities, and in general may inter- - pret the attributes any way it wants. For example, on some display - systems a request for bold might yield blink or vice versa. On oth- + attributes depending upon its capabilities, and in general may inter- + pret the attributes any way it wants. For example, on some display + systems a request for bold might yield blink or vice versa. On oth- ers, issuing an attribute request while another is already set up will - replace the earlier attribute rather than combine with it. Since - NetHack issues attribute requests sequentially (at least with the tty + replace the earlier attribute rather than combine with it. Since + NetHack issues attribute requests sequentially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to specify just one attribute. @@ -6387,16 +6389,14 @@ charisma armor-class condition alignment score - The pseudo-field "characteristics" can be used to set all six of - Str, Dex, Con, Int, Wis, and Cha at once. "HD" is "hit dice", an - approximation of experience level displayed when polymorphed. - "experience", "time", and "score" are conditionally displayed + The pseudo-field "characteristics" can be used to set all six of + Str, Dex, Con, Int, Wis, and Cha at once. "HD" is "hit dice", an + approximation of experience level displayed when polymorphed. + "experience", "time", and "score" are conditionally displayed depending upon your other option settings. - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6406,63 +6406,63 @@ - Instead of a behavior, "condition" takes the following condition - flags: stone, slime, strngl, foodpois, termill, blind, deaf, stun, + Instead of a behavior, "condition" takes the following condition + flags: stone, slime, strngl, foodpois, termill, blind, deaf, stun, conf, hallu, lev, fly, and ride. You can use "major_troubles" as an - alias for stone through termill, "minor_troubles" for blind through + alias for stone through termill, "minor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condi- tion. - Allowed behaviors are "always", "up", "down", "changed", a percent- + Allowed behaviors are "always", "up", "down", "changed", a percent- age or absolute number threshold, or text to match against. For the - hitpoints field, the additional behavior "criticalhp" is available. - It overrides other behavior rules if hit points are at or below the - major problem threshold (which varies depending upon maximum hit + hitpoints field, the additional behavior "criticalhp" is available. + It overrides other behavior rules if hit points are at or below the + major problem threshold (which varies depending upon maximum hit points and experience level). * "always" will set the default attributes for that field. - * "up", "down" set the field attributes for when the field value - changes upwards or downwards. This attribute times out after + * "up", "down" set the field attributes for when the field value + changes upwards or downwards. This attribute times out after statushilites turns. - * "changed" sets the field attribute for when the field value - changes. This attribute times out after statushilites turns. - (If a field has both a "changed" rule and an "up" or "down" - rule which matches a change in the field's value, the "up" or + * "changed" sets the field attribute for when the field value + changes. This attribute times out after statushilites turns. + (If a field has both a "changed" rule and an "up" or "down" + rule which matches a change in the field's value, the "up" or "down" one takes precedence.) - * percentage sets the field attribute when the field value - matches the percentage. It is specified as a number between 0 - and 100, followed by `%' (percent sign). If the percentage is + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number between 0 + and 100, followed by `%' (percent sign). If the percentage is prefixed with `<=' or `>=', it also matches when value is below - or above the percentage. Use prefix `<' or `>' to match when + or above the percentage. Use prefix `<' or `>' to match when strictly below or above. (The numeric limit is relaxed - slightly for those: >-1% and <101% are allowed.) Only four - fields support percentage rules. Percentages for "hitpoints" - and "power" are straightforward; they're based on the corre- - sponding maximum field. Percentage highlight rules are also - allowed for "experience level" and "experience points" (valid + slightly for those: >-1% and <101% are allowed.) Only four + fields support percentage rules. Percentages for "hitpoints" + and "power" are straightforward; they're based on the corre- + sponding maximum field. Percentage highlight rules are also + allowed for "experience level" and "experience points" (valid when the showexp option is enabled). For those, the percentage - is based on the progress from the start of the current experi- - ence level to the start of the next level. So if level 2 - starts at 20 points and level 3 starts at 40 points, having 30 - points is 50% and 35 points is 75%. 100% is unattainable for - experience because you'll gain a level and the calculations - will be reset for that new level, but a rule for =100% is + is based on the progress from the start of the current experi- + ence level to the start of the next level. So if level 2 + starts at 20 points and level 3 starts at 40 points, having 30 + points is 50% and 35 points is 75%. 100% is unattainable for + experience because you'll gain a level and the calculations + will be reset for that new level, but a rule for =100% is allowed and matches the special case of being exactly 1 experi- ence point short of the next level. - * absolute value sets the attribute when the field value matches - that number. The number must be 0 or higher, except for - "armor-class' which allows negative values, and may optionally - be preceded by `='. If the number is preceded by `<=' or `>=' - instead, it also matches when value is below or above. If the + * absolute value sets the attribute when the field value matches + that number. The number must be 0 or higher, except for + "armor-class' which allows negative values, and may optionally + be preceded by `='. If the number is preceded by `<=' or `>=' + instead, it also matches when value is below or above. If the prefix is `<' or `>', only match when strictly above or below. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6472,19 +6472,19 @@ - * criticalhp only applies to the hitpoints field and only when + * criticalhp only applies to the hitpoints field and only when current hit points are below a threshold (which varies by maxi- - mum hit points and experience level). When the threshold is - met, a criticalhp rule takes precedence over all other hit- + mum hit points and experience level). When the threshold is + met, a criticalhp rule takes precedence over all other hit- points rules. - * text match sets the attribute when the field value matches the - text. Text matches can only be used for "alignment", "carry- - ing-capacity", "hunger", "dungeon-level", and "title". For - title, only the role's rank title is tested; the character's + * text match sets the attribute when the field value matches the + text. Text matches can only be used for "alignment", "carry- + ing-capacity", "hunger", "dungeon-level", and "title". For + title, only the role's rank title is tested; the character's name is ignored. - The in-game options menu can help you determine the correct syn- + The in-game options menu can help you determine the correct syn- tax for a configuration file. The whole feature can be disabled by setting option statushilites @@ -6509,26 +6509,26 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set from + The options that are used to select a particular symbol set from the symbol file are: symset Set the name of the symbol set that you want to load. roguesymset - Set the name of the symbol set that you want to load for display on + Set the name of the symbol set that you want to load for display on the rogue level. - You can also override one or more symbols using the SYMBOLS and - ROGUESYMBOLS configuration file options. Symbols are specified as + You can also override one or more symbols using the SYMBOLS and + ROGUESYMBOLS configuration file options. Symbols are specified as name:value pairs. Note that NetHack escape-processes the value string - in conventional C fashion. This means that \ is a prefix to take the - following character literally. Thus \ needs to be represented as \\. - The special prefix form \m switches on the meta bit in the symbol - value, and the ^ prefix causes the following character to be treated + in conventional C fashion. This means that \ is a prefix to take the + following character literally. Thus \ needs to be represented as \\. + The special prefix form \m switches on the meta bit in the symbol + value, and the ^ prefix causes the following character to be treated - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6594,7 +6594,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6660,7 +6660,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6726,7 +6726,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6769,30 +6769,30 @@ Notes: - * Several symbols in this table appear to be blank. They are the + * Several symbols in this table appear to be blank. They are the space character, except for S_pet_override and S_hero_override which - don't have any default value and can only be used if enabled in the + don't have any default value and can only be used if enabled in the "sysconf" file. - * S_rock is misleadingly named; rocks and stones use S_gem. Statues - and boulders are the rock being referred to, but since version - 3.6.0, statues are displayed as the monster they depict. So S_rock - is only used for boulders and not used at all if overridden by the + * S_rock is misleadingly named; rocks and stones use S_gem. Statues + and boulders are the rock being referred to, but since version + 3.6.0, statues are displayed as the monster they depict. So S_rock + is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.16. Customizing Map Glyph Representations Using Unicode - If your platform or terminal supports the display of UTF-8 char- + If your platform or terminal supports the display of UTF-8 char- acter sequences, you can customize your game display by assigning Uni- - code codepoint values and red-green-blue colors to glyph representa- - tions. The customizations can be specified for use with a symset that - has a UTF8 handler within the symbols file such as the enhanced1 set, + code codepoint values and red-green-blue colors to glyph representa- + tions. The customizations can be specified for use with a symset that + has a UTF8 handler within the symbols file such as the enhanced1 set, or individually within your nethack.rc file. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6804,53 +6804,53 @@ The format for defining a glyph representation is: - OPTIONS=glyph:glyphid/U+nnnn/R-G-B + OPTIONS=glyph:glyphname/U+nnnn/R-G-B - The window port that is active needs to provide support for dis- - playing UTF-8 character sequences and explicit red-green-blue colors + The window port that is active needs to provide support for dis- + playing UTF-8 character sequences and explicit red-green-blue colors in order for the glyph representation to be visible. For example, the - following line in your configuration file will cause the glyph repre- - sentation for glyphid G_pool to use Unicode codepoint U+224B and the + following line in your configuration file will cause the glyph repre- + sentation for glyphname G_pool to use Unicode codepoint U+224B and the color represented by R-G-B value 0-0-160: OPTIONS=glyph:G_pool/U+224B/0-0-160 - The list of acceptable glyphid's can be produced by nethack --dumpg- - lyphids. Individual NetHack glyphs can be specified using the G_ pre- - fix, or you can use an S_ symbol for a glyphid and store the custom - representation for all NetHack glyphs that would map to that particu- - lar symbol. + The list of acceptable glyphnames can be produced by nethack --dumpg- + lyphnames. Individual NetHack glyphs can be specified using the G_ + prefix, or you can use an S_ symbol for a glyphname and store the cus- + tom representation for all NetHack glyphs that would map to that par- + ticular symbol. - You will need to select a symset with a UTF8 handler to enable + You will need to select a symset with a UTF8 handler to enable the display of the customizations, such as the Enhanced symset. 9.17. Configuring NetHack for Play by the Blind - NetHack can be set up to use only standard ASCII characters for - making maps of the dungeons. This makes even the MS-DOS versions of - NetHack (which use special line-drawing characters by default) com- - pletely accessible to the blind who use speech and/or Braille access - technologies. Players will require a good working knowledge of their + NetHack can be set up to use only standard ASCII characters for + making maps of the dungeons. This makes even the MS-DOS versions of + NetHack (which use special line-drawing characters by default) com- + pletely accessible to the blind who use speech and/or Braille access + technologies. Players will require a good working knowledge of their screen-reader's review features, and will have to know how to navigate - horizontally and vertically character by character. They will also + horizontally and vertically character by character. They will also find the search capabilities of their screen-readers to be quite valu- - able. Be certain to examine this Guidebook before playing so you have + able. Be certain to examine this Guidebook before playing so you have an idea what the screen layout is like. You'll also need to be able to - locate the PC cursor. It is always where your character is located. - Merely searching for an @-sign will not always find your character - since there are other humanoids represented by the same sign. Your - screen-reader should also have a function which gives you the row and - column of your review cursor and the PC cursor. These co-ordinates + locate the PC cursor. It is always where your character is located. + Merely searching for an @-sign will not always find your character + since there are other humanoids represented by the same sign. Your + screen-reader should also have a function which gives you the row and + column of your review cursor and the PC cursor. These co-ordinates are often useful in giving players a better sense of the overall loca- tion of items on the screen. - NetHack can also be compiled with support for sending the game + NetHack can also be compiled with support for sending the game messages to an external program, such as a text-to-speech synthesizer. - If the "#version" extended command shows "external program as a mes- - sage handler", your NetHack has been compiled with the capability. - When compiling NetHack from source on Linux and other POSIX systems, - define MSGHANDLER to enable it. To use the capability, set the envi- - ronment variable NETHACK_MSGHANDLER to an executable, which will be + If the "#version" extended command shows "external program as a mes- + sage handler", your NetHack has been compiled with the capability. + When compiling NetHack from source on Linux and other POSIX systems, + define MSGHANDLER to enable it. To use the capability, set the envi- + ronment variable NETHACK_MSGHANDLER to an executable, which will be executed with the game message as the program's only parameter. The most crucial settings to make the game more accessible are: @@ -6858,7 +6858,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6878,8 +6878,8 @@ Show menus on a cleared screen and aligned to the left edge. number_pad - A lot of speech access programs use the number-pad to review the - screen. If this is the case, disable the number_pad option and use + A lot of speech access programs use the number-pad to review the + screen. If this is the case, disable the number_pad option and use the traditional Rogue-like commands. paranoid_confirmation:swim @@ -6889,11 +6889,11 @@ Adds direction or location information to messages. spot_monsters - Shows a message when hero notices a monster; combine with accessi- + Shows a message when hero notices a monster; combine with accessi- blemsg. mon_movement - Shows a message when hero notices a monster movement; combine with + Shows a message when hero notices a monster movement; combine with spot_monsters and accessiblemsg. autodescribe @@ -6903,15 +6903,15 @@ Give feedback messages when interesting map locations change. mention_walls - Give feedback messages when walking towards a wall or when travel + Give feedback messages when walking towards a wall or when travel command was interrupted. whatis_coord:compass - When targeting with cursor, describe the cursor position with coor- + When targeting with cursor, describe the cursor position with coor- dinates relative to your character. whatis_filter:area - When targeting with cursor, filter possible locations so only those + When targeting with cursor, filter possible locations so only those in the same area (eg. same room, or same corridor) are considered. whatis_moveskip @@ -6919,12 +6919,12 @@ instead of moving 8 units at a time. nostatus_updates - Prevent updates to the status lines at the bottom of the screen, if - your screen-reader reads those lines. The same information can be + Prevent updates to the status lines at the bottom of the screen, if + your screen-reader reads those lines. The same information can be seen via the "#attributes" command. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -6939,25 +6939,28 @@ 9.18. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system adminis- - trator should set up a global configuration; this is a file in the - same format as the traditional per-user configuration file (see - above). This file should be named sysconf and placed in the same - directory as the other NetHack support files. The options recognized - in this file are listed below. Any option not set uses a compiled-in + If NetHack is compiled with the SYSCF option, a system adminis- + trator should set up a global configuration; this is a file in the + same format as the traditional per-user configuration file (see + above). This file should be named sysconf and placed in the same + directory as the other NetHack support files. The options recognized + in this file are listed below. Any option not set uses a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed to - play in debug mode (commonly referred to as wizard mode). A value - of a single asterisk (*) allows anyone to start a game in debug + WIZARDS = A space-separated list of user names who are allowed to + play in debug mode (commonly referred to as wizard mode). A value + of a single asterisk (*) allows anyone to start a game in debug mode. - SHELLERS = A list of users who are allowed to use the shell escape + SHELLERS = A list of users who are allowed to use the shell escape command (!). The syntax is the same as WIZARDS. EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. + GENERICUSERS = A list of user names that should prompt ``Who are + you?'' rather than become a character's name. + MSGHANDLER = A path and filename of executable. Whenever a message- window message is shown, NetHack runs this program. The program will get the message as the only parameter. @@ -6984,13 +6987,10 @@ The following four options affect the score file: - PERSMAX = Maximum number of entries for one person. - - ENTRYMAX = Maximum number of entries in the score file. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7000,6 +7000,10 @@ + PERSMAX = Maximum number of entries for one person. + + ENTRYMAX = Maximum number of entries in the score file. + POINTSMIN = Minimum number of points to get an entry in the score file. @@ -7026,7 +7030,7 @@ ing placeholders: %% - literal `%' - %v - version (eg. "3.7.0-0") + %v - version (eg. "5.0.0-0") %u - game UID %t - game start time, UNIX timestamp format %T - current time, UNIX timestamp format @@ -7047,16 +7051,12 @@ extremely large unless it is actively maintained. CRASHREPORTURL = If set to - https://www.nethack.org/links/cr-37BETA.html and support is compiled + https://www.nethack.org/links/cr-5.0.0.html and support is compiled in, brings up a browser window pre-populated with the information needed to report a problem if the game panics or ends up in an - internally inconsistent state, or if the #bugreport command is - invoked. - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7066,6 +7066,9 @@ + internally inconsistent state, or if the #bugreport command is + invoked. + 10. Scoring NetHack maintains a list of the top scores or scorers on your @@ -7116,13 +7119,10 @@ the game with the -D command-line switch or with the playmode:debug option. - For some systems, the player must be logged in under a particular - user name to be allowed to use debug mode; for others, the hero must - be given a particular character name (but may be any role; there's no - connection between "wizard mode" and the Wizard role). Attempting to - NetHack 3.7.0 April 16, 2026 + + NetHack 5.0.0 July 4, 2026 @@ -7132,6 +7132,10 @@ + For some systems, the player must be logged in under a particular + user name to be allowed to use debug mode; for others, the hero must + be given a particular character name (but may be any role; there's no + connection between "wizard mode" and the Wizard role). Attempting to start a game in debug mode when not allowed or not available will result in falling back to explore mode instead. @@ -7181,14 +7185,10 @@ Eric Hendrickson, Izchak Miller, Eric S. Raymond, John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack 3.0c. - NetHack 3.0 was ported to the Atari by Eric R. Smith, to OS/2 by - Timo Hakulinen, and to VMS by David Gentzel. The three of them and - Kevin Darcy later joined the main NetHack Development Team to produce - subsequent revisions of 3.0. - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7198,6 +7198,11 @@ + NetHack 3.0 was ported to the Atari by Eric R. Smith, to OS/2 by + Timo Hakulinen, and to VMS by David Gentzel. The three of them and + Kevin Darcy later joined the main NetHack Development Team to produce + subsequent revisions of 3.0. + Olaf Seibert ported NetHack 2.3 and 3.0 to the Amiga. Norm Meluch, Stephen Spackman and Pierre Martineau designed overlay code for PC NetHack 3.0. Johnny Lee ported NetHack 3.0 to the Macintosh. @@ -7247,14 +7252,9 @@ don't extend to individual monster and object types, just replacements for monster and object classes (so one custom image for all "a" insects and another for all "[" armor and so forth, not separate - images for beetles and ants or for cloaks and boots). - - Warwick Allison wrote a graphically displayed version of NetHack - for the Atari where the tiny pictures were described as "icons" and - were distinct for specific types of monsters and objects rather than - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7264,6 +7264,11 @@ + images for beetles and ants or for cloaks and boots). + + Warwick Allison wrote a graphically displayed version of NetHack + for the Atari where the tiny pictures were described as "icons" and + were distinct for specific types of monsters and objects rather than just their classes. He contributed them to the NetHack Development Team which rechristened them "tiles", original usage which has subse- quently been picked up by various other games. NetHack's tiles sup- @@ -7312,15 +7317,10 @@ source code patch only, without any ready-to-play distribution for systems that usually had such. - (To anyone considering resurrecting an old version: all versions - before 3.2.3 had a Y2K bug. The high scores file and the log file - contained dates which were formatted using a two-digit year, and - 1999's year 99 was followed by 2000's year 100. That got written out - successfully but it unintentionally introduced an extra column in the - file layout which prevented score entries from being read back in cor- - NetHack 3.7.0 April 16, 2026 + + NetHack 5.0.0 July 4, 2026 @@ -7330,6 +7330,12 @@ + (To anyone considering resurrecting an old version: all versions + before 3.2.3 had a Y2K bug. The high scores file and the log file + contained dates which were formatted using a two-digit year, and + 1999's year 99 was followed by 2000's year 100. That got written out + successfully but it unintentionally introduced an extra column in the + file layout which prevented score entries from being read back in cor- rectly, interfering with insertion of new high scores and with retrieval of old character names to use for random ghost and statue names in the current game.) @@ -7378,15 +7384,9 @@ Ron Van Iwaarden was the sole maintainer of NetHack for OS/2 the past several releases. Unfortunately Ron's last OS/2 machine stopped - working in early 2006. A great many thanks to Ron for keeping NetHack - alive on OS/2 all these years. - - Janne Salmijarvi and Teemu Suikki maintained and enhanced the - Amiga port of 3.4 after Janne Salmijarvi resurrected it for 3.3.1. - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7396,6 +7396,12 @@ + working in early 2006. A great many thanks to Ron for keeping NetHack + alive on OS/2 all these years. + + Janne Salmijarvi and Teemu Suikki maintained and enhanced the + Amiga port of 3.4 after Janne Salmijarvi resurrected it for 3.3.1. + Christian "Marvin" Bressler maintained 3.4 for the Atari after he resurrected it for 3.3.1. @@ -7417,42 +7423,36 @@ as a suitable release, it was decided that the version numbers present on that code snapshot would be retired and never used in an official NetHack release. An announcement was posted on the NetHack Develop- - ment Team's official nethack.org website to that effect, stating that - there would never be a 3.4.4, 3.5, or 3.5.0 official release version. + ment Team's official https://www.nethack.org website to that effect, + stating that there would never be a 3.4.4, 3.5, or 3.5.0 official + release version. - In January 2015, preparation began for the release of NetHack + In January 2015, preparation began for the release of NetHack 3.6. - At the beginning of development for what would eventually get - released as 3.6.0, the NetHack Development Team consisted of Warwick - Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, - Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and - Paul Winner. In early 2015, ahead of the release of 3.6.0, new mem- - bers Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack + At the beginning of development for what would eventually get + released as 3.6.0, the NetHack Development Team consisted of Warwick + Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie Collet, + Ken Lorber, Dean Luick, Pat Rankin, Mike Stephenson, Janet Walz, and + Paul Winner. In early 2015, ahead of the release of 3.6.0, new mem- + bers Sean Hunt, Pasi Kallinen, and Derek S. Ray joined the NetHack Development Team. - Near the end of the development of 3.6.0, one of the significant - inspirations for many of the humorous and fun features found in the + Near the end of the development of 3.6.0, one of the significant + inspirations for many of the humorous and fun features found in the game, author Terry Pratchett, passed away. NetHack 3.6.0 introduced a tribute to him. - 3.6.0 was released in December 2015, and merged work done by the - development team since the release of 3.4.3 with some of the beloved - community patches. Many bugs were fixed and some code was restruc- + 3.6.0 was released in December 2015, and merged work done by the + development team since the release of 3.4.3 with some of the beloved + community patches. Many bugs were fixed and some code was restruc- tured. - The NetHack Development Team, as well as Steve VanDevender and - Kevin Smolkowski, ensured that NetHack 3.6 continued to operate on - various UNIX flavors and maintained the X11 interface. - - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained - the port of NetHack 3.6 for MacOS. - - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex - Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the + The NetHack Development Team, as well as Steve VanDevender and + Kevin Smolkowski, ensured that NetHack 3.6 continued to operate on - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7462,47 +7462,144 @@ + various UNIX flavors and maintained the X11 interface. + + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick maintained + the port of NetHack 3.6 for MacOS. + + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex + Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir maintained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for NetHack - 3.6, hindered by limited access. Kevin Smolkowski has updated and - tested it for the most recent version of OpenVMS (V8.4 as of this + Pat Rankin attempted to keep the VMS port running for NetHack + 3.6, hindered by limited access. Kevin Smolkowski has updated and + tested it for the most recent version of OpenVMS (V8.4 as of this writing) on Alpha and Integrity (aka Itanium aka IA64) but not VAX. - Ray Chason resurrected the MS-DOS port for 3.6 and contributed + Ray Chason resurrected the MS-DOS port for 3.6 and contributed the necessary updates to the community at large. - In late April 2018, several hundred bug fixes for 3.6.0 and some - new features were assembled and released as NetHack 3.6.1. The - NetHack Development Team at the time of release of 3.6.1 consisted of - Warwick Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie - Collet, Pasi Kallinen, Ken Lorber, Dean Luick, Patric Mueller, Pat - Rankin, Derek S. Ray, Alex Smith, Mike Stephenson, Janet Walz, and + In late April 2018, several hundred bug fixes for 3.6.0 and some + new features were assembled and released as NetHack 3.6.1. The + NetHack Development Team at the time of release of 3.6.1 consisted of + Warwick Allison, Michael Allison, Ken Arromdee, David Cohrs, Jessie + Collet, Pasi Kallinen, Ken Lorber, Dean Luick, Patric Mueller, Pat + Rankin, Derek S. Ray, Alex Smith, Mike Stephenson, Janet Walz, and Paul Winner. In early May 2019, another 320 bug fixes along with some enhance- ments and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting team - participant for decades, joined the NetHack Development Team in late + Bart House, who had contributed to the game as a porting team + participant for decades, joined the NetHack Development Team in late May 2019. - NetHack 3.6.3 was released on December 5, 2019 containing over + NetHack 3.6.3 was released on December 5, 2019 containing over 190 bug fixes to NetHack 3.6.2. - NetHack 3.6.4 was released on December 18, 2019 containing a + NetHack 3.6.4 was released on December 18, 2019 containing a security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing some + NetHack 3.6.5 was released on January 27, 2020 containing some security fixes and a small number of bug fixes. NetHack 3.6.6 was released on March 8, 2020 containing a security fix and some bug fixes. - NetHack 3.6.7 was released on February 16, 2023 containing a + NetHack 3.6.7 was released on February 16, 2023 containing a security fix and some bug fixes. - The official NetHack web site is maintained by Ken Lorber at + Development work for the major release to follow NetHack 3.6 + began in 2015 around the same time as NetHack 3.6.0 was being + released. That development work continued in parallel to each of the + NetHack 3.6 releases from 2015 through 2023, and continued until the + end of April 2026. For the first time, that development was shared + publicly on GitHub and SourceForge as it occurred. It was done under + the label NetHack-3.7 work-in-progress (WIP), although the version + + + NetHack 5.0.0 July 4, 2026 + + + + + + NetHack Guidebook 115 + + + + number for the next release had not yet been solidified. + + Exposure of the development to the public brought many good + things, and some challenges. People were able to observe and criticize + changes and new features almost immediately, and they often did. The + GitHub pull request system made it straightforward for people to con- + tribute directly to development. Contributions resolved many, many + bugs in the game and we thank all the contributors. + + In early 2026, with the game development getting stable enough to + consider initiating an official release, the devteam reviewed the + nature and number of changes in the game. It was clear that there was + sufficient depth and breadth to warrant a major release and version + 5.0 was decided on. That's a new major release over 3.x, without + opening up any ambiguity or confusion with existing variants that + there might have been had it been released as version 4.0. + + NetHack 5.0.0 was released on May 2, 2026. + + The source code for NetHack 5.0.0 was modified and modernized to + be compliant with the C99 standard. The 5.0.0 release contained over + 3100 fixes, changes, and updated features. + + NetHack 5.0 was the first version to replace the lex and yacc + level and dungeon compilers of past versions, with a new Lua inter- + preter-based approach to provide those elements. Lua is also used for + the quest texts in NetHack 5.0.0. The entire development team acknowl- + edges the work done by Pasi Kallinen to make that happen. + + At the time of the NetHack 5.0 release, the core development + team, active and erstwhile, included Warwick Allison, Michael Allison, + Ken Arromdee, David Cohrs, Jessie Collet, Bart House, Kevin Hugo, Pasi + Kallinen, Ken Lorber, Dean Luick, Pat Rankin, Derek S. Ray, Alex + Smith, Patric Mueller, Mike Stephenson, Janet Walz, Paul Winner. + + Ken Lorber, Pat Rankin, Patrick Mueller and Michael Allison + helped ensure that NetHack 5.0 would run on macOS. + + Ingo Paschke somehow managed to revive a NetHack 5.0 port for the + Amiga, using a cross-compiler on a modern platform to do so. His work + was shared so others can straightforwardly produce NetHack 5.0 for the + Amiga thanks to his efforts. + + Ray Chason contributed the majority of maintenance work for the + NetHack 5.0 MS-DOS port, including porting the curses interface to it. + Michael Allison ensured that NetHack 5.0 core changes continued to + work with the msdos port and keep it alive. Cross-compiling the MS- + DOS port has helped make that possible and mostly painless. + + People that contributed to the Windows port of NetHack 5.0 since + the development of NetHack 5.0 began over eleven years ago, included + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, Alex Kompel, + Dion Nicolaas, Derek S. Ray and Yitzhak Sapir. + + + + NetHack 5.0.0 July 4, 2026 + + + + + + NetHack Guidebook 116 + + + + With sadness, the devteam would like to acknowledge and remember + the past contributions from the late Ron Van Iwaarden, who was the + sole maintainer of NetHack for OS/2 for several past NetHack releases. + Ron will be missed. + + The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. @@ -7518,24 +7615,53 @@ - NetHack 3.7.0 April 16, 2026 - NetHack Guidebook 115 + + + + + + + + + + + + + + + + + + + 12.1. Special Thanks - On behalf of the NetHack community, thank you very much once - again to M. Drew Streib and Pasi Kallinen for providing a public - NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy - Thomson for hardfought.org. Thanks to all those unnamed dungeoneers - who invest their time and effort into annual NetHack tournaments such - as Junethack, The November NetHack Tournament, and in days past, + On behalf of the NetHack community, thank you very much once + again to M. Drew Streib and Pasi Kallinen for providing a public + NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy + Thomson for hardfought.org. Thanks to all those unnamed dungeoneers + + + NetHack 5.0.0 July 4, 2026 + + + + + + NetHack Guidebook 117 + + + + who invest their time and effort into annual NetHack tournaments such + as Junethack, The November NetHack Tournament, and in days past, devnull.net (gone for now, but not forgotten). @@ -7580,21 +7706,9 @@ 12.2. Dungeoneers - From time to time, some depraved individual out there in netland - sends a particularly intriguing modification to help out with the - - - NetHack 3.7.0 April 16, 2026 - - - - - - NetHack Guidebook 116 - - - - game. The NetHack Development Team sometimes makes note of the names + From time to time, some depraved individual out there in netland + sends a particularly intriguing modification to help out with the + game. The NetHack Development Team sometimes makes note of the names of the worst of these miscreants in this, the list of Dungeoneers: @@ -7602,121 +7716,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Adam Aronow J. Ali Harlow Mikko Juola - Alex Kompel Janet Walz Nathan Eady - Alex Smith Janne Salmijarvi Norm Meluch - Andreas Dorn Jean-Christophe Collet Olaf Seibert - Andy Church Jeff Bailey Pasi Kallinen - Andy Swanson Jochen Erwied Pat Rankin - Andy Thomson John Kallen Patric Mueller - Ari Huttunen John Rupley Paul Winner - Bart House John S. Bien Pierre Martineau - Benson I. Margulies Johnny Lee Ralf Brown - Bill Dyer Jon W{tte Ray Chason - - - - NetHack 3.7.0 April 16, 2026 - - - - - - NetHack Guidebook 117 - - - - Boudewijn Waijers Jonathan Handler Richard Addison - Bruce Cox Joshua Delahunty Richard Beigel - Bruce Holloway Karl Garrison Richard P. Hughey - Bruce Mewborne Keizo Yamamoto Rob Menke - Carl Schelin Keith Simpson Robin Bandy - Chris Russo Ken Arnold Robin Johnson - David Cohrs Ken Arromdee Roderick Schertler - David Damerell Ken Lorber Roland McGrath - David Gentzel Ken Washikita Ron Van Iwaarden - David Hairston Kevin Darcy Ronnen Miller - Dean Luick Kevin Hugo Ross Brown - Del Lamb Kevin Sitze Sascha Wostmann - Derek S. Ray Kevin Smolkowski Scott Bigham - Deron Meranda Kevin Sweet Scott R. Turner - Dion Nicolaas Lars Huttar Sean Hunt - Dylan O'Donnell Leon Arnott Stephen Spackman - Eric Backus M. Drew Streib Stefan Thielscher - Eric Hendrickson Malcolm Ryan Stephen White - Eric R. Smith Mark Gooderum Steve Creps - Eric S. Raymond Mark Modrall Steve Linhart - Erik Andersen Marvin Bressler Steve VanDevender - Fredrik Ljungdahl Matthew Day Teemu Suikki - Frederick Roeber Merlyn LeRoy Tim Lennan - Gil Neiger Michael Allison Timo Hakulinen - Greg Laskin Michael Feir Tom Almy - Greg Olson Michael Hamel Tom West - Gregg Wonderly Michael Sokolov Warren Cheung - Hao-yang Wang Mike Engber Warwick Allison - Helge Hafting Mike Gallop Yitzhak Sapir - Irina Rempt-Drijfhout Mike Passaretti - Izchak Miller Mike Stephenson - - - - - - - - - - - - - - - - - - - - - - - - - - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 @@ -7726,7 +7726,73 @@ - Brand and product names are trademarks or registered trademarks + Adam Aronow Irina Rempt-Drijfhout Mike Gallop + Alex Kompel Izchak Miller Mike Passaretti + Alex Smith J. Ali Harlow Mike Stephenson + Andreas Dorn Janet Walz Mikko Juola + Andy Church Janne Salmijarvi Nathan Eady + Andy Swanson Jean-Christophe Collet Norm Meluch + Andy Thomson Jeff Bailey Olaf Seibert + Ari Huttunen Jochen Erwied Pasi Kallinen + Bart House John Kallen Pat Rankin + Benson I. Margulies John Rupley Patric Mueller + Bill Dyer John S. Bien Paul Winner + Boudewijn Waijers Johnny Lee Pierre Martineau + Bruce Cox Jon W{tte Ralf Brown + Bruce Holloway Jonathan Handler Ray Chason + Bruce Mewborne Joshua Delahunty Richard Addison + Cameron Root Karl Garrison Richard Beigel + Carl Schelin Keizo Yamamoto Richard P. Hughey + Chris Russo Keith Simpson Rob Menke + David Cohrs Ken Arnold Robin Bandy + David Damerell Ken Arromdee Robin Johnson + David Gentzel Ken Lorber Roderick Schertler + David Hairston Ken Washikita Roland McGrath + Dean Luick Kestrel Gregorich-Trevor Ron Van Iwaarden + Del Lamb Kevin Darcy Ronnen Miller + Derek S. Ray Kevin Hugo Ross Brown + Deron Meranda Kevin Sitze Sascha Wostmann + Dion Nicolaas Kevin Smolkowski Scott Bigham + Dylan O'Donnell Kevin Sweet Scott R. Turner + Eric Backus Lars Huttar Sean Hunt + Eric Hendrickson Leon Arnott Stephen Spackman + Eric R. Smith M. Drew Streib Stefan Thielscher + Eric S. Raymond Malcolm Ryan Stephen White + Erik Andersen Mark Gooderum Steve Creps + Fredrik Ljungdahl Mark Modrall Steve Linhart + Frederick Roeber Marvin Bressler Steve VanDevender + G. Branden Robinson Matthew Day Teemu Suikki + Gil Neiger Merlyn LeRoy Tim Lennan + Greg Laskin Michael Allison Timo Hakulinen + Greg Olson Michael Feir Tom Almy + Gregg Wonderly Michael Hamel Tom West + Hao-yang Wang Michael Meyer Warren Cheung + Helge Hafting Michael Sokolov Warwick Allison + Ingo Paschke Mike Engber Yitzhak Sapir + + + + + + + + + + + + + + NetHack 5.0.0 July 4, 2026 + + + + + + NetHack Guidebook 119 + + + + Brand and product names are trademarks or registered trademarks of their respective holders. @@ -7782,7 +7848,7 @@ - NetHack 3.7.0 April 16, 2026 + NetHack 5.0.0 July 4, 2026 diff --git a/doc/config.nh b/doc/config.nh index 920074b3e..00b8a8a08 100644 --- a/doc/config.nh +++ b/doc/config.nh @@ -1,8 +1,8 @@ -# NetHack 3.7 config.nh $NHDT-Date: 1745978702 2025/04/29 18:05:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 config.nh $NHDT-Date: 1745978702 2025/04/29 18:05:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2016 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # -# Sample run-time configuration file for NetHack 3.7.0 +# Sample run-time configuration file for NetHack 5.0.0 # usually named ".nethackrc" (note leading dot; location # depends upon the type of system nethack is running on). # diff --git a/doc/dlb.6 b/doc/dlb.6 index b58b12164..e314989d2 100644 --- a/doc/dlb.6 +++ b/doc/dlb.6 @@ -11,6 +11,8 @@ .. .NB $NHDT-Branch: keni-gitset $ .NR $NHDT-Revision: 1.13 $ +.ie \n(.g .ds ^ \(ha +.el .ds ^ ^ .\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or .\" before/after last/first 2 characters of a word. @@ -38,7 +40,7 @@ dlb \- NetHack data librarian }\c .RB [ v ]\c .B I -.IR list-file +.I list-file .PP .B dlb {\c @@ -69,18 +71,18 @@ Unlike is configured with a default set of file names to process. .ig .PP -^?ALLDOCS +\*^?ALLDOCS This facility is optional and may be excluded during NetHack configuration. -^: -^?DLB +\*^: +\*^?DLB This facility is optional but is included in this NetHack configuration. -^: +\*^: This facility is optional and was excluded from this NetHack configuration. -^. -^. +\*^. +\*^. .. .SS Operations .B c @@ -144,7 +146,7 @@ Kenneth Lorber Not a good .I tar emulation; -.B - +.B \- does not mean stdin or stdout. .IP \(bu Should include an optional compression facility. @@ -152,5 +154,12 @@ Should include an optional compression facility. Not all read-only files for NetHack can be read out of an archive; examining the source is the only way to know which files can be. .SH COPYRIGHT -This file is Copyright (C) \*(Na, \*(Nd for version \*(Nb:\*(Nr. -NetHack may be freely redistributed. See license for details. +.\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 +.\" offers no test for special character availability, and its feature +.\" set too closely resembles DWB 3.3 to test for it. Use a string with +.\" any nroff-mode formatter not claiming groff compatiblity. +.ds co \(co +.if !\n(.g .if n .ds co (C)\" in principle, should be just "c" +This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. +NetHack may be freely redistributed. +See license for details. diff --git a/doc/fixes3-6-7.txt b/doc/fixes3-6-7.txt index e34d9f1b4..6ac447eb6 100644 --- a/doc/fixes3-6-7.txt +++ b/doc/fixes3-6-7.txt @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.21 $ $NHDT-Date: 1683746783 2023/05/10 19:26:23 $ +$NHDT-Branch: to500 $:$NHDT-Revision: 1.2 $ $NHDT-Date: 1777409988 2026/04/28 20:59:48 $ fixes36.7 contains a summary of changes made to 3.6.6 in order to produce 3.6.7 as well as any post-release fixes in binaries. @@ -7,7 +7,7 @@ produce 3.6.7 as well as any post-release fixes in binaries. General Fixes and Modified Features ----------------------------------- during engraving, spaces were counted instead of non-space (cherry-pick of - 4e0a1e04 from NetHack-3.7) + 4e0a1e04 from NetHack WIP) avoid potential buffer overflow in append_str() resolve missing dependency in NetHack.sln code in include/tradstdc.h was trying to suppress warn_unused result by @@ -29,7 +29,7 @@ windows: the console.rc file had outdated information stating 3.6.3 when the official 3.6.6 binary was built. windows: switch from using keyhandling dll's to incorporating the three variations (default, ray, 340) in sys/winnt/nttty.c -curses: cherry-picked selectsaved code from 3.7 for menu of save files +curses: cherry-picked selectsaved code from NetHack WIP for menu of save files NetHackW: fix delay rendering of cursor when using farlook @@ -63,9 +63,11 @@ makedefs can produce individual bogusmon, engrave and epitaph files drinkfountain() fate 24 to curse objects could end up cursing objects on the floor chain instead of the intended inventory object chain proceed with showpaths option even if the sysconf file is missing -avoid memory leak in mk_artifact(); cherry-pick of 3cca4f27 from 3.7 WIP +avoid memory leak in mk_artifact(); cherry-pick of 3cca4f27 from NetHack WIP avoid using col in Guidebook build, since some distros no longer include it, particularly some that use musl libc back-port some nroff macro updates for Guidebook prevent a crash when using 'O' to interactively set a text match highlight for hunger +avoid a reported obuf reuse in use_misc() when using a bullwhip + diff --git a/doc/fixes3-7-0.txt b/doc/fixes5-0-0.txt similarity index 99% rename from doc/fixes3-7-0.txt rename to doc/fixes5-0-0.txt index 1f281f47c..7171ab1f6 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes5-0-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1649 $ $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1649 $ $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ General Fixes and Modified Features ----------------------------------- @@ -1451,7 +1451,7 @@ some theft messages by nymphs force "she", others use default monster naming if a nymph stole worn armor and got killed (perhaps by pet) before hero's next turn, feedback would be "You finish taking off your suit." regardless of the type of armor being taken off -when setting an option interactively [via O or 3.7's mO], if the particular +when setting an option interactively [via O or 5.0's mO], if the particular option uses a prompt to get a line of input (for compounds: 'fruit', 'scores', most numeric ones), input was treated as a comma-separated list of option[:value] rather than just the new value of that option @@ -1602,9 +1602,13 @@ when starting a new game as a monk, newsym(0,0) was being called (adjabil -> postadjabil -> see_monsters when initializing See_invisible as hero became level 1; seen 'monster' was the hero who hadn't been placed on the map yet) +incorporate a fix to prevent segfault due to rolling boulder trap +wands of digging generate less often lategame +more strict checking of dishonourable attacks +vault guard verbalization shouldn't be heard from too far away -Fixes to 3.7.0-x General Problems Exposed Via git Repository +Fixes to 5.0.0-x General Problems Exposed Via git Repository ------------------------------------------------------------ incrementing EDITLEVEL to invalidate incompatible save files was not working as intended because VERSION_COMPATIBILITY was defined as 3.7.0-0 and up @@ -2217,9 +2221,6 @@ uncursed genocide while hallucinating deliberately mis-reports hero's role as target but was also inappropriately showing it to livelog/#chronicle livelog/#chronicle for bribing a demon lord reported random monster and currency if hero was hallucinating -livelog/#chronicle for saving-grace: if saving-grace prevents hero's death, - report it [at present, it uses the livelog classification for breaking - a conduct] naming a type of item, unnaming it (with name of ), naming it again (new name or re-use of old one), then unnaming it again would issue impossible: "named object not in disco" @@ -2232,10 +2233,13 @@ when reading an engraving, suppress the addition of a trailing period if the cursed magic whistle could teleport hero on no-teleport levels give a brief explanation when receiving a wish for acquiring the Amulet teleportation traps no longer teleport you on levels made temporarily - no-teleport by the presence of a monster + no-teleport by the presence of a monster +an attempt to pick up an object from a monster's stomach would trigger + an impossible() in newsym() due to object having no ox,oy coordinates + set; set the coordinates to the monster's at the start of pick_obj() -Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository +Fixes to 5.0.0-x Platform and/or Interface Problems Exposed Via git Repository ------------------------------------------------------------------------------ curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support @@ -2899,11 +2903,6 @@ pyrolisk eggs explode when broken pauper-option to start the character with no possessions wand of secret door detection, spell of detect unseen, and wizard mode ^E now flash the cursor at each location where detection finds something -saving-grace: once per game if receiving a killing blow from full or nearly - full HP, survive with 1 HP -enlightenment/attribute disclosure for saving-grace: include a line for have - or haven't been saved (game in progress) or did or didn't get saved - (game over) via saving-grace 'selectsaved' lists "name-role-race-gend-algn" instead of just "name" in the menu of save files available to be restored 'selectsaved' prefixes "name-role-race-gend-algn" with "- " for normal play, diff --git a/doc/fixes5-0-1.txt b/doc/fixes5-0-1.txt new file mode 100644 index 000000000..e20471335 --- /dev/null +++ b/doc/fixes5-0-1.txt @@ -0,0 +1,344 @@ +NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.36 $ $NHDT-Date: 1781062909 2026/06/09 19:41:49 $ + +General Fixes and Modified Features +----------------------------------- +fix some cross-compile package filenames that still referenced 370 instead + of 500 +Use NHV macro (NHV=500) for filenames in Makefiles and/or hints files to make + it less likely to overlook or miss them next time +early startup options such as --showpaths could be run non-interactively, so + ensure that getret() doesn't prompt and wait for user input +fix issue where the new game startup message was stating 'Work-in-progress' + even when NH_DEVEL_STATUS was set to NH_STATUS_POSTRELEASE +if 'mention_decor' was set in config file or NETHACKOPTIONS, + starting the game told you that "you are standing on stairs which lead + out of the dungeon", even when the player entered the tutorial where + that wasn't true +when a vault guard was moved off the map, an impossible about trying to update + map location <0,0> was issued +doc: use full URL for nethack.org in Guidebook.mn +doc: fix a paste error in Guidebook.tex +doc: bring man pages up to date with *nix documentary conventions and ensure + their portable rendering among GNU, Heirloom Doctools, DWB 3.3, + Solaris 10, and Plan 9 troffs, and mandoc(1) +doc: fix spelling error in nethack.6 +spelling: "Flanian Pobble Bead" to "Flainian Pobble Bead" +obey statue type gender (gnome king statue in minetn-5) +fix statue and figurine genders in special levels in general +fix buffer overflow in update_topl when handling multiple items in a + container +fix random attended shrines in irregular rooms +fix experience-level up/down hilighting +cherry-pick a pair of core fixes from the m68k-wip branch to add menu + glyphs to shop bills and container tip/loot menus (pr #1539 + by ingpaschke) +tiles: make the tile for magic flute and mundane flute be exactly the + same; do the same thing for drum of earthquake and leather drum +fix a buffer overflow in reroll processing that was introduced in a + post-release 5.0.0 commit +ensure a checkpoint, aka a save_currentstate() call, isn't done before + the game is ready +add ANY_INT16 to any_types and use it for u.ux/uy/tx/ty and uz dlevel/dnum; + those are coordxy (int16_t) but the Lua bindings were treating them + as 1-byte fields, so on big-endian m68k Lua read the high byte (0) + instead of the actual value. Symptom: place_object off map <0,0> + win the tutorial. +fix an off-by-one in glyph_is_normal_piletop_obj (pr #1547 by ingpaschke) +replace the hashtable used for parsing glyphnames with sorted indices and + reduce the string allocation load during that processing (cherry-pick + of pr #1548 by ingpaschke) +for SELECTSAVE, allow utd flags for uptodate() to be passed down through + the small set of callers that eventually call uptodate() +avoid calling costly_spot(), costly_adjacent(), find_byowner(), which + all rely on shop_keeper() under the hood, in the midst of the level + loading process before all the required data structures have + been finalized +if the hero has already been told that an engraving vanished, ensure that + the engraving marker isn't still showing when prompted for a + new engraving +aklys path shouldn't be shown for locations that the hero cannot see +keep the player better-informed about status of the tether on their weapon +don't overflow svp.plname on restore (pr #1570 by chasonr) +monsters (including pets) aren't scared of the Sokoban rolling boulder traps +fix a bug in which steeds would continuously gain movement points while + being ridden +when hero's behavior makes erinyes stronger, cap level at 49 rather than 50 +with inventory item action for leash, distingluish leash-in-use from empty one +deafness check was missing from a shopkeeper message in ready_weapon() +thrown ball travel did not check for regions (pr #1595 by copperwater) +remove deprecated option --version:paste +the timeout for stasis wasn't decrementing while off-level; ensure the elapsed + time is taken into consideration upon return to the level +Some optimizations of the glyph lookup - don't produce names for swallow + glyphs that can never appear to speed up the building of the + glyph index in populate_glyphname_hash_indices; build a sorted + index for loadsyms so that it can be searched with bsearch + (pr #1612 by chasonr) +stethoscope applied to one monster disguised as another (double-trouble Wizard) + mis-described undisguised form (unintended side-effect of 5.0 commit + 064523e162f8e30bdb76186a854b9d8958f3b340) +mon_offmap() and place_monster() needed to operate on the same mstate bits +food_disappears() needed to include a tin check +cmdstr[] buffer was not being initialized in handler_rebind_keys_add() +don't catch thrown objects while asleep +don't refer to pet as "Your pet" until after the taming process has finished +checkpoint fixes (pr #1660 by k21971) +upon return to a level, catch up on remaining nutrition value by the same + percentage as the catch up for the weight +after polymorph or revival from corpse, monsters were not interacting with + the terrain until that monster's next move +fix undead corpses (zombies, etc.) now being edible +alias rings of constitution, strength, and damage, spellbook/scroll of + identification +pets left on another level no longer have their hunger postponed by the + time spent away + + +Platform- and/or Interface-Specific Fixes +----------------------------------------- +Amiga: fall back to text mode when tile mode is not viable +Amiga: Detect Workbench depth, display-database MaxDepth, and free chip RAM + if any signals AMIV can't run (e.g. A1000 with 4-colour WB) +Amiga: swap windowprocs to amii_procs before opening any screens +Amiga: disable SYSCF, drop sysconf from package; assure_syscf_file() was + killing the binary when run outside NetHack: was breaking normal + launches +Amiga: honor __stack under libnix; reference __stkinit so the linker pulls + swapstack.o from libnix.a; without it the program runs on the + inherited shell stack and crashes inside Lua / level-gen +Amiga: provide a real v4 UUID via get_nhuuid +Amiga: ship as a NetHack drawer with drawer icon and README +Amiga: ship Workbench icons for the binary and text files +Amiga: fix misleading fallback warning and stale comment +Amiga: stop rendering CLR_BLACK and CLR_WHITE as inverse video +Amiga: default number_pad:1 in shipped nethack.cnf +Amiga: promote AMIGA_INTUITION to supported so it shows up in version info +Amiga: wire altmeta option to sysflags.altmeta +Amiga: restore glyph icons in menus +Amiga: sys/amiga/README.amiga stated "Extract NH50AMI.ZIP" but it could + be named something else; added a note about the potential suffix +Amiga: `amiv_lprint_glyph` used an uninitialized `base` in tile-offset math +Amiga: `amii_clear_nhwindow` overview window never got cleared with the map +Amiga: `amii_sethipens` fell through from `NHW_TEXT` into `case -2`, clobbering + text-window pens +Amiga: `NHW_BASE`/`NHW_OVER` collided with `NHW_PERMINVENT=6`; renumbered + off `NHW_LAST_TYPE`, matching the `wintty.h` convention +Amiga: `make_menu_items` sized its output array by + `sizeof(amii_menu_item)` instead of `sizeof(menu_item)` +Amiga: `DoMenuScroll` could deref a NULL `amip` on the `SELECTUP` path +Amiga: `GlyphToIcon`'s ASCII passthrough used `> 10000` instead of `>=` +Amiga: `fopenp`'s buffer-bound check fired one byte too late +Amiga: fix port_help double-prefix path +Amiga: replace WINVERS_AMI* strcmp with WINDOWPORT() id compare +Amiga: route port paths through fqname() +Amiga: drop redundant 'either windowtype' guards +Amiga: deduplicate amii_procs and amiv_procs +Amiga: route non-menu messages from DoMenuScroll to ProcessMessage +Amiga: delete outdated/sys/amiga/ +Amiga: graphical tombstone RTG-screen fallback +Amiga: fix extended-command menu mouse-pick +Amiga: clamp amii_numcolors and guard tile CMAP loop +Amiga: fix --more-- infinite loop on overlong words +Amiga: bound BufferQueueChar; move CloseWindow out of Forbid() +Amiga: defensive NULL/bounds guards in menus and window creation +Amiga: tighten input/dialog buffer bounds +Amiga: header hygiene and palette-size constants +Amiga: drop UNTESTED AROS path; tighten fopenp separator write +Amiga: harden host-side bmp/xpm to iff converters +Amiga: tighten two minor issues from review +Amiga: fix bitmap/IFF resource handling in winchar.c +Amiga: fix overview-window crashes +Amiga: fix latent issue found in code review: fname[18]/sprintf risks + overflow for >=10 in any version field; switch to snprintf into + a wider static buffer +Amiga: fix latent issue found in code review: (1L << i) for i==31 (or + shifting into the depth-loop terminator) is undefined for signed + long;use 1UL +Amiga: fix latent issue found in code review: Drop unused cnt= from + amii_display_nhwindow's DoMenuScroll call; the menu return value + is consumed elsewhere, not here +Amiga & Atari: enable USE_BUFFERING for buffered stdio structlevel savefile + write path +curses on Windows: the number of columns was being capped by default + at 110 in cursinit.c; try to use the console width if no explicit + setting was specified in the config file; impacted both wincon + and wingui curses +curses on Windows: some early data is alloc'd for the windows console + settings in both tty and curses (pdcursesmod) prior to the + window port initialization, but only tty was freeing it; call + console_exit() in nethack_exit if window port is curses +curses on Windows: dialogs pertaining to the need for self-recover + were not visible and therefore the player had no idea that + answers were expected or why +gcc-16: tiletext.c [-Wdiscarded-qualifiers] warning suppression +libnh: update get_nhuuid() for libnhmain +libnh: sys/libnh/libnhmain.c: drop `static` on `whoami()` +libnh: rewrote sys/unix/hints/macOS.500: rewrote the libnh.a rule. The + `ar rcs libnh.a $(HOBJ) $(LIBNHSYSOBJ) liblua-$(LUA_VERSION).a` had + four problems: (a) ar archives liblua.a as a single opaque member + that macOS ld can't dereference, (b) date.o (DATE_O, kept separate + from HOBJ) was never archived, so `populate_nomakedefs` and + `nomakedefs` were missing, (c) hacklib.a was likewise omitted, and + (d) HOBJ already contains $(SYSOBJ) (with unixmain.o) and $(WINOBJ) + (the tty windowport), which duplicated symbols from libnhmain.o / + winshim.o. +libnh: sys/libnh/libnhmain.c: gate the emscripten-only code in get_nhuuid + with `#ifdef __EMSCRIPTEN__` instead of `#ifdef NHUUID` +libnh: sys/unix/hints/macOS.500 in the WANT_LIBNH block, add an explicit + `recover: lua_support` dependency (gated by MAKEFILE_TOP). When + $(GAME) is overridden to empty, the regular `recover: $(GAME)` chain + no longer triggers `lua_support`, so include/nhlua.h never gets + generated and recover.c's transitive #include of hack.h fails +libnh: export GLYPH_PILETOP_OFF constant (pr #1562 by avgas3) +Linux: add WANT_SYSTEM_LUA=1 support to the linux.500 hints files and + its included files, making it possible to avoid the 'fetch-lua' + step and the subsequent compiling of Lua; it tries to use use + the Lua5.4 package that is already installed on the system +macOS: fix ncurses build with Homebrew +MS-DOS: Fix custom colors in VESA BIOS mode (pr #1577 by chasonr) +MS-DOS: VESA mode: set the viewport size correctly so the position bar + does not overlap the map; correctly set the size to which tiles are + stretched when overview mode (F4) is selected (pr #1579 by chasonr) +MS-DOS: VESA and 16 color modes: Pass correct parameters to vga_userpan + and vesa_userpan, so the pan keys (CTRL+arrow) work correctly. Some + emulations don't report CTRL with up or down arrows, so accept + CTRL-home, CTRL-page up, CTRL page down and CTRL-end + (pr #1579 by chasonr) +MS-DOS: 16 color mode: Set the panning direction so CTRL-left and CTRL-right + pan in the same direction as 3.4.3. (pr #1579 by chasonr) +MS-DOS: makefont.lua was generating incorrect PSF fonts; there can be + multiple characters mapped to a single glyph, but the mappings + should be separated by FE bytes (pr #1581 by chasonr) +MS-DOS: accept only single character font mappings (pr #1581 by chasonr) +MS-DOS: add U+2299, U+2601 and U+2980 to the bundled fonts, so that all + symbols specified in the Extended2 symbol set are available; + also,a few more directives are added to the files, so that + FontForge can load them and display their contents + (pr #1610 by chasonr) +MS-DOS: The 16 color mode loads the font specified in font_map, and accepts + it only if its size is 8 by 16 pixels; avoid a null dereference + if the font is not found (pr #1611 by chasonr) +MS-DOS: some optimizations for tile handling; change 16-color mode and + VESA mode so that the tile is processed once, when it is first + displayed, with the result cached; Use memcpy when splitting the + image into tiles; only load the tileset once (pr #1617 by chasonr) +MS-DOS: Define a separate palette for VGA text (pr #1620 by chasonr) +MS-DOS: some conditional cleanup for SUPPRESS_GRAPHICS, TILES_IN_GLYPHMAP, + NO_TILES, WANT_WIN_CURSES=1 without WANT_WIN_TTY=1 + (pr #1632 by chasonr) +MS-DOS: support decals in all VESA modes and in 16 color mode; support + decals in the overview modes as well as the normal map mode; + provide correct highlighting for vga_redrawmap and vesa_redrawmap; + provide the hilite_pet and hilite_pile flags in the default + configuration file (pr #1649 by chasonr) +musl: musl libc does not have __sighandler_t so don't use it in the + macro definition for SIG_RET_TYPE with musl +tty: allow custom glyph colors if they're basic 16 nethack colors + on terminals with less than 256 colors +WASM: resolve some build failures in 'make CROSS_TO_WASM=1' +WASM: hints file cross-pre2.500 update to CFLAGS to include -DNHUUID +Windows: don't demand keypress on intentional exit +Windows: correct a NetHack 5.0.0 packaging error if visual studio was + used; a remnant hard-coded 370 was in package.nmake +Windows: setting any map_mode option in the config file could trigger + an app failure on launch by dereferencing a null pointer +Windows: a Windows console debug line began showing up after the sources + switched patchlevel.h NH_DEVEL_STATUS from NH_STATUS_RELEASED to + NH_STATUS_POSTRELEASE; make it only ever show if (wizard) is true +Windows: with SELECTSAVE don't display error messages to a regular player + about out-of-date save files encountered while building the + saved-game list to select from; the game doesn't offer any + action to assist with them presently, and they would have to be + dealt with external to the game, so try not to annoy +Windows: fix startup of GUI NetHackW.exe if there was an explicit + OPTIONS=windowtype:tty in the config file +Windows: fix hilite_pet on the GUI NetHackW.exe when ascii map was selected +Windows: support -a (alignment) -g (gender) -p (profession) -r (race) + command line options via genl_prag() function in earlyarg.c +Windows: in the event that there is a collision between a menu group + accelerator and an individual menu item's accelerator, disregard + the group accelerator; only known collision is '$' at this time +X11: obey timed_delay +X11: improve status lines with text attributes for status hilites, + hitpointbar, some unicode support, 3-line status +X11: fix menu windows being taller than the screen +X11: allow menu scrolling by pageup/pagedown/home/end keys +X11: toggle off perm_invent if user closes the perm inventory window +X11: fix menu group accelerators +X11: implement all text attributes for menus +X11: fix crash when loading a nonexistent font +X11: use xft to render fonts +X11: support tab-separated menu columns +X11: support BMP, GIF and PNG tiles (pr #1666 by chasonr) +X11: remove the limit on the number of widgets managed in winlabel.c; it was + possible, though difficult, to exceed the limit; tabify the + #wizcustom menu and fix X11's handling of that menu; correctly + display tabs produced by the unpaid inventory command + (pr #1668 by chasonr) +Unix: don't complain about MAXPLAYERS with unknown command line param + + +General New Features +-------------------- +sysconf option MAX_REROLL_RATE to limit rate at which rerolls are performed +idlecheckpoint config file option to update checkpoint files whenever an + input request isn't responded to within IDLECHECKPOINT_WAIT_TIME + seconds; helps ensure that a recover operation, if it turns out + to be needed, is much more current than the last level change; + support added for Windows console, Qt, and curses + + +Platform- and/or Interface-Specific New Features +------------------------------------------------ + + +NetHack Community Patches (or Variation) Included +------------------------------------------------- +NCURSES_CFLAGS was being ignored when using hints/linux.500 with only + WANT_WIN_TTY=1 and not WANT_WIN_CURSES=1 (pr #1522 by torakoya) +added a hints file netbsd.500 for NetBSD (pr #1519 by SirWumpus) + + +Code Cleanup and Reorganization +------------------------------- +add Contributing.md with some guidelines for making a pull request that + is in an acceptable format +Make all top-level .md files subject to nhsub substitutions +Fix subst for luahelper +Amiga: delete dead files and dead-macro code +Amiga: delete the .p prototype headers +Amiga: drop #if 0 dead-code blocks +Amiga: drop TESTING dev toggle in winchar.c +Amiga: collapse #ifndef CROSS_TO_AMIGA include forks +Amiga: clean up amiconf.h +Amiga: drop OPT_DISPMAP / display_map / fast_map machinery +Amiga: correct command-line flag doc in amii.hlp +Amiga: delete outdated/sys/amiga/ source folder tree +Amiga: drop legacy non-gcc compiler guards +Amiga: remove remnants of support for compiling on Amiga (the old + compilers couldn't cope with such a large codebase anymore) +Amiga: remove old conditionals for running on OS 1.3 +Amiga: remove miscellaneous unused code like TTY/BBS support, commented + out test code etc +Amiga: make INTUI_NEW_LOOK unconditional +Amiga: drop SHAREDLIB dead build flavor +Amiga: make amigapkg depend on $(GAMEBIN) +unix hints: consolidate all the bsd flavours into a single sys/unix/bsd.500 + hints file to ease maintenance going forward; use bsd make + conditional logic to carry out steps unique to NetBSD, OpenBSD, + FreeBSD, GhostBSD +unix hints: the Makefiles distributed by sys/unix/setup.sh will now check + for the presence of a make.prefs at the top of the NetHack tree, + and will include it if it exists; make.prefs must contain valid + Makefile syntax and can be used to set preferences instead of + placing them on the make command line; Use GNU make syntax for GNU + make, and use bsd make syntax for bsd make +share a single copy of nhuuid generation code between Amiga, Atari, and msdos + by way of sys/share/pcmain.c (cherry-pick from pr #1541 by ingpaschke) +nhgitset.pl: Set up future deprecation of PRE and POST hooks. +switch to using LUA_VERSION_NUM instead of LUA_VERSION_RELEASE_NUM for Lua + version checking +include a set of decals (petmark and pilemark) in win/share/decals.txt + and adjust tile processing to include it +preserve inactive level timestamps across saving and restoring so that + monster catch-up, including tameness loss, retains time spent away diff --git a/doc/lua.adoc b/doc/lua.adoc index 9cfa1cd8e..456503569 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -100,7 +100,7 @@ Only available if NetHack was compiled with DUMPLOG. | %T | current time, timestamp | %d | game start, YYYYMMDDhhmmss | %D | current time, YYYYMMDDhhmmss -| %v | game version, eg. '3.7.0-0' +| %v | game version, eg. '5.0.0-0' | %u | UID | %n | player name | %N | first character of player name diff --git a/doc/makedefs.6 b/doc/makedefs.6 index 5e24242fa..af3919c39 100644 --- a/doc/makedefs.6 +++ b/doc/makedefs.6 @@ -1,5 +1,5 @@ .\"DO NOT REMOVE NH_DATESUB .TH MAKEDEFS 6 "Date(%-d %B %Y)" Project(uc) -.TH MAKEDEFS 6 "25 December 2024" NETHACK +.TH MAKEDEFS 6 "26 April 2026" NETHACK .\"DO NOT REMOVE NH_DATESUB .ds Nd Date(%Y) .ds Nd 2024 .de NB @@ -8,8 +8,10 @@ .de NR .ds Nr \\$2 .. -.NB $NHDT-Branch: NetHack-3.7 $ +.NB $NHDT-Branch: NetHack-5 $ .NR $NHDT-Revision: 1.22 $ +.ie \n(.g .ds ^ \(ha +.el .ds ^ ^ .\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or .\" before/after last/first 2 characters of a word. @@ -20,80 +22,73 @@ makedefs \- NetHack miscellaneous build-time functions .SH SYNOPSIS .B makedefs -{ -.B -o -| -.B -d -| -.B -e -| -.B -m -| -.B -v -| -.B -p -| -.B -q -| -.B -r -| -.B -h +{\c +.BR \-o |\c +.BR \-d |\c +.BR \-e |\c +.BR \-m |\c +.BR \-v |\c +.BR \-p |\c +.BR \-q |\c +.BR \-r |\c +.B \-h\c } .P -.B makedefs --input +.B makedefs \-\-input .I file -.B --output +.B \-\-output .I file -.BI -- command +.BI \-\- command .SH DESCRIPTION -.PP .B Makedefs is a build-time tool used for a variety of -.BR NetHack (6) -source file creation and modification tasks. For historical reasons, +.IR nethack (6) +source file creation and modification tasks. +For historical reasons, .B makedefs -takes two types of command lines. When invoked with a short option, the -files operated on are determined when +takes two types of command lines. +When invoked with a short option, +the files operated on are determined when .B makedefs -is compiled. When invoked with a long option, the -.B --input -and -.B --output +is compiled. +When invoked with a long option, +the +.B \-\-input +and +.B \-\-output options are used to specify the files for the -.BI -- command. +.BI \-\- command. Each command is only available in one of the two formats. .SH SHORT COMMANDS Upper and lower case are both accepted for the short commands. .TP -.B -o +.B \-o Generate -.I onames.h. -.br +.IR onames.h . .TP -.B -d +.B \-d Generate -.I data.base. -.br +.IR data.base . .TP -.B -e +.B \-e Generate -.I dungeon.pdf. +.IR dungeon.pdf . The input file .I dungeon.def is passed through the same logic as that used by the -.B --grep +.B \-\-grep command; see the .B MDGREP FUNCTIONS section below for details. -.br .TP -.B -m +.B \-m Generate .I date.h and .I options -file. It will read +file. +It will read .IR dat/gitinfo.txt , only if it is present, to obtain .B githash= @@ -102,175 +97,184 @@ and info and include related preprocessor #defines in .I date.h file. -.br .TP -.B -p +.B \-p Generate -.I pm.h -.br +.IR pm.h . .TP -.B -q +.B \-q Generate the .I rumors file. -.br .TP -.B -s +.B \-s Generate the -.IR bogusmon ", " engrave ", and " epitaph " files." -.br +.IR bogusmon , +.IR engrave , +and +.I epitaph +files. .TP -.B -1 +.B \-1 Generate the -.IR epitaph +.I epitaph file. -.br .TP -.B -2 +.B \-2 Generate the -.IR engrave +.I engrave file. -.br .TP -.B -3 +.B \-3 Generate the -.IR bogusmon +.I bogusmon file. -.br .TP -.B -h +.B \-h Generate the -.B oracles +.I oracles file. -.br .SH LONG COMMANDS .TP -.B --debug +.B \-\-debug Show debugging output. -.br .TP -.B --make \fR[\fIcommand\fR] -Execute a short command. Command is given without preceding dash. -.br +.B \-\-make \fR[\fIcommand\fR] +Execute a short command. +.I Command +is given without preceding dash. .TP -.BI --input " file" +.BI \-\-input " file" Specify the input .I file -for the command (if needed). If the file is - standard -input is read. -.br +for the command (if needed). +If +.I file +is \*(lq\-\*(rq, +.B makedefs +reads the standard input stream. .TP -.BI --output " file" +.BI \-\-output " file" Specify the output .I file -for the command (if needed). If the file is - standard -output is written. -.br +for the command (if needed). +If +.I file +is \*(lq\-\*(rq, +.B makedefs +writes to the standard input stream. .TP -.B --svs \fR[\fIdelimiter\fR] +.B \-\-svs \fR[\fIdelimiter\fR] Generate a version string to standard output without a trailing newline. If specified, the delimiter is used between each part of the version string. -.br .TP -.B --grep +.B \-\-grep Filter the input .I file to the output .IR file . See the .B MDGREP FUNCTIONS section below for information on controlling the filtering operation. -.br .TP -.B --grep-showvars +.B \-\-grep\-showvars Show the name and value for each variable known to the grep option. -.br .TP -.B --grep-trace +.B \-\-grep\-trace Turn on debug tracing for the grep function ( -.B --grep +.B \-\-grep must be specified as well). -.br .TP -.BI --grep-defined " symbol" +.BI \-\-grep\-defined " symbol" Exit shell true (0) if .I symbol is known and defined, otherwise exit shell false (1). .TP -.BI --grep-define " symbol" +.BI \-\-grep\-define " symbol" Force the value of .I symbol -to be "defined." +to be \*(lqdefined.\*(rq .I Symbol must already be known to .BR makedefs . -.br .TP -.BI --grep-undef " symbol" +.BI \-\-grep\-undef " symbol" Force the definition of .I symbol -to be "undefined." +to be \*(lqundefined.\*(rq .I Symbol must already be known to .BR makedefs . .SH MDGREP FUNCTIONS The -.B --grep +.B \-\-grep command (and certain other commands) filter their input, on a line-by-line basis, according to control lines embedded in the input and on information gleaned from the -.BR NetHack (6) -configuration. This allows certain changes such as embedding platform-specific +.I nethack +configuration. +This allows certain changes such as embedding platform-specific documentation into the master documentation files. .P Rules: -.RS -.IP - 4 +.IP \(bu The default conditional state is printing enabled. -.IP - 4 +.IP \(bu Any line .I NOT -starting with a caret (^) is either suppressed or passed through unchanged +starting with a caret (\*^) is either suppressed or passed through unchanged depending on the current conditional state. -.IP - 4 +.IP \(bu Any line starting with a caret is a control line; as in C, zero or more spaces may be embedded in the line almost anywhere (except immediately after the caret); however the caret must be in column 1. -.IP - 4 +.IP \(bu Conditionals may be nested. -.IP - 4 +.IP \(bu .I Makedefs will exit with an error code if any errors are detected; processing will continue (if it can) to allow as many errors as possible to be detected. -.IP - 4 -Unknown identifiers are treated as both TRUE and as an error. Note that -.BR --undef " or " #undef +.IP \(bu +Unknown identifiers are treated as both TRUE and as an error. +Note that +.BR \-\-undef " or " #undef in the -.BR NetHack (6) +.I nethack configuration are different from unknown. -.RE .P Control lines: -.RS -.IP ^^ 4 +.TP +.B +\*^\*^ a line starting with a (single) literal caret -.IP ^# +.TP +.B \*^# a comment -.IP ^?\fIID +.TP +.B \*^?\fIID if the .I ID is defined set the conditional state to TRUE -.IP ^!\fIID +.TP +.B \*^!\fIID if the .I ID is not defined set the conditional state to TRUE -.IP ^: +.TP +.B \*^: else; invert the conditional state -.IP ^. +.TP +.B \*^. end the most recent conditional -.RE .\".SH EXAMPLES .SH AUTHOR The NetHack Development Team .SH COPYRIGHT -This file is Copyright (C) \*(Na, \*(Nd for version \*(Nb:\*(Nr. -NetHack may be freely redistributed. See license for details. +.\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 +.\" offers no test for special character availability, and its feature +.\" set too closely resembles DWB 3.3 to test for it. Use a string with +.\" any nroff-mode formatter not claiming groff compatiblity. +.ds co \(co +.if !\n(.g .if n .ds co (C)\" in principle, should be just "c" +This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. +NetHack may be freely redistributed. +See license for details. diff --git a/doc/makedefs.txt b/doc/makedefs.txt index 38a27f308..7bae10fa1 100644 --- a/doc/makedefs.txt +++ b/doc/makedefs.txt @@ -6,12 +6,12 @@ NAME makedefs - NetHack miscellaneous build-time functions SYNOPSIS - makedefs { -o | -d | -e | -m | -v | -p | -q | -r | -h } + makedefs {-o|-d|-e|-m|-v|-p|-q|-r|-h} makedefs --input file --output file --command DESCRIPTION - Makedefs is a build-time tool used for a variety of NetHack(6) source + Makedefs is a build-time tool used for a variety of nethack(6) source file creation and modification tasks. For historical reasons, makedefs takes two types of command lines. When invoked with a short option, the files operated on are determined when makedefs is compiled. When @@ -30,11 +30,11 @@ SHORT COMMANDS through the same logic as that used by the --grep command; see the MDGREP FUNCTIONS section below for details. - -m Generate date.h and options file. It will read dat/gitinfo.txt, + -m Generate date.h and options file. It will read dat/gitinfo.txt, only if it is present, to obtain githash= and gitbranch= info and include related preprocessor #defines in date.h file. - -p Generate pm.h + -p Generate pm.h. -q Generate the rumors file. @@ -57,12 +57,12 @@ LONG COMMANDS dash. --input file - Specify the input file for the command (if needed). If the file - is - standard input is read. + Specify the input file for the command (if needed). If file is + "-", makedefs reads the standard input stream. --output file - Specify the output file for the command (if needed). If the - file is - standard output is written. + Specify the output file for the command (if needed). If file is + "-", makedefs writes to the standard input stream. --svs [delimiter] Generate a version string to standard output without a trailing @@ -96,57 +96,55 @@ LONG COMMANDS MDGREP FUNCTIONS The --grep command (and certain other commands) filter their input, on a line-by-line basis, according to control lines embedded in the input - and on information gleaned from the NetHack(6) configuration. This - allows certain changes such as embedding platform-specific documenta- - tion into the master documentation files. + and on information gleaned from the nethack configuration. This allows + certain changes such as embedding platform-specific documentation into + the master documentation files. Rules: - - The default conditional state is printing enabled. + o The default conditional state is printing enabled. - - Any line NOT starting with a caret (^) is either suppressed - or passed through unchanged depending on the current condi- - tional state. + o Any line NOT starting with a caret (^) is either suppressed or + passed through unchanged depending on the current conditional + state. - - Any line starting with a caret is a control line; as in C, - zero or more spaces may be embedded in the line almost any- - where (except immediately after the caret); however the - caret must be in column 1. + o Any line starting with a caret is a control line; as in C, zero + or more spaces may be embedded in the line almost anywhere + (except immediately after the caret); however the caret must be + in column 1. - - Conditionals may be nested. + o Conditionals may be nested. - - Makedefs will exit with an error code if any errors are - detected; processing will continue (if it can) to allow as - many errors as possible to be detected. + o Makedefs will exit with an error code if any errors are + detected; processing will continue (if it can) to allow as many + errors as possible to be detected. - - Unknown identifiers are treated as both TRUE and as an - error. Note that --undef or #undef in the NetHack(6) con- - figuration are different from unknown. + o Unknown identifiers are treated as both TRUE and as an error. + Note that --undef or #undef in the nethack configuration are + different from unknown. Control lines: - ^^ a line starting with a (single) literal caret + ^^ a line starting with a (single) literal caret - ^# a comment + ^# a comment - ^?ID - if the ID is defined set the conditional state to TRUE + ^?ID if the ID is defined set the conditional state to TRUE - ^!ID - if the ID is not defined set the conditional state to TRUE + ^!ID if the ID is not defined set the conditional state to TRUE - ^: else; invert the conditional state + ^: else; invert the conditional state - ^. end the most recent conditional + ^. end the most recent conditional AUTHOR The NetHack Development Team COPYRIGHT This file is Copyright (C) Kenneth Lorber, 2024 for version - NetHack-3.7:1.22. NetHack may be freely redistributed. See license - for details. + NetHack-5:1.22. NetHack may be freely redistributed. See license for + details. -NETHACK 25 December 2024 MAKEDEFS(6) +NETHACK 26 April 2026 MAKEDEFS(6) diff --git a/doc/mnh.7 b/doc/mnh.7 index df7fe5856..802c806ec 100644 --- a/doc/mnh.7 +++ b/doc/mnh.7 @@ -1,5 +1,16 @@ +.\"DO NOT REMOVE NH_DATESUB .TH MAKEDEFS 6 "Date(%-d %B %Y)" Project(uc) .\" $NHDT-Branch: NetHack-3.6.2 $:$NHDT-Revision: 1.0 $ $NHDT-Date: 1541298620 2018/11/04 02:30:20 $ -.TH MNH 7 NETHACK +.TH MNH 7 "4 November 2018" NETHACK +.\"DO NOT REMOVE NH_DATESUB .ds Nd Date(%Y) +.ds Nd 2018 +.de NB +.ds Nb \\$2 +.. +.de NR +.ds Nr \\$2 +.. +.NB $NHDT-Branch: NetHack-3.6.2 $ +.NR $NHDT-Revision: 1.0 $ .SH NAME mnh \- additional text formatting macros for the NetHack Guidebook .SH SYNOPSIS @@ -9,14 +20,14 @@ mnh \- additional text formatting macros for the NetHack Guidebook .\".B "troff \-mn" .\"[ options ] file ... .SH DESCRIPTION -.PP This package of .IR nroff (1) and .IR troff (1) macro definitions extends .IR tmac.n (7) -for the NetHack Guidebook. This document should be +for the NetHack Guidebook. +This document should be read as an addendum to the documentation for .IR tmac.n . .PP @@ -27,11 +38,10 @@ and number registers are defined below. .SH FILES doc/tmac.nh .SH "SEE ALSO" -mn(7) +.IR mn (7) .SH AUTHOR Pat Rankin .SH REQUESTS -.PP In the .I Note column, diff --git a/doc/mnh.txt b/doc/mnh.txt index 4d78af3d5..729409a99 100644 --- a/doc/mnh.txt +++ b/doc/mnh.txt @@ -58,4 +58,4 @@ UR mac - - URL passthrough for HTML generator - NETHACK MNH(7) +NETHACK 4 November 2018 MNH(7) diff --git a/doc/nethack.6 b/doc/nethack.6 index 3605423ca..d6c922e00 100644 --- a/doc/nethack.6 +++ b/doc/nethack.6 @@ -1,5 +1,5 @@ .\"DO NOT REMOVE NH_DATESUB .TH NETHACK 6 "Date(%-d %B %Y)" Project(uc) -.TH NETHACK 6 "25 December 2024" NETHACK +.TH NETHACK 6 "26 April 2026" NETHACK .\"DO NOT REMOVE NH_DATESUB .ds Nd Date(%Y) .ds Nd 2024 .de NB @@ -8,7 +8,7 @@ .de NR .ds Nr \\$2 .. -.NB $NHDT-Branch: NetHack-3.7 $ +.NB $NHDT-Branch: NetHack-5 $ .NR $NHDT-Revision: 1.31 $ .\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or @@ -16,134 +16,124 @@ .ie \n(.g .hy 12 .el .hy 14 .ds Na Robert Patrick Rankin +.\" DWB, Solaris 10, and Plan 9 troffs don't support `\(ti`, `\(oq`, or +.\" `\(cq`. Assume the best, then detect these older troffs and fall +.\" back as needed. +.\" +.\" Put NO SPACE between special character and comment escape sequences. +.ds ~ \(ti\" The name "ti" is taken by *roff's `ti` request. +.ds oq \(oq +.ds cq \(cq +.if !\n(.g \{\ +. ds ~ ~ +. ds oq ` +. ds cq ' +.\} +.\" Define string to exercise groff's hyphenless break point feature. +.ie \n(.g .ds : \: +.el .ds : \" empty +.\" Define string to exercise groff's adjustable, unbreakable space. +.ie \n(.g .ds _ \~ +.el .ds _ \ \" backslash, space +.\" Define local versions of groff's "an-ext.tmac" macros if needed. +.ds %% \" empty +.if \n(.g .ig %% +.\" Add supplementary paragraph tag on its own line after TP. +.de TQ +. br +. ns +. \" Do not quote the argument to `TP`; the user might specify +. \" their own quotes for multi-word tags or to exercise AT&T troff +. \" quoting rules. +. TP \\$1\" +.. +.%% .SH NAME nethack \- Exploring The Mazes of Menace .SH SYNOPSIS +.HP +.nr sA \n(.j \" Save the adjustment mode. .na -.hy 0 -.\" Some options ordering is explicit (-d first, -u before -D), others -.\" have been arranged to fit within an 80-column page with nearly full -.\" lines while avoiding splitting "[" and "-opt ]" or "[ -opt" and "]" -.\" across line boundaries. It would be better to do that with 'roff magic. .B nethack -[ -.BR \-d | \-\-directory -.I directory -] -.\" '.B token newline .I token' will include a space between the two tokens; -.\" '.BI token token' will not. Likewise for .BR, .RB, &c. -[ -.BR \-w | \-\-windowtype -.I interface -] -.br 1 -[ -.BI \-\-nethackrc: RC-file -| -.B \-\-no\-nethackrc -] -[ -.B \-n -] -[ -.BR \-dec " | " \-ibm -] -.br 1 -[ -.B \-u -.I playername -] -[ -.BR \-X " | " \-D -] -[ -.B \-p -.I profession -] -[ -.B \-r -.I race -] -[ -.B \-\@ +.RI [ role-option ] +.RB [ \-d | \-\-directory\*_\c +.IR directory ] +.RB [ \-w | \-\-windowtype\*_\c +.IR interface ] +\%[\c +.BI \-\-nethackrc: rc-file\c +|\c +.B \-\-no\-nethackrc\c ] +.RB [ \-n ] +.RB [ \-dec | \-ibm ] +.RB [ \-u\*_\c +.IR player-name ] +.RB [ \-X | \-D ] +.RB [ \-p\*_\c +.IR profession ] +.RB [ \-r\*_\c +.IR race ] +.RB [ \-@ ] .PP -Also -[ +.I role-option +can be any of the following. +.PP +.RS +.nf .BR \-A | \-Arc -| .BR \-B | \-Bar -| .BR \-C | \-Cav -| .BR \-H | \-Hea -| .BR \-K | \-Kni -| .BR \-M | \-Mon -| .BR \-P | \-Pri -| .BR \-R | \-Rog -| -.BR \-Ran -| +.B \-Ran .BR \-S | \-Sam -| .BR \-T | \-Tou -| .BR \-V | \-Val -| .BR \-W | \-Wiz -] +.fi +.RE +.HP +.B nethack +.RB { \-s | \-\-scores } +.RB [ \-d | \-\-directory\*_\c +.IR directory ] +.RB [ \-v ] +.RB [ \-p\*_\c +.IR profession ] +.RB [ \-r\*_\c +.IR race ] +.RI [ player-name\*_\c +\&.\|.\|.] .PP .B nethack -[ -.BR \-d | \-\-directory -.I directory -] -.BR \-s | \-\-scores -[ -.B \-v -] -.br 1 -[ -.B \-p -.I profession -] -[ -.B \-r -.I race -] -[ -.I playernames -] +.RB { \-\-usage | \-\-help } .PP .B nethack -[ -.B \-\-usage -| -.B \-\-help -] -[ -.BR \-\-showpaths -] -.\" force line wrap now rather than have that happen after the opening brace -.br -[ -.BR \-\-version [ :copy | :dump | :show ] -] -.ad -.hy 14 +.B \-\-showpaths +.PP +.B nethack +.BR \-\-version [ :copy | :dump\c +.RB | :show ] +.ad \n(sA \" Restore the adjustment mode. .\" Make sure path is not hyphenated below .hw nethackdir .SH DESCRIPTION -.PP .I NetHack -is a display oriented Dungeons & Dragons(tm) - like game. -The standard tty display and command structure resemble rogue. +is a fantasy-themed game of survival, +exploration, +and combat +set in the Mazes of Menace, +an elaborate underground complex. .PP -Other, more graphical display options exist for most platforms. +Traditionally, +the game's interface uses a Unix terminal connection, +depicting the interface on a grid of character cells +and responding to keyboard-entered commands. +Other interface options exist for most platforms. .PP To get started you really only need to know two commands. The command @@ -201,17 +191,17 @@ below). On other systems, the default may be different, possibly NetHack.cnf. On MS-DOS, the name is defaults.nh in NetHack's directory (folder), while -.\" on the Macintosh or BeOS, it is \(lqNetHack Defaults\(rq, and +.\" on the Macintosh or BeOS, it is \*(lqNetHack Defaults\*(rq, and on VMS|OpenVMS it is nethack.ini in your home directory. The default configuration file may be overridden via the -.BI \-\-nethackrc: "rc-file" +.BI \-\-nethackrc: rc-file command line option or by setting NETHACKOPTIONS in your environment to a string consisting of an @ character followed by the path and filename. .PP The .B \-u -.I playername -option supplies the answer to the question "Who are you?". +.I player-name +option supplies the answer to the question \*(lqWho are you?\*(rq. It overrides any name from the options or configuration file, USER, LOGNAME, or getlogin(), which will otherwise be tried in order. If none of these provides a useful name, the player will be asked for one. @@ -220,31 +210,34 @@ so you can have several saved games under different names. Conversely, you must use the appropriate player name to restore a saved game. .PP A -.I playername +.I player-name suffix can be used to specify the profession, race, alignment and/or gender -of the character. The full syntax of the playername that includes a -suffix is "name-ppp-rrr-aaa-ggg". "ppp" are at least the first three letters +of the character. +The full syntax of a +.I player-name +including a suffix is \*(lqname\-ppp\-rrr\-aaa\-ggg\*(rq. +\*(lqppp\*(rq are at least the first three letters of the profession (this can also be specified using a separate .B \-p .I profession -option). "rrr" are at least the first three letters of the character's +option). +\*(lqrrr\*(rq are at least the first three letters of the character's race (this can also be specified using a separate .B \-r .I race -option). "aaa" are at least the first three letters of the character's -alignment, and "ggg" are at least the first three letters of the -character's gender. Any of the parts of the suffix may be left out. +option). +\*(lqaaa\*(rq are at least the first three letters of the character's +alignment, and \*(lqggg\*(rq are at least the first three letters of the +character's gender. +Any of the parts of the suffix may be left out. .PP .B \-p .I profession can be used to determine the character profession, also known as the role. You can specify either the male or female name for the character role, or the first three characters of the role as an abbreviation. -.\" .B "\-p \@" +.\" .B "\-p @" .\" has been retained to explicitly request that a random role be chosen. -.\" It may need to be quoted with a backslash (\\@) if @ -.\" is the "kill" character (see "stty") for the terminal, in order -.\" to prevent the current input line from being cleared. .PP Likewise, .B \-r @@ -270,7 +263,7 @@ The | .BR \-R | \-Rog | -.BR \-Ran +.B \-Ran | .BR \-S | \-Sam | @@ -289,8 +282,8 @@ is already used for the .I Rogue role. .PP -.B \-\@ -tells nethack to choose any omitted characteristics (profession/role, race, +.B \-@ +tells NetHack to choose any omitted characteristics (profession/role, race, gender, alignment) randomly without prompting. Otherwise, leaving out any of these characteristics will result in you being prompted during game startup for the information. @@ -305,11 +298,22 @@ option will start the game in a special non-scoring discovery mode (also known as explore mode). .B \-D will start the game in debug mode (also known as wizard mode) after -changing the character name to \(lqwizard\(rq, if the player is allowed. +changing the character name to \*(lqwizard\*(rq, +if the player is allowed. Otherwise it will switch to .BR \-X . Control of who is allowed to use debug mode is done via the -.RI "\(lq" WIZARDS= "\(rq line in nethack's " sysconf " file." +.\" The `lq` and `rq` strings are not reliable in macro calls, because +.\" some nroffs interpolate `"` for them, messing up macro argument +.\" delimitation. Use an (initially) uglier method than `RI`. +.\".RI "\*(lq" WIZARDS= "\*(rq line in NetHack's " sysconf " file." +\*(lq\c +.I WIZARDS=\c +\*(rq +line in +NetHack's +.I sysconf +file. .PP The .BR \-d " or " \-\-directory @@ -317,7 +321,8 @@ option, which must be the first argument if it appears, supplies a directory which is to serve as the playground. It overrides the value from NETHACKDIR, HACKDIR, or the directory specified by the game administrator during compilation -(usually /usr/games/lib/nethackdir). +(usually +.IR /usr/\*:games/\*:lib/\*:nethackdir ). This option is usually only useful to the game administrator. The playground must contain several auxiliary files such as help files, the list of top scorers, and a subdirectory @@ -335,18 +340,15 @@ specified in the run-time configuration file. NetHack's #version command shows available interfaces. .PP The -.BI \-\-nethackrc: RC-file +.BI \-\-nethackrc: rc-file option will use -.I RC-file +.I rc-file instead of the default run-time configuration file -.RI "(typically " \(ti/.nethackrc ")" +.RI "(typically " \*~/.nethackrc ) and the .B \-\-no\-nethackrc option can be used to skip any run-time configuration file. .PP -.\" extra blank line -.br 1 -.PP Some options provide feedback and then exit rather than play the game: .PP The @@ -355,7 +357,7 @@ option alone will print out the list of your scores on the current version. An immediately following .B \-v reports on all versions present in the score file. -.RB \(oq \-s | \-s\~\-v \(cq +.RB \*(oq \-s | \-s\*_\-v \*(cq may also be followed by arguments .B \-p .I profession @@ -367,7 +369,7 @@ Either can be specified multiple times to include more than one role or more than one race. When both are specified, score entries which match either the role or the race (or both) are printed rather than just entries which match both. -.RB \(oq \-s | \-s\~\-v \(cq +.RB \*(oq \-s | \-s\*_\-v \*(cq may be followed by one or more player names to print the scores of the players mentioned, by 'all' to print out all scores, or by a number to print that many top scores. @@ -406,10 +408,9 @@ customize aspects of how the game operates. .BR \-\-usage " or " \-\-help will display information similar to this manual page, then exit. Use -.RB \(oq "nethack \-\-usage | more" \(cq +.RB \*(oq "nethack \-\-usage | more" \*(cq to read it a page at a time. .SH AUTHORS -.PP Jay Fenlason (+ Kenny Woodland, Mike Thome and Jon Payne) wrote the original hack, very much like rogue (but full of bugs). .PP @@ -427,160 +428,240 @@ development by the Usenet. Andries Brouwer has made this request for the distinction, as he may eventually release a new version of his own. .SH FILES -.PP Run-time configuration options were discussed above and use a platform specific name for a file in a platform specific location. For Unix, the -name is '.nethackrc' in the user's home directory. - -.br +name is +.I .nethackrc +in the user's home directory. +.PP All other files are in the playground directory, -normally /usr/games/lib/nethackdir. -If DLB was defined during the compile, the data files and special levels -will be inside a larger file, normally nhdat, instead of being separate -files. - -.br -.DT -.\" continuation lines begin with -.ta \w'cmdhelp, opthelp, wizhelp\ \ \ 'u -nethack The program itself. -.br -Guidebook\ |\ Guidebook.txt NetHack's user manual. -.br -data, oracles, rumors Data files used by NetHack. -.br -bogusmon Another data file. -.br -engrave, epitaph, tribute Still more data files. -.br -symbols Data file holding sets of specifications -.br -\ for how to display monsters, objects, and -.br -\ map features. -.br -options Data file containing a description of the -.br -\ build-time option settings. -.br -help,\ hh,\ cmdhelp Help data files. -('cmdhelp' is obsolete.) -.br -opthelp,\ optmenu,\ wizhelp More help data files. -.br -keyhelp,\ usagehlp Even more help data files. -.br -*.lua Predefined special levels, dungeon control -.br -\ for special levels, quest texts. -.br -history A short history of NetHack. -.br -license Rules governing redistribution. -.br -record The list of top scorers. -.br -logfile An extended list of games played -.br -\ (optional). -.br -xlogfile A more detailed version of 'logfile' -.br -\ (also optional). -.br -paniclog Record of exceptional conditions -.br -\ discovered during program execution. -.br -xlock.nn Description of dungeon level 'nn' of -.br -\ active game 'x' if there's a limit on the -.br -\ number of simultaneously active games. -.br -UUcccccc.nn Alternate form for dungeon level 'nn' -.br -\ of active game by user 'UU' playing -.br -\ character named 'cccccc' when there's no -.br -\ limit on number of active games. -.br -perm Lock file for xlock.0 or UUcccccc.0. -.br -bonD0.nn Descriptions of the ghost and belongings -.br -\ of a deceased adventurer who met his or -.br -\ her demise on level 'nn'. +normally +.IR /usr/\*:games/\*:lib/\*:nethackdir . +If DLB was defined during the compile, +the data files and special levels will be inside a larger file, +normally +.IR nhdat , +instead of being separate files. +.TP +.I nethack +The program itself. +.TP +.I Guidebook +.TQ +.I Guidebook.txt +NetHack's user manual. +.TP +.I data +.TQ +.I oracles +.TQ +.I rumors +Data files used by NetHack. +.TP +.I bogusmon +Another data file. +.TP +.I engrave +.TQ +.I epitaph +.TQ +.I tribute +Still more data files. +.TP +.I symbols +Data file holding sets of specifications +for how to display monsters, objects, and +map features. +.TP +.I options +Data file containing a description of the +build-time option settings. +.TP +.I help +.TQ +.I hh +.TQ +.I cmdhelp +Help data files. +.RI ( cmdhelp +is obsolete.) +.TP +.I opthelp +.TQ +.I optmenu +.TQ +.I wizhelp +More help data files. +.TP +.I keyhelp +.TQ +.I usagehlp +Even more help data files. +.TP +.RI * .lua +Predefined special levels, dungeon control +for special levels, quest texts. +.TP +.I history +A short history of NetHack. +.TP +.I license +Rules governing redistribution. +.TP +.I record +The list of top scorers. +.TP +.I logfile +An extended list of games played +(optional). +.TP +.I xlogfile +A more detailed version of +.I logfile +(also optional). +.TP +.I paniclog +Record of exceptional conditions +discovered during program execution. +.TP +.RI x lock. nn +Description of dungeon level +.I nn +of active game +.I x +if there's a limit on the +number of simultaneously active games. +.TP +.RI UUcccccc . nn +Alternate form for dungeon level +.I nn +of active game by user +.I UU +playing character named +.I cccccc +when there's no +limit on number of active games. +.TP +.I perm +Lock file for +.RI x lock.0 +or +.RI UUcccccc .0 . +.TP +.IR bonD0. nn +Descriptions of the ghost and belongings +of a deceased adventurer who met his or +her demise on level +.IR nn . A subsequent -.br -\ character might encounter this old level. -.br -.\"following line should contain -\ -.br -save/ A subdirectory containing saved games. -.br -.\"following line should contain -\ -.br -sysconf System-wide options. Required if -.br -\ program is built with 'SYSCF' option -.br -\ enabled, ignored if not. -.br - -The location of 'sysconf' is specified at build time and can't be changed -except by updating source file "config.h" and rebuilding the program. -.br - +character might encounter this old level. +.TP +.I save/ +Subdirectory containing saved games. +.TP +.I sysconf +System-wide options. +Required if +program is built with 'SYSCF' option +enabled, ignored if not. +.PP +The location of +.I sysconf +is specified at build time and can't be changed +except by updating source file +.\" We do the following in an ugly and non-idiomatic way to work around +.\" a DWB 3.3 nroff bug. +.\" troff: if-else overflow.; doc/nethack.6:623 +.\" stack: }S }S }S }S }S }S }S }S }S }S }S }S }S }S }S }S RI +.\" Even at that, DWB insists on setting the period in roman. +"\c +.I config.h\c +" +and rebuilding the program. +.PP NetHack's Guidebook might not be present if whoever packaged or installed the program distribution neglected to include it. -.br - -In a perfect world, 'paniclog' would remain empty. +.PP +In a perfect world, +.I paniclog +would remain empty. .SH ENVIRONMENT -.DT -.ta \w'NETHACKDIR or HACKDIR\ \ \ 'u -USER or LOGNAME Your login name. -.br -HOME Your home directory. -.br -SHELL Your shell. -.br -TERM The type of your terminal. -.br -HACKPAGER or PAGER Replacement for default pager. -.br -MAIL Mailbox file. -.br -MAILREADER Replacement for default reader -.br -\ (probably /bin/mail or /usr/ucb/mail). -.br -NETHACKDIR or HACKDIR Playground. -.br -NETHACKOPTIONS String predefining several NetHack options. -.br - -If the same option is specified in both NETHACKOPTIONS and .nethackrc, -the value assigned in NETHACKOPTIONS takes precedence. -.br - -SHOPTYPE and SPLEVTYPE can be used in debugging (wizard) mode. -.br -DEBUGFILES can be used if the program was built with 'DEBUG' enabled. +In some cases, +.I NetHack +attempts to access multiple environment variables in sequence +(via +.IR getenv (3) +or similar) +to determine information. +.TP 16n \" "NETHACKOPTIONS" + 2n +.I USER +.TQ +.I +LOGNAME +Your login name. +.TP +.I HOME +Your home directory. +.TP +.I SHELL +Your login shell +(not necessarily the one running when you started +.IR NetHack ). +.TP +.I TERM +Your terminal type. +.TP +.I HACKPAGER +.TQ +.I PAGER +Replacement for default pager. +.TP +.I MAIL +Mailbox file. +.TP +.I MAILREADER +Replacement for default reader +(probably +.I /bin/\*:mail +or +.IR /usr/\*:ucb/\*:mail ). +.TP +.I NETHACKDIR +.TQ +.I HACKDIR +Playground. +.TP +.I NETHACKOPTIONS +Predefined +.I NetHack +options. +.PP +If the same option is specified in both +.I \%NETHACKOPTIONS +and +.IR \%.nethackrc , +the value assigned in +.I \%NETHACKOPTIONS +takes precedence. +.PP +.I SHOPTYPE +and +.I \%SPLEVTYPE +can be used in debugging (wizard) mode. +.I \%DEBUGFILES +can be used if the program was built with 'DEBUG' enabled. .SH "SEE ALSO" -.PP -recover(6) +.IR recover (6) .SH BUGS -.PP Probably infinite. .SH COPYRIGHT -This file is Copyright (C) \*(Na, \*(Nd for version \*(Nb:\*(Nr. -NetHack may be freely redistributed. See license for details. -.PP -Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. +.\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 +.\" offers no test for special character availability, and its feature +.\" set too closely resembles DWB 3.3 to test for it. Use a string with +.\" any nroff-mode formatter not claiming groff compatiblity. +.ds co \(co +.if !\n(.g .if n .ds co (C)\" in principle, should be just "c" +This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. +NetHack may be freely redistributed. +See license for details. diff --git a/doc/nethack.txt b/doc/nethack.txt index ca120c3e0..c3e19b0e2 100644 --- a/doc/nethack.txt +++ b/doc/nethack.txt @@ -6,24 +6,44 @@ NAME nethack - Exploring The Mazes of Menace SYNOPSIS - nethack [ -d|--directory directory ] [ -w|--windowtype interface ] - [ --nethackrc:RC-file | --no-nethackrc ] [ -n ] [ -dec | -ibm ] - [ -u playername ] [ -X | -D ] [ -p profession ] [ -r race ] [ -@ ] + nethack [role-option] [-d|--directory directory] [-w|--window- + type interface] [--nethackrc:rc-file|--no-nethackrc] [-n] + [-dec|-ibm] [-u player-name] [-X|-D] [-p profession] [-r race] + [-@] - Also [ -A|-Arc | -B|-Bar | -C|-Cav | -H|-Hea | -K|-Kni | -M|-Mon | - -P|-Pri | -R|-Rog | -Ran | -S|-Sam | -T|-Tou | -V|-Val | -W|-Wiz ] + role-option can be any of the following. - nethack [ -d|--directory directory ] -s|--scores [ -v ] - [ -p profession ] [ -r race ] [ playernames ] + -A|-Arc + -B|-Bar + -C|-Cav + -H|-Hea + -K|-Kni + -M|-Mon + -P|-Pri + -R|-Rog + -Ran + -S|-Sam + -T|-Tou + -V|-Val + -W|-Wiz - nethack [ --usage | --help ] [ --showpaths ] - [ --version[:copy|:dump|:show] ] + nethack {-s|--scores} [-d|--directory directory] [-v] [-p profession] + [-r race] [player-name ...] + + nethack {--usage|--help} + + nethack --showpaths + + nethack --version[:copy|:dump|:show] DESCRIPTION - NetHack is a display oriented Dungeons & Dragons(tm) - like game. The - standard tty display and command structure resemble rogue. + NetHack is a fantasy-themed game of survival, exploration, and combat + set in the Mazes of Menace, an elaborate underground complex. - Other, more graphical display options exist for most platforms. + Traditionally, the game's interface uses a Unix terminal connection, + depicting the interface on a grid of character cells and responding to + keyboard-entered commands. Other interface options exist for most + platforms. To get started you really only need to know two commands. The command ? will give you a list of the available commands (as well as other @@ -65,7 +85,7 @@ DESCRIPTION setting NETHACKOPTIONS in your environment to a string consisting of an @ character followed by the path and filename. - The -u playername option supplies the answer to the question "Who are + The -u player-name option supplies the answer to the question "Who are you?". It overrides any name from the options or configuration file, USER, LOGNAME, or getlogin(), which will otherwise be tried in order. If none of these provides a useful name, the player will be asked for @@ -74,9 +94,9 @@ DESCRIPTION versely, you must use the appropriate player name to restore a saved game. - A playername suffix can be used to specify the profession, race, align- - ment and/or gender of the character. The full syntax of the playername - that includes a suffix is "name-ppp-rrr-aaa-ggg". "ppp" are at least + A player-name suffix can be used to specify the profession, race, + alignment and/or gender of the character. The full syntax of a player- + name including a suffix is "name-ppp-rrr-aaa-ggg". "ppp" are at least the first three letters of the profession (this can also be specified using a separate -p profession option). "rrr" are at least the first three letters of the character's race (this can also be specified using @@ -100,7 +120,7 @@ DESCRIPTION must be uppercase. Ranger has no single-letter choice because -R is already used for the Rogue role. - -@ tells nethack to choose any omitted characteristics (profes- + -@ tells NetHack to choose any omitted characteristics (profes- sion/role, race, gender, alignment) randomly without prompting. Other- wise, leaving out any of these characteristics will result in you being prompted during game startup for the information. @@ -113,16 +133,16 @@ DESCRIPTION mode (also known as wizard mode) after changing the character name to "wizard", if the player is allowed. Otherwise it will switch to -X. Control of who is allowed to use debug mode is done via the "WIZARDS=" - line in nethack's sysconf file. + line in NetHack's sysconf file. The -d or --directory option, which must be the first argument if it appears, supplies a directory which is to serve as the playground. It overrides the value from NETHACKDIR, HACKDIR, or the directory speci- - fied by the game administrator during compilation (usually - /usr/games/lib/nethackdir). This option is usually only useful to the - game administrator. The playground must contain several auxiliary - files such as help files, the list of top scorers, and a subdirectory - save where games are saved. + fied by the game administrator during compilation (usually /usr/games/ + lib/nethackdir). This option is usually only useful to the game admin- + istrator. The playground must contain several auxiliary files such as + help files, the list of top scorers, and a subdirectory save where + games are saved. The -w or --windowtype interface option can be used to specify which interface to use if the program has been built with support for more @@ -130,7 +150,7 @@ DESCRIPTION specified in the run-time configuration file. NetHack's #version com- mand shows available interfaces. - The --nethackrc:RC-file option will use RC-file instead of the default + The --nethackrc:rc-file option will use rc-file instead of the default run-time configuration file (typically ~/.nethackrc) and the --no-nethackrc option can be used to skip any run-time configuration file. @@ -194,81 +214,136 @@ AUTHORS FILES Run-time configuration options were discussed above and use a platform specific name for a file in a platform specific location. For Unix, - the name is '.nethackrc' in the user's home directory. + the name is .nethackrc in the user's home directory. - All other files are in the playground directory, normally - /usr/games/lib/nethackdir. If DLB was defined during the compile, the - data files and special levels will be inside a larger file, normally - nhdat, instead of being separate files. + All other files are in the playground directory, normally /usr/games/ + lib/nethackdir. If DLB was defined during the compile, the data files + and special levels will be inside a larger file, normally nhdat, + instead of being separate files. - nethack The program itself. - Guidebook | Guidebook.txt NetHack's user manual. - data, oracles, rumors Data files used by NetHack. - bogusmon Another data file. - engrave, epitaph, tribute Still more data files. - symbols Data file holding sets of specifications - for how to display monsters, objects, and - map features. - options Data file containing a description of the - build-time option settings. - help, hh, cmdhelp Help data files. ('cmdhelp' is obsolete.) - opthelp, optmenu, wizhelp More help data files. - keyhelp, usagehlp Even more help data files. - *.lua Predefined special levels, dungeon control - for special levels, quest texts. - history A short history of NetHack. - license Rules governing redistribution. - record The list of top scorers. - logfile An extended list of games played - (optional). - xlogfile A more detailed version of 'logfile' - (also optional). - paniclog Record of exceptional conditions - discovered during program execution. - xlock.nn Description of dungeon level 'nn' of - active game 'x' if there's a limit on the - number of simultaneously active games. - UUcccccc.nn Alternate form for dungeon level 'nn' - of active game by user 'UU' playing - character named 'cccccc' when there's no - limit on number of active games. - perm Lock file for xlock.0 or UUcccccc.0. - bonD0.nn Descriptions of the ghost and belongings - of a deceased adventurer who met his or - her demise on level 'nn'. A subsequent - character might encounter this old level. + nethack + The program itself. - save/ A subdirectory containing saved games. + Guidebook + Guidebook.txt + NetHack's user manual. - sysconf System-wide options. Required if - program is built with 'SYSCF' option - enabled, ignored if not. + data + oracles + rumors Data files used by NetHack. - The location of 'sysconf' is specified at build time and can't be - changed except by updating source file "config.h" and rebuilding the - program. + bogusmon + Another data file. - NetHack's Guidebook might not be present if whoever packaged or + engrave + epitaph + tribute + Still more data files. + + symbols + Data file holding sets of specifications for how to display mon- + sters, objects, and map features. + + options + Data file containing a description of the build-time option set- + tings. + + help + hh + cmdhelp + Help data files. (cmdhelp is obsolete.) + + opthelp + optmenu + wizhelp + More help data files. + + keyhelp + usagehlp + Even more help data files. + + *.lua Predefined special levels, dungeon control for special levels, + quest texts. + + history + A short history of NetHack. + + license + Rules governing redistribution. + + record The list of top scorers. + + logfile + An extended list of games played (optional). + + xlogfile + A more detailed version of logfile (also optional). + + paniclog + Record of exceptional conditions discovered during program exe- + cution. + + xlock.nn + Description of dungeon level nn of active game x if there's a + limit on the number of simultaneously active games. + + UUcccccc.nn + Alternate form for dungeon level nn of active game by user UU + playing character named cccccc when there's no limit on number + of active games. + + perm Lock file for xlock.0 or UUcccccc.0. + + bonD0.nn + Descriptions of the ghost and belongings of a deceased adven- + turer who met his or her demise on level nn. A subsequent char- + acter might encounter this old level. + + save/ Subdirectory containing saved games. + + sysconf + System-wide options. Required if program is built with 'SYSCF' + option enabled, ignored if not. + + The location of sysconf is specified at build time and can't be changed + except by updating source file "config.h" and rebuilding the program. + + NetHack's Guidebook might not be present if whoever packaged or installed the program distribution neglected to include it. - In a perfect world, 'paniclog' would remain empty. + In a perfect world, paniclog would remain empty. ENVIRONMENT - USER or LOGNAME Your login name. - HOME Your home directory. - SHELL Your shell. - TERM The type of your terminal. - HACKPAGER or PAGER Replacement for default pager. - MAIL Mailbox file. - MAILREADER Replacement for default reader - (probably /bin/mail or /usr/ucb/mail). - NETHACKDIR or HACKDIR Playground. - NETHACKOPTIONS String predefining several NetHack options. + In some cases, NetHack attempts to access multiple environment vari- + ables in sequence (via getenv(3) or similar) to determine information. + + USER + LOGNAME Your login name. + + HOME Your home directory. + + SHELL Your login shell (not necessarily the one running when + you started NetHack). + + TERM Your terminal type. + + HACKPAGER + PAGER Replacement for default pager. + + MAIL Mailbox file. + + MAILREADER Replacement for default reader (probably /bin/mail or + /usr/ucb/mail). + + NETHACKDIR + HACKDIR Playground. + + NETHACKOPTIONS Predefined NetHack options. If the same option is specified in both NETHACKOPTIONS and .nethackrc, the value assigned in NETHACKOPTIONS takes precedence. - SHOPTYPE and SPLEVTYPE can be used in debugging (wizard) mode. + SHOPTYPE and SPLEVTYPE can be used in debugging (wizard) mode. DEBUGFILES can be used if the program was built with 'DEBUG' enabled. SEE ALSO @@ -278,12 +353,10 @@ BUGS Probably infinite. COPYRIGHT - This file is Copyright (C) Robert Patrick Rankin, 2024 for version - NetHack-3.7:1.31. NetHack may be freely redistributed. See license - for details. - - Dungeons & Dragons is a Trademark of Wizards of the Coast, Inc. + This file is Copyright (C) Robert Patrick Rankin, 2024 for version + NetHack-5:1.31. NetHack may be freely redistributed. See license for + details. -NETHACK 25 December 2024 NETHACK(6) +NETHACK 26 April 2026 NETHACK(6) diff --git a/doc/options.txt b/doc/options.txt index 71a4dd6bc..54c654161 100644 --- a/doc/options.txt +++ b/doc/options.txt @@ -1,5 +1,5 @@ The definition for each OPTIONS= option resides in include/optlist.h as of -February 2020 in 3.7 WIP. +February 2020 in the WIP branch. Boolean and compound options are combined into a single allopt[] array. diff --git a/doc/recover.6 b/doc/recover.6 index 3829760e9..a1c8ad68b 100644 --- a/doc/recover.6 +++ b/doc/recover.6 @@ -1,5 +1,5 @@ .\"DO NOT REMOVE NH_DATESUB .TH RECOVER 6 "Date(%-d %B %Y)" Project(uc) -.TH RECOVER 6 "25 December 2024" NETHACK +.TH RECOVER 6 "26 April 2026" NETHACK .\"DO NOT REMOVE NH_DATESUB .ds Nd Date(%Y) .ds Nd 2024 .de NB @@ -8,9 +8,11 @@ .de NR .ds Nr \\$2 .. -.NB $NHDT-Branch: NetHack-3.7 $ +.NB $NHDT-Branch: NetHack-5 $ .NR $NHDT-Revision: 1.12 $ -.\" groff and AT&T-descended troffs use different hyphenation patterns. +.ie \n(.g .ds ^ \(ha +.el .ds ^ ^ +.\" groff and AT&T-descended troffs use different hyphenation patterns. .\" Don't hyphenate the last word on a page or column, or .\" before/after last/first 2 characters of a word. .ie \n(.g .hy 12 @@ -20,77 +22,89 @@ recover \- recover a NetHack game interrupted by disaster .SH SYNOPSIS .B recover -[ -.B \-d -.I directory -] -.I "base1 base2" ... +.RB [ \-d +.IR playground-directory ] +.I base +\&.\|.\|. .SH DESCRIPTION -.PP -Occasionally, a NetHack game will be interrupted by disaster -when the game or the system crashes. -Prior to NetHack v3.1, these games were lost because various information +Occasionally, a NetHack game is interrupted by disaster +when the program or the system crashes. +Prior to NetHack v3.1, these games were lost because information like the player's inventory was kept only in memory. Now, all pertinent information can be written out to disk, so such games can be recovered at the point of the last level change. .PP -The -.I base -options tell +.I Base +operands tell .I recover which files to process. -Each base option specifies recovery of a separate game. +Each +.I base +specifies recovery of a separate game. .PP The .B \-d option, which must be the first argument if it appears, -supplies a directory which is the NetHack playground. -It overrides the value from NETHACKDIR, HACKDIR, or the directory +supplies the directory housing the NetHack playground. +It overrides the value of the environment variables +.I NETHACKDIR +and +.IR HACKDIR , +and the directory specified by the game administrator during compilation -(usually /usr/games/lib/nethackdir). +(usually +.IR /usr/games/lib/nethackdir ). .ig .PP -^?ALLDOCS +\*^?ALLDOCS For recovery to be possible, -.I nethack +.IR nethack (6) must have been compiled with the INSURANCE option, and the run-time option .I checkpoint must also have been on. -^: -^?INSURANCE +\*^: +\*^?INSURANCE For recovery to be possible, .I nethack must have been compiled with the INSURANCE option (this configuration was), and the run-time option .I checkpoint must also have been on. -^: +\*^: This configuration of .I nethack was created without support for recovery. -^. -^. +\*^. +\*^. .. -NetHack normally writes out files for levels as the player leaves them, +.IR nethack (6) +normally writes out files for levels as the player leaves them, so they will be ready for return visits. -When checkpointing, NetHack also writes out the level entered and +When checkpointing, it also writes out the level entered and the current game state on every level change. -This naturally slows level changes down somewhat. +This procedure slows level changes. .PP -The level file names are of the form base.nn, where nn is an internal -bookkeeping number for the level. -The file base.0 is used for game identity, locking, and, when checkpointing, +The level file names are of the form +.IR base. nn, where +.I nn +is an internal bookkeeping number for the level. +The file +.I base.0 +is used for game identity, locking, and, when checkpointing, for the game state. Various OSes use different strategies for constructing the base name. -Microcomputers use the character name, possibly truncated and modified +Single-user systems use the character name, +possibly truncated and modified to be a legal filename on that system. Multi-user systems use the (modified) character name prefixed by a user number to avoid conflicts, -or "xlock" if the number of concurrent players is being limited. +or +.I xlock +if the number of concurrent players is being limited. It may be necessary to look in the playground to find the correct base name of the interrupted game. .I recover -will transform these level files into a save file of the same name as +transforms these level files into a save file of the same name that .I nethack would have used. .PP @@ -105,13 +119,16 @@ through setuid or setgid is tantamount to leaving the playground world-writable, with respect to both cheating and messing up other players. For a single-user system, this of course does not change anything, -so some of the microcomputer ports install +so some of these ports install .I recover by default. .PP For a multi-user system, -the game administrator may want to arrange for all .0 files in the -playground to be fed to recover when the host machine boots, +the game administrator may want to arrange for all +.I .0 +files in the playground to be fed to +.I recover +when the host machine boots, and handle game crashes individually. If the user population is sufficiently trustworthy, .I recover @@ -122,12 +139,11 @@ In either case, .I recover is easily compiled from the distribution utility directory. .SH NOTES -.PP Like .I nethack itself, .I recover -will overwrite existing savefiles of the same name. +will overwrite existing save files of the same name. Savefiles created by .I recover are uncompressed; @@ -136,17 +152,24 @@ but even a compression-using .I nethack will find them in the uncompressed form. .SH "SEE ALSO" -nethack(6) +.IR nethack (6) .SH BUGS -.PP .I recover makes no attempt to find out if a base name specifies a game in progress. If multiple machines share a playground, this would be impossible to determine. .PP .I recover -should be taught to use the nethack playground locking mechanism to -avoid conflicts. +should be taught to use the +.I nethack +playground locking mechanism to avoid conflicts. .SH COPYRIGHT -This file is Copyright (C) \*(Na, \*(Nd for version \*(Nb:\*(Nr. -NetHack may be freely redistributed. See license for details. +.\" All troffs and nroffs support `\(co` except Plan 9 nroff, but Plan 9 +.\" offers no test for special character availability, and its feature +.\" set too closely resembles DWB 3.3 to test for it. Use a string with +.\" any nroff-mode formatter not claiming groff compatiblity. +.ds co \(co +.if !\n(.g .if n .ds co (C)\" in principle, should be just "c" +This file is Copyright \*(co \*(Na, \*(Nd for version \*(Nb:\*(Nr. +NetHack may be freely redistributed. +See license for details. diff --git a/doc/recover.txt b/doc/recover.txt index e13d2995f..2631dda0e 100644 --- a/doc/recover.txt +++ b/doc/recover.txt @@ -6,39 +6,39 @@ NAME recover - recover a NetHack game interrupted by disaster SYNOPSIS - recover [ -d directory ] base1 base2 ... + recover [-d playground-directory] base ... DESCRIPTION - Occasionally, a NetHack game will be interrupted by disaster when the - game or the system crashes. Prior to NetHack v3.1, these games were - lost because various information like the player's inventory was kept - only in memory. Now, all pertinent information can be written out to - disk, so such games can be recovered at the point of the last level - change. + Occasionally, a NetHack game is interrupted by disaster when the pro- + gram or the system crashes. Prior to NetHack v3.1, these games were + lost because information like the player's inventory was kept only in + memory. Now, all pertinent information can be written out to disk, so + such games can be recovered at the point of the last level change. - The base options tell recover which files to process. Each base option - specifies recovery of a separate game. + Base operands tell recover which files to process. Each base specifies + recovery of a separate game. The -d option, which must be the first argument if it appears, supplies - a directory which is the NetHack playground. It overrides the value - from NETHACKDIR, HACKDIR, or the directory specified by the game admin- - istrator during compilation (usually /usr/games/lib/nethackdir). - NetHack normally writes out files for levels as the player leaves them, - so they will be ready for return visits. When checkpointing, NetHack - also writes out the level entered and the current game state on every - level change. This naturally slows level changes down somewhat. + the directory housing the NetHack playground. It overrides the value + of the environment variables NETHACKDIR and HACKDIR, and the directory + specified by the game administrator during compilation (usually + /usr/games/lib/nethackdir). nethack(6) normally writes out files for + levels as the player leaves them, so they will be ready for return vis- + its. When checkpointing, it also writes out the level entered and the + current game state on every level change. This procedure slows level + changes. - The level file names are of the form base.nn, where nn is an internal + The level file names are of the form base.nn,where nn is an internal bookkeeping number for the level. The file base.0 is used for game identity, locking, and, when checkpointing, for the game state. Vari- - ous OSes use different strategies for constructing the base name. - Microcomputers use the character name, possibly truncated and modified - to be a legal filename on that system. Multi-user systems use the + ous OSes use different strategies for constructing the base name. Sin- + gle-user systems use the character name, possibly truncated and modi- + fied to be a legal filename on that system. Multi-user systems use the (modified) character name prefixed by a user number to avoid conflicts, - or "xlock" if the number of concurrent players is being limited. It - may be necessary to look in the playground to find the correct base - name of the interrupted game. recover will transform these level files - into a save file of the same name as nethack would have used. + or xlock if the number of concurrent players is being limited. It may + be necessary to look in the playground to find the correct base name of + the interrupted game. recover transforms these level files into a save + file of the same name that nethack would have used. Since recover must be able to read and delete files from the playground and create files in the save directory, it has interesting interactions @@ -46,7 +46,7 @@ DESCRIPTION setuid or setgid is tantamount to leaving the playground world- writable, with respect to both cheating and messing up other players. For a single-user system, this of course does not change anything, so - some of the microcomputer ports install recover by default. + some of these ports install recover by default. For a multi-user system, the game administrator may want to arrange for all .0 files in the playground to be fed to recover when the host @@ -56,7 +56,7 @@ DESCRIPTION is easily compiled from the distribution utility directory. NOTES - Like nethack itself, recover will overwrite existing savefiles of the + Like nethack itself, recover will overwrite existing save files of the same name. Savefiles created by recover are uncompressed; they may be compressed afterwards if desired, but even a compression-using nethack will find them in the uncompressed form. @@ -74,9 +74,9 @@ BUGS COPYRIGHT This file is Copyright (C) Kenneth Lorber, 2024 for version - NetHack-3.7:1.12. NetHack may be freely redistributed. See license - for details. + NetHack-5:1.12. NetHack may be freely redistributed. See license for + details. -NETHACK 25 December 2024 RECOVER(6) +NETHACK 26 April 2026 RECOVER(6) diff --git a/doc/sound.txt b/doc/sound.txt index 66ff2d0d0..ee4c34893 100644 --- a/doc/sound.txt +++ b/doc/sound.txt @@ -1,4 +1,4 @@ -NetHack 3.7 sound.txt $NHDT-Date: 1693253363 2023/08/28 20:09:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +NetHack 5.0 sound.txt $NHDT-Date: 1693253363 2023/08/28 20:09:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ Introduction @@ -495,7 +495,7 @@ use the following guidelines: These hints files might require updates to include your new soundlib addition. You can look at what was done for macsound support - in sys/unix/hints/macOS.370 for inspiration. + in sys/unix/hints/macOS.500 for inspiration. sys/unix/NetHack.xcodeproj/project.pbxproj diff --git a/doc/tmac.nh b/doc/tmac.nh index f8c30c2d0..459ee623d 100644 --- a/doc/tmac.nh +++ b/doc/tmac.nh @@ -1,4 +1,4 @@ -.\" NetHack 3.7 tmac.nh $NHDT-Date: $ $NHDT-Branch: $:$NHDT-Revision: $ +.\" NetHack 5.0 tmac.nh $NHDT-Date: $ $NHDT-Branch: $:$NHDT-Revision: $ . .\" Miscellaneous tmac.n-style macros specifically for nethack's Guidebook. .\" @@ -139,4 +139,6 @@ .\" before/after last/first 2 characters of a word. .ie \n(.g .hy 12 .el .hy 14 +.ds JW Jon W{tte\" +.if \n(.g .if !'\*[.T]'ascii' .ds JW Jon W\(:atte .\"tmac.nh/" diff --git a/doc/window.txt b/doc/window.txt index d2f55793a..f45db607b 100644 --- a/doc/window.txt +++ b/doc/window.txt @@ -1,4 +1,4 @@ -NetHack 3.7 window.txt $NHDT-Date: 1666390558 2022/10/21 22:15:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ +NetHack 5.0 window.txt $NHDT-Date: 1666390558 2022/10/21 22:15:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.70 $ Introduction @@ -227,7 +227,7 @@ print_glyph(window, x, y, glyphinfo, bkglyphinfo) int ttychar; /* the character mapping for the original tty * interface. Most or all window ports wanted * and used this for various things so it is - * provided in 3.7+ */ + * provided in 5.0+ */ short int symidx; /* offset into syms array */ unsigned glyphflags; /* more detail about the entity */ diff --git a/include/align.h b/include/align.h index 0ccaf0e4d..36c9d1aff 100644 --- a/include/align.h +++ b/include/align.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 align.h $NHDT-Date: 1604269810 2020/11/01 22:30:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 align.h $NHDT-Date: 1781973076 2026/06/20 16:31:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Mike Stephenson, Izchak Miller 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/amiconf.h b/include/amiconf.h index 682ed3a2b..51342e44f 100644 --- a/include/amiconf.h +++ b/include/amiconf.h @@ -7,41 +7,17 @@ #define AMICONF_H #undef abs /* avoid using macro form of abs */ -#ifndef __SASC_60 #undef min /* this gets redefined */ #undef max /* this gets redefined */ -#endif #include /* get time_t defined before use! */ -#ifdef CROSS_TO_AMIGA #include #include #include #include #include #include -#endif - -#ifdef __SASC_60 /* since SAS can prevent re-inclusion */ -#include /* general things, including builtins */ -#include -#endif - -#ifdef AZTEC_50 -#include -#define AZTEC_C_WORKAROUND /* Bug which turns up in sounds.c. Bummer... */ -#define NO_SIGNAL /* 5.0 signal handling doesn't like SIGINT... */ -#endif - -#ifdef _DCC -#include -#define _SIZE_T -#endif - -#ifndef __GNUC__ -typedef long off_t; -#endif #define MICRO /* must be defined to allow some inclusions */ @@ -53,69 +29,32 @@ typedef long off_t; /* data librarian defs */ #define DLBFILE "nhdat" /* main library */ -/* nhsdat sound library not used in 3.7 */ +/* nhsdat sound library not used in 5.0 */ #undef DLBFILE2 -#ifndef CROSS_TO_AMIGA -#define FILENAME_CMP stricmp /* case insensitive */ -#else #define FILENAME_CMP strcmpi /* case insensitive */ -#endif - -#ifndef __SASC_60 #define O_BINARY 0 -#endif - -/* Compile in New Intuition look for 2.0 */ -#ifdef IDCMP_CLOSEWINDOW -#ifndef INTUI_NEW_LOOK -#define INTUI_NEW_LOOK 1 -#endif -#endif #define MFLOPPY /* You'll probably want this; provides assistance \ * for typical personal computer configurations \ */ -#ifndef CROSS_TO_AMIGA -#define RANDOM -#endif /* ### amidos.c ### */ extern void nethack_exit(int); -/* ### amiwbench.c ### */ - -extern void ami_wbench_init(void); -extern void ami_wbench_args(void); -extern int ami_wbench_getsave(int); -extern void ami_wbench_unlink(char *); -extern int ami_wbench_iconsize(char *); -extern void ami_wbench_iconwrite(char *); -extern int ami_wbench_badopt(const char *); -extern void ami_wbench_cleanup(void); -extern void getlind(const char *, char *, const char *); - /* ### winreq.c ### */ extern void amii_setpens(int); -extern void exit(int); +extern void getlind(const char *, char *, const char *); extern void CleanUp(void); -extern void Abort(long); +extern void Abort(long) NORETURN; extern int getpid(void); -extern char *CopyFile(const char *, const char *); extern int kbhit(void); extern int WindowGetchar(void); -extern void ami_argset(int *, char *[]); -extern void ami_mkargline(int *, char **[]); extern void ami_wininit_data(int); -#define FromWBench 0 /* A hint for compiler ... */ -/* extern boolean FromWBench; /* how were we run? */ -extern int ami_argc; -extern char **ami_argv; - #ifndef MICRO_H #include "micro.h" #endif @@ -125,36 +64,16 @@ extern char **ami_argv; #endif #define remove(x) unlink(x) - -/* DICE wants rewind() to return void. We want it to return int. */ -#if defined(_DCC) || defined(__GNUC__) #define rewind(f) fseek(f, 0, 0) -#endif - -#ifdef AZTEC_C -extern FILE *freopen(const char *, const char *, FILE *); -extern char *gets(char *); -#endif - -/* - * If AZTEC_C we can't use the long cpath in vision.c.... - */ -#ifdef AZTEC_C -#undef MACRO_CPATH -#endif /* * (Possibly) configurable Amiga options: */ #define HACKFONT /* Use special hack.font */ -#ifndef CROSS_TO_AMIGA /* issues with prototype and spawnl */ -#define SHELL /* Have a shell escape command (!) */ -#endif #define MAIL /* Get mail at unexpected occasions */ -#define DEFAULT_ICON "NetHack:default.icon" /* private icon */ #define AMIFLUSH /* toss typeahead (select flush in .cnf) */ -/* #define OPT_DISPMAP /* enable fast_map option */ +#define SFSTRUCT_BUFFERING /* buffered stdio writes for structlevel files */ /* new window system options */ /* WRONG - AMIGA_INTUITION should go away */ @@ -165,51 +84,39 @@ extern char *gets(char *); #define CHANGE_COLOR 1 #define DEPTH 6 /* Maximum depth of the screen allowed */ #define AMII_MAXCOLORS (1L << DEPTH) +/* Number of palette entries actually populated in amii_init_map[] (AMII text + * mode) and amiv_init_map[] (AMIV tile mode). Indices beyond these read 0. */ +#define AMII_PALETTE_SIZE 8 +#define AMIV_PALETTE_SIZE 32 typedef unsigned short AMII_COLOR_TYPE; -#define PORT_HELP "nethack:amii.hlp" +#define PORT_HELP "amii.hlp" #undef TERMLIB -#define AMII_MUFFLED_VOLUME 40 -#define AMII_SOFT_VOLUME 50 -#define AMII_OKAY_VOLUME 60 -#define AMII_LOUDER_VOLUME 80 - -#ifdef TTY_GRAPHICS -#define ANSI_DEFAULT -#endif - -extern int amibbs; /* BBS mode? */ - #ifdef AMII_GRAPHICS extern int amii_numcolors; void amii_setpens(int); #endif -/* for cmd.c: override version in micro.h */ -#ifdef __SASC_60 -#undef M -#define M(c) ((c) -128) -#endif struct ami_sysflags { char sysflagsid[10]; #ifdef AMIFLUSH boolean altmeta; /* use ALT keys as META */ boolean amiflush; /* kill typeahead */ #endif -#ifdef AMII_GRAPHICS +#ifdef AMII_GRAPHICS int numcols; unsigned short amii_dripens[20]; /* DrawInfo Pens currently there are 13 in v39 */ AMII_COLOR_TYPE amii_curmap[AMII_MAXCOLORS]; /* colormap */ #endif -#ifdef OPT_DISPMAP - boolean fast_map; /* use optimized, less flexible map display */ -#endif #ifdef MFLOPPY boolean asksavedisk; #endif }; extern struct ami_sysflags sysflags; +#undef SYSCF +#undef SYSCF_FILE + #endif /* AMICONF_H */ diff --git a/include/artifact.h b/include/artifact.h index 2db7270fb..021743445 100644 --- a/include/artifact.h +++ b/include/artifact.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 artifact.h $NHDT-Date: 1602692711 2020/10/14 16:25:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 artifact.h $NHDT-Date: 1781973076 2026/06/20 16:31:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.23 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/artilist.h b/include/artilist.h index 0dd2181a8..2b7e9ef8d 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 artilist.h $NHDT-Date: 1710957374 2024/03/20 17:56:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 artilist.h $NHDT-Date: 1781973076 2026/06/20 16:31:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/attrib.h b/include/attrib.h index 47ede7a3f..653c5fe65 100644 --- a/include/attrib.h +++ b/include/attrib.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 attrib.h $NHDT-Date: 1596498527 2020/08/03 23:48:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 attrib.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright 1988, Mike Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/botl.h b/include/botl.h index ad09d51ba..83539424b 100644 --- a/include/botl.h +++ b/include/botl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 botl.h $NHDT-Date: 1694893330 2023/09/16 19:42:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ +/* NetHack 5.0 botl.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.45 $ */ /* Copyright (c) Michael Allison, 2003 */ /* NetHack may be freely redistributed. See license for details. */ @@ -238,14 +238,14 @@ extern int cond_idx[CONDITION_COUNT]; #define BL_TH_ALWAYS_HILITE 105 /* highlight regardless of value */ #define BL_TH_CRITICALHP 106 /* highlight critically low HP */ -#define HL_ATTCLR_NONE CLR_MAX + 1 -#define HL_ATTCLR_BOLD CLR_MAX + 2 -#define HL_ATTCLR_DIM CLR_MAX + 3 -#define HL_ATTCLR_ITALIC CLR_MAX + 4 -#define HL_ATTCLR_ULINE CLR_MAX + 5 -#define HL_ATTCLR_BLINK CLR_MAX + 6 -#define HL_ATTCLR_INVERSE CLR_MAX + 7 -#define BL_ATTCLR_MAX CLR_MAX + 8 +#define HL_ATTCLR_NONE (CLR_MAX + 1) +#define HL_ATTCLR_BOLD (CLR_MAX + 2) +#define HL_ATTCLR_DIM (CLR_MAX + 3) +#define HL_ATTCLR_ITALIC (CLR_MAX + 4) +#define HL_ATTCLR_ULINE (CLR_MAX + 5) +#define HL_ATTCLR_BLINK (CLR_MAX + 6) +#define HL_ATTCLR_INVERSE (CLR_MAX + 7) +#define BL_ATTCLR_MAX (CLR_MAX + 8) enum hlattribs { HL_UNDEF = 0x00, diff --git a/include/color.h b/include/color.h index a1fa5327b..3d5292a65 100644 --- a/include/color.h +++ b/include/color.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 color.h $NHDT-Date: 1682205020 2023/04/22 23:10:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 color.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ */ /* Copyright (c) Steve Linhart, Eric Raymond, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -65,7 +65,6 @@ struct nethack_color { int tableindex; int rgbindex; const char *name; - const char *hexval; long r, g, b; }; @@ -73,6 +72,8 @@ typedef struct color_and_attr { int color, attr; } color_attr; +extern const struct nethack_color colortable[]; + #endif /* COLOR_H */ /*color.h*/ diff --git a/include/config.h b/include/config.h index 5016c6702..9b5216377 100644 --- a/include/config.h +++ b/include/config.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 config.h $NHDT-Date: 1710344316 2024/03/13 15:38:36 $ $NHDT-Branch: keni-staticfn $:$NHDT-Revision: 1.188 $ */ +/* NetHack 5.0 config.h $NHDT-Date: 1710344316 2024/03/13 15:38:36 $ $NHDT-Branch: keni-staticfn $:$NHDT-Revision: 1.188 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -36,7 +36,7 @@ /* Hint: if you're not developing code, don't define ULTRIX_PROTO. */ -#include "config1.h" /* should auto-detect MSDOS, MAC, AMIGA, and WIN32 */ +#include "config1.h" /* should auto-detect MSDOS, MAC68K, AMIGA, and WIN32 */ /* * Consolidated version, patchlevel, development status. @@ -67,8 +67,8 @@ * tty, X11, mac, amii, BeOS, Qt, Gem, Gnome, shim */ -/* MAC also means MAC windows */ -#ifdef MAC +/* MAC68K also means MAC windows */ +#ifdef MAC68K #ifndef AUX #define DEFAULT_WINDOW_SYS "mac" #endif @@ -339,7 +339,7 @@ #define ENTRYMAX 100 /* must be >= 10 */ #endif #ifndef PERS_IS_UID -#if !defined(MICRO) && !defined(MAC) && !defined(WIN32) +#if !defined(MICRO) && !defined(MAC68K) && !defined(WIN32) #define PERS_IS_UID 1 /* delete for PERSMAX per name; now per uid */ #else #define PERS_IS_UID 0 @@ -434,7 +434,7 @@ */ #define INSURANCE /* allow crashed game recovery */ -#if !defined(MAC) && !defined(SHIM_GRAPHICS) +#if !defined(MAC68K) && !defined(SHIM_GRAPHICS) #define CHDIR /* delete if no chdir() available */ #endif @@ -533,7 +533,7 @@ typedef unsigned char uchar; #define MACRO_CPATH /* use clear_path macros instead of functions */ #endif -#if !defined(MAC) +#if !defined(MAC68K) #if !defined(NOCLIPPING) #define CLIPPING /* allow smaller screens -- ERS */ #endif @@ -677,9 +677,23 @@ typedef unsigned char uchar; #ifdef NHL_SANDBOX #ifdef CHRONICLE /* LIVELOG (and therefore CHRONICLE) is needed for --loglua */ +#ifndef LIVELOG #define LIVELOG #endif #endif +#endif + +/* experimential; if the platform/window-port supports it; when the game has + * started to wait for player input, and the wait lasts longer than + * IDLECHECKPOINT_WAIT_TIME seconds (defined in hack.h or *conf.h), the game + * will perform an update to the checkpoint file. + * Currently has support in: + * WIN32CON + * Qt + * curses + */ + +/* #define IDLECHECKPOINT */ /* End of Section 4 */ diff --git a/include/config1.h b/include/config1.h index 402e0e73c..4e1f6639a 100644 --- a/include/config1.h +++ b/include/config1.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 config1.h $NHDT-Date: 1596498530 2020/08/03 23:48:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 5.0 config1.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.32 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -45,23 +45,23 @@ #endif #ifdef macintosh /* Auto-defined symbol for MPW compilers (sc and mrc) */ -#define MAC +#define MAC68K #endif #ifdef THINK_C /* Think C auto-defined symbol */ -#define MAC +#define MAC68K #define NEED_VARARGS #endif #ifdef __MWERKS__ /* defined by Metrowerks' Codewarrior compiler */ #ifndef __BEOS__ /* BeOS */ -#define MAC +#define MAC68K #endif #define NEED_VARARGS #define USE_STDARG #endif -#if defined(MAC) || defined(__BEOS__) +#if defined(MAC68K) || defined(__BEOS__) #define DLB #undef UNIX #endif diff --git a/include/context.h b/include/context.h index c207c5a8d..f4f161aae 100644 --- a/include/context.h +++ b/include/context.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 context.h $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ */ +/* NetHack 5.0 context.h $NHDT-Date: 1781973077 2026/06/20 16:31:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.61 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/coord.h b/include/coord.h index f20f74dd7..13e9c642c 100644 --- a/include/coord.h +++ b/include/coord.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 coord.h $NHDT-Date: 1596498531 2020/08/03 23:48:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 coord.h $NHDT-Date: 1781973078 2026/06/20 16:31:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/cstd.h b/include/cstd.h index 54c950a40..6ecea80a8 100644 --- a/include/cstd.h +++ b/include/cstd.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 cstd.h $NHDT-Date: 1725652996 2024/09/06 20:03:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ +/* NetHack 5.0 cstd.h $NHDT-Date: 1781973078 2026/06/20 16:31:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/decl.h b/include/decl.h index f66c0f5a8..49f9e17c8 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1725653004 2024/09/06 20:03:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.377 $ */ +/* NetHack 5.0 decl.h $NHDT-Date: 1781973078 2026/06/20 16:31:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.408 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -344,6 +344,7 @@ struct instance_globals_d { /* new */ boolean deferred_showpaths; char *deferred_showpaths_dir; + boolean disable_glyphname_hash_indices_prefill; boolean havestate; }; @@ -785,6 +786,9 @@ struct instance_globals_p { unsigned pline_flags; char prevmsg[BUFSZ]; + /* mon.c */ + enum mon_terrain_effects pending_terrain_effects; + /* potion.c */ int potion_nothing; int potion_unkn; @@ -802,6 +806,9 @@ struct instance_globals_p { int poly_zapped; /* new stuff */ + int puzzling_criteria; + char puzzling_ilets[invlet_basic + 1]; + boolean havestate; }; @@ -840,9 +847,6 @@ struct instance_globals_r { struct instance_globals_s { - /* allmain.c */ - boolean saving_grace_turn; /* saving grace was triggered this turn */ - /* artifact.c */ int spec_dbon_applies; /* coordinate effects from spec_dbon() with messages in artifact_hit() */ @@ -974,15 +978,15 @@ struct instance_globals_t { struct instance_globals_u { - /* allmain.c */ - int uhp_at_start_of_monster_turn; - /* botl.c */ boolean update_all; /* decl.c */ boolean unweapon; + /* revision.c */ + int uplift_needed_rev0_to_rev1; + /* role.c */ struct Role urole; /* player's role. May be munged in role_init() */ struct Race urace; /* player's race. May be munged in role_init() */ @@ -1175,6 +1179,8 @@ struct instance_globals_saved_m { struct instance_globals_saved_n { /* dungeon.c */ int n_dgns; /* number of dungeons (also used in mklev.c and do.c) */ + /* files.c */ + char nhuuid[NHUUIDSZ]; /* mkroom.c */ int nroom; /* region.c */ @@ -1225,6 +1231,12 @@ struct instance_globals_saved_u { dest_area updest; }; +struct instance_globals_saved_w { + /* reserved */ + long wreserve; + int32_t wtreserved; +}; + struct instance_globals_saved_x { /* mkmaze.c */ int xmin, xmax; /* level boundaries x */ @@ -1278,9 +1290,15 @@ extern struct instance_globals_saved_r svr; extern struct instance_globals_saved_s svs; extern struct instance_globals_saved_t svt; extern struct instance_globals_saved_u svu; +extern struct instance_globals_saved_w svw; extern struct instance_globals_saved_x svx; extern struct instance_globals_saved_y svy; extern struct sinfo program_state; /* flags describing game's current state */ +/* flags describing current level's loading/making/readiness status; + * restlevelstate() already associated term 'levelstate' for a different + * purpose, so attempt to avoid confusion + */ +extern struct levelstatus level_status; struct const_globals { const struct obj zeroobj; /* used to zero out a struct obj */ diff --git a/include/defsym.h b/include/defsym.h index 8229ab400..1ad2bb6f2 100644 --- a/include/defsym.h +++ b/include/defsym.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 defsym.h $NHDT-Date: 1725653007 2024/09/06 20:03:27 $ $NHDT-Branch: NetHack-3.7 $ $NHDT-Revision: 1.25 $ */ +/* NetHack 5.0 defsym.h $NHDT-Date: 1781973078 2026/06/20 16:31:18 $ $NHDT-Branch: NetHack-5.0 $ $NHDT-Revision: 1.27 $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/dgn_file.h b/include/dgn_file.h index 4a94e0cdc..e09d098f3 100644 --- a/include/dgn_file.h +++ b/include/dgn_file.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 dgn_file.h $NHDT-Date: 1596498533 2020/08/03 23:48:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 dgn_file.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) 1989 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/display.h b/include/display.h index fc52eac41..d7e8e64b5 100644 --- a/include/display.h +++ b/include/display.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.h $NHDT-Date: 1725653008 2024/09/06 20:03:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 5.0 display.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.118 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -27,12 +27,12 @@ * Returns true if the hero can sense the given monster. This includes * monsters that are hiding or mimicking other monsters. * - * [3.7] Note: the map doesn't display any monsters when hero is swallowed + * [5.0] Note: the map doesn't display any monsters when hero is swallowed * (or display non-adjacent, non-submerged ones when hero is underwater), * so treat those situations as blocking telepathy, detection, and warning * even though conceptually they shouldn't do so. * - * [3.7 also] The macros whose name begins with an underscore have been + * [5.0 also] The macros whose name begins with an underscore have been * converted to functions in order to have compilers generate smaller code. * The retained underscore versions are still used in display.c but should * only be used in other situations if the function calls actually produce @@ -138,7 +138,7 @@ * creature in an apparently empty spot. * Infravision is not relevant; we assume that invisible monsters are also * invisible to infravision. - * [3.7: the macro definition erroneously started with 'mtmp->minvis' for + * [5.0: the macro definition erroneously started with 'mtmp->minvis' for * over 20 years. The one place it's used called it as knowninvisible(mtmp) * so worked by coincidence when there was no argument expansion involved * on the first line.] @@ -846,7 +846,7 @@ enum glyph_offsets { || glyph_is_piletop_generic_obj(glyph)) #define glyph_is_normal_piletop_obj(glyph) \ ((glyph) == GLYPH_OBJ_PILETOP_OFF \ - || ((glyph) > GLYPH_OBJ_PILETOP_OFF + FIRST_OBJECT - 1 \ + || ((glyph) >= GLYPH_OBJ_PILETOP_OFF + FIRST_OBJECT - 1 \ && (glyph) < (GLYPH_OBJ_PILETOP_OFF + NUM_OBJECTS))) #define glyph_is_normal_object(glyph) \ ((glyph) == GLYPH_OBJ_OFF \ diff --git a/include/dlb.h b/include/dlb.h index 2fff03046..c51c9bace 100644 --- a/include/dlb.h +++ b/include/dlb.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 dlb.h $NHDT-Date: 1596498534 2020/08/03 23:48:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 dlb.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ @@ -9,7 +9,7 @@ #ifdef DLB /* implementations */ -#if defined(MAC) && !defined(MAC_CROSS) +#if defined(MAC68K) && !defined(MAC68K_CROSS) #define DLBRSRC /* use Mac resources */ #else #define DLBLIB /* use a set of external files */ diff --git a/include/dungeon.h b/include/dungeon.h index f364bcd8e..09967adf8 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 dungeon.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.56 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/engrave.h b/include/engrave.h index 33ee19c80..27d152608 100644 --- a/include/engrave.h +++ b/include/engrave.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 engrave.h $NHDT-Date: 1596498535 2020/08/03 23:48:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 engrave.h $NHDT-Date: 1781973079 2026/06/20 16:31:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.22 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/extern.h b/include/extern.h index a02f26c54..5fd542749 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1523 $ */ +/* NetHack 5.0 extern.h $NHDT-Date: 1778886716 2026/05/15 15:11:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1558 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -339,6 +339,7 @@ extern char *get_configfile(void); extern const char *get_default_configfile(void); extern void rcfile(void); extern void rcfile_interface_options(void); +extern void rcfile_only_this_option(enum opt); extern void heed_all_config_statements(void); extern void disregard_all_config_statements(void); extern void heed_this_config_statement(int); @@ -346,12 +347,20 @@ extern void disregard_this_config_statement(int); extern boolean config_unmatched_ignored(void); extern void clear_ignore_errors_on_unmatched(void); extern void set_ignore_errors_on_unmatched(void); +extern void rcfile_only_this_statement(int); +#ifdef WIN32 +extern boolean check_for_portable_config(void); +#endif +#ifdef MSWIN_GRAPHICS +extern void disregard_some_mswin_options(void); +extern void rcfile_only_some_mswin_options(void); +#endif /* ### coloratt.c ### */ extern char *color_attr_to_str(color_attr *); extern boolean color_attr_parse_str(color_attr *, char *); -extern int32 colortable_to_int32(struct nethack_color *); +extern int32 colortable_to_int32(const struct nethack_color *); extern int query_color(const char *, int) NO_NNARGS; extern int query_attr(const char *, int) NO_NNARGS; extern boolean query_color_attr(color_attr *, const char *) NONNULLARG1; @@ -511,6 +520,7 @@ extern void destroy_drawbridge(coordxy, coordxy); /* ### decl.c ### */ extern void program_state_init(void); +extern void level_status_init(void); extern void decl_globals_init(void); extern void sa_victual(volatile struct victual_info *); @@ -684,7 +694,8 @@ extern void free_mgivenname(struct monst *) NONNULLARG1; extern void new_oname(struct obj *, int) NONNULLARG1; extern void free_oname(struct obj *) NONNULLARG1; extern const char *safe_oname(struct obj *) NONNULLARG1; -extern struct monst *christen_monst(struct monst *, const char *) NONNULLARG1; +extern struct monst *christen_monst(struct monst *, const char *) NONNULL + NONNULLARG1; extern struct obj *oname(struct obj *, const char *, unsigned) NONNULLPTRS; extern boolean objtyp_is_callable(int); extern int name_ok(struct obj *); @@ -696,9 +707,11 @@ extern char *x_monnam(struct monst *, int, const char *, int, boolean) NONNULLAR extern char *l_monnam(struct monst *) NONNULLARG1; extern char *mon_nam(struct monst *) NONNULLARG1; extern char *noit_mon_nam(struct monst *) NONNULLARG1; +extern char *noit_or_your_mon_nam(struct monst *) NONNULLARG1; extern char *some_mon_nam(struct monst *) NONNULLARG1; extern char *Monnam(struct monst *) NONNULLARG1; extern char *noit_Monnam(struct monst *) NONNULLARG1; +extern char *noit_or_your_Monnam(struct monst *) NONNULLARG1; extern char *Some_Monnam(struct monst *) NONNULLARG1; extern char *noname_monnam(struct monst *, int) NONNULLARG1; extern char *m_monnam(struct monst *) NONNULLARG1; @@ -938,6 +951,7 @@ extern void early_options(int *argc_p, char ***argv_p, char **hackdir_p); #ifdef WIN32 int windows_early_options(const char *); #endif +extern void genl_prag(int, char **); /* profession, race, align, gender */ /* ### eat.c ### */ @@ -986,7 +1000,7 @@ extern void done1(int); extern int done2(void); extern void done_in_by(struct monst *, int) NONNULLARG1; extern void done_object_cleanup(void); -extern void NH_abort(char *); +extern void NH_abort(const char *); #endif /* !MAKEDEFS_C && MDLIB_C && !CPPREGEX_C */ #if !defined(CPPREGEX_C) ATTRNORETURN extern void panic(const char *, ...) PRINTF_F(1, 2) NORETURN; @@ -1092,7 +1106,7 @@ extern NHFILE *get_freeing_nhfile(void); extern NHFILE *restore_saved_game(void); extern int check_panic_save(void); #ifdef SELECTSAVED -extern char *plname_from_file(const char *, boolean) NONNULLARG1; +extern char *plname_from_file(const char *, boolean, int) NONNULLARG1; #endif extern char **get_saved_games(void); extern void free_saved_games(char **); @@ -1128,6 +1142,8 @@ extern boolean Death_quote(char *, int) NONNULLARG1; extern void livelog_add(long ll_type, const char *) NONNULLARG2; ATTRNORETURN extern void do_deferred_showpaths(int) NORETURN; extern boolean contains_directory(const char *); +extern void get_nhuuid(void); +extern void free_nhuuid(void); /* ### fountain.c ### */ @@ -1171,16 +1187,16 @@ int set_map_customcolor(glyph_map *gm, uint32 nhcolor) NONNULLARG1; extern int unicode_val(const char *); extern int glyphrep(const char *) NONNULLARG1; extern int match_glyph(char *) NONNULLARG1; -extern void dump_all_glyphids(FILE *fp) NONNULLARG1; -extern void wizcustom_glyphids(winid win); -extern void fill_glyphid_cache(void); -extern void free_glyphid_cache(void); -extern boolean glyphid_cache_status(void); +extern void dump_all_glyphnames(FILE *fp) NONNULLARG1; +extern void wizcustom_glyphnames(winid win); +extern void populate_glyphname_hash_indices(void); +extern void empty_glyphname_hash_indices(void); +extern boolean glyphname_hash_indices_loaded(void); extern void apply_customizations(enum graphics_sets which_set, enum do_customizations docustomize); extern void purge_custom_entries(enum graphics_sets which_set); extern void purge_all_custom_entries(void); -extern void dump_glyphids(void); +extern void dump_glyphnames(void); extern void clear_all_glyphmap_colors(void); extern void reset_customcolors(void); extern int glyph_to_cmap(int); @@ -1234,7 +1250,6 @@ extern int monster_nearby(void); extern void end_running(boolean); extern void nomul(int); extern void unmul(const char *); -extern int saving_grace(int); extern void showdamage(int); extern void losehp(int, const char *, schar) ; extern int weight_cap(void); @@ -1392,6 +1407,7 @@ extern void perm_invent_toggled(boolean negated); extern void prepare_perminvent(winid window); extern struct obj *carrying_stoning_corpse(void); extern void repopulate_perminvent(void); +extern int check_for_puzzling_nonmerge(struct obj *); /* ### ioctl.c ### */ @@ -1449,7 +1465,7 @@ extern boolean stumble_on_door_mimic(coordxy, coordxy); extern int doopen_indir(coordxy, coordxy); extern int doclose(void); -#ifdef MAC +#ifdef MAC68K /* outdated functions removed */ /* ### macfile.c ### */ /* ### macmain.c ### */ @@ -1853,6 +1869,9 @@ extern void see_monster_closeup(struct monst *, boolean) NONNULLARG1; extern void see_nearby_monsters(void); extern void shieldeff_mon(struct monst *) NONNULLARG1; extern void flash_mon(struct monst *) NONNULLARG1; +extern boolean maybe_set_terrain_effects(struct monst *, + struct permonst *) NONNULLARG1; +extern void terrain_effects(void); /* ### mondata.c ### */ @@ -1973,9 +1992,6 @@ extern void mplayer_talk(struct monst *) NONNULLARG1; #ifndef WIN32 extern int tgetch(void); #endif -#ifndef TOS -extern char switchar(void); -#endif #ifndef __GO32__ extern long freediskspace(char *); #ifdef MSDOS @@ -2157,7 +2173,7 @@ extern void tutorial(boolean); #if !defined(MAKEDEFS_C) && !defined(MDLIB_C) && !defined(CPPREGEX_C) -/* ### consoletty.c ### */ +/* ### consoletty.c ### */ #ifdef WIN32 extern void get_scr_size(void); @@ -2170,7 +2186,10 @@ void console_g_putch(int in_ch); extern void set_output_mode(int); extern void synch_cursor(void); extern void nethack_enter_consoletty(void); -extern void consoletty_exit(void); +/* body in consoletty.c and mhmain.c */ +extern int get_approx_display_cols(void); +extern int get_approx_display_rows(void); +extern void console_exit(void); extern int set_keyhandling_via_option(void); #ifdef ENHANCED_SYMBOLS extern void tty_utf8graphics_fixup(void); @@ -2221,6 +2240,8 @@ extern boolean the_unique_pm(struct permonst *) NONNULLARG1; extern boolean erosion_matters(struct obj *) NONNULLARG1; extern char *doname(struct obj *) NONNULLARG1; extern char *doname_with_price(struct obj *) NONNULLARG1; +extern char *doname_with_cgender(struct obj *) NONNULLARG1; +extern char *doname_with_price_and_cgender(struct obj *) NONNULLARG1; extern char *doname_vague_quan(struct obj *) NONNULLARG1; extern boolean not_fully_identified(struct obj *) NONNULLARG1; extern char *corpse_xname(struct obj *, const char *, unsigned) NONNULLARG1; @@ -2406,6 +2427,9 @@ extern void gettty(void); extern void settty(const char *); extern void setftty(void); ATTRNORETURN extern void error(const char *, ...) PRINTF_F(1, 2) NORETURN; +#ifdef ENHANCED_SYMBOLS +extern void tty_utf8graphics_fixup(void); +#endif #if defined(TIMED_DELAY) && defined(_MSC_VER) extern void msleep(unsigned); #endif @@ -2740,9 +2764,18 @@ void restore_gamelog(NHFILE *); boolean restgamestate(NHFILE *); void restore_msghistory(NHFILE *); #endif -extern void rest_adjust_levelflags(void); +extern void rest_adjust_levelflags(long); extern void moves_to_relative_time(long *); extern void relative_time_to_moves(long *); +extern boolean revision_increment(int, int, uchar *); + +/* ### revision.c ### */ + +extern boolean revision_increment(int, int, uchar *); +#ifdef DEMO_UPLIFTS +void uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *rev0, + struct mystruct *rev1); +#endif /* DEMO_UPLIFTS */ /* ### rip.c ### */ @@ -2975,6 +3008,7 @@ extern void credit_report(struct monst *shkp, int idx, boolean silent) NONNULLARG1; extern void use_unpaid_trapobj(struct obj *, coordxy, coordxy) NONNULLARG1; extern void noisy_shop(struct mkroom *); +extern const char *says(void); /* ### shknam.c ### */ @@ -3587,7 +3621,7 @@ extern void dump_version_info(void); extern void store_critical_bytes(NHFILE *) NONNULLARG1; extern int compare_critical_bytes(NHFILE *, int *, unsigned long) NONNULLARG1; extern int get_critical_size_count(void); -extern int validate(NHFILE *, const char *, boolean) NONNULLARG1; +extern int validate(NHFILE *, const char *, boolean, int) NONNULLARG1; /* ### video.c ### */ @@ -3895,6 +3929,7 @@ extern void wizcustom_callback(winid win, int glyphnum, char *id); extern int wiz_display_macros(void); extern int wiz_mon_diff(void); extern int wiz_objprobs(void); +extern int wiz_show_nhuuid(void); #endif extern void sanity_check(void); @@ -4039,6 +4074,8 @@ extern char *get_port_id(char *); #ifdef RUNTIME_PASTEBUF_SUPPORT extern void port_insert_pastebuf(char *); #endif +extern void get_nhuuid(void); +extern void free_nhuuid(void); #endif /* !MAKEDEFS_C && !MDLIB_C */ diff --git a/include/flag.h b/include/flag.h index f48b4693c..3502354c5 100644 --- a/include/flag.h +++ b/include/flag.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 flag.h $NHDT-Date: 1744860497 2025/04/16 19:28:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.251 $ */ +/* NetHack 5.0 flag.h $NHDT-Date: 1781973080 2026/06/20 16:31:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.265 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -156,6 +156,15 @@ struct flag { boolean showrace; /* show hero glyph by race rather than by role */ boolean travelcmd; /* allow travel command */ int runmode; /* update screen display during run moves */ + + int reserved1; + int reserved2; + int reserved3; + int reserved4; + int reserved5; + int reserved6; + int reserved7; + int reserved8; }; /* @@ -246,6 +255,8 @@ struct instance_flags { * to input becoming taken over); * True => enable fuzzer when entering moveloop */ boolean herecmd_menu; /* use menu when mouseclick on yourself */ + boolean idlecheckpoint; /* platform should perform a checkpoint update + * if waiting for input longer than 10 seconds */ boolean invis_goldsym; /* gold symbol is ' '? */ boolean in_lua; /* executing a lua script */ boolean lua_testing; /* doing lua tests */ @@ -499,7 +510,7 @@ struct instance_flags { #ifdef MAC_GRAPHICS_ENV #define large_font obsolete #endif -#ifdef MAC +#ifdef MAC68K #define popup_dialog wc_popup_dialog #endif #define preload_tiles wc_preload_tiles diff --git a/include/fnamesiz.h b/include/fnamesiz.h index ed2d264b8..ea54f9c0b 100644 --- a/include/fnamesiz.h +++ b/include/fnamesiz.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 fnamesiz.h $NHDT-Date: 1580310580 2020/01/29 15:09:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 fnamesiz.h $NHDT-Date: 1781973080 2026/06/20 16:31:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ */ /*-Copyright (c) Michael Allison, 2020. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/func_tab.h b/include/func_tab.h index e5438ce58..605b2f665 100644 --- a/include/func_tab.h +++ b/include/func_tab.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 func_tab.h $NHDT-Date: 1684791775 2023/05/22 21:42:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 func_tab.h $NHDT-Date: 1781973080 2026/06/20 16:31:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.29 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/global.h b/include/global.h index 47e783742..e3bac1ea4 100644 --- a/include/global.h +++ b/include/global.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 global.h $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.159 $ */ +/* NetHack 5.0 global.h $NHDT-Date: 1704225560 2024/01/02 19:59:20 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.159 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -185,7 +185,7 @@ typedef uchar nhsym; #ifdef AMIGA #define PORT_ID "Amiga" #endif -#ifdef MAC +#ifdef MAC68K #define PORT_ID "Mac" #endif #ifdef __APPLE__ @@ -422,7 +422,7 @@ extern struct nomakedefs_s nomakedefs; #include "color.h" /* - * Version 3.7.x has aspirations of portable file formats. We + * Version 5.0.x has aspirations of portable file formats. We * make a distinction between MAIL functionality and MAIL_STRUCTURES * so that the underlying structures are consistent, whether MAIL is * defined or not. diff --git a/include/hack.h b/include/hack.h index f655a8961..3a6cc96c2 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.h $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */ +/* NetHack 5.0 hack.h $NHDT-Date: 1781973080 2026/06/20 16:31:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.299 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -38,7 +38,6 @@ #include "sys.h" #include "timeout.h" #include "winprocs.h" -#include "wintype.h" #include "vision.h" #include "you.h" @@ -64,6 +63,7 @@ #define CXN_PFX_THE 4 /* prefix with "the " (unless pname) */ #define CXN_ARTICLE 8 /* include a/an/the prefix */ #define CXN_NOCORPSE 16 /* suppress " corpse" suffix */ +#define CXN_ADDGNDR 32 /* include a gender */ /* number of turns it takes for vault guard to show up */ #define VAULT_GUARD_TIME 30 @@ -588,6 +588,13 @@ enum inventory_counts { /* 2023/11/30 invlet_max is not yet used anywhere */ }; +#ifndef IDLECHECKPOINT_WAIT_TIME +#define IDLECHECKPOINT_WAIT_TIME 10 /* seconds to wait before executing a checkpoint; + * always #define'd but only has meaning if + * IDLECHECKPOINT is defined. + */ +#endif + struct kinfo { struct kinfo *next; /* chain of delayed killers */ int id; /* uprop keys to ID a delayed killer */ @@ -702,6 +709,8 @@ enum nhcb_calls { NUM_NHCB }; +#define NHUUIDSZ 37 + struct plinemsg_type { xint16 msgtype; /* one of MSGTYP_foo */ struct nhregex *regex; @@ -716,6 +725,14 @@ struct plinemsg_type { /* bitmask for callers of hide_unhide_msgtypes() */ #define MSGTYP_MASK_REP_SHOW ((1 << MSGTYP_NOREP) | (1 << MSGTYP_NOSHOW)) +enum mon_terrain_effects { + no_terrain_effects = 0x00000000, + /* these bit values must be beyond the MON_ ranges in monst.h + since they get set on mon->mstate */ + nonflyer_vs_liquid = 0x10000000, + candrown_vs_liquid = 0x20000000, +}; + /* polyself flags */ enum polyself_flags { POLY_NOFLAGS = 0x00, @@ -791,6 +808,7 @@ struct sinfo { int config_error_ready; /* config_error_add is ready, available */ int beyond_savefile_load; /* set when past savefile loading */ int savefile_completed; /* savefile has completed writing */ + int reading_bonesfile; /* in the midst of trying to read bones file */ #ifdef PANICLOG int in_paniclog; /* writing a panicloc entry */ #endif @@ -811,6 +829,14 @@ struct sinfo { #endif }; +/* structure for current 'level_status'; not saved and restored */ +struct levelstatus { + int making; /* makelevel has begun */ + int loading; /* level loading has begun */ + int shkready; /* shops ready */ + int ready; /* level is ready */ +}; + /* value of program_state.input_state, significant during readchar(); get_count() expects digits then a command so sets it to commandInp */ enum InputState { @@ -1391,9 +1417,10 @@ typedef uint32_t mmflags_nht; /* makemon MM_ flags */ #define HEALTHY_TIN (-3) /* Corpse aging */ -#define TAINT_AGE (50L) /* age when corpses go bad */ +#define INEDIBLE_AGE (50L) /* age when corpse becomes unsafe to eat */ +#define TAINT_AGE (100L) /* age when corpse becomes tainted */ +#define ROT_AGE (250L) /* age when corpse rots away */ #define TROLL_REVIVE_CHANCE 37 /* 1/37 chance for 50 turns ~ 75% chance */ -#define ROT_AGE (250L) /* age when corpses rot away */ /* Some misc definitions */ #define POTION_OCCUPANT_CHANCE(n) (13 + 2 * (n)) diff --git a/include/hacklib.h b/include/hacklib.h index 18630e1b1..3db368a58 100644 --- a/include/hacklib.h +++ b/include/hacklib.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 hacklib.h $NHDT-Date: 1725653010 2024/09/06 20:03:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 hacklib.h $NHDT-Date: 1781973081 2026/06/20 16:31:21 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/integer.h b/include/integer.h index f12cf21bf..7fb059887 100644 --- a/include/integer.h +++ b/include/integer.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 integer.h $NHDT-Date: 1720397754 2024/07/08 00:15:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 integer.h $NHDT-Date: 1781973081 2026/06/20 16:31:21 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ @@ -50,7 +50,7 @@ #endif /* !HAS_INTTYPES_H */ #if defined(__GNUC__) && defined(__INT64_MAX__) && !defined(HAS_STDINT_H) #define HAS_STDINT_H -#endif +#endif #endif /* claims to be C99 */ #endif /*?__DECC*/ diff --git a/include/lint.h b/include/lint.h index 76d9aee7a..c92671c6f 100644 --- a/include/lint.h +++ b/include/lint.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 lint.h $NHDT-Date: 1655631029 2022/06/19 09:30:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ +/* NetHack 5.0 lint.h $NHDT-Date: 1781973081 2026/06/20 16:31:21 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) 2016 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mail.h b/include/mail.h index 4b3ec2d05..835f89d3c 100644 --- a/include/mail.h +++ b/include/mail.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mail.h $NHDT-Date: 1596498544 2020/08/03 23:49:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mail.h $NHDT-Date: 1781973081 2026/06/20 16:31:21 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) 2015 by Kenneth Lorber */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mextra.h b/include/mextra.h index 8472a5ad2..771696cd6 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mextra.h $NHDT-Date: 1720717969 2024/07/11 17:12:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mextra.h $NHDT-Date: 1781973082 2026/06/20 16:31:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mfndpos.h b/include/mfndpos.h index a1ec75461..d5efb5495 100644 --- a/include/mfndpos.h +++ b/include/mfndpos.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mfndpos.h $NHDT-Date: 1596498546 2020/08/03 23:49:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 mfndpos.h $NHDT-Date: 1781973082 2026/06/20 16:31:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2005. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/micro.h b/include/micro.h index fd10be51b..ad1e3d25d 100644 --- a/include/micro.h +++ b/include/micro.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 micro.h $NHDT-Date: 1596498546 2020/08/03 23:49:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 micro.h $NHDT-Date: 1781973082 2026/06/20 16:31:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) 2015 by Kenneth Lorber */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mkroom.h b/include/mkroom.h index 883d97020..81c0de6c7 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkroom.h $NHDT-Date: 1725653011 2024/09/06 20:03:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 mkroom.h $NHDT-Date: 1781973082 2026/06/20 16:31:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.35 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monattk.h b/include/monattk.h index 912d93284..7cddd1dee 100644 --- a/include/monattk.h +++ b/include/monattk.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monattk.h $NHDT-Date: 1596498548 2020/08/03 23:49:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 monattk.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.23 $ */ /* NetHack may be freely redistributed. See license for details. */ /* Copyright 1988, M. Stephenson */ diff --git a/include/mondata.h b/include/mondata.h index 430b5e83d..4cd388d66 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mondata.h $NHDT-Date: 1703845738 2023/12/29 10:28:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ */ +/* NetHack 5.0 mondata.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monflag.h b/include/monflag.h index 18c2e4256..2e8234bc4 100644 --- a/include/monflag.h +++ b/include/monflag.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monflag.h $NHDT-Date: 1596498549 2020/08/03 23:49:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 monflag.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.33 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/monst.h b/include/monst.h index 8f189b4b7..5cd6aa64d 100644 --- a/include/monst.h +++ b/include/monst.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monst.h $NHDT-Date: 1738640524 2025/02/03 19:42:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 5.0 monst.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -55,15 +55,23 @@ enum m_ap_types { M_AP_MONSTER = 3 /* a monster; mostly used for cloned Wizard */ }; -#define MON_FLOOR 0x00 -#define MON_OFFMAP 0x01 -#define MON_DETACH 0x02 -#define MON_MIGRATING 0x04 -#define MON_LIMBO 0x08 -#define MON_BUBBLEMOVE 0x10 -#define MON_ENDGAME_FREE 0x20 -#define MON_ENDGAME_MIGR 0x40 -#define MON_OBLITERATE 0x80 +#define MON_FLOOR 0x00000000 +#define MON_OFFMAP 0x00000001 +#define MON_DETACH 0x00000002 +#define MON_MIGRATING 0x00000004 +#define MON_LIMBO 0x00000008 +#define MON_BUBBLEMOVE 0x00000010 +#define MON_ENDGAME_FREE 0x00000020 +#define MON_ENDGAME_MIGR 0x00000040 +#define MON_OBLITERATE 0x00000080 +#define MON_STILL_ARRIVING 0x00000100 +#define MON_PARKED 0x00000200 +/* 0x10000000 through 0x40000000 match enum pending_terrain_effects */ +/* 0x10000000 */ /* nonflyer_vs_liquid */ +/* 0x20000000 */ /* candrown_vs_liquid */ +/* 0x40000000 */ +#define TERRAIN_FALLOUT_MASK 0x70000000 + #define M_AP_TYPMASK 0x7 #define M_AP_F_DKNOWN 0x8 @@ -211,6 +219,10 @@ struct monst { /* dead monsters stay on the fmon list until dmonsfree() at end of turn */ #define DEADMONSTER(mon) ((mon)->mhp < 1) +/* vault guards intentionally remain on the fmon list at 0,0 until + the temporary corridor is dealt with */ +#define PARKEDMONSTER(mon) ((mon)->isgd && (mon)->mx == 0) +/* eventually, we'll be able to use (((mon)->mstate & MON_PARKED) != 0) */ #define is_starting_pet(mon) ((mon)->m_id == svc.context.startingpet_mid) #define is_vampshifter(mon) \ @@ -251,7 +263,10 @@ struct monst { #define mon_perma_blind(mon) (!mon->mcansee && !mon->mblinded) -#define mon_offmap(mon) ((mon)->mstate != MON_FLOOR) +#define MON_OFF_MAP_BITS (MON_OFFMAP | MON_DETACH | MON_LIMBO | MON_MIGRATING \ + | MON_ENDGAME_FREE | MON_ENDGAME_MIGR | MON_BUBBLEMOVE | MON_PARKED) + +#define mon_offmap(mon) (((mon)->mstate & (MON_OFF_MAP_BITS)) != 0) /* Get the maximum difficulty monsters that can currently be generated, given the current level difficulty and the hero's level. */ diff --git a/include/monsters.h b/include/monsters.h index c7605d3b6..4677a3740 100644 --- a/include/monsters.h +++ b/include/monsters.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 monsters.h $NHDT-Date: 1723945838 2024/08/18 01:50:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.124 $ */ +/* NetHack 5.0 monsters.h $NHDT-Date: 1781973083 2026/06/20 16:31:23 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.134 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -972,7 +972,7 @@ 8, CLR_RED, SCORPION), /* * trappers, lurkers, &c - * Note: prior to 3.7, these were defined to do AD_DGST damage, + * Note: prior to 5.0, these were defined to do AD_DGST damage, * but they don't swallow their victims into their stomachs and * digest, they enfold and crush or suffocate. * The Monster Manual states that someone engulfed by a trapper @@ -2031,7 +2031,7 @@ | M1_OMNIVORE, M2_STRONG, 0, 13, HI_GOLD, GOLDEN_NAGA), - /* 3.7: guardian naga used to have three attacks: bite, spit, hug + /* 5.0: guardian naga used to have three attacks: bite, spit, hug but in order for the hug to succeed the two preceding attacks had to have hit, and it's not possible to both bite and spit, hence the hug never hit; change to spit, bite, touch, hug; if the bite @@ -2132,7 +2132,7 @@ M1_HUMANOID | M1_OMNIVORE | M1_POIS | M1_TPORT, M2_HOSTILE, M3_INFRAVISIBLE, 9, CLR_CYAN, QUANTUM_MECHANIC), - /* 3.7: from slash'em, to expand Q class; hit polymorphs target */ + /* 5.0: from slash'em, to expand Q class; hit polymorphs target */ MON(NAM("genetic engineer"), S_QUANTMECH, LVL(12, 12, 3, 10, 0), (G_GENO | 1), A(ATTK(AT_CLAW, AD_POLY, 1, 4), @@ -2695,7 +2695,7 @@ | M2_SHAPESHIFTER, M3_INFRAVISIBLE, 11, HI_DOMESTIC, DOPPELGANGER), - /* 3.7: shopkeepers used to have speed 18, but if/when they were + /* 5.0: shopkeepers used to have speed 18, but if/when they were hasted they always got 2 moves per turn and had a tendency to move away from blocking the door and then move right back; since they might start with a potion of speed and drink that as soon as the @@ -2925,7 +2925,7 @@ #define SEDUCTION_ATTACKS_NO \ A(ATTK(AT_CLAW, AD_PHYS, 1, 3), ATTK(AT_CLAW, AD_PHYS, 1, 3), \ ATTK(AT_BITE, AD_DRLI, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK) - /* incubus and succubus; prior to 3.7, succubus and incubus were + /* incubus and succubus; prior to 5.0, succubus and incubus were distinct monsters; "amorous demon" is considered to be a temporary placeholder but may be here to stay... */ MON(NAMS("incubus", "succubus", "amorous demon"), S_DEMON, @@ -3195,7 +3195,7 @@ /* * sea monsters * - * 3.7: all the fish except kraken used to specify M1_SLITHY, presumably + * 5.0: all the fish except kraken used to specify M1_SLITHY, presumably * cloned from giant eel. Using "slither" to describe their movement * wasn't appropriate. Unfortunately, locomotion() isn't able to choose * "swim" as their movement description because it is only passed a diff --git a/include/nhmd4.h b/include/nhmd4.h index f235a1bb7..658ec0117 100644 --- a/include/nhmd4.h +++ b/include/nhmd4.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhmd4.h $NHDT-Date: 1708811386 2024/02/24 21:49:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhmd4.h $NHDT-Date: 1781973084 2026/06/20 16:31:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ */ /*- Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/nhregex.h b/include/nhregex.h index 6dc989213..e85fe2f23 100644 --- a/include/nhregex.h +++ b/include/nhregex.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhregex.h $NHDT-Date: $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: $ */ +/* NetHack 5.0 nhregex.h $NHDT-Date: $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: $ */ /* NetHack may be freely redistributed. See license for details. */ #ifndef NHREGEX_H diff --git a/include/obj.h b/include/obj.h index d9ef83d21..ba5e26d5d 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 obj.h $NHDT-Date: 1718999845 2024/06/21 19:57:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 obj.h $NHDT-Date: 1781973084 2026/06/20 16:31:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.131 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/objclass.h b/include/objclass.h index fa210f519..4e006fb59 100644 --- a/include/objclass.h +++ b/include/objclass.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 objclass.h $NHDT-Date: 1596498553 2020/08/03 23:49:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 5.0 objclass.h $NHDT-Date: 1781973084 2026/06/20 16:31:24 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/objects.h b/include/objects.h index 41076db28..f1f410606 100644 --- a/include/objects.h +++ b/include/objects.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 objects.h $NHDT-Date: 1749097644 2025/06/04 20:27:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 objects.h $NHDT-Date: 1781973085 2026/06/20 16:31:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ */ /* Copyright (c) Mike Threepoint, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -224,7 +224,7 @@ WEAPON("stiletto", NoDes, /* 3.6: worm teeth and crysknives now stack; when a stack of teeth is enchanted at once, they fuse into one crysknife; when a stack of crysknives drops, the whole stack reverts to teeth */ -/* 3.7: change crysknife from MINERAL to BONE and worm tooth from 0 to BONE */ +/* 5.0: change crysknife from MINERAL to BONE and worm tooth from 0 to BONE */ WEAPON("worm tooth", NoDes, 1, 1, 0, 0, 20, 2, 2, 2, 0, 0, P_KNIFE, BONE, CLR_WHITE, WORM_TOOTH), @@ -1453,7 +1453,7 @@ WAND("secret door detection", WAN_SECRET_DOOR_DETECTION), WAND("enlightenment", "crystal", 15, 150, 1, NODIR, GLASS, HI_GLASS, WAN_ENLIGHTENMENT), -WAND("create monster", "maple", 45, 200, 1, NODIR, WOOD, HI_WOOD, +WAND("create monster", "maple", 50, 200, 1, NODIR, WOOD, HI_WOOD, WAN_CREATE_MONSTER), WAND("wishing", "pine", 5, 500, 1, NODIR, WOOD, HI_WOOD, WAN_WISHING), @@ -1477,13 +1477,13 @@ WAND("cancellation", "platinum", 45, 200, 1, IMMEDIATE, PLATINUM, CLR_WHITE, WAN_CANCELLATION), WAND("teleportation", "iridium", 45, 200, 1, IMMEDIATE, METAL, CLR_BRIGHT_CYAN, WAN_TELEPORTATION), -WAND("opening", "zinc", 25, 150, 1, IMMEDIATE, METAL, HI_METAL, +WAND("opening", "zinc", 30, 150, 1, IMMEDIATE, METAL, HI_METAL, WAN_OPENING), -WAND("locking", "aluminum", 25, 150, 1, IMMEDIATE, METAL, HI_METAL, +WAND("locking", "aluminum", 30, 150, 1, IMMEDIATE, METAL, HI_METAL, WAN_LOCKING), WAND("probing", "uranium", 30, 150, 1, IMMEDIATE, METAL, HI_METAL, WAN_PROBING), -WAND("digging", "iron", 55, 150, 1, RAY, IRON, HI_METAL, +WAND("digging", "iron", 40, 150, 1, RAY, IRON, HI_METAL, WAN_DIGGING), /* magic missile ... lightning must be in this order; see buzz() */ WAND("magic missile", "steel", 50, 150, 1, RAY, IRON, HI_METAL, diff --git a/include/optlist.h b/include/optlist.h index 4d3474a4b..efb26982e 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 optlist.h */ +/* NetHack 5.0 optlist.h */ /* NetHack may be freely redistributed. See license for details. */ #ifndef OPTLIST_H @@ -137,7 +137,7 @@ static int optfn_##a(int, int, boolean, char *, char *); "your starting alignment (lawful, neutral, or chaotic)") /* end of special ordering; remainder of entries are in alphabetical order */ - NHOPTB(accessiblemsg, Advanced, 0, opt_out, set_in_game, + NHOPTB(accessiblemsg, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &a11y.accessiblemsg, Term_False, "add location information to messages") NHOPTB(acoustics, Advanced, 0, opt_out, set_in_game, @@ -159,6 +159,10 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(altmeta, Advanced, 0, opt_out, set_in_game, Off, Yes, No, No, NoAlias, &iflags.altmeta, Term_False, "treat \"ESC c\" as M-c (Meta+c, 8th bit set)") +#elif defined(AMIGA_INTUITION) + NHOPTB(altmeta, Advanced, 0, opt_out, set_in_game, + On, Yes, No, No, NoAlias, &sysflags.altmeta, Term_False, + "treat ALT+c as M-c (Meta+c, 8th bit set)") #else NHOPTB(altmeta, Advanced, 0, opt_out, set_in_config, Off, Yes, No, No, NoAlias, (boolean *) 0, Term_False, @@ -167,7 +171,9 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(armorstatus, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.armorstatus, Term_False, "summarize currently worn armor in a status field") - NHOPTB(ascii_map, Advanced, 0, opt_in, set_in_game, + /* this one needs unique handling because different window ports + expect different defaults */ + NHOPTB(ascii_map, Advanced, 0, ascii_map_Def, set_in_game, ascii_map_Def, Yes, No, No, NoAlias, &iflags.wc_ascii_map, Term_False, "show map as text") NHOPTO("autocompletions", Advanced, o_autocomplete, BUFSZ, opt_in, @@ -181,7 +187,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(autoopen, Behavior, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.autoopen, Term_False, "walking into a door attempts to open it") - NHOPTB(autopickup, Behavior, 0, opt_out, set_in_game, + NHOPTB(autopickup, Behavior, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.pickup, Term_False, "automatically pick up objects") NHOPTO("autopickup exceptions", Behavior, o_autopickup_exceptions, BUFSZ, @@ -233,7 +239,7 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(cmdassist, Behavior, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &iflags.cmdassist, Term_False, "give help for errors on direction input") - NHOPTB(color, Map, 0, opt_in, set_in_game, + NHOPTB(color, Map, 0, opt_out, set_in_game, On, Yes, No, No, "colour", &iflags.wc_color, Term_False, "use color in map") NHOPTB(confirm, Advanced, 0, opt_out, set_in_game, @@ -357,11 +363,15 @@ static int optfn_##a(int, int, boolean, char *, char *); NHOPTB(herecmd_menu, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.herecmd_menu, Term_False, "show commands available in this location") -#if defined(MAC) +#if 0 +/* there is no optfn_hicolor() defined in options.c presently + and that is required for NHOPTC */ +#if defined(MAC68K) NHOPTC(hicolor, Advanced, 15, opt_in, set_in_config, No, Yes, No, No, NoAlias, "same as palette, only order is reversed") #endif +#endif /* 0 */ NHOPTB(hilite_pet, Map, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.wc_hilite_pet, Term_False, "use highlight for pets") @@ -387,7 +397,10 @@ static int optfn_##a(int, int, boolean, char *, char *); Yes, Yes, No, No, NoAlias, "load IBMGraphics display symbols into symset") #endif -#ifndef MAC + NHOPTB(idlecheckpoint, Advanced, 0, opt_in, set_in_game, + Off, Yes, No, No, NoAlias, &iflags.idlecheckpoint, Term_Off, + "update checkpoint file if input is idle for 10 seconds") +#ifndef MAC68K NHOPTB(ignintr, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.ignintr, Term_False, "ignore interrupt signals") @@ -417,7 +430,7 @@ static int optfn_##a(int, int, boolean, char *, char *); On, Yes, No, No, NoAlias, &flags.biff, Term_False, "enable the mail daemon") NHOPTC(map_mode, Advanced, 20, opt_in, set_gameview, - Yes, Yes, No, No, NoAlias, "map display mode under Windows") + Yes, Yes, Yes, No, NoAlias, "map display mode under Windows") NHOPTB(mention_decor, Advanced, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.mention_decor, Term_False, "give feedback when walking over interesting features") @@ -449,7 +462,7 @@ static int optfn_##a(int, int, boolean, char *, char *); Yes, Yes, No, Yes, "use_menu_glyphs", "show object symbols in menus") #ifdef TTY_GRAPHICS - NHOPTB(menu_overlay, Advanced, 0, opt_in, set_in_game, + NHOPTB(menu_overlay, Advanced, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &iflags.menu_overlay, Term_False, "menus overlay and align to right") #else @@ -539,7 +552,7 @@ static int optfn_##a(int, int, boolean, char *, char *); No, Yes, No, No, NoAlias, "the inventory order of the items in your pack") #ifdef CHANGE_COLOR -#ifndef MAC /* not old Mac OS9 */ +#ifndef MAC68K /* not old Mac OS9 */ NHOPTC(palette, Advanced, 15, opt_in, set_gameview, No, Yes, Yes, No, "hicolor", "palette (adjust an RGB color in palette (color/R-G-B)") @@ -761,7 +774,7 @@ static int optfn_##a(int, int, boolean, char *, char *); "display game turns in status line") #ifdef TIMED_DELAY NHOPTB(timed_delay, Map, 0, opt_out, set_in_game, - Off, Yes, No, No, NoAlias, &flags.nap, Term_False, + On, Yes, No, No, NoAlias, &flags.nap, Term_False, "use delay when pausing for display effects") #else NHOPTB(timed_delay, Map, 0, opt_in, set_in_config, @@ -784,11 +797,11 @@ static int optfn_##a(int, int, boolean, char *, char *); On, Yes, No, No, NoAlias, &flags.travelcmd, Term_False, "enable traveling via mouse click") #ifdef DEBUG - NHOPTB(travel_debug, Advanced, 0, opt_out, set_wizonly, + NHOPTB(travel_debug, Advanced, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.trav_debug, Term_False, (char *)0) #else - NHOPTB(travel_debug, Advanced, 0, opt_out, set_wizonly, + NHOPTB(travel_debug, Advanced, 0, opt_in, set_wizonly, Off, No, No, No, NoAlias, (boolean *) 0, Term_False, (char *)0) #endif @@ -812,7 +825,7 @@ static int optfn_##a(int, int, boolean, char *, char *); (char *)0) NHOPTC(versinfo, Advanced, 80, opt_out, set_in_game, No, Yes, No, Yes, NoAlias, "extra information for 'showvers'") -#ifdef MSDOS +#if defined(MSDOS) && defined(NO_TERMS) NHOPTC(video, Advanced, 20, opt_in, set_in_config, No, Yes, No, No, NoAlias, "method of video updating") #endif diff --git a/include/patchlevel.h b/include/patchlevel.h index 75e1d3311..7bf713ff5 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 patchlevel.h $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */ +/* NetHack 5.0 patchlevel.h $NHDT-Date: 1781973085 2026/06/20 16:31:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.310 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,9 +6,9 @@ #ifndef PATCHLEVEL_H #define PATCHLEVEL_H -/* NetHack 3.7.x */ -#define VERSION_MAJOR 3 -#define VERSION_MINOR 7 +/* NetHack 5.0.x */ +#define VERSION_MAJOR 5 +#define VERSION_MINOR 0 /* * PATCHLEVEL is updated for each release. */ @@ -17,7 +17,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 140 +#define EDITLEVEL 0 /* * Development status possibilities. @@ -30,7 +30,7 @@ /* * Development status of this NetHack version. */ -#define NH_DEVEL_STATUS NH_STATUS_WIP +#define NH_DEVEL_STATUS NH_STATUS_POSTRELEASE #ifndef DEBUG /* allow tool chains to define without causing warnings */ #define DEBUG @@ -43,6 +43,14 @@ #define COPYRIGHT_BANNER_C nomakedefs.copyright_banner_c #define COPYRIGHT_BANNER_D " See license for details." +/* + * SAVEFILE_REVISION_LEVEL + * Increment this if there has been a change to a data structure + * that the source code is prepared to handle and convert properly. + * The SAVEFILE_REVISION_LEVEL value needs to fit into an unsigned byte. + */ +#define SAVEFILE_REVISION_LEVEL 0x00 + /* * If two or more successive releases have compatible data files, define * this with the version number of the oldest such release so that the @@ -59,13 +67,18 @@ * to individual level files matter; changes to general game state don't) * but the extra complexity to support that is not worth the effort.] */ -/*#define VERSION_COMPATIBILITY 0x03070000L*/ +/*#define VERSION_COMPATIBILITY 0x05000000L*/ /****************************************************************************/ -/* Version 3.7.x */ +/* Version 5.0.x */ /* - * NetHack 3.7.0, + * NetHack 5.0.0, May 2, 2026 + * + * Sources changed to be compliant with the C99 standard. + * level compiler, dungeon compiler, and quest text all replaced with + * Lua alternatives. + * Refer to doc/fixes5-0-0.txt for a complete list of fixes and changes. * */ @@ -75,7 +88,7 @@ /* Patch 7, February 16, 2023 * * during engraving, spaces were counted instead of non-space (cherry-pick of - * 4e0a1e04 from NetHack-3.7) + * 4e0a1e04 from NetHack WIP) * avoid potential buffer overflow in append_str() * resolve missing dependency in NetHack.sln * code in include/tradstdc.h was trying to suppress warn_unused result by @@ -95,7 +108,7 @@ * the official 3.6.6 binary was built. * windows: switch from using keyhandling dll's to incorporating the three * variations (default, ray, 340) in sys/winnt/nttty.c - * curses: cherry-picked selectsaved code from 3.7 for menu of save files + * curses: cherry-picked selectsaved code from 5.0 for menu of save files * NetHackW: fix delayed rendering of cursor when using farlook */ diff --git a/include/pcconf.h b/include/pcconf.h index 6736d8d9d..bdcc8e56b 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcconf.h $NHDT-Date: 1596498554 2020/08/03 23:49:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ +/* NetHack 5.0 pcconf.h $NHDT-Date: 1781973085 2026/06/20 16:31:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.40 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -73,9 +73,9 @@ * You may uncomment any/all of the options below. * */ -#ifndef SUPPRESS_GRAPHICS +#if defined(TTY_GRAPHICS) && !defined(SUPPRESS_GRAPHICS) #if (defined(SCREEN_BIOS) || defined(SCREEN_DJGPPFAST)) && !defined(PC9800) -#ifdef TILES_IN_GLYPHMAP +#if defined(TILES_IN_GLYPHMAP) || defined(ENHANCED_SYMBOLS) #define SCREEN_VGA /* Include VGA graphics routines in the build */ #define SCREEN_VESA #endif @@ -148,9 +148,13 @@ LEVELDIR, SAVEDIR, BONESDIR, DATADIR, \ SCOREDIR, LOCKDIR, CONFIGDIR, and TROUBLEDIR. \ */ - #endif /* MSDOS configuration stuff */ +/* include early argument processing --dumpenums etc. */ +#if defined(MSDOS) +#define PC_EARLY_OPTIONS +#endif + #ifndef PATHLEN #define PATHLEN 64 /* maximum pathlength */ #endif @@ -288,6 +292,10 @@ #endif #endif /* End of sanity check block */ +#if defined(MSDOS) && defined(SUPPRESS_GRAPHICS) +#define NO_TERMCAP_HEADERS +#endif + #if defined(MSDOS) && defined(DLB) #define FILENAME_CMP stricmp /* case insensitive */ #endif diff --git a/include/permonst.h b/include/permonst.h index fbc135c41..24b7c0cbe 100644 --- a/include/permonst.h +++ b/include/permonst.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 permonst.h $NHDT-Date: 1725653014 2024/09/06 20:03:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 permonst.h $NHDT-Date: 1781973085 2026/06/20 16:31:25 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/prop.h b/include/prop.h index 16b7efd50..e7a108e01 100644 --- a/include/prop.h +++ b/include/prop.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 prop.h $NHDT-Date: 1702274027 2023/12/11 05:53:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 prop.h $NHDT-Date: 1781973086 2026/06/20 16:31:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/quest.h b/include/quest.h index 77af3049f..d91dd8f93 100644 --- a/include/quest.h +++ b/include/quest.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 quest.h $NHDT-Date: 1596498556 2020/08/03 23:49:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 quest.h $NHDT-Date: 1781973086 2026/06/20 16:31:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Mike Stephenson 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/rect.h b/include/rect.h index 5544db272..ef444a223 100644 --- a/include/rect.h +++ b/include/rect.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 rect.h $NHDT-Date: 1596498557 2020/08/03 23:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 rect.h $NHDT-Date: 1781973086 2026/06/20 16:31:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) 1990 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/region.h b/include/region.h index b9b7ced43..87cda9f0e 100644 --- a/include/region.h +++ b/include/region.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 region.h $NHDT-Date: 1596498557 2020/08/03 23:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 region.h $NHDT-Date: 1781973086 2026/06/20 16:31:26 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/revision.h b/include/revision.h new file mode 100644 index 000000000..70c0dd6fe --- /dev/null +++ b/include/revision.h @@ -0,0 +1,228 @@ +/* NetHack 5.0 revision.h $NHDT-Date: 1779927286 2026/05/28 00:14:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ */ +/* Copyright (c) Michael Allison, 2026. */ +/* NetHack may be freely redistributed. See license for details. */ + +/* + * Supporting revisions to NetHack structs via incremental + * uplifts, rather than incrementing EDITLEVEL and breaking + * savefile compatibility. + * + * Here is the contrived example struct we'll use for + * this document: + * + * The old revision: The new revision: + * + * struct mystruct { struct mystruct { + * int field1; int field1; + * int field2; int field2; + * char field3; char field3; + * long field4; long field4; + * }; int newfielda; + * int newfieldb; + * }; + * + * Steps (using mystruct as an example name) + * + * 1. Paste an exact copy of the struct declaration as it is/was + * in the previous revision into include/revision.h, shrouded by + * #if defined(MYSTRUCT_REV0), and tack a '_rev0' suffix onto the + * name of the struct. For example, + * + * #if defined(MYSTRUCT_REV0) + * struct mystruct_rev0 { + * int field1; + * int field2; + * char field3; + * long field4; + * }; + * + * That goes just ahead of this existing placeholder: + * + * #elif defined(XXX_REV0) + * + * 2. Place a comment ahead of the mystruct_rev0 declaration + * that explains what has changed, and why the revision + * is required. + * + * 3. Immediately following the revised struct declaration in the + * original header file where it is located, add the following: + * + * #define MYSTRUCT_REV0 + * #include "revision.h" + * #undef MYSTRUCT_REV0 + * + * 4. In include/savefile.h, add a new prototype for a function + * to read the previous revision from the savefile, ideally + * immediately following the prototype for the current active + * one that hasn't got the '_rev0' suffix: + * + * extern void sfi_mystruct(NHFILE *, struct mystruct *, + * const char *); + * extern void sfi_mystruct_rev0(NHFILE *, struct mystruct_rev0 *, + * const char *); + * + * 5. Also in include/savefile.h, in the '#if NH_C < 202300L' block, + * add an entry below the one that should already exist for the + * struct that hasn't got the '_rev0' suffix: + * + * #define Sfi_mystruct(a,b,c) sfi_rm(a, b, c) + * #define Sfi_mystruct_rev0(a, b, c) sfi_mystruct_rev0(a, b, c) + * + * 6. Also in include/savefile.h, in the '#define sfi(nhfp, dt, tag)' + * generic function definition, add an entry below the one + * that should already exist for the struct name that hasn't + * got the '_rev0' suffix: + * + * struct mystruct * : sfi_mystruct, \ + * struct mystruct_rev0 * : sfi_mysruct_rev0, \ + * + * 7. Also in include/savefile.h, a little further down in the + * 'Sfi_' macro definitions, add one below the existing + * one for the struct without the '_rev0' suffix: + * + * #define Sfi_mystruct(a,b,c) sfi(a, b, c) + * #define Sfi_mystruct_rev0(a, b, c) sfi(a, b, c) + * + * Only the input 'Sfi_' is required, because the old revision + * will never be written out to a file, only read in from a + * a file, so no 'Sfo_' is needed. + * + * 8. In include/sfmacros.h, add a new entry below the existing + * entry that exists without the '_rev0' suffix: + * + * SF_C(struct, mystruct) + * SF_C(struct, mystruct_rev0) + * + * 9. In include/sfprocs.h, add a new SF_PROTO_C entry below the + * existing entry that already exists without the '_rev0' suffix: + * + * SF_PROTO_C(struct, mystruct); + * SF_PROTO_C(struct, mystruct_rev0); + * + * 10. Also in include/sfprocs.h, add a new SF_ENTRY_C entry below the + * entry that already exists without the '_rev0' suffix: + * + * SF_ENTRY_C(struct, mystruct); + * SF_ENTRY_C(struct, mystruct_rev0); + * + * 11. In src/sfbase.c, add a prototype for a 'norm_ptrs' stub function + * below the entry that already exists without the '_rev0' suffix: + * + * void norm_ptrs_mystruct(struct mystruct *d_mystruct); + * void norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct); + * + * 12. Also in src/sfbase.c, add a 'norm_ptrs' stub function below the + * stub function that already exists without the '_rev0' suffix: + * + * void + * norm_ptrs_mystruct(struct mystruct *d_mystruct UNUSED) + * { + * } + * + * void + * norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct_rev0 UNUSED) + * { + * } + * + * 13. In src/sfstruct.c, add entries to the 'historical' section below the + * existing entry that doesn't have a '_rev0' suffix. You need an 'sfo_' + * entry and an 'sfi_' entry here, because they have to match function + * pointers in another struct. The 'sfo_' function will not be called + * from anywhere. + * + * historical_sfo_mystruct, + * historical_sfo_mystruct_rev0, + * ... + * historical_sfi_mystruct, + * historical_sfi_mystruct_rev0, + * + * 14. In the C source file where the 'Sfi_' call is made for your struct, + * the current code likely has a line for reading the struct from + * a file, similar the one shown below for the mystruct example: + * + * Sfi_mystruct(nhfp, &svl.mystruct, "mystruct-example"); + * + * That single line will need to modified to become a code block similar + * to this, so that the uplift function will get called: + * + * if (!gu.uplift_needed_rev0_to_rev1) { + * Sfi_mystruct(nhfp, &svl.mystruct, "mystruct-example"); + * } else { + * struct mystruct_rev0 old_mystruct; + * + * Sfi_mystruct_rev0(nhfp, &old_mystruct, "mystruct-example"); + * uplift_mystruct_rev0_to_mystruct(&old_mystruct, &svl.mystruct); + * } + * } + * + * 15. Shortly after the reading of the struct by the 'Sfi_' function, + * if the newer revision of the struct added some new fields, new code + * will be needed to initialize the new fields to sane values. + * There is no data for the new fields in the existing savefile. + * + * if (gu.uplift_needed_rev0_to_rev1 == 1) { + * svl.mystruct.newfielda = sanevalue1; + * svl.mystruct.newfieldb = sanevalue2; + * } + * + * 16. In include/extern.h, add a prototype to the ' ### revision.c ###' + * section for the supporting uplift function: + * + * extern void uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *, + * struct mystruct *); + * + * 17. Add the uplift function to src/revision.c. It needs to do + * field-by-field copies of the fields that exist in the old + * revision and the new revision. For now, it likely needs to + * be handcrafted using your knowledge of the struct's old + * and new revisions. + * + * Be sure that any new fields present in the newer revision + * of the struct get set to sane values or initialized to + * zero. Do whatever suits those fields best, based on your + * knowledge of the struct. + * + * void + * uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *rev0, + * struct mystruct *rev1) + * { + * rev1->field1 = rev0->field1; + * rev1->field2 = rev0->field2; + * rev1->field3 = rev0->field3; + * rev1->field4 = rev0->field4; + * + * rev1->newfielda = 0; // new field + * rev1->newfieldb = 42; // new field + * } + * + */ + +#if defined(MYSTRUCT_REV0) +#ifdef DEMO_UPLIFTS +/* + * struct mystruct_rev0 + * + * This is the predecessor for 'struct mystruct' + * Revisions to 'struct mystruct' that 'struct mystruct_rev0' does not have: + * int newfielda; + * int newfieldb; + * + * The uplift function is: + * void uplift_mystruct_rev0_to_mystruct(struct *mystruct_rev0, + * struct *mystruct); + */ + +struct mystruct_rev0 { + int field1; + int field2; + char field3; + long field4; +}; +#endif /* DEMO_UPLIFTS */ + +#elif defined(XXX_REV0) + +#else +#error Unproductive inclusion of revision.h +#endif +/* revision.h */ diff --git a/include/rm.h b/include/rm.h index 0819b4d52..729997efa 100644 --- a/include/rm.h +++ b/include/rm.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 rm.h $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ +/* NetHack 5.0 rm.h $NHDT-Date: 1781973087 2026/06/20 16:31:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.126 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/savefile.h b/include/savefile.h index dc569c771..22eb5ac6e 100644 --- a/include/savefile.h +++ b/include/savefile.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 savefile.h $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1476 $ */ +/* NetHack 5.0 savefile.h $NHDT-Date: 1781973087 2026/06/20 16:31:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ @@ -184,6 +184,10 @@ extern void sfi_int(NHFILE *, int *, const char *); extern void sfi_unsigned(NHFILE *, unsigned *, const char *); extern void sfi_long(NHFILE *, long *, const char *); extern void sfi_ulong(NHFILE *, ulong *, const char *); +#ifdef DEMO_UPLIFTS +extern void sfi_mystruct(NHFILE *, struct mystruct *, const char *); +extern void sfi_mystruct_rev0(NHFILE *, struct mystruct_rev0 *, const char *); +#endif #if NH_C < 202300L #define Sfo_aligntyp(a,b,c) sfo_aligntyp(a, b, c) #define Sfo_any(a,b,c) sfo_any(a, b, c) @@ -315,6 +319,10 @@ extern void sfi_ulong(NHFILE *, ulong *, const char *); #define Sfi_unsigned(a, b, c) sfi_unsigned(a, b, c); #define Sfi_xint8(a, b, c) sfi_xint8(a, b, c); #define Sfi_xint16(a, b, c) sfi_xint16(a, b, c); +#ifdef DEMO_UPLIFTS +#define Sfi_mystruct(a, b, c) sfi_mystruct(a, b, c) +#define Sfi_mystruct_rev0(a, b, c) sfi_mystruct_rev0(a, b, c) +#endif #else #define sfo(nhfp, dt, tag) \ @@ -553,7 +561,7 @@ extern void sfi_ulong(NHFILE *, ulong *, const char *); #define Sfi_dest_area(a,b,c) sfi(a, b, c) #define Sfi_levelflags(a,b,c) sfi(a, b, c) #define Sfi_rm(a,b,c) sfi(a, b, c) -#define Sfi_cemetery(a,b,c) sfi(a, b, c) +#define Sfi_cemetery(a,b,c) sfi_cemetery(a, b, c) #define Sfi_damage(a,b,c) sfi(a, b, c) #define Sfi_stairway(a,b,c) sfi(a, b, c) #define Sfi_obj(a,b,c) sfi(a, b, c) @@ -575,6 +583,10 @@ extern void sfi_ulong(NHFILE *, ulong *, const char *); #define Sfi_unsigned(a, b, c) sfi(a, b, c) #define Sfi_xint8(a, b, c) sfi(a, b, c) #define Sfi_xint16(a, b, c) sfi(a, b, c) +#ifdef DEMO_UPLIFTS +#define Sfi_mystruct(a, b, c) sfi(a, b, c) +#define Sfi_mystruct_rev0(a, b, c) sfi(a, b, c) +#endif #endif /* not in _Generic */ diff --git a/include/seffects.h b/include/seffects.h index 0774209b0..9ad03b0d5 100644 --- a/include/seffects.h +++ b/include/seffects.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 seffects.h $NHDT-Date: 1693253118 2023/08/28 20:05:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 seffects.h $NHDT-Date: 1781973087 2026/06/20 16:31:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ */ /* Copyright (c) Michael Allison, 2023 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/selvar.h b/include/selvar.h index 2551efa34..2854173f4 100644 --- a/include/selvar.h +++ b/include/selvar.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 selvar.h $NHDT-Date: 1709677544 2024/03/05 22:25:44 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 selvar.h $NHDT-Date: 1709677544 2024/03/05 22:25:44 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sfmacros.h b/include/sfmacros.h index 752b74978..0905effaf 100644 --- a/include/sfmacros.h +++ b/include/sfmacros.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfmacros.h $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 5.0 sfmacros.h $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ @@ -49,6 +49,10 @@ SF_C(struct, s_level) SF_C(struct, trap) SF_C(struct, you) SF_C(union, any) +#ifdef DEMO_UPLIFTS +SF_C(struct, mystruct) +SF_C(struct, mystruct_rev0) +#endif SF_A(aligntyp) SF_A(boolean) diff --git a/include/sfprocs.h b/include/sfprocs.h index f544b04c9..63bb631fe 100644 --- a/include/sfprocs.h +++ b/include/sfprocs.h @@ -68,6 +68,10 @@ SF_PROTO_C(struct, trap); SF_PROTO_C(struct, version_info); SF_PROTO_C(struct, you); SF_PROTO_C(union, any); +#ifdef DEMO_UPLIFTS +SF_PROTO_C(struct, mystruct); +SF_PROTO_C(struct, mystruct_rev0); +#endif SF_PROTO(int16); SF_PROTO(int32); SF_PROTO(int64); @@ -149,6 +153,10 @@ struct sf_procs { SF_ENTRY_C(struct, version_info); SF_ENTRY_C(struct, you); SF_ENTRY_C(union, any); +#ifdef DEMO_UPLIFTS + SF_ENTRY_C(struct, mystruct); + SF_ENTRY_C(struct, mystruct_rev0); +#endif SF_ENTRY(aligntyp); SF_ENTRY(boolean); diff --git a/include/skills.h b/include/skills.h index 307694cfb..7ddb4a5cd 100644 --- a/include/skills.h +++ b/include/skills.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 skills.h $NHDT-Date: 1596498559 2020/08/03 23:49:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 skills.h $NHDT-Date: 1781973087 2026/06/20 16:31:27 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sndprocs.h b/include/sndprocs.h index e27793e45..0a5f879d4 100755 --- a/include/sndprocs.h +++ b/include/sndprocs.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sndprocs.h $NHDT-Date: 1725653015 2024/09/06 20:03:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 sndprocs.h $NHDT-Date: 1781973088 2026/06/20 16:31:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Michael Allison, 2022 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sp_lev.h b/include/sp_lev.h index 52e89978c..3b00335d5 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.h $NHDT-Date: 1622361649 2021/05/30 08:00:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 sp_lev.h $NHDT-Date: 1781973088 2026/06/20 16:31:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.62 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/spell.h b/include/spell.h index 9299282e2..5d42ab733 100644 --- a/include/spell.h +++ b/include/spell.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 spell.h $NHDT-Date: 1646838388 2022/03/09 15:06:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 spell.h $NHDT-Date: 1781973088 2026/06/20 16:31:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright 1986, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/stairs.h b/include/stairs.h index bb37a4dee..8d2371fda 100644 --- a/include/stairs.h +++ b/include/stairs.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 stairs.h $NHDT-Date: 1685863327 2023/06/04 07:22:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 5.0 stairs.h $NHDT-Date: 1781973088 2026/06/20 16:31:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sym.h b/include/sym.h index d965ec2ff..6939a4943 100644 --- a/include/sym.h +++ b/include/sym.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sym.h $NHDT-Date: $ $NHDT-Branch: $ $NHDT-Revision: $ */ +/* NetHack 5.0 sym.h $NHDT-Date: $ $NHDT-Branch: $ $NHDT-Revision: $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sys.h b/include/sys.h index 63f7f5394..da060cad7 100644 --- a/include/sys.h +++ b/include/sys.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sys.h $NHDT-Date: 1693083207 2023/08/26 20:53:27 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 5.0 sys.h $NHDT-Date: 1693083207 2023/08/26 20:53:27 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.41 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -25,6 +25,7 @@ struct sysopt_s { * -1: getenv() didn't find a value for DEBUGFILES. */ int maxplayers; + int maxrerollrate; int seduce; int check_save_uid; /* restoring savefile checks UID? */ int check_plname; /* use plname for checking wizards/explorers/shellers */ diff --git a/include/tcap.h b/include/tcap.h index 896c00e6f..ddab92ec8 100644 --- a/include/tcap.h +++ b/include/tcap.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tcap.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 tcap.h $NHDT-Date: 1781973089 2026/06/20 16:31:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.17 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1989. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -13,7 +13,7 @@ #endif /* might display need graphics code? */ -#if !defined(AMIGA) && !defined(TOS) && !defined(MAC) +#if !defined(AMIGA) && !defined(TOS) && !defined(MAC68K) #if defined(TERMLIB) || defined(OS2) || defined(MSDOS) #define ASCIIGRAPH #endif diff --git a/include/tile2x11.h b/include/tile2x11.h index 2839e8946..d801c5a87 100644 --- a/include/tile2x11.h +++ b/include/tile2x11.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile2x11.h $NHDT-Date: 1597274123 2020/08/12 23:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 tile2x11.h $NHDT-Date: 1781973089 2026/06/20 16:31:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) 2002 by David Cohrs */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tileset.h b/include/tileset.h index d4422203d..f6f394ac8 100644 --- a/include/tileset.h +++ b/include/tileset.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tileset.h $NHDT-Date: 1596498564 2020/08/03 23:49:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ */ +/* NetHack 5.0 tileset.h $NHDT-Date: 1781973089 2026/06/20 16:31:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -9,6 +9,9 @@ struct Pixel { unsigned char r, g, b, a; }; +/* To let the tileset interface split the tiles into separate images, use + * these functions */ + struct TileImage { /* Image data */ unsigned width, height; @@ -22,12 +25,8 @@ void set_tile_type(boolean true_color); void free_tiles(void); const struct TileImage *get_tile(unsigned tile_index); -/* For resizing tiles */ -struct TileImage *stretch_tile(const struct TileImage *, unsigned, - unsigned); -void free_tile(struct TileImage *); +/* To read the tileset as a single image, use these functions */ -/* Used internally by the tile set code */ struct TileSetImage { /* Image data */ unsigned width, height; @@ -42,6 +41,16 @@ struct TileSetImage { unsigned tile_width, tile_height; }; +boolean read_tile_image(struct TileSetImage *image, + const char *filename, boolean true_color); +void free_tile_image(struct TileSetImage *image); + +/* For resizing tiles */ +struct TileImage *stretch_tile(const struct TileImage *, unsigned, + unsigned); +void free_tile(struct TileImage *); + +/* Used internally by the tile set code */ boolean read_bmp_tiles(const char *filename, struct TileSetImage *image); boolean read_gif_tiles(const char *filename, struct TileSetImage *image); boolean read_png_tiles(const char *filename, struct TileSetImage *image); diff --git a/include/timeout.h b/include/timeout.h index 0712c2e93..4fa967488 100644 --- a/include/timeout.h +++ b/include/timeout.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 timeout.h $NHDT-Date: 1705087443 2024/01/12 19:24:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 5.0 timeout.h $NHDT-Date: 1781973089 2026/06/20 16:31:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ */ /* Copyright 1994, Dean Luick */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tradstdc.h b/include/tradstdc.h index 4c304b625..f42eba1a9 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tradstdc.h $NHDT-Date: 1744938651 2025/04/17 17:10:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 5.0 tradstdc.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -157,7 +157,7 @@ typedef const char *vA; [nethack's core doesn't use VA_NEXT() so doesn't use VA_SHIFT() either, and this definition is just retained for completeness. lev_comp does use VA_NEXT(), but it passes all 'argX' arguments. - Note: as of 3.7.0, lev_comp doesn't exist anymore.] + Note: as of 5.0.0, lev_comp doesn't exist anymore.] */ #define VA_SHIFT() \ (arg1 = arg2, arg2 = arg3, arg3 = arg4, arg4 = arg5, arg5 = arg6, \ @@ -317,7 +317,7 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ * Language * Standard * - * NetHack 3.7 range + * NetHack 5.0 range * / * / * C2y X NetHack 3.6 and earlier range @@ -328,7 +328,7 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ * C89 X * * - * The NetHack 3.7 source code currently makes use of the following + * The NetHack 5.0 source code currently makes use of the following * C99 (and above) language features: * * commas at the end of enumerator lists @@ -337,7 +337,7 @@ typedef genericptr genericptr_t; /* (void *) or (char *) */ * variadic macros * 'long long' * - * The NetHack 3.7 source code adheres to the following greater-than C99 + * The NetHack 5.0 source code adheres to the following greater-than C99 * language restrictions: * * Removal of K&R function definitions diff --git a/include/trap.h b/include/trap.h index 206951baa..d8ae807ab 100644 --- a/include/trap.h +++ b/include/trap.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.h $NHDT-Date: 1670316586 2022/12/06 08:49:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 trap.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.38 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/unixconf.h b/include/unixconf.h index 1e346d3d5..ffe5d7a03 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixconf.h $NHDT-Date: 1711213886 2024/03/23 17:11:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ */ +/* NetHack 5.0 unixconf.h $NHDT-Date: 1778686773 2026/05/13 15:39:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.60 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -170,7 +170,7 @@ #ifdef AMS #define AMS_MAILBOX "/Mailbox" #else -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #define DEF_MAILREADER "/usr/bin/mail" #else #define DEF_MAILREADER "/usr/ucb/Mail" @@ -331,8 +331,16 @@ #include #endif +#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) +#define tparm2(s, x) tparm(s,x,0,0,0,0,0,0,0,0) +#else +#define tparm2(s, x) tparm(s,x) +#endif + #if defined(BSD) || defined(ULTRIX) -#if !defined(DGUX) && !defined(SUNOS4) +#if !defined(DGUX) && !defined(SUNOS4) \ + && !defined(__NetBSD__) && !defined(__FreeBSD__) \ + && !defined(__OpenBSD__) #define memcpy(d, s, n) bcopy(s, d, n) #define memcmp(s1, s2, n) bcmp(s2, s1, n) #endif diff --git a/include/vision.h b/include/vision.h index a9be002dc..c519718e1 100644 --- a/include/vision.h +++ b/include/vision.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 vision.h $NHDT-Date: 1666478832 2022/10/22 22:47:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 vision.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/vmsconf.h b/include/vmsconf.h index 57b8a7b05..bafb9ed65 100644 --- a/include/vmsconf.h +++ b/include/vmsconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsconf.h $NHDT-Date: 1596498569 2020/08/03 23:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 vmsconf.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -164,7 +164,7 @@ PANICTRACE_GDB=2 #at conclusion of panic, show a call traceback and then */ /* This used to be force-defined for VMS in topten.c, but with - * the global variable consolidation into g in 3.7, it has to be + * the global variable consolidation into g in 5.0, it has to be * defined here so that decl.h includes the field in g. */ #define UPDATE_RECORD_IN_PLACE diff --git a/include/warnings.h b/include/warnings.h index b35a037ae..96d104c23 100644 --- a/include/warnings.h +++ b/include/warnings.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 warnings.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 warnings.h $NHDT-Date: 1781973090 2026/06/20 16:31:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Michael Allison, 2021. */ #ifndef WARNINGS_H diff --git a/include/weight.h b/include/weight.h index a404eb1af..38a82e149 100644 --- a/include/weight.h +++ b/include/weight.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 weight.h $NHDT-Date: 1742427965 2025/03/19 23:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 weight.h $NHDT-Date: 1781973091 2026/06/20 16:31:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/winX.h b/include/winX.h index 295abaa8d..0133c3d44 100644 --- a/include/winX.h +++ b/include/winX.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winX.h $NHDT-Date: 1740795096 2025/02/28 18:11:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ +/* NetHack 5.0 winX.h $NHDT-Date: 1781973092 2026/06/20 16:31:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.69 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -9,6 +9,13 @@ #ifndef WINX_H #define WINX_H +#ifdef USE_XFT +#include +typedef XftFont X11_Font; +#else +typedef XFontStruct X11_Font; +#endif + #ifndef COLOR_H #include "color.h" /* CLR_MAX */ #endif @@ -80,7 +87,7 @@ struct text_map_info_t { square_ascent, /* placement of changes. */ square_lbearing; -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) XFontStruct *font; #endif }; @@ -127,7 +134,12 @@ struct line_element { }; struct mesg_info_t { +#ifdef USE_XFT + Pixel fgpixel; /* Color for text drawing */ +#else + GC gc; /* GC for text drawing */ XFontStruct *fs; /* Font for the window. */ +#endif int num_lines; /* line count */ struct line_element *head; /* head of circular line queue */ struct line_element *line_here; /* current drawn line position */ @@ -135,7 +147,6 @@ struct mesg_info_t { /* bottom of screen */ struct line_element *last_pause_head; /* pointer to head of previous */ /* turn */ - GC gc; /* GC for text drawing */ int char_width, /* Saved font information so we can */ char_height, /* calculate the correct placement */ char_ascent, /* of changes. */ @@ -153,7 +164,9 @@ struct mesg_info_t { struct status_info_t { struct text_buffer text; /* Just a text buffer. */ Pixel fg, bg; /* foreground and background */ +#ifndef USE_XFT XFontStruct *fs; /* Status window font structure. */ +#endif Dimension spacew; /* width of one space */ Position x, y[3]; /* x coord (not used), y for up to three lines */ Dimension wd, ht; /* width (not used), height (same for all lines) */ @@ -194,7 +207,9 @@ struct menu_info_t { struct menu curr_menu; /* Menu being displayed. */ struct menu new_menu; /* New menu being built. */ +#ifndef USE_XFT XFontStruct *fs; /* Font for the window. */ +#endif long menu_count; /* number entered by user */ Dimension line_height; /* Total height of a line of text. */ Dimension internal_height; /* Internal height between widget & border */ @@ -217,10 +232,6 @@ struct menu_info_t { */ struct text_info_t { struct text_buffer text; - XFontStruct *fs; /* Font for the text window. */ - int max_width; /* Width of widest line so far. */ - int extra_width, /* Sum of left and right border widths. */ - extra_height; /* Sum of top and bottom border widths. */ boolean blocked; /* */ boolean destroy_on_ack; /* Destroy this window when acknowledged. */ #ifdef GRAPHIC_TOMBSTONE @@ -242,8 +253,10 @@ struct xwindow { boolean nh_colors_inited; XColor nh_colors[CLR_MAX]; +#ifndef USE_XFT XFontStruct *boldfs; /* Bold font */ Display *boldfs_dpy; /* Bold font display */ +#endif char *title; union { @@ -287,6 +300,8 @@ struct xwindow { * and dumplog message history */ #define YN_NO_DEFAULT 2U /* don't convert quitchars to 0 or ESC to q/n/def */ +#define DELAY_EVENT_ID 66 /* arbitrary byte value */ + /* Window variables (winX.c). */ extern struct xwindow window_list[MAX_WINDOWS]; extern XtAppContext app_context; /* context of application */ @@ -315,6 +330,16 @@ typedef struct { Pixel pet_mark_color; /* color of pet mark */ String pilemark_bitmap; /* X11 bitmap file used to mark item piles */ Pixel pilemark_color; /* color of item pile mark */ +#ifdef USE_XFT + String font_map; /* font for the map */ + String font_menu; /* font for menus */ + String font_message; /* font for the message window */ + String font_status; /* font for the status window */ + String font_text; /* font for text windows */ +#ifdef GRAPHIC_TOMBSTONE + String font_rip; /* font for tombstone */ +#endif +#endif #ifdef GRAPHIC_TOMBSTONE String tombstone; /* name of XPM file for tombstone */ int tombtext_x; /* x-coord of center of first tombstone text */ @@ -329,6 +354,9 @@ extern void (*input_func)(Widget, XEvent *, String *, Cardinal *); extern struct window_procs X11_procs; +/* Flag maintained by the blink callback */ +extern boolean X11_blink; + /* Check for an invalid window id. */ #define check_winid(window) \ do { \ @@ -338,8 +366,10 @@ extern struct window_procs X11_procs; } while (0) /* ### Window.c ### */ +#ifndef USE_XFT extern Font WindowFont(Widget); extern XFontStruct *WindowFontStruct(Widget); +#endif /* ### dialogs.c ### */ extern Widget CreateDialog(Widget, String, XtCallbackProc, XtCallbackProc); @@ -351,23 +381,16 @@ extern void positionpopup(Widget, boolean); /* ### winX.c ### */ extern struct xwindow *find_widget(Widget); extern XColor get_nhcolor(struct xwindow *, int); -extern void init_menu_nhcolors(struct xwindow *); extern void load_boldfont(struct xwindow *, Widget); -extern Boolean nhApproxColor(Screen *, Colormap, char *, XColor *); -extern Boolean nhCvtStringToPixel(Display *, XrmValuePtr, Cardinal *, - XrmValuePtr, XrmValuePtr, XtPointer *); -extern void get_window_frame_extents(Widget, long *, long *, long *, long *); extern void get_widget_window_geometry(Widget, int *, int *, int *, int *); -extern char *fontname_boldify(const char *); -extern Dimension nhFontHeight(Widget); +extern Dimension nhFontHeight(Widget, int); extern char key_event_to_char(XKeyEvent *); -extern void msgkey(Widget, XtPointer, XEvent *, Boolean *); extern void highlight_yn(boolean); extern void nh_XtPopup(Widget, int, Widget); extern void nh_XtPopdown(Widget); extern void win_X11_init(int); extern void find_scrollbars(Widget, Widget, Widget *, Widget *); -extern void nh_keyscroll(Widget, XEvent *, String *, Cardinal *); +extern Boolean nhApproxColor(Screen *, Colormap, char *, XColor *); /* ### winmesg.c ### */ extern void set_message_slider(struct xwindow *); @@ -397,8 +420,6 @@ extern void create_menu_window(struct xwindow *); extern void destroy_menu_window(struct xwindow *); /* ### winmisc.c ### */ -extern XtPointer i2xtp(int); -extern int xtp2i(XtPointer); extern void ps_key(Widget, XEvent *, String *, Cardinal *); /* player selection action */ extern void race_key(Widget, XEvent *, String *, @@ -419,9 +440,14 @@ extern void release_extended_cmds(void); /* ### winstatus.c ### */ extern void create_status_window(struct xwindow *, boolean, Widget); extern void destroy_status_window(struct xwindow *); +#ifndef STATUS_HILITES extern void adjust_status(struct xwindow *, const char *); +#endif extern void null_out_status(void); extern void check_turn_events(void); +#ifdef STATUS_HILITES +extern void X11_tty_status_blink(void); +#endif /* ### wintext.c ### */ extern void delete_text(Widget, XEvent *, String *, Cardinal *); @@ -439,7 +465,6 @@ extern void append_text_buffer(struct text_buffer *, const char *, boolean); /* text buffer routines */ extern void init_text_buffer(struct text_buffer *); extern void clear_text_buffer(struct text_buffer *); -extern void free_text_buffer(struct text_buffer *); #ifdef GRAPHIC_TOMBSTONE extern void calculate_rip_text(int, time_t); #endif @@ -452,64 +477,96 @@ extern int get_name_width(Widget); extern Widget get_value_widget(Widget); extern void set_value_width(Widget, int); extern int get_value_width(Widget); -extern void hilight_value(Widget); extern void swap_fg_bg(Widget); extern void set_value(Widget w, const char *new_value); /* external declarations */ -extern char *X11_getmsghistory(boolean); -extern void X11_putmsghistory(const char *, boolean); -extern void X11_init_nhwindows(int *, char **); extern void X11_player_selection(void); -extern void X11_askname(void); -extern void X11_get_nh_event(void); extern void X11_exit_nhwindows(const char *); -extern void X11_suspend_nhwindows(const char *); -extern void X11_resume_nhwindows(void); extern winid X11_create_nhwindow(int); -extern void X11_clear_nhwindow(winid); -extern void X11_display_nhwindow(winid, boolean); extern void X11_destroy_nhwindow(winid); -extern void X11_curs(winid, int, int); -extern void X11_putstr(winid, int, const char *); -extern void X11_display_file(const char *, boolean); extern void X11_start_menu(winid, unsigned long); extern void X11_add_menu(winid, const glyph_info *, const ANY_P *, char, char, int, int, const char *, unsigned int); extern void X11_end_menu(winid, const char *); extern int X11_select_menu(winid, int, MENU_ITEM_P **); -extern void X11_mark_synch(void); -extern void X11_wait_synch(void); #ifdef CLIPPING extern void X11_cliparound(int, int); #endif extern void X11_print_glyph(winid, coordxy, coordxy, const glyph_info *, const glyph_info *); extern void X11_raw_print(const char *); -extern void X11_raw_print_bold(const char *); -extern int X11_nhgetch(void); -extern int X11_nh_poskey(coordxy *, coordxy *, int *); extern void X11_nhbell(void); -extern int X11_doprev_message(void); extern char X11_yn_function_core(const char *, const char *, char, unsigned); -extern char X11_yn_function(const char *, const char *, char); extern void X11_getlin(const char *, char *); extern int X11_get_ext_cmd(void); -extern void X11_number_pad(int); -extern void X11_delay_output(void); extern void X11_status_init(void); extern void X11_status_finish(void); extern void X11_status_enablefield(int, const char *, const char *, boolean); extern void X11_status_update(int, genericptr_t, int, int, int, unsigned long *); -#ifdef GRAPHIC_TOMBSTONE -extern void X11_outrip(winid, int, time_t); -#else +#ifndef GRAPHIC_TOMBSTONE extern void genl_outrip(winid, int, time_t); #endif -extern void X11_preference_update(const char *); extern void X11_update_inventory(int); -extern win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *); +extern X11_map_symbol X11_glyph_char(const glyph_info *); +#ifndef USE_XFT +extern XFontStruct *X11_bold_font(Display *, XFontStruct *); +extern XFontStruct *X11_italic_font(Display *, XFontStruct *); +#endif /* !USE_XFT */ +#ifdef ENHANCED_SYMBOLS +extern XFontStruct *X11_unicode_font(Display *, XFontStruct *); +#endif + +#ifdef USE_XFT +extern XftFont *X11_new_font(Widget w, unsigned attrs, int win_type); +extern void X11_release_font(Widget w, XftFont *font); +extern void X11_new_color(Widget w, Pixel pixel, XftColor *color); +#endif + +/* ### winlabel.c ### */ +/* Functions for management of enhanced labels */ +extern void X11_wrap_widget(Widget, int); +extern void X11_update_label(Widget); +extern void X11_set_attrs(Widget, unsigned); +extern void X11_set_highlight(Widget, boolean); +extern void X11_set_percent(Widget, unsigned, Pixel); +extern void X11_set_column_widths(Widget, const int *, unsigned); +extern void X11_blink_labels(void); +extern int X11_font_height(X11_Font *); +extern int X11_column_width(Display *, X11_Font *, const char *, size_t); + +/* + * These are for widgets that use the enhanced label services only for text + * rendering; not for percentage bars, underlines and such. They only need + * these services if XFT is in use. + */ +#ifdef USE_XFT +static inline void +X11_wrap_widget_if_Xft(Widget w, int win_type) +{ + X11_wrap_widget(w, win_type); +} + +static inline void +X11_update_label_if_Xft(Widget w) +{ + X11_update_label(w); +} +#else /* !USE_XFT */ +static inline void +X11_wrap_widget_if_Xft(Widget w, int win_type) +{ + nhUse(w); + nhUse(win_type); +} + +static inline void +X11_update_label_if_Xft(Widget w) +{ + nhUse(w); +} +#endif /* ?USE_XFT */ #endif /* WINX_H */ diff --git a/include/winami.h b/include/winami.h index 1cfd85078..16732101b 100644 --- a/include/winami.h +++ b/include/winami.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winami.h $NHDT-Date: 1596498569 2020/08/03 23:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 winami.h $NHDT-Date: 1781973091 2026/06/20 16:31:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991. */ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1992, 1993. */ /* NetHack may be freely redistributed. See license for details. */ @@ -32,6 +32,7 @@ struct amii_menu { const char *query; /* Query string */ int count; /* Number of strings. */ char chr; /* Character to assign for accelerator */ + boolean has_glyphs; /* Any item carries a real glyph (AMIV) */ }; /* descriptor for Amiga Intuition-based windows. If we decide to cope with @@ -58,16 +59,8 @@ struct amii_WinDesc { char *morestr; /* string to display instead of default */ /* amiga stuff */ struct Window *win; /* Intuition window pointer */ -#ifdef INTUI_NEW_LOOK - struct ExtNewWindow *newwin; /* NewWindow alloc'd */ -#else - struct NewWindow *newwin; /* ExtNewWindow alloc'd */ -#endif -#ifdef INTUI_NEW_LOOK + struct ExtNewWindow *newwin; /* NewWindow alloc'd */ struct TagItem wintags[MAXWINTAGS]; /* Tag items for this window */ -#else - long wintags[MAXWINTAGS * 2]; -#endif void *hook; /* Hook structure pointer for tiles version */ #define FLMAP_INGLYPH 1 /* An NHW_MAP window is in glyph mode */ #define FLMAP_CURSUP 2 /* An NHW_MAP window has the cursor displayed */ @@ -116,8 +109,8 @@ typedef struct WEVENT { /* port specific variable declarations */ extern winid WIN_BASE; extern winid WIN_OVER; -#define NHW_BASE 6 -#define NHW_OVER 7 /* overview window */ +#define NHW_BASE (NHW_LAST_TYPE + 1) +#define NHW_OVER (NHW_LAST_TYPE + 2) /* overview window */ extern struct amii_WinDesc *amii_wins[MAXWIN + 1]; diff --git a/include/wincurs.h b/include/wincurs.h index ad1a333fa..43780e276 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 wincurs.h */ +/* NetHack 5.0 wincurs.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ @@ -128,14 +128,6 @@ extern void curses_refresh_nethack_windows(void); extern void curses_del_nhwin(winid wid); extern void curses_del_wid(winid wid); extern void curs_destroy_all_wins(void); -#ifdef ENHANCED_SYMBOLS -extern void curses_putch(winid wid, int x, int y, int ch, - struct unicode_representation *u, int color, - int framecolor, int attrs); -#else -extern void curses_putch(winid wid, int x, int y, int ch, int color, - int framecolor, int attrs); -#endif extern void curses_get_window_size(winid wid, int *height, int *width); extern boolean curses_window_has_border(winid wid); extern boolean curses_window_exists(winid wid); @@ -145,7 +137,6 @@ extern void curses_puts(winid wid, int attr, const char *text); extern void curses_clear_nhwin(winid wid); extern void curses_alert_win_border(winid wid, boolean onoff); extern void curses_alert_main_borders(boolean onoff); -extern int get_framecolor(int nhcolor, int framecolor); extern void curses_draw_map(int sx, int sy, int ex, int ey); extern boolean curses_map_borders(int *sx, int *sy, int *ex, int *ey, int ux, int uy); diff --git a/include/windconf.h b/include/windconf.h index 81ad8baeb..415bb31ef 100644 --- a/include/windconf.h +++ b/include/windconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 windconf.h $NHDT-Date: 1596498552 2020/08/03 23:49:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 5.0 windconf.h $NHDT-Date: 1781973091 2026/06/20 16:31:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.133 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994. */ /* NetHack may be freely redistributed. See license for details. */ @@ -35,6 +35,12 @@ #define EARLY_CONFIGFILE_PASS #define TTY_PERM_INVENT +#ifdef WIN32CON +#define IDLECHECKPOINT +#endif + +#define TIMED_DELAY + /* * ----------------------------------------------------------------- * The remaining code shouldn't need modification. @@ -157,7 +163,7 @@ typedef SSIZE_T ssize_t; #endif /* _MSC_VER */ /* The following is needed for prototypes of certain functions */ -#if defined(_MSC_VER) +#if defined(_MSC_VER) || defined(__GNUC__) #include /* Provides prototypes of exit(), spawn() */ #endif diff --git a/include/winprocs.h b/include/winprocs.h index a60a00c77..5ae1d2606 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winprocs.h $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ +/* NetHack 5.0 winprocs.h $NHDT-Date: 1781973091 2026/06/20 16:31:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.95 $ */ /* Copyright (c) David Cohrs, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -76,7 +76,7 @@ struct window_procs { void (*win_delay_output)(void); #ifdef CHANGE_COLOR void (*win_change_color)(int, long, int); -#ifdef MAC +#ifdef MAC68K void (*win_change_background)(int); short (*win_set_font_name)(winid, char *); #endif @@ -127,7 +127,7 @@ extern #define display_file (*windowprocs.win_display_file) #define start_menu (*windowprocs.win_start_menu) #define end_menu (*windowprocs.win_end_menu) -/* 3.7: There are real add_menu() and select_menu in the core now. +/* 5.0: There are real add_menu() and select_menu in the core now. * add_menu does some common activities, such as menu_colors. * select_menu does some before and after activities. * add_menu() and select_menu() are in windows.c @@ -151,7 +151,7 @@ extern #define nh_poskey (*windowprocs.win_nh_poskey) #define nhbell (*windowprocs.win_nhbell) #define nh_doprev_message (*windowprocs.win_doprev_message) -/* 3.7: There is a real getlin() in the core now, which does +/* 5.0: There is a real getlin() in the core now, which does * some before and after activities. * [alternative fix for menu search via ':'.] * getlin() is in windows.c @@ -162,7 +162,7 @@ extern #define nh_delay_output (*windowprocs.win_delay_output) #ifdef CHANGE_COLOR #define change_color (*windowprocs.win_change_color) -#ifdef MAC +#ifdef MAC68K #define change_background (*windowprocs.win_change_background) #define set_font_name (*windowprocs.win_set_font_name) #endif @@ -297,7 +297,7 @@ struct wc_Opt { /* Macro for the currently active Window Port whose function pointers have been loaded */ #if 0 -/* 3.7 The string comparison version isn't used anymore */ +/* 5.0 The string comparison version isn't used anymore */ #define WINDOWPORT(wn) \ (windowprocs.name && !strncmpi((#wn), windowprocs.name, strlen((#wn)))) #endif @@ -394,7 +394,7 @@ struct chain_procs { void (*win_delay_output)(CARGS); #ifdef CHANGE_COLOR void (*win_change_color)(CARGS, int, long, int); -#ifdef MAC +#ifdef MAC68K void (*win_change_background)(CARGS, int); short (*win_set_font_name)(CARGS, winid, char *); #endif diff --git a/include/wintty.h b/include/wintty.h index c0c5d842e..54861e82b 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintty.h $NHDT-Date: 1656014599 2022/06/23 20:03:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.55 $ */ +/* NetHack 5.0 wintty.h $NHDT-Date: 1781973092 2026/06/20 16:31:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.84 $ */ /* Copyright (c) David Cohrs, 1991,1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -280,7 +280,7 @@ extern void tty_number_pad(int); extern void tty_delay_output(void); #ifdef CHANGE_COLOR extern void tty_change_color(int color, long rgb, int reverse); -#ifdef MAC +#ifdef MAC68K extern void tty_change_background(int white_or_black); extern short set_tty_font_name(winid, char *); #endif @@ -331,7 +331,7 @@ extern char *tgetstr(const char *, char **); extern char *tgoto(const char *, int, int); #endif /* NO_TERMCAP_HEADERS */ #else /* ?NO_TERMS */ -#ifdef MAC +#ifdef MAC68K #ifdef putchar #undef putchar #undef putc @@ -342,7 +342,7 @@ extern char *tgoto(const char *, int, int); extern int term_putc(int c); extern int term_flush(void *desc); extern int term_puts(const char *str); -#endif /* MAC */ +#endif /* MAC68K */ #if defined(MSDOS) || defined(WIN32) #if defined(SCREEN_BIOS) || defined(SCREEN_DJGPPFAST) || defined(WIN32) #undef putchar diff --git a/include/wintype.h b/include/wintype.h index 6b94bef64..4df54c16f 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintype.h $NHDT-Date: 1717880364 2024/06/08 20:59:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ */ +/* NetHack 5.0 wintype.h $NHDT-Date: 1781973092 2026/06/20 16:31:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.60 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -58,6 +58,7 @@ enum any_types { ANY_STR, /* pointer to null-terminated char string */ ANY_NFUNC, /* pointer to function taking no args, returning int */ ANY_MASK32, /* 32-bit mask (stored as unsigned long) */ + ANY_INT16, /* xint16 / coordxy (16-bit signed) */ ANY_INVALID /* leave this last */ }; @@ -167,7 +168,7 @@ typedef struct glyphinfo { #define MENU_ITEMFLAGS_SKIPINVERT 0x0000002U #define MENU_ITEMFLAGS_SKIPMENUCOLORS 0x0000004U -/* 3.7+ enhanced menu flags that not all window ports are likely to +/* 5.0+ enhanced menu flags that not all window ports are likely to * support initially. * * As behavior and appearance modification flags are added, the various diff --git a/include/xwindow.h b/include/xwindow.h index c388fb54b..7f363393e 100644 --- a/include/xwindow.h +++ b/include/xwindow.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 xwindow.h $NHDT-Date: 1596498574 2020/08/03 23:49:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 xwindow.h $NHDT-Date: 1781973092 2026/06/20 16:31:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/xwindowp.h b/include/xwindowp.h index 8aa0fb37f..ca6038ffe 100644 --- a/include/xwindowp.h +++ b/include/xwindowp.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 xwindowp.h $NHDT-Date: 1596498575 2020/08/03 23:49:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 xwindowp.h $NHDT-Date: 1781973093 2026/06/20 16:31:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/you.h b/include/you.h index a073e5c57..33e2f840f 100644 --- a/include/you.h +++ b/include/you.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 you.h $NHDT-Date: 1702349061 2023/12/12 02:44:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ +/* NetHack 5.0 you.h $NHDT-Date: 1781973093 2026/06/20 16:31:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.89 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -160,6 +160,10 @@ struct u_conduct { /* number of times... */ long sokocheat; /* violated special 'rules' in Sokoban */ long pets; /* obtained a pet */ /* genocides already listed at end of game */ + long reserved1; + long reserved2; + long reserved3; + long reserved4; }; struct u_roleplay { @@ -168,6 +172,9 @@ struct u_roleplay { boolean deaf; /* permanently deaf */ boolean pauper; /* no starting inventory */ boolean reroll; /* starting inventory/attr rerolling enabled */ + boolean reserved1; + boolean reserved2; + boolean reserved3; long numbones; /* # of bones files loaded */ long numrerolls; /* # of rerolls used */ }; @@ -428,7 +435,6 @@ struct you { Bitfield(uinvulnerable, 1); /* you're invulnerable (praying) */ Bitfield(uburied, 1); /* you're buried */ Bitfield(uedibility, 1); /* blessed food detect; sense unsafe food */ - Bitfield(usaving_grace, 1); /* prevents death once */ Bitfield(uhandedness, 1); /* There is no advantage for either handedness. The distinction is only for flavor variation and for use in messages. */ @@ -498,6 +504,7 @@ struct you { short mcham; /* vampire mndx if shapeshifted to bat/cloud */ short umovement; /* instead of youmonst.movement */ schar uachieved[N_ACH]; /* list of achievements in the order attained */ + struct monst *umonst; /* for future conversion of &gy.youmonst to u.umonst */ }; /* end of `struct you' */ diff --git a/include/youprop.h b/include/youprop.h index f2c166606..468dd684b 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 youprop.h $NHDT-Date: 1725653018 2024/09/06 20:03:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ +/* NetHack 5.0 youprop.h $NHDT-Date: 1781973093 2026/06/20 16:31:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/.travis.yml b/outdated/.travis.yml index b0f0dfc3b..81e377790 100644 --- a/outdated/.travis.yml +++ b/outdated/.travis.yml @@ -179,5 +179,5 @@ deploy: on: tags: true prerelease: true - name: "Pre-Release build of NetHack 3.7.0" - body: "This is an auto generated Pre-Release build of NetHack 3.7.0" + name: "Pre-Release build of NetHack 3.6.0" + body: "This is an auto generated Pre-Release build of NetHack 3.6.0" diff --git a/outdated/dat/symbols b/outdated/dat/symbols index 6f6824a9c..77d2238fc 100644 --- a/outdated/dat/symbols +++ b/outdated/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.7 symbols $NHDT-Date: 1596498253 2020/08/03 23:44:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ +# NetHack 3.6 symbols $NHDT-Date: 1596498253 2020/08/03 23:44:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/include/mac-carbon.h b/outdated/include/mac-carbon.h index b773c732f..fb270054f 100644 --- a/outdated/include/mac-carbon.h +++ b/outdated/include/mac-carbon.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mac-carbon.h $NHDT-Date: 1596498540 2020/08/03 23:49:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 mac-carbon.h $NHDT-Date: 1596498540 2020/08/03 23:49:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ @@ -21,6 +21,7 @@ * set "Prefix File" to include/mac-carbon.h */ +#define MAC68K #define MAC #undef UNIX diff --git a/outdated/include/mac-qt.h b/outdated/include/mac-qt.h index 429106c92..b284142d3 100644 --- a/outdated/include/mac-qt.h +++ b/outdated/include/mac-qt.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mac-qt.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 mac-qt.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ @@ -22,6 +22,7 @@ */ #undef MAC +#undef MAC68K #define UNIX #define BSD diff --git a/outdated/include/mac-term.h b/outdated/include/mac-term.h index 8bef72d0b..50c0e2301 100644 --- a/outdated/include/mac-term.h +++ b/outdated/include/mac-term.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mac-term.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 mac-term.h $NHDT-Date: 1596498541 2020/08/03 23:49:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 2003. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ @@ -23,6 +23,7 @@ /* Stuff needed for the core of NetHack */ #undef MAC +#undef MAC68K #define UNIX #define BSD #define __FreeBSD__ /* Darwin is based on FreeBSD */ diff --git a/outdated/include/macconf.h b/outdated/include/macconf.h index fdde526c3..596609d16 100644 --- a/outdated/include/macconf.h +++ b/outdated/include/macconf.h @@ -3,7 +3,7 @@ /*-Copyright (c) Kevin Hugo, 2004. */ /* NetHack may be freely redistributed. See license for details. */ -#ifdef MAC +#ifdef MAC68K #ifndef MACCONF_H #define MACCONF_H @@ -16,7 +16,7 @@ * __MWERKS__ Metrowerks' Codewarrior compiler * * We use these early in config.h to define some needed symbols, - * including MAC. + * including MAC68K. # # The Metrowerks compiler defines __STDC__ (which sets NHSTC) and uses # WIDENED_PROTOTYPES (defined if UNWIDENED_PROTOTYPES is undefined and @@ -123,4 +123,4 @@ extern void error(const char *, ...); #define MAC_GRAPHICS_ENV #endif /* ! MACCONF_H */ -#endif /* MAC */ +#endif /* MAC68K */ diff --git a/outdated/include/macpopup.h b/outdated/include/macpopup.h index 873af3cc6..79c67d73a 100644 --- a/outdated/include/macpopup.h +++ b/outdated/include/macpopup.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 macpopup.h $NHDT-Date: 1596498542 2020/08/03 23:49:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.6 macpopup.h $NHDT-Date: 1596498542 2020/08/03 23:49:02 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Nethack Development Team, 1999. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mactty.h b/outdated/include/mactty.h index 7f84747bc..a620b5b9e 100644 --- a/outdated/include/mactty.h +++ b/outdated/include/mactty.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mactty.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.6 mactty.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Jon W{tte 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/macwin.h b/outdated/include/macwin.h index 1e017ae2b..ef89fceb2 100644 --- a/outdated/include/macwin.h +++ b/outdated/include/macwin.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 macwin.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.6 macwin.h $NHDT-Date: 1596498543 2020/08/03 23:49:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kevin Hugo, 2003. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/mttypriv.h b/outdated/include/mttypriv.h index 5fc90abc4..a1b4e0f62 100644 --- a/outdated/include/mttypriv.h +++ b/outdated/include/mttypriv.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mttypriv.h $NHDT-Date: 1596498551 2020/08/03 23:49:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 mttypriv.h $NHDT-Date: 1596498551 2020/08/03 23:49:11 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Jon W{tte 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/system.h b/outdated/include/system.h index 2616b07f6..a3571ad44 100644 --- a/outdated/include/system.h +++ b/outdated/include/system.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 system.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 3.6 system.h $NHDT-Date: 1596498562 2020/08/03 23:49:22 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -21,7 +21,7 @@ /* some old may not define off_t and size_t; if your system is * one of these, define them by hand below */ -#if (defined(VMS) && !defined(__GNUC__)) || defined(MAC) +#if (defined(VMS) && !defined(__GNUC__)) || defined(MAC68K) #include #else #ifndef AMIGA @@ -41,7 +41,7 @@ typedef unsigned int size_t; #endif #endif /* MICRO && !TOS */ -#if defined(__TURBOC__) || defined(MAC) +#if defined(__TURBOC__) || defined(MAC68K) #include /* time_t is not in */ #endif #if defined(ULTRIX) && !(defined(ULTRIX_PROTO) || defined(NHSTDC)) @@ -200,7 +200,7 @@ extern int unlink(const char *); #endif /* AZTEC_50 && __GNUC__ */ -#ifdef MAC +#ifdef MAC68K #ifndef __CONDITIONALMACROS__ /* universal headers */ extern int close(int); /* unistd.h */ extern int read(int, char *, int); /* unistd.h */ @@ -313,7 +313,7 @@ extern long fork(void); /* The POSIX string.h is required to define all the mem* and str* functions */ #include #else -#if defined(SYSV) || defined(VMS) || defined(MAC) || defined(SUNOS4) +#if defined(SYSV) || defined(VMS) || defined(MAC68K) || defined(SUNOS4) #if defined(NHSTDC) || (defined(VMS) && !defined(ANCIENT_VAXC)) #if !defined(_AIX32) && !(defined(SUNOS4) && defined(__STDC__)) /* Solaris unbundled cc (acc) */ @@ -423,7 +423,7 @@ extern char *strncat(char *, const char *, size_t); extern char *strpbrk(const char *, const char *); #ifdef NOT_C99 -#if defined(SYSV) || defined(MICRO) || defined(MAC) || defined(VMS) \ +#if defined(SYSV) || defined(MICRO) || defined(MAC68K) || defined(VMS) \ || defined(HPUX) extern char *strchr(const char *, int); extern char *strrchr(const char *, int); @@ -435,7 +435,7 @@ extern char *rindex(const char *, int); extern int strcmp(const char *, const char *); extern int strncmp(const char *, const char *, size_t); -#if defined(MICRO) || defined(MAC) || defined(VMS) +#if defined(MICRO) || defined(MAC68K) || defined(VMS) extern size_t strlen(const char *); #else #ifdef HPUX diff --git a/outdated/include/tosconf.h b/outdated/include/tosconf.h index 1ea893f4d..90ffb4fcb 100644 --- a/outdated/include/tosconf.h +++ b/outdated/include/tosconf.h @@ -42,6 +42,7 @@ #ifdef MINT #define SUSPEND /* allow suspending the game */ #endif +#define SFSTRUCT_BUFFERING /* buffered stdio writes for structlevel files */ #ifndef TERMLIB #define ANSI_DEFAULT /* use vt52 by default */ diff --git a/outdated/include/trampoli.h b/outdated/include/trampoli.h index f45d3bb98..7fa42779d 100644 --- a/outdated/include/trampoli.h +++ b/outdated/include/trampoli.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 trampoli.h $NHDT-Date: 1596498566 2020/08/03 23:49:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 3.6 trampoli.h $NHDT-Date: 1596498566 2020/08/03 23:49:26 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) 1989, by Norm Meluch and Stephen Spackman */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/winGnome.h b/outdated/include/winGnome.h index 93bbbeb13..4714c17d2 100644 --- a/outdated/include/winGnome.h +++ b/outdated/include/winGnome.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winGnome.h $NHDT-Date: 1596498571 2020/08/03 23:49:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 winGnome.h $NHDT-Date: 1596498571 2020/08/03 23:49:31 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.9 $ */ /* Copyright (C) 1998 by Erik Andersen */ /* Copyright (C) 1998 by Anthony Taylor */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/include/wingem.h b/outdated/include/wingem.h index 4c1378c0e..017f718f5 100644 --- a/outdated/include/wingem.h +++ b/outdated/include/wingem.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 wingem.h $NHDT-Date: 1596498570 2020/08/03 23:49:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.6 wingem.h $NHDT-Date: 1596498570 2020/08/03 23:49:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Christian Bressler, 1999 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/outdated/sys/amiga/.gitattributes b/outdated/sys/amiga/.gitattributes deleted file mode 100644 index cc4b3cd52..000000000 --- a/outdated/sys/amiga/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.p NHSUBST -* NH_filestag=(file%s_for_Amiga_versions_-_untested_for_3.7) diff --git a/outdated/sys/amiga/Build.ami b/outdated/sys/amiga/Build.ami deleted file mode 100644 index 2b435d827..000000000 --- a/outdated/sys/amiga/Build.ami +++ /dev/null @@ -1,140 +0,0 @@ - - Compiling Amiga NetHack 3.4 - Last Revision: 21 February 2002 for NetHack 3.4.1 - - - We would like to thank each and every one of the people who took - the time and effort to report bugs to us. THANK YOU! (And keep - up the good work!) - -I. Introduction - - The Amiga-specific documentation has been split since the 3.1.3 release - - please read the file Install.ami for information specific to the - Amiga port before continuing. - - If you have problems with compilation, installation, or think you have - found a bug in the game, please report it by electronic mail to the - development group at nethack-bugs@nethack.org, where it will be routed - to the appropriate person. Include your configuration, the version of - NetHack you are playing (use the 'v' command or see - include/patchlevel.h), and as much specific information as possible. - As NetHack runs on many different machines, be sure to mention that you - are playing the Amiga version and also mention if you are using the - version for mc68k or ppc. - - If you want to find out about distributing NetHack, read the license - (in NetHack:license or type ?i during the game). - -II. Compiling Amiga NetHack 3.4 - -II.A. Compilation Overview - Compiling NetHack is not very hard - basically you do a little - configuration and start make. It does, however, require a good amount - of disk space and time. It also needs a good bit of memory, especially - for linking. - -II.B. Basic Compilation - - NetHack can be built with SAS/C version 6.5x. The commercial version - of DICE might work, but NetHack version 3.2.2 or later haven't been - compiled with it. The "official" compiler for NetHack 3.6 is SAS/C 6.58 - - we have dropped support for SAS/C 5.x. - - The Manx/Aztec port has not been tested recently and is certainly - broken. Anyone managing to compile NetHack with this compiler is - encouraged to submit context diffs of the required changes. When last - tested, NetHack required version 5.0B of that compiler. - - Compiling with gcc should also work. - -II.B.1. Introduction to Compiling NetHack - Before doing any compilation, read the README files distributed with - the source. These should familiarize you with the source tree layout - and what files are shared with what computers; everything in the - sys/amiga directory is used exclusively by the Amiga. - - The makefile (sys/amiga/Makefile.ami) depends on certain assignments, - providing the developer with a fairly flexible environment. See - sys/amiga/Makefile.ami for assignment assumptions. DICE users should - see section II.B.3 for information on creating a DMakefile usable with - DMake. - - Edit config.h to your liking and system configuration. The defaults - should be satisfactory for most systems. - - Read VERY CAREFULLY through the Makefile to familiarize yourself - with which assignments are assumed. Otherwise, you're going to get - something like "Insert NH: in any drive." You will need uudecode, - and, if you need to modify dgn_comp or lev_comp, flex, and bison. - The first thing Makefile.ami does is build makedefs, which handles - a variety of data file generation, and then lev_comp and dgn_comp - which compile the special levels. Makedefs will then be run to create - a few files, followed by a roughly alphabetically sorted compilation - of the entire source tree. This process will compile selected files - from the sys/amiga, sys/share, win/tty, and src directories, eventually - creating sbin/nethack. After building the main binary, a make install - will build the auxiliary files including help files, special levels, - icons, and the font files and will put these files into their final - positions - most will be in dlb archives (if DLB was defined in config.h). - The first make run should be done in NH:obj and the make install should be - done in NetHack:; for both runs, the makefile is NH:sys/amiga/Makefile.ami - (or NH:sys/amiga/DMakefile for DMake and NH:sys/amiga/Makefile.agc for - gcc). - - Note that not all the source is simple C code. If you are modifying - lev_comp or dgn_comp you may need bison and/or flex (depending on what - modifications you are making). You do not need any of these tools to - simply build NetHack - all the C output files are provided in the source - distribution. Also, the ifchange script requires a version of diff that - produces standard Unix format context diffs for proper operation - the - version shipped with SAS/C is not sufficient. - - If you do not have bison and flex, copy the files from sys/share. The - include files go in include/ and the C files go in util/. If the compile - fails due to prototype errors for malloc and realloc, try deleting - the first line of lev_comp.c and dgn_comp.c. - -II.B.2. Compiling NetHack with SAS/C version 6.58 - - NOTE WELL - Amiga NetHack has dropped support for SAS/C version 5. - This version of NetHack was developed with SAS/C 6.58. Earlier versions - than version of the compiler are known to cause problems - don't use them. - - A couple of notes and warnings from the SAS/C users on the team: - - * Included in the SAS/C port is code for generating a SnapShot.tb - file upon catching various internal disasters. That is why the - debug=l flag is in the makefile. This adds about 270K to the disk - image, but it does not increase the run time memory requirements. - - * The 5.10b optimizer did not produce correct code for NetHack. The - current optimizer has not been tested. - -II.B.3. Compiling NetHack with the commercial version of DICE - - IMPORTANT NOTE: If you are using DMake, you need to create DMakefile - from Makefile.ami. Do the following: - - cd NH:sys/amiga - edit from Makefile.ami to DMakefile with mkdmake opt w255 - - Some versions of DMake have been known to crash horribly on the - makefile - if this happens, you'll need to download another make - utility, such as AMake (ftp://ftp.dragonfire.net/amiga/utils/amake), - which will run in DMake-compatibility mode if invoked with the -C switch - (e.g. "amake -C -f NH:sys/amiga/DMakefile", or just - "alias dmake amake -C"). - - SECOND IMPORTANT NOTE: The score list is currently disabled when - compiling under DICE, due to an as-yet-unknown problem which causes - system crashes when displaying the score list. - - NetHack can be compiled using the commercial version of DICE only. The - registered shareware version had a bug in it which resulted in odd- - aligned procedures. (It is possible to patch DC1 to fix this problem; - however, this is not recommended, and you should upgrade to the - commercial version.) - - During compilation, DICE will output a lot of warnings; they can be - safely ignored. diff --git a/outdated/sys/amiga/Install.ami b/outdated/sys/amiga/Install.ami deleted file mode 100644 index 58ad2409b..000000000 --- a/outdated/sys/amiga/Install.ami +++ /dev/null @@ -1,200 +0,0 @@ - - Using and Installing Amiga NetHack 3.4 - (or Everything You Never Wanted to Know Before NetHacking) - (or Not Everything That Happens Always Comes Knocking) - - Last Revision: 28 March 2000 for NetHack 3.4.1 - - -0. Pre-intro for NetHack 3.4.1: - Amiga-specific changes for 3.4.1: - Most (around 99%) known bugs fixed (volunteers welcome). - HackWB and HackCli are no longer supported. Use the main binary. - - We would like to thank each and every one of the people who took - the time and effort to report bugs to us. THANK YOU! - -I. Introduction - -I.A. Overview - Welcome to Amiga NetHack! If this is your first visit to our fair - city, you are in for an amazing but dangerous journey; if you have - visited us before, beware! the city has changed in many strange and - subtle ways; it has also grown quite a bit. This missive brings to - light those mundane tasks which must be dealt with before beginning - your journey; for those of you who are faced with the task of - installing the pre-fabricated version of our town, section III - (Installing Amiga NetHack 3.6) will guide you through the task at - hand. If you are ready to visit, the local visitors guide is in - section II (Using Amiga NetHack 3.6); please also see the general - guide packaged separately (the file "GuideBook"). - - To all our visitors, a hearty Welcome! - and please be careful. - - [Those responsible for the previous paragraphs have been sacked. The - documentation has been completed at great expense in a more traditional - style. -- The Management] - -I.B. Getting Help - If you have questions about strategy, weapons, or monsters, the best - place to go for help is the Usenet newsgroup rec.games.roguelike.nethack. - - If you have problems with installation or think you have found a bug - in the game, please report it by electronic mail to the development - team at nethack-bugs@nethack.org, where it will be routed to the - appropriate person. Include your configuration, the version of - NetHack you are playing (use the 'v' command), whether or not you are - using an official binary release (and if so which one) and as much - specific information as possible. As NetHack runs on many different - machines, be sure to mention that you are playing the Amiga version. - -I.C. Credits - Olaf Seibert first ported NetHack 2.3 and 3.0 to the Amiga. Richard - Addison, Andrew Church, Jochen Erwied, Mark Gooderum, Ken Lorber, - Greg Olson, Mike Passaretti, and Gregg Wonderly polished and extended - the 3.0 and 3.1 ports. Andrew Church, Ken Lorber, and Gregg Wonderly - are responsible for the 3.2 port. Janne Salmijärvi resurrected the - amigaport for 3.3 and Teemu Suikki joined before 3.4.0. - -II. Using Amiga NetHack 3.4 - Run NetHack from the shell or from some tool that allows that, - ie. ToolManager. See the NetHack.txt file for command line options - and other usage. - -II.A. Sources of Information - Where to go depends on what you want to find out. If you want to find - out about distributing NetHack, read the license (in NetHack:license - or type ?i during the game). For an introduction to NetHack, read - the GuideBook file. To find out what options are compiled into your - copy of NetHack, type #v during the game. Finally, for information - during the game on all kinds of things, type ? and select from the - menu or by pressing Help key. - -II.B. The Amiga NetHack WorkBench Front End - Starting from 3.3.0 HackWB is not supported. - -II.C. The Amiga NetHack CLI Front End - Starting from 3.3.0 CLI Front end is not supported either. - - Instead, use the main binary. See NetHack.txt file for the standard Unix - flags for NetHack. In addition to those flags, Amiga NetHack accepts - the flags -l to force non-interlaced mode and -L to force interlaced mode. - -II.D. Amiga-Specific Information for NetHack - - There are several options that are unique to the Amiga version of - NetHack that may be specified in the NetHack.cnf file or on an - OPTIONS line: - - altmeta allows the ALT keys to function as META keys. The default - is altmeta. - flush flush discards all characters in the queue except the first, - which limits typeahead accidents. The default is !flush. - silent turn off the audio output. The default is silent. - - The current version of Amiga NetHack also supports menu accelerators. - See Guidebook.txt for a detailed description. Also supported is - selecting the number of stacked objects to drop, used with the (D)rop - command. Type the number and then select an item (or items with - accelerators). Items with a count associated with them are denoted - with # in place of -. I.e. 'd - 3 blessed daggers' becomes - 'd # 3 blessed daggers'. You can clear the count by hitting esc - while counting or deselect and reselect the item. The default - is to drop all selected items (as before). - - For other options how to configure the screen setting and colors refer - to Nethack.cnf. - -III. Installing Amiga NetHack 3.4 - -III.A. General Installation - Installation should be easy - basically it consists of putting files - where they belong and adding an assign to your startup. If you are - installing from the official binary distribution, simply unpacking - the archive in the appropriate directory will put the files in the - places they belong. - - IF YOU ALREADY HAVE A PREVIOUS VERSION INSTALLED YOU MUST DELETE THE - OLD SAVE AND BONES FILES - THEY WILL NOT WORK! This includes save - and bones files from all previous versions of NetHack (yes, even 3.3.1). - If you have a game in progress and want to finish it, use your - current version and then update. - -Will NetHack fit on your machine? - NetHack 3.6 is large. NetHack 3.4 is very large. You will need: - > Any standard series Amiga: 500, 600, 1000, 1200, 2000, 2500, 3000, 4000. - > WorkBench 2.04 or later. - > At least 3 meg of RAM. NetHack will NOT run in 1 meg (probably even 2). - > Mass storage: A hard drive with over 3 meg of free space is highly - recommended. - -Hard Disk Installation: - Unpack the archive to your place of choice. Since you are reading this - you've probably done that already. Now just assign NetHack: to - NetHack directory containing the executable and datafiles and other needed - directories. - - Use the table in the next section to see where things should end up. - Be sure that the file 8 ends up in NetHack:hack/8. - -Configuration - Using your favorite text editor, edit NetHack:NetHack.cnf to match - your system. - - Create the save file directory (makedir NetHack:save) and the levels file - directory (makedir NetHack:levels), if they don't already exist. - - Create the score file (echo to NetHack:record) and, if desired, the log - file (echo to NetHack:logfile), if they don't already exist. You may - leave out logfile, but record is needed. - -III.B. File Location Table -NetHack: - amii.hlp Guidebook.txt hack.font - license NetHack NetHack.cnf - NetHack.txt nhdat nhsdat - record Recover Recover.txt - logfile (optional, but useful) -NetHack:hack - 8 -NetHack:tiles - monsters.iff objects.iff other.iff - -IV. BBS Interface - - [Since HackCli and split binary is no longer supported the following - probably doesn't apply anymore. Due to lack of a suitable environment - it is also untested.] - - The BBS mode is based on the standard NetHack tty port and is designed - for use in a BBS setting - it is specifically not recommended for use - on the console. The current TTY mode has changed significantly since - the preliminary version released with 3.1.2. In particular, BBS mode - now works with split binaries (only), and now supports multiple games - in progress at the same time for multi-line boards (note however that - any individual user should not be allowed to run two instances of - NetHack at the same time). - - To set up NetHack for use with a BBS, set OPTIONS=windowtype:tty - and unset DUNGEONS, TRAPS, and EFFECTS in NetHack.cnf. Configure - the BBS to expect I/O through stdin and stdout, and have NetHack - invoked as: - HackCLI :uid -u uname options... - where uid is any string (without embedded spaces, colons, or slashes) - that is unique for each BBS user and uname is some corresponding human- - readable name for that user. Uid is used in constructing file names - to prevent collisions between simultaneous games and to prevent - people from using other people's save files. Uname is the name the - character will have in the game and the name that will appear in the - record file. - - The terminal is assumed to be a 24x80 ANSI-compatible terminal. - The present version does not deal with situations such as low - memory gracefully - as NetHack uses a considerable amount of - memory this is particularly painful with multiple games in - progress. Sysops are reminded to be familiar with the recover - utility, which may be needed from time to time and which should - probably not be available directly to users. Bug reports and - suggestions for improvements are requested from the user community - - this is still considered alpha software. - diff --git a/outdated/sys/amiga/Makefile.agc b/outdated/sys/amiga/Makefile.agc deleted file mode 100644 index 5f36d0049..000000000 --- a/outdated/sys/amiga/Makefile.agc +++ /dev/null @@ -1,1241 +0,0 @@ -# NetHack Makefile. -# Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991,1992,1993,1996. -# NetHack may be freely redistributed. See license for details. - -### -### modified for gcc by Teemu Suikki (zu@iki.fi) -### -### note: you need to use smake.. sorry -### - -### -### DIRECTORY STRUCTURE -### - -NH = nh: - -SBIN = $(NH)sbin/ -SLIB = $(NH)slib/ -NETHACK = $(NH)NetHack/ -HACKEXE = $(NH)HackExe/ -AMI = $(NH)sys/amiga/ -DAT = $(NH)dat/ -DOC = $(NH)doc/ -I = $(NH)include/ -SHARE = $(NH)sys/share/ -NHS = $(NH)src/ -TTY = $(NH)win/tty/ -WSHARE = $(NH)win/share/ -UTIL = $(NH)util/ -O = $(NH)obj/ -OO = $(NH)objo/ -# NB: O and OO MUST be different directories - -### -### INVOCATION -### - -MAKE = smake - -# Startup makefile with: -# -# $(MAKE) -f $(AMI)Makefile.amigcc -# $(MAKE) -f $(AMI)Makefile.amigcc install -# -# You may use following targets on $(MAKE) command lines: -# all do it all (default) -# link just create binary from object files -# obj just create common object files -# obja just create amiga object files -# objs just create shared object files -# clean deletes the object files -# spotless deletes the object files, main binary, and more -# -# Note: We do not build the Guidebook here since it needs tbl -# (See the file sys/unix/Makefile.doc for more information) - -#[SAS5] [and gcc?] -# If we were to use the precompiled header file feature in a newer version -# of SAS/C, we would comment out these following two lines. -# If we don't use precompiled header files, we uncomment it as well. - -HDEP = $(I)hack.h -CSYM = - -#Pathname for uudecode program: -UUDEC = uudecode - -# Flex/Bison command assignments -- Useful only if you have flex/bison -FLEX = flex -BISON = bison -# FBFIL and FBLIB may be used, if required by your version of flex or bison, -# to specify additional files or libraries to be linked with -FBFIL = -FBLIB = #lib lib:compat.lib - -# If you're compiling this on a 1.3 system, you'll have to uncomment the -# following (for use with the ifchange script below). Also useful instead of -# "protect ifchange +s" -EXECUTE = execute - -# Headers we depend on -AMDEP = $(AMI)winproto.h $(AMI)winext.h $(AMI)windefs.h $(I)winami.h - -# Pathname for the C compiler being used. - -CC = gcc -c -ASM = as - -# Compilation flags for selected C Compiler: -# $(CFLAGS) should appear before filename arguments of $(CC) command line. - -CFLAGS = -O3 -I $(I) - -# Components of various link command lines: -# $(LINK) should be the pathname of the linker being used (with any options -# that should appear at the beginning of the command line). The name of the -# output file should appear immediately after $(LNSPEC). $(LIN) should -# appear before the list of object files in each link command. $(LLINK) -# should appear as the list of object files in the link command line that -# creates the NetHack executable. $(LLIB) should appear at the end of each -# link command line. - -LINK = gcc -noixemul -O3 -LIN = -LLINK = -LLIB = -FLLIB = -OBJSPEC = -o -PNSPEC = -o -LNSPEC = -o -CCLINK = gcc -noixemul -CLFLAGS = -O3 -INCLSPEC = -I -DEFSPEC = -D -IGNSPEC = -j - -### -### FILE LISTS -### - -# A more reasonable random number generator (recommended for the Amiga): - -RANDOBJ = $(O)random.o - -.PRECIOUS: $(I)config.h $(I)decl.h $(I)hack.h $(I)permonst.h $(I)you.h - -# Almost nothing below this line should have to be changed. -# (Exceptions are marked by [SAS6], [MANX], etc.) -# -# Other things that have to be reconfigured are in config.h, -# (amiconf.h, pcconf.h), and possibly system.h, tradstdc.h. - -# Object files for makedefs: - -MAKEOBJS = \ - $(OO)makedefs.o $(O)monst.o $(O)objects.o - -# Object files for special levels compiler: - -SPLEVOBJS = \ - $(OO)lev_yacc.o $(OO)lev_lex.o $(OO)lev_main.o \ - $(O)decl.o $(O)drawing.o $(O)monst.o \ - $(O)objects.o $(OO)panic.o - -# Object files for dungeon compiler - -DGNCOMPOBJS = \ - $(OO)dgn_yacc.o $(OO)dgn_lex.o $(OO)dgn_main.o $(O)alloc.o $(OO)panic.o - -# Object files for NetHack: - -COMMOBJ = \ - $(O)allmain.o $(O)alloc.o $(O)apply.o $(O)artifact.o \ - $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o \ - $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o \ - $(O)dig.o $(O)display.o $(O)dlb.o $(O)do.o \ - $(O)do_name.o $(O)do_wear.o $(O)dog.o $(O)dogmove.o \ - $(O)dokick.o $(O)dothrow.o $(O)drawing.o $(O)dungeon.o \ - $(O)eat.o $(O)end.o $(O)engrave.o $(O)exper.o \ - $(O)explode.o $(O)extralev.o $(O)files.o $(O)fountain.o \ - $(O)hack.o $(O)hacklib.o $(O)invent.o $(O)light.o \ - $(O)lock.o $(O)mail.o $(O)makemon.o $(O)mapglyph.o \ - $(O)mcastu.o $(O)mhitm.o $(O)mhitu.o $(O)minion.o \ - $(O)mklev.o $(O)mkmap.o $(O)mkmaze.o $(O)mkobj.o \ - $(O)mkroom.o $(O)mon.o $(O)mondata.o $(O)monmove.o \ - $(O)monst.o $(O)mplayer.o $(O)mthrowu.o $(O)muse.o \ - $(O)music.o $(O)o_init.o $(O)objects.o $(O)objnam.o \ - $(O)options.o $(O)pager.o $(O)pickup.o $(O)pline.o \ - $(O)polyself.o $(O)potion.o $(O)pray.o $(O)priest.o \ - $(O)quest.o $(O)questpgr.o $(O)read.o $(O)rect.o \ - $(O)region.o $(O)restore.o $(O)rnd.o $(O)role.o \ - $(O)rumors.o $(O)save.o $(O)shk.o $(O)shknam.o \ - $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o \ - $(O)steal.o $(O)steed.o $(O)sys.o $(O)teleport.o \ - $(O)timeout.o $(O)topten.o $(O)track.o $(O)trap.o \ - $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)version.o \ - $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o \ - $(O)windows.o $(O)wizard.o $(O)worm.o $(O)worn.o \ - $(O)write.o $(O)zap.o - -MAKEDEFOBJ = \ - $(O)monstr.o - -AMIGAOBJ = \ - $(O)amidos.o $(O)amirip.o $(O)amistack.o \ - $(O)amiwind.o $(O)winami.o $(O)winchar.o $(O)winfuncs.o \ - $(O)winkey.o $(O)winamenu.o $(O)winreq.o $(O)winstr.o - -# Objects from assembly sources (because DMake can't handle default rules) -AMIGAOBJ2 = \ -# $(O)dispmap.o - -SHAREOBJ = \ - $(O)pcmain.o $(RANDOBJ) - -TTYOBJ = \ - $(O)getline.o $(O)termcap.o $(O)topl.o $(O)wintty.o $(O)amitty.o \ - $(O)rip.o - -# Yuck yuck yuck. Have to tell DMake where these are, since they're not -# all in the same place. -TTYSRC = \ - $(TTY)getline.c $(TTY)termcap.c $(TTY)topl.c $(TTY)wintty.c \ - $(AMI)amitty.c $(NHS)rip.c - -# All the object files for NetHack: - -HOBJ = $(COMMOBJ) $(AMIGAOBJ) $(AMIGAOBJ2) $(SHAREOBJ) $(MAKEDEFOBJ) $(TTYOBJ) - -### -### DATA FILES -### - -# quest files -ADFILES1= $(SLIB)Arc-fila.lev $(SLIB)Arc-filb.lev $(SLIB)Arc-loca.lev \ - $(SLIB)Arc-strt.lev -ADFILES= $(SLIB)Arc-goal.lev $(ADFILES1) - -BDFILES1= $(SLIB)Bar-fila.lev $(SLIB)Bar-filb.lev $(SLIB)Bar-loca.lev \ - $(SLIB)Bar-strt.lev -BDFILES= $(SLIB)Bar-goal.lev $(BDFILES1) - -CDFILES1= $(SLIB)Cav-fila.lev $(SLIB)Cav-filb.lev $(SLIB)Cav-loca.lev \ - $(SLIB)Cav-strt.lev -CDFILES= $(SLIB)Cav-goal.lev $(CDFILES1) - -HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \ - $(SLIB)Hea-strt.lev -HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1) - -KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \ - $(SLIB)Kni-strt.lev -KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1) - -MDFILES1= $(SLIB)Mon-fila.lev $(SLIB)Mon-filb.lev $(SLIB)Mon-loca.lev \ - $(SLIB)Mon-strt.lev -MDFILES= $(SLIB)Mon-goal.lev $(MDFILES1) - -PDFILES1= $(SLIB)Pri-fila.lev $(SLIB)Pri-filb.lev $(SLIB)Pri-loca.lev \ - $(SLIB)Pri-strt.lev -PDFILES= $(SLIB)Pri-goal.lev $(PDFILES1) - -RDFILES1= $(SLIB)Rog-fila.lev $(SLIB)Rog-filb.lev $(SLIB)Rog-loca.lev \ - $(SLIB)Rog-strt.lev -RDFILES= $(SLIB)Rog-goal.lev $(RDFILES1) - -RANFILES1= $(SLIB)Ran-fila.lev $(SLIB)Ran-filb.lev $(SLIB)Ran-loca.lev \ - $(SLIB)Ran-strt.lev -RANFILES= $(SLIB)Ran-goal.lev $(RANFILES1) - -SDFILES1= $(SLIB)Sam-fila.lev $(SLIB)Sam-filb.lev $(SLIB)Sam-loca.lev \ - $(SLIB)Sam-strt.lev -SDFILES= $(SLIB)Sam-goal.lev $(SDFILES1) - -TDFILES1= $(SLIB)Tou-fila.lev $(SLIB)Tou-filb.lev $(SLIB)Tou-loca.lev \ - $(SLIB)Tou-strt.lev -TDFILES= $(SLIB)Tou-goal.lev $(TDFILES1) - -VDFILES1= $(SLIB)Val-fila.lev $(SLIB)Val-filb.lev $(SLIB)Val-loca.lev \ - $(SLIB)Val-strt.lev -VDFILES= $(SLIB)Val-goal.lev $(VDFILES1) - -WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \ - $(SLIB)Wiz-strt.lev -WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1) - -XDFILES= $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \ - $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \ - $(VDFILES) $(WDFILES) - -TILEFILES= \ - $(SBIN)txt2iff \ - $(NETHACK)tiles \ - $(NETHACK)tiles/objects.iff \ - $(NETHACK)tiles/monsters.iff \ - $(NETHACK)tiles/other.iff - -INSTDUNGEONFILES1= \ - $(SLIB)air.lev $(SLIB)asmodeus.lev $(SLIB)astral.lev \ - $(SLIB)baalz.lev $(SLIB)bigrm-1.lev $(SLIB)bigrm-2.lev \ - $(SLIB)bigrm-3.lev $(SLIB)bigrm-4.lev $(SLIB)bigrm-5.lev \ - $(SLIB)castle.lev $(SLIB)dungeon $(SLIB)earth.lev \ - $(SLIB)fakewiz1.lev $(SLIB)fakewiz2.lev $(SLIB)fire.lev \ - $(SLIB)juiblex.lev $(SLIB)knox.lev $(SLIB)medusa-1.lev \ - $(SLIB)medusa-2.lev $(SLIB)minend-1.lev $(SLIB)minend-2.lev \ - $(SLIB)minetn-1.lev $(SLIB)minetn-2.lev $(SLIB)minefill.lev \ - $(SLIB)options $(SLIB)oracle.lev $(SLIB)orcus.lev \ - $(SLIB)sanctum.lev $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev \ - $(SLIB)soko2-1.lev $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev \ - $(SLIB)soko3-2.lev $(SLIB)soko4-1.lev $(SLIB)soko4-2.lev \ - $(SLIB)tower1.lev $(SLIB)tower2.lev $(SLIB)tower3.lev \ - $(SLIB)valley.lev $(SLIB)water.lev $(SLIB)wizard1.lev \ - $(SLIB)wizard2.lev $(SLIB)wizard3.lev \ - $(XDFILES) - -INSTDUNGEONFILES= $(NETHACK)NetHack.cnf $(INSTDUNGEONFILES1) - - -INSTDATAFILES= \ - $(NETHACK)license $(NETHACK)logfile $(NETHACK)record \ - $(NETHACK)tomb.iff $(NETHACK)amii.hlp $(NETHACK)Recover.txt \ - $(NETHACK)GuideBook.txt $(NETHACK)NetHack.txt $(NETHACK)Install.ami \ -# $(NETHACK)HackWB.hlp $(NETHACK)WBDefaults.def - -LIBFILES= \ - $(INSTDUNGEONFILES1) \ - $(SLIB)cmdhelp $(SLIB)data $(SLIB)dungeon \ - $(SLIB)help $(SLIB)hh $(SLIB)history \ - $(SLIB)opthelp $(SLIB)oracles $(SLIB)rumors \ - $(SLIB)quest.dat $(SLIB)wizhelp - -### -### Getting down to business: -### - -all: $(COMPACT_HEADERS) $(SBIN)lev_comp $(SBIN)dgn_comp $(SBIN)NetHack \ - $(SBIN)dlb $(NETHACK)recover #$(NETHACK)HackCli $(SBIN)splitter \ -# $(NETHACK)HackWB - -install: inst-data inst-dungeon inst-fonts inst-tiles \ - $(NETHACK)recover $(NETHACK)NetHack $(NETHACK)nhdat - #$(NETHACK)NetHack.dir inst-icons - -$(SBIN)NetHack: link - -$(NETHACK)NetHack: $(SBIN)NetHack - copy $(SBIN)NetHack $(NETHACK)NetHack - -## uuh this is messy.. smake has weird command line length limit -link: $(HOBJ) - list to t:link lformat="$(O)%s" $(O)\#?.o QUICK NOHEAD - echo "\#sh" to t:cc - echo "$(LINK) $(LNSPEC) $(SBIN)NetHack $(LIN) $(LLIB) $(LLINK) " >>t:cc noline - fmt -u -w 2500 t:link >>t:cc - sh t:cc - delete t:cc t:link - - -## dlb support -$(OO)dlb_main.o: $(UTIL)dlb_main.c $(HDEP) $(I)dlb.h $(I)date.h - $(CC) $(CFLAGS) $(OBJSPEC)$(OO)dlb_main.o $(UTIL)dlb_main.c - -$(SBIN)dlb: $(OO)dlb_main.o $(O)dlb.o $(O)alloc.o $(OO)panic.o - $(LINK) $(PNSPEC) $(SBIN)dlb $(LIN) $(OO)dlb_main.o $(O)dlb.o \ - $(O)alloc.o $(OO)panic.o $(LLIB) - -obj: $(HOBJ) - -obja: $(AMIGAOBJ) - -objs: $(SHAREOBJ) - - -SUFFIXES = .lev .des -.des.lev: - $(SBIN)lev_comp $< - -# The default method for creating object files: - -#$(O)%.o: $(NHS)%.c -.c.o: - $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)$@ $< - -clean: - -delete $(O)\#?.o $(OO)\#?.o - -spotless: clean - -delete $(SBIN)NetHack $(SBIN)lev_comp $(SBIN)makedefs $(SBIN)dgn_comp - -delete $(SBIN)dlb $(SBIN)txt2iff $(SBIN)splitter - -delete $(SBIN)tilemap - -delete $(SLIB)data $(SLIB)rumors - -delete $(SLIB)\#?.lev - -delete $(SLIB)dungeon - -delete $(SLIB)cmdhelp $(SLIB)help $(SLIB)hh $(SLIB)history - -delete $(SLIB)opthelp $(SLIB)options $(SLIB)oracles - -delete $(SLIB)quest.dat $(SLIB)wizhelp -# -delete $(SLIB)earth.lev $(SLIB)air.lev $(SLIB)fire.lev -# -delete $(SLIB)water.lev $(SLIB)astral.lev -# -delete $(SLIB)tower1.lev $(SLIB)tower2.lev $(SLIB)tower3.lev -# -delete $(SLIB)fakewiz1.lev $(SLIB)fakewiz2.lev -# -delete $(SLIB)medusa-1.lev $(SLIB)medusa-2.lev -# -delete $(SLIB)oracle.lev $(SLIB)wizard1.lev $(SLIB)wizard2.lev -# -delete $(SLIB)wizard3.lev $(DAT)dungeon.pdf $(SLIB)valley.lev -# -delete $(SLIB)minefill.lev -# -delete $(SLIB)minetn-1 $(SLIB)minetn-2 $(SLIB)minend-1 $(SLIB)minend-2 -# -delete $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev $(SLIB)soko2-1.lev -# -delete $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev $(SLIB)soko3-2.lev -# -delete $(SLIB)soko4-1.lev $(SLIB)soko4-2.lev -# -delete $(ADFILES) -# -delete $(BDFILES) -# -delete $(CDFILES) -# -delete $(HDFILES) -# -delete $(KDFILES) -# -delete $(MDFILES) -# -delete $(PDFILES) -# -delete $(RDFILES) -# -delete $(RANFILES) -# -delete $(SDFILES) -# -delete $(TDFILES) -# -delete $(VDFILES) -# -delete $(WDFILES) - -delete $(I)onames.h $(I)pm.h $(I)date.h - -delete $(NHS)tile.c $(NHS)monstr.c - -delete $(I)tile.h -# -echo to $(I)onames.h "" noline -# -c:wait 2 -# -echo to $(I)pm.h "" noline -# -c:wait 2 -# -setdate $(UTIL)makedefs.c -# -c:wait 2 - -# Creating precompiled version of $(I)hack.h to save disk I/O. - -# -# Please note: The dependency lines for the modules here are -# deliberately incorrect. Including "hack.h" in -# the dependency list would cause a dependency -# loop. -# - -$(SBIN)makedefs: $(MAKEOBJS) - $(LINK) $(LNSPEC) $(SBIN)makedefs $(LIN) $(MAKEOBJS) $(LLIB) - -$(OO)makedefs.o: $(UTIL)makedefs.c $(I)config.h $(I)permonst.h $(I)monsym.h \ - $(I)objclass.h $(I)patchlevel.h $(I)artilist.h - $(CC) $(DEFSPEC)MAKEDEFS_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)makedefs.c - -$(SBIN)lev_comp: $(SPLEVOBJS) - $(LINK) $(LNSPEC) $(SBIN)lev_comp $(LIN) $(SPLEVOBJS) $(FBFIL) $(FLLIB) - -$(SBIN)dgn_comp: $(DGNCOMPOBJS) - $(LINK) $(LNSPEC) $(SBIN)dgn_comp $(LIN) $(DGNCOMPOBJS) $(FBFIL) $(FLLIB) - -$(OO)lev_yacc.o: $(UTIL)lev_yacc.c $(HDEP) $(I)sp_lev.h $(I)pm.h $(I)onames.h -# setdate $(UTIL)lev_yacc.c - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)PREFIX="NH:slib/" $(CFLAGS) \ - $(DEFSPEC)alloca=malloc $(OBJSPEC)$@ $(UTIL)lev_yacc.c - -$(OO)lev_lex.o: $(UTIL)lev_lex.c $(HDEP) $(I)lev_comp.h $(I)sp_lev.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)lev_lex.c - -$(OO)lev_main.o: $(UTIL)lev_main.c $(HDEP) $(I)pm.h $(I)onames.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)lev_main.c - -$(OO)dgn_yacc.o: $(UTIL)dgn_yacc.c $(HDEP) $(I)dgn_file.h $(I)patchlevel.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(DEFSPEC)alloca=malloc \ - $(OBJSPEC)$@ $(UTIL)dgn_yacc.c - -$(OO)dgn_lex.o: $(UTIL)dgn_lex.c $(I)config.h $(I)dgn_comp.h $(I)dgn_file.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)dgn_lex.c - -$(OO)dgn_main.o: $(UTIL)dgn_main.c $(I)config.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)dgn_main.c - -$(OO)panic.o: $(UTIL)panic.c $(HDEP) - -$(OO)recover.o: $(UTIL)recover.c $(I)config.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)recover.c - -$(NETHACK)recover: $(OO)recover.o - $(LINK) $(LNSPEC) $(NETHACK)recover $(LIN) $(OO)recover.o $(LLIB) - -# [OPTION] -- If you have flex/bison, leave these uncommented. Otherwise, -# comment them out and be careful! (You're not guaranteed to have the most -# up to date *_comp.c, *_comp.h and *_lex.c) - -$(I)lev_comp.h: $(UTIL)lev_yacc.c $(I)patchlevel.h - -$(UTIL)lev_yacc.c: $(UTIL)lev_comp.y $(I)patchlevel.h - $(BISON) -d $(UTIL)lev_comp.y -# copy y.tab.c $(UTIL)lev_yacc.c -# copy y.tab.h $(I)lev_comp.h - copy $(UTIL)lev_comp.tab.c $(UTIL)lev_yacc.c - copy $(UTIL)lev_comp.tab.h $(I)lev_comp.h -# delete y.tab.c -# delete y.tab.h - delete $(UTIL)lev_comp.tab.c - delete $(UTIL)lev_comp.tab.h - -$(UTIL)lev_lex.c: $(UTIL)lev_comp.l $(I)patchlevel.h - $(FLEX) $(UTIL)lev_comp.l - copy lex.yy.c $(UTIL)lev_lex.c - delete lex.yy.c - -$(I)dgn_comp.h: $(UTIL)dgn_yacc.c $(I)patchlevel.h - -$(UTIL)dgn_yacc.c: $(UTIL)dgn_comp.y $(I)patchlevel.h - $(BISON) -d $(UTIL)dgn_comp.y -# copy y.tab.c $(UTIL)dgn_yacc.c -# copy y.tab.h $(I)dgn_comp.h - copy $(UTIL)dgn_comp.tab.c $(UTIL)dgn_yacc.c - copy $(UTIL)dgn_comp.tab.h $(I)dgn_comp.h -# delete y.tab.c -# delete y.tab.h - delete $(UTIL)dgn_comp.tab.c - delete $(UTIL)dgn_comp.tab.h - -$(UTIL)dgn_lex.c: $(UTIL)dgn_comp.l $(I)patchlevel.h - $(FLEX) $(UTIL)dgn_comp.l - copy lex.yy.c $(UTIL)dgn_lex.c - delete lex.yy.c - -# -# The following include files depend on makedefs to be created. -# As a result, they are not defined in HACKINCL, instead, their -# dependencies are explicitly outlined here. -# - -# -# date.h should be remade any time any of the source or include code -# is modified. Unfortunately, this would make the contents of this -# file far more complex. Since "hack.h" depends on most of the include -# files, we kludge around this by making date.h dependent on hack.h, -# even though it doesn't include this file. -# - -$(I)date.h $(DAT)options: $(HDEP) $(SBIN)makedefs $(AMIGAOBJ) $(I)patchlevel.h - $(SBIN)makedefs -v - $(EXECUTE) ifchange MOVE $(I)t.date.h $(I)date.h - -c:wait 2 - -$(I)onames.h: $(SBIN)makedefs - $(SBIN)makedefs -o - $(EXECUTE) ifchange TOUCH $(I)t.onames.h $(I)onames.h $(I)decl.h - $(EXECUTE) ifchange MOVE $(I)t.onames.h $(I)onames.h - -c:wait 2 - -$(I)pm.h: $(SBIN)makedefs - $(SBIN)makedefs -p - $(EXECUTE) ifchange TOUCH $(I)t.pm.h $(I)pm.h $(I)decl.h $(I)youprop.h - $(EXECUTE) ifchange MOVE $(I)t.pm.h $(I)pm.h - -c:wait 2 - -$(SLIB)quest.dat: $(DAT)quest.txt $(SBIN)makedefs - $(SBIN)makedefs -q - -$(NHS)monstr.c: $(HDEP) $(SBIN)makedefs - $(SBIN)makedefs -m - -c:wait 2 - -$(SLIB)oracles: $(DAT)oracles.txt $(SBIN)makedefs - $(SBIN)makedefs -h - -c:wait 2 - -# -# The following programs vary depending on what OS you are using. -# As a result, they are not defined in HACKSRC and their dependencies -# are explicitly outlined here. -# - -$(O)amidos.o: $(AMI)amidos.c $(HDEP) - -$(O)amirip.o: $(AMI)amirip.c $(HDEP) - -$(O)aglue.o: $(AMI)aglue.a - $(ASM) $(AFLAGS) $(AOBJSPEC)$(O)aglue.o $(AMI)aglue.a - -$(O)winchar.o: $(AMI)winchar.c $(NHS)tile.c $(HDEP) - -$(NHS)tile.c: $(WSHARE)tilemap.c - $(CCLINK) $(CFLAGS) $(PNSPEC) $(SBIN)tilemap $(WSHARE)tilemap.c - $(SBIN)tilemap - -$(O)winstr.o: $(AMI)winstr.c $(HDEP) $(AMDEP) - -$(O)winreq.o: $(AMI)winreq.c $(HDEP) $(AMDEP) $(AMI)colorwin.c $(AMI)clipwin.c - -$(O)winfuncs.o: $(AMI)winfuncs.c $(HDEP) $(AMDEP) $(I)patchlevel.h - -$(O)winkey.o: $(AMI)winkey.c $(HDEP) $(AMDEP) - -$(O)winamenu.o: $(AMI)winamenu.c $(HDEP) $(AMDEP) - -$(O)winami.o: $(AMI)winami.c $(HDEP) $(AMDEP) #$(AMI)char.c $(AMI)randwin.c - -#$(O)amilib.o: $(AMI)amilib.c $(HDEP) $(AMDEP) - -$(O)amiwind.o: $(AMI)amiwind.c $(AMI)amimenu.c $(HDEP) $(AMDEP) - -$(O)amiwbench.o: $(AMI)amiwbench.c $(HDEP) - -$(O)random.o: $(SHARE)random.c - -$(O)pcmain.o: $(SHARE)pcmain.c $(HDEP) $(I)dlb.h - -$(O)dispmap.o: $(AMI)dispmap.s - $(ASM) $(AFLAGS) $(AOBJSPEC)$@ $< - -# Stuff to build the front ends -$(NETHACK)HackWB: $(OO)wb.o $(OO)wbx.o $(OO)loader.o $(OO)multi.o - $(LINK) $(LNSPEC) $(NETHACK)HackWB $(LIN) $(OO)wb.o $(OO)wbx.o \ - $(OO)loader.o $(OO)multi.o $(LLIB) - -$(NETHACK)HackCli: $(OO)cli.o $(OO)loader.o $(OO)multi.o - $(LINK) $(LNSPEC) $(NETHACK)HackCli $(LIN) $(OO)cli.o $(OO)loader.o \ - $(OO)multi.o $(LLIB) - -# This needs to exist to eliminate the HackWB startup message -$(NETHACK)WBDefaults.def: - echo to $(NETHACK)WBDefaults.def - -WBH = $(AMI)wbdefs.h $(AMI)wbstruct.h $(AMI)wbprotos.h -ASP = $(AMI)splitter -$(OO)wb.o: $(WBH) $(AMI)wb.c $(AMI)wbwin.c $(AMI)wbdata.c $(AMI)wbgads.c \ - $(I)patchlevel.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)wb.o $(AMI)wb.c - -$(OO)wbx.o: $(WBH) $(AMI)wbcli.c $(AMI)wbwin.c $(AMI)wbdata.c \ - $(I)patchlevel.h $(I)date.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)wbx.o $(AMI)wbcli.c - -$(OO)loader.o: $(ASP)/loader.c $(ASP)/split.h $(ASP)/amiout.h $(ASP)/multi.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)loader.o $(ASP)/loader.c - -$(OO)multi.o: $(ASP)/multi.c $(ASP)/multi.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)multi.o $(ASP)/multi.c - -$(OO)cli.o: $(WBH) $(AMI)wbcli.c $(I)patchlevel.h $(I)date.h - $(CC) $(WBCFLAGS) $(WBC2FLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)cli.o \ - $(AMI)wbcli.c - -#### -# splitter support -$(SBIN)splitter: $(OO)splitter.o $(OO)arg.o - $(LINK) $(LNSPEC) $(SBIN)splitter $(LIN) $(OO)splitter.o $(OO)arg.o \ - $(LLIB) - -$(NETHACK)NetHack.dir: $(SBIN)splitter $(SBIN)NetHack - $(SBIN)splitter $(SBIN)NetHack - -$(OO)splitter.o: $(ASP)/splitter.c $(ASP)/split.h $(ASP)/amiout.h $(ASP)/arg.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)splitter.o \ - $(ASP)/splitter.c - -$(OO)arg.o: $(ASP)/arg.c $(ASP)/arg.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)arg.o $(ASP)/arg.c - -# Create/copy other stuff into NetHack: directory: - -$(NETHACK)tomb.iff: $(SBIN)xpm2iff $(AMI)grave16.xpm - $(SBIN)xpm2iff $(AMI)grave16.xpm $(NETHACK)tomb.iff - -$(OO)xpm2iff.o: $(AMI)xpm2iff.c - $(CC) $(CFLAGS) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(AMI)xpm2iff.c - -$(SBIN)xpm2iff: $(OO)xpm2iff.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)xpm2iff.o $(FLLIB) - -# Tile installation for the tile version of the game -inst-tiles: $(TILEFILES) - -$(NETHACK)tiles: - -makedir $(NETHACK)tiles - -$(OO)txt2iff.o: $(AMI)txt2iff.c - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ \ - $(AMI)txt2iff.c - -$(OO)ppmwrite.o: $(WSHARE)ppmwrite.c - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)ppmwrite.c - -$(OO)tiletext.o: $(WSHARE)tiletext.c $(I)config.h $(WSHARE)tile.h - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)tiletext.c - -$(OO)tiletxt.o: $(WSHARE)tilemap.c $(I)hack.h - $(CC) $(CFLAGS) $(CSYM) $(DEFSPEC)TILETEXT $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)tilemap.c - -NAMEOBJS = $(O)drawing.o $(O)decl.o $(O)monst.o $(O)objects.o - -$(SBIN)txt2ppm: $(OO)ppmwrite.o $(NAMEOBJS) $(O)alloc.o $(OO)panic.o $(OO)tiletext.o $(OO)tiletxt.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)ppmwrite.o $(NAMEOBJS) $(OO)tiletext.o $(OO)tiletxt.o $(O)alloc.o $(OO)panic.o $(FLLIB) - -$(SBIN)txt2iff: $(OO)txt2iff.o $(NAMEOBJS) $(OO)tiletext.o $(OO)tiletxt.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)txt2iff.o $(NAMEOBJS) $(OO)tiletext.o \ - $(OO)tiletxt.o $(FLLIB) - -$(NETHACK)tiles/objects.iff: $(WSHARE)objects.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)objects.txt $(NETHACK)tiles/objects.iff - -$(NETHACK)tiles/monsters.iff: $(WSHARE)monsters.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)monsters.txt $(NETHACK)tiles/monsters.iff - -$(NETHACK)tiles/other.iff: $(WSHARE)other.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)other.txt $(NETHACK)tiles/other.iff - -inst-dungeon: $(INSTDUNGEONFILES) - -$(NETHACK)options : $(DAT)options - copy $(DAT)options $@ - -# Create compiled dungeon files -BGM= $(SLIB)bigrm-2.lev $(SLIB)bigrm-3.lev $(SLIB)bigrm-4.lev $(SLIB)bigrm-5.lev -$(BGM): $(SLIB)bigrm-1.lev - -$(SLIB)bigrm-1.lev: $(DAT)bigroom.des $(SBIN)lev_comp - -$(SLIB)castle.lev: $(DAT)castle.des $(SBIN)lev_comp - -ENDGAME1= $(SLIB)air.lev $(SLIB)earth.lev $(SLIB)fire.lev $(SLIB)water.lev -$(ENDGAME1): $(SLIB)astral.lev - -$(SLIB)astral.lev: $(DAT)endgame.des $(SBIN)lev_comp - -GEHENNOM1= $(SLIB)asmodeus.lev $(SLIB)baalz.lev $(SLIB)juiblex.lev \ - $(SLIB)orcus.lev $(SLIB)sanctum.lev -$(GEHENNOM1): $(SLIB)valley.lev - -$(SLIB)valley.lev: $(DAT)gehennom.des $(SBIN)lev_comp - -$(SLIB)knox.lev: $(DAT)knox.des $(SBIN)lev_comp - -MINES1= $(SLIB)minend-1.lev $(SLIB)minend-2.lev $(SLIB)minetn-1.lev $(SLIB)minetn-2.lev -$(MINES1): $(SLIB)minefill.lev - -$(SLIB)minefill.lev: $(DAT)mines.des $(SBIN)lev_comp - -$(SLIB)oracle.lev: $(DAT)oracle.des $(SBIN)lev_comp - -TOWER1= $(SLIB)tower1.lev $(SLIB)tower2.lev -$(TOWER1): $(SLIB)tower3.lev - -$(SLIB)tower3.lev: $(DAT)tower.des $(SBIN)lev_comp - -WIZARD1= $(SLIB)wizard1.lev $(SLIB)wizard2.lev $(SLIB)wizard3.lev \ - $(SLIB)fakewiz1.lev -$(WIZARD1): $(SLIB)fakewiz2.lev - -$(SLIB)fakewiz2.lev: $(DAT)yendor.des $(SBIN)lev_comp - -MEDUSA1= $(SLIB)medusa-1.lev -$(MEDUSA1): $(SLIB)medusa-2.lev - -$(SLIB)medusa-2.lev: $(DAT)medusa.des $(SBIN)lev_comp - -SOKOBAN1= $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev $(SLIB)soko2-1.lev \ - $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev $(SLIB)soko3-2.lev \ - $(SLIB)soko4-1.lev -$(SOKOBAN1): $(SLIB)soko4-2.lev - -$(SLIB)soko4-2.lev: $(DAT)sokoban.des $(SBIN)lev_comp - -$(ADFILES1): $(SLIB)Arc-goal.lev - -$(SLIB)Arc-goal.lev: $(DAT)Arch.des $(SBIN)lev_comp - -$(BDFILES1): $(SLIB)Bar-goal.lev - -$(SLIB)Bar-goal.lev: $(DAT)Barb.des $(SBIN)lev_comp - -$(CDFILES1): $(SLIB)Cav-goal.lev - -$(SLIB)Cav-goal.lev: $(DAT)Caveman.des $(SBIN)lev_comp - -$(HDFILES1): $(SLIB)Hea-goal.lev - -$(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp - -$(KDFILES1): $(SLIB)Kni-goal.lev - -$(SLIB)Kni-goal.lev: $(DAT)Knight.des $(SBIN)lev_comp - -$(MDFILES1): $(SLIB)Mon-goal.lev - -$(SLIB)Mon-goal.lev: $(DAT)Monk.des $(SBIN)lev_comp - -$(PDFILES1): $(SLIB)Pri-goal.lev - -$(SLIB)Pri-goal.lev: $(DAT)Priest.des $(SBIN)lev_comp - -$(RDFILES1): $(SLIB)Rog-goal.lev - -$(SLIB)Rog-goal.lev: $(DAT)Rogue.des $(SBIN)lev_comp - -$(RANFILES1): $(SLIB)Ran-goal.lev - -$(SLIB)Ran-goal.lev: $(DAT)Ranger.des $(SBIN)lev_comp - -$(SDFILES1): $(SLIB)Sam-goal.lev - -$(SLIB)Sam-goal.lev: $(DAT)Samurai.des $(SBIN)lev_comp - -$(TDFILES1): $(SLIB)Tou-goal.lev - -$(SLIB)Tou-goal.lev: $(DAT)Tourist.des $(SBIN)lev_comp - -$(VDFILES1): $(SLIB)Val-goal.lev - -$(SLIB)Val-goal.lev: $(DAT)Valkyrie.des $(SBIN)lev_comp - -$(WDFILES1): $(SLIB)Wiz-goal.lev - -$(SLIB)Wiz-goal.lev: $(DAT)Wizard.des $(SBIN)lev_comp - -$(SLIB)dungeon: $(DAT)dungeon.def $(SBIN)makedefs $(SBIN)dgn_comp - $(SBIN)makedefs -e - $(SBIN)dgn_comp $(DAT)dungeon.pdf - copy $(DAT)dungeon $(SLIB)dungeon - delete $(DAT)dungeon - -inst-data: $(INSTDATAFILES) - -$(NETHACK)amii.hlp: $(AMI)amii.hlp - copy $(AMI)amii.hlp $@ - -#$(NETHACK)data: $(DAT)data -# copy $(DAT)data $@ - -$(SLIB)data: $(DAT)data.base $(I)config.h $(SBIN)makedefs - $(SBIN)makedefs -d - -#$(NETHACK)rumors: $(DAT)rumors -# copy $(DAT)rumors $@ - -$(SLIB)rumors: $(DAT)rumors.tru $(DAT)rumors.fal $(SBIN)makedefs - $(SBIN)makedefs -r - -$(SLIB)cmdhelp: $(DAT)cmdhelp - copy $(DAT)cmdhelp $@ - -$(SLIB)help: $(DAT)help - copy $(DAT)help $@ - -$(SLIB)hh: $(DAT)hh - copy $(DAT)hh $@ - -$(NETHACK)HackWB.hlp: $(AMI)HackWB.hlp - copy $(AMI)HackWB.hlp $@ - -$(SLIB)history: $(DAT)history - copy $(DAT)history $@ - -$(NETHACK)license: $(DAT)license - copy $(DAT)license $@ - -$(SLIB)opthelp: $(DAT)opthelp - copy $(DAT)opthelp $@ - -$(NETHACK)Recover.txt: $(DOC)Recover.txt - copy $(DOC)Recover.txt $@ - -$(NETHACK)GuideBook.txt: $(DOC)GuideBook.txt - copy $(DOC)GuideBook.txt $@ - -$(NETHACK)NetHack.txt: $(DOC)NetHack.txt - copy $(DOC)NetHack.txt $@ - -$(NETHACK)Install.ami: $(AMI)Install.ami - copy $(AMI)Install.ami $@ - -$(NETHACK)logfile: - echo to $@ - -$(NETHACK)record: - echo to $@ - -$(SLIB)wizhelp: $(DAT)wizhelp - copy $(DAT)wizhelp $@ - -# Create the directories here because NetHack.cnf puts them there by default -$(NETHACK)NetHack.cnf: $(AMI)NetHack.cnf - copy $(AMI)NetHack.cnf $@ - -makedir $(NETHACK)save - -makedir $(NETHACK)levels - -# Unpack and install fonts - -INSTFONTFILES= $(NETHACK)hack.font $(NETHACK)hack $(NETHACK)hack/8 - -inst-fonts: $(INSTFONTFILES) - -$(NETHACK)hack/8: $(AMI)amifont8.uu $(NETHACK)hack - $(UUDEC) $(AMI)amifont8.uu - copy 8 $(NETHACK)hack/8 - delete 8 - -$(NETHACK)hack.font: $(AMI)amifont.uu - $(UUDEC) $(AMI)amifont.uu - copy hack.font $(NETHACK)hack.font - delete hack.font - -$(NETHACK)hack: - -makedir $@ - -INSTICONFILES= \ - $(NETHACK)default.icon $(NETHACK)NetHack.info $(NETHACK)NewGame.info \ - $(NETHACK)HackWB.info - -inst-icons: $(INSTICONFILES) - -# Unpack the icons into place - -$(NETHACK)default.icon: $(AMI)dflticon.uu - $(UUDEC) $(AMI)dflticon.uu -# copy default.icon $(NETHACK)default.icon -# delete default.icon - -$(NETHACK)NetHack.info: $(AMI)NHinfo.uu - $(UUDEC) $(AMI)NHinfo.uu -# copy NetHack.info $(NETHACK)NetHack.info -# delete NetHack.info - -$(NETHACK)NewGame.info: $(AMI)NewGame.uu - $(UUDEC) $(AMI)NewGame.uu -# copy NewGame.info $(NETHACK)NewGame.info -# delete NewGame.info - -$(NETHACK)HackWB.info: $(AMI)HackWB.uu - $(UUDEC) $(AMI)HackWB.uu -# copy HackWB.info $(NETHACK)HackWB.info -# delete HackWB.info - -# If DLB is defined, create the nhdat library file in the playground -# directory. If not, move all the data files there. -$(NETHACK)nhdat: $(LIBFILES) - list to T:nhdat.lst $(SLIB) QUICK NOHEAD FILES - echo >T:make-nhdat $(SBIN)dlb cCfI $(SLIB) $(NETHACK)nhdat T:nhdat.lst - echo >>T:make-nhdat if not exists $(NETHACK)nhdat - echo >>T:make-nhdat copy $(SLIB)\#? $(NETHACK) - echo >>T:make-nhdat endif - execute T:make-nhdat - -delete T:make-nhdat - -# DO NOT DELETE THIS LINE - -$(O)allmain.o: $(NHS)allmain.c $(HDEP) - -$(O)alloc.o: $(NHS)alloc.c $(I)config.h - -$(O)apply.o: $(NHS)apply.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)apply.c - -$(O)artifact.o: $(NHS)artifact.c $(HDEP) $(I)artifact.h $(I)artilist.h - -$(O)attrib.o: $(NHS)attrib.c $(HDEP) $(I)artifact.h - -$(O)ball.o: $(NHS)ball.c $(HDEP) - -$(O)bones.o: $(NHS)bones.c $(HDEP) - -$(O)botl.o: $(NHS)botl.c $(HDEP) - -$(O)cmd.o: $(NHS)cmd.c $(HDEP) $(I)func_tab.h - -$(O)dbridge.o: $(NHS)dbridge.c $(HDEP) - -$(O)decl.o: $(NHS)decl.c $(HDEP) $(I)quest.h - -$(O)detect.o: $(NHS)detect.c $(HDEP) $(I)artifact.h - -$(O)dig.o: $(NHS)dig.c $(HDEP) - -$(O)display.o: $(NHS)display.c $(HDEP) - -$(O)dlb.o: $(NHS)dlb.c $(HDEP) $(I)dlb.h - -$(O)do.o: $(NHS)do.c $(HDEP) - -$(O)do_name.o: $(NHS)do_name.c $(HDEP) - -$(O)do_wear.o: $(NHS)do_wear.c $(HDEP) - -$(O)dog.o: $(NHS)dog.c $(HDEP) - -$(O)dogmove.o: $(NHS)dogmove.c $(HDEP) $(I)mfndpos.h - -$(O)dokick.o: $(NHS)dokick.c $(HDEP) - -$(O)dothrow.o: $(NHS)dothrow.c $(HDEP) - -$(O)drawing.o: $(NHS)drawing.c $(HDEP) $(I)tcap.h - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)drawing.c - -$(O)dungeon.o: $(NHS)dungeon.c $(HDEP) $(I)dgn_file.h $(I)dlb.h - -$(O)eat.o: $(NHS)eat.c $(HDEP) - -$(O)end.o: $(NHS)end.c $(HDEP) $(I)dlb.h - -$(O)engrave.o: $(NHS)engrave.c $(HDEP) - -$(O)exper.o: $(NHS)exper.c $(HDEP) - -$(O)explode.o: $(NHS)explode.c $(HDEP) - -$(O)extralev.o: $(NHS)extralev.c $(HDEP) - -$(O)files.o: $(NHS)files.c $(HDEP) $(I)dlb.h $(I)date.h - -$(O)fountain.o: $(NHS)fountain.c $(HDEP) - -$(O)hack.o: $(NHS)hack.c $(HDEP) - -$(O)hacklib.o: $(NHS)hacklib.c $(HDEP) - -$(O)invent.o: $(NHS)invent.c $(HDEP) $(I)artifact.h - -$(O)light.o: $(NHS)light.c $(HDEP) - -$(O)lock.o: $(NHS)lock.c $(HDEP) - -$(O)mail.o: $(NHS)mail.c $(HDEP) $(I)mail.h - -$(O)makemon.o: $(NHS)makemon.c $(HDEP) - -$(O)mapglyph.o: $(NHS)mapglyph.c $(HDEP) - -$(O)mcastu.o: $(NHS)mcastu.c $(HDEP) - -$(O)mhitm.o: $(NHS)mhitm.c $(HDEP) $(I)artifact.h - -$(O)mhitu.o: $(NHS)mhitu.c $(HDEP) $(I)artifact.h - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)mhitu.c - -$(O)minion.o: $(NHS)minion.c $(HDEP) - -$(O)mklev.o: $(NHS)mklev.c $(HDEP) - -$(O)mkmap.o: $(NHS)mkmap.c $(HDEP) $(I)sp_lev.h - -$(O)mkmaze.o: $(NHS)mkmaze.c $(HDEP) $(I)sp_lev.h - -$(O)mkobj.o: $(NHS)mkobj.c $(HDEP) $(I)artifact.h $(I)prop.h - -$(O)mkroom.o: $(NHS)mkroom.c $(HDEP) - -$(O)mon.o: $(NHS)mon.c $(HDEP) $(I)mfndpos.h - -$(O)mondata.o: $(NHS)mondata.c $(HDEP) - -$(O)monmove.o: $(NHS)monmove.c $(HDEP) $(I)mfndpos.h $(I)artifact.h - -$(O)monst.o: $(NHS)monst.c $(I)config.h $(I)permonst.h $(I)monsym.h \ - $(I)color.h - -$(O)monstr.o: $(NHS)monstr.c $(HDEP) - -$(O)mplayer.o: $(NHS)mplayer.c $(HDEP) - -$(O)mthrowu.o: $(NHS)mthrowu.c $(HDEP) - -$(O)muse.o: $(NHS)muse.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)muse.c - -$(O)music.o: $(NHS)music.c $(HDEP) #interp.c - -$(O)o_init.o: $(NHS)o_init.c $(HDEP) - -$(O)objects.o: $(NHS)objects.c $(I)config.h $(I)obj.h $(I)objclass.h \ - $(I)prop.h $(I)skills.h $(I)color.h - $(CC) $(CFLAGS) $(INCLSPEC)$(NHS) $(OBJSPEC)$@ $(NHS)objects.c - -$(O)objnam.o: $(NHS)objnam.c $(HDEP) - -$(O)options.o: $(NHS)options.c $(HDEP) $(I)tcap.h $(I)config.h \ - $(I)objclass.h $(I)flag.h - -$(O)pager.o: $(NHS)pager.c $(HDEP) $(I)dlb.h - -$(O)pickup.o: $(NHS)pickup.c $(HDEP) - -$(O)pline.o: $(NHS)pline.c $(HDEP) - -$(O)polyself.o: $(NHS)polyself.c $(HDEP) - -$(O)potion.o: $(NHS)potion.c $(HDEP) - -$(O)pray.o: $(NHS)pray.c $(HDEP) - -$(O)priest.o: $(NHS)priest.c $(HDEP) $(I)mfndpos.h - -$(O)quest.o: $(NHS)quest.c $(HDEP) $(I)quest.h - -$(O)questpgr.o: $(NHS)questpgr.c $(HDEP) $(I)dlb.h - -$(O)read.o: $(NHS)read.c $(HDEP) - -$(O)rect.o: $(NHS)rect.c $(HDEP) - -$(O)region.o: $(NHS)region.c $(HDEP) - -$(O)restore.o: $(NHS)restore.c $(HDEP) $(I)tcap.h $(I)quest.h - -$(O)rnd.o: $(NHS)rnd.c $(HDEP) - -$(O)role.o: $(NHS)role.c $(HDEP) - -$(O)rumors.o: $(NHS)rumors.c $(HDEP) $(I)dlb.h - -$(O)save.o: $(NHS)save.c $(HDEP) $(I)quest.h - -$(O)shk.o: $(NHS)shk.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)shk.c - -$(O)shknam.o: $(NHS)shknam.c $(HDEP) - -$(O)sit.o: $(NHS)sit.c $(HDEP) $(I)artifact.h - -$(O)sounds.o: $(NHS)sounds.c $(HDEP) - -$(O)sp_lev.o: $(NHS)sp_lev.c $(HDEP) $(I)sp_lev.h $(I)rect.h $(I)dlb.h - -$(O)spell.o: $(NHS)spell.c $(HDEP) - -$(O)steal.o: $(NHS)steal.c $(HDEP) - -$(O)steed.o: $(NHS)steed.c $(HDEP) - -$(O)sys.o: $(NHS)sys.c $(HDEP) - -$(O)teleport.o: $(NHS)teleport.c $(HDEP) - -$(O)timeout.o: $(NHS)timeout.c $(HDEP) - -$(O)topten.o: $(NHS)topten.c $(HDEP) $(I)dlb.h - -$(O)track.o: $(NHS)track.c $(HDEP) - -$(O)trap.o: $(NHS)trap.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)trap.c - -$(O)u_init.o: $(NHS)u_init.c $(HDEP) - -$(O)uhitm.o: $(NHS)uhitm.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)uhitm.c - -$(O)vault.o: $(NHS)vault.c $(HDEP) - -$(O)version.o: $(NHS)version.c $(HDEP) $(I)date.h $(I)patchlevel.h - -$(O)vision.o: $(NHS)vision.c $(HDEP) #$(I)vis_tab.h - -$(O)weapon.o: $(NHS)weapon.c $(HDEP) - -$(O)were.o: $(NHS)were.c $(HDEP) - -$(O)wield.o: $(NHS)wield.c $(HDEP) - -$(O)windows.o: $(NHS)windows.c $(HDEP) $(I)wintty.h - -$(O)wizard.o: $(NHS)wizard.c $(HDEP) - -$(O)worm.o: $(NHS)worm.c $(HDEP) - -$(O)worn.o: $(NHS)worn.c $(HDEP) - -$(O)write.o: $(NHS)write.c $(HDEP) - -$(O)zap.o: $(NHS)zap.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)zap.c - -$(O)getline.o: $(TTY)getline.c $(HDEP) $(I)wintty.h - -$(O)termcap.o: $(TTY)termcap.c $(HDEP) $(I)wintty.h $(I)tcap.h - -$(O)topl.o: $(TTY)topl.c $(HDEP) $(I)wintty.h $(I)tcap.h - -$(O)wintty.o: $(TTY)wintty.c $(HDEP) $(I)wintty.h $(I)tcap.h \ - $(I)date.h $(I)patchlevel.h - -$(O)amitty.o: $(AMI)amitty.c $(HDEP) - -$(O)amistack.o: $(AMI)amistack.c - $(CC) $(CFLAGS3) $(CSYM) $(OBJSPEC)$@ $(AMI)amistack.c - -$(O)rip.o: $(NHS)rip.c $(HDEP) - - -$(I)config.h: $(I)config1.h $(I)tradstdc.h $(I)global.h - -setdate $(I)config.h - -c:wait 2 - -# onames.h handled at onames.h target, pm.h - -$(I)decl.h: $(I)quest.h $(I)spell.h $(I)color.h $(I)obj.h $(I)you.h - -setdate $(I)decl.h - -c:wait 2 - -$(I)global.h: $(I)coord.h $(I)pcconf.h $(I)amiconf.h - -setdate $(I)global.h - -c:wait 2 - -$(I)hack.h: $(I)config.h $(I)context.h $(I)trap.h $(I)decl.h $(I)dungeon.h - $(I)monsym.h $(I)mkroom.h $(I)objclass.h $(I)flag.h $(I)rm.h - $(I)vision.h $(I)display.h $(I)wintype.h $(I)engrave.h - $(I)rect.h $(I)region.h $(I)sys.h - -setdate $(I)hack.h - -c:wait 2 - -$(I)permonst.h: $(I)monattk.h $(I)monflag.h $(I)align.h - -setdate $(I)permonst.h - -c:wait 2 - -$(I)you.h: $(I)align.h $(I)attrib.h $(I)monst.h $(I)mextra.h $(I)youprop.h $(I)skills.h - -setdate $(I)you.h - -c:wait 2 - -# pm.h handled at target - -$(I)youprop.h: $(I)prop.h $(I)permonst.h $(I)mondata.h - -setdate $(I)youprop.h - -c:wait 2 - -$(I)display.h: $(I)vision.h $(I)mondata.h - -setdate $(I)display.h - -c:wait 2 - -$(I)dungeon.h: $(I)align.h - -setdate $(I)dungeon.h - -c:wait 2 - -$(I)engrave.h: $(I)rect.h - -setdate $(I)engrave.h - -c:wait 2 - -$(I)mextra.h: $(I)align.h - -setdate $(I)mextra.h - -c:wait 2 - -$(I)mondata.h: $(I)align.h - -setdate $(I)mondata.h - -c:wait 2 - -$(I)monst.h: $(I)align.h $(I)mextra.h - -setdate $(I)monst.h - -c:wait 2 - -$(I)pcconf.h: $(I)micro.h $(I)system.h - -setdate $(I)pcconf.h - -c:wait 2 - -$(I)rm.h: $(I)align.h - -setdate $(I)rm.h - -c:wait 2 - - -#notes -# install keeps doing re-install because it keeps rebuilding lev_comp??? -# fixed(?) - deleted setdate diff --git a/outdated/sys/amiga/Makefile.ami b/outdated/sys/amiga/Makefile.ami deleted file mode 100644 index d07a6633b..000000000 --- a/outdated/sys/amiga/Makefile.ami +++ /dev/null @@ -1,1578 +0,0 @@ -# NetHack Makefile. -# Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1991,1992,1993,1996. -# NetHack may be freely redistributed. See license for details. - -### -### INTRODUCTION -### - -# This makefile is arranged for compiling for the Amiga with SAS/C 6.51 but -# can be configured for compiling with Manx C 5 or commercial DICE with -# simple changes. The appropriate changes are identified by #[compiler] -# where compiler is one of: SAS6, MANX, or DICE; the options in this -# makefile as should be set according to the compiler being used. (But see -# note 3 below.) - -# Note: When using the Manx compiler, an alternate make utility is -# required. The bundled Aztec make is just too damaged. - -# Note 2: The #SFD_xxx lines are used with mkdmake to generate a DMake- -# compatible makefile (DMakefile) from this file. Any line beginning with -# #SFD_INSTEAD replaces, in DMakefile, the following line from Makefile.ami. -# #SFD_BEGIN, #SFD_ELSE, and #SFD_END bracket multi-line sections for the two -# makefile formats. -# When changing this file, #SFD_INSTEAD lines will need to be inserted for -# the following cases: -# - Dependencies with different numbers of filenames (both > 1) on -# either side. The #SFD_INSTEAD line should immediately precede -# the line with the colon, and should contain a double colon "::" -# instead of a single colon. -# - Special command lists that override the default. A line containing -# "#SFD_INSTEAD #none" should precede such a rule. If the rule is -# more than one line long, precede it with "#SFD_BEGIN" and -# "#SFD_ELSE", and follow it with "#SFD_END". -# - Files not in the src, sys/amiga, sys/share, or win/tty directories -# that rely on the default ".c.o" rule. Following the dependency -# should be "#SFD_INSTEAD " with the filename inserted -# into the default rule where appropriate, then a line contianing -# "#none". -# In any SFD_BEGIN/ELSE/END block added, put a '##' before every line -# between the BEGIN and ELSE. Any line that's really a comment needs three -# '#'s, e.g. "### DICE comment". - -# Note 2A: Whenever an SFD line/block is added, the appropriate repeat count -# in mkdmake must be changed. (The repeat count "0" meaning "repeat -# until end of file" doesn't work as advertised.) - -# Note 3: mkdmake will automatically substitute DICE flags, etc. for SAS -# where appropriate. Since the makefile is already set up for SAS, -# the only people who end up having to make changes here are Manx -# users (or people who want to change the defaults). - -### -### DIRECTORY STRUCTURE -### - -NH = NH: -SBIN = $(NH)sbin/ -SLIB = $(NH)slib/ -NETHACK = $(NH)NetHack/ -HACKEXE = $(NH)HackExe/ -AMI = $(NH)sys/amiga/ -DAT = $(NH)dat/ -DOC = $(NH)doc/ -I = $(NH)include/ -SHARE = $(NH)sys/share/ -NHS = $(NH)src/ -TTY = $(NH)win/tty/ -WSHARE = $(NH)win/share/ -UTIL = $(NH)util/ -O = $(NH)obj/ -OO = $(NH)objo/ -# NB: O and OO MUST be different directories - -### -### INVOCATION -### - -#[SAS6] -#MAKE = smake -#[MANX] -#MAKE = make -#[DICE] -#MAKE = dmake - -# Startup makefile with: -# -#[SAS6] -#[MANX] -# $(MAKE) -f $(AMI)Makefile.ami -# $(MAKE) -f $(AMI)Makefile.ami install -# -#[DICE] -# $(MAKE) -f $(AMI)DMakefile -# $(MAKE) -f $(AMI)DMakefile install -# -# -# You may use following targets on $(MAKE) command lines: -# all do it all (default) -# link just create binary from object files -# obj just create common object files -# obja just create amiga object files -# objs just create shared object files -# clean deletes the object files -# spotless deletes the object files, main binary, and more -# -# Note: We do not build the Guidebook here since it needs tbl -# (See the file sys/unix/Makefile.doc for more information) - -#X# Precompiled header files: -#X# $(HDEP) should appear in any dependency list for an object file where -#X# we would want to make use of the precompiled version of $(I)hack.h, -#X# while $(CSYM) should appear in the C compiler command line that creates -#X# any such object file. (Changes made here should agree with the $(HDEP): -#X# target that appears later in this makefile.) -#X# - -#SFD_BEGIN -## -###[DICE] -### If we were compiling with DICE and wanted to use the symbol table -### pre-loading feature, we would uncomment these following two lines. -## -##HDEP = $(I)hack.sym -##CSYM = -H$(I)hack.sym=hack.h -## -#SFD_ELSE - -#[SAS5] -# If we were to use the precompiled header file feature in a newer version -# of SAS/C, we would comment out these following two lines. -# If we don't use precompiled header files, we uncomment it as well. - -HDEP = $(I)hack.h $(I)pm.h $(I)onames.h -CSYM = - -#[MANX] -# If we were compiling with Aztec, and wanted to use the symbol table -# pre-loading feature, we would uncomment these following two lines. - -#HDEP = Ram:hack.sym -#CSYM = +IRam:hack.sym - -#SFD_END - -#Pathname for uudecode program: -UUDEC = uudecode - -# Flex/Bison command assignments -- Useful only if you have flex/bison -FLEX = flex -BISON = bison -# FBFIL and FBLIB may be used, if required by your version of flex or bison, -# to specify additional files or libraries to be linked with -FBFIL = -FBLIB = #lib lib:compat.lib - -# If you're compiling this on a 1.3 system, you'll have to uncomment the -# following (for use with the ifchange script below). Also useful instead of -# "protect ifchange +s" -EXECUTE = execute - -# Headers we depend on -AMDEP = $(AMI)winproto.h $(AMI)winext.h $(AMI)windefs.h $(I)winami.h - -# Pathname for the C compiler being used. - -#SFD_BEGIN -## -###[DICE] -##CC = dcc -##ASM = das -## -#SFD_ELSE - -#[SAS6] -CC = sc -ASM = asm - -#[MANX] -#CC = cc - -#SFD_END - -# Compilation flags for selected C Compiler: -# $(CFLAGS) should appear before filename arguments of $(CC) command line. - -#SFD_BEGIN -## -###[DICE] -##CFLAGS = -c -I$(I) -mC -mD -ms -// -##CFLAGS2 = -##WBCFLAGS = -c -I$(I) -mC -mD -ms -// -##WBC2FLAGS = -DCLI -##SPLFLAGS = -DSPLIT -## -#SFD_ELSE - -#[SAS6] -# Note: make sure your CLI stack size is large (at least 50K) or lev_comp -# and makedefs may fail terribly - stack checking is disabled. -# -# **** WARNING **** GST support is not fool proof. You must make makedefs -# without a GST first so that the generated headers -# that are part of the GST can be made. -# -#GSTSRC=$(AMI)gst.c -# -#GSTHEAD=$(I)hack.h $(I)pm.h $(I)trap.h $(I)onames.h \ -# $(AMI)winami.p $(AMI)amidos.p $(AMI)amiwind.p -# -#GSTFILE=$(O)NetHack.gst -# undefine this to not compile with GSTs -#GST=gst=$(GSTFILE) -# -DEBUG=debug=symbol -CPU=cpu=68000 -#OPTFLAGS=opt opttime optpeep optgo optinl optsched optcomp=10 optdep=5 optrdep=5 #optalias +OPTTIME -OPTSIZE -CFLAGS = data=far nominc $(DEBUG) idir=$(I) $(CPU) nostkchk nover \ - codename=nhcode dataname=nhdata strmerge $(OPTFLAGS) $(TILES) $(SAVEDS) \ - afp $(ERRREXX) $(GST) -# for files that are too large for the standard flags: -CFLAGS2 = code=far strmerge $(SAVEDS) -WBCFLAGS = ignore=217,62 data=far ansi nminc code=far idir=$(I) $(CPU) afp \ - $(DEBUG) $(ERRREXX) define=AMIGA $(GST) -XXX = data=far ansi nminc idir=$(I) $(CPU) afp opt optinline optinlocal \ - optloop opttime -WBC2FLAGS = define=CLI -SPLFLAGS = define=SPLIT #dollarok -#for amistack.c -CFLAGS3 = data=near dataname=__MERGED nominc $(DEBUG) idir=$(I) $(CPU) nover nostkchk \ - codename=nhcode strmerge $(OPTFLAGS) $(TILES) $(SAVEDS) \ - afp $(ERRREXX) $(GST) - -#[MANX] -#CFLAGS = -i$(I) -mc -md -ms -pa -ps -bs -wo -qq -#WBCFLAGS = -mc -md -ms -pa -ps -bs -wo -qq -pp - -#SFD_END - -# Assembly flags: - -#SFD_BEGIN -## -###[DICE] -##AFLAGS = -##AOBJSPEC = -o -## -#SFD_ELSE - -#[SAS6] -AFLAGS = #what to put here? -AOBJSPEC = -o - -#SFD_END - -# Components of various link command lines: -# $(LINK) should be the pathname of the linker being used (with any options -# that should appear at the beginning of the command line). The name of the -# output file should appear immediately after $(LNSPEC). $(LIN) should -# appear before the list of object files in each link command. $(LLINK) -# should appear as the list of object files in the link command line that -# creates the NetHack executable. $(LLIB) should appear at the end of each -# link command line. - -# Note: amiga.lib added due to missing prototypes/pragmas. -# Should be deleted when this is resolved. - -#SFD_BEGIN -## -###[DICE] -### If you have flex/bison libraries, use the second definition of FLLIB -### instead of the first. -## -##LINK = dcc -mD -##LIN = -##LLINK = @$(AMI)ami.lnk -##LLIB = -##FLLIB = -###FLLIB = -l$(FBLIB) -##OBJSPEC = -o -##PNSPEC = -o -##LNSPEC = -o -##CCLINK = dcc -##CLFLAGS = -I$(I) -mC -mD -ms -// -##INCLSPEC = -I -##DEFSPEC = -D -##IGNSPEC = -j -## -#SFD_ELSE - -#[SAS6] - -LINK = slink noicons verbose maxhunk 262144 stripdebug -LIN = from lib:catch.o -LLINK = with $(AMI)ami.lnk -LLIB = lib lib:scnb.lib BATCH #lib lib:amiga.lib BATCH #scnb.lib or sc.lib -FLLIB = $(FBLIB) lib Lib:sc.lib BATCH -OBJSPEC = objname= -PNSPEC = noicons to #pname= -LNSPEC = to -CCLINK = sc link -INCLSPEC = idir= -DEFSPEC = define= -IGNSPEC = ignore= -COMPACT_HEADERS=$(GSTFILE) - -#[MANX] - -#LINK = ln -g +q +ss -o -#LIN = -#LLINK = -f $(AMI)ami.lnk -#LLIB = -lcl16 -#FLLIB = -lcl16 -#OBJSPEC = -o -#PNSPEC = -o -#LNSPEC = -o -#CCLINK = cc -#INCLSPEC = -i -#DEFSPEC = -d -#IGNSPEC = -j - -#SFD_END - -### -### FILE LISTS -### - -# A more reasonable random number generator (recommended for the Amiga): - -RANDOBJ = $(O)random.o - -#SFD_INSTEAD #none -.PRECIOUS: $(I)config.h $(I)decl.h $(I)hack.h $(I)permonst.h $(I)you.h - -# Almost nothing below this line should have to be changed. -# (Exceptions are marked by [SAS6], [MANX], etc.) -# -# Other things that have to be reconfigured are in config.h, -# (amiconf.h, pcconf.h), and possibly system.h, tradstdc.h. - -# Object files for makedefs: - -MAKEOBJS = \ - $(OO)makedefs.o $(O)monst.o $(O)objects.o - -# Object files for special levels compiler: - -SPLEVOBJS = \ - $(OO)lev_yacc.o $(OO)lev_lex.o $(OO)lev_main.o \ - $(O)decl.o $(O)drawing.o $(O)monst.o \ - $(O)objects.o $(OO)panic.o - -# Object files for dungeon compiler - -DGNCOMPOBJS = \ - $(OO)dgn_yacc.o $(OO)dgn_lex.o $(OO)dgn_main.o $(O)alloc.o $(OO)panic.o - -# Object files for NetHack: - -COMMOBJ = \ - $(O)allmain.o $(O)alloc.o $(O)apply.o $(O)artifact.o \ - $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o \ - $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o \ - $(O)dig.o $(O)display.o $(O)dlb.o $(O)do.o \ - $(O)do_name.o $(O)do_wear.o $(O)dog.o $(O)dogmove.o \ - $(O)dokick.o $(O)dothrow.o $(O)drawing.o $(O)dungeon.o \ - $(O)eat.o $(O)end.o $(O)engrave.o $(O)exper.o \ - $(O)explode.o $(O)extralev.o $(O)files.o $(O)fountain.o \ - $(O)hack.o $(O)hacklib.o $(O)invent.o $(O)light.o \ - $(O)lock.o $(O)mail.o $(O)makemon.o $(O)mapglyph.o \ - $(O)mcastu.o $(O)mhitm.o $(O)mhitu.o $(O)minion.o \ - $(O)mklev.o $(O)mkmap.o $(O)mkmaze.o $(O)mkobj.o \ - $(O)mkroom.o $(O)mon.o $(O)mondata.o $(O)monmove.o \ - $(O)monst.o $(O)mplayer.o $(O)mthrowu.o $(O)muse.o \ - $(O)music.o $(O)o_init.o $(O)objects.o $(O)objnam.o \ - $(O)options.o $(O)pager.o $(O)pickup.o $(O)pline.o \ - $(O)polyself.o $(O)potion.o $(O)pray.o $(O)priest.o \ - $(O)quest.o $(O)questpgr.o $(O)read.o $(O)rect.o \ - $(O)region.o $(O)restore.o $(O)rnd.o $(O)role.o \ - $(O)rumors.o $(O)save.o $(O)shk.o $(O)shknam.o \ - $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o \ - $(O)steal.o $(O)steed.o $(O)sys.o $(O)teleport.o \ - $(O)timeout.o $(O)topten.o $(O)track.o $(O)trap.o \ - $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)version.o \ - (O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o \ - $(O)windows.o $(O)wizard.o $(O)worm.o $(O)worn.o \ - $(O)write.o $(O)zap.o - -MAKEDEFOBJ = \ - $(O)monstr.o - -AMIGAOBJ = \ - $(O)amidos.o $(O)amirip.o $(O)amistack.o \ - $(O)amiwind.o $(O)winami.o $(O)winchar.o $(O)winfuncs.o \ - $(O)winkey.o $(O)winamenu.o $(O)winreq.o $(O)winstr.o - -# Objects from assembly sources (because DMake can't handle default rules) -AMIGAOBJ2 = \ -# $(O)dispmap.o - -SHAREOBJ = \ - $(O)pcmain.o $(RANDOBJ) - -TTYOBJ = \ - $(O)getline.o $(O)termcap.o $(O)topl.o $(O)wintty.o $(O)amitty.o \ - $(O)rip.o - -# Yuck yuck yuck. Have to tell DMake where these are, since they're not -# all in the same place. -TTYSRC = \ - $(TTY)getline.c $(TTY)termcap.c $(TTY)topl.c $(TTY)wintty.c \ - $(AMI)amitty.c $(NHS)rip.c - -# All the object files for NetHack: - -HOBJ = $(COMMOBJ) $(AMIGAOBJ) $(AMIGAOBJ2) $(SHAREOBJ) $(MAKEDEFOBJ) $(TTYOBJ) - -### -### DATA FILES -### - -# quest files -ADFILES1= $(SLIB)Arc-fila.lev $(SLIB)Arc-filb.lev $(SLIB)Arc-loca.lev \ - $(SLIB)Arc-strt.lev -ADFILES= $(SLIB)Arc-goal.lev $(ADFILES1) - -BDFILES1= $(SLIB)Bar-fila.lev $(SLIB)Bar-filb.lev $(SLIB)Bar-loca.lev \ - $(SLIB)Bar-strt.lev -BDFILES= $(SLIB)Bar-goal.lev $(BDFILES1) - -CDFILES1= $(SLIB)Cav-fila.lev $(SLIB)Cav-filb.lev $(SLIB)Cav-loca.lev \ - $(SLIB)Cav-strt.lev -CDFILES= $(SLIB)Cav-goal.lev $(CDFILES1) - -HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \ - $(SLIB)Hea-strt.lev -HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1) - -KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \ - $(SLIB)Kni-strt.lev -KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1) - -MDFILES1= $(SLIB)Mon-fila.lev $(SLIB)Mon-filb.lev $(SLIB)Mon-loca.lev \ - $(SLIB)Mon-strt.lev -MDFILES= $(SLIB)Mon-goal.lev $(MDFILES1) - -PDFILES1= $(SLIB)Pri-fila.lev $(SLIB)Pri-filb.lev $(SLIB)Pri-loca.lev \ - $(SLIB)Pri-strt.lev -PDFILES= $(SLIB)Pri-goal.lev $(PDFILES1) - -RDFILES1= $(SLIB)Rog-fila.lev $(SLIB)Rog-filb.lev $(SLIB)Rog-loca.lev \ - $(SLIB)Rog-strt.lev -RDFILES= $(SLIB)Rog-goal.lev $(RDFILES1) - -RANFILES1= $(SLIB)Ran-fila.lev $(SLIB)Ran-filb.lev $(SLIB)Ran-loca.lev \ - $(SLIB)Ran-strt.lev -RANFILES= $(SLIB)Ran-goal.lev $(RANFILES1) - -SDFILES1= $(SLIB)Sam-fila.lev $(SLIB)Sam-filb.lev $(SLIB)Sam-loca.lev \ - $(SLIB)Sam-strt.lev -SDFILES= $(SLIB)Sam-goal.lev $(SDFILES1) - -TDFILES1= $(SLIB)Tou-fila.lev $(SLIB)Tou-filb.lev $(SLIB)Tou-loca.lev \ - $(SLIB)Tou-strt.lev -TDFILES= $(SLIB)Tou-goal.lev $(TDFILES1) - -VDFILES1= $(SLIB)Val-fila.lev $(SLIB)Val-filb.lev $(SLIB)Val-loca.lev \ - $(SLIB)Val-strt.lev -VDFILES= $(SLIB)Val-goal.lev $(VDFILES1) - -WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \ - $(SLIB)Wiz-strt.lev -WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1) - -XDFILES= $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \ - $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \ - $(VDFILES) $(WDFILES) - -TILEFILES= \ - $(SBIN)txt2iff \ - $(NETHACK)tiles \ - $(NETHACK)tiles/objects.iff \ - $(NETHACK)tiles/monsters.iff \ - $(NETHACK)tiles/other.iff - -INSTDUNGEONFILES1= \ - $(SLIB)air.lev $(SLIB)asmodeus.lev $(SLIB)astral.lev \ - $(SLIB)baalz.lev $(SLIB)bigrm-1.lev $(SLIB)bigrm-2.lev \ - $(SLIB)bigrm-3.lev $(SLIB)bigrm-4.lev $(SLIB)bigrm-5.lev \ - $(SLIB)castle.lev $(SLIB)dungeon $(SLIB)earth.lev \ - $(SLIB)fakewiz1.lev $(SLIB)fakewiz2.lev $(SLIB)fire.lev \ - $(SLIB)juiblex.lev $(SLIB)knox.lev $(SLIB)medusa-1.lev \ - $(SLIB)medusa-2.lev $(SLIB)minend-1.lev $(SLIB)minend-2.lev \ - $(SLIB)minetn-1.lev $(SLIB)minetn-2.lev $(SLIB)minefill.lev \ - $(SLIB)options $(SLIB)oracle.lev $(SLIB)orcus.lev \ - $(SLIB)sanctum.lev $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev \ - $(SLIB)soko2-1.lev $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev \ - $(SLIB)soko3-2.lev $(SLIB)soko4-1.lev $(SLIB)soko4-2.lev \ - $(SLIB)tower1.lev $(SLIB)tower2.lev $(SLIB)tower3.lev \ - $(SLIB)valley.lev $(SLIB)water.lev $(SLIB)wizard1.lev \ - $(SLIB)wizard2.lev $(SLIB)wizard3.lev \ - $(XDFILES) - -INSTDUNGEONFILES= $(NETHACK)NetHack.cnf $(INSTDUNGEONFILES1) - - -INSTDATAFILES= \ - $(NETHACK)license $(NETHACK)logfile $(NETHACK)record \ - $(NETHACK)tomb.iff $(NETHACK)amii.hlp $(NETHACK)Recover.txt \ - $(NETHACK)GuideBook.txt $(NETHACK)NetHack.txt $(NETHACK)Install.ami - -LIBFILES= \ - $(INSTDUNGEONFILES1) \ - $(SLIB)cmdhelp $(SLIB)data $(SLIB)dungeon \ - $(SLIB)help $(SLIB)hh $(SLIB)history \ - $(SLIB)opthelp $(SLIB)oracles $(SLIB)rumors \ - $(SLIB)quest.dat $(SLIB)wizhelp - -### -### Getting down to business: -### - -#SFD_INSTEAD all: $(SBIN)lev_comp $(SBIN)dgn_comp $(SBIN)NetHack \ -all: $(COMPACT_HEADERS) $(SBIN)lev_comp $(SBIN)dgn_comp $(SBIN)NetHack \ - $(SBIN)dlb $(NETHACK)recover - -install: all inst-data inst-dungeon inst-fonts inst-tiles \ - $(NETHACK)nhdat $(NETHACK)NetHack - -$(SBIN)NetHack: $(HOBJ) $(AMI)ami.lnk - $(LINK) $(LNSPEC) $(SBIN)NetHack $(LIN) $(LLINK) $(LLIB) - -$(NETHACK)NetHack: $(SBIN)NetHack - copy $(SBIN)NetHack $(NETHACK)NetHack - -link: - $(LINK) $(LNSPEC) $(SBIN)NetHack $(LIN) $(LLINK) $(LLIB) - -$(AMI)ami.lnk: $(AMI)Makefile.ami - list to $(AMI)ami.lnk lformat="$(O)%s" $(O)\#?.o QUICK NOHEAD - -## dlb support -$(OO)dlb_main.o: $(UTIL)dlb_main.c $(HDEP) $(I)dlb.h $(I)date.h - $(CC) $(CFLAGS) $(OBJSPEC)$(OO)dlb_main.o $(UTIL)dlb_main.c - -$(SBIN)dlb: $(OO)dlb_main.o $(O)dlb.o $(O)alloc.o $(OO)panic.o - $(LINK) $(PNSPEC) $(SBIN)dlb $(LIN) $(OO)dlb_main.o $(O)dlb.o \ - $(O)alloc.o $(OO)panic.o $(LLIB) - -obj: $(HOBJ) - -obja: $(AMIGAOBJ) - -objs: $(SHAREOBJ) - - -#SFD_BEGIN -#SFD_ELSE -SUFFIXES = .lev .des -.des.lev: - $(SBIN)lev_comp $< -#SFD_END - - -# The default method for creating object files: - -#SFD_BEGIN -## -###[DICE] -## -##$(COMMOBJ): $(COMMOBJ:"$(O)*.o":"$(NHS)%1.c") -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)%(left) %(right) -## -##$(AMIGAOBJ): $(AMIGAOBJ:"$(O)*.o":"$(AMI)%1.c") -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)%(left) %(right) -## -##$(SHAREOBJ): $(SHAREOBJ:"$(O)*.o":"$(SHARE)%1.c") -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)%(left) %(right) -## -##$(TTYOBJ): $(TTYSRC) -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)%(left) %(right) -## -#SFD_ELSE - -#[SAS6] - -.c.o: - $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)$@ $< - -#SFD_END - - -clean: - -delete $(O)\#?.o $(OO)\#?.o - -spotless: clean - -delete $(SBIN)NetHack $(SBIN)lev_comp $(SBIN)makedefs $(SBIN)dgn_comp - -delete $(SBIN)dlb $(SBIN)txt2iff $(SBIN)splitter - -delete $(SBIN)tilemap - -delete $(SLIB)data $(SLIB)rumors - -delete $(SLIB)\#?.lev - -delete $(SLIB)dungeon - -delete $(SLIB)cmdhelp $(SLIB)help $(SLIB)hh $(SLIB)history - -delete $(SLIB)opthelp $(SLIB)options $(SLIB)oracles - -delete $(SLIB)quest.dat $(SLIB)wizhelp -# -delete $(SLIB)earth.lev $(SLIB)air.lev $(SLIB)fire.lev -# -delete $(SLIB)water.lev $(SLIB)astral.lev -# -delete $(SLIB)tower1.lev $(SLIB)tower2.lev $(SLIB)tower3.lev -# -delete $(SLIB)fakewiz1.lev $(SLIB)fakewiz2.lev -# -delete $(SLIB)medusa-1.lev $(SLIB)medusa-2.lev -# -delete $(SLIB)oracle.lev $(SLIB)wizard1.lev $(SLIB)wizard2.lev -# -delete $(SLIB)wizard3.lev $(DAT)dungeon.pdf $(SLIB)valley.lev -# -delete $(SLIB)minefill.lev -# -delete $(SLIB)minetn-1 $(SLIB)minetn-2 $(SLIB)minend-1 $(SLIB)minend-2 -# -delete $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev $(SLIB)soko2-1.lev -# -delete $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev $(SLIB)soko3-2.lev -# -delete $(SLIB)soko4-1.lev $(SLIB)soko4-2.lev -# -delete $(ADFILES) -# -delete $(BDFILES) -# -delete $(CDFILES) -# -delete $(HDFILES) -# -delete $(KDFILES) -# -delete $(MDFILES) -# -delete $(PDFILES) -# -delete $(RDFILES) -# -delete $(RANFILES) -# -delete $(SDFILES) -# -delete $(TDFILES) -# -delete $(VDFILES) -# -delete $(WDFILES) - -delete $(I)onames.h $(I)pm.h $(I)date.h - -delete $(NHS)tile.c $(NHS)monstr.c - -delete $(I)tile.h -# -echo to $(I)onames.h "" noline -# -wait 2 -# -echo to $(I)pm.h "" noline -# -wait 2 -# -setdate $(UTIL)makedefs.c -# -wait 2 - -# Creating precompiled version of $(I)hack.h to save disk I/O. - -#SFD_BEGIN -## -###[DICE] -### If we were compiling with DICE and wanted to use the symbol table -### pre-loading feature, we would technically not need a rule to make the -### precompiled header file, because DCC handles this automatically; -### however, we must delete the precompiled header file if any of the -### includes change, and we need to create it manually because the -### sys/amiga sources, compiled first, define things differently than the -### main sources want them. -## -##$(HDEP): $(I)hack.h $(I)pm.h $(I)onames.h -## -delete $(I)hack.sym -## echo to Ram:hackincl.c "#include " -## $(CC) $(CFLAGS) $(CSYM) $(OBJSPEC)Ram:hackincl.o Ram:hackincl.c -## -delete Ram:hackincl.c Ram:hackincl.o -## -#SFD_ELSE - -#X#[SAS5] -#X# If we were to use the precompiled header file feature of SAS/C, we -#X# would uncomment the following lines. (Also see defines for HDEP and -#X# CSYM near the beginning of this file, as these should be appropriately -#X# defined.) - -#X#$(HDEP): $(I)hack.h $(SBIN)makedefs -#X# echo to Ram:hackincl.c "#include <$(I)hack.h>" -#X# $(CC) $(CFLAGS) -ph $(OBJSPEC)$@ Ram:hackincl.c -#X# -delete Ram:hackincl.c - -#[MANX] -# If we were compiling with Aztec, and wanted to use the symbol table -# pre-loading feature, we would uncomment these following two lines. - -#$(HDEP): $(I)hack.h $(SBIN)makedefs -# $(CC) $(CFLAGS) -a $(OBJSPEC)Ram:hack.asm +h$@ $(I)hack.h -# -delete Ram:hack.asm - -#SFD_END - -# -# Please note: The dependency lines for the modules here are -# deliberately incorrect. Including "hack.h" in -# the dependency list would cause a dependency -# loop. -# - -$(SBIN)makedefs: $(MAKEOBJS) - $(LINK) $(LNSPEC) $(SBIN)makedefs $(LIN) $(MAKEOBJS) $(LLIB) - -$(OO)makedefs.o: $(UTIL)makedefs.c $(I)config.h $(I)permonst.h $(I)monsym.h \ - $(I)objclass.h $(I)patchlevel.h $(I)artilist.h - $(CC) $(DEFSPEC)MAKEDEFS_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)makedefs.c - -$(SBIN)lev_comp: $(SPLEVOBJS) - $(LINK) $(LNSPEC) $(SBIN)lev_comp $(LIN) $(SPLEVOBJS) $(FBFIL) $(FLLIB) - -$(SBIN)dgn_comp: $(DGNCOMPOBJS) - $(LINK) $(LNSPEC) $(SBIN)dgn_comp $(LIN) $(DGNCOMPOBJS) $(FBFIL) $(FLLIB) - -$(OO)lev_yacc.o: $(UTIL)lev_yacc.c $(HDEP) $(I)sp_lev.h $(I)pm.h $(I)onames.h -# setdate $(UTIL)lev_yacc.c - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)PREFIX="NH:slib/" $(CFLAGS) \ - $(DEFSPEC)alloca=malloc $(OBJSPEC)$@ $(UTIL)lev_yacc.c - -$(OO)lev_lex.o: $(UTIL)lev_lex.c $(HDEP) $(I)lev_comp.h $(I)sp_lev.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)lev_lex.c - -$(OO)lev_main.o: $(UTIL)lev_main.c $(HDEP) $(I)pm.h $(I)onames.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)lev_main.c - -$(OO)dgn_yacc.o: $(UTIL)dgn_yacc.c $(HDEP) $(I)dgn_file.h $(I)patchlevel.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(DEFSPEC)alloca=malloc \ - $(OBJSPEC)$@ $(UTIL)dgn_yacc.c - -$(OO)dgn_lex.o: $(UTIL)dgn_lex.c $(I)config.h $(I)dgn_comp.h $(I)dgn_file.h - $(CC) $(DEFSPEC)LEV_LEX_C $(CFLAGS) $(OBJSPEC)$@ $(UTIL)dgn_lex.c - -$(OO)dgn_main.o: $(UTIL)dgn_main.c $(I)config.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)dgn_main.c - -$(OO)panic.o: $(UTIL)panic.c $(HDEP) -#SFD_INSTEAD $(CC) $(CFLAGS) $(OBJSPEC)%(left) $(UTIL)panic.c -#none - -$(OO)recover.o: $(UTIL)recover.c $(I)config.h $(I)date.h - $(CC) $(DEFSPEC)LEV_LEX_C $(DEFSPEC)AMIGA $(CFLAGS) $(OBJSPEC)$@ \ - $(UTIL)recover.c - -$(NETHACK)recover: $(OO)recover.o - $(LINK) $(LNSPEC) $(NETHACK)recover $(LIN) $(OO)recover.o $(LLIB) - -# [OPTION] -- If you have flex/bison, leave these uncommented. Otherwise, -# comment them out and be careful! (You're not guaranteed to have the most -# up to date *_comp.c, *_comp.h and *_lex.c) - -$(I)lev_comp.h: $(UTIL)lev_yacc.c $(I)patchlevel.h - -$(UTIL)lev_yacc.c: $(UTIL)lev_comp.y $(I)patchlevel.h - $(BISON) -d $(UTIL)lev_comp.y -# copy y.tab.c $(UTIL)lev_yacc.c -# copy y.tab.h $(I)lev_comp.h - copy $(UTIL)lev_comp.tab.c $(UTIL)lev_yacc.c - copy $(UTIL)lev_comp.tab.h $(I)lev_comp.h -# delete y.tab.c -# delete y.tab.h - delete $(UTIL)lev_comp.tab.c - delete $(UTIL)lev_comp.tab.h - -$(UTIL)lev_lex.c: $(UTIL)lev_comp.l $(I)patchlevel.h - $(FLEX) $(UTIL)lev_comp.l - copy lex.yy.c $(UTIL)lev_lex.c - delete lex.yy.c - -$(I)dgn_comp.h: $(UTIL)dgn_yacc.c $(I)patchlevel.h - -$(UTIL)dgn_yacc.c: $(UTIL)dgn_comp.y $(I)patchlevel.h - $(BISON) -d $(UTIL)dgn_comp.y -# copy y.tab.c $(UTIL)dgn_yacc.c -# copy y.tab.h $(I)dgn_comp.h - copy $(UTIL)dgn_comp.tab.c $(UTIL)dgn_yacc.c - copy $(UTIL)dgn_comp.tab.h $(I)dgn_comp.h -# delete y.tab.c -# delete y.tab.h - delete $(UTIL)dgn_comp.tab.c - delete $(UTIL)dgn_comp.tab.h - -$(UTIL)dgn_lex.c: $(UTIL)dgn_comp.l $(I)patchlevel.h - $(FLEX) $(UTIL)dgn_comp.l - copy lex.yy.c $(UTIL)dgn_lex.c - delete lex.yy.c - -# -# The following include files depend on makedefs to be created. -# As a result, they are not defined in HACKINCL, instead, their -# dependencies are explicitly outlined here. -# - -# -# date.h should be remade any time any of the source or include code -# is modified. Unfortunately, this would make the contents of this -# file far more complex. Since "hack.h" depends on most of the include -# files, we kludge around this by making date.h dependent on hack.h, -# even though it doesn't include this file. -# - -#SFD_INSTEAD $(I)date.h $(DAT)options:: $(HDEP) $(SBIN)makedefs $(AMIGAOBJ) -$(I)date.h $(DAT)options: $(HDEP) $(SBIN)makedefs $(AMIGAOBJ) $(I)patchlevel.h - $(SBIN)makedefs -v - $(EXECUTE) $(AMI)ifchange MOVE $(I)t.date.h $(I)date.h - -wait 2 - -$(I)onames.h: $(SBIN)makedefs - $(SBIN)makedefs -o - $(EXECUTE) $(AMI)ifchange TOUCH $(I)t.onames.h $(I)onames.h $(I)decl.h - $(EXECUTE) $(AMI)ifchange MOVE $(I)t.onames.h $(I)onames.h - -wait 2 - -$(I)pm.h: $(SBIN)makedefs - $(SBIN)makedefs -p - $(EXECUTE) $(AMI)ifchange TOUCH $(I)t.pm.h $(I)pm.h $(I)decl.h $(I)youprop.h - $(EXECUTE) $(AMI)ifchange MOVE $(I)t.pm.h $(I)pm.h - -wait 2 - -$(SLIB)quest.dat: $(DAT)quest.txt $(SBIN)makedefs - $(SBIN)makedefs -q - -$(NHS)monstr.c: $(HDEP) $(SBIN)makedefs - $(SBIN)makedefs -m - -wait 2 - -$(SLIB)oracles: $(DAT)oracles.txt $(SBIN)makedefs - $(SBIN)makedefs -h - -wait 2 - -# -# The following programs vary depending on what OS you are using. -# As a result, they are not defined in HACKSRC and their dependencies -# are explicitly outlined here. -# - -$(O)amidos.o: $(AMI)amidos.c $(HDEP) - -$(O)amirip.o: $(AMI)amirip.c $(HDEP) - -$(O)aglue.o: $(AMI)aglue.a - $(ASM) $(AFLAGS) $(AOBJSPEC)$(O)aglue.o $(AMI)aglue.a - -$(O)winchar.o: $(AMI)winchar.c $(NHS)tile.c $(HDEP) - -$(NHS)tile.c: $(WSHARE)tilemap.c -#SFD_INSTEAD $(CCLINK) $(CLFLAGS) $(PNSPEC) $(SBIN)tilemap $(WSHARE)tilemap.c - $(CCLINK) $(CFLAGS) $(PNSPEC) $(SBIN)tilemap $(WSHARE)tilemap.c - $(SBIN)tilemap - -$(O)winstr.o: $(AMI)winstr.c $(HDEP) $(AMDEP) - -$(O)winreq.o: $(AMI)winreq.c $(HDEP) $(AMDEP) $(AMI)colorwin.c $(AMI)clipwin.c - -$(O)winfuncs.o: $(AMI)winfuncs.c $(HDEP) $(AMDEP) $(I)patchlevel.h - -$(O)winkey.o: $(AMI)winkey.c $(HDEP) $(AMDEP) - -$(O)winamenu.o: $(AMI)winamenu.c $(HDEP) $(AMDEP) - -$(O)winami.o: $(AMI)winami.c $(HDEP) $(AMDEP) #$(AMI)char.c $(AMI)randwin.c - -#$(O)amilib.o: $(AMI)amilib.c $(HDEP) $(AMDEP) - -$(O)amiwind.o: $(AMI)amiwind.c $(AMI)amimenu.c $(HDEP) $(AMDEP) - -$(O)amiwbench.o: $(AMI)amiwbench.c $(HDEP) - -$(O)random.o: $(SHARE)random.c - -$(O)pcmain.o: $(SHARE)pcmain.c $(HDEP) $(I)dlb.h - -$(O)dispmap.o: $(AMI)dispmap.s - $(ASM) $(AFLAGS) $(AOBJSPEC)$@ $< - -# Stuff to build the front ends -$(NETHACK)HackWB: $(OO)wb.o $(OO)wbx.o $(OO)loader.o $(OO)multi.o - $(LINK) $(LNSPEC) $(NETHACK)HackWB $(LIN) $(OO)wb.o $(OO)wbx.o \ - $(OO)loader.o $(OO)multi.o $(LLIB) - -$(NETHACK)HackCli: $(OO)cli.o $(OO)loader.o $(OO)multi.o - $(LINK) $(LNSPEC) $(NETHACK)HackCli $(LIN) $(OO)cli.o $(OO)loader.o \ - $(OO)multi.o $(LLIB) - -# This needs to exist to eliminate the HackWB startup message -#SFD_INSTEAD $(NETHACK)WBDefaults.def: $(NETHACK)WBDefaults.def -$(NETHACK)WBDefaults.def: - echo to $(NETHACK)WBDefaults.def - -WBH = $(AMI)wbdefs.h $(AMI)wbstruct.h $(AMI)wbprotos.h -ASP = $(AMI)splitter -$(OO)wb.o: $(WBH) $(AMI)wb.c $(AMI)wbwin.c $(AMI)wbdata.c $(AMI)wbgads.c \ - $(I)patchlevel.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)wb.o $(AMI)wb.c - -$(OO)wbx.o: $(WBH) $(AMI)wbcli.c $(AMI)wbwin.c $(AMI)wbdata.c \ - $(I)patchlevel.h $(I)date.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)wbx.o $(AMI)wbcli.c - -$(OO)loader.o: $(ASP)/loader.c $(ASP)/split.h $(ASP)/amiout.h $(ASP)/multi.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)loader.o $(ASP)/loader.c - -$(OO)multi.o: $(ASP)/multi.c $(ASP)/multi.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)multi.o $(ASP)/multi.c - -$(OO)cli.o: $(WBH) $(AMI)wbcli.c $(I)patchlevel.h $(I)date.h - $(CC) $(WBCFLAGS) $(WBC2FLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)cli.o \ - $(AMI)wbcli.c - -#### -# splitter support -$(SBIN)splitter: $(OO)splitter.o $(OO)arg.o - $(LINK) $(LNSPEC) $(SBIN)splitter $(LIN) $(OO)splitter.o $(OO)arg.o \ - $(LLIB) - -$(NETHACK)NetHack.dir: $(SBIN)splitter $(SBIN)NetHack - $(SBIN)splitter $(SBIN)NetHack - -$(OO)splitter.o: $(ASP)/splitter.c $(ASP)/split.h $(ASP)/amiout.h $(ASP)/arg.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)splitter.o \ - $(ASP)/splitter.c - -$(OO)arg.o: $(ASP)/arg.c $(ASP)/arg.h - $(CC) $(WBCFLAGS) $(SPLFLAGS) $(OBJSPEC)$(OO)arg.o $(ASP)/arg.c - -# Create/copy other stuff into NetHack: directory: - -$(NETHACK)tomb.iff: $(SBIN)xpm2iff $(AMI)grave16.xpm - $(SBIN)xpm2iff $(AMI)grave16.xpm $(NETHACK)tomb.iff - -$(OO)xpm2iff.o: $(AMI)xpm2iff.c - $(CC) $(CFLAGS) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(AMI)xpm2iff.c - -$(SBIN)xpm2iff: $(OO)xpm2iff.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)xpm2iff.o $(FLLIB) - -# Tile installation for the tile version of the game -inst-tiles: $(TILEFILES) - -#SFD_INSTEAD $(NETHACK)tiles: $(NETHACK)tiles -$(NETHACK)tiles: - -makedir $(NETHACK)tiles - -$(OO)txt2iff.o: $(AMI)txt2iff.c - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ \ - $(AMI)txt2iff.c - -$(OO)ppmwrite.o: $(WSHARE)ppmwrite.c - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)ppmwrite.c - -$(OO)tiletext.o: $(WSHARE)tiletext.c $(I)config.h $(WSHARE)tile.h - $(CC) $(CFLAGS) $(CSYM) $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)tiletext.c - -$(OO)tiletxt.o: $(WSHARE)tilemap.c $(I)hack.h - $(CC) $(CFLAGS) $(CSYM) $(DEFSPEC)TILETEXT $(INCLSPEC)$(WSHARE) $(OBJSPEC)$@ $(WSHARE)tilemap.c - -NAMEOBJS = $(O)drawing.o $(O)decl.o $(O)monst.o $(O)objects.o - -$(SBIN)txt2ppm: $(OO)ppmwrite.o $(NAMEOBJS) $(O)alloc.o $(OO)panic.o $(OO)tiletext.o $(OO)tiletxt.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)ppmwrite.o $(NAMEOBJS) $(OO)tiletext.o $(OO)tiletxt.o $(O)alloc.o $(OO)panic.o $(FLLIB) - -$(SBIN)txt2iff: $(OO)txt2iff.o $(NAMEOBJS) $(OO)tiletext.o $(OO)tiletxt.o - $(LINK) $(LNSPEC) $@ $(LIN) $(OO)txt2iff.o $(NAMEOBJS) $(OO)tiletext.o \ - $(OO)tiletxt.o $(FLLIB) - -$(NETHACK)tiles/objects.iff: $(WSHARE)objects.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)objects.txt $(NETHACK)tiles/objects.iff - -$(NETHACK)tiles/monsters.iff: $(WSHARE)monsters.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)monsters.txt $(NETHACK)tiles/monsters.iff - -$(NETHACK)tiles/other.iff: $(WSHARE)other.txt $(SBIN)txt2iff - $(SBIN)txt2iff $(WSHARE)other.txt $(NETHACK)tiles/other.iff - -inst-dungeon: $(INSTDUNGEONFILES) - -$(NETHACK)options : $(DAT)options - copy $(DAT)options $@ - -# Create compiled dungeon files -BGM= $(SLIB)bigrm-2.lev $(SLIB)bigrm-3.lev $(SLIB)bigrm-4.lev $(SLIB)bigrm-5.lev -$(BGM): $(SLIB)bigrm-1.lev - -$(SLIB)bigrm-1.lev: $(DAT)bigroom.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)bigroom.des -#none - -$(SLIB)castle.lev: $(DAT)castle.des $(SBIN)lev_comp - -ENDGAME1= $(SLIB)air.lev $(SLIB)earth.lev $(SLIB)fire.lev $(SLIB)water.lev -$(ENDGAME1): $(SLIB)astral.lev - -$(SLIB)astral.lev: $(DAT)endgame.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)endgame.des -#none - -GEHENNOM1= $(SLIB)asmodeus.lev $(SLIB)baalz.lev $(SLIB)juiblex.lev \ - $(SLIB)orcus.lev $(SLIB)sanctum.lev -$(GEHENNOM1): $(SLIB)valley.lev - -$(SLIB)valley.lev: $(DAT)gehennom.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)gehennom.des -#none - -$(SLIB)knox.lev: $(DAT)knox.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)knox.des -#none - -MINES1= $(SLIB)minend-1.lev $(SLIB)minend-2.lev $(SLIB)minetn-1.lev $(SLIB)minetn-2.lev -$(MINES1): $(SLIB)minefill.lev - -$(SLIB)minefill.lev: $(DAT)mines.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)mines.des -#none - -$(SLIB)oracle.lev: $(DAT)oracle.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)oracle.des -#none - -TOWER1= $(SLIB)tower1.lev $(SLIB)tower2.lev -$(TOWER1): $(SLIB)tower3.lev - -$(SLIB)tower3.lev: $(DAT)tower.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)tower.des -#none - -WIZARD1= $(SLIB)wizard1.lev $(SLIB)wizard2.lev $(SLIB)wizard3.lev \ - $(SLIB)fakewiz1.lev -$(WIZARD1): $(SLIB)fakewiz2.lev - -$(SLIB)fakewiz2.lev: $(DAT)yendor.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)yendor.des -#none - -MEDUSA1= $(SLIB)medusa-1.lev -$(MEDUSA1): $(SLIB)medusa-2.lev - -$(SLIB)medusa-2.lev: $(DAT)medusa.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)medusa.des -#none - -SOKOBAN1= $(SLIB)soko1-1.lev $(SLIB)soko1-2.lev $(SLIB)soko2-1.lev \ - $(SLIB)soko2-2.lev $(SLIB)soko3-1.lev $(SLIB)soko3-2.lev \ - $(SLIB)soko4-1.lev -$(SOKOBAN1): $(SLIB)soko4-2.lev - -$(SLIB)soko4-2.lev: $(DAT)sokoban.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)sokoban.des -#none - -$(ADFILES1): $(SLIB)Arc-goal.lev - -$(SLIB)Arc-goal.lev: $(DAT)Arch.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Arch.des -#none - -$(BDFILES1): $(SLIB)Bar-goal.lev - -$(SLIB)Bar-goal.lev: $(DAT)Barb.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Barb.des -#none - -$(CDFILES1): $(SLIB)Cav-goal.lev - -$(SLIB)Cav-goal.lev: $(DAT)Caveman.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Caveman.des -#none - -$(HDFILES1): $(SLIB)Hea-goal.lev - -$(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Healer.des -#none - -$(KDFILES1): $(SLIB)Kni-goal.lev - -$(SLIB)Kni-goal.lev: $(DAT)Knight.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Knight.des -#none - -$(MDFILES1): $(SLIB)Mon-goal.lev - -$(SLIB)Mon-goal.lev: $(DAT)Monk.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Monk.des -#none - -$(PDFILES1): $(SLIB)Pri-goal.lev - -$(SLIB)Pri-goal.lev: $(DAT)Priest.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Priest.des -#none - -$(RDFILES1): $(SLIB)Rog-goal.lev - -$(SLIB)Rog-goal.lev: $(DAT)Rogue.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Rogue.des -#none - -$(RANFILES1): $(SLIB)Ran-goal.lev - -$(SLIB)Ran-goal.lev: $(DAT)Ranger.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Ranger.des -#none - -$(SDFILES1): $(SLIB)Sam-goal.lev - -$(SLIB)Sam-goal.lev: $(DAT)Samurai.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Samurai.des -#none - -$(TDFILES1): $(SLIB)Tou-goal.lev - -$(SLIB)Tou-goal.lev: $(DAT)Tourist.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Tourist.des -#none - -$(VDFILES1): $(SLIB)Val-goal.lev - -$(SLIB)Val-goal.lev: $(DAT)Valkyrie.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Valkyrie.des -#none - -$(WDFILES1): $(SLIB)Wiz-goal.lev - -$(SLIB)Wiz-goal.lev: $(DAT)Wizard.des $(SBIN)lev_comp -#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Wizard.des -#none - -$(SLIB)dungeon: $(DAT)dungeon.def $(SBIN)makedefs $(SBIN)dgn_comp - $(SBIN)makedefs -e - $(SBIN)dgn_comp $(DAT)dungeon.pdf - copy $(DAT)dungeon $(SLIB)dungeon - delete $(DAT)dungeon - -inst-data: $(INSTDATAFILES) - -$(NETHACK)amii.hlp: $(AMI)amii.hlp - copy $(AMI)amii.hlp $@ - -#$(NETHACK)data: $(DAT)data -# copy $(DAT)data $@ - -$(SLIB)data: $(DAT)data.base $(I)config.h $(SBIN)makedefs - $(SBIN)makedefs -d - -#$(NETHACK)rumors: $(DAT)rumors -# copy $(DAT)rumors $@ - -$(SLIB)rumors: $(DAT)rumors.tru $(DAT)rumors.fal $(SBIN)makedefs - $(SBIN)makedefs -r - -$(SLIB)cmdhelp: $(DAT)cmdhelp - copy $(DAT)cmdhelp $@ - -$(SLIB)help: $(DAT)help - copy $(DAT)help $@ - -$(SLIB)hh: $(DAT)hh - copy $(DAT)hh $@ - -$(NETHACK)HackWB.hlp: $(AMI)HackWB.hlp - copy $(AMI)HackWB.hlp $@ - -$(SLIB)history: $(DAT)history - copy $(DAT)history $@ - -$(NETHACK)license: $(DAT)license - copy $(DAT)license $@ - -$(SLIB)opthelp: $(DAT)opthelp - copy $(DAT)opthelp $@ - -$(NETHACK)Recover.txt: $(DOC)Recover.txt - copy $(DOC)Recover.txt $@ - -$(NETHACK)GuideBook.txt: $(DOC)GuideBook.txt - copy $(DOC)GuideBook.txt $@ - -$(NETHACK)NetHack.txt: $(DOC)NetHack.txt - copy $(DOC)NetHack.txt $@ - -$(NETHACK)Install.ami: $(AMI)Install.ami - copy $(AMI)Install.ami $@ - -#SFD_INSTEAD $(NETHACK)logfile: $(NETHACK)logfile -$(NETHACK)logfile: - echo to $@ - -#SFD_INSTEAD $(NETHACK)record: $(NETHACK)record -$(NETHACK)record: - echo to $@ - -$(SLIB)wizhelp: $(DAT)wizhelp - copy $(DAT)wizhelp $@ - -# Create the directories here because NetHack.cnf puts them there by default -$(NETHACK)NetHack.cnf: $(AMI)NetHack.cnf - copy $(AMI)NetHack.cnf $@ - -makedir $(NETHACK)save - -makedir $(NETHACK)levels - -#SFD_BEGIN -#SFD_ELSE -$(O)NetHack.gst: $(GSTSRC) $(I)hack.h - sc makegst=$(GSTFILE) $(CFLAGS) $(GSTSRC) -#SFD_END - -# Unpack and install fonts - -INSTFONTFILES= $(NETHACK)hack.font $(NETHACK)hack $(NETHACK)hack/8 - -inst-fonts: $(INSTFONTFILES) - -$(NETHACK)hack/8: $(AMI)amifont8.uu $(NETHACK)hack - $(UUDEC) $(AMI)amifont8.uu - copy 8 $(NETHACK)hack/8 - delete 8 - -$(NETHACK)hack.font: $(AMI)amifont.uu - $(UUDEC) $(AMI)amifont.uu - copy hack.font $(NETHACK)hack.font - delete hack.font - -#SFD_INSTEAD $(NETHACK)hack: $(NETHACK)hack -$(NETHACK)hack: - -makedir $@ - -INSTICONFILES= \ - $(NETHACK)default.icon $(NETHACK)NetHack.info $(NETHACK)NewGame.info \ - $(NETHACK)HackWB.info - -inst-icons: $(INSTICONFILES) - -# Unpack the icons into place - -$(NETHACK)default.icon: $(AMI)dflticon.uu - $(UUDEC) $(AMI)dflticon.uu -# copy default.icon $(NETHACK)default.icon -# delete default.icon - -$(NETHACK)NetHack.info: $(AMI)NHinfo.uu - $(UUDEC) $(AMI)NHinfo.uu -# copy NetHack.info $(NETHACK)NetHack.info -# delete NetHack.info - -$(NETHACK)NewGame.info: $(AMI)NewGame.uu - $(UUDEC) $(AMI)NewGame.uu -# copy NewGame.info $(NETHACK)NewGame.info -# delete NewGame.info - -$(NETHACK)HackWB.info: $(AMI)HackWB.uu - $(UUDEC) $(AMI)HackWB.uu -# copy HackWB.info $(NETHACK)HackWB.info -# delete HackWB.info - -# If DLB is defined, create the nhdat library file in the playground -# directory. If not, move all the data files there. -$(NETHACK)nhdat: $(LIBFILES) $(SBIN)dlb - list to T:nhdat.lst $(SLIB) QUICK NOHEAD FILES - echo >T:make-nhdat $(SBIN)dlb cCfI $(SLIB) $(NETHACK)nhdat T:nhdat.lst - echo >>T:make-nhdat if not exists $(NETHACK)nhdat - echo >>T:make-nhdat copy $(SLIB)\#? $(NETHACK) - echo >>T:make-nhdat endif - execute T:make-nhdat - -delete T:make-nhdat - -# DO NOT DELETE THIS LINE - -$(O)allmain.o: $(NHS)allmain.c $(HDEP) - -$(O)alloc.o: $(NHS)alloc.c $(I)config.h - -$(O)apply.o: $(NHS)apply.c $(HDEP) -#SFD_INSTEAD #none - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)apply.c - -$(O)artifact.o: $(NHS)artifact.c $(HDEP) $(I)artifact.h $(I)artilist.h - -$(O)attrib.o: $(NHS)attrib.c $(HDEP) $(I)artifact.h - -$(O)ball.o: $(NHS)ball.c $(HDEP) - -$(O)bones.o: $(NHS)bones.c $(HDEP) - -$(O)botl.o: $(NHS)botl.c $(HDEP) - -$(O)cmd.o: $(NHS)cmd.c $(HDEP) $(I)func_tab.h - -$(O)dbridge.o: $(NHS)dbridge.c $(HDEP) - -$(O)decl.o: $(NHS)decl.c $(HDEP) $(I)quest.h - -$(O)detect.o: $(NHS)detect.c $(HDEP) $(I)artifact.h - -$(O)dig.o: $(NHS)dig.c $(HDEP) - -$(O)display.o: $(NHS)display.c $(HDEP) - -$(O)dlb.o: $(NHS)dlb.c $(HDEP) $(I)dlb.h - -$(O)do.o: $(NHS)do.c $(HDEP) - -$(O)do_name.o: $(NHS)do_name.c $(HDEP) - -$(O)do_wear.o: $(NHS)do_wear.c $(HDEP) - -$(O)dog.o: $(NHS)dog.c $(HDEP) - -$(O)dogmove.o: $(NHS)dogmove.c $(HDEP) $(I)mfndpos.h - -$(O)dokick.o: $(NHS)dokick.c $(HDEP) - -$(O)dothrow.o: $(NHS)dothrow.c $(HDEP) - -$(O)drawing.o: $(NHS)drawing.c $(HDEP) $(I)tcap.h - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)drawing.c - -$(O)dungeon.o: $(NHS)dungeon.c $(HDEP) $(I)dgn_file.h $(I)dlb.h - -$(O)eat.o: $(NHS)eat.c $(HDEP) - -$(O)end.o: $(NHS)end.c $(HDEP) $(I)dlb.h - -$(O)engrave.o: $(NHS)engrave.c $(HDEP) - -$(O)exper.o: $(NHS)exper.c $(HDEP) - -$(O)explode.o: $(NHS)explode.c $(HDEP) - -$(O)extralev.o: $(NHS)extralev.c $(HDEP) - -$(O)files.o: $(NHS)files.c $(HDEP) $(I)dlb.h $(I)date.h - -$(O)fountain.o: $(NHS)fountain.c $(HDEP) - -$(O)hack.o: $(NHS)hack.c $(HDEP) - -$(O)hacklib.o: $(NHS)hacklib.c $(HDEP) - -$(O)invent.o: $(NHS)invent.c $(HDEP) $(I)artifact.h - -$(O)light.o: $(NHS)light.c $(HDEP) - -$(O)lock.o: $(NHS)lock.c $(HDEP) - -$(O)mail.o: $(NHS)mail.c $(HDEP) $(I)mail.h - -$(O)makemon.o: $(NHS)makemon.c $(HDEP) - -$(O)mapglyph.o: $(NHS)mapglyph.c $(HDEP) - -$(O)mcastu.o: $(NHS)mcastu.c $(HDEP) - -$(O)mhitm.o: $(NHS)mhitm.c $(HDEP) $(I)artifact.h - -$(O)mhitu.o: $(NHS)mhitu.c $(HDEP) $(I)artifact.h - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)mhitu.c - -$(O)minion.o: $(NHS)minion.c $(HDEP) - -$(O)mklev.o: $(NHS)mklev.c $(HDEP) - -$(O)mkmap.o: $(NHS)mkmap.c $(HDEP) $(I)sp_lev.h - -$(O)mkmaze.o: $(NHS)mkmaze.c $(HDEP) $(I)sp_lev.h - -$(O)mkobj.o: $(NHS)mkobj.c $(HDEP) $(I)artifact.h $(I)prop.h - -$(O)mkroom.o: $(NHS)mkroom.c $(HDEP) - -$(O)mon.o: $(NHS)mon.c $(HDEP) $(I)mfndpos.h - -$(O)mondata.o: $(NHS)mondata.c $(HDEP) - -$(O)monmove.o: $(NHS)monmove.c $(HDEP) $(I)mfndpos.h $(I)artifact.h - -$(O)monst.o: $(NHS)monst.c $(I)config.h $(I)permonst.h $(I)monsym.h $(I)color.h - -$(O)monstr.o: $(NHS)monstr.c $(HDEP) -#SFD_INSTEAD $(CC) $(CFLAGS) $(OBJSPEC)%(left) $(NHS)monstr.c -#none - -$(O)mplayer.o: $(NHS)mplayer.c $(HDEP) - -$(O)mthrowu.o: $(NHS)mthrowu.c $(HDEP) - -$(O)muse.o: $(NHS)muse.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)muse.c - -$(O)music.o: $(NHS)music.c $(HDEP) #interp.c - -$(O)o_init.o: $(NHS)o_init.c $(HDEP) - -$(O)objects.o: $(NHS)objects.c $(I)config.h $(I)obj.h $(I)objclass.h \ - $(I)prop.h $(I)skills.h $(I)color.h -#SFD_INSTEAD #none - $(CC) $(CFLAGS) $(INCLSPEC)$(NHS) $(OBJSPEC)$@ $(NHS)objects.c - -$(O)objnam.o: $(NHS)objnam.c $(HDEP) - -$(O)options.o: $(NHS)options.c $(HDEP) $(I)tcap.h $(I)config.h \ - $(I)objclass.h $(I)flag.h - -$(O)pager.o: $(NHS)pager.c $(HDEP) $(I)dlb.h - -$(O)pickup.o: $(NHS)pickup.c $(HDEP) - -$(O)pline.o: $(NHS)pline.c $(HDEP) - -$(O)polyself.o: $(NHS)polyself.c $(HDEP) - -$(O)potion.o: $(NHS)potion.c $(HDEP) - -$(O)pray.o: $(NHS)pray.c $(HDEP) - -$(O)priest.o: $(NHS)priest.c $(HDEP) $(I)mfndpos.h - -$(O)quest.o: $(NHS)quest.c $(HDEP) $(I)quest.h - -$(O)questpgr.o: $(NHS)questpgr.c $(HDEP) $(I)dlb.h - -$(O)read.o: $(NHS)read.c $(HDEP) - -$(O)rect.o: $(NHS)rect.c $(HDEP) - -$(O)region.o: $(NHS)region.c $(HDEP) - -$(O)restore.o: $(NHS)restore.c $(HDEP) $(I)tcap.h $(I)quest.h - -$(O)rnd.o: $(NHS)rnd.c $(HDEP) - -$(O)role.o: $(NHS)role.c $(HDEP) - -$(O)rumors.o: $(NHS)rumors.c $(HDEP) $(I)dlb.h - -$(O)save.o: $(NHS)save.c $(HDEP) $(I)quest.h - -$(O)shk.o: $(NHS)shk.c $(HDEP) -#SFD_INSTEAD #none - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)shk.c - -$(O)shknam.o: $(NHS)shknam.c $(HDEP) - -$(O)sit.o: $(NHS)sit.c $(HDEP) $(I)artifact.h - -$(O)sounds.o: $(NHS)sounds.c $(HDEP) - -$(O)sp_lev.o: $(NHS)sp_lev.c $(HDEP) $(I)sp_lev.h $(I)rect.h $(I)dlb.h - -$(O)spell.o: $(NHS)spell.c $(HDEP) - -$(O)steal.o: $(NHS)steal.c $(HDEP) - -$(O)steed.o: $(NHS)steed.c $(HDEP) - -$(O)sys.o: $(NHS)sys.c $(HDEP) - -$(O)teleport.o: $(NHS)teleport.c $(HDEP) - -$(O)timeout.o: $(NHS)timeout.c $(HDEP) - -$(O)topten.o: $(NHS)topten.c $(HDEP) $(I)dlb.h - -$(O)track.o: $(NHS)track.c $(HDEP) - -$(O)trap.o: $(NHS)trap.c $(HDEP) -#SFD_INSTEAD #none - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)trap.c - -$(O)u_init.o: $(NHS)u_init.c $(HDEP) - -$(O)uhitm.o: $(NHS)uhitm.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)uhitm.c - -$(O)vault.o: $(NHS)vault.c $(HDEP) - -$(O)version.o: $(NHS)version.c $(HDEP) $(I)date.h $(I)patchlevel.h - -# DMake doesn't grok mid-line comments -#SFD_INSTEAD $(O)vision.o: $(NHS)vision.c $(HDEP) -$(O)vision.o: $(NHS)vision.c $(HDEP) #$(I)vis_tab.h - -$(O)weapon.o: $(NHS)weapon.c $(HDEP) - -$(O)were.o: $(NHS)were.c $(HDEP) - -$(O)wield.o: $(NHS)wield.c $(HDEP) - -$(O)windows.o: $(NHS)windows.c $(HDEP) $(I)wintty.h - -$(O)wizard.o: $(NHS)wizard.c $(HDEP) - -$(O)worm.o: $(NHS)worm.c $(HDEP) - -$(O)worn.o: $(NHS)worn.c $(HDEP) - -$(O)write.o: $(NHS)write.c $(HDEP) - -$(O)zap.o: $(NHS)zap.c $(HDEP) - $(CC) $(CFLAGS) $(CFLAGS2) $(OBJSPEC)$@ $(NHS)zap.c - -$(O)getline.o: $(TTY)getline.c $(HDEP) $(I)wintty.h - -$(O)termcap.o: $(TTY)termcap.c $(HDEP) $(I)wintty.h $(I)tcap.h - -$(O)topl.o: $(TTY)topl.c $(HDEP) $(I)wintty.h $(I)tcap.h - -$(O)wintty.o: $(TTY)wintty.c $(HDEP) $(I)wintty.h $(I)tcap.h \ - $(I)date.h $(I)patchlevel.h - -$(O)amitty.o: $(AMI)amitty.c $(HDEP) - -$(O)amistack.o: $(AMI)amistack.c - $(CC) $(CFLAGS3) $(CSYM) $(OBJSPEC)$@ $(AMI)amistack.c - -$(O)rip.o: $(NHS)rip.c $(HDEP) - - -$(I)config.h: $(I)config1.h $(I)tradstdc.h $(I)global.h - -setdate $(I)config.h - -wait 2 - -# onames.h handled at onames.h target, pm.h - -$(I)decl.h: $(I)quest.h $(I)spell.h $(I)color.h $(I)obj.h $(I)you.h - -setdate $(I)decl.h - -wait 2 - -$(I)global.h: $(I)coord.h $(I)pcconf.h $(I)amiconf.h - -setdate $(I)global.h - -wait 2 - -$(I)hack.h: $(I)config.h $(I)context.h $(I)trap.h $(I)decl.h $(I)dungeon.h \ - $(I)monsym.h $(I)mkroom.h $(I)objclass.h $(I)flag.h $(I)rm.h \ - $(I)vision.h $(I)display.h $(I)wintype.h $(I)engrave.h \ - $(I)rect.h $(I)region.h $(I)sys.h - -setdate $(I)hack.h - -wait 2 - -$(I)permonst.h: $(I)monattk.h $(I)monflag.h $(I)align.h - -setdate $(I)permonst.h - -wait 2 - -$(I)you.h: $(I)align.h $(I)attrib.h $(I)monst.h $(I)mextra.h $(I)youprop.h $(I)skills.h - -setdate $(I)you.h - -wait 2 - -# pm.h handled at target - -$(I)youprop.h: $(I)prop.h $(I)permonst.h $(I)mondata.h - -setdate $(I)youprop.h - -wait 2 - -$(I)display.h: $(I)vision.h $(I)mondata.h - -setdate $(I)display.h - -wait 2 - -$(I)dungeon.h: $(I)align.h - -setdate $(I)dungeon.h - -wait 2 - -$(I)engrave.h: $(I)rect.h - -setdate $(I)engrave.h - -wait 2 - -$(I)mextra.h: $(I)align.h - -setdate $(I)mextra.h - -wait 2 - -$(I)mondata.h: $(I)align.h - -setdate $(I)mondata.h - -wait 2 - -$(I)monst.h: $(I)align.h $(I)mextra.h - -setdate $(I)monst.h - -wait 2 - -$(I)pcconf.h: $(I)micro.h $(I)system.h - -setdate $(I)pcconf.h - -wait 2 - -$(I)rm.h: $(I)align.h - -setdate $(I)rm.h - -wait 2 - - -#notes -# install keeps doing re-install because it keeps rebuilding lev_comp??? -# fixed(?) - deleted setdate -# make nhdat rebuils sys/amiga objects diff --git a/outdated/sys/amiga/NetHack.cnf b/outdated/sys/amiga/NetHack.cnf deleted file mode 100644 index 89794c094..000000000 --- a/outdated/sys/amiga/NetHack.cnf +++ /dev/null @@ -1,213 +0,0 @@ -# A '#' at the beginning of a line means the rest of the line is a comment. - -# This is an example configuration file. -# If several people are to use it, don't specify "name" or personal -# prefences like "dogname" or "packorder" in OPTIONS. - -# To change configuration, comment out the unwanted configurations, and -# remove the comment from the configuration you want. - -# Some options to set personal preferences. If several people are to -# use it, options like these should not be set here - use the command line -#OPTIONS=name:Janet-V,female,dogname:Fido,fruit:apricot -#OPTIONS=packorder:")[%?+/=!(*0_`,scores:10t/2a,noverbose -#OPTIONS=gender:male -#OPTIONS=role:random -#OPTIONS=race:random -#OPTIONS=align:chaotic -# Other general options -#OPTIONS=time,rest_on_space,noautopickup - -# The search path for files like record, help, opthelp, etc. -PATH=NetHack: - -# My own setup -#OPTIONS=nolegacy,fruit:lemon,time,autopickup,checkpoint,showexp,showscore,standout,nonews -#OPTIONS=nomail,flush,eight_bit_tty,scores:10t/2a,pickup_types:$,suppress_alert:3.3.0,autoquiver - -# The windowtype option must be set before any options regarding colors and palette -# are set otherwise previously set values will be overridden by the defaults -# -# The font version of the game -OPTIONS=windowtype:amii -# -# New tile version of the game -#OPTIONS=windowtype:amitile -# -# A hard disk configuration. -# -HACKDIR=NetHack: -LEVELS=Nethack:Levels -SAVE=Nethack:Save -BONESDIR=Nethack:Levels -SCOREDIR=Nethack: -LOCKDIR=Nethack: -CONFIGDIR=Nethack: -DATADIR=Nethack: -TROUBLEDIR=Nethack: - -# *** CHARACTER GRAPHICS *** -# -# See the on-line help or the Guidebook for which symbols are in which -# positions. -# -# Note that the hack.font has special graphics characters from 192 on. - -# An example using the hack.font graphics character set: -DUNGEON = 032 192 193 194 195 196 197 198 216 214 \ - 215 213 217 145 146 147 148 035 035 217 \ - 218 229 060 062 060 062 095 124 092 035 \ - 123 125 042 125 042 042 035 035 046 035 \ - 125 - -TRAPS = 094 094 094 094 094 094 094 094 094 094 \ - 094 094 094 094 094 094 094 034 094 094 \ - 094 094 - -EFFECTS = 241 240 242 243 042 033 123 125 \ - 064 038 042 035 \ - 244 245 246 247 239 248 249 250 \ - 230 234 231 236 212 237 232 235 233 - -WARNINGS = 048 049 050 051 052 053 - -# Monitors vary greatly in their color response. If the default colors -# are not good on your monitor, here are some other alternatives for the -# font version of the game: -# -# Last color of the palette is always used for the cursor. -# -#CBM 1960, set color/contrast for good pure red, green, and blue. True colors. -#PENS=000,fff,a61,7bb,0f0,e0c,00f,f00 -#CBM 1960, set color/contrast as above, better colors for NetHack. -#PENS=667,fff,da1,7bb,2f0,e0d,0af,f42 -#and other suggestions: -#PENS=888,ffc,840,0b8,4e4,e8b,7be,a04 -#PENS=000,fff,830,7ae,181,c06,23e,c00 -# -# For an "interlaced"+ line screen, the default font is courier:13. If you want -# a different font, set it here. The format is "fontname.font:size"; i.e. the -# .font extension is required. -#FONT=courier.font:13 -#FONT=topaz.font:8 -# -# Proportional fonts such as CGTimes are probably not a good idea because they -# result in many things not being spaced out correctly. -#FONT=CGTimes.font:15 -# -# This sized proportional font is readable, but still has spacing problems -#FONT=CGTimes.font:21 -# -# FOR AGA OR OTHER DISPLAYS CAPABLE OF 5 OR MORE PLANES... -# -# For a screen of depth 5 the following dripens provide a brown border -# using pens 16-31. -# -# Pens 16-31 can be redefined with PENS= if you want different colors, -# using the PENS= values below for a 4 plane screen as the first 16 colors. -# -#DEPTH=5 -#DRIPENS=0,0,0,17,27,23,1,23,15,0,23,27 -# -# The APEN and BPEN values in the various types of windows can be set in -# the manner shown below. These values are for the 16 color version of -# the tile game. -# -# These values are specified as APEN,BPEN (foreground,background) -# -#MSGPENS=1,12 -#STATUSPENS=1,12 -#MENUPENS=1,23 -#TEXTPENS=1,23 -#OTHERPENS=1,23 -# -# FOR ECS OR OTHERS ONLY CAPABLE OF 4 PLANES... -# -# These values work good for the TILE version of the game on ECS machines -# These are the default values for reference purposes. -# -#DEPTH=4 -#defaults for tilemode: -#PENS=000,fff,0bf,f60,00f,090,69b,f00,6f0,ff0,f0f,940,466,c40,ddb,fb9 -#DRIPENS=0,1,0,2,4,12,14,12,7,1,12,4 -#defaults for fontmode: -#PENS=000,fff,830,7ac,181,c06,23e,c00 -#DRIPENS=0,6,2,1,6,3,1,3,7,1,3,6 -# -# The APEN and BPEN values in the various types of windows can be set in -# the manner shown below. These values are for a 32 color version of -# the tile game. -# -# These values are specified as APEN,BPEN (foreground,background) -# -#MSGPENS=1,12 -#STATUSPENS=1,12 -#MENUPENS=0,14 -#TEXTPENS=0,14 -#OTHERPENS=1,12 -# -# New alternative color scheme for 16 color font mode. -# This changes the colors of monsters, objects etc. -# -# FGPENS and BGPENS define APEN and BPEN for objects and monsters on the map. -# The colors are in the following order: -# black, red, green, brown, blue, magenta, cyan, gray, no color, orange, -# bright green, yellow, bright blue, bright magenta, bright cyan, white -# -DEPTH=4 -PENS=000,fff,830,7ac,181,c06,23e,c00,888,f60,4f4,ff0,4af,f8f,8ff,f00 -FGPENS= 0, 7, 4, 2, 6, 5, 3, 8, 1, 9,10,11,12,13,14, 1 -BGPENS= 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -# -# Screen mode selections below should all work for either the font or tile -# version of the game. Other modes can be tried and as long as they are at -# least 640x200, the game should adapt to them... -# -# Select screenmode with a requester -#SCREENMODE=Req -# NTSC_MONITOR_ID -#SCREENMODE=0x00019000 -# PAL_MONITOR_ID -#SCREENMODE=0x00029000 -# NTSC_MONITOR_ID+LACE -#SCREENMODE=0x00019004 -# PAL_MONITOR_ID+LACE -#SCREENMODE=0x00029004 -# NTSC_MONITOR_ID+HIRES+LACE -#SCREENMODE=0x00019024 -# PAL_MONITOR_ID+HIRES+LACE -#SCREENMODE=0x00029024 -# VGA_MONITOR_ID -#SCREENMODE=0x00031000 -# VGAPRODUCT_KEY -#SCREENMODE=0x00039024 -# A2024TENHERTZ_KEY -#SCREENMODE=0x00041000 -# A2024FIFTEENHERTZ_KEY -#SCREENMODE=0x00049000 -# EURO72_MONITOR_ID -#SCREENMODE=0x00061000 -# EURO72PRODUCT_KEY -#SCREENMODE=0x00069024 -# EURO72PRODUCTLACE_KEY -#SCREENMODE=0x00069025 -# EURO72PRODUCTDBL_KEY -#SCREENMODE=0x00069020 -# EURO36_MONITOR_ID -#SCREENMODE=0x00071000 -# SUPER72HIRESDBL_KEY -#SCREENMODE=0x00089008 -# SUPER72SUPERDBL_KEY -#SCREENMODE=0x00089028 -# DBLNTSCHIRES_KEY -#SCREENMODE=0x00099000 -# DBLNTSCHIRESFF_KEY -#SCREENMODE=0x00099004 -# DBLNTSCHIRESLACE_KEY -#SCREENMODE=0x00099005 -# DBLPALHIRES_KEY -#SCREENMODE=0x000a9000 -# DBLPALHIRESFF_KEY -#SCREENMODE=0x000a9004 -# DBLPALHIRESLACE_KEY -#SCREENMODE=0x000a9005 diff --git a/outdated/sys/amiga/ifchange b/outdated/sys/amiga/ifchange deleted file mode 100644 index d06450c08..000000000 --- a/outdated/sys/amiga/ifchange +++ /dev/null @@ -1,55 +0,0 @@ -.KEY oper/a,tmp/a,real/a,f1,f2,f3,f4,f5 - -. ; miscellaneous script functions for the Amiga -. ; Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993, 1996. -. ; NetHack may be freely redistributed. See license for details. - -FAILAT 6 -IF EQ "MOVE" - IF EXISTS - diff >T:mic -c - search from T:mic SEARCH "---" QUIET - IF WARN - echo "MOVE: no change" - delete - ELSE - echo "MOVE: copy" - copy clone - delete - ENDIF - ELSE - echo "MOVE: copy2" - copy clone - delete - ENDIF - QUIT -ENDIF - -IF EQ "TOUCH" - IF EXISTS - diff >T:mic -c - search from T:mic SEARCH "---" QUIET - IF NOT WARN - echo "TOUCH: touch" - IF NOT EQ "@" - setdate - ENDIF - IF NOT EQ "@" - setdate - ENDIF - IF NOT EQ "@" - setdate - ENDIF - IF NOT EQ "@" - setdate - ENDIF - IF NOT EQ "@" - setdate - ENDIF - ENDIF - ENDIF - QUIT -ENDIF - -echo "ifchange: '' not recognized" -quit 10 diff --git a/outdated/sys/amiga/mkdmake b/outdated/sys/amiga/mkdmake deleted file mode 100644 index fc002ef10..000000000 --- a/outdated/sys/amiga/mkdmake +++ /dev/null @@ -1,13 +0,0 @@ -GE/$@/%(left)/ -GE/$ - -#include "config.h" -#include "tile.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _DCC -#include -#include -#include -#endif - -void panic(const char *); -void map_colors(void); -int BestMatch(int, int, int); - -extern pixval ColorMap[3][MAXCOLORMAPSIZE]; -extern int colorsinmap; - -/* - * WARNING: - * This program carries forth the assumption that the colormaps in all - * of the .txt files are the same. This is a bug. - */ - -struct { - int Height; - int Width; -} IFFScreen; - -/* - * We are using a hybrid form of our own design which we call a BMAP (for - * bitmap) form. It is an ILBM with the bitmaps already deinterleaved, - * completely uncompressed. - * This speeds the loading of the images from the games point of view because - * it - * does not have to deinterleave and uncompress them. - */ -#define ID_BMAP MAKE_ID('B', 'M', 'A', 'P') /* instead of ILBM */ -#define ID_BMHD MAKE_ID('B', 'M', 'H', 'D') /* Same as ILBM */ -#define ID_CAMG MAKE_ID('C', 'A', 'M', 'G') /* Same as ILBM */ -#define ID_CMAP MAKE_ID('C', 'M', 'A', 'P') /* Same as ILBM */ -#define ID_PDAT \ - MAKE_ID('P', 'D', 'A', 'T') /* Extra data describing plane \ - * size due to graphics.library \ - * rounding requirements. \ - */ -#define ID_PLNE MAKE_ID('P', 'L', 'N', 'E') /* The planes of the image */ - -#ifndef _DCC -extern -#endif - struct Library *IFFParseBase; - -int nplanes; - -/* BMHD from IFF documentation */ -typedef struct { - UWORD w, h; - WORD x, y; - UBYTE nPlanes; - UBYTE masking; - UBYTE compression; - UBYTE reserved1; - UWORD transparentColor; - UBYTE xAspect, yAspect; - WORD pageWidth, pageHeight; -} BitMapHeader; - -typedef struct { - UBYTE r, g, b; -} AmiColorMap; - -pixel pixels[TILE_Y][TILE_X]; -AmiColorMap *cmap; - -int findcolor(register pixel *pix); -void packwritebody(pixel (*tile)[TILE_X], char **planes, int tileno); - -void -error(char *str) -{ - fprintf(stderr, "ERROR: %s\n", str); -} - -/* - * This array maps the image colors to the amiga's first 16 colors. The - * colors - * are reordered to help with maintaining dripen settings. - */ -int colrmap[] = { 0, 6, 9, 15, 4, 10, 2, 3, 5, 11, 7, 13, 8, 1, 14, 12 }; - -/* How many tiles fit across and down. */ - -#define COLS 20 -#define ROWS ((tiles + COLS - 1) / COLS) - -main(int argc, char **argv) -{ - int colors; - struct { - long nplanes; - long pbytes; - long across; - long down; - long npics; - long xsize; - long ysize; - } pdat; - long pbytes; /* Bytes of data in a plane */ - int i, cnt; - BitMapHeader bmhd; - struct IFFHandle *iff; - long camg = HIRES | LACE; - int tiles = 0; - char **planes; - - if (argc != 3) { - fprintf(stderr, "Usage: %s source destination\n", argv[0]); - exit(1); - } - -#if defined(_DCC) || defined(__GNUC__) - IFFParseBase = OpenLibrary("iffparse.library", 0); - if (!IFFParseBase) { - error("unable to open iffparse.library"); - exit(1); - } -#endif - - /* First, count the files in the file */ - if (fopen_text_file(argv[1], "r") != TRUE) { - perror(argv[1]); - return (1); - } - - nplanes = 0; - i = colorsinmap - 1; /*IFFScreen.Colors - 1; */ - while (i != 0) { - nplanes++; - i >>= 1; - } - - planes = malloc(nplanes * sizeof(char *)); - if (planes == 0) { - error("can not allocate planes pointer"); - exit(1); - } - - while (read_text_tile(pixels) == TRUE) - ++tiles; - fclose_text_file(); - - IFFScreen.Width = COLS * TILE_X; - IFFScreen.Height = ROWS * TILE_Y; - - pbytes = (COLS * ROWS * TILE_X + 15) / 16 * 2 * TILE_Y; - - for (i = 0; i < nplanes; ++i) { - planes[i] = calloc(1, pbytes); - if (planes[i] == 0) { - error("can not allocate planes pointer"); - exit(1); - } - } - - /* Now, process it */ - if (fopen_text_file(argv[1], "r") != TRUE) { - perror(argv[1]); - return (1); - } - - iff = AllocIFF(); - if (!iff) { - error("Can not allocate IFFHandle"); - return (1); - } - - iff->iff_Stream = Open(argv[2], MODE_NEWFILE); - if (!iff->iff_Stream) { - error("Can not open output file"); - return (1); - } - - InitIFFasDOS(iff); - OpenIFF(iff, IFFF_WRITE); - - PushChunk(iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN); - - bmhd.w = IFFScreen.Width; - bmhd.h = IFFScreen.Height; - bmhd.x = 0; - bmhd.y = 0; - bmhd.nPlanes = nplanes; - bmhd.masking = 0; - bmhd.compression = 0; - bmhd.reserved1 = 0; - bmhd.transparentColor = 0; - bmhd.xAspect = 100; - bmhd.yAspect = 100; - bmhd.pageWidth = TILE_X; - bmhd.pageHeight = TILE_Y; - - PushChunk(iff, ID_BMAP, ID_BMHD, sizeof(bmhd)); - WriteChunkBytes(iff, &bmhd, sizeof(bmhd)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_CAMG, sizeof(camg)); - WriteChunkBytes(iff, &camg, sizeof(camg)); - PopChunk(iff); - - /* We need to reorder the colors to get reasonable default pens but - * we also need to know where some of the colors are - so go find out. - */ - map_colors(); - - cmap = malloc((colors = (1L << nplanes)) * sizeof(AmiColorMap)); - for (i = 0; i < colors; ++i) { - cmap[colrmap[i]].r = ColorMap[CM_RED][i]; - cmap[colrmap[i]].g = ColorMap[CM_GREEN][i]; - cmap[colrmap[i]].b = ColorMap[CM_BLUE][i]; - } - - PushChunk(iff, ID_BMAP, ID_CMAP, IFFSIZE_UNKNOWN); - for (i = 0; i < colors; ++i) - WriteChunkBytes(iff, &cmap[i], 3); - PopChunk(iff); - - cnt = 0; - while (read_text_tile(pixels) == TRUE) { - packwritebody(pixels, planes, cnt); - if (cnt % 20 == 0) - printf("%d..", cnt); - ++cnt; - fflush(stdout); - } - - pdat.nplanes = nplanes; - pdat.pbytes = pbytes; - pdat.xsize = TILE_X; - pdat.ysize = TILE_Y; - pdat.across = COLS; - pdat.down = ROWS; - pdat.npics = cnt; - - PushChunk(iff, ID_BMAP, ID_PDAT, IFFSIZE_UNKNOWN); - WriteChunkBytes(iff, &pdat, sizeof(pdat)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_PLNE, IFFSIZE_UNKNOWN); - for (i = 0; i < nplanes; ++i) - WriteChunkBytes(iff, planes[i], pbytes); - PopChunk(iff); - - CloseIFF(iff); - Close(iff->iff_Stream); - FreeIFF(iff); - - printf("\n%d tiles converted\n", cnt); - -#if defined(_DCC) || defined(__GNUC__) - CloseLibrary(IFFParseBase); -#endif - exit(0); -} - -findcolor(register pixel *pix) -{ - register int i; - - for (i = 0; i < MAXCOLORMAPSIZE; ++i) { - if ((pix->r == ColorMap[CM_RED][i]) - && (pix->g == ColorMap[CM_GREEN][i]) - && (pix->b == ColorMap[CM_BLUE][i])) { - return (i); - } - } - return (-1); -} - -void -packwritebody(pixel (*tile)[TILE_X], char **planes, int tileno) -{ - register int i, j, k, col; - register char *buf; - register int across, rowbytes, xoff, yoff; - - /* how many tiles fit across? */ - across = COLS; - - /* How many bytes per pixel row */ - rowbytes = ((IFFScreen.Width + 15) / 16) * 2; - - /* How many bytes to account for y distance in planes */ - yoff = ((tileno / across) * TILE_Y) * rowbytes; - - /* How many bytes to account for x distance in planes */ - xoff = (tileno % across) * (TILE_X / 8); - - /* For each row... */ - for (i = 0; i < TILE_Y; ++i) { - /* For each bitplane... */ - for (k = 0; k < nplanes; ++k) { - const int mask = 1l << k; - - /* Go across the row */ - for (j = 0; j < TILE_X; j++) { - col = findcolor(&tile[i][j]); - if (col == -1) { - error("can not convert pixel color to colormap index"); - return; - } - /* Shift the colors around to have good complements and to - * know the dripen values. - */ - col = colrmap[col]; - - /* To top left corner of tile */ - buf = planes[k] + yoff + xoff; - - /*To i'th row of tile and the correct byte for the j'th - * pixel*/ - buf += (i * rowbytes) + (j / 8); - - /* Or in the bit for this color */ - *buf |= (((col & mask) != 0) << (7 - (j % 8))); - } - } - } -} - -/* #define DBG */ - -/* map_colors - * The incoming colormap is in arbitrary order and has arbitrary colors in - * it, but we need (some) specific colors in specific places. Find the - * colors we need and fix the mapping table to match. - */ -/* What we are aiming for: */ -/* XXX was 0-7 */ -#define CX_BLACK 0 -#define CX_WHITE 1 -#define CX_BROWN 11 -#define CX_CYAN 2 -#define CX_GREEN 5 -#define CX_MAGENTA 10 -#define CX_BLUE 4 -#define CX_RED 7 -/* we don't care about the rest, at least now */ -/* should get: black white blue red grey greyblue ltgrey */ -void -map_colors() -{ - int x; -#if 1 - int tmpmap[] = { 0, 2, 3, 7, 4, 5, 8, 9, 10, 11, 13, 15, 12, 1, 14, 6 }; -/* still not right: gray green yellow lost somewhere? */ -#else - int tmpmap[16]; - int x, y; - for (x = 0; x < 16; x++) - tmpmap[x] = -1; /* set not assigned yet */ - - tmpmap[BestMatch(0, 0, 0)] = CX_BLACK; - tmpmap[BestMatch(255, 255, 255)] = CX_WHITE; - tmpmap[BestMatch(255, 0, 0)] = CX_RED; - tmpmap[BestMatch(0, 255, 0)] = CX_GREEN; - tmpmap[BestMatch(0, 0, 255)] = CX_BLUE; - - /* clean up the rest */ - for (x = 0; x < 16; x++) { - for (y = 0; y < 16; y++) - if (tmpmap[y] == x) - goto outer_cont; - for (y = 0; y < 16; y++) - if (tmpmap[y] == -1) { - tmpmap[y] = x; - break; - } - if (y == 16) - panic("too many colors?"); - outer_cont: - ; - } - for (x = 0; x < 16; x++) - if (tmpmap[y] == -1) - panic("lost color?"); -#endif - for (x = 0; x < 16; x++) { -#ifdef DBG - printf("final: c[%d]=%d (target: %d)\n", x, tmpmap[x], colrmap[x]); -#endif - colrmap[x] = tmpmap[x]; - } -} -BestMatch(r, g, b) int r, g, b; -{ - int x; - int bestslot; - int bestrate = 99999999L; - for (x = 0; x < 16; x++) { - int rr = r - ColorMap[CM_RED][x]; - int gg = g - ColorMap[CM_GREEN][x]; - int bb = b - ColorMap[CM_BLUE][x]; - int rate = rr * rr + gg * gg + bb * bb; - if (bestrate > rate) { - bestrate = rate; - bestslot = x; - } - } -#ifdef DBG - printf("map (%d,%d,%d) -> %d (error=%d)\n", r, g, b, bestslot, bestrate); -#endif - return bestslot; -} - -long * -alloc(unsigned int n) -{ - long *ret = malloc(n); - if (!ret) { - error("Can't allocate memory"); - exit(1); - } - return (ret); -} - -void -panic(const char *msg) -{ - fprintf(stderr, "PANIC: %s\n", msg); - exit(1); -} diff --git a/outdated/sys/amiga/xpm2iff.c b/outdated/sys/amiga/xpm2iff.c deleted file mode 100644 index 0ffbc8c47..000000000 --- a/outdated/sys/amiga/xpm2iff.c +++ /dev/null @@ -1,363 +0,0 @@ -/* NetHack 3.6 xpm2iff.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) 1995 by Gregg Wonderly, Naperville, Illinois */ -/* NetHack may be freely redistributed. See license for details. */ - -#include - -#include "config.h" -#include "tile.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef _DCC -#include -#include -#include -#endif - -struct xpmscreen { - int Width; - int Height; - int Colors; - int ColorResolution; - int Background; - int AspectRatio; - int Interlace; - int BytesPerRow; -} XpmScreen; - -/* translation table from xpm characters to RGB and colormap slots */ -struct Ttable { - char flag; - char r, g, b; - int slot; /* output colortable index */ -} ttable[256]; - -pixval ColorMap[3][MAXCOLORMAPSIZE]; -int colorsinmap; - -/* - * We are using a hybrid form of our own design which we call a BMAP (for - * bitmap) form. It is an ILBM with the bitmaps already deinterleaved, - * completely uncompressed. - * This speeds the loading of the images from the games point of view because - * it - * does not have to deinterleave and uncompress them. - */ -#define ID_BMAP MAKE_ID('B', 'M', 'A', 'P') /* instead of ILBM */ -#define ID_BMHD MAKE_ID('B', 'M', 'H', 'D') /* Same as ILBM */ -#define ID_CAMG MAKE_ID('C', 'A', 'M', 'G') /* Same as ILBM */ -#define ID_CMAP MAKE_ID('C', 'M', 'A', 'P') /* Same as ILBM */ -#define ID_PDAT \ - MAKE_ID('P', 'D', 'A', 'T') /* Extra data describing plane \ - * size due to graphics.library \ - * rounding requirements. \ - */ -#define ID_PLNE MAKE_ID('P', 'L', 'N', 'E') /* The planes of the image */ - -int nplanes; - -/* BMHD from IFF documentation */ -typedef struct { - UWORD w, h; - WORD x, y; - UBYTE nPlanes; - UBYTE masking; - UBYTE compression; - UBYTE reserved1; - UWORD transparentColor; - UBYTE xAspect, yAspect; - WORD pageWidth, pageHeight; -} BitMapHeader; - -typedef struct { - UBYTE r, g, b; -} AmiColorMap; - -pixel pixels[TILE_Y][TILE_X]; -AmiColorMap *cmap; - -void -error(char *str) -{ - fprintf(stderr, "ERROR: %s\n", str); -} - -char **planes; - -main(int argc, char **argv) -{ - int colors; - struct { - long nplanes; - long pbytes; - long across; - long down; - long npics; - long xsize; - long ysize; - } pdat; - long pbytes; /* Bytes of data in a plane */ - int i, cnt; - BitMapHeader bmhd; - struct IFFHandle *iff; - long camg = HIRES | LACE; - int tiles = 0; - int index; - -#if defined(_DCC) || defined(__GNUC__) - IFFParseBase = OpenLibrary("iffparse.library", 0); - if (!IFFParseBase) { - error("unable to open iffparse.library"); - exit(1); - } -#endif - - if (fopen_xpm_file(argv[1], "r") != TRUE) { - perror(argv[1]); - return (1); - } - - nplanes = 0; - i = XpmScreen.Colors - 1; - while (i != 0) { - nplanes++; - i >>= 1; - } - - planes = malloc(nplanes * sizeof(char *)); - if (planes == 0) { - error("can not allocate planes pointer"); - exit(1); - } - - XpmScreen.BytesPerRow = ((XpmScreen.Width + 15) / 16) * 2; - pbytes = XpmScreen.BytesPerRow * XpmScreen.Height; - for (i = 0; i < nplanes; ++i) { - planes[i] = malloc(pbytes); - if (planes[i] == 0) { - error("can not allocate planes pointer"); - exit(1); - } - memset(planes[i], 0, pbytes); - } - - iff = AllocIFF(); - if (!iff) { - error("Can not allocate IFFHandle"); - return (1); - } - - iff->iff_Stream = Open(argv[2], MODE_NEWFILE); - if (!iff->iff_Stream) { - error("Can not open output file"); - return (1); - } - - InitIFFasDOS(iff); - OpenIFF(iff, IFFF_WRITE); - - PushChunk(iff, ID_BMAP, ID_FORM, IFFSIZE_UNKNOWN); - - bmhd.w = XpmScreen.Width; - bmhd.h = XpmScreen.Height; - bmhd.x = 0; - bmhd.y = 0; - bmhd.nPlanes = nplanes; - bmhd.masking = 0; - bmhd.compression = 0; - bmhd.reserved1 = 0; - bmhd.transparentColor = 0; - bmhd.xAspect = 100; - bmhd.yAspect = 100; - bmhd.pageWidth = 0; /* not needed for this program */ - bmhd.pageHeight = 0; /* not needed for this program */ - - PushChunk(iff, ID_BMAP, ID_BMHD, sizeof(bmhd)); - WriteChunkBytes(iff, &bmhd, sizeof(bmhd)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_CAMG, sizeof(camg)); - WriteChunkBytes(iff, &camg, sizeof(camg)); - PopChunk(iff); - -#define SCALE(x) (x) - cmap = malloc((colors = (1L << nplanes)) * sizeof(AmiColorMap)); - if (cmap == 0) { - error("Can't allocate color map"); - exit(1); - } - for (index = 0; index < 256; index++) { - if (ttable[index].flag) { - cmap[ttable[index].slot].r = SCALE(ttable[index].r); - cmap[ttable[index].slot].g = SCALE(ttable[index].g); - cmap[ttable[index].slot].b = SCALE(ttable[index].b); - } - } -#undef SCALE - - PushChunk(iff, ID_BMAP, ID_CMAP, IFFSIZE_UNKNOWN); - WriteChunkBytes(iff, cmap, colors * sizeof(*cmap)); - PopChunk(iff); - - conv_image(); - - pdat.nplanes = nplanes; - pdat.pbytes = pbytes; - pdat.xsize = XpmScreen.Width; - pdat.ysize = XpmScreen.Height; - pdat.across = 0; - pdat.down = 0; - pdat.npics = 1; - - PushChunk(iff, ID_BMAP, ID_PDAT, IFFSIZE_UNKNOWN); - WriteChunkBytes(iff, &pdat, sizeof(pdat)); - PopChunk(iff); - - PushChunk(iff, ID_BMAP, ID_PLNE, IFFSIZE_UNKNOWN); - for (i = 0; i < nplanes; ++i) - WriteChunkBytes(iff, planes[i], pbytes); - PopChunk(iff); - - CloseIFF(iff); - Close(iff->iff_Stream); - FreeIFF(iff); - -#if defined(_DCC) || defined(__GNUC__) - CloseLibrary(IFFParseBase); -#endif - exit(0); -} - -#define SETBIT(Plane, Plane_offset, Col, Value) \ - if (Value) { \ - planes[Plane][Plane_offset + (Col / 8)] |= 1 << (7 - (Col & 7)); \ - } - -conv_image() -{ - int row, col, planeno; - - for (row = 0; row < XpmScreen.Height; row++) { - char *xb = xpmgetline(); - int plane_offset; - if (xb == 0) - return; - plane_offset = row * XpmScreen.BytesPerRow; - for (col = 0; col < XpmScreen.Width; col++) { - int slot; - int color = xb[col]; - if (!ttable[color].flag) { - fprintf(stderr, "Bad image data\n"); - } - slot = ttable[color].slot; - for (planeno = 0; planeno < nplanes; planeno++) { - SETBIT(planeno, plane_offset, col, slot & (1 << planeno)); - } - } - } -} - -long * -alloc(unsigned int n) -{ - long *ret = malloc(n); - if (!ret) { - error("Can't allocate memory"); - exit(1); - } - return (ret); -} - -FILE *xpmfh = 0; -char initbuf[200]; -char *xpmbuf = initbuf; - -/* version 1. Reads the raw xpm file, NOT the compiled version. This is - * not a particularly good idea but I don't have time to do the right thing - * at this point, even if I was absolutely sure what that was. */ -fopen_xpm_file(const char *fn, const char *mode) -{ - int temp; - char *xb; - if (strcmp(mode, "r")) - return FALSE; /* no choice now */ - if (xpmfh) - return FALSE; /* one file at a time */ - xpmfh = fopen(fn, mode); - if (!xpmfh) - return FALSE; /* I'm hard to please */ - - /* read the header */ - xb = xpmgetline(); - if (xb == 0) - return FALSE; - if (4 != sscanf(xb, "%d %d %d %d", &XpmScreen.Width, &XpmScreen.Height, - &XpmScreen.Colors, &temp)) - return FALSE; /* bad header */ - /* replace the original buffer with one big enough for - * the real data - */ - /* XXX */ - xpmbuf = malloc(XpmScreen.Width * 2); - if (!xpmbuf) { - error("Can't allocate line buffer"); - exit(1); - } - if (temp != 1) - return FALSE; /* limitation of this code */ - - { - /* read the colormap and translation table */ - int ccount = -1; - while (ccount++ < (XpmScreen.Colors - 1)) { - char index; - int r, g, b; - xb = xpmgetline(); - if (xb == 0) - return FALSE; - if (4 != sscanf(xb, "%c c #%2x%2x%2x", &index, &r, &g, &b)) { - fprintf(stderr, "Bad color entry: %s\n", xb); - return FALSE; - } - ttable[index].flag = 1; /* this color is valid */ - ttable[index].r = r; - ttable[index].g = g; - ttable[index].b = b; - ttable[index].slot = ccount; - } - } - return TRUE; -} - -/* This deserves better. Don't read it too closely - you'll get ill. */ -#define bufsz 2048 -char buf[bufsz]; -xpmgetline() -{ - char *bp; - do { - if (fgets(buf, bufsz, xpmfh) == 0) - return 0; - } while (buf[0] != '"'); - /* strip off the trailing <",> if any */ - for (bp = buf; *bp; bp++) - ; - bp--; - while (isspace(*bp)) - bp--; - if (*bp == ',') - bp--; - if (*bp == '"') - bp--; - bp++; - *bp = '\0'; - - return &buf[1]; -} diff --git a/outdated/sys/atari/.gitattributes b/outdated/sys/atari/.gitattributes index db7b27210..b51126e53 100644 --- a/outdated/sys/atari/.gitattributes +++ b/outdated/sys/atari/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_Atari_version_-_untested_for_3.7) +* NH_filestag=(file%s_for_Atari_version_-_untested_for_5.0) diff --git a/outdated/sys/be/.gitattributes b/outdated/sys/be/.gitattributes index 38ec7931e..f7d41ab76 100644 --- a/outdated/sys/be/.gitattributes +++ b/outdated/sys/be/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_BeOS_version_-_untested_for_3.7) +* NH_filestag=(file%s_for_BeOS_version_-_untested_for_5.0) diff --git a/outdated/sys/os2/.gitattributes b/outdated/sys/os2/.gitattributes index 4041868ff..7859972d3 100644 --- a/outdated/sys/os2/.gitattributes +++ b/outdated/sys/os2/.gitattributes @@ -1,2 +1,2 @@ Makefile.* NHSUBST -* NH_filestag=(file%s_for_OS/2_version_-_untested_for_3.7) +* NH_filestag=(file%s_for_OS/2_version_-_untested_for_5.0) diff --git a/outdated/sys/unix/hints/cross-amiga b/outdated/sys/unix/hints/cross-amiga index ac66b6046..f21e9bfbc 100644 --- a/outdated/sys/unix/hints/cross-amiga +++ b/outdated/sys/unix/hints/cross-amiga @@ -1,4 +1,4 @@ -# NetHack 3.7 cross-amiga +# NetHack 3.6 cross-amiga # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/include/cross-amiga-post b/outdated/sys/unix/hints/include/cross-amiga-post index b3f5baf93..74de334cf 100644 --- a/outdated/sys/unix/hints/include/cross-amiga-post +++ b/outdated/sys/unix/hints/include/cross-amiga-post @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-amiga-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.6 include/cross-amiga-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ # # Cross-compiling -POST section for Amiga diff --git a/outdated/sys/unix/hints/include/cross-amiga-pre b/outdated/sys/unix/hints/include/cross-amiga-pre index 2d5b24ede..afaadbba2 100644 --- a/outdated/sys/unix/hints/include/cross-amiga-pre +++ b/outdated/sys/unix/hints/include/cross-amiga-pre @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-amiga-pre +# NetHack 3.6 include/cross-amiga-pre # # Cross-compiling -PRE section for amiga # @@ -141,7 +141,7 @@ override TARGET_CFLAGS = -c -O $(TOOLARCH) \ -I../outdated/sys/amiga -I../win/share \ $(LUAINCL) -DAMIGA -DTILES_IN_GLYPHMAP $(PDCURSESDEF) \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_AMIGA \ - -DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0\"" + -DAMIGA_VERSION_STRING=\""VER: NetHack 3.6.0\"" # -DMICRO -DPATHLEN=31 -DFILENAME=80 override TARGET_CXXFLAGS = $(TARGET_CFLAGS) ifeq "$(REGEXOBJ)" "$(TARGETPFX)cppregex.o" diff --git a/outdated/sys/unix/hints/linux b/outdated/sys/unix/hints/linux index 48ab631c1..73220fce7 100644 --- a/outdated/sys/unix/hints/linux +++ b/outdated/sys/unix/hints/linux @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux $NHDT-Date: 1596498415 2020/08/03 23:46:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# NetHack 3.6 linux $NHDT-Date: 1596498415 2020/08/03 23:46:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/linux-qt4 b/outdated/sys/unix/hints/linux-qt4 index 3ef04923d..a199fdaa8 100644 --- a/outdated/sys/unix/hints/linux-qt4 +++ b/outdated/sys/unix/hints/linux-qt4 @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux-qt4 $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ +# NetHack 3.6 linux-qt4 $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/linux-qt5 b/outdated/sys/unix/hints/linux-qt5 index 7d24406e0..2b30e9690 100644 --- a/outdated/sys/unix/hints/linux-qt5 +++ b/outdated/sys/unix/hints/linux-qt5 @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux-qt5 $NHDT-Date: 1596498417 2020/08/03 23:46:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ +# NetHack 3.6 linux-qt5 $NHDT-Date: 1596498417 2020/08/03 23:46:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/linux-x11 b/outdated/sys/unix/hints/linux-x11 index 64dc9c235..2e8599de1 100644 --- a/outdated/sys/unix/hints/linux-x11 +++ b/outdated/sys/unix/hints/linux-x11 @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux-x11 $NHDT-Date: 1596498418 2020/08/03 23:46:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ +# NetHack 3.6 linux-x11 $NHDT-Date: 1596498418 2020/08/03 23:46:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx b/outdated/sys/unix/hints/macosx index c74742396..2853d5911 100644 --- a/outdated/sys/unix/hints/macosx +++ b/outdated/sys/unix/hints/macosx @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx $NHDT-Date: 1596498419 2020/08/03 23:46:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ +# NetHack 3.6 macosx $NHDT-Date: 1596498419 2020/08/03 23:46:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.10 b/outdated/sys/unix/hints/macosx10.10 index 262a8af33..e87538182 100644 --- a/outdated/sys/unix/hints/macosx10.10 +++ b/outdated/sys/unix/hints/macosx10.10 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.11 $NHDT-Date: 1596498420 2020/08/03 23:47:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ +# NetHack 3.6 macosx10.11 $NHDT-Date: 1596498420 2020/08/03 23:47:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.10-qt b/outdated/sys/unix/hints/macosx10.10-qt index 99899ec1e..5c0c4e2af 100644 --- a/outdated/sys/unix/hints/macosx10.10-qt +++ b/outdated/sys/unix/hints/macosx10.10-qt @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.10-qt $NHDT-Date: 1597704795 2020/08/17 22:53:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ +# NetHack 3.6 macosx10.10-qt $NHDT-Date: 1597704795 2020/08/17 22:53:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.14 b/outdated/sys/unix/hints/macosx10.14 index 79454a7ae..402cd0cc0 100644 --- a/outdated/sys/unix/hints/macosx10.14 +++ b/outdated/sys/unix/hints/macosx10.14 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.14 $NHDT-Date: 1596498422 2020/08/03 23:47:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ +# NetHack 3.6 macosx10.14 $NHDT-Date: 1596498422 2020/08/03 23:47:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.5 b/outdated/sys/unix/hints/macosx10.5 index b4a5def41..29eacc428 100644 --- a/outdated/sys/unix/hints/macosx10.5 +++ b/outdated/sys/unix/hints/macosx10.5 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.5 $NHDT-Date: 1596498424 2020/08/03 23:47:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.34 $ +# NetHack 3.6 macosx10.5 $NHDT-Date: 1596498424 2020/08/03 23:47:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.34 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.7 b/outdated/sys/unix/hints/macosx10.7 index e307e0ec8..3c371c9fb 100644 --- a/outdated/sys/unix/hints/macosx10.7 +++ b/outdated/sys/unix/hints/macosx10.7 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.7 $NHDT-Date: 1596498424 2020/08/03 23:47:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ +# NetHack 3.6 macosx10.7 $NHDT-Date: 1596498424 2020/08/03 23:47:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/unix/hints/macosx10.8 b/outdated/sys/unix/hints/macosx10.8 index 0961bb198..8f7aea25a 100644 --- a/outdated/sys/unix/hints/macosx10.8 +++ b/outdated/sys/unix/hints/macosx10.8 @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.8 $NHDT-Date: 1596498425 2020/08/03 23:47:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ +# NetHack 3.6 macosx10.8 $NHDT-Date: 1596498425 2020/08/03 23:47:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009. # NetHack may be freely redistributed. See license for details. # diff --git a/outdated/sys/vms/lev_lex.h b/outdated/sys/vms/lev_lex.h index 2198df851..a6d8a62cf 100644 --- a/outdated/sys/vms/lev_lex.h +++ b/outdated/sys/vms/lev_lex.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 lev_lex.h $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.6 lev_lex.h $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.9 $ */ /* "vms/lev_lex.h" copied into "util/stdio.h" for use in *_lex.c only! * This is an awful kludge to allow util/*_lex.c made by SunOS's `lex' * to be compiled as is. (It isn't needed with `flex' or VMS POSIX diff --git a/outdated/sys/wince/.gitattributes b/outdated/sys/wince/.gitattributes index 0742a1d02..340366cbb 100644 --- a/outdated/sys/wince/.gitattributes +++ b/outdated/sys/wince/.gitattributes @@ -1,4 +1,4 @@ *.ce NHSUBST *.mak NHSUBST *.bat NHSUBST -* NH_filestag=(file%s_for_Windows_CE_and_PocketPC_-_untested_for_3.7) +* NH_filestag=(file%s_for_Windows_CE_and_PocketPC_-_untested_for_5.0) diff --git a/outdated/sys/wince/ceinc/.gitattributes b/outdated/sys/wince/ceinc/.gitattributes index 26a22a17d..5a72c68fc 100644 --- a/outdated/sys/wince/ceinc/.gitattributes +++ b/outdated/sys/wince/ceinc/.gitattributes @@ -1 +1 @@ -* NH_filestag=(header_file%s_for_Windows_CE_and_PocketPC_-_untested_for_3.7) +* NH_filestag=(header_file%s_for_Windows_CE_and_PocketPC_-_untested_for_5.0) diff --git a/outdated/sys/wince/winhack.rc b/outdated/sys/wince/winhack.rc index 504cc228e..99047d98a 100644 --- a/outdated/sys/wince/winhack.rc +++ b/outdated/sys/wince/winhack.rc @@ -300,7 +300,7 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "NetHack 3.7.0 for Windows CE\0" + VALUE "Comments", "NetHack 3.6.0 for Windows CE\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "nethackm\0" VALUE "FileVersion", "3, 7, 0, 0\0" diff --git a/outdated/sys/wince/winhcksp.rc b/outdated/sys/wince/winhcksp.rc index 959fba59c..e4b9ac50e 100644 --- a/outdated/sys/wince/winhcksp.rc +++ b/outdated/sys/wince/winhcksp.rc @@ -276,7 +276,7 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "NetHack 3.7.0 for Smartphone 2002\0" + VALUE "Comments", "NetHack 3.6.0 for Smartphone 2002\0" VALUE "CompanyName", " \0" VALUE "FileDescription", "nethackm\0" VALUE "FileVersion", "3, 7, 0, 0\0" diff --git a/outdated/win/Qt3/qt3_win.h b/outdated/win/Qt3/qt3_win.h index c5548e37c..e3a2076c1 100644 --- a/outdated/win/Qt3/qt3_win.h +++ b/outdated/win/Qt3/qt3_win.h @@ -1,4 +1,4 @@ -// NetHack 3.6 qt_win.h $NHDT-Date: 1575917700 2019/12/09 18:55:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +// NetHack 3.6 qt_win.h $NHDT-Date: 1575917700 2019/12/09 18:55:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.0 $ // Copyright (c) Warwick Allison, 1999. // NetHack may be freely redistributed. See license for details. // diff --git a/outdated/win/gem/.gitattributes b/outdated/win/gem/.gitattributes index 303f8dfcc..b78f4ea3d 100644 --- a/outdated/win/gem/.gitattributes +++ b/outdated/win/gem/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_GEM_versions_-_untested_for_3.7) +* NH_filestag=(file%s_for_GEM_versions_-_untested_for_5.0) diff --git a/outdated/win/gem/wingem.c b/outdated/win/gem/wingem.c index 078a2d2a7..65e599885 100644 --- a/outdated/win/gem/wingem.c +++ b/outdated/win/gem/wingem.c @@ -63,7 +63,7 @@ struct window_procs Gem_procs = { Gem_getlin, Gem_get_ext_cmd, Gem_number_pad, Gem_delay_output, #ifdef CHANGE_COLOR /* the Mac uses a palette device */ Gem_change_color, -#ifdef MAC +#ifdef MAC68K Gem_change_background, Gem_set_font_name, #endif Gem_get_color_string, @@ -76,7 +76,7 @@ struct window_procs Gem_procs = { genl_can_suspend_no, }; -#ifdef MAC +#ifdef MAC68K void * Gem_change_background(dummy) int dummy; diff --git a/outdated/win/gnome/.gitattributes b/outdated/win/gnome/.gitattributes index b5ad839b8..15f036561 100644 --- a/outdated/win/gnome/.gitattributes +++ b/outdated/win/gnome/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_GNOME_versions_-_untested_for_3.7) +* NH_filestag=(file%s_for_GNOME_versions_-_untested_for_5.0) diff --git a/sound/wav/README b/sound/wav/README index 00a0321ae..e7917b36c 100644 --- a/sound/wav/README +++ b/sound/wav/README @@ -13,7 +13,7 @@ Those had been removed in commit 217671e00f626e53d314757b4687950466efb360 in May 2019, at the same time built-in speaker support was removed. Some of those original files have been converted into wav files starting -with NetHack 3.7. The pitch variation versions offer a chance for very +with NetHack 5.0. The pitch variation versions offer a chance for very simple tune playback on platforms that offer a basic play-sound function call, which many do. There is no need to manipulate the underlying sounds with those, although sound library interfaces may certainly produce diff --git a/sound/wav/attributions.txt b/sound/wav/attributions.txt index 1a90447e1..43ce7b051 100644 --- a/sound/wav/attributions.txt +++ b/sound/wav/attributions.txt @@ -1,4 +1,4 @@ -/* NetHack 3.7 attributions.txt $NHDT-Date: 1652831519 2022/05/17 23:51:59 $ +/* NetHack 5.0 attributions.txt $NHDT-Date: 1652831519 2022/05/17 23:51:59 $ Attributions and credits and modifications for sounds used are listed below. diff --git a/sound/windsound/windsound.c b/sound/windsound/windsound.c index 0dc486f18..78077f435 100644 --- a/sound/windsound/windsound.c +++ b/sound/windsound/windsound.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 windsound.c $NHDT-Date: $ $NHDT-Branch: $NHDT-Revision: $ */ +/* NetHack 5.0 windsound.c $NHDT-Date: $ $NHDT-Branch: $NHDT-Revision: $ */ /* Copyright (c) Michael Allison, 2022 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/.gitattributes b/src/.gitattributes index a618fdc82..1a6ae3089 100644 --- a/src/.gitattributes +++ b/src/.gitattributes @@ -16,4 +16,4 @@ qt_xcmd.moc NH_filesgentag=>qt_kde0.moc qt_yndlg.moc NH_filesgentag=>qt_kde0.moc tile.c NH_filesgentag=(file%s_optionally_generated_by_tilemap_at_compile_time) -monstr.c NH_filesgentag=(file%s_generated_by_makedefs_-m_but_unused_in_3.7) +monstr.c NH_filesgentag=(file%s_generated_by_makedefs_-m_but_unused_in_5.0) diff --git a/src/.gitignore b/src/.gitignore index 30c020d13..5d660d4a5 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -33,3 +33,7 @@ GNUmakefile GNUmakefile.depend .*.c .depend +date-gui.nmk +date-tty.nmk + + diff --git a/src/allmain.c b/src/allmain.c index 2923f51a3..5136d18ff 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 allmain.c $NHDT-Date: 1771213100 2026/02/15 19:38:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ */ +/* NetHack 5.0 allmain.c $NHDT-Date: 1781973040 2026/06/20 16:30:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.304 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -22,15 +22,9 @@ staticfn void regen_pw(int); staticfn void regen_hp(int); staticfn void interrupt_multi(const char *); -#ifdef CRASHREPORT -#define USED_FOR_CRASHREPORT -#else -#define USED_FOR_CRASHREPORT UNUSED -#endif - /*ARGSUSED*/ void -early_init(int argc USED_FOR_CRASHREPORT, char *argv[] USED_FOR_CRASHREPORT) +early_init(int argc, char *argv[]) { program_state_init(); #ifdef CRASHREPORT @@ -42,6 +36,8 @@ early_init(int argc USED_FOR_CRASHREPORT, char *argv[] USED_FOR_CRASHREPORT) monst_globals_init(); sys_early_init(); runtime_info_init(); + nhUse(argc); + nhUse(argv[0]); } staticfn void @@ -210,7 +206,11 @@ moveloop_core(void) encumber_msg(); svc.context.mon_moving = TRUE; - gu.uhp_at_start_of_monster_turn = u.uhp; + /* call terrain_effects during mon_moving phase */ + if (gp.pending_terrain_effects) { + terrain_effects(); + gp.pending_terrain_effects = no_terrain_effects; + } do { monscanmove = movemon(); if (u.umovement >= NORMAL_SPEED) @@ -279,8 +279,6 @@ moveloop_core(void) if (u.ublesscnt) u.ublesscnt--; - gs.saving_grace_turn = FALSE; - /* One possible result of prayer is healing. Whether or * not you get healed depends on your current hit points. * If you are allowed to regenerate during the prayer, @@ -432,8 +430,6 @@ moveloop_core(void) else if (!u.umoved) (void) pooleffects(FALSE); - gs.saving_grace_turn = FALSE; - /* vision while buried or underwater is updated here */ if (Underwater) under_water(0); @@ -588,6 +584,9 @@ maybe_do_tutorial(void) vision_recalc(0); docrt(); iflags.nofollowers = FALSE; + } else { + /* no tutorial, so okay to process mention_decor now */ + rcfile_only_this_option(opt_mention_decor); } } @@ -599,6 +598,9 @@ moveloop(boolean resuming) if (!resuming) maybe_do_tutorial(); + /* process one deferred option post-tutorial */ + rcfile_only_this_option(opt_mention_decor); + for (;;) { moveloop_core(); } @@ -745,7 +747,7 @@ init_sound_disp_gamewindows(void) ever having been used, use it here to pacify the Qt interface */ start_menu(WIN_INVEN, menu_behavior), end_menu(WIN_INVEN, (char *) 0); -#ifdef MAC +#ifdef MAC68K /* This _is_ the right place for this - maybe we will * have to split init_sound_disp_gamewindows into * create_gamewindows and show_gamewindows to get rid of this ifdef... @@ -775,6 +777,17 @@ newgame(void) { int i; +#ifdef SYSCF + time_t last_reroll_time; + time_t cur_reroll_time; + int rerolls_this_second = 0; +# if defined(BSD) && !defined(POSIX_TYPES) +# define GET_REROLL_TIME(t) (void) time((long *) t); +# else +# define GET_REROLL_TIME(t) (void) time(t); +# endif +#endif /* defined(SYSCF) */ + /* make sure welcome messages are given before noticing monsters */ notice_mon_off(); disp.botlx = TRUE; @@ -783,6 +796,7 @@ newgame(void) svc.context.next_attrib_check = 600L; /* arbitrary first setting */ svc.context.tribute.enabled = TRUE; /* turn on 3.6 tributes */ svc.context.tribute.tributesz = sizeof(struct tribute_info); + get_nhuuid(); for (i = LOW_PM; i < NUMMONS; i++) svm.mvitals[i].mvflags = mons[i].geno & G_NOCORPSE; @@ -824,7 +838,32 @@ newgame(void) docrt(); flush_screen(1); bot(); + +#ifdef SYSCF + GET_REROLL_TIME(&last_reroll_time); +#endif + while (u.uroleplay.reroll && reroll_menu()) { +#ifdef SYSCF + if (sysopt.maxrerollrate > 0) { + check_reroll_time: + GET_REROLL_TIME(&cur_reroll_time); + + if (last_reroll_time != cur_reroll_time) { + last_reroll_time = cur_reroll_time; + rerolls_this_second = 1; + } else { + if (rerolls_this_second >= sysopt.maxrerollrate) { + if (!paranoid_query(TRUE, "Continue rerolling?")) + break; + goto check_reroll_time; + } + ++rerolls_this_second; + } + } +#endif + + ++u.uroleplay.numrerolls; u_init_inventory_attrs(); bot(); } @@ -841,10 +880,10 @@ newgame(void) urealtime.realtime = 0L; urealtime.start_timing = getnow(); + program_state.something_worth_saving++; /* useful data now exists */ #ifdef INSURANCE save_currentstate(); #endif - program_state.something_worth_saving++; /* useful data now exists */ /* Success! */ welcome(TRUE); @@ -865,7 +904,8 @@ welcome(boolean new_game) /* false => restoring an old game */ #endif char buf[BUFSZ]; - boolean currentgend = Upolyd ? u.mfemale : flags.female; + boolean currentgend = Upolyd ? u.mfemale : flags.female, + adrift = (u.ualign.type != u.ualignbase[A_CURRENT]); l_nhcore_call(new_game ? NHCORE_START_NEW_GAME : NHCORE_RESTORE_OLD_GAME); @@ -888,8 +928,30 @@ welcome(boolean new_game) /* false => restoring an old game */ * restores it's only shown if different from its original value. */ *buf = '\0'; +#if 0 if (new_game || u.ualignbase[A_ORIGINAL] != u.ualignbase[A_CURRENT]) Sprintf(eos(buf), " %s", align_str(u.ualignbase[A_ORIGINAL])); +#else + /* + * 2026-04-24 + * GitHub issue https://github.com/NetHack/NetHack/issues/537 + * "Judging by the comment above, it should display your new alignment + * if it was changed, so align_str(u.ualignbase[A_CURRENT]) would + * probably be more appropriate. This won't affect the new game message." + * + * That is followed by a suggestion to revisit the matter (paraphrased): + * "That's actually intentional; the comment oversimplifies. + * When it was implemented, it may have been the only way to tell that + * you had converted alignment. Now ^X mentions your starting alignment + * if base alignment has been changed, so revisiting this welcome back + * message." + */ + if (new_game || u.ualignbase[A_ORIGINAL] != u.ualignbase[A_CURRENT] || adrift) + Sprintf(eos(buf), " %s%s", + adrift ? "adrift " : "", + adrift ? align_str(u.ualign.type) + : align_str(u.ualignbase[A_CURRENT])); +#endif if (!gu.urole.name.f && (new_game ? (gu.urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE) diff --git a/src/alloc.c b/src/alloc.c index 05dfb502f..1861a04d6 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 alloc.c $NHDT-Date: 1737281026 2025/01/19 02:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ */ +/* NetHack 5.0 alloc.c $NHDT-Date: 1781973040 2026/06/20 16:30:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/apply.c b/src/apply.c index 40aefc3d9..5c7ac71ac 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1769342601 2026/01/25 04:03:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.475 $ */ +/* NetHack 5.0 apply.c $NHDT-Date: 1781973040 2026/06/20 16:30:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.482 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -390,7 +390,10 @@ use_stethoscope(struct obj *obj) } if ((mtmp = m_at(rx, ry)) != 0) { const char *mnm = x_monnam(mtmp, ARTICLE_A, (const char *) 0, - SUPPRESS_IT | SUPPRESS_INVISIBLE, FALSE); + (SUPPRESS_IT | SUPPRESS_INVISIBLE + /* stethoscope reveals true form; seemimic + below will clear mtmp->mappearance */ + | SUPPRESS_MAPPEARANCE), FALSE); /* gb.bhitpos needed by mstatusline() iff mtmp is a long worm */ gb.bhitpos.x = rx, gb.bhitpos.y = ry; @@ -3505,7 +3508,6 @@ use_pole(struct obj *obj, boolean autohit) return ECMD_FAIL; } - check_caitiff(mtmp); gn.notonhead = (gb.bhitpos.x != mtmp->mx || gb.bhitpos.y != mtmp->my); /* Snickersnee allows one free hit from a distance per turn */ @@ -3844,7 +3846,6 @@ use_grapple(struct obj *obj) flags.confirm = FALSE; (void) attack_checks(mtmp, uwep); flags.confirm = save_confirm; - check_caitiff(mtmp); (void) thitmonst(mtmp, uwep); return ECMD_TIME; } diff --git a/src/artifact.c b/src/artifact.c index e0e3df173..348f2108d 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 artifact.c $NHDT-Date: 1715889721 2024/05/16 20:02:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.236 $ */ +/* NetHack 5.0 artifact.c $NHDT-Date: 1781973041 2026/06/20 16:30:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.264 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/attrib.c b/src/attrib.c index 27f454fd8..16469fbcf 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 attrib.c $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ */ +/* NetHack 5.0 attrib.c $NHDT-Date: 1781973041 2026/06/20 16:30:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.142 $ */ /* Copyright 1988, 1989, 1990, 1992, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ @@ -683,7 +683,7 @@ rnd_attr(void) { int i, x = rn2(100); - /* 3.7: the x -= ... calculation used to have an off by 1 error that + /* 5.0: the x -= ... calculation used to have an off by 1 error that resulted in the values being biased toward Str and away from Cha */ for (i = 0; i < A_MAX; ++i) if ((x -= gu.urole.attrdist[i]) < 0) diff --git a/src/ball.c b/src/ball.c index 069a71ce4..1ed458319 100644 --- a/src/ball.c +++ b/src/ball.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 ball.c $NHDT-Date: 1596498150 2020/08/03 23:42:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 ball.c $NHDT-Date: 1781973041 2026/06/20 16:30:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) David Cohrs, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -808,7 +808,8 @@ drag_ball(coordxy x, coordxy y, int *bc_control, miss(xname(uball), victim); } /* now check again in case mon died */ - if (!m_at(uchain->ox, uchain->oy)) { + if (!m_at(uchain->ox, uchain->oy) + && in_out_region(uchain->ox, uchain->oy)) { u.ux = uchain->ox; u.uy = uchain->oy; newsym(u.ux0, u.uy0); @@ -820,6 +821,9 @@ drag_ball(coordxy x, coordxy y, int *bc_control, *ballx = uchain->ox; *bally = uchain->oy; move_bc(0, *bc_control, *ballx, *bally, *chainx, *chainy); + /* weirdness: you were dragged back on account of the ball falling + * into the pit, but if you escape the pit, the ball is "on top of" + * the pit and does not hinder your movement further */ spoteffects(TRUE); return FALSE; } @@ -932,10 +936,11 @@ drop_ball(coordxy x, coordxy y) && (is_pool(x, y) || ((t = t_at(x, y)) && (is_pit(t->ttyp) - || is_hole(t->ttyp))))) { + || is_hole(t->ttyp)))) + && in_out_region(x, y)) { u.ux = x; u.uy = y; - } else { + } else if (in_out_region(x - u.dx, y - u.dy)) { u.ux = x - u.dx; u.uy = y - u.dy; } diff --git a/src/bones.c b/src/bones.c index 5afb0cbcd..715580f98 100644 --- a/src/bones.c +++ b/src/bones.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 bones.c $NHDT-Date: 1701500709 2023/12/02 07:05:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */ +/* NetHack 5.0 bones.c $NHDT-Date: 1781973041 2026/06/20 16:30:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.159 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -471,6 +471,7 @@ savebones(int how, time_t when, struct obj *corpse) to be given here, but it has been moved to done() so that it gets delivered even when savebones() isn't called] */ drop_upon_death(mtmp, (struct obj *) 0, u.ux, u.uy); + assert(mtmp != NULL && mtmp->data != NULL); /* static analysis hack */ /* 'mtmp' now has hero's inventory; if 'mtmp' is a mummy, give it a wrapping unless already carrying one */ if (mtmp->data->mlet == S_MUMMY && !m_carrying(mtmp, MUMMY_WRAPPING)) @@ -611,6 +612,7 @@ savebones(int how, time_t when, struct obj *corpse) nhfp->mode = WRITING; store_version(nhfp); + Sfo_char(nhfp, &svn.nhuuid[0], "ancestor-nhuuid", sizeof svn.nhuuid); /* if a bones pool digit is in use, it precedes the bonesid string and isn't recorded in the file */ Sfo_char(nhfp, &c, "bones_count", 1); @@ -632,6 +634,7 @@ getbones(void) NHFILE *nhfp = (NHFILE *) 0; char c = 0, *bonesid, oldbonesid[40] = { 0 }; /* was [10]; more should be safer */ + char ancestor_nhuuid[SIZE(svn.nhuuid)]; #ifndef SFCTOOL if (discover) /* save bones files for real games */ @@ -657,19 +660,24 @@ getbones(void) return 0; } - if (validate(nhfp, gb.bones, FALSE) != SF_UPTODATE) { + program_state.reading_bonesfile = 1; + if (validate(nhfp, gb.bones, FALSE, 0) != SF_UPTODATE) { if (!wizard) pline("Discarding unusable bones; no need to panic..."); ok = FALSE; + program_state.reading_bonesfile = 0; } else { ok = TRUE; if (wizard) { if (y_n("Get bones?") == 'n') { close_nhfile(nhfp); compress_bonesfile(); + program_state.reading_bonesfile = 0; return 0; } } + Sfi_char(nhfp, &ancestor_nhuuid[0], "ancestor-nhuuid", + sizeof ancestor_nhuuid); Sfi_char(nhfp, &c, "bones_count", 1); /* length incl. '\0' */ if ((unsigned) c <= sizeof oldbonesid) { Sfi_char(nhfp, oldbonesid, "bonesid", (int) c); @@ -680,6 +688,7 @@ getbones(void) close_nhfile(nhfp); compress_bonesfile(); /* ToDo: maybe unlink these problematic bones? */ + program_state.reading_bonesfile = 0; return 0; } if (strcmp(bonesid, oldbonesid) != 0) { @@ -691,6 +700,7 @@ getbones(void) pline1(errbuf); ok = FALSE; /* won't die of trickery */ } + program_state.reading_bonesfile = 0; trickery(errbuf); } else { struct monst *mtmp; @@ -723,6 +733,7 @@ getbones(void) } } close_nhfile(nhfp); + program_state.reading_bonesfile = 0; sanitize_engravings(); u.uroleplay.numbones++; diff --git a/src/botl.c b/src/botl.c index 66c4b8950..301dc2b4c 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 botl.c $NHDT-Date: 1769839231 2026/01/30 22:00:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.277 $ */ +/* NetHack 5.0 botl.c $NHDT-Date: 1781973042 2026/06/20 16:30:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.286 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -714,7 +714,7 @@ static struct istat_s initblstats[MAXBLSTATS] = { INIT_BLSTAT("gold", " %s", ANY_LONG, 40, BL_GOLD), INIT_BLSTATP("power", " Pw:%s", ANY_INT, 10, BL_ENEMAX, BL_ENE), INIT_BLSTAT("power-max", "(%s)", ANY_INT, 10, BL_ENEMAX), - INIT_BLSTATP("experience-level", " Xp:%s", ANY_INT, 10, BL_EXP, BL_XP), + INIT_BLSTATP("experience-level", " Xp:%s", ANY_INT, 10, BL_XP, BL_XP), INIT_BLSTAT("armor-class", " AC:%s", ANY_INT, 10, BL_AC), INIT_BLSTAT("HD", " HD:%s", ANY_INT, 10, BL_HD), INIT_BLSTAT("time", " T:%s", ANY_LONG, 30, BL_TIME), @@ -4539,9 +4539,13 @@ status_hilite_menu(void) #endif any = cg.zeroany; any.a_int = fld + 1; - Sprintf(buf, "%-18s", initblstats[i].fldname); + if (iflags.menu_tab_sep) { + Sprintf(buf, "%s\t", initblstats[i].fldname); + } else { + Sprintf(buf, "%-18s ", initblstats[i].fldname); + } if (count) - Sprintf(eos(buf), " (%d defined)", count); + Sprintf(eos(buf), "(%d defined)", count); add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); } diff --git a/src/calendar.c b/src/calendar.c index 5a5287b2a..61f984cfc 100644 --- a/src/calendar.c +++ b/src/calendar.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 calendar.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 calendar.c $NHDT-Date: 1781973042 2026/06/20 16:30:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* Copyright (c) Robert Patrick Rankin, 1991 */ diff --git a/src/cfgfiles.c b/src/cfgfiles.c index 2ba0c2fde..08db400d6 100644 --- a/src/cfgfiles.c +++ b/src/cfgfiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cfgfiles.c $NHDT-Date: 1740532826 2025/02/25 17:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.417 $ */ +/* NetHack 5.0 cfgfiles.c $NHDT-Date: 1781973042 2026/06/20 16:30:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.23 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -9,7 +9,7 @@ #include "dlb.h" #include -#if (!defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ +#if (!defined(MAC68K) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ || defined(USE_FCNTL) #include #endif @@ -35,6 +35,9 @@ staticfn char *is_config_section(char *); staticfn boolean handle_config_section(char *); boolean parse_config_line(char *); staticfn char *find_optparam(char *); +#ifdef WIN32 +staticfn boolean portable_sysconf_only_this_statement(int); +#endif #ifndef SFCTOOL staticfn boolean cnf_line_OPTIONS(char *); staticfn boolean cnf_line_AUTOPICKUP_EXCEPTION(char *); @@ -71,6 +74,7 @@ staticfn boolean cnf_line_CHECK_PLNAME(char *); staticfn boolean cnf_line_SEDUCE(char *); staticfn boolean cnf_line_HIDEUSAGE(char *); staticfn boolean cnf_line_MAXPLAYERS(char *); +staticfn boolean cnf_line_MAX_REROLL_RATE(char *); staticfn boolean cnf_line_PERSMAX(char *); staticfn boolean cnf_line_PERS_IS_UID(char *); staticfn boolean cnf_line_ENTRYMAX(char *); @@ -108,7 +112,7 @@ staticfn void cnf_parser_init(struct _cnf_parser_state *parser); staticfn void cnf_parser_done(struct _cnf_parser_state *parser); staticfn void parse_conf_buf(struct _cnf_parser_state *parser, boolean (*proc)(char *arg)); -/* next one is in extern.h; why here too? */ + /* next one is in extern.h; why here too? */ boolean parse_conf_str(const char *str, boolean (*proc)(char *arg)); static boolean ignore_errors_on_unmatched = FALSE, ignore_statement_errors = FALSE; @@ -127,7 +131,7 @@ static const char *default_configfile = #ifdef UNIX ".nethackrc"; #else -#if defined(MAC) || defined(__BEOS__) +#if defined(MAC68K) || defined(__BEOS__) "NetHack Defaults"; #else #if defined(MSDOS) || defined(WIN32) @@ -276,7 +280,7 @@ fopen_config_file(const char *filename, int src) } /* fall through to standard names */ -#if defined(MICRO) || defined(MAC) || defined(__BEOS__) || defined(WIN32) +#if defined(MICRO) || defined(MAC68K) || defined(__BEOS__) || defined(WIN32) set_configfile_name(fqname(default_configfile, CONFIGPREFIX, 0)); if ((fp = fopen(configfile, "r")) != (FILE *) 0) { return fp; @@ -367,7 +371,7 @@ fopen_config_file(const char *filename, int src) wait_synch(); } #endif /* !VMS => Unix */ -#endif /* !(MICRO || MAC || __BEOS__ || WIN32) */ +#endif /* !(MICRO || MAC68K || __BEOS__ || WIN32) */ return (FILE *) 0; } @@ -965,6 +969,19 @@ cnf_line_MAXPLAYERS(char *bufp) return TRUE; } +staticfn boolean +cnf_line_MAX_REROLL_RATE(char *bufp) +{ + int n = atoi(bufp); + + if (n < 0 || n > 255) { + config_error_add("Illegal value in MAX_REROLL_RATE (maximum is 255)"); + n = 10; + } + sysopt.maxrerollrate = n; + return TRUE; +} + staticfn boolean cnf_line_PERSMAX(char *bufp) { @@ -1346,6 +1363,7 @@ static const struct match_config_line_stmt { CNFL_S(SEDUCE, 6), CNFL_S(HIDEUSAGE, 9), CNFL_S(MAXPLAYERS, 10), + CNFL_S(MAX_REROLL_RATE, 10), CNFL_S(PERSMAX, 7), CNFL_S(PERS_IS_UID, 11), CNFL_S(ENTRYMAX, 8), @@ -1956,24 +1974,6 @@ rcfile(void) /*[end of nethackrc handling]*/ } -void -rcfile_interface_options(void) -{ - allopt_array_init(); - disregard_all_options(); - disregard_all_config_statements(); - heed_this_option(opt_windowtype); - heed_this_option(opt_soundlib); - set_ignore_errors_on_unmatched(); - ignore_statement_errors = TRUE; - rcfile(); - heed_all_config_statements(); - heed_all_options(); - disregard_this_option(opt_windowtype); - disregard_this_option(opt_soundlib); - clear_ignore_errors_on_unmatched(); - ignore_statement_errors = FALSE; -} void heed_all_config_statements(void) @@ -2023,6 +2023,162 @@ config_unmatched_ignored(void) return TRUE; return FALSE; } +void +rcfile_interface_options(void) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_option(opt_windowtype); + heed_this_option(opt_soundlib); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + disregard_this_option(opt_windowtype); + disregard_this_option(opt_soundlib); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} + +void +rcfile_only_this_option(enum opt heeded_option) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_option(heeded_option); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} + +void +rcfile_only_this_statement(int statementid) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_config_statement(statementid); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} + +#ifdef WIN32 +extern char portable_device_path[_MAX_PATH]; /* windsys.c */ +extern boolean portable; + +staticfn boolean +portable_sysconf_only_this_statement(int statementid) +{ + const char *exepath; + char portable_sysconf[_MAX_PATH]; + + exepath = windows_exepath(); + if (exepath) { + Snprintf(portable_sysconf, sizeof portable_sysconf, "%s/sysconf", + exepath); + if (portable_sysconf[0] && file_exists(portable_sysconf)) { +#ifdef SYSCF +#ifdef SYSCF_FILE + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_config_statement(statementid); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + + config_error_init(TRUE, portable_sysconf, FALSE); + go.opt_phase = syscf_opt; + (void) read_config_file(portable_sysconf, set_in_sysconf); + config_error_done(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; + if (sysopt.portable_device_paths) { + Snprintf(portable_device_path, sizeof portable_device_path, + "%s\\", exepath); + return TRUE; + } +#endif +#endif /* SYSCF */ + } + } + return FALSE; +} + +boolean +check_for_portable_config(void) +{ + int i, target_index = -1; + + for (i = 0; i < SIZE(config_line_stmt); i++) { + if (!strcmp(config_line_stmt[i].name, "PORTABLE_DEVICE_PATHS")) { + target_index = i; + break; + } + } + if (target_index >= 0) { + return portable_sysconf_only_this_statement(target_index); + } + return FALSE; +} +#endif + +#ifdef MSWIN_GRAPHICS +void +disregard_some_mswin_options(void) +{ + /* later for these */ + disregard_this_option(opt_map_mode); + disregard_this_option(opt_font_map); + disregard_this_option(opt_font_menu); + disregard_this_option(opt_font_message); + disregard_this_option(opt_font_status); + + disregard_this_option(opt_font_size_map); + disregard_this_option(opt_font_size_menu); + disregard_this_option(opt_font_size_message); + disregard_this_option(opt_font_size_status); +} + +void +rcfile_only_some_mswin_options(void) +{ + allopt_array_init(); + disregard_all_options(); + disregard_all_config_statements(); + heed_this_option(opt_map_mode); + heed_this_option(opt_font_map); + heed_this_option(opt_font_menu); + heed_this_option(opt_font_message); + heed_this_option(opt_font_status); + + heed_this_option(opt_font_size_map); + heed_this_option(opt_font_size_menu); + heed_this_option(opt_font_size_message); + heed_this_option(opt_font_size_status); + set_ignore_errors_on_unmatched(); + ignore_statement_errors = TRUE; + rcfile(); + heed_all_config_statements(); + heed_all_options(); + clear_ignore_errors_on_unmatched(); + ignore_statement_errors = FALSE; +} +#endif /* MSWIN_GRAPHICS */ + #endif /* SFCTOOL */ #ifdef SYSCF diff --git a/src/cmd.c b/src/cmd.c index de20c283b..beeba8780 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.755 $ */ +/* NetHack 5.0 cmd.c $NHDT-Date: 1781973043 2026/06/20 16:30:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.772 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -674,10 +674,15 @@ doextlist(void) add_menu_heading(menuwin, buf); menushown[pass] = 1; } - /* longest ef_txt at present is "wizrumorcheck" (13 chars); - 2nd field will be " " or " [A]" or " [m]" or "[mA]" */ - Sprintf(buf, " %-14s %4s %s", efp->ef_txt, - doc_extcmd_flagstr(menuwin, efp), cmd_desc); + if (iflags.menu_tab_sep) { + Sprintf(buf, " %s\t%s\t%s", efp->ef_txt, + doc_extcmd_flagstr(menuwin, efp), cmd_desc); + } else { + /* longest ef_txt at present is "wizrumorcheck" (13 chars); + 2nd field will be " " or " [A]" or " [m]" or "[mA]" */ + Sprintf(buf, " %-14s %4s %s", efp->ef_txt, + doc_extcmd_flagstr(menuwin, efp), cmd_desc); + } add_menu_str(menuwin, buf); ++n; } @@ -1735,8 +1740,8 @@ struct ext_func_tab extcmdlist[] = { dohelp, IFBURIED | GENERALCMD, NULL }, { '\0', "herecmdmenu", "show menu of commands you can do here", doherecmdmenu, IFBURIED | AUTOCOMPLETE | GENERALCMD, NULL }, - { '\0', "history", "show long version and game history", - dohistory, IFBURIED | GENERALCMD, NULL }, + { '\0', "history", "show a summary of the game's development", + dohistory, IFBURIED | AUTOCOMPLETE | GENERALCMD, NULL }, { 'i', "inventory", "show your inventory", ddoinv, IFBURIED | GENERALCMD, NULL }, { 'I', "inventtype", "show inventory of one specific item class", @@ -1989,6 +1994,8 @@ struct ext_func_tab extcmdlist[] = { wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { '\0', "wizseenv", "show map locations' seen vectors", wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, + { '\0', "wizshownhuuid", "show NHUUID for this game", + wiz_show_nhuuid, AUTOCOMPLETE | WIZMODECMD, NULL }, { '\0', "wizsmell", "smell monster", wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL }, { '\0', "wiztelekinesis", "telekinesis", @@ -2297,7 +2304,9 @@ handler_rebind_keys_add(boolean keyfirst) char buf2[QBUFSZ]; uchar key = '\0'; int clr = NO_COLOR; + char cmdstr[BUFSZ]; + cmdstr[0] = '\0'; if (keyfirst) { pline("Bind which key? "); key = pgetchar(); @@ -2351,7 +2360,6 @@ handler_rebind_keys_add(boolean keyfirst) destroy_nhwindow(win); if (npick > 0) { struct Cmd_bind *prevcmd; - char cmdstr[BUFSZ]; i = picks->item.a_int; free((genericptr_t) picks); @@ -2491,7 +2499,8 @@ handler_change_autocompletions(void) if (strlen(ec->ef_txt) < 2) continue; - Sprintf(buf, "%s", ec->ef_txt); + /* switched to Snprintf to eliminate -Wformat-overflow warning */ + Snprintf(buf, sizeof buf, "%s", ec->ef_txt); for (j = 0; j < n; ++j) { if (ec == &extcmdlist[(picks[j].item.a_int - 1)]) { @@ -2954,7 +2963,7 @@ dokeylist(void) Sprintf(buf, "%-7s", key2txt(key, buf2)); #else /* first of the keyless commands */ - Sprintf(buf2, "[%s]", key2txt(key, buf)); + Snprintf(buf2, sizeof buf2, "[%s]", key2txt(key, buf)); Sprintf(buf, "%-21s", buf2); #endif Strcat(buf, " interrupt: break out of NetHack (SIGINT)"); @@ -4405,11 +4414,16 @@ enum menucmd { MCMD_REST, MCMD_LOOK_HERE, MCMD_LOOK_AT, + MCMD_PRAY, + MCMD_ENGRAVE, + MCMD_ATTRIBUTES, + MCMD_PREVIOUS_MESSAGES, MCMD_ATTACK_NEXT2U, MCMD_UNTRAP_HERE, MCMD_OFFER, MCMD_INVENTORY, MCMD_CAST_SPELL, + MCMD_JUMP, MCMD_THROW_OBJ, MCMD_TRAVEL, @@ -4505,6 +4519,10 @@ there_cmd_menu_self(winid win, coordxy x, coordxy y, int *act UNUSED) mcmd_addmenu(win, MCMD_REST, "Rest one turn"), ++K; mcmd_addmenu(win, MCMD_SEARCH, "Search around you"), ++K; mcmd_addmenu(win, MCMD_LOOK_HERE, "Look at what is here"), ++K; + mcmd_addmenu(win, MCMD_PRAY, "Pray here"), ++K; + mcmd_addmenu(win, MCMD_ENGRAVE, "Engrave here"), ++K; + mcmd_addmenu(win, MCMD_ATTRIBUTES, "View attributes"), ++K; + mcmd_addmenu(win, MCMD_PREVIOUS_MESSAGES, "Access memories"), ++K; if (num_spells() > 0) mcmd_addmenu(win, MCMD_CAST_SPELL, "Cast a spell"), ++K; @@ -4514,6 +4532,9 @@ there_cmd_menu_self(winid win, coordxy x, coordxy y, int *act UNUSED) mcmd_addmenu(win, MCMD_UNTRAP_HERE, "Attempt to disarm trap"), ++K; } + if (Jumping) { + mcmd_addmenu(win, MCMD_JUMP, "Jump"), ++K; + } return K; } @@ -4803,7 +4824,7 @@ act_on_act( cmdq_add_key(CQ_CANNED, 'y'); /* "There is foo here; eat it?" */ break; case MCMD_DROP: - cmdq_add_ec(CQ_CANNED, dodrop); + cmdq_add_ec(CQ_CANNED, doddrop); break; case MCMD_INVENTORY: cmdq_add_ec(CQ_CANNED, ddoinv); @@ -4819,6 +4840,18 @@ act_on_act( gc.clicklook_cc.y = u.uy + dy; cmdq_add_ec(CQ_CANNED, doclicklook); break; + case MCMD_PRAY: + cmdq_add_ec(CQ_CANNED, dopray); + break; + case MCMD_ENGRAVE: + cmdq_add_ec(CQ_CANNED, doengrave); + break; + case MCMD_ATTRIBUTES: + cmdq_add_ec(CQ_CANNED, doattributes); + break; + case MCMD_PREVIOUS_MESSAGES: + cmdq_add_key(CQ_CANNED, C('p')); + break; case MCMD_UNTRAP_HERE: cmdq_add_ec(CQ_CANNED, dountrap); cmdq_add_dir(CQ_CANNED, 0, 0, 1); @@ -4830,6 +4863,9 @@ act_on_act( case MCMD_CAST_SPELL: cmdq_add_ec(CQ_CANNED, docast); break; + case MCMD_JUMP: + cmdq_add_ec(CQ_CANNED, dojump); + break; default: break; } diff --git a/src/coloratt.c b/src/coloratt.c index 436e9274e..d8685b919 100644 --- a/src/coloratt.c +++ b/src/coloratt.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 coloratt.c $NHDT-Date: 1737286550 2025/01/19 03:35:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 coloratt.c $NHDT-Date: 1781973043 2026/06/20 16:30:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) Pasi Kallinen, 2024 */ /* NetHack may be freely redistributed. See license for details. */ @@ -58,172 +58,183 @@ static const struct attr_names attrnames[] = { { "reverse", ATR_INVERSE }, }; -/* { colortyp, tableindex, rgbindx, name, hexval, r, g, b }, */ +/* { colortyp, tableindex, rgbindx, name, r, g, b }, */ -static struct nethack_color colortable[] = { - { nh_color, 0, 0, "black", "", 0, 0, 0 }, - { nh_color, 1, 0, "red", "", 255, 0, 0 }, - { nh_color, 2, 0, "green", "", 34, 139, 34 }, - { nh_color, 3, 0, "brown", "", 165, 42, 42 }, - { nh_color, 4, 0, "blue", "", 0, 0, 255 }, - { nh_color, 5, 0, "magenta", "", 255, 0, 255 }, - { nh_color, 6, 0, "cyan", "", 0, 255, 255 }, - { nh_color, 7, 0, "gray", "", 128, 128, 128 }, - { no_color, 8, 0, "nocolor", "", 0, 0, 0 }, - { nh_color, 9, 0, "orange", "", 255, 165, 0 }, - { nh_color, 10, 0, "bright-green", "", 0, 128, 0 }, - { nh_color, 11, 0, "yellow", "", 255, 255, 0 }, - { nh_color, 12, 0, "bright-blue", "", 173, 216, 230 }, - { nh_color, 13, 0, "bright-magenta", "", 147, 112, 219 }, - { nh_color, 14, 0, "light-cyan", "", 224, 255, 255 }, - { nh_color, 15, 0, "white", "", 255, 255, 255 }, - { rgb_color, 16, 0, "maroon", "#800000", 128, 0, 0 }, - { rgb_color, 17, 1, "dark-red", "#8B0000", 139, 0, 0 }, - { rgb_color, 18, 2, "brown", "#A52A2A", 165, 42, 42 }, - { rgb_color, 19, 3, "firebrick", "#B22222", 178, 34, 34 }, - { rgb_color, 20, 4, "crimson", "#DC143C", 220, 20, 60 }, - { rgb_color, 21, 5, "red", "#FF0000", 255, 0, 0 }, - { rgb_color, 22, 6, "tomato", "#FF6347", 255, 99, 71 }, - { rgb_color, 23, 7, "coral", "#FF7F50", 255, 127, 80 }, - { rgb_color, 24, 8, "indian-red", "#CD5C5C", 205, 92, 92 }, - { rgb_color, 25, 9, "light-coral", "#F08080", 240, 128, 128 }, - { rgb_color, 26, 10, "dark-salmon", "#E9967A", 233, 150, 122 }, - { rgb_color, 27, 11, "salmon", "#FA8072", 250, 128, 114 }, - { rgb_color, 28, 12, "light-salmon", "#FFA07A", 255, 160, 122 }, - { rgb_color, 29, 13, "orange-red", "#FF4500", 255, 69, 0 }, - { rgb_color, 30, 14, "dark-orange", "#FF8C00", 255, 140, 0 }, - { rgb_color, 31, 15, "orange", "#FFA500", 255, 165, 0 }, - { rgb_color, 32, 16, "gold", "#FFD700", 255, 215, 0 }, - { rgb_color, 33, 17, "dark-golden-rod", "#B8860B", 184, 134, 11 }, - { rgb_color, 34, 18, "golden-rod", "#DAA520", 218, 165, 32 }, - { rgb_color, 35, 19, "pale-golden-rod", "#EEE8AA", 238, 232, 170 }, - { rgb_color, 36, 20, "dark-khaki", "#BDB76B", 189, 183, 107 }, - { rgb_color, 37, 21, "khaki", "#F0E68C", 240, 230, 140 }, - { rgb_color, 38, 22, "olive", "#808000", 128, 128, 0 }, - { rgb_color, 39, 23, "yellow", "#FFFF00", 255, 255, 0 }, - { rgb_color, 40, 24, "yellow-green", "#9ACD32", 154, 205, 50 }, - { rgb_color, 41, 25, "dark-olive-green", "#556B2F", 85, 107, 47 }, - { rgb_color, 42, 26, "olive-drab", "#6B8E23", 107, 142, 35 }, - { rgb_color, 43, 27, "lawn-green", "#7CFC00", 124, 252, 0 }, - { rgb_color, 44, 28, "chart-reuse", "#7FFF00", 127, 255, 0 }, - { rgb_color, 45, 29, "green-yellow", "#ADFF2F", 173, 255, 47 }, - { rgb_color, 46, 30, "dark-green", "#006400", 0, 100, 0 }, - { rgb_color, 47, 31, "green", "#008000", 0, 128, 0 }, - { rgb_color, 48, 32, "forest-green", "#228B22", 34, 139, 34 }, - { rgb_color, 49, 33, "lime", "#00FF00", 0, 255, 0 }, - { rgb_color, 50, 34, "lime-green", "#32CD32", 50, 205, 50 }, - { rgb_color, 51, 35, "light-green", "#90EE90", 144, 238, 144 }, - { rgb_color, 52, 36, "pale-green", "#98FB98", 152, 251, 152 }, - { rgb_color, 53, 37, "dark-sea-green", "#8FBC8F", 143, 188, 143 }, - { rgb_color, 54, 38, "medium-spring-green", "#00FA9A", 0, 250, 154 }, - { rgb_color, 55, 39, "spring-green", "#00FF7F", 0, 255, 127 }, - { rgb_color, 56, 40, "sea-green", "#2E8B57", 46, 139, 87 }, - { rgb_color, 57, 41, "medium-aqua-marine", "#66CDAA", 102, 205, 170 }, - { rgb_color, 58, 42, "medium-sea-green", "#3CB371", 60, 179, 113 }, - { rgb_color, 59, 43, "light-sea-green", "#20B2AA", 32, 178, 170 }, - { rgb_color, 60, 44, "dark-slate-gray", "#2F4F4F", 47, 79, 79 }, - { rgb_color, 61, 45, "teal", "#008080", 0, 128, 128 }, - { rgb_color, 62, 46, "dark-cyan", "#008B8B", 0, 139, 139 }, - { rgb_color, 63, 47, "aqua", "#00FFFF", 0, 255, 255 }, - { rgb_color, 64, 48, "cyan", "#00FFFF", 0, 255, 255 }, - { rgb_color, 65, 49, "light-cyan", "#E0FFFF", 224, 255, 255 }, - { rgb_color, 66, 50, "dark-turquoise", "#00CED1", 0, 206, 209 }, - { rgb_color, 67, 51, "turquoise", "#40E0D0", 64, 224, 208 }, - { rgb_color, 68, 52, "medium-turquoise", "#48D1CC", 72, 209, 204 }, - { rgb_color, 69, 53, "pale-turquoise", "#AFEEEE", 175, 238, 238 }, - { rgb_color, 70, 54, "aqua-marine", "#7FFFD4", 127, 255, 212 }, - { rgb_color, 71, 55, "powder-blue", "#B0E0E6", 176, 224, 230 }, - { rgb_color, 72, 56, "cadet-blue", "#5F9EA0", 95, 158, 160 }, - { rgb_color, 73, 57, "steel-blue", "#4682B4", 70, 130, 180 }, - { rgb_color, 74, 58, "corn-flower-blue", "#6495ED", 100, 149, 237 }, - { rgb_color, 75, 59, "deep-sky-blue", "#00BFFF", 0, 191, 255 }, - { rgb_color, 76, 60, "dodger-blue", "#1E90FF", 30, 144, 255 }, - { rgb_color, 77, 61, "light-blue", "#ADD8E6", 173, 216, 230 }, - { rgb_color, 78, 62, "sky-blue", "#87CEEB", 135, 206, 235 }, - { rgb_color, 79, 63, "light-sky-blue", "#87CEFA", 135, 206, 250 }, - { rgb_color, 80, 64, "midnight-blue", "#191970", 25, 25, 112 }, - { rgb_color, 81, 65, "navy", "#000080", 0, 0, 128 }, - { rgb_color, 82, 66, "dark-blue", "#00008B", 0, 0, 139 }, - { rgb_color, 83, 67, "medium-blue", "#0000CD", 0, 0, 205 }, - { rgb_color, 84, 68, "blue", "#0000FF", 0, 0, 255 }, - { rgb_color, 85, 69, "royal-blue", "#4169E1", 65, 105, 225 }, - { rgb_color, 86, 70, "blue-violet", "#8A2BE2", 138, 43, 226 }, - { rgb_color, 87, 71, "indigo", "#4B0082", 75, 0, 130 }, - { rgb_color, 88, 72, "dark-slate-blue", "#483D8B", 72, 61, 139 }, - { rgb_color, 89, 73, "slate-blue", "#6A5ACD", 106, 90, 205 }, - { rgb_color, 90, 74, "medium-slate-blue", "#7B68EE", 123, 104, 238 }, - { rgb_color, 91, 75, "medium-purple", "#9370DB", 147, 112, 219 }, - { rgb_color, 92, 76, "dark-magenta", "#8B008B", 139, 0, 139 }, - { rgb_color, 93, 77, "dark-violet", "#9400D3", 148, 0, 211 }, - { rgb_color, 94, 78, "dark-orchid", "#9932CC", 153, 50, 204 }, - { rgb_color, 95, 79, "medium-orchid", "#BA55D3", 186, 85, 211 }, - { rgb_color, 96, 80, "purple", "#800080", 128, 0, 128 }, - { rgb_color, 97, 81, "thistle", "#D8BFD8", 216, 191, 216 }, - { rgb_color, 98, 82, "plum", "#DDA0DD", 221, 160, 221 }, - { rgb_color, 99, 83, "violet", "#EE82EE", 238, 130, 238 }, - { rgb_color, 100, 84, "magenta", "#FF00FF", 255, 0, 255 }, - { rgb_color, 101, 85, "orchid", "#DA70D6", 218, 112, 214 }, - { rgb_color, 102, 86, "medium-violet-red", "#C71585", 199, 21, 133 }, - { rgb_color, 103, 87, "pale-violet-red", "#DB7093", 219, 112, 147 }, - { rgb_color, 104, 88, "deep-pink", "#FF1493", 255, 20, 147 }, - { rgb_color, 105, 89, "hot-pink", "#FF69B4", 255, 105, 180 }, - { rgb_color, 106, 90, "light-pink", "#FFB6C1", 255, 182, 193 }, - { rgb_color, 107, 91, "pink", "#FFC0CB", 255, 192, 203 }, - { rgb_color, 108, 92, "antique-white", "#FAEBD7", 250, 235, 215 }, - { rgb_color, 109, 93, "beige", "#F5F5DC", 245, 245, 220 }, - { rgb_color, 110, 94, "bisque", "#FFE4C4", 255, 228, 196 }, - { rgb_color, 111, 95, "blanched-almond", "#FFEBCD", 255, 235, 205 }, - { rgb_color, 112, 96, "wheat", "#F5DEB3", 245, 222, 179 }, - { rgb_color, 113, 97, "corn-silk", "#FFF8DC", 255, 248, 220 }, - { rgb_color, 114, 98, "lemon-chiffon", "#FFFACD", 255, 250, 205 }, - { rgb_color, 115, 99, "light-golden-rod-yellow", "#FAFAD2", 250, 250, 210 }, - { rgb_color, 116, 100, "light-yellow", "#FFFFE0", 255, 255, 224 }, - { rgb_color, 117, 101, "saddle-brown", "#8B4513", 139, 69, 19 }, - { rgb_color, 118, 102, "sienna", "#A0522D", 160, 82, 45 }, - { rgb_color, 119, 103, "chocolate", "#D2691E", 210, 105, 30 }, - { rgb_color, 120, 104, "peru", "#CD853F", 205, 133, 63 }, - { rgb_color, 121, 105, "sandy-brown", "#F4A460", 244, 164, 96 }, - { rgb_color, 122, 106, "burly-wood", "#DEB887", 222, 184, 135 }, - { rgb_color, 123, 107, "tan", "#D2B48C", 210, 180, 140 }, - { rgb_color, 124, 108, "rosy-brown", "#BC8F8F", 188, 143, 143 }, - { rgb_color, 125, 109, "moccasin", "#FFE4B5", 255, 228, 181 }, - { rgb_color, 126, 110, "navajo-white", "#FFDEAD", 255, 222, 173 }, - { rgb_color, 127, 111, "peach-puff", "#FFDAB9", 255, 218, 185 }, - { rgb_color, 128, 112, "misty-rose", "#FFE4E1", 255, 228, 225 }, - { rgb_color, 129, 113, "lavender-blush", "#FFF0F5", 255, 240, 245 }, - { rgb_color, 130, 114, "linen", "#FAF0E6", 250, 240, 230 }, - { rgb_color, 131, 115, "old-lace", "#FDF5E6", 253, 245, 230 }, - { rgb_color, 132, 116, "papaya-whip", "#FFEFD5", 255, 239, 213 }, - { rgb_color, 133, 117, "sea-shell", "#FFF5EE", 255, 245, 238 }, - { rgb_color, 134, 118, "mint-cream", "#F5FFFA", 245, 255, 250 }, - { rgb_color, 135, 119, "slate-gray", "#708090", 112, 128, 144 }, - { rgb_color, 136, 120, "light-slate-gray", "#778899", 119, 136, 153 }, - { rgb_color, 137, 121, "light-steel-blue", "#B0C4DE", 176, 196, 222 }, - { rgb_color, 138, 122, "lavender", "#E6E6FA", 230, 230, 250 }, - { rgb_color, 139, 123, "floral-white", "#FFFAF0", 255, 250, 240 }, - { rgb_color, 140, 124, "alice-blue", "#F0F8FF", 240, 248, 255 }, - { rgb_color, 141, 125, "ghost-white", "#F8F8FF", 248, 248, 255 }, - { rgb_color, 142, 126, "honeydew", "#F0FFF0", 240, 255, 240 }, - { rgb_color, 143, 127, "ivory", "#FFFFF0", 255, 255, 240 }, - { rgb_color, 144, 128, "azure", "#F0FFFF", 240, 255, 255 }, - { rgb_color, 145, 129, "snow", "#FFFAFA", 255, 250, 250 }, - { rgb_color, 146, 130, "black", "#000000", 0, 0, 0 }, - { rgb_color, 147, 131, "dim-gray", "#696969", 105, 105, 105 }, - { rgb_color, 148, 132, "gray", "#808080", 128, 128, 128 }, - { rgb_color, 149, 133, "dark-gray", "#A9A9A9", 169, 169, 169 }, - { rgb_color, 150, 134, "silver", "#C0C0C0", 192, 192, 192 }, - { rgb_color, 151, 135, "light-gray", "#D3D3D3", 211, 211, 211 }, - { rgb_color, 152, 136, "gainsboro", "#DCDCDC", 220, 220, 220 }, - { rgb_color, 153, 137, "white-smoke", "#F5F5F5", 245, 245, 245 }, - { rgb_color, 154, 138, "white", "#FFFFFF", 255, 255, 255 }, +#define NHC nh_color +#define NOC no_color +#define RGBC rgb_color + +const struct nethack_color colortable[] = { + { NHC, 0, 0, "black", 0x00, 0x00, 0x00 }, /* CLR_BLACK */ + { NHC, 1, 0, "red", 0xFF, 0x00, 0x00 }, /* CLR_RED */ + { NHC, 2, 0, "green", 0x22, 0x8B, 0x22 }, /* CLR_GREEN */ + { NHC, 3, 0, "brown", 0xA5, 0x2A, 0x2A }, /* CLR_BROWN */ + { NHC, 4, 0, "blue", 0x00, 0x00, 0xFF }, /* CLR_BLUE */ + { NHC, 5, 0, "magenta", 0xFF, 0x00, 0xFF }, /* CLR_MAGENTA */ + { NHC, 6, 0, "cyan", 0x00, 0xFF, 0xFF }, /* CLR_CYAN */ + { NHC, 7, 0, "gray", 0x80, 0x80, 0x80 }, /* CLR_GRAY */ + { NOC, 8, 0, "nocolor", 0x00, 0x00, 0x00 }, /* NO_COLOR */ + { NHC, 9, 0, "orange", 0xFF, 0xA5, 0x00 }, /* CLR_ORANGE */ + { NHC, 10, 0, "bright-green", + 0x00, 0x80, 0x00 }, /* CLR_BRIGHT_GREEN */ + { NHC, 11, 0, "yellow", 0xFF, 0xFF, 0x00 }, /* CLR_YELLOW */ + { NHC, 12, 0, "bright-blue", 0xAD, 0xD8, 0xE6 }, /* CLR_BRIGHT_BLUE */ + { NHC, 13, 0, "bright-magenta", + 0x93, 0x70, 0xDB }, /* CLR_BRIGHT_MAGENTA */ + { NHC, 14, 0, "light-cyan", 0xE0, 0xFF, 0xFF }, /* CLR_BRIGHT_CYAN */ + { NHC, 15, 0, "white", 0xFF, 0xFF, 0xFF }, /* CLR_WHITE */ + { RGBC, 16, 0, "maroon", 0x80, 0x00, 0x00 }, /* #800000 */ + { RGBC, 17, 1, "dark-red", 0x8B, 0x00, 0x00 }, /* #8B0000 */ + { RGBC, 18, 2, "brown", 0xA5, 0x2A, 0x2A }, /* #A52A2A */ + { RGBC, 19, 3, "firebrick", 0xB2, 0x22, 0x22 }, /* #B22222 */ + { RGBC, 20, 4, "crimson", 0xDC, 0x14, 0x3C }, /* #DC143C */ + { RGBC, 21, 5, "red", 0xFF, 0x00, 0x00 }, /* #FF0000 */ + { RGBC, 22, 6, "tomato", 0xFF, 0x63, 0x47 }, /* #FF6347 */ + { RGBC, 23, 7, "coral", 0xFF, 0x7F, 0x50 }, /* #FF7F50 */ + { RGBC, 24, 8, "indian-red", 0xCD, 0x5C, 0x5C }, /* #CD5C5C */ + { RGBC, 25, 9, "light-coral", 0xF0, 0x80, 0x80 }, /* #F08080 */ + { RGBC, 26, 10, "dark-salmon", 0xE9, 0x96, 0x7A }, /* #E9967A */ + { RGBC, 27, 11, "salmon", 0xFA, 0x80, 0x72 }, /* #FA8072 */ + { RGBC, 28, 12, "light-salmon", 0xFF, 0xA0, 0x7A }, /* #FFA07A */ + { RGBC, 29, 13, "orange-red", 0xFF, 0x45, 0x00 }, /* #FF4500 */ + { RGBC, 30, 14, "dark-orange", 0xFF, 0x8C, 0x00 }, /* #FF8C00 */ + { RGBC, 31, 15, "orange", 0xFF, 0xA5, 0x00 }, /* #FFA500 */ + { RGBC, 32, 16, "gold", 0xFF, 0xD7, 0x00 }, /* #FFD700 */ + { RGBC, 33, 17, "dark-golden-rod", 0xB8, 0x86, 0x0B }, /* #B8860B */ + { RGBC, 34, 18, "golden-rod", 0xDA, 0xA5, 0x20 }, /* #DAA520 */ + { RGBC, 35, 19, "pale-golden-rod", 0xEE, 0xE8, 0xAA }, /* #EEE8AA */ + { RGBC, 36, 20, "dark-khaki", 0xBD, 0xB7, 0x6B }, /* #BDB76B */ + { RGBC, 37, 21, "khaki", 0xF0, 0xE6, 0x8C }, /* #F0E68C */ + { RGBC, 38, 22, "olive", 0x80, 0x80, 0x00 }, /* #808000 */ + { RGBC, 39, 23, "yellow", 0xFF, 0xFF, 0x00 }, /* #FFFF00 */ + { RGBC, 40, 24, "yellow-green", 0x9A, 0xCD, 0x32 }, /* #9ACD32 */ + { RGBC, 41, 25, "dark-olive-green", 0x55, 0x6B, 0x2F }, /* #556B2F */ + { RGBC, 42, 26, "olive-drab", 0x6B, 0x8E, 0x23 }, /* #6B8E23 */ + { RGBC, 43, 27, "lawn-green", 0x7C, 0xFC, 0x00 }, /* #7CFC00 */ + { RGBC, 44, 28, "chart-reuse", 0x7F, 0xFF, 0x00 }, /* #7FFF00 */ + { RGBC, 45, 29, "green-yellow", 0xAD, 0xFF, 0x2F }, /* #ADFF2F */ + { RGBC, 46, 30, "dark-green", 0x00, 0x64, 0x00 }, /* #006400 */ + { RGBC, 47, 31, "green", 0x00, 0x80, 0x00 }, /* #008000 */ + { RGBC, 48, 32, "forest-green", 0x22, 0x8B, 0x22 }, /* #228B22 */ + { RGBC, 49, 33, "lime", 0x00, 0xFF, 0x00 }, /* #00FF00 */ + { RGBC, 50, 34, "lime-green", 0x32, 0xCD, 0x32 }, /* #32CD32 */ + { RGBC, 51, 35, "light-green", 0x90, 0xEE, 0x90 }, /* #90EE90 */ + { RGBC, 52, 36, "pale-green", 0x98, 0xFB, 0x98 }, /* #98FB98 */ + { RGBC, 53, 37, "dark-sea-green", 0x8F, 0xBC, 0x8F }, /* #8FBC8F */ + { RGBC, 54, 38, "medium-spring-green", 0x00, 0xFA, 0x9A }, /* #00FA9A */ + { RGBC, 55, 39, "spring-green", 0x00, 0xFF, 0x7F }, /* #00FF7F */ + { RGBC, 56, 40, "sea-green", 0x2E, 0x8B, 0x57 }, /* #2E8B57 */ + { RGBC, 57, 41, "medium-aqua-marine", 0x66, 0xCD, 0xAA }, /* #66CDAA */ + { RGBC, 58, 42, "medium-sea-green", 0x3C, 0xB3, 0x71 }, /* #3CB371 */ + { RGBC, 59, 43, "light-sea-green", 0x20, 0xB2, 0xAA }, /* #20B2AA */ + { RGBC, 60, 44, "dark-slate-gray", 0x2F, 0x4F, 0x4F }, /* #2F4F4F */ + { RGBC, 61, 45, "teal", 0x00, 0x80, 0x80 }, /* #008080 */ + { RGBC, 62, 46, "dark-cyan", 0x00, 0x8B, 0x8B }, /* #008B8B */ + { RGBC, 63, 47, "aqua", 0x00, 0xFF, 0xFF }, /* #00FFFF */ + { RGBC, 64, 48, "cyan", 0x00, 0xFF, 0xFF }, /* #00FFFF */ + { RGBC, 65, 49, "light-cyan", 0xE0, 0xFF, 0xFF }, /* #E0FFFF */ + { RGBC, 66, 50, "dark-turquoise", 0x00, 0xCE, 0xD1 }, /* #00CED1 */ + { RGBC, 67, 51, "turquoise", 0x40, 0xE0, 0xD0 }, /* #40E0D0 */ + { RGBC, 68, 52, "medium-turquoise", 0x48, 0xD1, 0xCC }, /* #48D1CC */ + { RGBC, 69, 53, "pale-turquoise", 0xAF, 0xEE, 0xEE }, /* #AFEEEE */ + { RGBC, 70, 54, "aqua-marine", 0x7F, 0xFF, 0xD4 }, /* #7FFFD4 */ + { RGBC, 71, 55, "powder-blue", 0xB0, 0xE0, 0xE6 }, /* #B0E0E6 */ + { RGBC, 72, 56, "cadet-blue", 0x5F, 0x9E, 0xA0 }, /* #5F9EA0 */ + { RGBC, 73, 57, "steel-blue", 0x46, 0x82, 0xB4 }, /* #4682B4 */ + { RGBC, 74, 58, "corn-flower-blue", 0x64, 0x95, 0xED }, /* #6495ED */ + { RGBC, 75, 59, "deep-sky-blue", 0x00, 0xBF, 0xFF }, /* #00BFFF */ + { RGBC, 76, 60, "dodger-blue", 0x1E, 0x90, 0xFF }, /* #1E90FF */ + { RGBC, 77, 61, "light-blue", 0xAD, 0xD8, 0xE6 }, /* #ADD8E6 */ + { RGBC, 78, 62, "sky-blue", 0x87, 0xCE, 0xEB }, /* #87CEEB */ + { RGBC, 79, 63, "light-sky-blue", 0x87, 0xCE, 0xFA }, /* #87CEFA */ + { RGBC, 80, 64, "midnight-blue", 0x19, 0x19, 0x70 }, /* #191970 */ + { RGBC, 81, 65, "navy", 0x00, 0x00, 0x80 }, /* #000080 */ + { RGBC, 82, 66, "dark-blue", 0x00, 0x00, 0x8B }, /* #00008B */ + { RGBC, 83, 67, "medium-blue", 0x00, 0x00, 0xCD }, /* #0000CD */ + { RGBC, 84, 68, "blue", 0x00, 0x00, 0xFF }, /* #0000FF */ + { RGBC, 85, 69, "royal-blue", 0x41, 0x69, 0xE1 }, /* #4169E1 */ + { RGBC, 86, 70, "blue-violet", 0x8A, 0x2B, 0xE2 }, /* #8A2BE2 */ + { RGBC, 87, 71, "indigo", 0x4B, 0x00, 0x82 }, /* #4B0082 */ + { RGBC, 88, 72, "dark-slate-blue", 0x48, 0x3D, 0x8B }, /* #483D8B */ + { RGBC, 89, 73, "slate-blue", 0x6A, 0x5A, 0xCD }, /* #6A5ACD */ + { RGBC, 90, 74, "medium-slate-blue", 0x7B, 0x68, 0xEE }, /* #7B68EE */ + { RGBC, 91, 75, "medium-purple", 0x93, 0x70, 0xDB }, /* #9370DB */ + { RGBC, 92, 76, "dark-magenta", 0x8B, 0x00, 0x8B }, /* #8B008B */ + { RGBC, 93, 77, "dark-violet", 0x94, 0x00, 0xD3 }, /* #9400D3 */ + { RGBC, 94, 78, "dark-orchid", 0x99, 0x32, 0xCC }, /* #9932CC */ + { RGBC, 95, 79, "medium-orchid", 0xBA, 0x55, 0xD3 }, /* #BA55D3 */ + { RGBC, 96, 80, "purple", 0x80, 0x00, 0x80 }, /* #800080 */ + { RGBC, 97, 81, "thistle", 0xD8, 0xBF, 0xD8 }, /* #D8BFD8 */ + { RGBC, 98, 82, "plum", 0xDD, 0xA0, 0xDD }, /* #DDA0DD */ + { RGBC, 99, 83, "violet", 0xEE, 0x82, 0xEE }, /* #EE82EE */ + { RGBC, 100, 84, "magenta", 0xFF, 0x00, 0xFF }, /* #FF00FF */ + { RGBC, 101, 85, "orchid", 0xDA, 0x70, 0xD6 }, /* #DA70D6 */ + { RGBC, 102, 86, "medium-violet-red", 0xC7, 0x15, 0x85 }, /* #C71585 */ + { RGBC, 103, 87, "pale-violet-red", 0xDB, 0x70, 0x93 }, /* #DB7093 */ + { RGBC, 104, 88, "deep-pink", 0xFF, 0x14, 0x93 }, /* #FF1493 */ + { RGBC, 105, 89, "hot-pink", 0xFF, 0x69, 0xB4 }, /* #FF69B4 */ + { RGBC, 106, 90, "light-pink", 0xFF, 0xB6, 0xC1 }, /* #FFB6C1 */ + { RGBC, 107, 91, "pink", 0xFF, 0xC0, 0xCB }, /* #FFC0CB */ + { RGBC, 108, 92, "antique-white", 0xFA, 0xEB, 0xD7 }, /* #FAEBD7 */ + { RGBC, 109, 93, "beige", 0xF5, 0xF5, 0xDC }, /* #F5F5DC */ + { RGBC, 110, 94, "bisque", 0xFF, 0xE4, 0xC4 }, /* #FFE4C4 */ + { RGBC, 111, 95, "blanched-almond", 0xFF, 0xEB, 0xCD }, /* #FFEBCD */ + { RGBC, 112, 96, "wheat", 0xF5, 0xDE, 0xB3 }, /* #F5DEB3 */ + { RGBC, 113, 97, "corn-silk", 0xFF, 0xF8, 0xDC }, /* #FFF8DC */ + { RGBC, 114, 98, "lemon-chiffon", 0xFF, 0xFA, 0xCD }, /* #FFFACD */ + { RGBC, 115, 99, "light-golden-rod-yellow", + 0xFA, 0xFA, 0xD2 }, /* #FAFAD2 */ + { RGBC, 116, 100, "light-yellow", 0xFF, 0xFF, 0xE0 }, /* #FFFFE0 */ + { RGBC, 117, 101, "saddle-brown", 0x8B, 0x45, 0x13 }, /* #8B4513 */ + { RGBC, 118, 102, "sienna", 0xA0, 0x52, 0x2D }, /* #A0522D */ + { RGBC, 119, 103, "chocolate", 0xD2, 0x69, 0x1E }, /* #D2691E */ + { RGBC, 120, 104, "peru", 0xCD, 0x85, 0x3F }, /* #CD853F */ + { RGBC, 121, 105, "sandy-brown", 0xF4, 0xA4, 0x60 }, /* #F4A460 */ + { RGBC, 122, 106, "burly-wood", 0xDE, 0xB8, 0x87 }, /* #DEB887 */ + { RGBC, 123, 107, "tan", 0xD2, 0xB4, 0x8C }, /* #D2B48C */ + { RGBC, 124, 108, "rosy-brown", 0xBC, 0x8F, 0x8F }, /* #BC8F8F */ + { RGBC, 125, 109, "moccasin", 0xFF, 0xE4, 0xB5 }, /* #FFE4B5 */ + { RGBC, 126, 110, "navajo-white", 0xFF, 0xDE, 0xAD }, /* #FFDEAD */ + { RGBC, 127, 111, "peach-puff", 0xFF, 0xDA, 0xB9 }, /* #FFDAB9 */ + { RGBC, 128, 112, "misty-rose", 0xFF, 0xE4, 0xE1 }, /* #FFE4E1 */ + { RGBC, 129, 113, "lavender-blush", 0xFF, 0xF0, 0xF5 }, /* #FFF0F5 */ + { RGBC, 130, 114, "linen", 0xFA, 0xF0, 0xE6 }, /* #FAF0E6 */ + { RGBC, 131, 115, "old-lace", 0xFD, 0xF5, 0xE6 }, /* #FDF5E6 */ + { RGBC, 132, 116, "papaya-whip", 0xFF, 0xEF, 0xD5 }, /* #FFEFD5 */ + { RGBC, 133, 117, "sea-shell", 0xFF, 0xF5, 0xEE }, /* #FFF5EE */ + { RGBC, 134, 118, "mint-cream", 0xF5, 0xFF, 0xFA }, /* #F5FFFA */ + { RGBC, 135, 119, "slate-gray", 0x70, 0x80, 0x90 }, /* #708090 */ + { RGBC, 136, 120, "light-slate-gray", 0x77, 0x88, 0x99 }, /* #778899 */ + { RGBC, 137, 121, "light-steel-blue", 0xB0, 0xC4, 0xDE }, /* #B0C4DE */ + { RGBC, 138, 122, "lavender", 0xE6, 0xE6, 0xFA }, /* #E6E6FA */ + { RGBC, 139, 123, "floral-white", 0xFF, 0xFA, 0xF0 }, /* #FFFAF0 */ + { RGBC, 140, 124, "alice-blue", 0xF0, 0xF8, 0xFF }, /* #F0F8FF */ + { RGBC, 141, 125, "ghost-white", 0xF8, 0xF8, 0xFF }, /* #F8F8FF */ + { RGBC, 142, 126, "honeydew", 0xF0, 0xFF, 0xF0 }, /* #F0FFF0 */ + { RGBC, 143, 127, "ivory", 0xFF, 0xFF, 0xF0 }, /* #FFFFF0 */ + { RGBC, 144, 128, "azure", 0xF0, 0xFF, 0xFF }, /* #F0FFFF */ + { RGBC, 145, 129, "snow", 0xFF, 0xFA, 0xFA }, /* #FFFAFA */ + { RGBC, 146, 130, "black", 0x00, 0x00, 0x00 }, /* #000000 */ + { RGBC, 147, 131, "dim-gray", 0x69, 0x69, 0x69 }, /* #696969 */ + { RGBC, 148, 132, "gray", 0x80, 0x80, 0x80 }, /* #808080 */ + { RGBC, 149, 133, "dark-gray", 0xA9, 0xA9, 0xA9 }, /* #A9A9A9 */ + { RGBC, 150, 134, "silver", 0xC0, 0xC0, 0xC0 }, /* #C0C0C0 */ + { RGBC, 151, 135, "light-gray", 0xD3, 0xD3, 0xD3 }, /* #D3D3D3 */ + { RGBC, 152, 136, "gainsboro", 0xDC, 0xDC, 0xDC }, /* #DCDCDC */ + { RGBC, 153, 137, "white-smoke", 0xF5, 0xF5, 0xF5 }, /* #F5F5F5 */ + { RGBC, 154, 138, "white", 0xFF, 0xFF, 0xFF }, /* #FFFFFF */ }; +#undef NHC +#undef NOC +#undef RGBC + #ifdef CHANGE_COLOR staticfn int32 alt_color_spec(const char *cp); #endif int32 -colortable_to_int32(struct nethack_color *cte) +colortable_to_int32(const struct nethack_color *cte) { int32 clr = NO_COLOR | NH_BASIC_COLOR; @@ -875,7 +886,8 @@ static struct { int index; uint32 value; } color_256_definitions[] = { - /* color values are from unnethack */ + /* from unnethack - these are the colors used by xterm + when $TERM is set to xterm-256color */ { 16, 0x000000 }, { 17, 0x00005f }, { 18, 0x000087 }, { 19, 0x0000af }, { 20, 0x0000d7 }, { 21, 0x0000ff }, { 22, 0x005f00 }, { 23, 0x005f5f }, { 24, 0x005f87 }, diff --git a/src/date.c b/src/date.c index 3ec4fbb3d..8ec8f4061 100644 --- a/src/date.c +++ b/src/date.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 date.c $NHDT-Date: 1655402414 2022/06/16 18:00:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 date.c $NHDT-Date: 1781973043 2026/06/20 16:30:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) Michael Allison, 2021. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dbridge.c b/src/dbridge.c index 72d39be82..0c9352432 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dbridge.c $NHDT-Date: 1772771734 2026/03/05 20:35:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 5.0 dbridge.c $NHDT-Date: 1781973044 2026/06/20 16:30:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/decl.c b/src/decl.c index 66f3d060e..64c829ce2 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ +/* NetHack 5.0 decl.c $NHDT-Date: 1781973044 2026/06/20 16:30:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.368 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -313,6 +313,7 @@ static const struct instance_globals_d g_init_d = { FALSE, /* decor_levitate_override */ FALSE, /* deferred_showpaths */ NULL, /* deferred_showpaths_dir */ + FALSE, /* disable_glyphname_hash_indices_prefill */ TRUE, /* havestate*/ }; @@ -636,6 +637,8 @@ static const struct instance_globals_p g_init_p = { /* pline.c */ 0U, /* pline_flags */ UNDEFINED_VALUES, /* prevmsg */ + /* mon.c */ + no_terrain_effects, /* pending_terrain_effects */ /* potion.c */ UNDEFINED_VALUE, /* potion_nothing */ UNDEFINED_VALUE, /* potion_unkn */ @@ -647,6 +650,13 @@ static const struct instance_globals_p g_init_p = { UNDEFINED_PTR, /* propellor */ /* zap.c */ UNDEFINED_VALUE, /* poly_zap */ + 0, /* puzzling_criteria */ + { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, /* puzzling_ilets[] */ + TRUE, /* havestate*/ }; @@ -675,8 +685,6 @@ static const struct instance_globals_r g_init_r = { }; static const struct instance_globals_s g_init_s = { - /* allmain.c */ - FALSE, /* saving_grace_turn */ /* artifact.c */ 0, /* spec_dbon_applies */ /* decl.c */ @@ -767,12 +775,12 @@ static const struct instance_globals_t g_init_t = { }; static const struct instance_globals_u g_init_u = { - /* allmain.c */ - 0, /* uhp_at_start_of_monster_turn */ /* botl.c */ FALSE, /* update_all */ /* decl.c */ FALSE, /* unweapon */ + /* revision.c */ + 0, /* uplift_needed_rev0_to_rev1 */ /* role.c */ UNDEFINED_ROLE, /* urole */ UNDEFINED_RACE, /* urace */ @@ -930,6 +938,11 @@ static const struct instance_globals_saved_m init_svm = { static const struct instance_globals_saved_n init_svn = { /* dungeon.c */ 0, /* n_dgns */ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 + }, /* nhuuid */ /* mkroom.c */ 0, /* nroom */ /* region.c */ @@ -986,6 +999,11 @@ static const struct instance_globals_saved_x init_svx = { UNDEFINED_VALUE /* xmax */ }; +static const struct instance_globals_saved_w init_svw = { + 0, /* wreserve */ + 100, /* wtreserved, not used currently */ +}; + static const struct instance_globals_saved_y init_svy = { /* mkmaze.c */ UNDEFINED_VALUE, /* ymin */ @@ -993,6 +1011,7 @@ static const struct instance_globals_saved_y init_svy = { }; static const struct sinfo init_program_state = { 0 }; +static const struct levelstatus init_level_status = { 0 }; #if 0 struct instance_globals g; @@ -1041,9 +1060,11 @@ struct instance_globals_saved_r svr; struct instance_globals_saved_s svs; struct instance_globals_saved_t svt; struct instance_globals_saved_u svu; +struct instance_globals_saved_w svw; struct instance_globals_saved_x svx; struct instance_globals_saved_y svy; struct sinfo program_state; +struct levelstatus level_status; const struct const_globals cg = { DUMMY, /* zeroobj */ @@ -1069,6 +1090,12 @@ program_state_init(void) program_state = init_program_state; } +void +level_status_init(void) +{ + level_status = init_level_status; +} + void decl_globals_init(void) { @@ -1118,6 +1145,7 @@ decl_globals_init(void) svs = init_svs; svt = init_svt; svu = init_svu; + svw = init_svw; svx = init_svx; svy = init_svy; @@ -1176,6 +1204,9 @@ decl_globals_init(void) gu.urole = urole_init_data; gu.urace = urace_init_data; +#ifdef DISABLE_GLYPHID_CACHE_PREFILL + gd.disable_glyphname_hash_indices_prefill = TRUE; +#endif } /* fields in 'hands_obj' don't matter, just its distinct address */ diff --git a/src/detect.c b/src/detect.c index bf536e127..8f93df374 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 detect.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 5.0 detect.c $NHDT-Date: 1781973044 2026/06/20 16:30:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.197 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -345,7 +345,7 @@ gold_detect(struct obj *sobj) /* look for gold carried by monsters (might be in a container) */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { if (mtmp == u.usteed) { @@ -433,7 +433,7 @@ gold_detect(struct obj *sobj) ugold = TRUE; } for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; temp = 0; if (findgold(mtmp->minvent) || monsndx(mtmp->data) == PM_GOLD_GOLEM) { @@ -497,7 +497,7 @@ food_detect(struct obj *sobj) ct++; } for (mtmp = fmon; mtmp && (!ct || !ctu); mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) if (o_in(obj, oclass)) { @@ -561,7 +561,7 @@ food_detect(struct obj *sobj) map_object(temp, 1); } for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) if ((temp = o_in(obj, oclass)) != 0) { @@ -666,7 +666,7 @@ object_detect(struct obj *detector, /* object doing the detecting */ u.usteed->mx = u.ux, u.usteed->my = u.uy; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) { if ((!class && !boulder) || o_in(obj, class) @@ -736,7 +736,7 @@ object_detect(struct obj *detector, /* object doing the detecting */ /* Objects in the monster's inventory override floor objects. */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; for (obj = mtmp->minvent; obj; obj = obj->nobj) if ((!class && !boulder) || (otmp = o_in(obj, class)) != 0 @@ -807,7 +807,7 @@ monster_detect(struct obj *otmp, /* detecting object (if any) */ * with positive hit-points to know for sure. */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; ++mcnt; break; /* no need for full count, just 1 or more vs 0 */ @@ -826,7 +826,7 @@ monster_detect(struct obj *otmp, /* detecting object (if any) */ cls(); unconstrained = unconstrain_map(); for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx)) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; if (!mclass || mtmp->data->mlet == mclass || (mtmp->data == &mons[PM_LONG_WORM] @@ -969,7 +969,7 @@ display_trap_map(int cursed_src) (void) detect_obj_traps(svl.level.buriedobjlist, TRUE, cursed_src, NULL); (void) detect_obj_traps(fobj, TRUE, cursed_src, NULL); for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; (void) detect_obj_traps(mon->minvent, TRUE, cursed_src, NULL); } @@ -1046,7 +1046,7 @@ trap_detect( found = TRUE; } for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; if ((tr = detect_obj_traps(mon->minvent, FALSE, 0, NULL)) != OTRAP_NONE) { @@ -1643,7 +1643,7 @@ findone(coordxy zx, coordxy zy, genericptr_t whatfound) struct monst *mtmp = m_at(zx, zy); struct found_things *found_p = (struct found_things *) whatfound; - if (mtmp && (DEADMONSTER(mtmp) || (mtmp->isgd && !mtmp->mx))) + if (mtmp && (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp))) mtmp = (struct monst *) NULL; found_p->ft_cc.x = zx; /* needed by detect_obj_traps() */ found_p->ft_cc.y = zy; diff --git a/src/dig.c b/src/dig.c index 5e5fc1a74..fa9ea2108 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dig.c $NHDT-Date: 1740629713 2025/02/26 20:15:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ +/* NetHack 5.0 dig.c $NHDT-Date: 1781973044 2026/06/20 16:30:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.236 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -455,7 +455,7 @@ dig(void) } else if (digtyp == DIGTYP_BOULDER && (obj = sobj_at(BOULDER, dpx, dpy)) != 0) { fracture_rock(obj); - /*[3.7: this probably isn't necessary anymore]*/ + /*[5.0: this probably isn't necessary anymore]*/ if ((bobj = sobj_at(BOULDER, dpx, dpy)) != 0) { /* another boulder here, restack it to the top */ obj_extract_self(bobj); diff --git a/src/display.c b/src/display.c index d3241ce9f..3e74ea42e 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.c $NHDT-Date: 1777000050 2026/04/23 19:07:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.263 $ */ +/* NetHack 5.0 display.c $NHDT-Date: 1781973045 2026/06/20 16:30:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.270 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1164,6 +1164,7 @@ tether_glyph(coordxy x, coordxy y) static struct tmp_glyph { coord saved[TMP_AT_MAX_GLYPHS]; /* previously updated positions */ + boolean shown_on_map[TMP_AT_MAX_GLYPHS]; int sidx; /* index of next unused slot in saved[] */ int style; /* either DISP_BEAM or DISP_FLASH or DISP_ALWAYS */ int glyph; /* glyph to use when printing */ @@ -1175,6 +1176,7 @@ tmp_at(coordxy x, coordxy y) { static struct tmp_glyph *tglyph = (struct tmp_glyph *) 0; struct tmp_glyph *tmp; + boolean suppress_show = FALSE; switch (x) { case DISP_BEAM: @@ -1220,27 +1222,42 @@ tmp_at(coordxy x, coordxy y) int i; /* Erase (reset) from source to end */ - for (i = 0; i < tglyph->sidx; i++) + for (i = 0; i < tglyph->sidx; i++) { newsym(tglyph->saved[i].x, tglyph->saved[i].y); + tglyph->shown_on_map[i] = FALSE; + } } else if (tglyph->style == DISP_TETHER) { int i; if (y == BACKTRACK && tglyph->sidx > 1) { /* backtrack */ for (i = tglyph->sidx - 1; i > 0; i--) { - newsym(tglyph->saved[i].x, tglyph->saved[i].y); - show_glyph(tglyph->saved[i - 1].x, - tglyph->saved[i - 1].y, tglyph->glyph); - flush_screen(0); /* make sure it shows up */ - nh_delay_output(); + if (tglyph->shown_on_map[i]) { + newsym(tglyph->saved[i].x, tglyph->saved[i].y); + tglyph->shown_on_map[i] = FALSE; + } + if (cansee(tglyph->saved[i - 1].x, + tglyph->saved[i - 1].y)) { + tglyph->shown_on_map[i - 1] = TRUE; + show_glyph(tglyph->saved[i - 1].x, + tglyph->saved[i - 1].y, tglyph->glyph); + flush_screen(0); /* make sure it shows up */ + nh_delay_output(); + } } tglyph->sidx = 1; } - for (i = 0; i < tglyph->sidx; i++) - newsym(tglyph->saved[i].x, tglyph->saved[i].y); + for (i = 0; i < tglyph->sidx; i++) { + if (tglyph->shown_on_map[i]) + newsym(tglyph->saved[i].x, tglyph->saved[i].y); + } } else { /* DISP_FLASH or DISP_ALWAYS */ - if (tglyph->sidx) /* been called at least once */ - newsym(tglyph->saved[0].x, tglyph->saved[0].y); + if (tglyph->sidx) { /* been called at least once */ + if (tglyph->shown_on_map[0]) { + newsym(tglyph->saved[0].x, tglyph->saved[0].y); + tglyph->shown_on_map[0] = FALSE; + } + } } /* tglyph->sidx = 0; -- about to be freed, so not necessary */ tmp = tglyph->prev; @@ -1253,10 +1270,13 @@ tmp_at(coordxy x, coordxy y) if (!isok(x, y)) break; if (tglyph->style == DISP_BEAM || tglyph->style == DISP_ALL) { - if (tglyph->style != DISP_ALL && !cansee(x, y)) - break; if (tglyph->sidx >= TMP_AT_MAX_GLYPHS) break; /* too many locations */ + if (tglyph->style != DISP_ALL && !cansee(x, y)) { + tglyph->shown_on_map[tglyph->sidx] = FALSE; + suppress_show = TRUE; + break; + } /* save pos for later erasing */ tglyph->saved[tglyph->sidx].x = x; tglyph->saved[tglyph->sidx].y = y; @@ -1269,26 +1289,47 @@ tmp_at(coordxy x, coordxy y) px = tglyph->saved[tglyph->sidx - 1].x; py = tglyph->saved[tglyph->sidx - 1].y; - show_glyph(px, py, tether_glyph(px, py)); + if (cansee(px, py)) { + tglyph->shown_on_map[tglyph->sidx - 1] = TRUE; + show_glyph(px, py, tether_glyph(px, py)); + } else { + tglyph->shown_on_map[tglyph->sidx - 1] = FALSE; + suppress_show = TRUE; + } } /* save pos for later use or erasure */ tglyph->saved[tglyph->sidx].x = x; tglyph->saved[tglyph->sidx].y = y; + if (!cansee(x, y)) { + tglyph->shown_on_map[tglyph->sidx] = FALSE; + suppress_show = TRUE; + } else { + /* happens at end of this default case */ + tglyph->shown_on_map[tglyph->sidx] = TRUE; + } tglyph->sidx += 1; } else { /* DISP_FLASH/ALWAYS */ - if (tglyph - ->sidx) { /* not first call, so reset previous pos */ + if (tglyph->sidx) { /* not first call, so reset previous pos */ newsym(tglyph->saved[0].x, tglyph->saved[0].y); + tglyph->shown_on_map[0] = FALSE; tglyph->sidx = 0; /* display is presently up to date */ } - if (!cansee(x, y) && tglyph->style != DISP_ALWAYS) + if (!cansee(x, y) && tglyph->style != DISP_ALWAYS) { + suppress_show = TRUE; + tglyph->shown_on_map[0] = FALSE; break; + } else { + /* happens at end of this default case */ + tglyph->shown_on_map[0] = TRUE; + } tglyph->saved[0].x = x; tglyph->saved[0].y = y; tglyph->sidx = 1; } - show_glyph(x, y, tglyph->glyph); /* show it */ + if (!suppress_show) + show_glyph(x, y, tglyph->glyph); /* show it */ + flush_screen(0); /* make sure it shows up */ break; } /* end switch */ @@ -1503,7 +1544,9 @@ see_monsters(void) /* loop through level.monsters (aka fmon) */ for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) + continue; + if ((mon->mstate & MON_STILL_ARRIVING) != 0) continue; newsym(mon->mx, mon->my); if (mon->wormno) @@ -2214,7 +2257,7 @@ flush_screen(int cursor_on_u) glyph_info bkglyphinfo = nul_glyphinfo; int bkglyph; - /* 3.7: don't update map, status, or perm_invent during save/restore */ + /* 5.0: don't update map, status, or perm_invent during save/restore */ if (_suppress_map_output()) return; @@ -3453,7 +3496,7 @@ t_warn(struct rm *lev) static const char warn_str[] = "wall_angle: %s: case %d: seenv = 0x%x"; const char *wname; - /* 3.7: non-T_wall cases added after shop repair (via breaching a wall, + /* 5.0: non-T_wall cases added after shop repair (via breaching a wall, using locking magic to put a door there, then unlocking the door; D_CLOSED carried over to the wall) triggered warning for "unknown" */ switch (lev->typ) { diff --git a/src/dlb.c b/src/dlb.c index d6551fe06..1a39cc3dd 100644 --- a/src/dlb.c +++ b/src/dlb.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dlb.c $NHDT-Date: 1596498157 2020/08/03 23:42:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 5.0 dlb.c $NHDT-Date: 1781973045 2026/06/20 16:30:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.30 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/do.c b/src/do.c index cacab11c7..ab179765f 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do.c $NHDT-Date: 1774269965 2026/03/23 04:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.404 $ */ +/* NetHack 5.0 do.c $NHDT-Date: 1781973045 2026/06/20 16:30:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.411 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -77,7 +77,7 @@ boulder_hits_pool( levl[rx][ry].typ = ROOM, levl[rx][ry].flags = 0; recalc_block_point(rx, ry); } - /* 3.7: normally DEADMONSTER() is used when traversing the fmon + /* 5.0: normally DEADMONSTER() is used when traversing the fmon list--dead monsters usually aren't still at specific map locations; however, if ice melts causing a giant to drown, that giant would still be on the map when it drops inventory; @@ -1376,12 +1376,19 @@ save_currentstate(void) { NHFILE *nhfp; + if (!program_state.something_worth_saving + || program_state.in_self_recover + || program_state.in_checkpoint) + return; + program_state.in_checkpoint++; if (flags.ins_chkpt) { /* write out just-attained level, with pets and everything */ nhfp = currentlevel_rewrite(); - if (!nhfp) + if (!nhfp) { + program_state.in_checkpoint--; return; + } if (nhfp->structlevel) bufon(nhfp->fd); nhfp->mode = WRITING; @@ -1533,7 +1540,7 @@ goto_level( * -2 5.21 4.17 0.0 * -3 2.08 0.0 0.0 * - * 3.7.0: the chance for the "mysterious force" to kick in goes down + * 5.0.0: the chance for the "mysterious force" to kick in goes down * as it kicks in, starting at 25% per climb attempt and dropping off * gradually but substantially. The drop off is greater when hero is * sent down farther so benefits lawfuls more than chaotics this time. @@ -2178,6 +2185,7 @@ revive_corpse(struct obj *corpse) pline("%s disappears%s!", The(cname), effect); } } + (void) maybe_set_terrain_effects(mtmp, 0); break; case OBJ_MINVENT: /* probably a nymph's */ @@ -2438,7 +2446,7 @@ set_wounded_legs(long side, int timex) set_itimeout(&HWounded_legs, (long) timex); /* the leg being wounded and its timeout might differ from one attack to the next, but we don't track the legs separately; - 3.7: both legs will ultimately heal together; this used to use + 5.0: both legs will ultimately heal together; this used to use direct assignment instead of bitwise-OR so getting wounded in one leg mysteriously healed the other */ EWounded_legs |= side; diff --git a/src/do_name.c b/src/do_name.c index c27396343..76dbae9bc 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_name.c $NHDT-Date: 1737013431 2025/01/15 23:43:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ +/* NetHack 5.0 do_name.c $NHDT-Date: 1781973046 2026/06/20 16:30:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.339 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -433,7 +433,7 @@ objtyp_is_callable(int i) switch(objects[i].oc_class) { case AMULET_CLASS: - /* 3.7: calling these used to be allowed but that enabled the + /* 5.0: calling these used to be allowed but that enabled the player to tell whether two unID'd amulets of yendor were both fake or one was real by calling them distinct names and then checking discoveries to see whether first name was replaced @@ -1059,6 +1059,15 @@ noit_mon_nam(struct monst *mtmp) FALSE); } +char * +noit_or_your_mon_nam(struct monst *mtmp) +{ + return x_monnam(mtmp, ARTICLE_THE, (char *) 0, + (has_mgivenname(mtmp) ? (SUPPRESS_SADDLE | SUPPRESS_IT) + : SUPPRESS_IT), + FALSE); +} + /* in between noit_mon_nam() and mon_nam(); if the latter would pick "it", use "someone" (for humanoids) or "something" (for others) instead */ char * @@ -1088,6 +1097,15 @@ noit_Monnam(struct monst *mtmp) return bp; } +char * +noit_or_your_Monnam(struct monst *mtmp) +{ + char *bp = noit_or_your_mon_nam(mtmp); + + *bp = highc(*bp); + return bp; +} + char * Some_Monnam(struct monst *mtmp) { @@ -1484,7 +1502,7 @@ static NEARDATA const char *const hliquids[] = { "caramel sauce", "ink", "aqueous humour", "milk substitute", "fruit juice", "glowing lava", "gastric acid", "mineral water", "cough syrup", "quicksilver", "sweet vitriol", "grey goo", "pink slime", - "cosmic latte", + "cosmic latte", "bone oil", "custard", "lard", "vinegar", "creosote", /* "new coke (tm)", --better not */ }; diff --git a/src/do_wear.c b/src/do_wear.c index 382b17741..c75e4b2f8 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_wear.c $NHDT-Date: 1737343372 2025/01/19 19:22:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */ +/* NetHack 5.0 do_wear.c $NHDT-Date: 1781973047 2026/06/20 16:30:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.212 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2501,7 +2501,7 @@ find_ac(void) uac -= u.ublessed; uac -= u.uspellprot; - /* put a cap on armor class [3.7: was +127,-128, now reduced to +/- 99 */ + /* put a cap on armor class [5.0: was +127,-128, now reduced to +/- 99 */ if (abs(uac) > AC_MAX) uac = sgn(uac) * AC_MAX; diff --git a/src/dog.c b/src/dog.c index a583de705..63783be37 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dog.c $NHDT-Date: 1753856387 2025/07/29 22:19:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ +/* NetHack 5.0 dog.c $NHDT-Date: 1781973045 2026/06/20 16:30:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.197 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -427,6 +427,8 @@ mon_arrive(struct monst *mtmp, int when) stairway *stway; d_level fromdlev; + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; /* shouldn't be set anyway */ + mtmp->mstate |= MON_STILL_ARRIVING; mtmp->nmon = fmon; fmon = mtmp; if (mtmp->isshk) @@ -462,8 +464,10 @@ mon_arrive(struct monst *mtmp, int when) here for monsters migrating to a newly created level */ restore_cham(mtmp); - if (mtmp == u.usteed) + if (mtmp == u.usteed) { + mtmp->mstate &= ~MON_STILL_ARRIVING; return; /* don't place steed on the map */ + } if (when == With_you) { /* When a monster accompanies you, sometimes it will arrive at your intended destination and you'll end up next to @@ -475,6 +479,7 @@ mon_arrive(struct monst *mtmp, int when) rloc_to(mtmp, u.ux, u.uy); else mnexto(mtmp, RLOC_NOMSG); + mtmp->mstate &= ~MON_STILL_ARRIVING; return; } else if (when == Wiz_arrive) { /* resurrect() is bringing existing wizard to harass the hero */ @@ -604,6 +609,7 @@ mon_arrive(struct monst *mtmp, int when) mtmp->mx = 0; /*(already is 0)*/ mtmp->my = xyflags; + if (xlocale) failed_to_place = !mnearto(mtmp, xlocale, ylocale, FALSE, RLOC_NOMSG); else @@ -616,6 +622,7 @@ mon_arrive(struct monst *mtmp, int when) else /* when==Wiz_arrive => not being called by losedogs() */ m_into_limbo(mtmp); } + mtmp->mstate &= ~MON_STILL_ARRIVING; } /* heal monster for time spent elsewhere */ @@ -899,6 +906,7 @@ migrate_to_level( /* prepare to take mtmp off the map */ num_segs = mon_leave(mtmp); /* take off map and move mtmp from fmon list to migrating_mons */ + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; relmon(mtmp, &gm.migrating_mons); /* mtmp->mx,my retain their value */ mtmp->mstate |= MON_MIGRATING; diff --git a/src/dogmove.c b/src/dogmove.c index 1218c305e..9c18b93ff 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dogmove.c $NHDT-Date: 1725733007 2024/09/07 18:16:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.156 $ */ +/* NetHack 5.0 dogmove.c $NHDT-Date: 1781973046 2026/06/20 16:30:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.177 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -286,8 +286,10 @@ dog_eat(struct monst *mtmp, if (tunnels(mtmp->data)) pline_mon(mtmp, "%s digs in.", noit_Monnam(mtmp)); else - pline_mon(mtmp, "%s %s %s.", noit_Monnam(mtmp), - devour ? "devours" : "eats", obj_name); + pline_mon(mtmp, "%s %s %s.", + devour ? noit_or_your_Monnam(mtmp) + : noit_Monnam(mtmp), + devour ? "devours" : "eats", obj_name); } else if (seeobj) { obj_name = distant_name(obj, doname); pline("It %s %s.", devour ? "devours" : "eats", obj_name); diff --git a/src/dokick.c b/src/dokick.c index 45d0b097c..a37e39fd9 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dokick.c $NHDT-Date: 1712453347 2024/04/07 01:29:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.223 $ */ +/* NetHack 5.0 dokick.c $NHDT-Date: 1781973046 2026/06/20 16:30:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.237 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -601,13 +601,13 @@ really_kick_object(coordxy x, coordxy y) || closed_door(x + u.dx, y + u.dy)) range = 1; - /* 3.7: this used to skip 'costly' handling if kickedobj->no_charge + /* 5.0: this used to skip 'costly' handling if kickedobj->no_charge was set but that optimization could result in no_charge staying set for objects kicked out of the shop */ shkp = find_objowner(gk.kickedobj, x, y); costly = (shkp && (costly_spot(x, y) || (costly_adjacent(shkp, x, y) && gk.kickedobj->unpaid))); - /* 3.7: give feedback about the item being kicked; some follow-on + /* 5.0: give feedback about the item being kicked; some follow-on messages refer to "it" */ Norep("You kick %s.", !isgold ? singular(gk.kickedobj, doname) : doname(gk.kickedobj)); @@ -1137,7 +1137,9 @@ kick_nondoor(coordxy x, coordxy y, int avrg_attrib) /* nothing, fruit or trouble? 75:23.5:1.5% */ if (rn2(3)) { - if (!rn2(6) && !(svm.mvitals[PM_KILLER_BEE].mvflags & G_GONE)) + if (!rn2(6) + && !(svm.mvitals[PM_KILLER_BEE].mvflags & G_GONE) + && !(gm.maploc->looted & TREE_SWARM)) You_hear("a low buzzing."); /* a warning */ kick_ouch(x, y, ""); return ECMD_TIME; diff --git a/src/dothrow.c b/src/dothrow.c index 952913a43..9a33e7a1b 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dothrow.c $NHDT-Date: 1737343372 2025/01/19 19:22:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ */ +/* NetHack 5.0 dothrow.c $NHDT-Date: 1781973046 2026/06/20 16:30:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.318 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1437,7 +1437,8 @@ throwing_weapon(struct obj *obj) || obj->otyp == WAR_HAMMER || obj->otyp == AKLYS); } -/* the currently thrown object is returning to you (not for boomerangs) */ +/* the currently thrown object is returning to you (not for boomerangs + or tethered weapons) */ staticfn void sho_obj_return_to_u(struct obj *obj) { @@ -1520,7 +1521,8 @@ throwit( boolean crossbowing, impaired = (Confusion || Stunned || Blind || Hallucination || Fumbling), - tethered_weapon = (arw && arw->tethered && (wep_mask & W_WEP) != 0); + tethered_weapon = (arw && arw->tethered && (wep_mask & W_WEP) != 0), + tether_released_msg = FALSE; gn.notonhead = FALSE; /* reset potentially stale value */ if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) { @@ -1685,8 +1687,14 @@ throwit( /* bhit display cleanup was left with this caller for tethered_weapon, but clean it up now since we're about to return */ - if (tethered_weapon) + if (tethered_weapon) { + if (!tether_released_msg) { + pline("The tether comes off your %s.", + body_part(ARM)); + tether_released_msg = TRUE; + } tmp_at(DISP_END, 0); + } throwit_return(FALSE); return; } @@ -1699,8 +1707,14 @@ throwit( if (!gt.thrownobj) { /* missile has already been handled */ - if (tethered_weapon) + if (tethered_weapon) { + if (!tether_released_msg) { + pline("The tether comes off your %s.", + body_part(ARM)); + tether_released_msg = TRUE; + } tmp_at(DISP_END, 0); + } } else if (u.uswallow && !iflags.returning_missile) { swallowit(obj); return; @@ -1729,46 +1743,88 @@ throwit( } else { int dmg = rn2(2); + if (tethered_weapon) { + /* It's tethered, so it usually returns to your + * inventory, despite impairment */ + obj = addinv_before(obj, oldslot); + encumber_msg(); + /* addinv autoquivers an aklys if quiver is empty; + if obj is quivered, remove it before wielding */ + if (obj->owornmask & W_QUIVER) + setuqwep((struct obj *) 0); + if (cansee(gb.bhitpos.x, gb.bhitpos.y)) + newsym(gb.bhitpos.x, gb.bhitpos.y); + } if (!dmg) { - pline(Blind ? "%s lands %s your %s." - : "%s back to you, landing %s your %s.", - Blind ? Something : Tobjnam(obj, "return"), - Levitation ? "beneath" : "at", - makeplural(body_part(FOOT))); + if (tethered_weapon) { + /* Blind mods unnecessary; you know what you threw, + * and it is tethered to your arm */ + pline("Your tethered %s snaps back but the tether slips from your %s.", + simpleonames(obj), body_part(ARM)); + tether_released_msg = TRUE; + } else { + pline(Blind + ? "%s lands %s your %s." + : "%s back to you, landing %s your %s.", + Blind ? Something : Tobjnam(obj, "return"), + Levitation ? "beneath" : "at", + makeplural(body_part(FOOT))); + } } else { dmg += rnd(3); - pline(Blind ? "%s your %s!" + if (tethered_weapon) { + Your("tethered %s returns and hits your %s!", + simpleonames(obj), body_part(ARM)); + } else { + pline( + Blind + ? "%s your %s!" : "%s back toward you, hitting your %s!", - Tobjnam(obj, Blind ? "hit" : "fly"), - body_part(ARM)); + Tobjnam(obj, Blind ? "hit" : "fly"), + body_part(ARM)); + } if (obj->oartifact) (void) artifact_hit((struct monst *) 0, &gy.youmonst, obj, &dmg, 0); losehp(Maybe_Half_Phys(dmg), killer_xname(obj), KILLED_BY); } - - if (u.uswallow) { - swallowit(obj); - return; + if (!tethered_weapon) { + if (u.uswallow) { + swallowit(obj); + return; + } + if (!ship_object(obj, u.ux, u.uy, FALSE)) + dropy(obj); + } else { + if (!tether_released_msg) { + pline_The("%s tether comes off your %s.", + s_suffix(simpleonames(obj)), body_part(ARM)); + tether_released_msg = TRUE; + } } - if (!ship_object(obj, u.ux, u.uy, FALSE)) - dropy(obj); } throwit_return(TRUE); return; } else { - if (tethered_weapon) + if (tethered_weapon) { + if (!tether_released_msg) { + pline("The tether comes off your %s.", + body_part(ARM)); + tether_released_msg = TRUE; + } tmp_at(DISP_END, 0); - /* when this location is stepped on, the weapon will be - auto-picked up due to 'obj->how_lost' of LOST_THROWN; - addinv() prevents thrown Mjollnir from being placed - into the quiver slot, but an aklys will end up there if - that slot is empty at the time; since hero will need to - explicitly rewield the weapon to get throw-and-return - capability back anyway, quivered or not shouldn't matter */ - pline("%s to return!", Tobjnam(obj, "fail")); - + /* when this location is stepped on, the weapon will be + auto-picked up due to 'obj->how_lost' of LOST_THROWN; + addinv() prevents thrown Mjollnir from being placed + into the quiver slot, but an aklys will end up there if + that slot is empty at the time; since hero will need to + explicitly rewield the weapon to get throw-and-return + capability back anyway, quivered or not shouldn't + matter */ + } else { + pline("%s to return!", Tobjnam(obj, "fail")); + } if (u.uswallow) { swallowit(obj); return; @@ -2082,7 +2138,7 @@ thitmonst( /* throwing real gems to co-aligned unicorns boosts Luck, to cross-aligned unicorns changes Luck by random amount; throwing worthless glass doesn't affect Luck but doesn't anger them; - 3.7: treat rocks and gray stones as attacks rather than like glass + 5.0: treat rocks and gray stones as attacks rather than like glass and also treat gems or glass shot via sling as attacks */ if (obj->oclass == GEM_CLASS && is_unicorn(mon->data) && objects[obj->otyp].oc_material != MINERAL && !uslinging()) { @@ -2151,6 +2207,8 @@ thitmonst( dieroll = rnd(20); + check_caitiff(mon); + if (obj->oclass == WEAPON_CLASS || is_weptool(obj) || obj->oclass == GEM_CLASS) { if (hmode == HMON_KICKED) { diff --git a/src/drawing.c b/src/drawing.c index 587489053..ec3a38668 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 drawing.c $NHDT-Date: 1596498163 2020/08/03 23:42:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */ +/* NetHack 5.0 drawing.c $NHDT-Date: 1781973047 2026/06/20 16:30:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.97 $ */ /* Copyright (c) NetHack Development Team 1992. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/dungeon.c b/src/dungeon.c index 72bb26206..b88ee0fa3 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.c $NHDT-Date: 1737343478 2025/01/19 19:24:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.228 $ */ +/* NetHack 5.0 dungeon.c $NHDT-Date: 1781973047 2026/06/20 16:30:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.239 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1058,11 +1058,22 @@ init_dungeon_dungeons( pd->tmpdungeon[dngidx].chance = dgn_chance; pd->tmpdungeon[dngidx].entry_lev = dgn_entry; - /* FIXME: these should have length checks */ + if (Strlen(dgn_fill) >= sizeof svd.dungeons[dngidx].fill_lvl) + panic("fill_lvl too long for dungeon %d", dngidx); Strcpy(svd.dungeons[dngidx].fill_lvl, dgn_fill); + + if (Strlen(dgn_name) >= sizeof svd.dungeons[dngidx].dname) + panic("dname too long for dungeon %d", dngidx); Strcpy(svd.dungeons[dngidx].dname, dgn_name); + + if (Strlen(dgn_protoname) >= sizeof svd.dungeons[dngidx].proto) + panic("proto too long for dungeon %d", dngidx); Strcpy(svd.dungeons[dngidx].proto, dgn_protoname); + + if (Strlen(dgn_themerms) >= sizeof svd.dungeons[dngidx].themerms) + panic("themerms too long for dungeon %d", dngidx); Strcpy(svd.dungeons[dngidx].themerms, dgn_themerms); + /* FIXME: accept "none", convert that to '\0' */ svd.dungeons[dngidx].boneid = *dgn_bonetag ? *dgn_bonetag : 0; free((genericptr) dgn_fill); diff --git a/src/earlyarg.c b/src/earlyarg.c index 352a9cf46..c64b6bfcd 100755 --- a/src/earlyarg.c +++ b/src/earlyarg.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 earlyarg.c $NHDT-Date: 1771213100 2026/02/15 19:38:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ */ +/* NetHack 5.0 earlyarg.c $NHDT-Date: 1782016695 2026/06/20 23:38:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -40,7 +40,7 @@ static const struct early_opt earlyopts[] = { #ifndef NODUMPENUMS { ARG_DUMPENUMS, "dumpenums", 9, FALSE }, #endif - { ARG_DUMPGLYPHIDS, "dumpglyphids", 12, FALSE }, + { ARG_DUMPGLYPHIDS, "dumpglyphnames", 12, FALSE }, { ARG_DUMPMONGEN, "dumpmongen", 10, FALSE }, { ARG_DUMPWEIGHTS, "dumpweights", 11, FALSE }, #ifdef WIN32 @@ -359,6 +359,89 @@ early_options(int *argc_p, char ***argv_p, char **hackdir_p) config_error_done(); return; } + +/* profession (role), race, alignment, gender command line options */ +void +genl_prag(int argc, char *argv[]) +{ + char *arg; + int i; + + config_error_init(FALSE, "command line", FALSE); + + while (argc > 1 && argv[1][0] == '-') { + argv++; + argc--; + arg = argv[0]; + /* allow second dash if arg is longer than one character */ + if (arg[0] == '-' && arg[1] == '-' + && arg[2] != '\0' + /* "--a=b" violates the "--" ok when at least 2 chars long rule */ + && (arg[3] != '\0' && arg[3] != '=' && arg[3] != ':')) + ++arg; + if (strchr("prag@", arg[1])) { + switch (arg[1]) { + case 'a': + if (arg[2]) { + if ((i = str2align(&arg[2])) >= 0) + flags.initalign = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2align(argv[0])) >= 0) + flags.initalign = i; + } + break; + case 'g': + if (arg[2]) { + if ((i = str2gend(&arg[2])) >= 0) + flags.initgend = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2gend(argv[0])) >= 0) + flags.initgend = i; + } + break; + case 'p': /* profession (role) */ + if (arg[2]) { + if ((i = str2role(&arg[2])) >= 0) + flags.initrole = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2role(argv[0])) >= 0) + flags.initrole = i; + } + break; + case 'r': /* race */ + if (arg[2]) { + if ((i = str2race(&arg[2])) >= 0) + flags.initrace = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2race(argv[0])) >= 0) + flags.initrace = i; + } + break; + case '@': + flags.randomall = 1; + break; + } + } else { + /* default for "-x" is to play as the role that starts with "x" */ + if ((i = str2role(&argv[1][0])) >= 0) { + flags.initrole = i; + } + } + } + + /* empty or "N errors on command line" */ + config_error_done(); + return; +} + /* for command-line options that perform some immediate action and then terminate the program without starting play, like 'nethack --version' or 'nethack -s Zelda'; do some cleanup before that termination */ @@ -498,11 +581,7 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg) if (extended_opt) { extended_opt++; - /* Deprecated in favor of "copy" - remove no later - than next major version */ - if (match_optname(extended_opt, "paste", 5, FALSE)) { - insert_into_pastebuf = TRUE; - } else if (match_optname(extended_opt, "copy", 4, FALSE)) { + if (match_optname(extended_opt, "copy", 4, FALSE)) { insert_into_pastebuf = TRUE; } else if (match_optname(extended_opt, "dump", 4, FALSE)) { /* version number plus enabled features and sanity @@ -530,7 +609,7 @@ argcheck(int argc, char *argv[], enum earlyarg e_arg) return 2; #endif case ARG_DUMPGLYPHIDS: - dump_glyphids(); + dump_glyphnames(); return 2; case ARG_DUMPMONGEN: dump_mongen(); @@ -709,6 +788,7 @@ dump_enums(void) monsters_enum, objects_enum, objects_misc_enum, + glyph_offsets_enum, defsym_cmap_enum, defsym_mon_syms_enum, defsym_mon_defchars_enum, @@ -720,6 +800,59 @@ dump_enums(void) NUM_ENUM_DUMPS }; +#define dump_go(go) { GLYPH_##go, #go } +static const struct enum_dump glyph_offsets_dump[] = { + dump_go(MON_OFF), + dump_go(MON_MALE_OFF), + dump_go(MON_FEM_OFF), + dump_go(PET_OFF), + dump_go(PET_MALE_OFF), + dump_go(PET_FEM_OFF), + dump_go(INVIS_OFF), + dump_go(DETECT_OFF), + dump_go(DETECT_MALE_OFF), + dump_go(DETECT_FEM_OFF), + dump_go(BODY_OFF), + dump_go(RIDDEN_OFF), + dump_go(RIDDEN_MALE_OFF), + dump_go(RIDDEN_FEM_OFF), + dump_go(OBJ_OFF), + dump_go(CMAP_OFF), + dump_go(CMAP_STONE_OFF), + dump_go(CMAP_MAIN_OFF), + dump_go(CMAP_MINES_OFF), + dump_go(CMAP_GEH_OFF), + dump_go(CMAP_KNOX_OFF), + dump_go(CMAP_SOKO_OFF), + dump_go(CMAP_A_OFF), + dump_go(ALTAR_OFF), + dump_go(CMAP_B_OFF), + dump_go(ZAP_OFF), + dump_go(CMAP_C_OFF), + dump_go(SWALLOW_OFF), + dump_go(EXPLODE_OFF), + dump_go(EXPLODE_DARK_OFF), + dump_go(EXPLODE_NOXIOUS_OFF), + dump_go(EXPLODE_MUDDY_OFF), + dump_go(EXPLODE_WET_OFF), + dump_go(EXPLODE_MAGICAL_OFF), + dump_go(EXPLODE_FIERY_OFF), + dump_go(EXPLODE_FROSTY_OFF), + dump_go(WARNING_OFF), + dump_go(STATUE_OFF), + dump_go(STATUE_MALE_OFF), + dump_go(STATUE_FEM_OFF), + dump_go(PILETOP_OFF), + dump_go(OBJ_PILETOP_OFF), + dump_go(BODY_PILETOP_OFF), + dump_go(STATUE_MALE_PILETOP_OFF), + dump_go(STATUE_FEM_PILETOP_OFF), + dump_go(UNEXPLORED_OFF), + dump_go(NOTHING_OFF), + { MAX_GLYPH, "MAX_GLYPH" } + }; +#undef dump_go + #define dump_om(om) { om, #om } static const struct enum_dump omdump[] = { dump_om(LAST_GENERIC), @@ -736,12 +869,14 @@ dump_enums(void) dump_om(LAST_GLASS_GEM), dump_om(NUM_REAL_GEMS), dump_om(NUM_GLASS_GEMS), - dump_om(MAX_GLYPH), + dump_om(MAXEXPCHARS), + dump_om(MAXTCHARS), + dump_om(WARNCOUNT), }; #undef dump_om static const struct enum_dump *const ed[NUM_ENUM_DUMPS] = { - monsdump, objdump, omdump, + monsdump, objdump, omdump, glyph_offsets_dump, defsym_cmap_dump, defsym_mon_syms_dump, defsym_mon_defchars_dump, objclass_defchars_dump, @@ -761,6 +896,7 @@ dump_enums(void) { "monnums", "PM_", UNPREFIXED_COUNT, 0, SIZE(monsdump) }, { "objects_nums", "", 1, 0, SIZE(objdump) }, { "misc_object_nums", "", 1, 0, SIZE(omdump) }, + { "glyph_offsets", "GLYPH_", 1, 0, SIZE(glyph_offsets_dump) }, { "cmap_symbols", "", 1, 0, SIZE(defsym_cmap_dump) }, { "mon_syms", "", 1, 0, SIZE(defsym_mon_syms_dump) }, { "mon_defchars", "", 1, 1, SIZE(defsym_mon_defchars_dump) }, @@ -803,9 +939,9 @@ dump_enums(void) #endif /* NODUMPENUMS */ void -dump_glyphids(void) +dump_glyphnames(void) { - dump_all_glyphids(stdout); + dump_all_glyphnames(stdout); } #endif /* !NODUMPENUMS */ diff --git a/src/eat.c b/src/eat.c index e62a2ffea..4e3d077e1 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 eat.c $NHDT-Date: 1740534854 2025/02/25 17:54:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ +/* NetHack 5.0 eat.c $NHDT-Date: 1781973048 2026/06/20 16:30:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.354 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -398,6 +398,11 @@ food_disappears(struct obj *obj) if (obj == svc.context.victual.piece) svc.context.victual = zero_victual; /* victual.piece = 0, .o_id = 0 */ + if (obj == svc.context.tin.tin) { + svc.context.tin.tin = (struct obj *) 0; + svc.context.tin.o_id = 0; + } + if (obj->timed) obj_stop_timers(obj); } @@ -839,7 +844,7 @@ cprefx(int pm) /* life-saving needed to reach here */ exercise(A_WIS, FALSE); /* revive an actual corpse; can't do that if it was a tin; - 3.7: this used to assume that such tins were impossible but + 5.0: this used to assume that such tins were impossible but they can be wished for in wizard mode; they can't make it to normal play though because bones creation empties them */ if (svc.context.victual.piece /* Null for tins */ @@ -1891,7 +1896,7 @@ eatcorpse(struct obj *otmp) rotted -= 2L; } - /* 3.7: globs don't become tainted, they shrink away */ + /* 5.0: globs don't become tainted, they shrink away */ if (!glob && !stoneable && !slimeable && rotted > 5L) { boolean cannibal = maybe_cannibal(mnum, FALSE); @@ -2176,7 +2181,7 @@ fprefx(struct obj *otmp) } else if (otmp->otyp == APPLE && otmp->cursed && !Sleep_resistance) { ; /* skip core joke; feedback deferred til fpostfx() */ -#if defined(MAC) || defined(MACOS) +#if defined(MAC68K) || defined(MACOS) /* KMH -- Why should Unix have all the fun? We check MACOS before UNIX to get the Apple-specific apple message; the '#if UNIX' code will still kick in for pear. */ @@ -2632,7 +2637,7 @@ edibility_prompts(struct obj *otmp) */ char buf[BUFSZ], foodsmell[BUFSZ], it_or_they[QBUFSZ]; - /* 3.7: decaying globs don't become tainted anymore; in 3.6, they did */ + /* 5.0: decaying globs don't become tainted anymore; in 3.6, they did */ boolean cadaver = (otmp->otyp == CORPSE), stoneorslime = FALSE; int material = objects[otmp->otyp].oc_material, mnum = otmp->corpsenm; long rotted = 0L; @@ -3179,7 +3184,7 @@ gethungry(void) u.uhunger--; /* ordinary food consumption */ /* - * 3.7: trigger is randomized instead of (moves % N). Makes + * 5.0: trigger is randomized instead of (moves % N). Makes * ring juggling (using the 'time' option to see the turn counter * in order to time swapping of a pair of rings of slow digestion, * wearing one on one hand, then putting on the other and taking @@ -3209,7 +3214,7 @@ gethungry(void) * Possessing the real Amulet imposes a separate hunger penalty * from wearing an amulet (so gets a double penalty when worn). * - * 3.7.0: Worn meat rings don't affect hunger. + * 5.0.0: Worn meat rings don't affect hunger. * Same with worn cheap plastic imitation of the Amulet. * +0 ring of protection might do something (enhanced "magical * cancellation") if hero doesn't have protection from some @@ -3222,7 +3227,7 @@ gethungry(void) */ switch (accessorytime) { /* note: use even cases among 0..19 only */ case 0: - /* 3.7: if not wearing a ring of slow digestion, obtaining + /* 5.0: if not wearing a ring of slow digestion, obtaining that property from worn armor (white dragon scales/mail) causes the armor to burn nutrition; since it's not actually a ring, we don't check for it on the ring diff --git a/src/end.c b/src/end.c index 389d8f548..ef26d317d 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 end.c $NHDT-Date: 1720397752 2024/07/08 00:15:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ */ +/* NetHack 5.0 end.c $NHDT-Date: 1781973048 2026/06/20 16:30:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.349 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -110,9 +110,12 @@ done2(void) u.usleep = 0; } - if (abandon_tutorial) + if (abandon_tutorial) { + /* mention_decor can be processed now */ + rcfile_only_this_option(opt_mention_decor); schedule_goto(&u.ucamefrom, UTOTYPE_ATSTAIRS, "Resuming regular play.", (char *) 0); + } return ECMD_OK; } @@ -1676,9 +1679,6 @@ nh_terminate(int status) program_state.in_moveloop = 0; /* won't be returning to normal play */ l_nhcore_call(NHCORE_GAME_EXIT); -#ifdef MAC - getreturn("to exit"); -#endif /* don't bother to try to release memory if we're in panic mode, to avoid trouble in case that happens to be due to memory problems */ if (!program_state.panicking) { @@ -1893,7 +1893,7 @@ build_english_list(char *in) # endif void -NH_abort(char *why USED_FOR_CRASHREPORT) +NH_abort(const char *why USED_FOR_CRASHREPORT) { #ifdef PANICTRACE int gdb_prio = SYSOPT_PANICTRACE_GDB; @@ -1909,7 +1909,7 @@ NH_abort(char *why USED_FOR_CRASHREPORT) #ifdef PANICTRACE #ifdef CRASHREPORT - if(!submit_web_report(1, "Panic", why)) + if (!submit_web_report(1, "Panic", why)) #endif { #ifndef VMS diff --git a/src/engrave.c b/src/engrave.c index 22ca30aaf..76b95716d 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 engrave.c $NHDT-Date: 1737345573 2025/01/19 19:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.165 $ */ +/* NetHack 5.0 engrave.c $NHDT-Date: 1781973048 2026/06/20 16:30:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.179 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -18,6 +18,7 @@ struct _doengrave_ctx { boolean disprefresh; /* TRUE if the display needs a refresh */ boolean frosted; /* TRUE if engraving on ice */ boolean adding; /* TRUE if adding to existing engraving */ + boolean hero_told_it_vanished; int ret; /* doengrave return value */ int type; /* Type of engraving made */ @@ -553,6 +554,7 @@ doengrave_ctx_init(struct _doengrave_ctx *de) de->zapwand = FALSE; de->disprefresh = FALSE; de->adding = FALSE; + de->hero_told_it_vanished = FALSE; de->ret = ECMD_OK; de->type = DUST; @@ -666,17 +668,21 @@ doengrave_sfx_item_WAN(struct _doengrave_ctx *de) case WAN_CANCELLATION: case WAN_MAKE_INVISIBLE: if (de->oep && de->oep->engr_type != HEADSTONE) { - if (!Blind) + if (!Blind) { pline_The("engraving on the %s vanishes!", surface(u.ux, u.uy)); + de->hero_told_it_vanished = TRUE; + } de->dengr = TRUE; } break; case WAN_TELEPORTATION: if (de->oep && de->oep->engr_type != HEADSTONE) { - if (!Blind) + if (!Blind) { pline_The("engraving on the %s vanishes!", surface(u.ux, u.uy)); + de->hero_told_it_vanished = TRUE; + } de->teleengr = TRUE; } break; @@ -1060,12 +1066,28 @@ doengrave(void) rloc_engr(de->oep); de->oep->eread = 0; de->oep->erevealed = 0; + /* The old engraving indicator is probably still showing + * if, for example, the hero is invisible. Get rid of it + * right now, if the player has already been told that + * it vanished. + */ + if (de->hero_told_it_vanished) + newsym(u.ux, u.uy); + de->disprefresh = TRUE; de->oep = (struct engr *) 0; } if (de->dengr) { del_engr(de->oep); de->oep = (struct engr *) 0; + /* The old engraving indicator is probably still showing + * if, for example, the hero is invisible. Get rid of it + * right now, if the player has already been told that + * it vanished. + */ + if (de->hero_told_it_vanished) + newsym(u.ux, u.uy); + de->disprefresh = TRUE; } /* Something has changed the engraving here */ diff --git a/src/exper.c b/src/exper.c index aee851126..9b65e79da 100644 --- a/src/exper.c +++ b/src/exper.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 exper.c $NHDT-Date: 1706133782 2024/01/24 22:03:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ */ +/* NetHack 5.0 exper.c $NHDT-Date: 1781973049 2026/06/20 16:30:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2007. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/explode.c b/src/explode.c index 70f4c8307..0a8eec530 100644 --- a/src/explode.c +++ b/src/explode.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 explode.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.122 $ */ +/* NetHack 5.0 explode.c $NHDT-Date: 1781973049 2026/06/20 16:30:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.128 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -643,10 +643,14 @@ explode( rehumanize(); } else { if (olet == MON_EXPLODE) { - if (generic) /* explosion was unseen; str=="explosion", */ - ; /* svk.killer.name=="gas spore's explosion". */ - else if (str != svk.killer.name && str != hallu_buf) + if (generic) { + /* explosion was unseen; str=="explosion", */ + /* svk.killer.name=="gas spore's explosion" */ + if (!strcmp(str, "explosion")) + Strcpy(svk.killer.name, str); + } else if (str != svk.killer.name && str != hallu_buf) { Strcpy(svk.killer.name, str); + } svk.killer.format = KILLED_BY_AN; } else if (olet == TRAP_EXPLODE) { svk.killer.format = NO_KILLER_PREFIX; diff --git a/src/extralev.c b/src/extralev.c index e0c2afc84..740f01fa4 100644 --- a/src/extralev.c +++ b/src/extralev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 extralev.c $NHDT-Date: 1737345573 2025/01/19 19:59:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ +/* NetHack 5.0 extralev.c $NHDT-Date: 1781973049 2026/06/20 16:30:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.30 $ */ /* Copyright 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/files.c b/src/files.c index ae45f6c07..d03ad1071 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 files.c $NHDT-Date: 1740532826 2025/02/25 17:20:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.417 $ */ +/* NetHack 5.0 files.c $NHDT-Date: 1781973049 2026/06/20 16:30:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.448 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -38,7 +38,7 @@ #include "wintty.h" /* more() */ #endif -#if (!defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ +#if (!defined(MAC68K) && !defined(O_WRONLY) && !defined(AZTEC_C)) \ || defined(USE_FCNTL) #include #endif @@ -110,10 +110,6 @@ static char fqn_filename_buffer[FQN_NUMBUF][FQN_MAX_FILENAME]; #ifdef AMIGA extern char PATH[]; /* see sys/amiga/amidos.c */ -extern char bbs_id[]; -#ifdef __SASC_60 -#include -#endif #include extern void amii_set_text_font(char *, int); @@ -137,7 +133,7 @@ extern boolean get_user_home_folder(char *, size_t); #endif #endif -#ifdef MAC +#ifdef MAC68K #undef unlink #define unlink macunlink #endif @@ -510,7 +506,7 @@ free_nhfile(NHFILE *nhfp) { if (nhfp) { init_nhfile(nhfp); - free(nhfp); + free((genericptr_t) nhfp); } } @@ -647,7 +643,7 @@ create_levelfile(int lev, char errbuf[]) nhfp->fd = open(fq_lock, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK); #else -#ifdef MAC +#ifdef MAC68K nhfp->fd = maccreat(fq_lock, LEVL_TYPE); #else nhfp->fd = creat(fq_lock, FCMASK); @@ -660,8 +656,9 @@ create_levelfile(int lev, char errbuf[]) Sprintf(errbuf, "Cannot create file \"%s\" for level %d (errno %d).", gl.lock, lev, errno); -#if defined(MSDOS) - setmode(nhfp->fd, O_BINARY); +#if defined(MSDOS) || defined(WIN32) + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } nhfp = viable_nhfile(nhfp); @@ -692,7 +689,7 @@ open_levelfile(int lev, char errbuf[]) nhfp->fpdef = (FILE *) 0; } if (nhfp && nhfp->structlevel) { -#ifdef MAC +#ifdef MAC68K nhfp->fd = macopen(fq_lock, O_RDONLY | O_BINARY, LEVL_TYPE); #else nhfp->fd = open(fq_lock, O_RDONLY | O_BINARY, 0); @@ -705,8 +702,9 @@ open_levelfile(int lev, char errbuf[]) Sprintf(errbuf, "Cannot open file \"%s\" for level %d (errno %d).", gl.lock, lev, errno); -#if defined(MSDOS) - setmode(nhfp->fd, O_BINARY); +#if defined(MSDOS) || defined(WIN32) + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } nhfp = viable_nhfile(nhfp); @@ -833,6 +831,9 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) const char *file; NHFILE *nhfp = (NHFILE *) 0; int failed = 0; +#if defined(WIN32) + errno_t err; +#endif if (errbuf) *errbuf = '\0'; @@ -851,7 +852,7 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) nhfp->style.binary = TRUE; nhfp->fnidx = historical; nhfp->fd = -1; - nhfp->fpdef = fopen(file, nhfp->style.binary ? WRBMODE : WRTMODE); + nhfp->fpdef = (FILE *) 0; if (nhfp->fpdef) { #ifdef SAVEFILE_DEBUGGING nhfp->fpdebug = fopen("create_bonesfile-debug.log", "a"); @@ -860,24 +861,29 @@ create_bonesfile(d_level *lev, char **bonesid, char errbuf[]) failed = errno; } if (nhfp->structlevel) { -#if defined(MICRO) || defined(WIN32) +#if defined(MICRO) /* Use O_TRUNC to force the file to be shortened if it already * exists and is currently longer. */ nhfp->fd = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK); +#elif defined(WIN32) + err = _sopen_s(&nhfp->fd, file, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, + _SH_DENYRW, _S_IREAD | _S_IWRITE); #else /* ?MICRO || WIN32 */ -/* implies UNIX or MAC (MAC is for OS9 or earlier) */ -#ifdef MAC +/* implies UNIX or MAC68K (MAC68K is for OS9 or earlier) */ +#ifdef MAC68K nhfp->fd = maccreat(file, BONE_TYPE); #else nhfp->fd = creat(file, FCMASK); -#endif /* ?MAC */ +#endif /* ?MAC68K */ #endif /* ?MICRO || WIN32 */ if (nhfp->fd < 0) failed = errno; -#if defined(MSDOS) - setmode(nhfp->fd, O_BINARY); +#if defined(MSDOS) || defined(WIN32) + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } if (failed && errbuf) /* failure explanation */ @@ -931,6 +937,9 @@ open_bonesfile(d_level *lev, char **bonesid) { const char *fq_bones; NHFILE *nhfp = (NHFILE *) 0; +#if defined(WIN32) + errno_t err UNUSED; +#endif *bonesid = set_bonesfile_name(gb.bones, lev); fq_bones = fqname(gb.bones, BONESPREFIX, 0); @@ -938,6 +947,10 @@ open_bonesfile(d_level *lev, char **bonesid) nhfp = new_nhfile(); if (nhfp) { +#if defined(WIN32) && defined(DEBUG) + if (nhfp->fd >= 0) + impossible("bones file NHFILE * has odd fd (%d)", nhfp->fd); +#endif nhfp->structlevel = TRUE; nhfp->fieldlevel = FALSE; nhfp->ftype = NHF_BONESFILE; @@ -947,20 +960,24 @@ open_bonesfile(d_level *lev, char **bonesid) nhfp->style.binary = (sysopt.bonesformat[0] != exportascii); nhfp->fnidx = sysopt.bonesformat[0]; nhfp->fd = -1; - nhfp->fpdef = fopen(fq_bones, nhfp->style.binary ? RDBMODE : RDTMODE); + nhfp->fpdef = (FILE *) 0; if (nhfp->fpdef) { #ifdef SAVEFILE_DEBUGGING nhfp->fpdebug = fopen("open_bonesfile-debug.log", "a"); #endif } if (nhfp->structlevel) { -#ifdef MAC +#if defined(MAC68K) nhfp->fd = macopen(fq_bones, O_RDONLY | O_BINARY, BONE_TYPE); +#elif defined(WIN32) + err = _sopen_s(&nhfp->fd, fq_bones, _O_RDONLY | _O_BINARY, + _SH_DENYRW, _S_IREAD | _S_IWRITE); #else nhfp->fd = open(fq_bones, O_RDONLY | O_BINARY, 0); #endif -#if defined(MSDOS) - setmode(nhfp->fd, O_BINARY); +#if defined(MSDOS) || defined(WIN32) + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } } @@ -1044,11 +1061,6 @@ set_savefile_name(boolean regularize_it) #if defined(MICRO) && !defined(WIN32) && !defined(MSDOS) if (strlen(gs.SAVEP) < (SAVESIZE - 1)) Strcpy(gs.SAVEF, gs.SAVEP); - else -#ifdef AMIGA - if (strlen(gs.SAVEP) + strlen(bbs_id) < (SAVESIZE - 1)) - strncat(gs.SAVEF, bbs_id, PATHLEN); -#endif { int i = strlen(gs.SAVEP); #ifdef AMIGA @@ -1124,7 +1136,7 @@ set_error_savefile(void) } Strcat(gs.SAVEF, ".e;1"); #else -#ifdef MAC +#ifdef MAC68K Strcat(gs.SAVEF, "-e"); #else Strcat(gs.SAVEF, ".e"); @@ -1163,16 +1175,16 @@ create_savefile(void) nhfp->fd = open(fq_save, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); #else /* !MICRO && !WIN32 */ -/* UNIX || MAC implied (MAC is OS9 or earlier only) */ -#ifdef MAC +/* UNIX || MAC68K implied (MAC68K is OS9 or earlier only) */ +#ifdef MAC68K nhfp->fd = maccreat(fq_save, SAVE_TYPE); #else nhfp->fd = creat(fq_save, FCMASK); #endif #endif /* MICRO || WIN32 */ #if defined(MSDOS) || defined(WIN32) - if (nhfp->fd >= 0) - (void) setmode(nhfp->fd, O_BINARY); + if (nhfp->fd >= 0) + (void) setmode(nhfp->fd, O_BINARY); #endif } } @@ -1219,7 +1231,7 @@ open_savefile(void) nhfp->fplog = fopen("open-savefile.log", "w"); #endif } -#ifdef MAC +#ifdef MAC68K nhfp->fd = macopen(fq_save, O_RDONLY | O_BINARY, SAVE_TYPE); #else nhfp->fd = open(fq_save, O_RDONLY | O_BINARY, 0); @@ -1257,7 +1269,7 @@ restore_saved_game(void) nh_uncompress(fq_save); if ((nhfp = open_savefile()) != 0) { - if ((sfstatus = validate(nhfp, fq_save, FALSE)) != SF_UPTODATE) { + if ((sfstatus = validate(nhfp, fq_save, FALSE, 0)) != SF_UPTODATE) { close_nhfile(nhfp); nhfp = problematic_savefile(sfstatus, fq_save); } @@ -1335,7 +1347,7 @@ check_panic_save(void) char * plname_from_file( const char *filename, - boolean without_wait_synch_per_file) + boolean without_wait_synch_per_file, int additional_utd_flags) { NHFILE *nhfp; unsigned ln; @@ -1356,7 +1368,8 @@ plname_from_file( nh_uncompress(gs.SAVEF); if ((nhfp = open_savefile()) != 0) { if ((sfstatus = validate(nhfp, filename, - without_wait_synch_per_file)) == SF_UPTODATE) { + without_wait_synch_per_file, + additional_utd_flags)) == SF_UPTODATE) { /* room for "name+role+race+gend+algn X" where the space before X is actually NUL and X is playmode: one of '-', 'X', or 'D' */ ln = (unsigned) PL_NSIZ_PLUS; @@ -1393,7 +1406,7 @@ get_saved_games(void) const char *fq_old_save; #endif char **files = 0; - int i, count_failures = 0; + int i, count_failures = 0, utd_flags_to_pass_downstream = 0; Strcpy(svp.plname, "*"); set_savefile_name(FALSE); @@ -1426,7 +1439,11 @@ get_saved_games(void) (void) memset((genericptr_t) result, 0, (n + 1) * sizeof (char *)); for(i = 0; i < n; i++) { char *r; - r = plname_from_file(files[i], SUPPRESS_WAITSYNCH_PERFILE); + if (!wizard) + utd_flags_to_pass_downstream = UTD_QUIETLY; + r = plname_from_file(files[i], + SUPPRESS_WAITSYNCH_PERFILE, + utd_flags_to_pass_downstream); if (r) { /* this renaming of the savefile is not compatible @@ -1453,7 +1470,7 @@ get_saved_games(void) } free_saved_games(files); - if (count_failures) + if (count_failures && !(utd_flags_to_pass_downstream & UTD_QUIETLY)) wait_synch(); } #endif /* WIN32 */ @@ -1487,7 +1504,7 @@ get_saved_games(void) Sprintf(filename, "save/%d%s", uid, name); r = plname_from_file(filename, - ALLOW_WAITSYNCH_PERFILE); + ALLOW_WAITSYNCH_PERFILE, 0); if (r) result[j++] = r; } @@ -1529,6 +1546,7 @@ free_saved_games(char **saved) free((genericptr_t) saved); } } + #endif /* !SFCTOOL */ /* ---------- END SAVE FILE HANDLING ----------- */ @@ -2028,7 +2046,7 @@ problematic_savefile(int sfstatus, const char *savefilenm) /* ---------- BEGIN EXTERNAL CONVERSION HANDLING ----------- */ -static boolean cvtinit = FALSE; +/* static boolean cvtinit = FALSE; */ #ifndef SFCTOOL static char *unconverted_filename = 0, *converted_filename = 0; @@ -2102,7 +2120,7 @@ make_converted_name(const char *filename) size_t sz = strlen(folderbuf); Snprintf(eos(folderbuf), sizeof folderbuf - sz, - "\\AppData\\Local\\NetHack\\3.7\\"); + "\\AppData\\Local\\NetHack\\5.0\\"); dir = (const char *) folderbuf; } #endif /* UNIX || WIN32 */ @@ -2149,7 +2167,7 @@ free_convert_filenames(void) free((genericptr_t) converted_filename), converted_filename = 0; if (unconverted_filename) free((genericptr_t) unconverted_filename), unconverted_filename = 0; - cvtinit = FALSE; +/* cvtinit = FALSE; */ } /* return TRUE if s contains a directory, not just a filespec */ @@ -2478,7 +2496,7 @@ fopen_wizkit_file(void) #endif } -#if defined(MICRO) || defined(MAC) || defined(__BEOS__) || defined(WIN32) +#if defined(MICRO) || defined(MAC68K) || defined(__BEOS__) || defined(WIN32) if ((fp = fopen(fqname(gw.wizkit, CONFIGPREFIX, 0), "r")) != (FILE *) 0) return fp; #else @@ -2757,13 +2775,13 @@ check_recordfile(const char *dir UNUSED_if_not_OS2_CODEVIEW) } #else /* MICRO || WIN32*/ -#ifdef MAC +#ifdef MAC68K /* Create the "record" file, if necessary */ fq_record = fqname(RECORD, SCOREPREFIX, 0); fd = macopen(fq_record, O_RDWR | O_CREAT, TEXT_TYPE); if (fd != -1) macclose(fd); -#endif /* MAC */ +#endif /* MAC68K */ #endif /* MICRO || WIN32*/ } @@ -2971,6 +2989,9 @@ recover_savefile(void) if (savewrite_failure) goto cleanup; + if (snhfp->structlevel) + bufoff(snhfp->fd); + /* TODO: this is not a single byte, so a big-endian byte swap * might be necessary here, if anyone is concerned about big-endian */ Sfo_int(snhfp, &pltmpsiz, "plname-size"); @@ -3023,6 +3044,8 @@ recover_savefile(void) } } } + if (snhfp->structlevel) + bufon(snhfp->fd); close_nhfile(snhfp); /* * We have a successful savefile! diff --git a/src/fountain.c b/src/fountain.c index 78925b04c..8cafaf2a2 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 fountain.c $NHDT-Date: 1699582923 2023/11/10 02:22:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ +/* NetHack 5.0 fountain.c $NHDT-Date: 1781973050 2026/06/20 16:30:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.121 $ */ /* Copyright Scott R. Turner, srt@ucla, 10/27/86 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/getpos.c b/src/getpos.c index ed53d334b..643d12bd6 100644 --- a/src/getpos.c +++ b/src/getpos.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 getpos.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ +/* NetHack 5.0 getpos.c $NHDT-Date: 1781973050 2026/06/20 16:30:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /*-Copyright (c) Pasi Kallinen, 2023. */ /* NetHack may be freely redistributed. See license for details. */ @@ -852,7 +852,7 @@ getpos(coord *ccp, boolean force, const char *goal) #endif curs(WIN_MAP, cx, cy); flush_screen(0); -#ifdef MAC +#ifdef MAC68K lock_mouse_cursor(TRUE); #endif lock_mouse_buttons(TRUE); @@ -1149,7 +1149,7 @@ getpos(coord *ccp, boolean force, const char *goal) flush_screen(0); } exitgetpos: -#ifdef MAC +#ifdef MAC68K lock_mouse_cursor(FALSE); #endif lock_mouse_buttons(FALSE); diff --git a/src/glyphs.c b/src/glyphs.c index 778cb4aeb..2ef04a3a6 100644 --- a/src/glyphs.c +++ b/src/glyphs.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 glyphs.c TODO: add NHDT branch/date/revision tags */ +/* NetHack 5.0 glyphs.c TODO: add NHDT branch/date/revision tags */ /* Copyright (c) Michael Allison, 2021. */ /* NetHack may be freely redistributed. See license for details. */ @@ -11,7 +11,7 @@ extern struct enum_dump objdump[]; #define Fprintf (void) fprintf -enum reserved_activities { res_nothing, res_dump_glyphids, res_fill_cache }; +enum reserved_activities { res_nothing, res_dump_glyphnames }; enum things_to_find { find_nothing, find_pm, find_oc, find_cmap, find_glyph }; struct find_struct { enum things_to_find findtype; @@ -26,21 +26,20 @@ struct find_struct { genericptr_t reserved; }; static const struct find_struct zero_find = { 0 }; -struct glyphid_cache_t { +struct glyphname_hash_index_entry_t { + uint32 hash; int glyphnum; - char *id; }; -static struct glyphid_cache_t *glyphid_cache; -static unsigned glyphid_cache_lsize; -static size_t glyphid_cache_size; -static struct find_struct glyphcache_find, to_custom_symbol_find; +static struct glyphname_hash_index_entry_t *glyphname_hash_indices_ptr; +static size_t glyphname_hash_indices_count; +static struct find_struct to_custom_symbol_find; static const long nonzero_black = CLR_BLACK | NH_BASIC_COLOR; -staticfn void init_glyph_cache(void); -staticfn void add_glyph_to_cache(int glyphnum, const char *id); -staticfn int find_glyph_in_cache(const char *id); -staticfn char *find_glyphid_in_cache_by_glyphnum(int glyphnum); +staticfn int find_glyph_in_hashtable(const char *id); +staticfn int cmp_glyphname_entry(const void *a, const void *b); staticfn uint32 glyph_hash(const char *id); +staticfn int compose_glyph_name(int glyph, char *buf, size_t bufsz); +staticfn int get_cmap_offset(void); staticfn void to_custom_symset_entry_callback(int glyph, struct find_struct *findwhat); staticfn int parse_id(const char *id, struct find_struct *findwhat); @@ -114,18 +113,18 @@ glyphrep_to_custom_map_entries( int *glyphptr) { to_custom_symbol_find = zero_find; - char buf[BUFSZ], *c_glyphid, *c_unicode, *c_colorval, *cp; + char buf[BUFSZ], *c_glyphname, *c_unicode, *c_colorval, *cp; int reslt = 0; long rgb = 0L; boolean slash = FALSE, colon = FALSE; - if (!glyphid_cache) + if (!glyphname_hash_indices_ptr) reslt = 1; /* for debugger use only; no cache available */ nhUse(reslt); Snprintf(buf, sizeof buf, "%s", op); c_unicode = c_colorval = (char *) 0; - c_glyphid = cp = buf; + c_glyphname = cp = buf; while (*cp) { if (*cp == ':' || *cp == '/') { if (*cp == ':') { @@ -148,8 +147,8 @@ glyphrep_to_custom_map_entries( } } /* some sanity checks */ - if (c_glyphid && *c_glyphid == ' ') - c_glyphid++; + if (c_glyphname && *c_glyphname == ' ') + c_glyphname++; if (c_colorval && *c_colorval == ' ') c_colorval++; if (c_unicode && *c_unicode == ' ') { @@ -176,7 +175,7 @@ glyphrep_to_custom_map_entries( to_custom_symbol_find.unicode_val = c_unicode; to_custom_symbol_find.extraval = glyphptr; to_custom_symbol_find.callback = to_custom_symset_entry_callback; - reslt = glyph_find_core(c_glyphid, &to_custom_symbol_find); + reslt = glyph_find_core(c_glyphname, &to_custom_symbol_find); return reslt; } @@ -196,6 +195,238 @@ fix_glyphname(char *str) return str; } +/* First SYM_PCHAR index in loadsyms[], cached (0 = not computed yet; + SYM_PCHAR is never at index 0). */ +static int cached_cmap_offset = 0; + +staticfn int +get_cmap_offset(void) +{ + if (!cached_cmap_offset) { + int i; + + for (i = 0; loadsyms[i].range; i++) { + if (loadsyms[i].range == SYM_PCHAR) { + cached_cmap_offset = i; + break; + } + } + } + return cached_cmap_offset; +} + +/* Build the canonical "G_xxx" identifier for the given glyph into buf. + * Returns 1 if a name was produced, 0 if this glyph has no canonical name + * (a few unused object indices); buf[0] is set to '\0' in that case. + * Callers must pass a BUFSZ-sized buffer. + * Used by find_glyph_in_hashtable to verify hash matches, by the + * --dumpglyphnames path, by populate_glyphname_hash_indices to fill the + * table, and by wizcustom_glyphnames. */ +staticfn int +compose_glyph_name(int glyph, char *buf, size_t bufsz) +{ + int i, j, mnum, cmap_offset; + boolean skip_base = FALSE; + const char *buf2, *buf3, *buf4; + char tmpbuf[4][QBUFSZ]; + + if (bufsz < BUFSZ) + return 0; + buf[0] = '\0'; + tmpbuf[0][0] = tmpbuf[1][0] = tmpbuf[2][0] = tmpbuf[3][0] = '\0'; + cmap_offset = get_cmap_offset(); + + if (glyph_is_monster(glyph)) { + buf2 = ""; + buf3 = monsdump[glyph_to_mon(glyph)].nm; + if (glyph_is_normal_male_monster(glyph)) { + buf2 = "male_"; + } else if (glyph_is_normal_female_monster(glyph)) { + buf2 = "female_"; + } else if (glyph_is_ridden_male_monster(glyph)) { + buf2 = "ridden_male_"; + } else if (glyph_is_ridden_female_monster(glyph)) { + buf2 = "ridden_female_"; + } else if (glyph_is_detected_male_monster(glyph)) { + buf2 = "detected_male_"; + } else if (glyph_is_detected_female_monster(glyph)) { + buf2 = "detected_female_"; + } else if (glyph_is_male_pet(glyph)) { + buf2 = "pet_male_"; + } else if (glyph_is_female_pet(glyph)) { + buf2 = "pet_female_"; + } + Snprintf(buf, bufsz, "G_%s%s", buf2, buf3); + } else if (glyph_is_body(glyph)) { + buf2 = glyph_is_body_piletop(glyph) ? "piletop_body_" : "body_"; + buf3 = monsdump[glyph_to_body_corpsenm(glyph)].nm; + Snprintf(buf, bufsz, "G_%s%s", buf2, buf3); + } else if (glyph_is_statue(glyph)) { + buf2 = glyph_is_fem_statue_piletop(glyph) + ? "piletop_statue_of_female_" + : glyph_is_fem_statue(glyph) + ? "statue_of_female_" + : glyph_is_male_statue_piletop(glyph) + ? "piletop_statue_of_male_" + : glyph_is_male_statue(glyph) + ? "statue_of_male_" + : ""; + buf3 = monsdump[glyph_to_statue_corpsenm(glyph)].nm; + Snprintf(buf, bufsz, "G_%s%s", buf2, buf3); + } else if (glyph_is_object(glyph)) { + i = glyph_to_obj(glyph); + if (((i > SCR_STINKING_CLOUD) && (i < SCR_MAIL)) + || ((i > WAN_LIGHTNING) && (i < GOLD_PIECE))) { + return 0; + } + if ((i >= WAN_LIGHT) && (i <= WAN_LIGHTNING)) + buf2 = "wand of "; + else if ((i >= SPE_DIG) && (i < SPE_BLANK_PAPER)) + buf2 = "spellbook of "; + else if ((i >= SCR_ENCHANT_ARMOR) && (i <= SCR_STINKING_CLOUD)) + buf2 = "scroll of "; + else if ((i >= POT_GAIN_ABILITY) && (i <= POT_WATER)) + buf2 = (i == POT_WATER) ? "flask of n" : "potion of "; + else if ((i >= RIN_ADORNMENT) && (i <= RIN_PROTECTION_FROM_SHAPE_CHAN)) + buf2 = "ring of "; + else if (i == LAND_MINE) + buf2 = "unset "; + else + buf2 = ""; + buf3 = (i == SCR_BLANK_PAPER) ? "blank scroll" + : (i == SPE_BLANK_PAPER) ? "blank spellbook" + : (i == SLIME_MOLD) ? "slime mold" + : obj_descr[i].oc_name + ? obj_descr[i].oc_name + : obj_descr[i].oc_descr; + Snprintf(buf, bufsz, "G_%s%s%s", + (glyph_is_normal_piletop_obj(glyph) + || glyph_is_piletop_generic_obj(glyph)) ? "piletop_" : "", + buf2, buf3); + } else if (glyph_is_cmap(glyph) || glyph_is_cmap_zap(glyph) + || glyph_is_swallow(glyph) || glyph_is_explosion(glyph)) { + int cmap = -1; + + buf2 = ""; + buf3 = ""; + buf4 = ""; + if (glyph == GLYPH_CMAP_OFF) { + cmap = S_stone; + buf3 = "stone substrate"; + skip_base = TRUE; + } else if (glyph_is_cmap_gehennom(glyph)) { + cmap = (glyph - GLYPH_CMAP_GEH_OFF) + S_vwall; + buf4 = "_gehennom"; + } else if (glyph_is_cmap_knox(glyph)) { + cmap = (glyph - GLYPH_CMAP_KNOX_OFF) + S_vwall; + buf4 = "_knox"; + } else if (glyph_is_cmap_main(glyph)) { + cmap = (glyph - GLYPH_CMAP_MAIN_OFF) + S_vwall; + buf4 = "_main"; + } else if (glyph_is_cmap_mines(glyph)) { + cmap = (glyph - GLYPH_CMAP_MINES_OFF) + S_vwall; + buf4 = "_mines"; + } else if (glyph_is_cmap_sokoban(glyph)) { + cmap = (glyph - GLYPH_CMAP_SOKO_OFF) + S_vwall; + buf4 = "_sokoban"; + } else if (glyph_is_cmap_a(glyph)) { + cmap = (glyph - GLYPH_CMAP_A_OFF) + S_ndoor; + } else if (glyph_is_cmap_altar(glyph)) { + static const char *const altar_text[] = { + "unaligned", "chaotic", "neutral", + "lawful", "other", + }; + + j = (glyph - GLYPH_ALTAR_OFF); + cmap = S_altar; + if (j != altar_other) { + Snprintf(tmpbuf[2], sizeof tmpbuf[2], "%s_", altar_text[j]); + buf2 = tmpbuf[2]; + } else { + buf3 = "altar other"; + skip_base = TRUE; + } + } else if (glyph_is_cmap_b(glyph)) { + cmap = (glyph - GLYPH_CMAP_B_OFF) + S_grave; + } else if (glyph_is_cmap_zap(glyph)) { + static const char *const zap_texts[] = { + "missile", "fire", "frost", "sleep", + "death", "lightning", "poison gas", "acid" + }; + + j = (glyph - GLYPH_ZAP_OFF); + cmap = (j % 4) + S_vbeam; + Snprintf(tmpbuf[2], sizeof tmpbuf[2], "%s", + loadsyms[cmap + cmap_offset].name + 2); + Snprintf(tmpbuf[3], sizeof tmpbuf[3], "%s zap %s", + zap_texts[j / 4], fix_glyphname(tmpbuf[2])); + buf3 = tmpbuf[3]; + buf2 = ""; + skip_base = TRUE; + } else if (glyph_is_cmap_c(glyph)) { + cmap = (glyph - GLYPH_CMAP_C_OFF) + S_digbeam; + } else if (glyph_is_swallow(glyph)) { + static const char *const swallow_texts[] = { + "top left", "top center", "top right", + "middle left", "middle right", "bottom left", + "bottom center", "bottom right", + }; + + j = glyph - GLYPH_SWALLOW_OFF; + mnum = j / ((S_sw_br - S_sw_tl) + 1); + if (!attacktype(&mons[mnum], AT_ENGL)) + return 0; + cmap = glyph_to_swallow(glyph); + Snprintf(tmpbuf[3], sizeof tmpbuf[3], "swallow %s %s", + monsdump[mnum].nm, swallow_texts[cmap]); + buf3 = tmpbuf[3]; + skip_base = TRUE; + } else if (glyph_is_explosion(glyph)) { + static const char *const expl_type_texts[] = { + "dark", "noxious", "muddy", "wet", + "magical", "fiery", "frosty", + }; + static const char *const expl_texts[] = { + "tl", "tc", "tr", "ml", "mc", + "mr", "bl", "bc", "br", + }; + int expl; + + j = glyph - GLYPH_EXPLODE_OFF; + expl = j / ((S_expl_br - S_expl_tl) + 1); + cmap = glyph_to_explosion(glyph) + S_expl_tl; + i = cmap - S_expl_tl; + Snprintf(tmpbuf[2], sizeof tmpbuf[2], "%s ", + expl_type_texts[expl]); + buf2 = tmpbuf[2]; + Snprintf(tmpbuf[3], sizeof tmpbuf[3], "%s%s", "expl_", + expl_texts[i]); + buf3 = tmpbuf[3]; + skip_base = TRUE; + } + if (!skip_base) { + if (cmap >= 0 && cmap < MAXPCHARS) + buf3 = loadsyms[cmap + cmap_offset].name + 2; + } + Snprintf(buf, bufsz, "G_%s%s%s", buf2, buf3, buf4); + } else if (glyph_is_invisible(glyph)) { + Snprintf(buf, bufsz, "G_invisible"); + } else if (glyph_is_nothing(glyph)) { + Snprintf(buf, bufsz, "G_nothing"); + } else if (glyph_is_unexplored(glyph)) { + Snprintf(buf, bufsz, "G_unexplored"); + } else if (glyph_is_warning(glyph)) { + j = glyph - GLYPH_WARNING_OFF; + Snprintf(buf, bufsz, "G_%s%d", "warning", j); + } + + if (buf[0] == '\0') + return 0; + fix_glyphname(buf + 2); + nhUse(mnum); + return 1; +} + int glyph_to_cmap(int glyph) { @@ -283,152 +514,96 @@ glyph_find_core( } /* - When we start to process a config file or a symbol file, - that might have G_ entries, generating all 9000+ glyphid - for comparison repeatedly each time we encounter a G_ - entry to decipher, then comparing against them, is obviously - extremely performance-poor. - - Setting aside the "comparison" part for now (that has to be - done in some manner), we can likely do something about the - repeated "generation" of the names for parsing prior to the - actual comparison part by generating them once, ahead of the - bulk of the potential parsings. We can later free up - all the memory those names consumed once the bulk parsing is - over with. -*/ - - -void -fill_glyphid_cache(void) -{ - int reslt = 0; - - if (!glyphid_cache) { - init_glyph_cache(); - } - if (glyphid_cache) { - glyphcache_find = zero_find; - glyphcache_find.findtype = find_nothing; - glyphcache_find.reserved = (genericptr_t) glyphid_cache; - glyphcache_find.restype = res_fill_cache; - reslt = parse_id((char *) 0, &glyphcache_find); - if (!reslt) { - free_glyphid_cache(); - glyphid_cache = (struct glyphid_cache_t *) 0; - } - } -} - -/* - * The glyph ID cache is a simple double-hash table. - * The cache size is a power of two, and two hashes are derived from the - * cache ID. The first is a location in the table, and the second is an - * offset. On any collision, the second hash is added to the first until - * a match or an empty bucket is found. - * The second hash is an odd number, which is necessary and sufficient - * to traverse the entire table. + * glyphname_hash_indices is a sorted (hash, glyph) index of canonical + * "G_xxx" identifiers. populate_glyphname_hash_indices() allocates one + * block of MAX_GLYPH * sizeof(entry) (some entries go unused for the + * scroll/gem appearance gaps), fills it via compose_glyph_name(), and + * sorts ascending by hash. Lookup is bsearch on the hash with + * compose_glyph_name()+strcmpi to disambiguate the rare collision. + * + * The name "hashtable" is historical; this is a sorted array, not an + * open-addressed hash table. The on-disk API in extern.h is kept so + * that callers (wizcmds.c, options.c) don't need to change. + * + * Memory: one alloc, ~75 KB for the 9577 named slots on a typical 5.0 + * build (struct is 8 bytes, no per-name strings). The same data in + * upstream's open-addressed table cost ~256 KB for the buckets plus + * ~290 KB of dupstr'd names plus malloc overhead. */ -staticfn void -init_glyph_cache(void) +staticfn int +cmp_glyphname_entry(const void *a, const void *b) { - size_t glyph; + uint32 ha = ((const struct glyphname_hash_index_entry_t *) a)->hash; + uint32 hb = ((const struct glyphname_hash_index_entry_t *) b)->hash; - /* Cache size of power of 2 not less than 2*MAX_GLYPH */ - glyphid_cache_lsize = 0; - glyphid_cache_size = 1; - while (glyphid_cache_size < 2*MAX_GLYPH) { - ++glyphid_cache_lsize; - glyphid_cache_size <<= 1; - } - - glyphid_cache = (struct glyphid_cache_t *) alloc( - glyphid_cache_size * sizeof (struct glyphid_cache_t)); - for (glyph = 0; glyph < glyphid_cache_size; ++glyph) { - glyphid_cache[glyph].glyphnum = 0; - glyphid_cache[glyph].id = (char *) 0; - } + if (ha < hb) + return -1; + if (ha > hb) + return 1; + return 0; } void -free_glyphid_cache(void) +populate_glyphname_hash_indices(void) { - size_t idx; + int glyph; + size_t n = 0; + char buf[BUFSZ]; - if (!glyphid_cache) + if (glyphname_hash_indices_ptr) return; - for (idx = 0; idx < glyphid_cache_size; ++idx) { - if (glyphid_cache[idx].id) { - free(glyphid_cache[idx].id); - glyphid_cache[idx].id = (char *) 0; + glyphname_hash_indices_ptr = (struct glyphname_hash_index_entry_t *) alloc( + MAX_GLYPH * sizeof (struct glyphname_hash_index_entry_t)); + + for (glyph = 0; glyph < MAX_GLYPH; ++glyph) { + if (compose_glyph_name(glyph, buf, sizeof buf)) { + glyphname_hash_indices_ptr[n].hash = glyph_hash(buf); + glyphname_hash_indices_ptr[n].glyphnum = glyph; + ++n; } } - free(glyphid_cache); - glyphid_cache = (struct glyphid_cache_t *) 0; + qsort(glyphname_hash_indices_ptr, n, + sizeof glyphname_hash_indices_ptr[0], cmp_glyphname_entry); + glyphname_hash_indices_count = n; } -staticfn void -add_glyph_to_cache(int glyphnum, const char *id) +void +empty_glyphname_hash_indices(void) { - uint32 hash = glyph_hash(id); - size_t hash1 = (size_t) (hash & (glyphid_cache_size - 1)); - size_t hash2 = (size_t) - (((hash >> glyphid_cache_lsize) & (glyphid_cache_size - 1)) | 1); - size_t i = hash1; - - do { - if (glyphid_cache[i].id == NULL) { - /* Empty bucket found */ - glyphid_cache[i].id = dupstr(id); - glyphid_cache[i].glyphnum = glyphnum; - return; - } - /* For speed, assume that no ID occurs twice */ - i = (i + hash2) & (glyphid_cache_size - 1); - } while (i != hash1); - /* This should never happen */ - panic("glyphid_cache full"); + if (!glyphname_hash_indices_ptr) + return; + free(glyphname_hash_indices_ptr); + glyphname_hash_indices_ptr = (struct glyphname_hash_index_entry_t *) 0; + glyphname_hash_indices_count = 0; } staticfn int -find_glyph_in_cache(const char *id) +find_glyph_in_hashtable(const char *id) { - uint32 hash = glyph_hash(id); - size_t hash1 = (size_t) (hash & (glyphid_cache_size - 1)); - size_t hash2 = (size_t) - (((hash >> glyphid_cache_lsize) & (glyphid_cache_size - 1)) | 1); - size_t i = hash1; + uint32 want = glyph_hash(id); + size_t lo = 0, hi = glyphname_hash_indices_count, mid; + char buf[BUFSZ]; - do { - if (glyphid_cache[i].id == NULL) { - /* Empty bucket found */ - return -1; - } - if (strcmpi(id, glyphid_cache[i].id) == 0) { - /* Match found */ - return glyphid_cache[i].glyphnum; - } - i = (i + hash2) & (glyphid_cache_size - 1); - } while (i != hash1); - return -1; -} - -staticfn char * -find_glyphid_in_cache_by_glyphnum(int glyphnum) -{ - size_t idx; - - if (!glyphid_cache) - return (char *) 0; - for (idx = 0; idx < glyphid_cache_size; ++idx) { - if (glyphid_cache[idx].glyphnum == glyphnum - && glyphid_cache[idx].id != 0) { - /* Match found */ - return glyphid_cache[idx].id; - } + /* Binary-search the sorted array for the first entry whose hash >= want. */ + while (lo < hi) { + mid = (lo + hi) >> 1; + if (glyphname_hash_indices_ptr[mid].hash < want) + lo = mid + 1; + else + hi = mid; } - return (char *) 0; + /* Walk forward across any equal-hash neighbours, verifying each by + reconstructing the canonical name and strcmpi'ing it back. */ + while (lo < glyphname_hash_indices_count + && glyphname_hash_indices_ptr[lo].hash == want) { + int g = glyphname_hash_indices_ptr[lo].glyphnum; + + if (compose_glyph_name(g, buf, sizeof buf) && !strcmpi(id, buf)) + return g; + ++lo; + } + return -1; } staticfn uint32 @@ -442,16 +617,16 @@ glyph_hash(const char *id) if ('A' <= ch && ch <= 'Z') { ch += 'a' - 'A'; } - hash = (hash << 1) | (hash >> 31); + hash = (hash << 5) | (hash >> 27); hash ^= ch; } return hash; } boolean -glyphid_cache_status(void) +glyphname_hash_indices_loaded(void) { - return (glyphid_cache != 0); + return (glyphname_hash_indices_ptr != 0); } int @@ -471,7 +646,7 @@ glyphrep(const char *op) { int reslt = 0, glyph = NO_GLYPH; - if (!glyphid_cache) + if (!glyphname_hash_indices_ptr) reslt = 1; /* for debugger use only; no cache available */ nhUse(reslt); reslt = glyphrep_to_custom_map_entries(op, &glyph); @@ -536,8 +711,10 @@ apply_customizations( struct customization_detail *details; struct symset_customization *sc; boolean at_least_one = FALSE, - do_colors = ((docustomize & do_custom_colors) != 0), - do_symbols = ((docustomize & do_custom_symbols) != 0); + do_colors = ((docustomize & do_custom_colors) != 0); +#ifdef ENHANCED_SYMBOLS + boolean do_symbols = ((docustomize & do_custom_symbols) != 0); +#endif int custs; for (custs = 0; custs < (int) custom_count; ++custs) { @@ -794,29 +971,25 @@ purge_custom_entries(enum graphics_sets which_set) } void -dump_all_glyphids(FILE *fp) +dump_all_glyphnames(FILE *fp) { - struct find_struct dump_glyphid_find = zero_find; + struct find_struct dump_glyphname_find = zero_find; - dump_glyphid_find.findtype = find_nothing; - dump_glyphid_find.reserved = (genericptr_t) fp; - dump_glyphid_find.restype = res_dump_glyphids; - (void) parse_id((char *) 0, &dump_glyphid_find); + dump_glyphname_find.findtype = find_nothing; + dump_glyphname_find.reserved = (genericptr_t) fp; + dump_glyphname_find.restype = res_dump_glyphnames; + (void) parse_id((char *) 0, &dump_glyphname_find); } void -wizcustom_glyphids(winid win) +wizcustom_glyphnames(winid win) { int glyphnum; - char *id; + char buf[BUFSZ]; - if (!glyphid_cache) - return; for (glyphnum = 0; glyphnum < MAX_GLYPH; ++glyphnum) { - id = find_glyphid_in_cache_by_glyphnum(glyphnum); - if (id) { - wizcustom_callback(win, glyphnum, id); - } + if (compose_glyph_name(glyphnum, buf, sizeof buf)) + wizcustom_callback(win, glyphnum, buf); } } @@ -826,15 +999,14 @@ parse_id( struct find_struct *findwhat) { FILE *fp = (FILE *) 0; - int i = 0, j, mnum, glyph, + int i = 0, glyph, pm_offset = 0, oc_offset = 0, cmap_offset = 0, pm_count = 0, oc_count = 0, cmap_count = 0; - boolean skip_base = FALSE, skip_this_one = FALSE, dump_ids = FALSE, - filling_cache = FALSE, is_S = FALSE, is_G = FALSE; - char buf[4][QBUFSZ]; + boolean dump_ids = FALSE, is_S = FALSE, is_G = FALSE; + char buf[BUFSZ]; if (findwhat->findtype == find_nothing && findwhat->restype) { - if (findwhat->restype == res_dump_glyphids) { + if (findwhat->restype == res_dump_glyphnames) { if (findwhat->reserved) { fp = (FILE *) findwhat->reserved; dump_ids = TRUE; @@ -842,20 +1014,12 @@ parse_id( return 0; } } - if (findwhat->restype == res_fill_cache) { - if (findwhat->reserved - && findwhat->reserved == (genericptr_t) glyphid_cache) { - filling_cache = TRUE; - } else { - return 0; - } - } } is_G = (id && id[0] == 'G' && id[1] == '_'); is_S = (id && id[0] == 'S' && id[1] == '_'); - if ((is_G && !glyphid_cache) || filling_cache || dump_ids || is_S) { + if (dump_ids || is_S) { while (loadsyms[i].range) { if (!pm_offset && loadsyms[i].range == SYM_MON) pm_offset = i; @@ -872,259 +1036,40 @@ parse_id( i++; } } - if (is_G || filling_cache || dump_ids) { - if (!filling_cache && id && glyphid_cache) { - int val = find_glyph_in_cache(id); + if (is_G && id) { + if (glyphname_hash_indices_ptr) { + /* Fast path: bsearch the populated index. */ + int val = find_glyph_in_hashtable(id); + if (val >= 0) { findwhat->findtype = find_glyph; findwhat->val = val; findwhat->loadsyms_offset = 0; return 1; - } else { - return 0; } } else { - const char *buf2, *buf3, *buf4; - - /* individual matching glyph entries */ + /* Unpopulated: linear scan, no alloc. */ for (glyph = 0; glyph < MAX_GLYPH; ++glyph) { - skip_base = FALSE; - skip_this_one = FALSE; - buf[0][0] = buf[1][0] = buf[2][0] = buf[3][0] = '\0'; - if (glyph_is_monster(glyph)) { - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - buf2 = ""; - buf3 = monsdump[glyph_to_mon(glyph)].nm; - - if (glyph_is_normal_male_monster(glyph)) { - buf2 = "male_"; - } else if (glyph_is_normal_female_monster(glyph)) { - buf2 = "female_"; - } else if (glyph_is_ridden_male_monster(glyph)) { - buf2 = "ridden_male_"; - } else if (glyph_is_ridden_female_monster(glyph)) { - buf2 = "ridden_female_"; - } else if (glyph_is_detected_male_monster(glyph)) { - buf2 = "detected_male_"; - } else if (glyph_is_detected_female_monster(glyph)) { - buf2 = "detected_female_"; - } else if (glyph_is_male_pet(glyph)) { - buf2 = "pet_male_"; - } else if (glyph_is_female_pet(glyph)) { - buf2 = "pet_female_"; - } - Strcpy(buf[0], "G_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - } else if (glyph_is_body(glyph)) { - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - buf2 = glyph_is_body_piletop(glyph) - ? "piletop_body_" - : "body_"; - buf3 = monsdump[glyph_to_body_corpsenm(glyph)].nm; - Strcpy(buf[0], "G_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - } else if (glyph_is_statue(glyph)) { - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - buf2 = glyph_is_fem_statue_piletop(glyph) - ? "piletop_statue_of_female_" - : glyph_is_fem_statue(glyph) - ? "statue_of_female_" - : glyph_is_male_statue_piletop(glyph) - ? "piletop_statue_of_male_" - : glyph_is_male_statue(glyph) - ? "statue_of_male_" - : ""; /* shouldn't happen */ - buf3 = monsdump[glyph_to_statue_corpsenm(glyph)].nm; - Strcpy(buf[0], "G_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - } else if (glyph_is_object(glyph)) { - i = glyph_to_obj(glyph); - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - if (((i > SCR_STINKING_CLOUD) && (i < SCR_MAIL)) - || ((i > WAN_LIGHTNING) && (i < GOLD_PIECE))) - skip_this_one = TRUE; - if (!skip_this_one) { - if ((i >= WAN_LIGHT) && (i <= WAN_LIGHTNING)) - buf2 = "wand of "; - else if ((i >= SPE_DIG) && (i < SPE_BLANK_PAPER)) - buf2 = "spellbook of "; - else if ((i >= SCR_ENCHANT_ARMOR) - && (i <= SCR_STINKING_CLOUD)) - buf2 = "scroll of "; - else if ((i >= POT_GAIN_ABILITY) && (i <= POT_WATER)) - buf2 = (i == POT_WATER) ? "flask of n" - : "potion of "; - else if ((i >= RIN_ADORNMENT) - && (i <= RIN_PROTECTION_FROM_SHAPE_CHAN)) - buf2 = "ring of "; - else if (i == LAND_MINE) - buf2 = "unset "; - else - buf2 = ""; - buf3 = (i == SCR_BLANK_PAPER) ? "blank scroll" - : (i == SPE_BLANK_PAPER) ? "blank spellbook" - : (i == SLIME_MOLD) ? "slime mold" - : obj_descr[i].oc_name - ? obj_descr[i].oc_name - : obj_descr[i].oc_descr; - Strcpy(buf[0], "G_"); - if (glyph_is_normal_piletop_obj(glyph)) - Strcat(buf[0], "piletop_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - } - } else if (glyph_is_cmap(glyph) || glyph_is_cmap_zap(glyph) - || glyph_is_swallow(glyph) - || glyph_is_explosion(glyph)) { - int cmap = -1; - - /* buf2 will hold the distinguishing prefix */ - /* buf3 will hold the base name */ - /* buf4 will hold the distinguishing suffix */ - buf2 = ""; - buf3 = ""; - buf4 = ""; - if (glyph == GLYPH_CMAP_OFF) { - cmap = S_stone; - buf3 = "stone substrate"; - skip_base = TRUE; - } else if (glyph_is_cmap_gehennom(glyph)) { - cmap = (glyph - GLYPH_CMAP_GEH_OFF) + S_vwall; - buf4 = "_gehennom"; - } else if (glyph_is_cmap_knox(glyph)) { - cmap = (glyph - GLYPH_CMAP_KNOX_OFF) + S_vwall; - buf4 = "_knox"; - } else if (glyph_is_cmap_main(glyph)) { - cmap = (glyph - GLYPH_CMAP_MAIN_OFF) + S_vwall; - buf4 = "_main"; - } else if (glyph_is_cmap_mines(glyph)) { - cmap = (glyph - GLYPH_CMAP_MINES_OFF) + S_vwall; - buf4 = "_mines"; - } else if (glyph_is_cmap_sokoban(glyph)) { - cmap = (glyph - GLYPH_CMAP_SOKO_OFF) + S_vwall; - buf4 = "_sokoban"; - } else if (glyph_is_cmap_a(glyph)) { - cmap = (glyph - GLYPH_CMAP_A_OFF) + S_ndoor; - } else if (glyph_is_cmap_altar(glyph)) { - static const char *const altar_text[] = { - "unaligned", "chaotic", "neutral", - "lawful", "other", - }; - - j = (glyph - GLYPH_ALTAR_OFF); - cmap = S_altar; - if (j != altar_other) { - Snprintf(buf[2], sizeof buf[2], "%s_", - altar_text[j]); - buf2 = buf[2]; - } else { - buf3 = "altar other"; - skip_base = TRUE; - } - } else if (glyph_is_cmap_b(glyph)) { - cmap = (glyph - GLYPH_CMAP_B_OFF) + S_grave; - } else if (glyph_is_cmap_zap(glyph)) { - static const char *const zap_texts[] = { - "missile", "fire", "frost", "sleep", - "death", "lightning", "poison gas", "acid" - }; - - j = (glyph - GLYPH_ZAP_OFF); - cmap = (j % 4) + S_vbeam; - Snprintf(buf[2], sizeof buf[2], "%s", - loadsyms[cmap + cmap_offset].name + 2); - Snprintf(buf[3], sizeof buf[3], "%s zap %s", - zap_texts[j / 4], fix_glyphname(buf[2])); - buf3 = buf[3]; - buf2 = ""; - skip_base = TRUE; - } else if (glyph_is_cmap_c(glyph)) { - cmap = (glyph - GLYPH_CMAP_C_OFF) + S_digbeam; - } else if (glyph_is_swallow(glyph)) { - static const char *const swallow_texts[] = { - "top left", "top center", "top right", - "middle left", "middle right", "bottom left", - "bottom center", "bottom right", - }; - - j = glyph - GLYPH_SWALLOW_OFF; - cmap = glyph_to_swallow(glyph); - mnum = j / ((S_sw_br - S_sw_tl) + 1); - Strcpy(buf[3], "swallow "); - Strcat(buf[3], monsdump[mnum].nm); - Strcat(buf[3], " "); - Strcat(buf[3], swallow_texts[cmap]); - buf3 = buf[3]; - skip_base = TRUE; - } else if (glyph_is_explosion(glyph)) { - static const char *const expl_type_texts[] = { - "dark", "noxious", "muddy", "wet", - "magical", "fiery", "frosty", - }; - static const char *const expl_texts[] = { - "tl", "tc", "tr", "ml", "mc", - "mr", "bl", "bc", "br", - }; - int expl; - - j = glyph - GLYPH_EXPLODE_OFF; - expl = j / ((S_expl_br - S_expl_tl) + 1); - cmap = glyph_to_explosion(glyph) + S_expl_tl; - i = cmap - S_expl_tl; - Snprintf(buf[2], sizeof buf[2], "%s ", - expl_type_texts[expl]); - buf2 = buf[2]; - Snprintf(buf[3], sizeof buf[3], "%s%s", "expl_", - expl_texts[i]); - buf3 = buf[3]; - skip_base = TRUE; - } - if (!skip_base) { - if (cmap >= 0 && cmap < MAXPCHARS) { - buf3 = loadsyms[cmap + cmap_offset].name + 2; - } - } - Strcpy(buf[0], "G_"); - Strcat(buf[0], buf2); - Strcat(buf[0], buf3); - Strcat(buf[0], buf4); - } else if (glyph_is_invisible(glyph)) { - Strcpy(buf[0], "G_invisible"); - } else if (glyph_is_nothing(glyph)) { - Strcpy(buf[0], "G_nothing"); - } else if (glyph_is_unexplored(glyph)) { - Strcpy(buf[0], "G_unexplored"); - } else if (glyph_is_warning(glyph)) { - j = glyph - GLYPH_WARNING_OFF; - Snprintf(buf[0], sizeof buf[0], "G_%s%d", "warning", j); - } - if (memchr(buf[0], '\0', sizeof buf[0]) == NULL) - panic("parse_id: buf[0] overflowed"); - if (!skip_this_one) { - fix_glyphname(buf[0]+2); - if (dump_ids) { - Fprintf(fp, "(%04d) %s\n", glyph, buf[0]); - } else if (filling_cache) { - add_glyph_to_cache(glyph, buf[0]); - } else if (id) { - if (!strcmpi(id, buf[0])) { - findwhat->findtype = find_glyph; - findwhat->val = glyph; - findwhat->loadsyms_offset = 0; - return 1; - } - } + if (compose_glyph_name(glyph, buf, sizeof buf) + && !strcmpi(id, buf)) { + findwhat->findtype = find_glyph; + findwhat->val = glyph; + findwhat->loadsyms_offset = 0; + return 1; } } - } /* not glyphid_cache */ - } else if (is_S) { + } + return 0; + } + if (dump_ids) { + /* iterate and dump every named glyph */ + for (glyph = 0; glyph < MAX_GLYPH; ++glyph) { + if (compose_glyph_name(glyph, buf, sizeof buf)) + Fprintf(fp, "(%04d) %s\n", glyph, buf); + } + return 1; + } + if (is_S) { /* cmap entries */ for (i = 0; i < cmap_count; ++i) { if (!strcmpi(loadsyms[i + cmap_offset].name + 2, id + 2)) { @@ -1144,7 +1089,7 @@ parse_id( } } /* permonst entries */ - for (i = 0; i <= pm_count; ++i) { + for (i = 0; i < pm_count; ++i) { if (!strcmpi(loadsyms[i + pm_offset].name + 2, id + 2)) { findwhat->findtype = find_pm; findwhat->val = i + 1; /* starts at 1 */ @@ -1153,8 +1098,6 @@ parse_id( } } } - if (dump_ids || filling_cache) - return 1; findwhat->findtype = find_nothing; findwhat->val = 0; findwhat->loadsyms_offset = 0; diff --git a/src/hack.c b/src/hack.c index 367591eff..eaeb8c365 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1763708572 2025/11/20 23:02:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.494 $ */ +/* NetHack 5.0 hack.c $NHDT-Date: 1781973050 2026/06/20 16:30:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.508 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1719,7 +1719,7 @@ notice_mon(struct monst *mtmp) set_msg_xy(mtmp->mx, mtmp->my); You("%s %s.", canseemon(mtmp) ? "see" : "notice", x_monnam(mtmp, - mtmp->mtame ? ARTICLE_YOUR + (mtmp->mtame && !Hallucination) ? ARTICLE_YOUR : (!has_mgivenname(mtmp) && !type_is_pname(mtmp->data)) ? ARTICLE_A : ARTICLE_NONE, @@ -2298,7 +2298,7 @@ domove_fight_empty(coordxy x, coordxy y) } else if (solid) { /* glyph might indicate unseen terrain if hero is blind; unlike searching, this won't reveal what that terrain is; - 3.7: used to say "solid rock" for STONE, but that made it be + 5.0: used to say "solid rock" for STONE, but that made it be different from unmapped walls outside of rooms (and was wrong on arboreal levels) */ if (levl[x][y].seenv || IS_STWALL(levl[x][y].typ) @@ -2310,7 +2310,7 @@ domove_fight_empty(coordxy x, coordxy y) } /* note: 'solid' is misleadingly named and catches pools of water and lava as well as rock and walls; - 3.7: furniture too */ + 5.0: furniture too */ } else { Strcpy(buf, "thin air"); } @@ -4242,60 +4242,6 @@ maybe_wail(void) } } -/* once per game, if receiving a killing blow from above 90% HP, - allow the hero to survive with 1 HP */ -int -saving_grace(int dmg) -{ - if (dmg < 0) { - impossible("saving_grace check for negative damage? (%d)", dmg); - return 0; - } -#if 0 /* saving grace _does_ protect hero during own actions */ - if (!svc.context.mon_moving) { - /* saving grace doesn't protect you from your own actions */ - return dmg; - } -#endif - if (dmg < u.uhp || u.uhp <= 0) { - /* no need for saving grace */ - return dmg; - } - - if (gs.saving_grace_turn) { - /* saving grace already triggered and prevents HP reducing below 1 - this turn (specifically: until the next player action or turn - boundary), don't print further messages or livelog entries */ - return u.uhp - 1; - } - - if (!u.usaving_grace && - (gu.uhp_at_start_of_monster_turn * 100 / u.uhpmax) >= 90) { - /* saving_grace doesn't have it's own livelog classification; - we might invent one, or perhaps use LL_LIFESAVE, but surviving - certain death (or preserving worn amulet of life saving) via - saving-grace feels like breaking a conduct; not sure how best - to phrase this though; classifying it as a spoiler will hide it - from #chronicle during play but show it to livelog observers */ - livelog_printf(LL_CONDUCT | LL_SPOILER, "%s (%d damage, %d/%d HP)", - "survived one-shot death via saving-grace", - /* include damage that happened earlier this turn */ - gu.uhp_at_start_of_monster_turn - u.uhp + dmg, - gu.uhp_at_start_of_monster_turn, u.uhpmax); - - /* note: this could reduce dmg to 0 if u.uhpmax==1 */ - dmg = u.uhp - 1; - u.usaving_grace = 1; /* used up */ - gs.saving_grace_turn = TRUE; - end_running(TRUE); - if (u.usleep) - unmul("Suddenly you wake up!"); - if (is_fainted()) - reset_faint(); - } - return dmg; -} - /* show a message how much damage you received */ void showdamage(int dmg) @@ -4330,7 +4276,6 @@ losehp(int n, const char *knam, schar k_format) return; } - n = saving_grace(n); u.uhp -= n; showdamage(n); if (u.uhp > u.uhpmax) diff --git a/src/hacklib.c b/src/hacklib.c index 25891684e..32e3af3b6 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hacklib.c $NHDT-Date: 1706213796 2024/01/25 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 hacklib.c $NHDT-Date: 1781973051 2026/06/20 16:30:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.133 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* Copyright (c) Robert Patrick Rankin, 1991 */ @@ -974,7 +974,7 @@ static struct datamodel_information dm[] = { "", "" }, { { 2, 4, 4, 8, 4 }, "ILP32LL64", "x86 32-bit" }, /* Windows or Unix */ { { 2, 4, 4, 8, 8 }, "IL32LLP64", "Windows x64 64-bit" }, - { { 2, 4, 8, 8, 8 }, "I32LP64", "Unix 64-bit"}, + { { 2, 4, 8, 8, 8 }, "I32LP64", "Unix 64-bit"}, { { 2, 8, 8, 8, 8 }, "ILP64", "Unix ILP64"}, /* HAL, SPARC64 */ }; diff --git a/src/iactions.c b/src/iactions.c index ca00a2be6..01c956e70 100644 --- a/src/iactions.c +++ b/src/iactions.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 iactions.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.543 $ */ +/* NetHack 5.0 iactions.c $NHDT-Date: 1781973051 2026/06/20 16:30:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2026. */ /* NetHack may be freely redistributed. See license for details. */ @@ -331,9 +331,17 @@ itemactions(struct obj *otmp) ia_addmenu(win, IA_APPLY_OBJ, 'a', "Use this tool to pick a lock"); else if (otmp->otyp == TINNING_KIT) ia_addmenu(win, IA_APPLY_OBJ, 'a', "Use this kit to tin a corpse"); - else if (otmp->otyp == LEASH) - ia_addmenu(win, IA_APPLY_OBJ, 'a', "Tie a pet to this leash"); - else if (otmp->otyp == SADDLE) + else if (otmp->otyp == LEASH) { + if (!otmp->leashmon) { + Strcpy(buf, "Attach this leash to a pet"); + } else { + mtmp = find_mid(otmp->leashmon, FM_FMON); + if (!mtmp) /* assume this won't happen */ + panic("Can't find leash's monster"); + Sprintf(buf, "Detach this leash from %s", some_mon_nam(mtmp)); + } + ia_addmenu(win, IA_APPLY_OBJ, 'a', buf); + } else if (otmp->otyp == SADDLE) ia_addmenu(win, IA_APPLY_OBJ, 'a', "Place this saddle on a pet"); else if (otmp->otyp == MAGIC_WHISTLE || otmp->otyp == TIN_WHISTLE) diff --git a/src/insight.c b/src/insight.c index ab2bcd1a1..f3a1aca4b 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1777004419 2026/04/23 20:20:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ +/* NetHack 5.0 insight.c $NHDT-Date: 1781973051 2026/06/20 16:30:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.139 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1974,21 +1974,6 @@ attributes_enlightenment( } #endif - /* saving-grace: show during final disclosure, hide during normal play */ - if (final || wizard || discover) { - static const char *verbchoices[2][2] = { - { "might avoid", "have avoided" }, - { "could have avoided", "avoided" }, - }; - /* u.usaving_grace will always be 0 or 1; final is 0 (game in - progress), 1 (game over, survived), or 2 (game over, died) */ - const char *verb = verbchoices[!!final][u.usaving_grace]; - - /* 'verb' has already been set for present or past but enl_msg() - needs it twice, one for in progress, the other for game over */ - enl_msg(You_, verb, verb, " a one-shot death via saving-grace", ""); - } - { const char *p; diff --git a/src/invent.c b/src/invent.c index a34517acf..725b78a62 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.543 $ */ +/* NetHack 5.0 invent.c $NHDT-Date: 1781973052 2026/06/20 16:30:52 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.563 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1526,7 +1526,7 @@ static const char *const currencies[] = { "cirbozoid", /* Starslip */ "credit chit", /* Deus Ex */ "cubit", /* Battlestar Galactica */ - "Flanian Pobble Bead", /* The Hitchhiker's Guide to the Galaxy */ + "Flainian Pobble Bead", /* The Hitchhiker's Guide to the Galaxy */ "fretzer", /* Jules Verne */ "imperial credit", /* Star Wars */ "Hong Kong Luna Dollar", /* The Moon is a Harsh Mistress */ @@ -2540,7 +2540,6 @@ askchain( return cnt; } - /* The menu for rerolling attributes and inventory. This is similar to the other inventory menus, but simpler to help it fit on @@ -2557,7 +2556,7 @@ reroll_menu(void) struct obj *otmp; int tmpglyph; glyph_info tmpglyphinfo; - char option; + char option = 'n'; char buf[BUFSZ]; win = create_nhwindow(NHW_MENU); @@ -2569,9 +2568,9 @@ reroll_menu(void) ATR_NONE, NO_COLOR, "start the game with this character", MENU_ITEMFLAGS_NONE); any.a_char = 'y'; + Strcpy(buf, "reroll another character"); add_menu(win, &nul_glyphinfo, &any, flags.lootabc ? 0 : 'r', 0, - ATR_NONE, NO_COLOR, "reroll another character", - MENU_ITEMFLAGS_NONE); + ATR_NONE, NO_COLOR, buf, MENU_ITEMFLAGS_NONE); any.a_char = 0; add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, "", MENU_ITEMFLAGS_NONE); @@ -2608,11 +2607,7 @@ reroll_menu(void) } destroy_nhwindow(win); - if (option == 'y') { - ++u.uroleplay.numrerolls; - return TRUE; - } - return FALSE; + return option == 'y'; } /* @@ -2706,6 +2701,52 @@ count_unidentified(struct obj *objchn) return unid_cnt; } +/* mark the puzzling items */ +int +check_for_puzzling_nonmerge(struct obj *objchn) +{ + int i, k, idx, puzzling_cnt = 0, ilet, mnums[invlet_basic + 1], + gndr[invlet_basic + 1]; + struct obj *obj; + boolean at_least_one = FALSE; + + gp.puzzling_criteria = 0; + for (i = 0; i < invlet_basic + 1; ++i) + gp.puzzling_ilets[i] = mnums[i] = gndr[i] = 0; + + + for (obj = objchn; obj; obj = obj->nobj) { + if (obj->otyp == CORPSE + && obj->corpsenm >= 0 && obj->corpsenm < NUMMONS) { + ilet = obj->invlet; + idx = (ilet >= 'A' && ilet <= 'Z') ? ilet - 'A' + : (ilet >= 'a' && ilet <= 'z') ? ilet - 'a' + 26 + : 53; + if (idx < 53) { + mnums[idx] = obj->corpsenm; + gndr[idx] = (obj->spe & CORPSTAT_MALE) ? CORPSTAT_MALE + : CORPSTAT_FEMALE; + at_least_one = TRUE; + } + } + } + if (at_least_one) { + for (i = 0; i < invlet_basic; ++i) { + for (k = i + 1; k < invlet_basic; ++k) { + if (k == i) + continue; + if (mnums[k] == mnums[i] && gndr[k] != gndr[i]) { + ++puzzling_cnt; + gp.puzzling_ilets[i] = gp.puzzling_ilets[k] = 1; + } + } + } + if (puzzling_cnt) + gp.puzzling_criteria = 411; + } + return puzzling_cnt; +} + /* dialog with user to identify a given number of items; 0 means all */ void identify_pack( @@ -3069,7 +3110,7 @@ display_pickinv( struct obj *otmp, wizid_fakeobj, inuse_fakeobj; char ilet, ret, *formattedobj; const char *invlet = flags.inv_order; - int n, classcount, inusecount = 0; + int n, classcount, inusecount = 0, puzzling_count = 0; winid win; /* windows being used */ anything any; menu_item *selected; @@ -3217,6 +3258,9 @@ display_pickinv( sortedinvent[0].obj = (struct obj *) 0; } + + puzzling_count = check_for_puzzling_nonmerge(gi.invent); + start_menu(win, menu_behavior); any = cg.zeroany; if (wizid) { @@ -3319,7 +3363,9 @@ display_pickinv( /* normal inventory item */ tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); - formattedobj = doname(otmp); + formattedobj = !puzzling_count + ? doname(otmp) + : doname_with_cgender(otmp); add_menu(win, &tmpglyphinfo, &any, ilet, wizid ? def_oc_syms[(int) otmp->oclass].sym : 0, ATR_NONE, clr, formattedobj, MENU_ITEMFLAGS_NONE); @@ -4115,6 +4161,7 @@ look_here( picked_some = (lookhere_flags & LOOKHERE_PICKED_SOME) != 0, /* skip 'dfeature' if caller used describe_decor() to show it */ skip_dfeature = (lookhere_flags & LOOKHERE_SKIP_DFEATURE) != 0; + int puzzling_count = 0; /* default pile_limit is 5; a value of 0 means "never skip" (and 1 effectively forces "always skip") */ @@ -4178,6 +4225,7 @@ look_here( } otmp = svl.level.objects[u.ux][u.uy]; + puzzling_count = check_for_puzzling_nonmerge(otmp); dfeature = dfeature_at(u.ux, u.uy, fbuf2); if (dfeature && !strcmp(dfeature, "pool of water") && Underwater) dfeature = 0; @@ -4299,11 +4347,15 @@ look_here( for (; otmp; otmp = otmp->nexthere) { if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) { felt_cockatrice = TRUE; - Sprintf(buf, "%s...", doname(otmp)); + Sprintf(buf, "%s...", + (puzzling_count) ? doname_with_cgender(otmp) + : doname(otmp)); putstr(tmpwin, 0, buf); break; } - putstr(tmpwin, 0, doname_with_price(otmp)); + putstr(tmpwin, 0, + (puzzling_count) ? doname_with_price_and_cgender(otmp) + : doname_with_price(otmp)); } display_nhwindow(tmpwin, TRUE); destroy_nhwindow(tmpwin); diff --git a/src/light.c b/src/light.c index 93f7ea50a..02fa686ac 100644 --- a/src/light.c +++ b/src/light.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 light.c $NHDT-Date: 1773375430 2026/03/12 20:17:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */ +/* NetHack 5.0 light.c $NHDT-Date: 1781973052 2026/06/20 16:30:52 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.88 $ */ /* Copyright (c) Dean Luick, 1994 */ /* NetHack may be freely redistributed. See license for details. */ @@ -303,7 +303,7 @@ show_transient_light(struct obj *obj, coordxy x, coordxy y) radius_squared = ls->range * ls->range; for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon) || (mon->isgd && !mon->mx)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; /* light range is the radius of a circle and we're limiting canseemon() to a square enclosing that circle, but setting @@ -343,7 +343,7 @@ transient_light_cleanup(void) so need to be replaced by "remembered, unseen monster" glyph */ mtempcount = 0; for (mon = fmon; mon; mon = mon->nmon) { - if (DEADMONSTER(mon)) + if (DEADMONSTER(mon) || PARKEDMONSTER(mon)) continue; if (mon->mtemplit) { mon->mtemplit = 0; @@ -522,7 +522,7 @@ relink_light_sources(boolean ghostly) /* * Caveat: - * There has been at least one instance during to-be-3.7 development + * There has been at least one instance during to-be-5.0 development * where the light_base linked list ended up with a circular link. * If that happens, then once all the traversed elements have their * LSF_NEEDS_FIXUP flag cleared, the traversal attempt will run wild. diff --git a/src/lock.c b/src/lock.c index 2e8851754..89378d088 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 lock.c $NHDT-Date: 1741793439 2025/03/12 07:30:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ */ +/* NetHack 5.0 lock.c $NHDT-Date: 1781973052 2026/06/20 16:30:52 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.150 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mail.c b/src/mail.c index 96735abe5..91706b80a 100644 --- a/src/mail.c +++ b/src/mail.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mail.c $NHDT-Date: 1762750699 2025/11/09 20:58:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ +/* NetHack 5.0 mail.c $NHDT-Date: 1781973052 2026/06/20 16:30:52 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.80 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/makemon.c b/src/makemon.c index 6f158ee01..d0c540e92 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 makemon.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ */ +/* NetHack 5.0 makemon.c $NHDT-Date: 1781973053 2026/06/20 16:30:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.277 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -17,7 +17,6 @@ staticfn int align_shift(struct permonst *); staticfn int temperature_shift(struct permonst *); staticfn boolean mk_gen_ok(int, unsigned, unsigned); staticfn int QSORTCALLBACK cmp_init_mongen_order(const void *, const void *); -staticfn void check_mongen_order(void); staticfn void init_mongen_order(void); staticfn boolean wrong_elem_type(struct permonst *); staticfn void m_initgrp(struct monst *, coordxy, coordxy, int, mmflags_nht); @@ -738,7 +737,7 @@ m_initinv(struct monst *mtmp) break; case S_GIANT: if (ptr == &mons[PM_MINOTAUR]) { - if (!rn2(3) || (gi.in_mklev && Is_earthlevel(&u.uz))) + if (!rn2(8) || (gi.in_mklev && Is_earthlevel(&u.uz))) (void) mongets(mtmp, WAN_DIGGING); } else if (is_giant(ptr)) { for (cnt = rn2((int) (mtmp->m_lev / 2)); cnt; cnt--) { @@ -1682,7 +1681,7 @@ rndmonst_adj(int minadj, int maxadj) if (montooweak(mndx, minmlev) || montoostrong(mndx, maxmlev)) continue; - if (upper && !isupper(monsym(ptr))) + if (upper && !isupper((int) monsym(ptr))) continue; if (elemlevel && wrong_elem_type(ptr)) continue; @@ -1777,6 +1776,8 @@ cmp_init_mongen_order(const void *p1, const void *p2) return difficulty1 - difficulty2; } +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) +staticfn void check_mongen_order(void); /* check that monsters are in correct difficulty order for mkclass() */ staticfn void check_mongen_order(void) @@ -1799,6 +1800,7 @@ check_mongen_order(void) } } } +#endif /* initialize monster order for mkclass */ staticfn void diff --git a/src/mcastu.c b/src/mcastu.c index 34d839906..a7873c656 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mcastu.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ */ +/* NetHack 5.0 mcastu.c $NHDT-Date: 1781973053 2026/06/20 16:30:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.122 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mdlib.c b/src/mdlib.c index fb4155dab..2668b856c 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mdlib.c $NHDT-Date: 1701499945 2023/12/02 06:52:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 mdlib.c $NHDT-Date: 1781973053 2026/06/20 16:30:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ @@ -93,7 +93,7 @@ staticfn void opt_out_words(char *, int *) NONNULLPTRS; staticfn void build_savebones_compat_string(void); static int idxopttext, done_runtime_opt_init_once = 0; -#define MAXOPT 60 /* 3.7: currently 40 lines get inserted into opttext[] */ +#define MAXOPT 60 /* 5.0: currently 40 lines get inserted into opttext[] */ static char *opttext[MAXOPT] = { 0 }; #define STOREOPTTEXT(line) \ ((void) ((idxopttext < MAXOPT) \ @@ -142,17 +142,18 @@ static struct win_information window_opts[] = { #ifdef SHIM_GRAPHICS { "shim", "NetHack Library Windowing Shim", TRUE }, #endif +#ifdef AMIGA_INTUITION + { "amii", "Amiga Intuition (text)", TRUE }, + { "amiv", "Amiga Intuition (tiles)", TRUE }, +#endif #if 0 /* remainder have been retired */ #ifdef GNOME_GRAPHICS /* unmaintained/defunct */ { "Gnome", "Gnome", TRUE }, #endif -#ifdef MAC /* defunct OS 9 interface */ +#ifdef MAC68K /* defunct OS 9 interface */ { "mac", "Mac", TRUE }, #endif -#ifdef AMIGA_INTUITION /* unmaintained/defunct */ - { "amii", "Amiga Intuition", TRUE }, -#endif #ifdef GEM_GRAPHICS /* defunct Atari interface */ { "Gem", "Gem", TRUE }, #endif @@ -355,14 +356,16 @@ bannerc_string(char *outbuf, size_t bufsz, const char *build_date) subbuf[0] = ' '; Strcpy(&subbuf[1], PORT_SUB_ID); #endif + #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) #if (NH_DEVEL_STATUS == NH_STATUS_BETA) - Strcat(subbuf, " Beta"); -#else - Strcat(subbuf, " Work-in-progress"); + Strcpy(subbuf, " Beta"); +#elif (NH_DEVEL_STATUS == NH_STATUS_WIP) + Strcpy(subbuf, " Work-in-progress"); +#elif (NH_DEVEL_STATUS == NH_STATUS_POSTRELEASE) + Strcpy(subbuf, " post-release"); #endif -#endif - +#endif /* !NH_STATUS_RELEASED */ Snprintf(outbuf, bufsz, " Version %s %s%s, %s %s.", mdlib_version_string(versbuf, "."), PORT_ID, subbuf, date_via_env ? "revised" : "built", build_date); @@ -533,7 +536,7 @@ static const char *const build_opts[] = { "screen clipping", #endif #ifdef NO_TERMS -#ifdef MAC +#ifdef MAC68K "screen control via mactty", #endif #ifdef SCREEN_BIOS @@ -573,6 +576,9 @@ static const char *const build_opts[] = { #ifdef USE_XPM "tiles file in XPM format", #endif +#ifdef USE_XFT + "font rendering with Xft", +#endif #ifdef GRAPHIC_TOMBSTONE "graphical RIP screen", #endif @@ -582,9 +588,6 @@ static const char *const build_opts[] = { #ifdef PREFIXES_IN_USE "variable playground", #endif -#ifdef VISION_TABLES - "vision tables", -#endif #ifdef SYSCF "system configuration at run-time", #endif @@ -798,7 +801,7 @@ build_options(void) #if defined(MAKEDEFS_C) || defined(FOR_RUNTIME) { static const char *const lua_info[] = { - "", "NetHack 3.7.* uses the 'Lua' interpreter to process some data:", "", + "", "NetHack 5.0.* uses the 'Lua' interpreter to process some data:", "", " :LUACOPYRIGHT:", "", /* 1 2 3 4 5 6 7 1234567890123456789012345678901234567890123456789012345678901234567890123456 diff --git a/src/mhitm.c b/src/mhitm.c index 5e8bb928e..4e7f0f078 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitm.c $NHDT-Date: 1732979463 2024/11/30 07:11:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ */ +/* NetHack 5.0 mhitm.c $NHDT-Date: 1781973054 2026/06/20 16:30:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.269 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -919,7 +919,7 @@ gulpmm( * -> relmon() used to call remove_monster() for the dead * monster even when it wasn't the one on the map, so we * needed to put magr back after mdef was killed and removed - * from their shared spot. But now [3.7] relmon() calls + * from their shared spot. But now [5.0] relmon() calls * mon_leaving_level() and that checks whether the monster at * dying monster's coordinates is that dying monster and only * removes it when they match. So magr is still at mdef's diff --git a/src/mhitu.c b/src/mhitu.c index 71d90a8ec..fe5fcc65c 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitu.c $NHDT-Date: 1775259433 2026/04/03 15:37:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ +/* NetHack 5.0 mhitu.c $NHDT-Date: 1781973054 2026/06/20 16:30:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.347 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1312,7 +1312,7 @@ gulpmu(struct monst *mtmp, struct attack *mattk) place_monster(mtmp, u.ux, u.uy); set_ustuck(mtmp); newsym(mtmp->mx, mtmp->my); - /* 3.7: dismount for all engulfers, not just for purple worms */ + /* 5.0: dismount for all engulfers, not just for purple worms */ if (u.usteed) { char buf[BUFSZ]; @@ -1916,7 +1916,6 @@ mdamageu(struct monst *mtmp, int n) if (u.mh < 1) rehumanize(); } else { - n = saving_grace(n); u.uhp -= n; showdamage(n); /* caller might have reduced uhpmax before calling mdamageu() */ diff --git a/src/minion.c b/src/minion.c index 96f9ffe1c..0a588989f 100644 --- a/src/minion.c +++ b/src/minion.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 minion.c $NHDT-Date: 1762727599 2025/11/09 14:33:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.81 $ */ +/* NetHack 5.0 minion.c $NHDT-Date: 1781973054 2026/06/20 16:30:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.88 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -43,9 +43,7 @@ monster_census(boolean spotted) /* seen|sensed vs all */ int count = 0; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (DEADMONSTER(mtmp)) - continue; - if (mtmp->isgd && mtmp->mx == 0) + if (DEADMONSTER(mtmp) || PARKEDMONSTER(mtmp)) continue; if (spotted && !canspotmon(mtmp)) continue; @@ -301,7 +299,8 @@ demon_talk(struct monst *mtmp) pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp), flags.female ? "Sister" : "Brother"); else if (canseemon(mtmp)) - pline("%s says something.", Amonnam(mtmp)); + pline("%s %s something.", Amonnam(mtmp), + says()); if (!tele_restrict(mtmp)) (void) rloc(mtmp, RLOC_MSG); return 1; diff --git a/src/mklev.c b/src/mklev.c index 2ddeefae9..210dd90ce 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mklev.c $NHDT-Date: 1737387068 2025/01/20 07:31:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.194 $ */ +/* NetHack 5.0 mklev.c $NHDT-Date: 1781973055 2026/06/20 16:30:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.207 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Alex Smith, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1261,6 +1261,9 @@ makelevel(void) impossible("makelevel() called when dungeon not yet initialized."); init_dungeons(); } + level_status_init(); + level_status.making = 1; + oinit(); /* assign level dependent obj probabilities */ clear_level_structures(); @@ -1416,7 +1419,7 @@ makelevel(void) for (i = 0; i < svn.nroom; ++i) { fill_special_room(&svr.rooms[i]); } - + level_status.shkready = 1; themerooms_post_level_generate(); if (gl.luacore && nhcb_counts[NHCB_LVL_ENTER]) { @@ -1425,6 +1428,7 @@ makelevel(void) nhl_pcall_handle(gl.luacore, 1, 0, "makelevel", NHLpa_panic); lua_settop(gl.luacore, 0); } + level_status.making = 0, level_status.ready = 1; } /* return TRUE if water location at (x,y) should have kelp. */ @@ -1930,7 +1934,7 @@ mktrap_victim(struct trap *ttmp) if (victim_mnum == PM_HUMAN && rn2(25)) victim_mnum = rn1(PM_WIZARD - PM_ARCHEOLOGIST, PM_ARCHEOLOGIST); otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], x, y, CORPSTAT_INIT); - otmp->age -= (TAINT_AGE + 1); /* died too long ago to safely eat */ + otmp->age -= (INEDIBLE_AGE + 1); /* died too long ago to safely eat */ } /* pick a random trap type, return NO_TRAP if "too hard" */ diff --git a/src/mkmap.c b/src/mkmap.c index fdf50649c..a84304ad1 100644 --- a/src/mkmap.c +++ b/src/mkmap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkmap.c $NHDT-Date: 1717432093 2024/06/03 16:28:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mkmap.c $NHDT-Date: 1781973055 2026/06/20 16:30:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) J. C. Collet, M. Stephenson and D. Cohrs, 1992 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkmaze.c b/src/mkmaze.c index 573eada04..5f612aa24 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkmaze.c $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.179 $ */ +/* NetHack 5.0 mkmaze.c $NHDT-Date: 1781973055 2026/06/20 16:30:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.185 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mkobj.c b/src/mkobj.c index eb55a0802..2ed92d009 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkobj.c $NHDT-Date: 1764044196 2025/11/24 20:16:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ +/* NetHack 5.0 mkobj.c $NHDT-Date: 1781973055 2026/06/20 16:30:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.335 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -957,7 +957,7 @@ mksobj_init(struct obj **obj, boolean artif) /* for emphasis; glob quantity is always 1 and weight varies when other globs coalesce with it or this one shrinks */ otmp->quan = 1L; - /* 3.7: globs in 3.6.x left owt as 0 and let weight() fix + /* 5.0: globs in 3.6.x left owt as 0 and let weight() fix that up during 'obj->owt = weight(obj)' below, but now we initialize glob->owt explicitly so weight() doesn't need to perform any fix up and returns glob->owt as-is */ @@ -1510,7 +1510,7 @@ shrink_glob( shrink = FALSE, gone = FALSE, updinv = FALSE; struct obj *contnr = (obj->where == OBJ_CONTAINED) ? obj->ocontainer : 0, *topcontnr = 0; - unsigned old_top_owt = 0; + unsigned old_top_owt = 0, old_owt = obj->owt; if (!obj->globby) { impossible("shrink_glob for non-glob [%d: %s]?", @@ -1539,12 +1539,25 @@ shrink_glob( obj->owt = 0; /* not required; accurately reflects obj's state */ shrinking_glob_gone(obj); } else { - /* shrank but not gone; reduce remaining weight */ + + /* shrank but not gone; reduce remaining weight + and food-content (if needed) */ obj->owt -= (unsigned) delta; /* when contained, update container's weight (recursively if nested); won't be in a container carried by hero (since catching up for lost time never applies in that situation) but might be in one on floor or one carried by a monster */ + if (old_owt && obj->oeaten) { + unsigned percent_reduction = 100 - ((obj->owt * 100) / old_owt), + oeaten_reduction; + + /* reduce remaining nutrition by same percentage */ + oeaten_reduction = (percent_reduction * obj->oeaten + 50) / 100; + + if (oeaten_reduction <= obj->oeaten) + obj->oeaten -= oeaten_reduction; + + } if (contnr) container_weight(contnr); /* resume regular shrinking */ @@ -1674,6 +1687,8 @@ shrinking_glob_gone(struct obj *obj) { xint16 owhere = obj->where; + /* obfree() should take care of eating_glob() food fixups */ + if (owhere == OBJ_INVENT) { if (obj->owornmask) { remove_worn_item(obj, FALSE); @@ -1899,7 +1914,7 @@ weight(struct obj *obj) manage glob->owt and there is nothing for weight() to do except return the current value as-is */ if (obj->globby) { - /* 3.7: in 3.6.x this checked for owt==0 and then used + /* 5.0: in 3.6.x this checked for owt==0 and then used owt as-is when non-zero or objects[].oc_weight if zero; we don't do that anymore because it confused calculating the weight of a container when a glob inside shrank down @@ -1964,7 +1979,7 @@ weight(struct obj *obj) } else if (obj->oclass == FOOD_CLASS && obj->oeaten) { return eaten_stat((int) obj->quan * wt, obj); } else if (obj->oclass == COIN_CLASS) { - /* 3.7: always weigh at least 1 unit; used to yield 0 for 1..49 */ + /* 5.0: always weigh at least 1 unit; used to yield 0 for 1..49 */ wt = (int) ((obj->quan + 50L) / 100L); return max(wt, 1); } else if (obj->otyp == HEAVY_IRON_BALL && obj->owt != 0) { @@ -2354,7 +2369,7 @@ place_object(struct obj *otmp, coordxy x, coordxy y) otmp->where = OBJ_FLOOR; /* if placed outside of shop, no_charge is no longer applicable */ - if (otmp->no_charge && !costly_spot(x, y) + if (level_status.shkready && otmp->no_charge && !costly_spot(x, y) && !costly_adjacent(find_objowner(otmp, x, y), x, y)) otmp->no_charge = 0; diff --git a/src/mkroom.c b/src/mkroom.c index c859b1c0e..a1def04cc 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkroom.c $NHDT-Date: 1613086701 2021/02/11 23:38:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ */ +/* NetHack 5.0 mkroom.c $NHDT-Date: 1781973056 2026/06/20 16:30:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.81 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -573,6 +573,8 @@ mkswamp(void) /* Michiel Huisjes & Fred de Wilde */ } } +/* return center of room, or a random free location + if center is blocked */ staticfn coord * shrine_pos(int roomno) { @@ -591,6 +593,14 @@ shrine_pos(int roomno) buf.y = troom->ly + delta / 2; if ((delta % 2) && rn2(2)) buf.y++; + + /* irregular room or the location is blocked */ + if (roomno != (int) levl[buf.x][buf.y].roomno + || (levl[buf.x][buf.y].typ != ROOM + && levl[buf.x][buf.y].typ != ICE + && levl[buf.x][buf.y].typ != CLOUD)) + (void) somexyspace(troom, &buf); + return &buf; } diff --git a/src/mon.c b/src/mon.c index 789ca8276..71d773f2e 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.621 $ */ +/* NetHack 5.0 mon.c $NHDT-Date: 1781062909 2026/06/09 19:41:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.634 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1230,20 +1230,25 @@ movemon_singlemon(struct monst *mtmp) off the map too; gd_move() decides whether the temporary corridor can be removed and guard discarded (via clearing mon->isgd flag so that dmonsfree() will get rid of mon) */ - if (mtmp->isgd && !mtmp->mx && !(mtmp->mstate & MON_MIGRATING)) { + if (PARKEDMONSTER(mtmp) && !(mtmp->mstate & MON_MIGRATING)) { /* parked at <0,0>; eventually isgd should get set to false */ if (svm.moves > mtmp->mlstmv) { (void) gd_move(mtmp); mtmp->mlstmv = svm.moves; } + mtmp->movement = 0; return FALSE; } - if (DEADMONSTER(mtmp)) + if (DEADMONSTER(mtmp)) { + mtmp->movement = 0; return FALSE; + } /* monster isn't on this map anymore */ - if (mon_offmap(mtmp)) + if (mon_offmap(mtmp)) { + mtmp->movement = 0; return FALSE; + } m_everyturn_effect(mtmp); @@ -2785,9 +2790,9 @@ m_detach( shkgone(mtmp); if (mtmp->wormno) wormgone(mtmp); + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; if (In_endgame(&u.uz)) mtmp->mstate |= MON_ENDGAME_FREE; - if ((mtmp->mstate & MON_DETACH) != 0) { impossible("m_detach: %s is already detached?", minimal_monnam(mtmp, FALSE)); @@ -3428,6 +3433,8 @@ set_ustuck(struct monst *mtmp) disp.botl = TRUE; u.ustuck = mtmp; + if (u.ustuck_mid) + u.ustuck_mid = 0; if (!u.ustuck) { u.uswallow = 0; u.uswldtim = 0; @@ -3929,6 +3936,7 @@ elemental_clog(struct monst *mon) if (mtmp) { int mx = mtmp->mx, my = mtmp->my; + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; mtmp->mstate |= MON_OBLITERATE; mongone(mtmp); /* places in the code might still reference mtmp->mx, mtmp->my */ @@ -4048,6 +4056,7 @@ mnearto( but for the moment it is leaving */ mon_leaving_level(othermon); othermon->mx = othermon->my = 0; /* 'othermon' is not on the map */ + othermon->mstate &= ~TERRAIN_FALLOUT_MASK; othermon->mstate |= MON_OFFMAP; } @@ -4863,7 +4872,7 @@ pick_animal(void) /* rogue level should use monsters represented by uppercase letters only, but since chameleons aren't generated there (not uppercase!) we don't perform a lot of retries */ - if (Is_rogue_level(&u.uz) && !isupper(monsym(&mons[res]))) + if (Is_rogue_level(&u.uz) && !isupper((int) monsym(&mons[res]))) res = ga.animal_list[rn2(ga.animal_list_count)]; return res; } @@ -5219,7 +5228,7 @@ select_newcham_form(struct monst *mon) } while (--tryct > 0 && !validspecmon(mon, mndx) /* try harder to select uppercase monster on rogue level */ && (tryct > 40 && Is_rogue_level(&u.uz) - && !isupper(monsym(&mons[mndx])))); + && !isupper((int) monsym(&mons[mndx])))); } return mndx; } @@ -5329,7 +5338,7 @@ newcham( /* for the first several tries we require upper-case on the rogue level (after that, we take whatever we get) */ if (tryct > 15 && Is_rogue_level(&u.uz) - && mdat && !isupper(monsym(mdat))) + && mdat && !isupper((int) monsym(mdat))) mdat = 0; if (mdat) break; @@ -5486,6 +5495,7 @@ newcham( if (!(mtmp->misc_worn_check & W_ARMG)) mselftouch(mtmp, "No longer petrify-resistant, ", !svc.context.mon_moving); + (void) maybe_set_terrain_effects(mtmp, olddata); check_gear_next_turn(mtmp); /* This ought to re-test can_carry() on each item in the inventory @@ -5534,6 +5544,69 @@ newcham( return 1; } +boolean +maybe_set_terrain_effects(struct monst *mtmp, struct permonst *oldmdat) +{ + struct permonst *mdat = mtmp->data; + boolean changed = FALSE; + + /* mtmp is in liquid */ + if (is_pool(mtmp->mx, mtmp->my) || Is_waterlevel(&u.uz) + || is_lava(mtmp->mx, mtmp->my) + || IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ)) { + /* mtmp is a non-flyer/floater/levitator */ + boolean above_water = + ((is_flyer(mdat) || is_floater(mdat)) + && !(mtmp == u.usteed && (Flying || Levitation))), + was_above_water = + (oldmdat + && ((is_flyer(oldmdat) || is_floater(oldmdat)) + && !(mtmp == u.usteed && (Flying || Levitation)))); + if (!above_water) { + changed = (!oldmdat || (above_water != was_above_water)); + gp.pending_terrain_effects |= nonflyer_vs_liquid; + mtmp->mstate |= (long) nonflyer_vs_liquid; + } + + /* swimmer/amphibious/breathless to something that is not */ + if (!cant_drown(mdat)) { + if (!changed) + changed = + (!oldmdat || ((cant_drown(oldmdat) != cant_drown(mdat)))); + gp.pending_terrain_effects |= candrown_vs_liquid; + mtmp->mstate |= (long) candrown_vs_liquid; + } + } + /* TODO: handle other terrains that could be harmful to a + revived mon or polymorphed mon */ + + return changed; +} + +/* + * The terrain is what it is, but the monster changed + * in some way (polymorphed or newly revived), and has + * been flagged as problematic with the terrain. + */ +void +terrain_effects(void) +{ + struct monst *mtmp, *mtmp2; + + for (mtmp = fmon; mtmp; mtmp = mtmp2) { + mtmp2 = mtmp->nmon; + if ((mtmp->mstate & TERRAIN_FALLOUT_MASK) != 0) { + /* nonflyer_vs_liquid */ + if (!DEADMONSTER(mtmp) + && ((mtmp->mstate & (long) (nonflyer_vs_liquid | candrown_vs_liquid)) != 0)) + (void) minliquid(mtmp); + + /* always clear these bits, even if DEADMONSTER */ + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; + } + } +} + /* sometimes an egg will be special */ #define BREEDER_EGG (!rn2(77)) @@ -5960,8 +6033,9 @@ adj_erinys(unsigned abuse) pm->mattk[2].damd = 4; } - /* also adjust level and difficulty */ - pm->mlevel = min(7 + u.ualign.abuse, 50); + /* also adjust level and difficulty; + mlevel >= 50 has a special meaning, so don't exceed 49 */ + pm->mlevel = min(7 + u.ualign.abuse, 49); pm->difficulty = min(10 + (u.ualign.abuse / 3), 25); } diff --git a/src/mondata.c b/src/mondata.c index d7ea80245..e9d25095c 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mondata.c $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ +/* NetHack 5.0 mondata.c $NHDT-Date: 1781973056 2026/06/20 16:30:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.148 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/monmove.c b/src/monmove.c index 6489d19d4..7752b340a 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 monmove.c $NHDT-Date: 1737392015 2025/01/20 08:53:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */ +/* NetHack 5.0 monmove.c $NHDT-Date: 1781973056 2026/06/20 16:30:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.284 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -922,7 +922,7 @@ dochug(struct monst *mtmp) /*FALLTHRU*/ case MMOVE_NOTHING: /* no movement, but it can still attack you */ case MMOVE_DONE: /* absolutely no movement */ - /* vault guard might have vanished */ + /* vault guard might have vanished; PARKEDMONSTER(mtmp) */ if (mtmp->isgd && (DEADMONSTER(mtmp) || mtmp->mx == 0)) return 1; /* behave as if it died */ /* During hallucination, monster appearance should @@ -1511,6 +1511,8 @@ postmov( if (mtmp->mx) newsym(mtmp->mx, mtmp->my); return MMOVE_DIED; /* it died */ + } else if (mon_offmap(mtmp)) { + return MMOVE_DONE; } ptr = mtmp->data; /* in case mintrap() caused polymorph */ @@ -1651,7 +1653,9 @@ postmov( u_on_newpos(mtmp->mx, mtmp->my); swallowed(0); } else { - newsym(mtmp->mx, mtmp->my); + /* only call newsym() when not a vault guard moving to <0,0> */ + if (mtmp->mx) + newsym(mtmp->mx, mtmp->my); } } /* mmoved==MMOVE_MOVED */ @@ -1784,13 +1788,13 @@ m_move(struct monst *mtmp, int after) * attack it. */ if (intruder && intruder != mtmp - /* 3.7: this used to use 'dist2() < 2' which meant that intended + /* 5.0: this used to use 'dist2() < 2' which meant that intended attack was disallowed if they were adjacent diagonally */ && dist2(mtmp->mx, mtmp->my, tx, ty) <= 2) { gb.bhitpos.x = tx, gb.bhitpos.y = ty; gn.notonhead = (intruder->mx != tx || intruder->my != ty); covetousattack = mattackm(mtmp, intruder); - /* 3.7: this used to erroneously use '== 2' (M_ATTK_DEF_DIED) */ + /* 5.0: this used to erroneously use '== 2' (M_ATTK_DEF_DIED) */ if (covetousattack & M_ATTK_AGR_DIED) return MMOVE_DIED; mmoved = MMOVE_MOVED; diff --git a/src/monst.c b/src/monst.c index b5864ecdb..2a0e1fb11 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 monst.c $NHDT-Date: 1705092160 2024/01/12 20:42:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ +/* NetHack 5.0 monst.c $NHDT-Date: 1781973056 2026/06/20 16:30:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mplayer.c b/src/mplayer.c index 041a997ec..480f59619 100644 --- a/src/mplayer.c +++ b/src/mplayer.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mplayer.c $NHDT-Date: 1596498188 2020/08/03 23:43:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 mplayer.c $NHDT-Date: 1781973057 2026/06/20 16:30:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.54 $ */ /* Copyright (c) Izchak Miller, 1992. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mthrowu.c b/src/mthrowu.c index 6f8ed721c..d54989c88 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mthrowu.c $NHDT-Date: 1737392015 2025/01/20 08:53:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */ +/* NetHack 5.0 mthrowu.c $NHDT-Date: 1781973057 2026/06/20 16:30:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -535,7 +535,7 @@ u_catch_thrown_obj(struct obj *otmp) int catch_chance = 100 - ACURR(A_DEX) - ((Role_if(PM_MONK) || Role_if(PM_ROGUE)) ? 20 : 0); - if (!Blind && !Confusion && !Stunned && !Fumbling + if (!Blind && !Confusion && !Stunned && !Fumbling && !Unaware && otmp->oclass != VENOM_CLASS && !nohands(gy.youmonst.data) && freehand() && calc_capacity(otmp->owt) <= SLT_ENCUMBER && !rn2(catch_chance)) { diff --git a/src/muse.c b/src/muse.c index 78b61c10b..0e4770d4e 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 muse.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.241 $ */ +/* NetHack 5.0 muse.c $NHDT-Date: 1781973057 2026/06/20 16:30:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.248 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/music.c b/src/music.c index 21614860d..b2e71e790 100644 --- a/src/music.c +++ b/src/music.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 music.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ +/* NetHack 5.0 music.c $NHDT-Date: 1781973058 2026/06/20 16:30:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.126 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlobj.c b/src/nhlobj.c index a0535074c..36ea624e5 100644 --- a/src/nhlobj.c +++ b/src/nhlobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhlobj.c $NHDT-Date: 1576097301 2019/12/11 20:48:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhlobj.c $NHDT-Date: 1781973058 2026/06/20 16:30:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) 2019 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlsel.c b/src/nhlsel.c index 9b5ef24c4..817cb775a 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhlua.c $NHDT-Date: 1769840272 2026/01/30 22:17:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 5.0 nhlua.c $NHDT-Date: 1781973058 2026/06/20 16:30:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/nhlua.c b/src/nhlua.c index 96970f73c..46c4e9c5d 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -1,10 +1,18 @@ -/* NetHack 3.7 nhlua.c $NHDT-Date: 1744963460 2025/04/18 00:04:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.153 $ */ +/* NetHack 5.0 nhlua.c $NHDT-Date: 1781973059 2026/06/20 16:30:59 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.168 $ */ /* Copyright (c) 2018 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" #include "dlb.h" +/* minimum and maximum LUA_VERSION_NUM expected by this version of NetHack */ +#ifndef NHL_MIN_VERSION_NUM_EXPECTED +#define NHL_MIN_VERSION_NUM_EXPECTED 504 +#endif +#ifndef NHL_MAX_VERSION_NUM_EXPECTED +#define NHL_MAX_VERSION_NUM_EXPECTED 505 +#endif + #ifndef LUA_VERSION_RELEASE_NUM #ifdef NHL_SANDBOX #undef NHL_SANDBOX @@ -1954,6 +1962,10 @@ nhl_push_anything(lua_State *L, int anytype, void *src) any.a_schar = *(schar *) src; lua_pushinteger(L, any.a_schar); break; + case ANY_INT16: + any.a_int = *(xint16 *) src; + lua_pushinteger(L, any.a_int); + break; } return 1; } @@ -1968,13 +1980,13 @@ nhl_meta_u_index(lua_State *L) void *ptr; int type; } ustruct[] = { - { "ux", &(u.ux), ANY_UCHAR }, - { "uy", &(u.uy), ANY_UCHAR }, + { "ux", &(u.ux), ANY_INT16 }, + { "uy", &(u.uy), ANY_INT16 }, { "dx", &(u.dx), ANY_SCHAR }, { "dy", &(u.dy), ANY_SCHAR }, { "dz", &(u.dz), ANY_SCHAR }, - { "tx", &(u.tx), ANY_UCHAR }, - { "ty", &(u.ty), ANY_UCHAR }, + { "tx", &(u.tx), ANY_INT16 }, + { "ty", &(u.ty), ANY_INT16 }, { "ulevel", &(u.ulevel), ANY_INT }, { "ulevelmax", &(u.ulevelmax), ANY_INT }, { "uhunger", &(u.uhunger), ANY_INT }, @@ -1985,8 +1997,8 @@ nhl_meta_u_index(lua_State *L) { "mh", &(u.mh), ANY_INT }, { "mhmax", &(u.mhmax), ANY_INT }, { "mtimedone", &(u.mtimedone), ANY_INT }, - { "dlevel", &(u.uz.dlevel), ANY_SCHAR }, /* actually coordxy */ - { "dnum", &(u.uz.dnum), ANY_SCHAR }, /* actually coordxy */ + { "dlevel", &(u.uz.dlevel), ANY_INT16 }, + { "dnum", &(u.uz.dnum), ANY_INT16 }, { "uluck", &(u.uluck), ANY_SCHAR }, { "uhp", &(u.uhp), ANY_INT }, { "uhpmax", &(u.uhpmax), ANY_INT }, @@ -2294,22 +2306,20 @@ DISABLE_WARNING_CONDEXPR_IS_CONSTANT lua_State * nhl_init(nhl_sandbox_info *sbi) { - /* It would be nice to import EXPECTED from each build system. XXX */ - /* And it would be nice to do it only once, but it's cheap. */ -#ifndef NHL_VERSION_EXPECTED -#if LUA_VERSION_NUM >= 505 -#define NHL_VERSION_EXPECTED 50500 -#else -#define NHL_VERSION_EXPECTED 50408 -#endif -#endif - #ifdef NHL_SANDBOX - if (NHL_VERSION_EXPECTED != LUA_VERSION_RELEASE_NUM) { - panic( - "sandbox doesn't know this Lua version: this=%d != expected=%d ", - LUA_VERSION_RELEASE_NUM, NHL_VERSION_EXPECTED); - } +#define SANDBOX_DOESNT_KNOW "sandbox doesn't know this Lua version: " +if (LUA_VERSION_NUM < NHL_MIN_VERSION_NUM_EXPECTED + || LUA_VERSION_NUM > NHL_MAX_VERSION_NUM_EXPECTED) { + if (NHL_MIN_VERSION_NUM_EXPECTED == NHL_MAX_VERSION_NUM_EXPECTED) + panic("%sthis=%d != expected=%d", SANDBOX_DOESNT_KNOW, + LUA_VERSION_NUM, NHL_MIN_VERSION_NUM_EXPECTED); + else + panic("%sthis=%d, but expected %d to %d", SANDBOX_DOESNT_KNOW, + LUA_VERSION_NUM, + NHL_MIN_VERSION_NUM_EXPECTED, + NHL_MAX_VERSION_NUM_EXPECTED); +} +#undef SANDBOX_DOESNT_KNOW #endif lua_State *L = nhlL_newstate(sbi, "nhl_init"); diff --git a/src/nhmd4.c b/src/nhmd4.c index 02d9aa74e..043166397 100644 --- a/src/nhmd4.c +++ b/src/nhmd4.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 nhmd4.c $NHDT-Date: 1708811387 2024/02/24 21:49:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 nhmd4.c $NHDT-Date: 1781973059 2026/06/20 16:30:59 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/o_init.c b/src/o_init.c index 5bb82d2e2..ead30d1d9 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 o_init.c $NHDT-Date: 1771216675 2026/02/15 20:37:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */ +/* NetHack 5.0 o_init.c $NHDT-Date: 1781973060 2026/06/20 16:31:00 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/objects.c b/src/objects.c index 9389e3863..51e93aa84 100644 --- a/src/objects.c +++ b/src/objects.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objects.c $NHDT-Date: 1596498192 2020/08/03 23:43:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.66 $ */ +/* NetHack 5.0 objects.c $NHDT-Date: 1781973059 2026/06/20 16:30:59 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.76 $ */ /* Copyright (c) Mike Threepoint, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/objnam.c b/src/objnam.c index 1246029fd..3405a6b68 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1745114235 2025/04/19 17:57:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.453 $ */ +/* NetHack 5.0 objnam.c $NHDT-Date: 1781973060 2026/06/20 16:31:00 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.464 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -780,7 +780,7 @@ xname_flags( doname() so we've added an external flag to request it */ Concat(buf, 0, "partly eaten "); } - if (obj->globby) { /* 3.7 added "medium" to replace no-prefix */ + if (obj->globby) { /* 5.0 added "medium" to replace no-prefix */ ConcatF2(buf, 0, "%s %s", (obj->owt <= 100) ? "small" : (obj->owt <= 300) ? "medium" : (obj->owt <= 500) ? "large" @@ -1214,9 +1214,10 @@ erosion_matters(struct obj *obj) return FALSE; } -#define DONAME_WITH_PRICE 1 -#define DONAME_VAGUE_QUAN 2 -#define DONAME_FOR_MENU 4 /* [not used anywhere yet] */ +#define DONAME_WITH_PRICE 1 +#define DONAME_VAGUE_QUAN 2 +#define DONAME_FOR_MENU 4 /* [not used anywhere yet] */ +#define DONAME_FORCE_GENDER 8 /* always add male or female */ /* core of doname() */ staticfn char * @@ -1227,7 +1228,8 @@ doname_base( boolean ispoisoned = FALSE, with_price = (doname_flags & DONAME_WITH_PRICE) != 0, vague_quan = (doname_flags & DONAME_VAGUE_QUAN) != 0, - for_menu = (doname_flags & DONAME_FOR_MENU) != 0; + for_menu = (doname_flags & DONAME_FOR_MENU) != 0, + with_corpse_genders = (doname_flags & DONAME_FORCE_GENDER) != 0; boolean known, dknown, cknown, bknown, lknown, fake_arti, force_the; char prefix[PREFIX]; @@ -1511,7 +1513,15 @@ doname_base( unsigned cxarg = (((obj->quan != 1L) ? 0 : CXN_ARTICLE) | CXN_NOCORPSE); char *cxstr, *save_xnamep; + int puzzidx = (obj->invlet >= 'A' && obj->invlet <= 'Z') + ? obj->invlet - 'A' + : (obj->invlet >= 'a' && obj->invlet <= 'z') + ? obj->invlet - 'a' + 26 + : invlet_basic; /* valid index, but always holds zero */ + if (with_corpse_genders && puzzidx < invlet_basic + && gp.puzzling_criteria == 411 && gp.puzzling_ilets[puzzidx]) + cxarg |= CXN_ADDGNDR; /* corpse_xname() sets xnamep; callers other than doname_base() itself shouldn't care about xnamep (pointer to start of current obuf[]) but keep it accurate anyway */ @@ -1673,9 +1683,11 @@ doname_base( nochrg ? "contents" : "for sale", pricebuf); } else if (nochrg > 0) { Concat(bp, 0, " (no charge)"); + } else if (iflags.pricequotes && !objects[obj->otyp].oc_name_known) { + append_price_quote(bp, &bp_eos, obj->otyp); } - if (price) + if (price > 0L) record_price_quote(obj->otyp, price / obj->quan, TRUE); } else if (iflags.pricequotes && !objects[obj->otyp].oc_name_known) { append_price_quote(bp, &bp_eos, obj->otyp); @@ -1761,6 +1773,20 @@ doname_with_price(struct obj *obj) return doname_base(obj, DONAME_WITH_PRICE); } +/* Name of object including corpse genders. */ +char * +doname_with_cgender(struct obj *obj) +{ + return doname_base(obj, DONAME_FORCE_GENDER); +} + +/* doname with both price and corpse gender */ +char * +doname_with_price_and_cgender(struct obj *obj) +{ + return doname_base(obj, DONAME_WITH_PRICE | DONAME_FORCE_GENDER); +} + /* "some" instead of precise quantity if obj->dknown not set */ char * doname_vague_quan(struct obj *obj) @@ -1835,9 +1861,10 @@ corpse_xname( any_prefix = (cxn_flags & CXN_ARTICLE) != 0, /* leave off suffix (do_name() appends "corpse" itself) */ omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0, + gndr_prefix = (cxn_flags & CXN_ADDGNDR) != 0, possessive = FALSE, glob = (otmp->otyp != CORPSE && otmp->globby); - const char *mnam; + const char *mnam, *gndr; /* some callers [aobjnam()] rely on prefix area that xname() sets aside */ gx.xnamep = nextobuf(); @@ -1877,15 +1904,19 @@ corpse_xname( into the code, so the() has been modified to deal with capitalized monster names; we could switch to using it below like an() */ + gndr = (gndr_prefix && otmp->spe & CORPSTAT_MALE) != 0 ? "male " + : (gndr_prefix && otmp->spe & CORPSTAT_FEMALE) != 0 ? "female " + : ""; if (!adjective || !*adjective) { + Strcat(nambuf, gndr); /* normal case: newt corpse */ Strcat(nambuf, mnam); } else { /* adjective positioning depends upon format of monster name */ if (possessive) /* Medusa's cursed partly eaten corpse */ - Sprintf(eos(nambuf), "%s %s", mnam, adjective); + Sprintf(eos(nambuf), "%s %s%s", mnam, gndr, adjective); else /* cursed partly eaten troll corpse */ - Sprintf(eos(nambuf), "%s %s", adjective, mnam); + Sprintf(eos(nambuf), "%s %s%s", adjective, gndr, mnam); /* in case adjective has a trailing space, squeeze it out */ mungspaces(nambuf); /* doname() might include a count in the adjective argument; @@ -3393,6 +3424,8 @@ static const struct alt_spellings { { "silver shield", SHIELD_OF_REFLECTION }, { "potion of sleep", POT_SLEEPING }, { "scroll of recharging", SCR_CHARGING }, + { "scroll of identification", SCR_IDENTIFY }, + { "spellbook of identification", SPE_IDENTIFY }, { "recharging", SCR_CHARGING }, { "stone", ROCK }, { "camera", EXPENSIVE_CAMERA }, @@ -3414,6 +3447,9 @@ static const struct alt_spellings { { "grapple", GRAPPLING_HOOK }, { "protection from shape shifters", RIN_PROTECTION_FROM_SHAPE_CHAN }, { "accuracy", RIN_INCREASE_ACCURACY }, + { "ring of constitution", RIN_GAIN_CONSTITUTION }, + { "ring of strength", RIN_GAIN_STRENGTH }, + { "ring of damage", RIN_INCREASE_DAMAGE }, /* if we ever add other sizes, move this to o_ranges[] with "bag" */ { "box", LARGE_BOX }, /* normally we wouldn't have to worry about unnecessary , but @@ -4106,9 +4142,9 @@ readobjnam_preparse(struct _readobjnam_data *d) break; d->gsize = 1; } else if (!strncmpi(d->bp, "medium ", l = 7)) { - /* 3.7: in 3.6, "medium" was only used during wishing and the + /* 5.0: in 3.6, "medium" was only used during wishing and the mid-size glob had no adjective when formatted, but as of - 3.7, "medium" has become an explicit part of the name for + 5.0, "medium" has become an explicit part of the name for combined globs of at least 5 individual ones (owt >= 100) and less than 15 (owt < 300) */ d->gsize = 2; diff --git a/src/options.c b/src/options.c index 786c5757e..aa555bad1 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1737556914 2025/01/22 06:41:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.753 $ */ +/* NetHack 5.0 options.c $NHDT-Date: 1778886716 2026/05/15 15:11:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.782 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -558,6 +558,7 @@ parseoptions( got_match = FALSE; if (allopt[i].pfx) { + assert(allopt[i].name != NULL); if (str_start_is(opts, allopt[i].name, TRUE)) { matchidx = i; got_match = pfx_match = TRUE; @@ -2558,6 +2559,14 @@ optfn_name( if ((op = string_for_env_opt(allopt[optidx].name, opts, FALSE)) != empty_optstr) { +#ifdef WIN32 + /* + * Under windows, if we already set flags.debug with -D + * on the command line, leave that alone. + */ + if (flags.debug && !strcmpi(svp.plname, "wizard")) + return optn_ok; +#endif nmcpy(svp.plname, op, PL_NSIZ); } else return optn_err; @@ -2730,7 +2739,7 @@ optfn_palette( } #if 0 -/* old MAC OS9 code */ +/* old MAC68K OS9 code */ staticfn int optfn_palette( int optidx UNUSED, int req, boolean negated UNUSED, @@ -3032,8 +3041,8 @@ optfn_paranoid_confirmation( " %s", paranoia[i].argname); } /* note: always leaves enough room for caller to tack on '\n' */ - opts[0] = '\0'; - (void) strncat(opts, tmpbuf[0] ? &tmpbuf[1] : "none", BUFSZ - 1); + Snprintf(opts, BUFSZ - 1, "%s", + tmpbuf[0] ? &tmpbuf[1] : "none"); return optn_ok; } if (req == do_handler) { @@ -3679,7 +3688,7 @@ optfn_scores( if ((op = string_for_opt(opts, FALSE)) == empty_optstr) return optn_err; - /* 3.7: earlier versions left old values for unspecified arguments + /* 5.0: earlier versions left old values for unspecified arguments if player's scores:foo option only specified some of the three; in particular, attempting to use 'scores:own' rather than 'scores:0 top/0 around/own' didn't work as intended */ @@ -4223,11 +4232,11 @@ optfn_symset( if (req == do_handler) { int reslt; - if (!glyphid_cache_status()) - fill_glyphid_cache(); + if (!glyphname_hash_indices_loaded()) + populate_glyphname_hash_indices(); reslt = handler_symset(optidx); - if (glyphid_cache_status()) - free_glyphid_cache(); + if (glyphname_hash_indices_loaded()) + empty_glyphname_hash_indices(); /* apply_customizations(gc.currentgraphics, (do_custom_colors | do_custom_symbols)); */ return reslt; @@ -5107,7 +5116,7 @@ pfxfn_font(int optidx, int req, boolean negated, char *opts, char *op) if (opttype > 0 && (op = string_for_opt(opts, FALSE)) != empty_optstr) { wc_set_font_name(opttype, op); -#ifdef MAC +#ifdef MAC68K set_font_name(opttype, op); #endif return optn_ok; @@ -5310,6 +5319,14 @@ optfn_boolean( #endif go.opt_need_redraw = TRUE; break; +#ifndef IDLECHECKPOINT + case opt_idlecheckpoint: + pline("There is no underlying support for 'idlecheckpoint'" + " compiled in."); + iflags.idlecheckpoint = FALSE; + give_opt_msg = FALSE; + break; +#endif default: break; } @@ -5686,8 +5703,13 @@ handler_disclose(void) start_menu(tmpwin, MENU_BEHAVE_STANDARD); any = cg.zeroany; for (i = 0; i < NUM_DISCLOSURE_OPTIONS; i++) { - Sprintf(buf, "%-12s[%c%c]", disclosure_names[i], - flags.end_disclose[i], disclosure_options[i]); + if (iflags.menu_tab_sep) { + Sprintf(buf, "%s\t[%c%c]", disclosure_names[i], + flags.end_disclose[i], disclosure_options[i]); + } else { + Sprintf(buf, "%-12s[%c%c]", disclosure_names[i], + flags.end_disclose[i], disclosure_options[i]); + } any.a_int = i + 1; add_menu(tmpwin, &nul_glyphinfo, &any, disclosure_options[i], 0, ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); @@ -6783,12 +6805,12 @@ complain_about_duplicate(int optidx) { char buf[BUFSZ]; -#ifdef MAC +#ifdef MAC68K /* the Mac has trouble dealing with the output of messages while * processing the config file. That should get fixed one day. * For now just return. */ -#else /* !MAC */ +#else /* !MAC68K */ buf[0] = '\0'; if (using_alias) Sprintf(buf, " (via alias: %s)", allopt[optidx].alias); @@ -6796,7 +6818,7 @@ complain_about_duplicate(int optidx) (allopt[optidx].opttyp == CompOpt) ? "compound" : "boolean", allopt[optidx].name, buf); -#endif /* ?MAC */ +#endif /* ?MAC68K */ return; } @@ -7142,9 +7164,10 @@ initoptions_init(void) gc.cmdline_windowsys = NULL; } - /* make any symbol parsing quicker */ - if (!glyphid_cache_status()) - fill_glyphid_cache(); + /* make any symbol parsing quicker, but only if + * gd.disable_glyphname_hash_indices_prefill is not set to TRUE */ + if (!glyphname_hash_indices_loaded() && !gd.disable_glyphname_hash_indices_prefill) + populate_glyphname_hash_indices(); /* set up the command parsing */ reset_commands(TRUE); /* init */ @@ -7316,6 +7339,7 @@ void initoptions_finish(void) { nhsym sym = 0; + disregard_this_option(opt_mention_decor); /* defer this */ rcfile(); (void) fruitadd(svp.pl_fruit, (struct fruit *) 0); @@ -7366,8 +7390,8 @@ initoptions_finish(void) iflags.wc_ascii_map = FALSE, iflags.wc_tiled_map = TRUE; #ifdef ENHANCED_SYMBOLS - if (glyphid_cache_status()) - free_glyphid_cache(); + if (glyphname_hash_indices_loaded()) + empty_glyphname_hash_indices(); apply_customizations(gc.currentgraphics, do_custom_symbols | do_custom_colors); #endif @@ -7403,8 +7427,24 @@ allopt_array_init(void) memcpy(allopt, allopt_init, sizeof(allopt)); determine_ambiguities(); for (i = 0; allopt[i].name; i++) { - if (allopt[i].addr) + if (allopt[i].addr) { +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED \ + && NH_DEVEL_STATUS != NH_STATUS_POSTRELEASE) + if (allopt[i].opttyp == BoolOpt + && allopt[i].initval != allopt[i].opt_in_out) + if (wizard) + impossible("conflicting option init for %s: %s is %s, %s is %s", + allopt[i].name, + "opt_in_out", + allopt[i].opt_in_out ? "on" : "off", "initval", + allopt[i].initval ? "on" : "off"); +#endif +#if 0 + if (allopt[i].opttyp == BoolOpt && i != opt_ascii_map) + allopt[i].initval = allopt[i].opt_in_out; +#endif *(allopt[i].addr) = allopt[i].initval; + } } heed_all_options(); /* @@ -8938,9 +8978,10 @@ doset(void) /* changing options via menu by Per Liboriussen */ getlin(buf, abuf); if (abuf[0] == '\033') continue; - Sprintf(buf, "%s:", allopt[opt_indx].name); - (void) strncat(eos(buf), abuf, - (sizeof buf - 1 - strlen(buf))); + Snprintf(buf, sizeof buf, + "%s:%s", + allopt[opt_indx].name, + abuf); /* pass the buck */ (void) parseoptions(buf, FALSE, FALSE); } @@ -9423,7 +9464,7 @@ static const char *opt_intro[] = { " NetHack Options Help:", "", #define CONFIG_SLOT 3 /* fill in next value at run-time */ (char *) 0, -#if !defined(MICRO) && !defined(MAC) +#if !defined(MICRO) && !defined(MAC68K) "or use `NETHACKOPTIONS=\"\"' in your environment", #endif "( is a list of options separated by commas)", @@ -10176,6 +10217,9 @@ heed_all_options(void) { int i; + /* ensure OPTIONS= lines are enabled */ + heed_this_config_statement(0); /* index 0 == OPTIONS */ + for (i = 0; i < OPTCOUNT; i++) allopt[i].disregarded = FALSE; } @@ -10192,6 +10236,9 @@ disregard_all_options(void) void heed_this_option(enum opt optidx) { + /* ensure OPTIONS= lines are enabled */ + heed_this_config_statement(0); /* index 0 == OPTIONS */ + if (optidx >= 0 && optidx < (enum opt) OPTCOUNT) allopt[optidx].disregarded = FALSE; } diff --git a/src/pager.c b/src/pager.c index 82b8bc7eb..9cc16fb85 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1774846177 2026/03/29 20:49:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.296 $ */ +/* NetHack 5.0 pager.c $NHDT-Date: 1781973061 2026/06/20 16:31:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.302 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -556,7 +556,7 @@ look_at_monster( /* describe a pool location's contents; might return a static buffer so caller should use it or copy it before calling waterbody_name() again - [3.7: moved here from mkmaze.c] */ + [5.0: moved here from mkmaze.c] */ const char * waterbody_name(coordxy x, coordxy y) { diff --git a/src/pickup.c b/src/pickup.c index 331933137..6e1f788a8 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pickup.c $NHDT-Date: 1773373633 2026/03/12 19:47:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.386 $ */ +/* NetHack 5.0 pickup.c $NHDT-Date: 1781973061 2026/06/20 16:31:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.397 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -42,7 +42,7 @@ staticfn int traditional_loot(boolean); staticfn int menu_loot(int, boolean); staticfn int tip_ok(struct obj *); staticfn int choose_tip_container_menu(void); -staticfn struct obj *tipcontainer_gettarget(struct obj *, boolean *); +staticfn struct obj *tipcontainer_gettarget(struct obj *, boolean *, int *); staticfn int tipcontainer_checks(struct obj *, struct obj *, boolean); staticfn char in_or_out_menu(const char *, struct obj *, boolean, boolean, boolean, boolean); @@ -544,7 +544,7 @@ allow_category(struct obj *obj) * 1) object class (armor, potion, &c); * 2) unpaid shop item; * 3) bless/curse state (blessed, uncursed, cursed, BUC-unknown). - * Version 3.7 added a fourth: + * Version 5.0 added a fourth: * 4) 'novelty' ('P' for just picked up items). * When only one type is present, the situation is simple: * to be accepted, obj's status must match one of the entries. @@ -1041,7 +1041,7 @@ query_objlist(const char *qstr, /* query string */ unsigned sortflags; glyph_info tmpglyphinfo = nul_glyphinfo; Loot *sortedolist, *srtoli; - int clr = NO_COLOR; + int clr = NO_COLOR, puzzling_count = 0; *pick_list = (menu_item *) 0; if (!olist && !engulfer) @@ -1076,6 +1076,8 @@ query_objlist(const char *qstr, /* query string */ return 1; } + puzzling_count = check_for_puzzling_nonmerge(olist); + sortflags = (((flags.sortloot == 'f' || (flags.sortloot == 'l' && !(qflags & USE_INVLET))) ? SORTLOOT_LOOT @@ -1134,7 +1136,9 @@ query_objlist(const char *qstr, /* query string */ (qflags & USE_INVLET) ? curr->invlet : (first && curr->oclass == COIN_CLASS) ? '$' : 0, def_oc_syms[(int) objects[curr->otyp].oc_class].sym, - ATR_NONE, clr, doname_with_price(curr), + ATR_NONE, clr, + (puzzling_count) ? doname_with_price_and_cgender(curr) + : doname_with_price(curr), MENU_ITEMFLAGS_NONE); first = FALSE; } @@ -1897,11 +1901,17 @@ struct obj * pick_obj(struct obj *otmp) { struct obj *result; - int ox = otmp->ox, oy = otmp->oy; - boolean robshop = (!u.uswallow && otmp != uball && costly_spot(ox, oy)); + coordxy ox, oy; + boolean robshop, fromfloor = otmp->where == OBJ_FLOOR; + /* otmp is either on the floor or in an engulfer's inventory; for the + latter, its probably won't be set */ + (void) get_obj_location(otmp, &ox, &oy, 0); + + robshop = (!u.uswallow && otmp != uball && costly_spot(ox, oy)); obj_extract_self(otmp); - newsym(ox, oy); + if (fromfloor) + newsym(ox, oy); /* for shop items, addinv() needs to be after addtobill() (so that object merger can take otmp->unpaid into account) but before @@ -2230,7 +2240,8 @@ doloot_core(void) if (num_conts > 1) { /* use a menu to loot many containers */ - int n, i; + int n, i, tmpglyph; + glyph_info tmpglyphinfo; winid win; anything any; menu_item *pick_list = (menu_item *) 0; @@ -2243,7 +2254,9 @@ doloot_core(void) cobj = cobj->nexthere) if (Is_container(cobj)) { any.a_obj = cobj; - add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, + tmpglyph = obj_to_glyph(cobj, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, 0, 0, ATR_NONE, clr, doname(cobj), MENU_ITEMFLAGS_NONE); } end_menu(win, "Loot which containers?"); @@ -3498,7 +3511,8 @@ tip_ok(struct obj *obj) staticfn int choose_tip_container_menu(void) { - int n, i; + int n, i, tmpglyph; + glyph_info tmpglyphinfo; winid win; anything any; menu_item *pick_list = (menu_item *) 0; @@ -3514,7 +3528,9 @@ choose_tip_container_menu(void) if (Is_container(otmp)) { ++i; any.a_obj = otmp; - add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, + tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, 0, 0, ATR_NONE, clr, doname(otmp), MENU_ITEMFLAGS_NONE); } if (gi.invent) { @@ -3595,10 +3611,25 @@ dotip(void) } else { for (cobj = svl.level.objects[cc.x][cc.y]; cobj; cobj = nobj) { + int target_count = 0; + boolean dum; /* argument placeholder, not actually used */ + char prompt_part2[BUFSZ]; + nobj = cobj->nexthere; if (!Is_container(cobj)) continue; - c = ynq(safe_qbuf(qbuf, "There is ", " here, tip it?", + /* + * Calling tipcontainer_gettarget with a non-zero int ptr + * as the 3rd argument just obtains the count of eligible + * tip targets. No menu is displayed and no tip-target pick + * is carried out. + */ + (void) tipcontainer_gettarget(cobj, &dum, &target_count); + Sprintf(prompt_part2, " here, tip it%s%s?", + (target_count == 0) ? " onto the " : "", + (target_count == 0) ? surface(cobj->ox, cobj->oy) + : ""); + c = ynq(safe_qbuf(qbuf, "There is ", prompt_part2, cobj, doname, ansimpleoname, "container")); if (c == 'q') @@ -3697,7 +3728,7 @@ tipcontainer(struct obj *box) /* or bag */ * if 'box' is known to be empty or known to be locked, give up * before choosing 'targetbox'. */ - targetbox = tipcontainer_gettarget(box, &cancelled); + targetbox = tipcontainer_gettarget(box, &cancelled, (int *) 0); if (cancelled) return; @@ -3864,15 +3895,17 @@ count_target_containers( staticfn struct obj * tipcontainer_gettarget( struct obj *box, - boolean *cancelled) + boolean *cancelled, + int *only_count_targets) { - int n, n_conts; - winid win; + int n, n_conts = 0, tmpglyph, looppass, count_tiptargets = 0; + glyph_info tmpglyphinfo; + winid win = WIN_ERR; anything any; - char buf[BUFSZ]; + char buf[BUFSZ], on_the_surface[BUFSZ]; menu_item *pick_list = (menu_item *) 0; struct obj dummyobj, *otmp; - boolean hands_available = TRUE, exclude_it; + boolean hands_available = TRUE, exclude_it, skip_targetmenu = FALSE; int clr = NO_COLOR; #if 0 /* [skip potential early return so that menu response is needed @@ -3886,56 +3919,88 @@ tipcontainer_gettarget( return (struct obj *) 0; } #endif + /* + * looppass 0 : count the elligible drop targets + * looppass 1 : if there are elligible tip targets, besides the floor, + * then build and present a menu of those targets, including + * the floor. + */ + for (looppass = 0; looppass < 2; looppass++) { + if (looppass == 1) { + if (only_count_targets) { + *only_count_targets = count_tiptargets; + skip_targetmenu = TRUE; + break; + } + if (count_tiptargets == 0) { + /* nothing but the floor */ + skip_targetmenu = TRUE; + break; + } + win = create_nhwindow(NHW_MENU); + start_menu(win, MENU_BEHAVE_STANDARD); - win = create_nhwindow(NHW_MENU); - start_menu(win, MENU_BEHAVE_STANDARD); + dummyobj = cg.zeroobj; /* lint suppression; only its address + matters */ + any = cg.zeroany; + any.a_obj = &dummyobj; + /* tip to floor does not require free hands */ + Sprintf(on_the_surface, "on the %s", surface(u.ux, u.uy)); + add_menu(win, &nul_glyphinfo, &any, '-', 0, ATR_NONE, clr, + on_the_surface, MENU_ITEMFLAGS_SELECTED); + add_menu_str(win, ""); - dummyobj = cg.zeroobj; /* lint suppression; only its address matters */ - any = cg.zeroany; - any.a_obj = &dummyobj; - /* tip to floor does not require free hands */ - add_menu(win, &nul_glyphinfo, &any, '-', 0, ATR_NONE, clr, - /* [TODO? vary destination string depending on surface()] */ - "on the floor", MENU_ITEMFLAGS_SELECTED); - add_menu_str(win, ""); - - n_conts = 0; - for (otmp = gi.invent; otmp; otmp = otmp->nobj) { - if (otmp == box) - continue; - /* skip non-containers; bag of tricks passes Is_container() test, - only include it if it isn't known to be a bag of tricks */ - if (!Is_container(otmp) - || (otmp->otyp == BAG_OF_TRICKS && otmp->dknown - && objects[otmp->otyp].oc_name_known)) - continue; - if (!n_conts++) - hands_available = u_handsy(); /* might issue message */ - /* container-to-container tip requires free hands; - exclude container as possible target when known to be locked */ - exclude_it = !hands_available || (otmp->olocked && otmp->lknown); - any = cg.zeroany; - any.a_obj = !exclude_it ? otmp : 0; - Sprintf(buf, "%s%s", !exclude_it ? "" : " ", doname(otmp)); - add_menu(win, &nul_glyphinfo, &any, !exclude_it ? otmp->invlet : 0, 0, - ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); + n_conts = 0; + } + for (otmp = gi.invent; otmp; otmp = otmp->nobj) { + if (otmp == box) + continue; + /* skip non-containers; bag of tricks passes Is_container() test, + only include it if it isn't known to be a bag of tricks */ + if (!Is_container(otmp) + || (otmp->otyp == BAG_OF_TRICKS && otmp->dknown + && objects[otmp->otyp].oc_name_known)) + continue; + if (!n_conts++) + hands_available = u_handsy(); /* might issue message */ + /* container-to-container tip requires free hands; + exclude container as possible target when known to be locked */ + exclude_it = !hands_available || (otmp->olocked && otmp->lknown); + if (looppass == 0) { + if (!exclude_it) + count_tiptargets++; + } else { + any = cg.zeroany; + any.a_obj = !exclude_it ? otmp : 0; + Sprintf(buf, "%s%s", !exclude_it ? "" : " ", doname(otmp)); + tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, + !exclude_it ? otmp->invlet : 0, 0, ATR_NONE, clr, + buf, MENU_ITEMFLAGS_NONE); + } + } } + if (!skip_targetmenu) { + Sprintf(buf, "Where to tip the contents of %s", doname(box)); + end_menu(win, buf); + n = select_menu(win, PICK_ONE, &pick_list); + destroy_nhwindow(win); - Sprintf(buf, "Where to tip the contents of %s", doname(box)); - end_menu(win, buf); - n = select_menu(win, PICK_ONE, &pick_list); - destroy_nhwindow(win); - - otmp = 0; - if (pick_list) { - otmp = pick_list[0].item.a_obj; - /* PICK_ONE with a preselected item might return 2; - if so, choose the one that wasn't preselected */ - if (n > 1 && otmp == &dummyobj) - otmp = pick_list[1].item.a_obj; - if (otmp == &dummyobj) - otmp = 0; - free((genericptr_t) pick_list); + otmp = 0; + if (pick_list) { + otmp = pick_list[0].item.a_obj; + /* PICK_ONE with a preselected item might return 2; + if so, choose the one that wasn't preselected */ + if (n > 1 && otmp == &dummyobj) + otmp = pick_list[1].item.a_obj; + if (otmp == &dummyobj) + otmp = 0; + free((genericptr_t) pick_list); + } + } else { + otmp = 0; + n = 0; /* don't flag as having been cancelled */ } *cancelled = (boolean) (n == -1); return otmp; diff --git a/src/pline.c b/src/pline.c index 79dd8b28b..83a42e8df 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pline.c $NHDT-Date: 1719819280 2024/07/01 07:34:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.130 $ */ +/* NetHack 5.0 pline.c $NHDT-Date: 1781973061 2026/06/20 16:31:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.150 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/polyself.c b/src/polyself.c index 43c76cf40..6e380ad96 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 polyself.c $NHDT-Date: 1772101811 2026/02/26 02:30:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ +/* NetHack 5.0 polyself.c $NHDT-Date: 1781973061 2026/06/20 16:31:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.233 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -1408,6 +1408,7 @@ rehumanize(void) disp.botl = TRUE; gv.vision_full_recalc = 1; encumber_msg(); + update_inventory(); if (was_flying && !Flying && u.usteed) You("and %s return gently to the %s.", mon_nam(u.usteed), surface(u.ux, u.uy)); diff --git a/src/potion.c b/src/potion.c index c79498f90..8f444d673 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 potion.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ */ +/* NetHack 5.0 potion.c $NHDT-Date: 1781973062 2026/06/20 16:31:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.288 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -581,7 +581,7 @@ dodrink(void) * was no longer dealing with an inventory item. Unwearing * the current potion is intended to keep it in inventory.] * - * 3.7: switch back to relying on useup() unless the object is + * 5.0: switch back to relying on useup() unless the object is * actually worn. Otherwise drinking a stack of unpaid potions * one by one in a shop makes each one a separate used-up item * for 'Ix' invent display and for itemized shop billing instead diff --git a/src/pray.c b/src/pray.c index 0c38f9f0a..1462b1e36 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pray.c $NHDT-Date: 1762680996 2025/11/09 01:36:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ +/* NetHack 5.0 pray.c $NHDT-Date: 1781973062 2026/06/20 16:31:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.253 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/priest.c b/src/priest.c index cb480a757..d679893ee 100644 --- a/src/priest.c +++ b/src/priest.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 priest.c $NHDT-Date: 1764567778 2025/11/30 21:42:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 5.0 priest.c $NHDT-Date: 1781973062 2026/06/20 16:31:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.110 $ */ /* Copyright (c) Izchak Miller, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/quest.c b/src/quest.c index 2b54baa86..c5ed1642c 100644 --- a/src/quest.c +++ b/src/quest.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 quest.c $NHDT-Date: 1774269965 2026/03/23 04:46:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ +/* NetHack 5.0 quest.c $NHDT-Date: 1781973063 2026/06/20 16:31:03 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/questpgr.c b/src/questpgr.c index 707846e90..96a3c5ad7 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 questpgr.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 5.0 questpgr.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.87 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/read.c b/src/read.c index b422ee082..a8437bc16 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1762577372 2025/11/07 20:49:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.323 $ */ +/* NetHack 5.0 read.c $NHDT-Date: 1782083451 2026/06/21 18:10:51 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.334 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -180,6 +180,7 @@ tshirt_text(struct obj *tshirt, char *buf) from book series _A_Song_of_Ice_and_Fire_ by George R.R. Martin, TV show "Game of Thrones" (probably an actual T-shirt too...) */ "/Valar morghulis/ -- /Valar dohaeris/", + "Asidonhopo once said: the namesake of my enemy is my enemy", }; Strcpy(buf, shirt_msgs[tshirt->o_id % SIZE(shirt_msgs)]); @@ -1505,7 +1506,7 @@ seffect_remove_curse(struct obj **sobjp) if (scursed) { pline_The("scroll disintegrates."); } else { - /* 3.7: this used to use a straight + /* 5.0: this used to use a straight for (obj = invent; obj; obj = obj->nobj) {} traversal, but for the confused case, secondary weapon might become cursed and be dropped, moving it from the invent chain @@ -3212,7 +3213,7 @@ create_particular_parse( d->which = name_to_mon(bufp, &gender_name_var); /* * With the introduction of male and female monster names - * in 3.7, preserve that detail. + * in 5.0, preserve that detail. * * If d->fem is already set to MALE or FEMALE at this juncture, it means * one of those terms was explicitly specified. diff --git a/src/rect.c b/src/rect.c index 1fb0f2b82..e63c2eac0 100644 --- a/src/rect.c +++ b/src/rect.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rect.c $NHDT-Date: 1596498203 2020/08/03 23:43:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 rect.c $NHDT-Date: 1781973063 2026/06/20 16:31:03 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.26 $ */ /* Copyright (c) 1990 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/region.c b/src/region.c index 796d48fc1..6980e06b5 100644 --- a/src/region.c +++ b/src/region.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 region.c $NHDT-Date: 1727251269 2024/09/25 08:01:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */ +/* NetHack 5.0 region.c $NHDT-Date: 1781973064 2026/06/20 16:31:04 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.112 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/report.c b/src/report.c index ecfa0ad17..e5f701287 100644 --- a/src/report.c +++ b/src/report.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 report.c $NHDT-Date: 1741406837 2025/03/07 20:07:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 report.c $NHDT-Date: 1777240823 2026/04/26 22:00:23 $ $NHDT-Branch: to500 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2024 */ /* NetHack may be freely redistributed. See license for details. */ @@ -295,7 +295,7 @@ submit_web_report(int cos, const char *msg, const char *why) char temp2[200]; int countpp = 0; /* pre and post traceback lines */ // URL loaded for creating reports to the NetHack DevTeam -// CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html +// CRASHREPORTURL=https://nethack.org/links/cr-5.0.0.html if (!sysopt.crashreporturl) return FALSE; SWR_ADD(sysopt.crashreporturl); diff --git a/src/restore.c b/src/restore.c index 33066d662..d5e7cca19 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 restore.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.234 $ */ +/* NetHack 5.0 restore.c $NHDT-Date: 1781973064 2026/06/20 16:31:04 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.265 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -30,6 +30,7 @@ staticfn int restlevelfile(xint8); staticfn void rest_bubbles(NHFILE *); staticfn void restore_gamelog(NHFILE *); staticfn void reset_oattached_mids(boolean); + /* these ones are declared non-static in extern.h if SFCTOOL is defined */ staticfn boolean restgamestate(NHFILE *); staticfn void rest_bubbles(NHFILE *); @@ -447,6 +448,14 @@ restmonchn(NHFILE *nhfp) restshk(mtmp, ghostly); if (mtmp->ispriest) restpriest(mtmp, ghostly); + if (mtmp->isgd) { + /* fixup for new bit MON_PARKED added post 5.0.0 */ + if (!mtmp->mx && (mtmp->mstate & MON_PARKED) == 0L + && (mtmp->mstate & MON_MIGRATING) == 0L) { + mtmp->mstate &= ~TERRAIN_FALLOUT_MASK; + mtmp->mstate |= MON_PARKED; + } + } if (!ghostly) { if (mtmp->m_id == svc.context.polearm.m_id) @@ -536,6 +545,8 @@ restgamestate(NHFILE *nhfp) #endif Sfi_ulong(nhfp, &uid, "gamestate-uid"); + Sfi_char(nhfp, &svn.nhuuid[0], "nhuuid", sizeof svn.nhuuid); + Sfi_long(nhfp, &svm.moves, "gamestate-moves"); #ifndef SFCTOOL if (SYSOPT_CHECK_SAVE_UID && uid != (unsigned long) getuid()) { /* strange ... */ @@ -596,6 +607,8 @@ restgamestate(NHFILE *nhfp) amii_setpens(amii_numcolors); /* use colors from save file */ #endif #endif /* !SFCTOOL */ + Sfi_long(nhfp, &svw.wreserve, "wreserve"); + Sfi_int32(nhfp, &svw.wtreserved, "wtreserved"); Sfi_you(nhfp, &u, "gamestate-you"); gy.youmonst.cham = u.mcham; @@ -697,7 +710,6 @@ restgamestate(NHFILE *nhfp) restore_dungeon(nhfp); restlevchn(nhfp); - Sfi_long(nhfp, &svm.moves, "gamestate-moves"); /* hero_seq isn't saved and restored because it can be recalculated */ gh.hero_seq = svm.moves << 3; /* normally handled in moveloop() */ Sfi_q_score(nhfp, &svq.quest_status, "gamestate-quest_status"); @@ -709,6 +721,14 @@ restgamestate(NHFILE *nhfp) restore_oracles(nhfp); Sfi_char(nhfp, svp.pl_character, "gamestate-pl_character", sizeof svp.pl_character); + /* Previous versions had a bug that clobbered pl_character on restore. + Fill it in if it was clobbered. */ + if (svp.pl_character[0] == '\0') { + if ((Upolyd ? u.mfemale : flags.female) && gu.urole.name.f) + Strcpy(svp.pl_character, gu.urole.name.f); + else + Strcpy(svp.pl_character, gu.urole.name.m); + } Sfi_char(nhfp, svp.pl_fruit, "gamestate-pl_fruit", sizeof svp.pl_fruit); freefruitchn(gf.ffruit); /* clean up fruit(s) made by initoptions() */ gf.ffruit = loadfruitchn(nhfp); @@ -787,11 +807,13 @@ dorecover(NHFILE *nhfp) { xint8 ltmp = 0; int rtmp; + char plname[PL_NSIZ_PLUS]; /* suppress map display if some part of the code tries to update that */ program_state.restoring = REST_GSTATE; - get_plname_from_file(nhfp, svp.plname, TRUE); + get_plname_from_file(nhfp, plname, TRUE); + Snprintf(svp.plname, sizeof(svp.plname), "%s", plname); /* * The position in the save file is now here: * @@ -822,9 +844,6 @@ dorecover(NHFILE *nhfp) init_oclass_probs(); /* recompute go.oclass_prob_totals[] */ restlevelstate(); -#ifdef INSURANCE - savestateinlock(); -#endif rtmp = restlevelfile(ledger_no(&u.uz)); if (rtmp < 2) return rtmp; /* dorecover called recursively */ @@ -886,8 +905,9 @@ dorecover(NHFILE *nhfp) restoreinfo.mread_flags = 0; rewind_nhfile(nhfp); /* return to beginning of file */ - (void) validate(nhfp, (char *) 0, FALSE); - get_plname_from_file(nhfp, svp.plname, TRUE); + (void) validate(nhfp, (char *) 0, FALSE, 0); + get_plname_from_file(nhfp, plname, TRUE); + Snprintf(svp.plname, sizeof(svp.plname), "%s", plname); /* not 0 nor REST_GSTATE nor REST_LEVELS */ program_state.restoring = REST_CURRENT_LEVEL; @@ -897,6 +917,11 @@ dorecover(NHFILE *nhfp) restlevelstate(); program_state.something_worth_saving = 1; /* useful data now exists */ + if (gu.uplift_needed_rev0_to_rev1 == 1) { + /* they've all been uplifted now */ + gu.uplift_needed_rev0_to_rev1 = 0; + } + if (!wizard && !discover) (void) delete_savefile(); if (Is_rogue_level(&u.uz)) @@ -926,6 +951,12 @@ dorecover(NHFILE *nhfp) run_timers(); /* expire all timers that have gone off while away */ program_state.restoring = 0; /* affects bot() so clear before docrt() */ +#ifdef INSURANCE + /* first checkpoint of the restored session; every level file has been + written and the current level has been read back in, so recover has + something to work with even if the player never changes level */ + save_currentstate(); +#endif if (ge.early_raw_messages && !program_state.beyond_savefile_load) { /* @@ -1059,6 +1090,8 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) #endif program_state.in_getlev = TRUE; + level_status_init(); + level_status.loading = 1; #ifndef SFCTOOL if (ghostly) @@ -1111,7 +1144,7 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) Sfi_dest_area(nhfp, &svu.updest, "lev-updest"); Sfi_dest_area(nhfp, &svd.dndest, "lev-dndest"); Sfi_levelflags(nhfp, &svl.level.flags, "lev-level_flags"); - rest_adjust_levelflags(); + rest_adjust_levelflags(elapsed); if (svd.doors) { free(svd.doors); svd.doors = 0; @@ -1161,9 +1194,11 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) dealloc_trap(trap); fobj = restobjchn(nhfp, FALSE); -#ifndef SFCTOOL - find_lev_obj(); -#endif /* !SFCTOOL */ + /* more work needs to be done on fobj in find_lev_obj() further down, + * but that needs to happen after set_residency() so that shop_keeper() + * will return correct results during the processing. + */ + /* restobjchn()'s `frozen' argument probably ought to be a callback routine so that we can check for objects being buried under ice */ svl.level.buriedobjlist = restobjchn(nhfp, FALSE); @@ -1176,16 +1211,21 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) for (y = 0; y < ROWNO; y++) svl.level.monsters[x][y] = (struct monst *) 0; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if ((mtmp->mstate & TERRAIN_FALLOUT_MASK) != 0) + gp.pending_terrain_effects |= (mtmp->mstate & TERRAIN_FALLOUT_MASK); if (mtmp->isshk) set_residency(mtmp, FALSE); + /* set some monst fields to sane values when coming from a bones file */ + if (ghostly) { + mtmp->movement = 0; + } if (mtmp->m_id == u.usteed_mid) { /* steed is kept on fmon list but off the map */ u.usteed = mtmp; u.usteed_mid = 0; } else { if (mtmp->m_id == u.ustuck_mid) { - set_ustuck(mtmp); - u.ustuck_mid = 0; + set_ustuck(mtmp); /* set_ustuck clears u.ustuck_mid */ } place_monster(mtmp, mtmp->mx, mtmp->my); if (mtmp->wormno) @@ -1193,7 +1233,6 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (hides_under(mtmp->data) && mtmp->mundetected) (void) hideunder(mtmp); } - /* regenerate monsters while on another level */ if (!u.uz.dlevel || program_state.restoring == REST_LEVELS) continue; @@ -1207,6 +1246,9 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) : peace_minded(mtmp->data); set_malign(mtmp); } else if (elapsed > 0L) { + /* restmon() based hunger on now; account for time away */ + if (has_edog(mtmp)) + EDOG(mtmp)->hungrytime -= elapsed; mon_catchup_elapsed_time(mtmp, elapsed); } /* update shape-changers in case protection against @@ -1216,6 +1258,11 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (ghostly || (elapsed > 0L && elapsed > (long) rnd(10))) hide_monst(mtmp); } + level_status.shkready = 1; + /* post-5.0.0: this is now postponed until here so that it takes place + after set_residency() has been called */ + find_lev_obj(); + #endif /* !SFCTOOL */ restdamage(nhfp); @@ -1299,20 +1346,23 @@ getlev(NHFILE *nhfp, int pid, xint8 lev) if (ghostly) clear_id_mapping(); +#endif + level_status.loading = 0, level_status.ready = 1; program_state.in_getlev = FALSE; -#else +#ifdef SFCTOOL nhUse(pid); nhUse(lev); #endif /* !SFCTOOL */ - program_state.in_getlev = FALSE; } void -rest_adjust_levelflags(void) +rest_adjust_levelflags(long elapsed) { /* adjust timestamps */ relative_time_to_moves(&svl.level.flags.stasis_until); + svl.level.flags.stasis_until -= elapsed; } + void moves_to_relative_time(long *timestamp) { diff --git a/src/revision.c b/src/revision.c new file mode 100644 index 000000000..161c1508b --- /dev/null +++ b/src/revision.c @@ -0,0 +1,89 @@ +/* NetHack 5.0 revision.c $NHDT-Date: 1779927286 2026/05/28 00:14:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.1 $ */ +/* Copyright (c) Michael Allison, 2026. */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" + +boolean revision_increment( + int file_rev_level, + int file_critical_byte_count, + uchar *csc) +{ + if (file_rev_level == 0 && SAVEFILE_REVISION_LEVEL == 1) { + /* + * Revision 1 + * We set a flag gu.uplift_needed_rev0_to_rev1 for use by restore routines. + * + */ + gu.uplift_needed_rev0_to_rev1 = 1; + if (csc[file_critical_byte_count - 1] == 0) + /* below may not be necessary, or even useful */ + csc[file_critical_byte_count - 1] = SAVEFILE_REVISION_LEVEL; + return TRUE; + } + return FALSE; +} + +#ifdef DEMO_UPLIFTS + +/* original revision 0 is in include/revision.h */ + +/* revision 1 */ +struct mystruct { + int field1; + int field2; + char field3; + long field4; + int newfielda; + int newfieldb; +}; + +void +uplift_mystruct_rev0_to_mystruct(struct mystruct_rev0 *rev0, + struct mystruct *rev1) +{ + rev1->field1 = rev0->field1; + rev1->field2 = rev0->field2; + rev1->field3 = rev0->field3; + rev1->field4 = rev0->field4; + rev1->newfielda = 0; // new field + rev1->newfieldb = 0; // new field +} + +void +read_mystruct(struct mystruct *ms) +{ +#ifdef SAVEFILE_REVISION_LEVEL + +#if (SAVEFILE_REVISION_LEVEL == 0) + Sfi_mystruct(nhfp, ms, "mystruct-example"); +#elif (SAVEFILE_REVISION_LEVEL == 1) + +#define MYSTRUCT_REV0 +#include "revision.h" +#undef MYSTRUCT_REV0 + + if (!gu.uplift_needed_rev0_to_rev1) { + Sfi_mystruct(nhfp, ms, "mystruct-example"); + } else { + struct mystruct_rev0 old_mystruct; + + Sfi_mystruct_rev0(nhfp, &old_mystruct, "mystruct-example"); + uplift_mystruct_rev0_to_mystruct(&old_mystruct, ms); + } + + /* this could be elsewhere in some other sourcefile for example, + * where it is needed */ + if (gu.uplift_needed_rev0_to_rev1 == 1) { + /* Provide suitable starting values for fields that were not + * present in the previous revision that was read */ + ms->newfielda = 0; // new field in Rev. 1 + ms->newfieldb = 42; // new field in Rev. 1 + } +#endif +#endif /* SAVEFILE_REVISION_LEVEL */ +} + +#endif /* DEMO_UPLIFTS */ + +/*revision.c*/ diff --git a/src/rip.c b/src/rip.c index c9c64dfae..fa8a425f9 100644 --- a/src/rip.c +++ b/src/rip.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rip.c $NHDT-Date: 1597967808 2020/08/20 23:56:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 5.0 rip.c $NHDT-Date: 1781973064 2026/06/20 16:31:04 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.49 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rnd.c b/src/rnd.c index beb4992ed..3551b57a0 100644 --- a/src/rnd.c +++ b/src/rnd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rnd.c $NHDT-Date: 1596498205 2020/08/03 23:43:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 5.0 rnd.c $NHDT-Date: 1781973065 2026/06/20 16:31:05 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.41 $ */ /* Copyright (c) 2004 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/role.c b/src/role.c index 8d4feaab2..ead4345cf 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 role.c $NHDT-Date: 1737607158 2025/01/22 20:39:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ */ +/* NetHack 5.0 role.c $NHDT-Date: 1781973065 2026/06/20 16:31:05 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rumors.c b/src/rumors.c index 5aac3bd40..fb5d2faa6 100644 --- a/src/rumors.c +++ b/src/rumors.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rumors.c $NHDT-Date: 1594370241 2020/07/10 08:37:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 5.0 rumors.c $NHDT-Date: 1781973065 2026/06/20 16:31:05 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.93 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -7,7 +7,7 @@ #include "dlb.h" /* [Note: this comment is fairly old, but still accurate for 3.1; - * it's no longer accurate for 3.7 but may still be of interest.] + * it's no longer accurate for 5.0 but may still be of interest.] * Rumors have been entirely rewritten to speed up the access. This is * essential when working from floppies. Using fseek() the way that's done * here means rumors following longer rumors are output more often than those @@ -303,7 +303,7 @@ rumor_check(void) DISABLE_WARNING_FORMAT_NONLITERAL -/* 3.7: augments rumors_check(); test 'engrave' or 'epitaph' or 'bogusmon' */ +/* 5.0: augments rumors_check(); test 'engrave' or 'epitaph' or 'bogusmon' */ staticfn void others_check( const char *ftype, /* header: "{Engravings|Epitaphs|Bogus monsters}:" */ @@ -554,10 +554,11 @@ outrumor( switch (mechanism) { case BY_ORACLE: /* Oracle delivers the rumor */ - pline("True to her word, the Oracle %ssays: ", + pline("True to her word, the Oracle %s%s: ", (!rn2(4) ? "offhandedly " : (!rn2(3) ? "casually " - : (rn2(2) ? "nonchalantly " : "")))); + : (rn2(2) ? "nonchalantly " : ""))), + says()); SetVoice((struct monst *) 0, 0, 80, voice_oracle); verbalize1(line); /* [WIS exercised by getrumor()] */ diff --git a/src/save.c b/src/save.c index fd6dfae2f..dea871d54 100644 --- a/src/save.c +++ b/src/save.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 save.c $NHDT-Date: 1737610109 2025/01/22 21:28:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.232 $ */ +/* NetHack 5.0 save.c $NHDT-Date: 1781973065 2026/06/20 16:31:05 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.263 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -31,7 +31,7 @@ staticfn void save_gamelog(NHFILE *); staticfn void savegamestate(NHFILE *); staticfn void savelev_core(NHFILE *, xint8); staticfn void save_msghistory(NHFILE *); -staticfn void save_adjust_levelflags(void); +staticfn void save_adjust_levelflags(long); #if defined(HANGUPHANDLING) #define HUP if (!program_state.done_hup) #else @@ -270,6 +270,8 @@ savegamestate(NHFILE *nhfp) program_state.saving++; /* caller should/did already set this... */ uid = (unsigned long) getuid(); Sfo_ulong(nhfp, &uid, "gamestate-uid"); + Sfo_char(nhfp, &svn.nhuuid[0], "nhuuid", sizeof svn.nhuuid); + Sfo_long(nhfp, &svm.moves, "gamestate-moves"); moves_to_relative_time(&svc.context.seer_turn); moves_to_relative_time(&svc.context.digging.lastdigtime); Sfo_context_info(nhfp, &svc.context, "gamestate-context"); @@ -280,7 +282,35 @@ savegamestate(NHFILE *nhfp) urealtime.finish_time = getnow(); urealtime.realtime += timet_delta(urealtime.finish_time, urealtime.start_timing); + Sfo_long(nhfp, &svw.wreserve, "wreserve"); + Sfo_int32(nhfp, &svw.wtreserved, "wtreserved"); + /* + * In a normal save operation initiated by the player, + * the u.ustuck_mid and u.usteed_mid were already set + * by savemonchn() called from savelev_core(). Under + * that operation, u.ustuck and u.usteed pointers no longer + * point to valid locations here. Their non-zero values serve + * only to flag that they are were set, but the pointers + * must not be dereferenced. + */ + if (program_state.in_checkpoint) { + /* + * It is critical to ensure that u.ustuck_mid and u.usteed_mid + * hold current and correct data, in case this is needed by + * recover. The pointers, if set, are still pointing at + * valid data during a checkpoint operation, unlike during + * a synchronized save operation. + */ + u.ustuck_mid = (u.ustuck) ? u.ustuck->m_id : 0; + u.usteed_mid = (u.usteed) ? u.usteed->m_id : 0; + } Sfo_you(nhfp, &u, "gamestate-you"); + + /* clear the in-memory value of these, now that they have been + * successfully written out. + */ + u.ustuck_mid = 0; + u.usteed_mid = 0; Sfo_char(nhfp, yyyymmddhhmmss(ubirthday), "gamestate-ubirthday", 14); Sfo_long(nhfp, &urealtime.realtime, "gamestate-realtime"); Sfo_char(nhfp, yyyymmddhhmmss(urealtime.start_timing), "gamestate-start_timing", 14); @@ -309,7 +339,6 @@ savegamestate(NHFILE *nhfp) save_dungeon(nhfp, (boolean) !!update_file(nhfp), (boolean) !!release_data(nhfp)); savelevchn(nhfp); - Sfo_long(nhfp, &svm.moves, "gamestate-moves"); Sfo_q_score(nhfp, &svq.quest_status, "gamestate-quest_status"); for (i = 0; i < (MAXSPELL + 1); ++i) { Sfo_spell(nhfp, &svs.spl_book[i], "gamestate-spl_book"); @@ -351,6 +380,9 @@ savestateinlock(void) char whynot[BUFSZ]; NHFILE *nhfp; + if (!program_state.something_worth_saving || program_state.in_self_recover) + return; + program_state.saving++; /* inhibit status and perm_invent updates */ /* When checkpointing is on, the full state needs to be written * on each checkpoint. When checkpointing is off, only the pid @@ -452,6 +484,7 @@ savelev_core(NHFILE *nhfp, xint8 lev) short tlev; #endif int i, c, r; + long timestamp; coord *tmpc; program_state.saving++; /* even if current mode is FREEING */ @@ -509,14 +542,17 @@ savelev_core(NHFILE *nhfp, xint8 lev) Sfo_schar(nhfp, &svl.lastseentyp[c][r], "lastseentyp"); } } - /* svm.moves will actually be read back into svo.omoves on restore */ - Sfo_long(nhfp, &svm.moves, "lev-timestmp"); + /* preserve idle time when copying levels; match getlev()'s + monster catch-up guard */ + timestamp = (!u.uz.dlevel || program_state.restoring == REST_LEVELS) + ? svo.omoves : svm.moves; + Sfo_long(nhfp, ×tamp, "lev-timestmp"); save_stairs(nhfp); Sfo_dest_area(nhfp, &svu.updest, "lev-updest"); Sfo_dest_area(nhfp, &svd.dndest, "lev-dndest"); - save_adjust_levelflags(); + save_adjust_levelflags(timestamp); Sfo_levelflags(nhfp, &svl.level.flags, "lev-level_flags"); - rest_adjust_levelflags(); + rest_adjust_levelflags(svm.moves - timestamp); Sfo_int(nhfp, &svd.doors_alloc, "lev-doors_alloc"); /* don't rely on underlying write() behavior to write @@ -564,10 +600,10 @@ savelev_core(NHFILE *nhfp, xint8 lev) } void -save_adjust_levelflags(void) +save_adjust_levelflags(long timestamp) { - /* adjust any timestamps */ - moves_to_relative_time(&svl.level.flags.stasis_until); + /* use the same time base as lev-timestmp */ + svl.level.flags.stasis_until -= timestamp; } staticfn void @@ -1164,6 +1200,7 @@ freedynamicdata(void) release_runtime_info(); /* build-time options and version stuff */ free_convert_filenames(); #endif /* FREE_ALL_MEMORY */ + free_nhuuid(); if (VIA_WINDOWPORT()) status_finish(); @@ -1171,8 +1208,8 @@ freedynamicdata(void) if (options_set_window_colors_flag) options_free_window_colors(); - if (glyphid_cache_status()) - free_glyphid_cache(); + if (glyphname_hash_indices_loaded()) + empty_glyphname_hash_indices(); if (tnhfp) { close_nhfile(tnhfp); diff --git a/src/selvar.c b/src/selvar.c index a35b9f7bd..1b9296415 100644 --- a/src/selvar.c +++ b/src/selvar.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 selvar.c $NHDT-Date: 1769840272 2026/01/30 22:17:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ +/* NetHack 5.0 selvar.c $NHDT-Date: 1781973066 2026/06/20 16:31:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/sfbase.c b/src/sfbase.c index 0cd70af4e..b78cd3167 100644 --- a/src/sfbase.c +++ b/src/sfbase.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfbase.c.template $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ +/* NetHack 5.0 sfbase.c.template $NHDT-Date$ $NHDT-Branch$:$NHDT-Revision$ */ /* Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ @@ -106,7 +106,7 @@ void sf_log(NHFILE *, const char *, size_t, int, char *); #define Sfvalue_xint16(a) sfvalue(a) #endif -/* not in _Generic */ +/* not in _Generic */ #define Sfvalue_long(a) sfvalue_long(a) #define Sfvalue_ulong(a) sfvalue_ulong(a) #define Sfvalue_char(a, d) sfvalue_char(a, d) @@ -195,7 +195,7 @@ void sfi_##dtyp(NHFILE *nhfp, keyw dtyp *d_##dtyp, const char *myname) complex_dump((uchar *) d_##dtyp)); \ } \ } - + #define SF_X(xxx, dtyp) \ void sfo_##dtyp(NHFILE *nhfp, xxx *d_##dtyp, const char *myname, int bfsz) \ { \ @@ -461,7 +461,7 @@ sfvalue_genericptr(genericptr a) { static char buf[20]; - Snprintf(buf, sizeof buf, "%s", + Snprintf(buf, sizeof buf, "%s", (a == 0) ? "0" : "glorkum"); return buf; } @@ -632,7 +632,8 @@ complex_dump(uchar *a) for (i = 0; i < SIZE(x); ++i) { x[i] = *uc++; } - Snprintf(buf, sizeof buf, "%03x %03x %03x %03x %03x %03x %03x %03x %03x %03x", + Snprintf(buf, sizeof buf, + "%03x %03x %03x %03x %03x %03x %03x %03x %03x %03x", x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9]); buf[40] = '\0'; return buf; @@ -743,6 +744,10 @@ void norm_ptrs_version_info(struct version_info *d_version_info); void norm_ptrs_vlaunchinfo(union vlaunchinfo *d_vlaunchinfo); void norm_ptrs_vptrs(union vptrs *d_vptrs); void norm_ptrs_you(struct you *d_you); +#ifdef DEMO_UPLIFTS +void norm_ptrs_mystruct(struct mystruct *d_mystruct); +void norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct_rev0); +#endif void norm_ptrs_any(union any *d_any UNUSED) @@ -1038,6 +1043,17 @@ norm_ptrs_rm(struct rm *d_rm UNUSED) { } +#ifdef DEMO_UPLIFTS +void +norm_ptrs_mystruct(struct mystruct *d_mystruct UNUSED) +{ +} +void +norm_ptrs_mystruct_rev0(struct mystruct_rev0 *d_mystruct_rev0 UNUSED) +{ +} +#endif + void norm_ptrs_s_level(struct s_level *d_s_level UNUSED) { diff --git a/src/sfstruct.c b/src/sfstruct.c index 8a15a0c17..4eb9a8ed2 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfstruct.c $NHDT-Date: 1606765215 2020/11/30 19:40:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ +/* NetHack 5.0 sfstruct.c $NHDT-Date: 1781973066 2026/06/20 16:31:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2025. */ /* NetHack may be freely redistributed. See license for details. */ @@ -194,7 +194,6 @@ struct sf_structlevel_procs historical_sfo_procs = { historical_sfo_version_info, historical_sfo_you, historical_sfo_any, - historical_sfo_aligntyp, historical_sfo_boolean, historical_sfo_coordxy, @@ -219,6 +218,10 @@ struct sf_structlevel_procs historical_sfo_procs = { historical_sfo_xint8, historical_sfo_char, historical_sfo_bitfield, +#ifdef DEMO_UPLIFTS + historical_sfo_mystruct, + historical_sfo_mystruct_rev0, +#endif } }; @@ -295,6 +298,10 @@ struct sf_structlevel_procs historical_sfi_procs = { historical_sfi_xint8, historical_sfi_char, historical_sfi_bitfield, +#ifdef DEMO_UPLIFTS + historical_sfi_mystruct, + historical_sfi_mystruct_rev0, +#endif } }; @@ -308,12 +315,12 @@ static long floc = 0L; /* * historical structlevel savefile writing and reading routines follow. - * These were moved here from save.c and restore.c between 3.6.3 and 3.7.0. + * These were moved here from save.c and restore.c between 3.6.3 and 5.0.0,. */ staticfn int getidx(int, int); -#if defined(UNIX) || defined(WIN32) +#if defined(UNIX) || defined(WIN32) || defined(SFSTRUCT_BUFFERING) #define USE_BUFFERING #endif @@ -322,6 +329,9 @@ struct restore_info restoreinfo = { }; #define MAXFD 5 +#ifdef SFSTRUCT_BUFFERING +#define BWBUFSZ 16384 +#endif enum {NOFLG = 0, NOSLOT = 1}; static int bw_sticky[MAXFD] = {-1,-1,-1,-1,-1}; static int bw_buffered[MAXFD] = {0,0,0,0,0}; @@ -424,6 +434,10 @@ bufon(int fd) if (!bw_FILE[idx]) { if ((bw_FILE[idx] = fdopen(fd, "w")) == 0) panic("buffering of file %d failed", fd); +#ifdef SFSTRUCT_BUFFERING + (void) setvbuf(bw_FILE[idx], (char *) 0, _IOFBF, + (size_t) BWBUFSZ); +#endif } bw_buffered[idx] = (bw_FILE[idx] != 0); #else @@ -572,7 +586,8 @@ mread(int fd, genericptr_t buf, unsigned len) /* Not perfect, but we don't have ssize_t available. */ rlen = (readLenType) read(fd, buf, (readLenType) len); if ((readLenType) rlen != (readLenType) len) { - if (restoreinfo.mread_flags == 1) { /* means "return anyway" */ + if ((restoreinfo.mread_flags == 1) /* means "return anyway" */ + || (program_state.reading_bonesfile == 1)) { restoreinfo.mread_flags = -1; return; } else { diff --git a/src/shk.c b/src/shk.c index 927352971..37e7b9422 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shk.c $NHDT-Date: 1736516428 2025/01/10 05:40:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.306 $ */ +/* NetHack 5.0 shk.c $NHDT-Date: 1781973066 2026/06/20 16:31:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.323 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1075,6 +1075,18 @@ shop_keeper(char rmno) correct the underlying svr.rooms[].resident issue but... */ return (struct monst *) 0; } + } else { + if (!level_status.shkready) { + int hmm UNUSED = 1; +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED \ + && NH_DEVEL_STATUS != NH_STATUS_POSTRELEASE) + impossible("untrustworthy null shkp; level_status.shkready" + " is FALSE (%d, %d, %d, &d)", + level_status.making, level_status.loading, + level_status.shkready, level_status.ready); +#endif + nhUse(hmm); + } } return shkp; } @@ -1525,7 +1537,7 @@ cheapest_item(int ibillct, Bill *ibill) long gmin = ibill[0].cost; /* - * 3.7: old version didn't determine cheapest item correctly if it + * 5.0: old version didn't determine cheapest item correctly if it * was either the partly used or partly intact portion of a partially * used stack. Rather than modify it to use bp_to_obj() in order to * obtain quanities for every entry on eshkp->bill_p[], switch to @@ -1675,7 +1687,8 @@ menu_pick_pay_items( menu_item *pick_list = (menu_item *) 0; char *p, buf[BUFSZ]; long amt, largest_amt, save_quan; - int i, j, n, amt_width; + int i, j, n, amt_width, tmpglyph; + glyph_info tmpglyphinfo; any = cg.zeroany; win = create_nhwindow(NHW_MENU); @@ -1716,7 +1729,9 @@ menu_pick_pay_items( isn't hallucinating; also, that would mess up the alignment */ Snprintf(buf, sizeof buf, "%*ld Zm, %s", amt_width, amt, p); any.a_int = i + 1; /* +1: avoid 0 */ - add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, buf, + tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng); + map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo); + add_menu(win, &tmpglyphinfo, &any, 0, 0, ATR_NONE, NO_COLOR, buf, MENU_ITEMFLAGS_NONE); } @@ -2034,6 +2049,12 @@ dopay(void) return paid ? ECMD_TIME : ECMD_OK; } +const char * +says(void) +{ + return Deaf ? "signs" : "says"; +} + /* for menustyle=Traditional, choose between paying for everything (by declining to itemize), asking item-by-item (by accepting itemization), or switch to selecting via menu (special 'm' answer at "Itemize? [ynq m]" @@ -2107,7 +2128,7 @@ pay_billed_items( } while (via_menu); /* - * 3.7: this used to make two passes through eshkp->bill_p[], + * 5.0: this used to make two passes through eshkp->bill_p[], * the first for used up items and the second for unpaid ones. * Items which were partly used were processed on both passes. * diff --git a/src/shknam.c b/src/shknam.c index 657487ed8..54e76d0ec 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shknam.c $NHDT-Date: 1764109114 2025/11/25 22:18:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */ +/* NetHack 5.0 shknam.c $NHDT-Date: 1781973067 2026/06/20 16:31:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.90 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -128,7 +128,7 @@ static const char *const shktools[] = { #ifdef WIN32 "Lexa", "Niod", #endif -#ifdef MAC +#ifdef MAC68K "Nhoj-lee", "Evad\'kh", "Ettaw-noj", "Tsew-mot", "Ydna-s", "Yao-hang", "Tonbar", "Kivenhoug", "Llardom", #endif diff --git a/src/sit.c b/src/sit.c index 15c16dbdf..2fc32471c 100644 --- a/src/sit.c +++ b/src/sit.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sit.c $NHDT-Date: 1718136168 2024/06/11 20:02:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 5.0 sit.c $NHDT-Date: 1781973067 2026/06/20 16:31:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.112 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -214,7 +214,7 @@ throne_sit_effect(void) You_feel("somehow out of place..."); } - /* 3.7: when the random chance for removal is hit, ask for confirmation + /* 5.0: when the random chance for removal is hit, ask for confirmation if in wizard mode, and remove the throne even if hero was teleported away from it. [This used to remove a throne at hero's current location if there happened to be one, so for the teleport case that diff --git a/src/sounds.c b/src/sounds.c index 5e4a0e1cd..224eeb5b3 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sounds.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.165 $ */ +/* NetHack 5.0 sounds.c $NHDT-Date: 1781973067 2026/06/20 16:31:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.172 $ */ /* Copyright (c) 1989 Janet Walz, Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -814,8 +814,10 @@ domonnoise(struct monst *mtmp) flags.female ? FEMALE : MALE)) : an(racenoun)); verbl_msg = verbuf; - } else - verbl_msg = vampmsg[vampindex]; + } else if (vampindex > 1) { + if (vampindex >= 0 && vampindex < SIZE(vampmsg)) + verbl_msg = vampmsg[vampindex]; + } } } break; @@ -1080,7 +1082,7 @@ domonnoise(struct monst *mtmp) } else switch (monsndx(ptr)) { case PM_HOBBIT: - /* 3.7: the 'complains' message used to be given if the + /* 5.0: the 'complains' message used to be given if the hobbit's current hit points were at 10 below max or less, but their max is normally less than 10 so it would almost never occur */ @@ -1536,6 +1538,8 @@ tiphat(void) return res; } +char *sounddir = 0; + #ifdef USER_SOUNDS typedef struct audio_mapping_rec { @@ -1549,7 +1553,6 @@ typedef struct audio_mapping_rec { static audio_mapping *soundmap = 0; static audio_mapping *sound_matches_message(const char *); -char *sounddir = 0; /* set in files.c */ /* adds a sound file mapping, returns 0 on failure, 1 on success */ int diff --git a/src/sp_lev.c b/src/sp_lev.c index 007d65404..163a68925 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.c $NHDT-Date: 1737610109 2025/01/22 21:28:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.373 $ */ +/* NetHack 5.0 sp_lev.c $NHDT-Date: 1778778225 2026/05/14 17:03:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.387 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -70,7 +70,7 @@ staticfn boolean good_stair_loc(coordxy, coordxy); staticfn void ensure_way_out(void); #if 0 -/* macosx complains that these are unused */ +/* macOS complains that these are unused */ staticfn long sp_code_jmpaddr(long, long); staticfn void spo_room(struct sp_coder *); staticfn void spo_trap(struct sp_coder *); @@ -2042,7 +2042,8 @@ create_monster(monster *m, struct mkroom *croom) && m_bad_boulder_spot(x, y)) { int retrylimit = 10; - remove_monster(x, y); + if (x >= 0) + remove_monster(x, y); do { x = m->x; y = m->y; @@ -3671,6 +3672,7 @@ lspo_object(lua_State *L) boolean nonpmobj = FALSE; int i; char *montype = get_table_str_opt(L, "montype", NULL); + int lflags = 0; if (montype) { if ((tmpobj.id == TIN && (!strcmpi(montype, "spinach") @@ -3688,11 +3690,18 @@ lspo_object(lua_State *L) G_NOGEN | G_IGNORE); } else { for (i = LOW_PM; i < NUMMONS; i++) - if (!strcmpi(mons[i].pmnames[NEUTRAL], montype) - || (mons[i].pmnames[MALE] != 0 - && !strcmpi(mons[i].pmnames[MALE], montype)) - || (mons[i].pmnames[FEMALE] != 0 - && !strcmpi(mons[i].pmnames[FEMALE], montype))) { + if (!strcmpi(mons[i].pmnames[NEUTRAL], montype)) { + pm = &mons[i]; + tmpobj.spe = 0; + break; + } else if (mons[i].pmnames[MALE] != 0 + && !strcmpi(mons[i].pmnames[MALE], montype)) { + lflags |= CORPSTAT_MALE; + pm = &mons[i]; + break; + } else if (mons[i].pmnames[FEMALE] != 0 + && !strcmpi(mons[i].pmnames[FEMALE], montype)) { + lflags |= CORPSTAT_FEMALE; pm = &mons[i]; break; } @@ -3703,8 +3712,8 @@ lspo_object(lua_State *L) else if (!nonpmobj) nhl_error(L, "Unknown montype"); } - if (tmpobj.id == STATUE || tmpobj.id == CORPSE) { - int lflags = 0; + if (tmpobj.id == STATUE || tmpobj.id == FIGURINE + || tmpobj.id == CORPSE) { if (get_table_boolean_opt(L, "historic", 0)) lflags |= CORPSTAT_HISTORIC; @@ -3712,7 +3721,8 @@ lspo_object(lua_State *L) lflags |= CORPSTAT_MALE; if (get_table_boolean_opt(L, "female", 0)) lflags |= CORPSTAT_FEMALE; - tmpobj.spe = lflags; + if (lflags != 0) + tmpobj.spe = lflags; } else if (tmpobj.id == EGG) { tmpobj.spe = get_table_boolean_opt(L, "laid_by_you", 0) ? 1 : 0; } else if (!nonpmobj) { /* tmpobj.spe is already set for nonpmobj */ diff --git a/src/spell.c b/src/spell.c index 43c2acd51..e60c2e0d8 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 spell.c $NHDT-Date: 1769498874 2026/01/26 23:27:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.185 $ */ +/* NetHack 5.0 spell.c $NHDT-Date: 1781973068 2026/06/20 16:31:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.189 $ */ /* Copyright (c) M. Stephenson 1988 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/stairs.c b/src/stairs.c index 89b9ff3e8..bf052aaf9 100644 --- a/src/stairs.c +++ b/src/stairs.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 stairs.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.207 $ */ +/* NetHack 5.0 stairs.c $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.207 $ */ /* Copyright (c) 2024 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/steal.c b/src/steal.c index fd53ff1b7..ded8c1749 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 steal.c $NHDT-Date: 1720895742 2024/07/13 18:35:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */ +/* NetHack 5.0 steal.c $NHDT-Date: 1781973068 2026/06/20 16:31:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.142 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/steed.c b/src/steed.c index 835a8562f..4f24cdb5c 100644 --- a/src/steed.c +++ b/src/steed.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 steed.c $NHDT-Date: 1720128167 2024/07/04 21:22:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ +/* NetHack 5.0 steed.c $NHDT-Date: 1781973068 2026/06/20 16:31:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.132 $ */ /* Copyright (c) Kevin Hugo, 1998-1999. */ /* NetHack may be freely redistributed. See license for details. */ @@ -903,8 +903,10 @@ place_monster(struct monst *mon, coordxy x, coordxy y) buf[0] = '\0'; /* normal map bounds are <1..COLNO-1,0..ROWNO-1> but sometimes - vault guards (either living or dead) are parked at <0,0> */ - if (!isok(x, y) && (x != 0 || y != 0 || !mon->isgd)) { + vault guards (either living or dead) are parked at <0,0>; + their mstate should have the MON_PARKED bit set (post-5.0.0) */ + if (!isok(x, y) + && !(((mon->mstate & MON_PARKED) != 0) || PARKEDMONSTER(mon))) { describe_level(buf, 0); impossible("trying to place %s at <%d,%d> mstate:%lx on %s", minimal_monnam(mon, TRUE), x, y, mon->mstate, buf); @@ -912,7 +914,7 @@ place_monster(struct monst *mon, coordxy x, coordxy y) } if ((mon == u.usteed && !gi.in_steed_dismounting) /* special case is for convoluted vault guard handling */ - || (DEADMONSTER(mon) && !(mon->isgd && x == 0 && y == 0))) { + || (DEADMONSTER(mon) && !PARKEDMONSTER(mon))) { describe_level(buf, 0); impossible("placing %s onto map, mstate:%lx, on %s?", (mon == u.usteed) ? "steed" : "defunct monster", @@ -928,7 +930,16 @@ place_monster(struct monst *mon, coordxy x, coordxy y) } mon->mx = x, mon->my = y; svl.level.monsters[x][y] = mon; - mon->mstate = MON_FLOOR; + /* even though MON_FLOOR is not actually a bit currently + (MON_FLOOR == 0) we want to preserve some of the other + bits that may be set. We'll probably make MON_FLOOR an + actual bit one day */ + + mon->mstate &= ~(MON_OFF_MAP_BITS); + + /* We don't mess with these bits above: + MON_OBLITERATE | MON_STILL_ARRIVING + */ } /*steed.c*/ diff --git a/src/strutil.c b/src/strutil.c index c35d22182..8047281b6 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 strutil.c $NHDT-Date: 1709571807 2024/03/04 17:03:27 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 strutil.c $NHDT-Date: 1709571807 2024/03/04 17:03:27 $ $NHDT-Branch: keni-mdlib-followup $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) Robert Patrick Rankin, 1991 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/symbols.c b/src/symbols.c index 0d60df7b2..99382b721 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 symbols.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.123 $ */ +/* NetHack 5.0 symbols.c $NHDT-Date: 1781973069 2026/06/20 16:31:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.128 $ */ /* Copyright (c) NetHack Development Team 2020. */ /* NetHack may be freely redistributed. See license for details. */ @@ -7,6 +7,9 @@ staticfn void savedsym_add(const char *, const char *, int); staticfn struct _savedsym *savedsym_find(const char *, int); +staticfn const struct symparse *search_loadsyms(const char *buf, size_t len); +staticfn int symparse_compare(const void *s1_, const void *s2_); +staticfn int symparse_find(const void *bstr_, const void *rec_); extern const uchar def_r_oc_syms[MAXOCLASSES]; /* drawing.c */ @@ -29,6 +32,11 @@ void (*utf8graphics_mode_callback)(void) = 0; /* set in term_start_screen and * found in unixtty,windtty,&c */ #endif +struct bounded_string { + const char *str; + size_t len; +}; + /* * Explanations of the functions found below: * @@ -864,43 +872,112 @@ match_sym(char *buf) { "S_explode8", "S_expl_bc" }, { "S_explode9", "S_expl_br" }, }; int i; - size_t len = strlen(buf); - const char *p = strchr(buf, ':'), *q = strchr(buf, '='); - const struct symparse *sp = loadsyms; + size_t len; + const struct symparse *sp; /* G_ lines will never match here */ if ((buf[0] == 'G' || buf[0] == 'g') && buf[1] == '_') return (struct symparse *) 0; - if (!p || (q && q < p)) - p = q; - if (p) { - /* note: there will be at most one space before the '=' - because caller has condensed buf[] with mungspaces() */ - if (p > buf && p[-1] == ' ') - p--; - len = (int) (p - buf); - } - while (sp->range) { - if ((len >= strlen(sp->name)) && !strncmpi(buf, sp->name, len)) - return sp; - sp++; - } + len = strcspn(buf, "=:"); + /* note: there will be at most one space before the '=' + because caller has condensed buf[] with mungspaces() */ + if (len != 0 && buf[len-1] == ' ') + len--; + sp = search_loadsyms(buf, len); + if (sp != NULL) + return sp; for (i = 0; i < SIZE(alternates); ++i) { if ((len >= strlen(alternates[i].altnm)) && !strncmpi(buf, alternates[i].altnm, len)) { - sp = loadsyms; - while (sp->range) { - if (!strcmp(alternates[i].nm, sp->name)) - return sp; - sp++; - } + sp = search_loadsyms(alternates[i].nm, strlen(alternates[i].nm)); + if (sp != NULL) + return sp; } } return (struct symparse *) 0; } -DISABLE_WARNING_FORMAT_NONLITERAL +staticfn const struct symparse * +search_loadsyms(const char *buf, size_t len) +{ + struct bounded_string bstr; + + /* Sorted index to loadsyms */ + static boolean first_time = TRUE; + static const struct symparse *loadsyms_sorted[SIZE(loadsyms) - 1]; + if (first_time) { + const struct symparse *sp = loadsyms; + size_t i = 0; + while (sp->range) { + loadsyms_sorted[i] = sp; + ++sp; + ++i; + } + qsort((struct symparse **)loadsyms_sorted, SIZE(loadsyms_sorted), + sizeof(loadsyms_sorted[0]), symparse_compare); + first_time = FALSE; + } + + bstr.str = buf; + bstr.len = len; + const struct symparse **sp = bsearch(&bstr, loadsyms_sorted, + SIZE(loadsyms_sorted), sizeof(loadsyms_sorted[0]), + symparse_find); + return sp ? *sp : NULL; +} + +staticfn int +symparse_compare(const void *s1_, const void *s2_) +{ + const struct symparse **s1 = (const struct symparse **)s1_; + const struct symparse **s2 = (const struct symparse **)s2_; + const char *n1 = (*s1)->name; + const char *n2 = (*s2)->name; + size_t i; + + /* Can we count on strcmpi to say less than or greater than consistently? */ + for (i = 0; n1[i] != 0 && n2[i] != 0; ++i) { + char c1 = n1[i]; + char c2 = n2[i]; + if ('A' <= c1 && c1 <= 'Z') { + c1 += 'a' - 'A'; + } + if ('A' <= c2 && c2 <= 'Z') { + c2 += 'a' - 'A'; + } + if (c1 != c2) { + return c1 - c2; + } + } + + return n1[i] - n2[i]; +} + +staticfn int +symparse_find(const void *bstr_, const void *rec_) +{ + const struct bounded_string *bstr = (const struct bounded_string *)bstr_; + const struct symparse **rec = (const struct symparse **)rec_; + size_t i; + + /* Can we count on strcmpi to say less than or greater than consistently? */ + for (i = 0; i < bstr->len; ++i) { + char c1 = bstr->str[i]; + char c2 = (*rec)->name[i]; + if ('A' <= c1 && c1 <= 'Z') { + c1 += 'a' - 'A'; + } + if ('A' <= c2 && c2 <= 'Z') { + c2 += 'a' - 'A'; + } + if (c1 != c2) { + return c1 - c2; + } + } + + return 0; +} /* * this is called from options.c to do the symset work. @@ -915,7 +992,7 @@ do_symset(boolean rogueflag) menu_item *symset_pick = (menu_item *) 0; boolean ready_to_switch = FALSE, nothing_to_do = FALSE; - char *symset_name, fmtstr[20]; + char *symset_name; struct symsetentry *sl; int res, which_set, setcount = 0, chosen = -2, defindx = 0; int clr = NO_COLOR; @@ -962,7 +1039,6 @@ do_symset(boolean rogueflag) return TRUE; } - Sprintf(fmtstr, "%%-%ds %%s", biggest + 2); tmpwin = create_nhwindow(NHW_MENU); start_menu(tmpwin, MENU_BEHAVE_STANDARD); any = cg.zeroany; @@ -993,7 +1069,11 @@ do_symset(boolean rogueflag) any.a_int = sl->idx + 2; if (symset_name && !strcmpi(sl->name, symset_name)) defindx = any.a_int; - Sprintf(buf, fmtstr, sl->name, sl->desc ? sl->desc : ""); + if (iflags.menu_tab_sep) { + Sprintf(buf, "%s\t%s", sl->name, sl->desc ? sl->desc : ""); + } else { + Sprintf(buf, "%-*s %s", biggest + 2, sl->name, sl->desc ? sl->desc : ""); + } add_menu(tmpwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf, (any.a_int == defindx) ? MENU_ITEMFLAGS_SELECTED @@ -1069,12 +1149,12 @@ do_symset(boolean rogueflag) if (gs.symset[which_set].name) { /* non-default symbols */ int ok; - if (!glyphid_cache_status()) { - fill_glyphid_cache(); + if (!glyphname_hash_indices_loaded()) { + populate_glyphname_hash_indices(); } ok = read_sym_file(which_set); - if (glyphid_cache_status()) { - free_glyphid_cache(); + if (glyphname_hash_indices_loaded()) { + empty_glyphname_hash_indices(); } if (ok) { ready_to_switch = TRUE; @@ -1098,6 +1178,4 @@ do_symset(boolean rogueflag) return TRUE; } -RESTORE_WARNING_FORMAT_NONLITERAL - /*symbols.c*/ diff --git a/src/sys.c b/src/sys.c index 4d8ad2dcf..6661b74a3 100644 --- a/src/sys.c +++ b/src/sys.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sys.c $NHDT-Date: 1717449153 2024/06/03 21:12:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 5.0 sys.c $NHDT-Date: 1781973069 2026/06/20 16:31:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.74 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -59,6 +59,7 @@ sys_early_init(void) sysopt.genericusers = (char *) 0; sysopt.msghandler = (char *) 0; sysopt.maxplayers = 0; /* XXX eventually replace MAX_NR_OF_PLAYERS */ + sysopt.maxrerollrate = 0; sysopt.bones_pools = 0; sysopt.livelog = LL_NONE; diff --git a/src/teleport.c b/src/teleport.c index b235cb238..649a58c4d 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 teleport.c $NHDT-Date: 1769342601 2026/01/25 04:03:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ +/* NetHack 5.0 teleport.c $NHDT-Date: 1781973069 2026/06/20 16:31:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.246 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2139,9 +2139,10 @@ rloco(struct obj *obj) svd.dndest.nhx, svd.dndest.nhy))); if (flooreffects(obj, tx, ty, "fall")) { - /* update old location since flooreffects() couldn't; + /* update old location (if any) since flooreffects() couldn't; unblock_point() for boulder handled by obj_extract_self() */ - newsym(otx, oty); + if (!(otx == 0 && oty == 0)) + newsym(otx, oty); return FALSE; } else if (otx == 0 && oty == 0) { ; /* fell through a trap door; no update of old loc needed */ diff --git a/src/timeout.c b/src/timeout.c index af974c84e..9b83e33b5 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 timeout.c $NHDT-Date: 1776080125 2026/04/13 03:35:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.207 $ */ +/* NetHack 5.0 timeout.c $NHDT-Date: 1781973070 2026/06/20 16:31:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.212 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -961,7 +961,7 @@ fall_asleep(int how_long, boolean wakeup_msg) if (wakeup_msg && gm.multi == how_long) { /* caller can follow with a direct call to Hear_again() if there's a need to override this when wakeup_msg is true */ - /* 3.7: how_long is negative so wasn't actually incrementing the + /* 5.0: how_long is negative so wasn't actually incrementing the deafness timeout when it used to be passed as-is */ incr_itimeout(&HDeaf, abs(how_long)); disp.botl = TRUE; diff --git a/src/topten.c b/src/topten.c index f7770791a..76869599d 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 topten.c $NHDT-Date: 1606009004 2020/11/22 01:36:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 5.0 topten.c $NHDT-Date: 1781973070 2026/06/20 16:31:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/track.c b/src/track.c index 178e5a6f9..af0ee8b03 100644 --- a/src/track.c +++ b/src/track.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 track.c $NHDT-Date: 1596498219 2020/08/03 23:43:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 track.c $NHDT-Date: 1781973070 2026/06/20 16:31:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/trap.c b/src/trap.c index c6b5d7227..3dae5590a 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.c $NHDT-Date: 1741926700 2025/03/13 20:31:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.621 $ */ +/* NetHack 5.0 trap.c $NHDT-Date: 1781973071 2026/06/20 16:31:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.645 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1129,6 +1129,9 @@ m_harmless_trap(struct monst *mtmp, struct trap *ttmp) case LANDMINE: break; case ROLLING_BOULDER_TRAP: + /* the Sokoban rolling boulder traps are not dangerous */ + if (In_sokoban(&u.uz)) + return TRUE; break; case SLP_GAS_TRAP: if (resists_sleep(mtmp) || defended(mtmp, AD_SLEE)) @@ -2698,9 +2701,6 @@ trapeffect_rolling_boulder_trap( trap->tseen = TRUE; if (DEADMONSTER(mtmp)) trapkilled = TRUE; - } else { - deltrap(trap); - newsym(mtmp->mx, mtmp->my); } return trapkilled ? Trap_Killed_Mon : mtmp->mtrapped ? Trap_Caught_Mon : Trap_Effect_Finished; @@ -3375,6 +3375,23 @@ launch_obj( while (tmp-- > 0) nh_delay_output(); + /* + * TEMPORARY? github issue #1490 by BartekCupial reports a + * segfault when boulder rolls out of bounds. That should be + * impossible because trap creation validates the path that + * the boulder will traverse. + * + * The suggested fix increments bhitpos, verifies with isok(), + * then undoes the increment if not ok. This is simpler. + */ + if (!isok(gb.bhitpos.x + dx, gb.bhitpos.y + dy)) { + x2 = x, y2 = y; /* use current spot for final boulder placement */ + break; + } + /* + * end TEMPORARY? + */ + x = (gb.bhitpos.x += dx); y = (gb.bhitpos.y += dy); @@ -5294,7 +5311,7 @@ untrap_prob( chance = 1; /* else chance stays 3 */ } else if (!webmaker(gy.youmonst.data)) { - chance = 7; /* 3.7: used to be 30 */ + chance = 7; /* 5.0: used to be 30 */ } } if (Confusion || Hallucination) @@ -5979,7 +5996,7 @@ untrap( } /* end if */ if (boxcnt) { - /* 3.7: this used to allow searching for traps on multiple + /* 5.0: this used to allow searching for traps on multiple containers on the same move and needed to keep track of whether any had been found but not attempted to untrap; now at most one per move may be checked and we only @@ -6838,7 +6855,7 @@ lava_effects(void) /* Check whether we should burn away boots *first* so we know whether to * make the player sink into the lava. Assumption: water walking only * comes from boots. - * (3.7: that assumption is no longer true, but having boots be the first + * (5.0: that assumption is no longer true, but having boots be the first * thing to come into contact with lava makes sense.) */ if (uarmf && (uarmf->in_use @@ -7109,6 +7126,9 @@ trapname( "sweet-smelling gas vent", "phone booth", "exploding runes", "never-ending elevator", "slime pit", "warp zone", "illusory floor", "pile of poo", "honey trap", "tourist trap", + "banana peel", "garden rake", "whoopie cushion", "box and stick trap", + "fly trap", "legal trap", "pit of snakes", "pollywog trap", + "slippery slope", "thirst trap", "suntrap", }; static char roletrap[33]; /* [17 + 5 + 1] should suffice */ diff --git a/src/u_init.c b/src/u_init.c index 2b322b497..cca46f17d 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 u_init.c $NHDT-Date: 1769398807 2026/01/25 19:40:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ +/* NetHack 5.0 u_init.c $NHDT-Date: 1781973071 2026/06/20 16:31:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/uhitm.c b/src/uhitm.c index 00858508e..8cd7403f7 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1752823766 2025/07/17 23:29:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.477 $ */ +/* NetHack 5.0 uhitm.c $NHDT-Date: 1781973071 2026/06/20 16:31:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.503 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2202,7 +2202,7 @@ steal_it(struct monst *mdef, struct attack *mattk) if (ustealo) { /* we will be taking everything */ char heshe[20]; - /* 3.7: this uses hero's base gender rather than nymph femininity + /* 5.0: this uses hero's base gender rather than nymph femininity but was using hardcoded pronouns She/her for target monster; switch to dynamic pronoun */ if (gender(mdef) == (int) u.mfemale @@ -4228,7 +4228,7 @@ mhitm_ad_ston( pline("%s seems to grimace.", Monnam(magr)); } /* - * 3.7: New moon is no longer overridden by carrying a + * 5.0: New moon is no longer overridden by carrying a * lizard corpse. Having the moon's impact on terrestrial * activity be affected by carrying a dead critter felt * silly. diff --git a/src/utf8map.c b/src/utf8map.c index 19f3b18e4..f85226ad1 100644 --- a/src/utf8map.c +++ b/src/utf8map.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 utf8map.c */ +/* NetHack 5.0 utf8map.c */ /* Copyright (c) Michael Allison, 2021. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/vault.c b/src/vault.c index 90157b7fa..597c4b267 100644 --- a/src/vault.c +++ b/src/vault.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vault.c $NHDT-Date: 1737622664 2025/01/23 00:57:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.113 $ */ +/* NetHack 5.0 vault.c $NHDT-Date: 1781973072 2026/06/20 16:31:12 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.121 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -146,6 +146,7 @@ restfakecorr(struct monst *grd) /* it seems you left the corridor - let the guard disappear */ if (clear_fcorr(grd, FALSE)) { grd->isgd = 0; /* dmonsfree() should delete this mon */ + grd->mstate &= ~MON_PARKED; mongone(grd); } } @@ -162,8 +163,11 @@ parkguard(struct monst *grd) remove_monster(grd->mx, grd->my); newsym(grd->mx, grd->my); } - if (m_at(0, 0) != grd) + if (m_at(0, 0) != grd) { + grd->mstate &= ~TERRAIN_FALLOUT_MASK; + grd->mstate |= MON_PARKED; place_monster(grd, 0, 0); + } /* [grd->mx,my just got set to 0,0 by place_monster(), so this just sets EGD(grd)->ogx,ogy to 0,0 too; is that what we want?] */ EGD(grd)->ogx = grd->mx; @@ -996,7 +1000,7 @@ gd_move(struct monst *grd) gd_letknow(grd); return -1; } else { - if (!Deaf) { + if (!Deaf && mdistu(grd) <= 10*10) { SetVoice(grd, 0, 80, 0); verbalize("Well, begone."); } diff --git a/src/version.c b/src/version.c index 0b82963b8..32da5c6d9 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 version.c $NHDT-Date: 1737622664 2025/01/23 00:57:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.105 $ */ +/* NetHack 5.0 version.c $NHDT-Date: 1781973072 2026/06/20 16:31:12 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.118 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -118,7 +118,7 @@ status_version(char *buf, size_t bufsz, boolean indent) #if 0 /* note: it's possible for branch name to be a prefix of game name but that's unlikely enough that we won't bother with it; having - branch "nethack-3.7" be a superset of game "nethack" seems like + branch "nethack-5.0" be a superset of game "nethack" seems like including both is redundant, but having branch "net" be a subset of game "nethack" doesn't feel that way; optimizing "net" out seems like it would be a mistake */ @@ -607,7 +607,7 @@ struct critical_sizes_with_names critical_sizes[] = { { (uchar) sizeof(struct objclass), "struct objclass" }, { (uchar) sizeof(struct oextra), "struct oextra" }, { (uchar) sizeof(struct q_score), "struct q_score" }, - { (uchar) sizeof(struct rm), "struct rm" }, + { (uchar) sizeof(struct rm), "struct rm" }, /* [61] */ { (uchar) sizeof(struct spell), "struct spell" }, { (uchar) sizeof(struct stairway), "struct stairway" }, { (uchar) sizeof(struct s_level), "struct s_level" }, @@ -660,7 +660,7 @@ struct critical_sizes_with_names critical_sizes[] = { { 0, "" }, { 0, "" }, { 0, "" }, - { 0, "" }, + { (uchar) SAVEFILE_REVISION_LEVEL, "savefile_revision_level" }, }; uchar cscbuf[SIZE(critical_sizes)]; @@ -779,7 +779,19 @@ compare_critical_bytes(NHFILE *nhfp, int *idx_1st_mismatch, unsigned long utdfla for (i = 0; i < (int) file_csc_count; ++i) { Sfi_uchar(nhfp, &cscbuf[i], "critical_sizes"); } + for (i = 1; i < cnt; ++i) { +#ifndef SFCTOOL + if (cscbuf[i] != critical_sizes[i].ucsize && i == cnt - 1) { + /* SAVEFILE_REVISION_LEVEL mismatch; attempt to deal with it */ + int file_rev_level = cscbuf[i]; + + if (revision_increment(file_rev_level, + file_csc_count, + cscbuf)) + continue; + } +#endif if (cscbuf[i] != critical_sizes[i].ucsize) { const char *dm = datamodel(0), *dmfile; @@ -837,11 +849,14 @@ compare_critical_bytes(NHFILE *nhfp, int *idx_1st_mismatch, unsigned long utdfla * SF_DM_MISMATCH (9) some other mismatch */ int -validate(NHFILE *nhfp, const char *name, boolean without_waitsynch_perfile) +validate(NHFILE *nhfp, const char *name, boolean without_waitsynch_perfile, + int additional_utd_flags) { unsigned long utdflags = 0L; int validsf = 0; +if (additional_utd_flags) + utdflags |= additional_utd_flags; #ifdef SFCTOOL utdflags |= UTD_QUIETLY; #endif diff --git a/src/vision.c b/src/vision.c index 709f54d02..4b41f325c 100644 --- a/src/vision.c +++ b/src/vision.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vision.c $NHDT-Date: 1724939600 2024/08/29 13:53:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 5.0 vision.c $NHDT-Date: 1781973072 2026/06/20 16:31:12 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -58,7 +58,7 @@ const coordxy circle_start[] = { /* 4*/ 10, /* 5*/ 15, /* 6*/ 21, - /* 7*/ 38, + /* 7*/ 28, /* 8*/ 36, /* 9*/ 45, /*10*/ 55, @@ -822,7 +822,18 @@ vision_recalc(int control) if ((old_row[col] & IN_SIGHT) || ((next_row[col] & COULD_SEE) ^ (old_row[col] & COULD_SEE))) + { + /* + * TEMPORARY? Sometimes we get here with col==0 and + * newsym()'s impossible() for !isok() is being + * triggered, so avoid calling it for <0,y>; other bad + * coordinates will produce a panic() as they should. + */ + if (col != 0) + /* + */ newsym(col, row); + } } } /* end for col . . */ diff --git a/src/weapon.c b/src/weapon.c index 81da05613..39b186812 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 weapon.c $NHDT-Date: 1725227810 2024/09/01 21:56:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */ +/* NetHack 5.0 weapon.c $NHDT-Date: 1781973073 2026/06/20 16:31:13 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.147 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -954,14 +954,19 @@ abon(void) if (Upolyd) return (adj_lev(&mons[u.umonnum]) - 3); + + /* this used to be '<= 18/50' for bonus of 1 but got changed to '< 18/50' + so that '18/50' gives a bonus of 2; gnome and orc player characters + have max Str of 18/50 and giving an extra bonus at that break point + provides an incentive for them to max out that characteristic */ if (str < 6) sbon = -2; else if (str < 8) sbon = -1; else if (str < 17) sbon = 0; - else if (str <= STR18(50)) - sbon = 1; /* up to 18/50 */ + else if (str < STR18(50)) + sbon = 1; /* up to 18/49 */ else if (str < STR18(100)) sbon = 2; else diff --git a/src/were.c b/src/were.c index 59197177f..b8969ceb5 100644 --- a/src/were.c +++ b/src/were.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 were.c $NHDT-Date: 1766588485 2025/12/24 07:01:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 5.0 were.c $NHDT-Date: 1781973073 2026/06/20 16:31:13 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.46 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/wield.c b/src/wield.c index 21aad53c4..f0abd801f 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wield.c $NHDT-Date: 1707525193 2024/02/10 00:33:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */ +/* NetHack 5.0 wield.c $NHDT-Date: 1781973073 2026/06/20 16:31:13 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.124 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -262,8 +262,13 @@ ready_weapon(struct obj *wep) if ((this_shkp = shop_keeper(inside_shop(u.ux, u.uy))) != (struct monst *) 0) { - pline("%s says \"You be careful with my %s!\"", - shkname(this_shkp), xname(wep)); + /* check msound because we don't have access to muteshk() */ + if (!Deaf && this_shkp->data->msound > MS_ANIMAL) + pline("%s %s \"You be careful with my %s!\"", + shkname(this_shkp), says(), xname(wep)); + else + pline("%s looks apprehensive about your wielding %s %s.", + shkname(this_shkp), mhis(this_shkp), xname(wep)); } } } diff --git a/src/windows.c b/src/windows.c index a36b0eaa4..3169ade76 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 windows.c $NHDT-Date: 1737345149 2025/01/19 19:52:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 5.0 windows.c $NHDT-Date: 1781973074 2026/06/20 16:31:14 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.147 $ */ /* Copyright (c) D. Cohrs, 1993. */ /* NetHack may be freely redistributed. See license for details. */ @@ -22,7 +22,7 @@ extern struct window_procs Qt_procs; #ifdef GEM_GRAPHICS /*#include "wingem.h"*/ #endif -#ifdef MAC +#ifdef MAC68K extern struct window_procs mac_procs; #endif #ifdef BEOS_GRAPHICS @@ -111,7 +111,7 @@ static struct win_choices { #ifdef GEM_GRAPHICS { &Gem_procs, win_Gem_init CHAINR(0) }, #endif -#ifdef MAC +#ifdef MAC68K { &mac_procs, 0 CHAINR(0) }, #endif #ifdef BEOS_GRAPHICS @@ -543,7 +543,7 @@ staticfn void hup_cliparound(int, int); #endif #ifdef CHANGE_COLOR staticfn void hup_change_color(int, long, int); -#ifdef MAC +#ifdef MAC68K staticfn short hup_set_font_name(winid, char *); #endif staticfn char *hup_get_color_string(void); @@ -592,7 +592,7 @@ static struct window_procs hup_procs = { hup_void_ndecl, /* nh_delay_output */ #ifdef CHANGE_COLOR hup_change_color, -#ifdef MAC +#ifdef MAC68K hup_void_fdecl_int, /* change_background */ hup_set_font_name, #endif @@ -795,14 +795,14 @@ hup_change_color(int color UNUSED, long rgb UNUSED, int reverse UNUSED) return; } -#ifdef MAC +#ifdef MAC68K /*ARGSUSED*/ staticfn short hup_set_font_name(winid window UNUSED, char *fontname UNUSED) { return 0; } -#endif /* MAC */ +#endif /* MAC68K */ staticfn char * hup_get_color_string(void) @@ -1186,7 +1186,7 @@ dump_fmtstr( else Strcpy(tmpbuf, "{current date+time}"); break; - case 'v': /* version, eg. "3.7.0-0" */ + case 'v': /* version, eg. "5.0.0,-0" */ Sprintf(tmpbuf, "%s", version_string(verbuf, sizeof verbuf)); break; case 'u': /* UID */ diff --git a/src/wizard.c b/src/wizard.c index c89e3296f..a7f6af3a5 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wizard.c $NHDT-Date: 1741407262 2025/03/07 20:14:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 5.0 wizard.c $NHDT-Date: 1781973074 2026/06/20 16:31:14 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.121 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -620,7 +620,7 @@ nasty(struct monst *summoner) for (i = rnd(tmp); i > 0 && count < MAXNASTIES; --i) { /* Of the 44 nasties[], 10 are lawful, 14 are chaotic, * and 20 are neutral. [These numbers are up date for - * 3.7.0; the ones in the next paragraph are not....] + * 5.0.0; the ones in the next paragraph are not....] * * Neutral caster, used for late-game harassment, * has 18/42 chance to stop the inner loop on each diff --git a/src/wizcmds.c b/src/wizcmds.c index b045578b8..41b49da8d 100644 --- a/src/wizcmds.c +++ b/src/wizcmds.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wizcmds.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 wizcmds.c $NHDT-Date: 1781973074 2026/06/20 16:31:14 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.36 $ */ /*-Copyright (c) Robert Patrick Rankin, 2024. */ /* NetHack may be freely redistributed. See license for details. */ @@ -97,7 +97,9 @@ makemap_unmakemon(struct monst *mtmp, boolean migratory) monsters won't get out of sync; it is not on the map but mongone() -> m_detach() -> mon_leaving_level() copes with that */ mtmp->mstate |= MON_OFFMAP; - mtmp->mstate &= ~(MON_MIGRATING | MON_LIMBO | MON_ENDGAME_MIGR); + mtmp->mstate &= ~(MON_MIGRATING | MON_LIMBO | MON_ENDGAME_MIGR + | TERRAIN_FALLOUT_MASK); + /* FIXME: will post-5.0.0 MON_PARKED need to be dealt with here? */ mtmp->nmon = fmon; fmon = mtmp; } @@ -1777,6 +1779,14 @@ wiz_display_macros(void) return ECMD_OK; } +/* the #wizshownhuuid command */ +int +wiz_show_nhuuid(void) +{ + pline("The NHUUID for this game is { %s }.", svn.nhuuid); + return ECMD_OK; +} + /* the #wizmondiff command */ int wiz_mon_diff(void) @@ -1937,14 +1947,16 @@ wiz_custom(void) #endif menu_item *pick_list = (menu_item *) 0; - if (!glyphid_cache_status()) - fill_glyphid_cache(); + if (!glyphname_hash_indices_loaded()) + populate_glyphname_hash_indices(); win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); - add_menu_heading(win, - " glyph glyph identifier " - " sym clr customcolor unicode utf8"); + const char *heading = iflags.menu_tab_sep + ? "glyph\tglyph identifier\tsym\tclr\tcustomcolor\tunicode\tutf8" + : " glyph glyph identifier " + " sym clr customcolor unicode utf8"; + add_menu_heading(win, heading); Sprintf(bufa, "%s: colorcount=%ld %s", wizcustom, (long) iflags.colorcount, gs.symset[PRIMARYSET].name ? gs.symset[PRIMARYSET].name @@ -1956,7 +1968,7 @@ wiz_custom(void) known_handling[gs.symset[PRIMARYSET].handling]); } Sprintf(buf, "%s", bufa); - wizcustom_glyphids(win); + wizcustom_glyphnames(win); end_menu(win, bufa); n = select_menu(win, PICK_NONE, &pick_list); destroy_nhwindow(win); @@ -1967,8 +1979,8 @@ wiz_custom(void) #endif if (n >= 1) free((genericptr_t) pick_list); - if (glyphid_cache_status()) - free_glyphid_cache(); + if (glyphname_hash_indices_loaded()) + empty_glyphname_hash_indices(); docrt(); } else pline(unavailcmd, ecname_from_fn(wiz_custom)); @@ -1981,10 +1993,8 @@ wizcustom_callback(winid win, int glyphnum, char *id) extern glyph_map glyphmap[MAX_GLYPH]; glyph_map *cgm; int clr = NO_COLOR; - char buf[BUFSZ], bufa[BUFSZ], bufb[BUFSZ], bufc[BUFSZ], bufd[BUFSZ], - bufu[BUFSZ]; + char buf[BUFSZ], bufa[BUFSZ], bufb[BUFSZ], bufc[BUFSZ], bufu[BUFSZ]; anything any; - uint8 *cp; if (win && id) { cgm = &glyphmap[glyphnum]; @@ -1993,24 +2003,35 @@ wizcustom_callback(winid win, int glyphnum, char *id) cgm->u || #endif cgm->customcolor != 0) { - Sprintf(bufa, "[%04d] %-44s", glyphnum, id); - Sprintf(bufb, "'\\%03d' %02d", - gs.showsyms[cgm->sym.symidx], cgm->sym.color); - Sprintf(bufc, "%011lx", (unsigned long) cgm->customcolor); + if (iflags.menu_tab_sep) { + Sprintf(bufa, "[%04d]\t%s\t", glyphnum, id); + Sprintf(bufb, "'\\%03d'\t%02d\t", + gs.showsyms[cgm->sym.symidx], cgm->sym.color); + Sprintf(bufc, "%011lx\t", (unsigned long) cgm->customcolor); + } else { + Sprintf(bufa, "[%04d] %-45s", glyphnum, id); + Sprintf(bufb, "'\\%03d' %02d ", + gs.showsyms[cgm->sym.symidx], cgm->sym.color); + Sprintf(bufc, "%011lx ", (unsigned long) cgm->customcolor); + } bufu[0] = '\0'; #ifdef ENHANCED_SYMBOLS if (cgm->u && cgm->u->utf8str) { + uint8 *cp; + char sep = iflags.menu_tab_sep ? '\t' : ' '; Sprintf(bufu, "U+%04lx", (unsigned long) cgm->u->utf32ch); cp = cgm->u->utf8str; while (*cp) { - Sprintf(bufd, " <%d>", (int) *cp); + char bufd[BUFSZ]; + Sprintf(bufd, "%c<%d>", sep, (int) *cp); Strcat(bufu, bufd); cp++; + sep = ' '; } } #endif any.a_int = glyphnum + 1; /* avoid 0 */ - Snprintf(buf, sizeof buf, "%s %s %s %s", bufa, bufb, bufc, bufu); + Snprintf(buf, sizeof buf, "%s%s%s%s", bufa, bufb, bufc, bufu); add_menu(win, &nul_glyphinfo, &any, 0, 0, ATR_NONE, clr, buf, MENU_ITEMFLAGS_NONE); } diff --git a/src/worm.c b/src/worm.c index a74b81ac8..54c82300f 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worm.c $NHDT-Date: 1652689653 2022/05/16 08:27:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 5.0 worm.c $NHDT-Date: 1781973075 2026/06/20 16:31:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.73 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -224,7 +224,7 @@ worm_move(struct monst *worm) wgrowtime[wnum] = svm.moves + rnd(5); } else { int mmove = mcalcmove(worm, FALSE), - /* prior to 3.7.0, next-grow increment was 3..17 but since + /* prior to 5.0.0,, next-grow increment was 3..17 but since it got checked every 4th turn when the speed 3 worm got to move, it was effectively 0..5; also, its usage was 'wgrowtime += incr', so often 'wgrowtime' would be diff --git a/src/worn.c b/src/worn.c index a481f3372..5efd376c6 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worn.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.119 $ */ +/* NetHack 5.0 worn.c $NHDT-Date: 1781973075 2026/06/20 16:31:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.124 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/write.c b/src/write.c index d7a1eddb4..2a2390cfe 100644 --- a/src/write.c +++ b/src/write.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 write.c $NHDT-Date: 1702023275 2023/12/08 08:14:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 5.0 write.c $NHDT-Date: 1781973075 2026/06/20 16:31:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.54 $ */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" diff --git a/src/zap.c b/src/zap.c index bdaa54cec..261fd3914 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 zap.c $NHDT-Date: 1770949988 2026/02/12 18:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.584 $ */ +/* NetHack 5.0 zap.c $NHDT-Date: 1781973075 2026/06/20 16:31:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.596 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -198,7 +198,7 @@ bhitm(struct monst *mtmp, struct obj *otmp) seemimic(mtmp); shieldeff(mtmp->mx, mtmp->my); pline("Boing!"); - /* 3.7: used to 'break' to avoid setting learn_it here */ + /* 5.0: used to 'break' to avoid setting learn_it here */ } else if (u.uswallow || rnd(20) < 10 + find_mac(mtmp)) { if (disguised_mimic) seemimic(mtmp); @@ -892,6 +892,10 @@ revive(struct obj *corpse, boolean by_hero) mmflags_nht mmflags = NO_MINVENT | MM_NOWAIT | MM_NOMSG; int montype, cgend, container_nesting = 0; boolean is_zomb; + /* normally use the name on the corpse object, but don't if drawing a + * player's ghost back into its body, in which case use the ghost's + * (player's) name */ + boolean use_corpse_name = TRUE; if (corpse->otyp != CORPSE) { impossible("Attempting to revive %s?", xname(corpse)); @@ -1085,6 +1089,16 @@ revive(struct obj *corpse, boolean by_hero) mtmp->mtame = ghost->mtame; } } + /* copy over ghost's name and struct ebones to newly revived "hero"; + * has_mgivenname should always be true because there are guards + * against renaming a ghost, but check it just to be sure */ + if (has_mgivenname(ghost)) { + mtmp = christen_monst(mtmp, MGIVENNAME(ghost)); + /* don't let player-provided name of corpse override actual + * name of ex-hero */ + use_corpse_name = FALSE; + } + copy_mextra(mtmp, ghost); /* pass on struct ebones */ /* was ghost, now alive, it's all very confusing */ mtmp->mconf = 1; /* separate ghost monster no longer exists */ @@ -1094,7 +1108,7 @@ revive(struct obj *corpse, boolean by_hero) } /* monster retains its name */ - if (has_oname(corpse) && !unique_corpstat(mtmp->data)) + if (use_corpse_name && has_oname(corpse) && !unique_corpstat(mtmp->data)) mtmp = christen_monst(mtmp, ONAME(corpse)); /* partially eaten corpse yields wounded monster */ if (corpse->oeaten) @@ -1865,7 +1879,7 @@ poly_obj(struct obj *obj, int id) while (otmp->otyp == SPE_POLYMORPH) otmp->otyp = rnd_class(svb.bases[SPBOOK_CLASS], SPE_BLANK_PAPER); /* reduce spellbook abuse; non-blank books degrade; - 3.7: novels don't use spestudied so shouldn't degrade to blank + 5.0: novels don't use spestudied so shouldn't degrade to blank (but don't force spestudied to zero for them since a non-zero value could get passed along to a future polymorph) */ if (otmp->otyp != SPE_BLANK_PAPER && otmp->otyp != SPE_NOVEL) { @@ -2357,7 +2371,7 @@ bhito(struct obj *obj, struct obj *otmp) if (cansee(ox, oy)) { if (canspotmon(mtmp)) { pline("%s is resurrected!", - upstart(noname_monnam(mtmp, ARTICLE_THE))); + mtmp->mtame ? YMonnam(mtmp) : Monnam(mtmp)); learn_it = by_u ? TRUE : gz.zap_oseen; } else { /* saw corpse but don't see monster: maybe @@ -3572,7 +3586,7 @@ miss(const char *str, struct monst *mtmp) { pline("%s %s %s.", The(str), vtense(str, "miss"), ((cansee(gb.bhitpos.x, gb.bhitpos.y) || canspotmon(mtmp)) - && flags.verbose) ? mon_nam(mtmp) : "it"); + && flags.verbose) ? ((mtmp->mtame) ? noit_mon_nam(mtmp) : mon_nam(mtmp)) : "it"); } staticfn void @@ -4547,7 +4561,7 @@ zhitu( } /* - * 3.7: when fatal, this used to yield "Killed by ." without any + * 5.0: when fatal, this used to yield "Killed by ." without any * information about who was responsible. Now 'buzzer' is used to try * to supply "zapped/cast/breathed by [imitating ]." * diff --git a/submodules/CHKSUMS b/submodules/CHKSUMS index c40043d77..94f84cb0d 100644 --- a/submodules/CHKSUMS +++ b/submodules/CHKSUMS @@ -1,5 +1,5 @@ # checksums for fetched submodules -# NetHack 3.7 CHKSUMS $NHDT-Date: 1693155877 2023/08/27 17:04:37 $ $NHDT-Branch: keni-luacksum $ +# NetHack 5.0 CHKSUMS $NHDT-Date: 1693155877 2023/08/27 17:04:37 $ $NHDT-Branch: keni-luacksum $ # check: # shasum -a 256 -c -s THISFILE < FILETOCHECK # generate: diff --git a/sys/amiga/NHinfo.uu b/sys/amiga/NHinfo.uu new file mode 100644 index 000000000..4659aa02f --- /dev/null +++ b/sys/amiga/NHinfo.uu @@ -0,0 +1,11 @@ +begin 664 nethack.info +MXQ```0```````````"``(``$``,``0````$````````````````````````` +M`````P```````````````````````````````````(`````````@`"```@`` +M``$#````````````````````````````#___\`]P'O`/(`3P"0``D`D!D-`/ +M?_[P"!K\D`AJ_-`/'?[P#S?^\`\\_O`/;GSP#RN\\`^>_?`/AOGP#YOY\`Y) +M]O`,9>9P")?9,`F8N9`/G'G0"3[\4`A__A`/___P```````````````````` +M`````````````````````````@```0=0``R?`2`-_T`@!8&00`?]W@`.FMP@ +M#.K80`&=_@``M\H``+S:``'N<0``JYP``-[_```&^```.]P``.G=@`&UX,`# +GG_%@" +To play from Workbench, open the NetHack drawer and double-click the +nethack icon. -The directory should contain: - nethack - game binary - nhdat - data library - symbols - symbol set definitions - sysconf - system configuration - nethack.cnf - game options - hack.font - font descriptor - hack/8 - font bitmap (8pt) - tiles/tiles16.iff - 16-color tiles (OCS/ECS) - tiles/tiles32.iff - 32-color tiles (AGA/RTG) - tomb.iff - tombstone image - record - high score file +To play from a Shell: -To play: - cd NetHack: - nethack + Work:NetHack/nethack + +To redirect to a different install -- for example to test two versions +side by side -- set the NETHACKDIR (or HACKDIR) environment variable +before launching: + + setenv NETHACKDIR Work:games/nethack-dev/ + Work:games/nethack-dev/nethack Display Modes ------------- -Two display modes are available, selected in nethack.cnf: - - Text mode (AMII): - OPTIONS=symset:AmigaFont - - Tile mode (AMIV): - OPTIONS=windowtype:amiv +The shipped nethack.cnf selects tile mode (AMIV). AMIV needs a screen +with at least 4 bitplanes (16 colours) and ~384 KB free chip RAM; on +machines that don't qualify, the binary automatically falls back to +text mode (AMII) at startup with a short note explaining why. Tile mode auto-selects tiles32.iff (32 colors, 5 bitplanes) when the screen supports 32+ colors, otherwise tiles16.iff (16 colors, 4 planes). +To force text mode unconditionally, edit nethack.cnf: + + #OPTIONS=windowtype:amiv + OPTIONS=windowtype:amii + OPTIONS=symset:AmigaFont + Configuration ------------- -Edit nethack.cnf for game options. Key settings: +Edit nethack.cnf for game options. Defaults shipped: - OPTIONS=windowtype:amiv - tile graphics (default) - OPTIONS=symset:AmigaFont - text mode with line-drawing chars - OPTIONS=menucolors - colored inventory items - OPTIONS=time,lit_corridor - show turn count, lit corridors - OPTIONS=boulder:0 - display boulders as '0' + OPTIONS=windowtype:amiv - tile graphics + OPTIONS=number_pad:1 - numpad movement; '5' is run prefix + OPTIONS=time,showexp - turn count, experience visible + OPTIONS=lit_corridor - show lit corridors + OPTIONS=menucolors - colored inventory items -Menu color examples (add after OPTIONS=menucolors): - MENUCOLOR=" blessed "=green - MENUCOLOR=" cursed "=red - MENUCOLOR=" uncursed "=cyan +ALT+letter shortcuts to extended commands (ALT+L for #loot, ALT+F for +#force, etc.) are enabled by default. On keymaps that need ALT for +typing characters (Scandinavian, German, French, ...) disable with: + + OPTIONS=!altmeta + +Menu color examples (after OPTIONS=menucolors): + + MENUCOLOR=" blessed "=green + MENUCOLOR=" cursed "=red + MENUCOLOR=" uncursed "=cyan Building from Source @@ -71,26 +78,27 @@ Cross-compilation from Linux using bebbo's m68k-amigaos-gcc toolchain (https://franke.ms/git/bebbo/amiga-gcc): # Install toolchain to /opt/amiga - # Clone NetHack 3.7 source + # Clone NetHack 5.0 source cd NetHack - sys/unix/setup.sh sys/unix/hints/linux.370 + sys/unix/setup.sh sys/unix/hints/linux.500 make fetch-lua make CROSS_TO_AMIGA=1 fetch-regex make CROSS_TO_AMIGA=1 all make CROSS_TO_AMIGA=1 package -The distribution ZIP is created at targets/amiga/NH370AMI.ZIP. +The distribution ZIP is created at targets/amiga/NH500AMI.ZIP. Toolchain requirements: - - m68k-amigaos-gcc (bebbo's amigaos-cross-toolchain in /opt/amiga) - - -noixemul (libnix) for linking - - -m68000 for maximum compatibility (or -m68020/040/060) + + - m68k-amigaos-gcc (bebbo's amigaos-cross-toolchain in /opt/amiga) + - -noixemul (libnix) for linking + - -m68000 for maximum compatibility (or -m68020/040/060) Known Issues ------------ - - Native Amiga compilation (SAS/C, DICE) is not supported; - cross-compilation with GCC is required + - Native Amiga compilation (SAS/C, DICE) is not supported; + cross-compilation with GCC is required Credits @@ -103,5 +111,5 @@ Ken Lorber, and Gregg Wonderly are responsible for the 3.2 port. Janne Salmijärvi resurrected the Amiga port for 3.3 and Teemu Suikki joined before 3.4.0. -Updated for NetHack 3.7, cross compile fixes and 32 color tile support by Ingo +Updated for NetHack 5.0, cross compile fixes and 32 color tile support by Ingo Paschke in 2026. diff --git a/sys/amiga/amidos.c b/sys/amiga/amidos.c index 01d33343f..6aa0577fe 100644 --- a/sys/amiga/amidos.c +++ b/sys/amiga/amidos.c @@ -20,31 +20,33 @@ #undef COUNT -#if defined(__SASC_60) || defined(__GNUC__) #include #include -#endif /* POSIX stubs needed by libnix (-noixemul) */ #ifdef __noixemul__ int getpid(void) { return (int)FindTask(NULL); } #endif -#ifdef AZTEC_50 -#include -#undef strcmpi -#endif +/* Point NetHack: at the directory we were launched from. Works for both + CLI ("nethack") and Workbench (icon double-click) launches, since + GetProgramDir() (V37+) resolves both. Any existing assign is replaced; + it would just be stale state from a previous install or session. */ +void +amiga_self_assign(void) +{ + BPTR dup; -/* Prototypes */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/amiwind.p" -#include "NH:sys/amiga/winami.p" -#include "NH:sys/amiga/amidos.p" -#else -#include "amiwind.p" -#include "winami.p" -#include "amidos.p" -#endif + if (GetProgramDir() == 0) + return; + if ((dup = DupLock(GetProgramDir())) == 0) + return; + if (!AssignLock("NetHack", dup)) + UnLock(dup); +} + +#include "winext.h" +#include "winproto.h" extern char Initialized; @@ -52,9 +54,7 @@ extern struct window_procs amii_procs; struct ami_sysflags sysflags = {0}; FILE *fopenp(const char *, const char *); -#ifndef __SASC_60 int Enable_Abort = 0; /* for stdio package */ -#endif /* Initial path, so we can find NetHack.cnf */ char PATH[PATHLEN] = "NetHack:"; @@ -85,27 +85,6 @@ getlogin(void) /* abs() provided by libnix/stdlib */ -#ifdef SHELL -int -dosh(void) -{ - int i = 0; - char buf[BUFSZ]; - extern struct ExecBase *SysBase; - - /* Only under 2.0 and later ROMs do we have System() */ - if (SysBase->LibNode.lib_Version >= 37 && !amibbs) { - getlin("Enter CLI Command...", buf); - if (buf[0] != '\033') - i = System(buf, NULL); - } else { - i = 0; - pline("No mysterious force prevented you from using multitasking."); - } - return i; -} -#endif /* SHELL */ - #ifdef MFLOPPY #include @@ -125,15 +104,7 @@ dosh(void) long freediskspace(char *path) { -#ifdef UNTESTED - /* these changes from Patric Mueller for AROS to - * handle larger disks. Also needs limits.h and aros/oldprograms.h - * for AROS. (keni) - */ - unsigned long long freeBytes = 0; -#else long freeBytes = 0; -#endif struct InfoData *infoData; /* Remember... longword aligned */ char fileName[32]; @@ -175,11 +146,6 @@ freediskspace(char *path) infoData->id_NumBlocks - infoData->id_NumBlocksUsed; freeBytes -= (freeBytes + EXTENSION) / (EXTENSION + 1); freeBytes *= infoData->id_BytesPerBlock; -#ifdef UNTESTED - if (freeBytes > LONG_MAX) { - freeBytes = LONG_MAX; - } -#endif } if (freeBytes < 0) freeBytes = 0; @@ -210,74 +176,6 @@ filesize(char *file) return size; } -#if 0 -void -void -eraseall(const char *path, const char *files) -{ - BPTR dirLock, dirLock2; - struct FileInfoBlock *fibp; - int chklen; -#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) - if(files != g.alllevels)panic("eraseall"); -#endif - chklen=(int)index(files,'*')-(int)files; - - if (dirLock = Lock( (char *)path ,SHARED_LOCK)) { - dirLock2=DupLock(dirLock); - dirLock2= CurrentDir(dirLock2); - fibp=AllocMem(sizeof(struct FileInfoBlock),0); - if(fibp){ - if(Examine(dirLock,fibp)){ - while(ExNext(dirLock,fibp)){ - if(!strncmp(fibp->fib_FileName,files,chklen)){ - DeleteFile(fibp->fib_FileName); - } - } - } - FreeMem(fibp,sizeof(struct FileInfoBlock)); - } - UnLock(dirLock); - UnLock(CurrentDir(dirLock2)); - } -} -#endif - -/* This size makes that most files can be copied with two Read()/Write()s */ - -#if 0 /* Unused */ -#define COPYSIZE 4096 - -char *CopyFile(const char *from, const char *to) -{ - BPTR fromFile, toFile; - char *buffer; - long size; - char *error = NULL; - - buffer = (char *) alloc(COPYSIZE); - if (fromFile = Open( (char *)from, MODE_OLDFILE)) { - if (toFile = Open( (char *)to, MODE_NEWFILE)) { - while (size = Read(fromFile, buffer, (long)COPYSIZE)) { - if (size == -1){ - error = "Read error"; - break; - } - if (size != Write(toFile, buffer, size)) { - error = "Write error"; - break; - } - } - Close(toFile); - } else - error = "Cannot open destination"; - Close(fromFile); - } else - error = "Cannot open source (this should not occur)"; - free(buffer); - return error; -} -#endif #ifdef MFLOPPY /* this should be replaced */ @@ -415,12 +313,15 @@ fopenp(const char *name, const char *mode) while (pp && *pp) { bp = buf; while (*pp && *pp != PATHSEP) { - if (bp > buf + BUFSIZ - 1) + if (bp >= buf + BUFSIZ - 1) return (NULL); lastch = *bp++ = *pp++; } - if (lastch != ':' && lastch != '/' && bp != buf) + if (lastch != ':' && lastch != '/' && bp != buf) { + if (bp >= buf + BUFSIZ - 2) + return (NULL); *bp++ = '/'; + } if (bp + strlen(name) > buf + BUFSIZ - 1) return (NULL); strcpy(bp, name); diff --git a/sys/amiga/amidos.p b/sys/amiga/amidos.p deleted file mode 100644 index ed669f563..000000000 --- a/sys/amiga/amidos.p +++ /dev/null @@ -1,42 +0,0 @@ -/* NetHack 3.6 amidos.p $NHDT-Date: 1432512796 2015/05/25 00:13:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1992, 1993. */ -/* NetHack may be freely redistributed. See license for details. */ - -/* amidos.c */ -void flushout (void); -#ifndef getuid -int getuid (void); -#endif -#ifndef getpid -int getpid (void); -#endif -#ifndef getlogin -char *getlogin (void); -#endif -#ifndef abs -int abs(int ); -#endif -int tgetch (void); -int dosh (void); -long freediskspace(char *); -long filesize(char *); -void eraseall(const char * , const char *); -char *CopyFile(const char * , const char *); -void copybones(int ); -void playwoRAMdisk (void); -int saveDiskPrompt(int ); -void gameDiskPrompt (void); -void append_slash(char *); -void getreturn(const char *); -#ifndef msmsg -void msmsg( const char *, ... ); -#endif -#if !defined(__SASC_60) && !defined(_DCC) && !defined(CROSS_TO_AMIGA) -int chdir(char *); -#endif -#ifndef strcmpi -int strcmpi(char * , char *); -#endif -#if !defined(memcmp) && !defined(AZTEC_C) && !defined(_DCC) && !defined(__GNUC__) -int memcmp(unsigned char * , unsigned char * , int ); -#endif diff --git a/sys/amiga/amigst.c b/sys/amiga/amigst.c deleted file mode 100644 index 8f6a74f64..000000000 --- a/sys/amiga/amigst.c +++ /dev/null @@ -1,49 +0,0 @@ -/* NetHack 3.6 amigst.c $NHDT-Date: 1432512794 2015/05/25 00:13:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */ -/* NetHack may be freely redistributed. See license for details. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#undef strcmpi -#include -#include - -#ifdef __SASC -#include /* for __emit */ -#include -#include -#include -#include -#include -#include -#include -#endif - -#include "hack.h" -#include "winprocs.h" -#include "winami.h" - -#ifdef AZTEC -#include -#endif - -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/winami.p" -#include "NH:sys/amiga/amiwind.p" -#include "NH:sys/amiga/amidos.p" -#else -#include "winami.p" -#include "amiwind.p" -#include "amidos.p" -#endif - -/* end amigst.c */ diff --git a/sys/amiga/amii.hlp b/sys/amiga/amii.hlp index 88716f05e..6139b29ff 100644 --- a/sys/amiga/amii.hlp +++ b/sys/amiga/amii.hlp @@ -1,31 +1,67 @@ - Amiga-specific help file for NetHack 3.6 + Amiga-specific help for NetHack 5.0 -The Amiga port of NetHack supports a number of additional commands -and facilities specific to the Amiga. Listed below are the things -which are either specific to the Amiga port or might not appear -in other ports. -While playing NetHack you can press: +Special key combinations +------------------------ + ALT-HELP Edit the screen colour palette. + CTL-HELP Set tile scaling and clipping (amiv only). + SHIFT-HELP Toggle the dungeon overview window (amiv only). - ALT-HELP Color requestor. - CTL-HELP Scale display (amitile only). - SHIFT-HELP Overview window (amitile only). -Amiga-specific run-time options: - altmeta use the alt keys as meta keys - flush throw away keyboard type-ahead +Command-line flags +------------------ + -L Force interlaced (tall) screen. + -l Force non-interlaced screen. + -uNAME Play as NAME (e.g. -uwizard for wizard mode). + -pCLASS Pick a profession (e.g. -pvalkyrie). + -rRACE Pick a race. -Command line options recognized are +Wizard/debug mode is gated on the player name matching WIZARD_NAME +("wizard" by default), so the simplest way in is -uwizard. - -n No News at game startup. - -X Play in discovery mode. - -D Play in debug mode. - -L Interlaced screen. - -l Never Interlaced screen. - -u Play as player given as - an argument. - -r Pick a race given as an - argument. - -p Pick a profession given - as an argument - -? Gives command line usage. + +Configuration (nethack.cnf in the NetHack: drawer) +-------------------------------------------------- +Window backend selection: + + OPTIONS=windowtype:amiv tile graphics (default) + OPTIONS=windowtype:amii text/character mode + +Amiga-specific runtime options: + + OPTIONS=altmeta ALT+letter sends META+letter (default on). + Disable with !altmeta if your keymap needs + ALT for typing accented characters. + OPTIONS=flush drop any keys queued during long operations + OPTIONS=asksavedisk prompt for a save-disk before saving + (MFLOPPY only) + + +File-location overrides +----------------------- +NetHack: is automatically assigned to the directory the executable was +launched from. All game files default to that volume. Override any of +these in nethack.cnf to relocate parts of the game state: + + HACKDIR=NetHack: program / shared data + LEVELDIR=NetHack: per-level files during play + SAVEDIR=NetHack:save/ save files + BONESDIR=NetHack:bones/ bones files (shared between games) + DATADIR=NetHack: nhdat and other data files + SCOREDIR=NetHack: record / logfile + LOCKDIR=NetHack: lock files + CONFIGDIR=NetHack: per-user config + +You can also override the install path entirely without editing the cnf +by setting the NETHACKDIR or HACKDIR shell environment variable before +launching: + + setenv NETHACKDIR Work:games/nethack-dev/ + Work:games/nethack-dev/nethack + + +Display fallback +---------------- +Tile mode (amiv) requires at least 16 colours and ~384 KB free chip +RAM. If neither is available the game falls back to text mode (amii) +at startup with a one-line note. diff --git a/sys/amiga/amirip.c b/sys/amiga/amirip.c index 5f4aa52af..5ccb9aac1 100644 --- a/sys/amiga/amirip.c +++ b/sys/amiga/amirip.c @@ -28,20 +28,10 @@ static struct RastPort *rp; #undef NULL #define NULL 0 -#ifdef AZTEC_C -#include -#else -#ifdef _DCC -#include -#include -#include -#include -#else #include #include #include #include -#endif static BitMapHeader tomb_bmhd; static struct BitMap *tombimg = NULL; @@ -58,14 +48,8 @@ static int xoff, yoff; /* image centering */ #undef red #undef green #undef blue -#ifdef _DCC -#include -#include -#else #include #include -#endif -#endif /* AZTEC_C */ static struct Window *ripwin = 0; static void tomb_text(char *); @@ -97,7 +81,7 @@ static struct NewWindow newwin = { 0, 0, 640, 200, 1, 0, int wh; /* was local in outrip, but needed for SCALE macro */ -int cmap_white, cmap_black; +int cmap_outline, cmap_fill; void amii_outrip(winid tmpwin, int how, time_t when) @@ -115,6 +99,16 @@ amii_outrip(winid tmpwin, int how, time_t when) if (!WINVERS_AMIV || HackScreen->RastPort.BitMap->Depth < 4) goto cleanup; + /* The graphical tombstone uses raw chipset-style palette twiddling + * (LoadRGB4, transpalette fade) and BltBitMap to a SMART_REFRESH + * window. That works on the native chipset and AGA, but on RTG + * setups (Picasso96, CyberGraphX) the visible display is decoupled + * from the chipset registers and the tombstone never appears. + * Detect RTG by screen size beyond what chipset modes can reach + * and fall through to the plain ASCII tombstone instead. */ + if (HackScreen->Width > 800 || HackScreen->Height > 600) + goto cleanup; + /* Use the users display size */ newwin.Height = amiIDisplay->ypix - newwin.TopEdge; newwin.Width = amiIDisplay->xpix; @@ -148,11 +142,11 @@ amii_outrip(winid tmpwin, int how, time_t when) for (i = 0; i < SIZE(cols); i++) cols[i] = cols_base[i] + xoff; - cmap_white = search_cmap(0, 0, 0); - cmap_black = search_cmap(15, 15, 15); + cmap_outline = search_cmap(0, 0, 0); + cmap_fill = search_cmap(15, 15, 15); - BltBitMap(tombimg, 0, 0, rp->BitMap, xoff, yoff, tomb_bmhd.w, tomb_bmhd.h, - 0xc0, 0xff, NULL); + BltBitMapRastPort(tombimg, 0, 0, rp, xoff, yoff, + tomb_bmhd.w, tomb_bmhd.h, 0xc0); /* Put together death description */ formatkiller(buf, sizeof buf, how, FALSE); @@ -270,8 +264,8 @@ cleanup: Forbid(); while (imsg = (struct IntuiMessage *) GetMsg(ripwin->UserPort)) ReplyMsg((struct Message *) imsg); - CloseWindow(ripwin); Permit(); + CloseWindow(ripwin); } LoadRGB4(&HackScreen->ViewPort, sysflags.amii_curmap, amii_numcolors); @@ -295,23 +289,23 @@ tomb_text(char *p) sprintf(buf, " %s ", p); l = TextLength(rp, buf, strlen(buf)); - SetAPen(rp, cmap_white); + SetAPen(rp, cmap_outline); Move(rp, cols[cno] - (l / 2) - 1, tomb_line); Text(rp, buf, strlen(buf)); - SetAPen(rp, cmap_white); + SetAPen(rp, cmap_outline); Move(rp, cols[cno] - (l / 2) + 1, tomb_line); Text(rp, buf, strlen(buf)); - SetAPen(rp, cmap_white); + SetAPen(rp, cmap_outline); Move(rp, cols[cno] - (l / 2), tomb_line - 1); Text(rp, buf, strlen(buf)); - SetAPen(rp, cmap_white); + SetAPen(rp, cmap_outline); Move(rp, cols[cno] - (l / 2), tomb_line + 1); Text(rp, buf, strlen(buf)); - SetAPen(rp, cmap_black); + SetAPen(rp, cmap_fill); Move(rp, cols[cno] - (l / 2), tomb_line); Text(rp, buf, strlen(buf)); } diff --git a/sys/amiga/amistack.c b/sys/amiga/amistack.c index e0ea10a7b..50abff355 100644 --- a/sys/amiga/amistack.c +++ b/sys/amiga/amistack.c @@ -1,27 +1,16 @@ /* NetHack 3.6 amistack.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ -/* Copyright (c) Janne Salmij�rvi, Tampere, Finland, 2000 */ +/* Copyright (c) Janne Salmijärvi, Tampere, Finland, 2000 */ /* NetHack may be freely redistributed. See license for details. */ /* * Increase stack size to allow deep recursions. + * NetHack 5.0 with Lua needs significantly more stack than 3.6. * - * Note: This is SAS/C specific, using other compiler probably - * requires another method for increasing stack. - * + * libnix needs __stkinit referenced to pull swapstack.o from libnix.a. */ -#ifdef __SASC_60 -#include -#endif - -/* - * Increase stack size to allow deep recursions. - * NetHack 3.7 with Lua needs significantly more stack than 3.6. - */ - -#ifdef __SASC_60 -long __stack = 256 * 1024; -#else -/* For GCC with -noixemul (libnix), __stack is also recognized */ unsigned long __stack = 256 * 1024; +#ifdef CROSS_TO_AMIGA +extern void __stkinit(void); +void *__nh_force_stkinit = __stkinit; #endif diff --git a/sys/amiga/amitty.c b/sys/amiga/amitty.c deleted file mode 100644 index 22036c8f5..000000000 --- a/sys/amiga/amitty.c +++ /dev/null @@ -1,85 +0,0 @@ -/* NetHack 3.6 amitty.c $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */ -/* NetHack may be freely redistributed. See license for details. */ - -/* TTY-specific code for the Amiga - * This is still experimental. - * Still to do: - * add real termcap handling - currently requires ANSI_DEFAULT - */ - -#include "hack.h" -#include "tcap.h" -#include -#include - -#ifdef _DCC -#define getch() getchar() -#endif -#ifdef __SASC_60 -#include -#endif - -void tty_change_color(void); -char *tty_get_color_string(void); - -int amibbs = 0; /* BBS mode */ -char bbs_id[80] = ""; /* BBS uid equivalent */ -long afh_in, afh_out; /* BBS mode Amiga filehandles */ - -#ifdef TTY_GRAPHICS - -void -settty(const char *s) -{ - end_screen(); - if (s) - raw_print(s); - iflags.cbreak = ON; /* this is too easy: probably wrong */ -#if 1 /* should be version>=36 */ - /* if(IsInteractive(afh_in)){ */ - SetMode(afh_in, 0); /* con mode */ -/* } */ -#endif -} -void -gettty() -{ -#if 1 /* should be VERSION >=36 */ - /* if(IsInteractive(afh_in)){ */ - SetMode(afh_in, 1); /* raw mode */ -/* } */ -#endif -} -void -setftty() -{ - iflags.cbreak = ON; /* ditto */ -} -char kill_char = 'X' - '@'; -char erase_char = '\b'; -int -tgetch(void) -{ - unsigned char x; - Read(afh_in, &x, 1); - return (x == '\r') ? '\n' : x; -} -void -get_scr_size() -{ - CO = 80; - LI = 24; -} - -#endif - -void -tty_change_color() -{ -} -char * -tty_get_color_string() -{ - return (""); -} diff --git a/sys/amiga/amiwind.c b/sys/amiga/amiwind.c index d931697b7..c3c1b3394 100644 --- a/sys/amiga/amiwind.c +++ b/sys/amiga/amiwind.c @@ -3,15 +3,9 @@ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif /* Have to undef CLOSE as display.h and intuition.h both use it */ #undef CLOSE @@ -23,9 +17,10 @@ static struct Message *GetFMsg(struct MsgPort *); #endif static int BufferGetchar(void); -static void ProcessMessage(struct IntuiMessage *message); +void ProcessMessage(struct IntuiMessage *message); -#define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch)) +#define BufferQueueChar(ch) \ + do { if (KbdBuffered < KBDBUFFER) KbdBuffer[KbdBuffered++] = (ch); } while (0) struct Device *ConsoleDevice = NULL; @@ -38,11 +33,7 @@ struct Library *GadToolsBase = NULL; struct Library *LayersBase = NULL; struct Library *AslBase = NULL; -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/amimenu.c" -#else #include "amimenu.c" -#endif /* Now our own variables */ @@ -61,7 +52,7 @@ struct Library *DiskfontBase; #define KBDBUFFER 10 static unsigned char KbdBuffer[KBDBUFFER]; -unsigned char KbdBuffered; +int KbdBuffered; #ifdef HACKFONT @@ -69,15 +60,17 @@ struct TextFont *TextsFont = NULL; struct TextFont *HackFont = NULL; struct TextFont *RogueFont = NULL; -UBYTE FontName[] = "NetHack:hack.font"; -/* # chars in "NetHack:": */ -#define SIZEOF_DISKNAME 8 +/* hack.font is registered via NetHack:hack.font (which references + * NetHack:hack/8). OpenFont()/SetFont() take the bare name; only + * OpenDiskFont() needs the full path. */ +UBYTE HackFontName[] = "hack.font"; +UBYTE HackFontPath[] = "NetHack:hack.font"; #endif struct TextAttr Hack80 = { #ifdef HACKFONT - &FontName[SIZEOF_DISKNAME], + HackFontName, #else (UBYTE *) "topaz.font", #endif @@ -328,9 +321,6 @@ ConvertKey(struct IntuiMessage *message) got = 0; break; } -#ifdef OPT_DISPMAP - dispmap_sanity(); -#endif if (got) { CO = (w->Width - w->BorderLeft - w->BorderRight) / mxsize; @@ -365,7 +355,7 @@ ConvertKey(struct IntuiMessage *message) * ahead of input demands, when the user types ahead. */ -static void +void ProcessMessage(struct IntuiMessage *message) { int c; @@ -620,17 +610,16 @@ amii_cleanup(void) Forbid(); while (msg = (struct IntuiMessage *) GetMsg(HackPort)) ReplyMsg((struct Message *) msg); + Permit(); kill_nhwindows(1); DeleteMsgPort(HackPort); HackPort = NULL; - Permit(); } /* Close the screen, under v37 or greater it is a pub screen and there may * be visitors, so check close status and wait till everyone is gone. */ if (HackScreen) { -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { if (MenuStrip) FreeMenus(MenuStrip); @@ -643,9 +632,7 @@ amii_cleanup(void) }; EasyRequest(NULL, &easy, NULL, NULL); } - } else -#endif - { + } else { CloseScreen(HackScreen); } HackScreen = NULL; @@ -693,13 +680,6 @@ amii_cleanup(void) IntuitionBase = NULL; } -#ifdef SHAREDLIB - if (DOSBase) { - CloseLibrary((struct Library *) DOSBase); - DOSBase = NULL; - } -#endif - ((struct Process *) FindTask(NULL))->pr_WindowPtr = (APTR) pr_WindowPtr; Initialized = 0; @@ -707,11 +687,9 @@ amii_cleanup(void) #endif /* AMII_GRAPHICS */ -#ifndef SHAREDLIB void Abort(long rc) { - int fault = 1; #ifdef CHDIR extern char orgdir[]; chdir(orgdir); @@ -724,38 +702,11 @@ Abort(long rc) } else #endif printf("\n\nAbort with alert code %08lx...\n", rc); -/* Alert(rc); this is too severe */ -#ifdef __SASC -#ifdef INTUI_NEW_LOOK - if (IntuitionBase->LibNode.lib_Version >= 37) { - struct EasyStruct es = { - sizeof(struct EasyStruct), 0, "NetHack Panic Request", - "NetHack is Aborting with code == 0x%08lx", - "Continue Abort|Return to Program|Clean up and exit", - }; - fault = EasyRequest(NULL, &es, NULL, (long) rc); - if (fault == 2) - return; - } -#endif - if (fault == 1) { - /* __emit(0x4afc); */ /* illegal instruction */ - __emit(0x40fc); /* divide by */ - __emit(0x0000); /* #0 */ - /* NOTE: don't move amii_cleanup() above here - */ - /* it is too likely to kill the system */ - /* before it can get the SnapShot out, if */ - /* there is something really wrong. */ - } -#endif #ifdef AMII_GRAPHICS if (windowprocs.win_init_nhwindows == amii_procs.win_init_nhwindows) amii_cleanup(); #endif #undef exit -#ifdef AZTEC_C - _abort(); -#endif exit((int) rc); } @@ -764,7 +715,6 @@ CleanUp(void) { amii_cleanup(); } -#endif #ifdef AMII_GRAPHICS @@ -880,7 +830,6 @@ amii_number_pad(int state) } #endif /* AMII_GRAPHICS */ -#ifndef SHAREDLIB void amiv_loadlib(void) { @@ -910,4 +859,3 @@ VA_DECL(const char *, s) VA_END(); Abort(0L); } -#endif diff --git a/sys/amiga/amiwind.p b/sys/amiga/amiwind.p deleted file mode 100644 index 762646dc2..000000000 --- a/sys/amiga/amiwind.p +++ /dev/null @@ -1,40 +0,0 @@ -/* NetHack 3.6 amiwind.p $NHDT-Date: 1432512795 2015/05/25 00:13:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.6 $ */ -/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */ -/* NetHack may be freely redistributed. See license for details. */ - -/* amiwind.c */ -#ifdef INTUI_NEW_LOOK -struct Window * OpenShWindow(struct ExtNewWindow *) ; -#else -struct Window * OpenShWindow(struct NewWindow *) ; -#endif -void CloseShWindow(struct Window *); -int kbhit (void); -int amikbhit (void); -int WindowGetchar (void); -WETYPE WindowGetevent (void); -void WindowFlush (void); -void WindowPutchar(char ); -void WindowFPuts(const char *); -void WindowPuts(const char *); -void WindowPrintf( char *,... ); -void CleanUp (void); -int ConvertKey( struct IntuiMessage * ); -#ifndef SHAREDLIB -void Abort(long ); -#endif -void flush_glyph_buffer(struct Window *); -void amiga_print_glyph(winid , int , int ); -void start_glyphout(winid ); -void amii_end_glyphout(winid ); -#ifdef INTUI_NEW_LOOK -struct ExtNewWindow * DupNewWindow(struct ExtNewWindow *); -void FreeNewWindow(struct ExtNewWindow *); -#else -struct NewWindow * DupNewWindow(struct NewWindow *); -void FreeNewWindow(struct NewWindow *); -#endif -void bell (void); -void amii_delay_output (void); -void amii_number_pad(int ); -void amii_cleanup( void ); diff --git a/sys/amiga/bmp2iff_host.c b/sys/amiga/bmp2iff_host.c index 154335297..1182aa732 100644 --- a/sys/amiga/bmp2iff_host.c +++ b/sys/amiga/bmp2iff_host.c @@ -65,6 +65,41 @@ static const RGB amiv_pal[16] = { {0xFF,0xBB,0x99}, /* 15 peach */ }; +/* --------------------------------------------------------- */ +/* Little-endian readers (BMP is LE regardless of host) */ +/* --------------------------------------------------------- */ + +static int +read_u16le(FILE *fp, uint16_t *out) +{ + int lo = fgetc(fp), hi = fgetc(fp); + if (hi == EOF) return 0; + *out = (uint16_t)(((unsigned) hi << 8) | (unsigned) lo); + return 1; +} + +static int +read_u32le(FILE *fp, uint32_t *out) +{ + int b0 = fgetc(fp), b1 = fgetc(fp); + int b2 = fgetc(fp), b3 = fgetc(fp); + if (b3 == EOF) return 0; + *out = ((uint32_t)(unsigned) b3 << 24) + | ((uint32_t)(unsigned) b2 << 16) + | ((uint32_t)(unsigned) b1 << 8) + | (uint32_t)(unsigned) b0; + return 1; +} + +static int +read_i32le(FILE *fp, int32_t *out) +{ + uint32_t v; + if (!read_u32le(fp, &v)) return 0; + *out = (int32_t) v; + return 1; +} + /* --------------------------------------------------------- */ /* Colour helpers */ /* --------------------------------------------------------- */ @@ -345,7 +380,7 @@ main(int argc, char **argv) int nplanes, maxcol; int i, y; RGB outpal[256]; - int remap[256]; + int remap[256] = {0}; uint8_t *remapped; uint8_t *plane_data[8]; uint8_t cmap_rgb[256 * 3]; @@ -370,8 +405,22 @@ main(int argc, char **argv) bmpfp = fopen(argv[3], "rb"); if (!bmpfp) { perror(argv[3]); return 1; } - if (fread(&fhdr, sizeof(fhdr), 1, bmpfp) != 1 - || fread(&ihdr, sizeof(ihdr), 1, bmpfp) != 1) { + if (!read_u16le(bmpfp, &fhdr.bfType) + || !read_u32le(bmpfp, &fhdr.bfSize) + || !read_u16le(bmpfp, &fhdr.bfReserved1) + || !read_u16le(bmpfp, &fhdr.bfReserved2) + || !read_u32le(bmpfp, &fhdr.bfOffBits) + || !read_u32le(bmpfp, &ihdr.biSize) + || !read_i32le(bmpfp, &ihdr.biWidth) + || !read_i32le(bmpfp, &ihdr.biHeight) + || !read_u16le(bmpfp, &ihdr.biPlanes) + || !read_u16le(bmpfp, &ihdr.biBitCount) + || !read_u32le(bmpfp, &ihdr.biCompression) + || !read_u32le(bmpfp, &ihdr.biSizeImage) + || !read_i32le(bmpfp, &ihdr.biXPelsPerMeter) + || !read_i32le(bmpfp, &ihdr.biYPelsPerMeter) + || !read_u32le(bmpfp, &ihdr.biClrUsed) + || !read_u32le(bmpfp, &ihdr.biClrImportant)) { fprintf(stderr, "Failed to read BMP header\n"); return 1; } @@ -388,6 +437,11 @@ main(int argc, char **argv) img_w = ihdr.biWidth; img_h = abs(ihdr.biHeight); + if (img_w <= 0 || img_w > 16384 || img_h <= 0 || img_h > 16384) { + fprintf(stderr, "BMP dimensions out of range: %dx%d\n", + img_w, img_h); + return 1; + } ncolors = ihdr.biClrUsed ? ihdr.biClrUsed : 256; if (ncolors > 256) ncolors = 256; @@ -409,16 +463,27 @@ main(int argc, char **argv) /* read pixel data */ rowstride = (img_w + 3) & ~3; bmpdata = malloc(rowstride * img_h); + if (!bmpdata) { + fprintf(stderr, "malloc failure on bmpdata\n"); + return 1; + } fseek(bmpfp, fhdr.bfOffBits, SEEK_SET); if (fread(bmpdata, 1, rowstride * img_h, bmpfp) != (size_t)(rowstride * img_h)) { fprintf(stderr, "Failed to read pixel data\n"); + free(bmpdata); + fclose(bmpfp); return 1; } fclose(bmpfp); /* flip bottom-up to top-down */ pixels = malloc(img_w * img_h); + if (!pixels) { + fprintf(stderr, "malloc failure on pixels\n"); + free(bmpdata); + return 1; + } if (ihdr.biHeight > 0) { for (y = 0; y < img_h; y++) memcpy(pixels + y * img_w, @@ -441,13 +506,22 @@ main(int argc, char **argv) maxcol, outpal, remap); remapped = malloc(img_w * img_h); + if (!remapped) { + fprintf(stderr, "malloc failure on remapped\n"); + return 1; + } for (i = 0; i < img_w * img_h; i++) remapped[i] = (uint8_t)remap[pixels[i]]; /* convert to bitplanes */ planesize = (img_w / 8) * img_h; - for (i = 0; i < nplanes; i++) + for (i = 0; i < nplanes; i++) { plane_data[i] = calloc(1, planesize); + if (!plane_data[i]) { + fprintf(stderr, "calloc failure for plane %d\n", i); + return 1; + } + } to_planes(remapped, img_w, img_h, nplanes, plane_data); diff --git a/sys/amiga/clipwin.c b/sys/amiga/clipwin.c index f2d38ce64..6277b6b60 100644 --- a/sys/amiga/clipwin.c +++ b/sys/amiga/clipwin.c @@ -197,7 +197,7 @@ static struct Gadget ClipXSIZE = { static struct PropInfo ClipClipYSIZESInfo = { AUTOKNOB + FREEHORIZ, /* PropInfo flags */ - -25937, -1, /* horizontal and vertical pot values */ + 39599, -1, /* horizontal and vertical pot values */ 10922, -1, /* horizontal and vertical body values */ }; diff --git a/sys/amiga/cnf-info.uu b/sys/amiga/cnf-info.uu new file mode 100644 index 000000000..f9b9f0887 --- /dev/null +++ b/sys/amiga/cnf-info.uu @@ -0,0 +1,23 @@ +begin 644 nethack.cnf.info +MXQ```0``````(``4`!X`'@`&``$``0?Z<1@'^I$H```````````````````` +M```!!``'^J`!X``T`) +M2*@'``````````````````````@'^``(````"`?`>`@````(!^``"`````@' +MP``(````"`>`?@@````(`^``"`````@!_^`(````"`'_``@````(`?Y_"``` +M``@`__`(````"`#\``@````8`WP7___T'^UO_!?___0?Z__\%___]!_ +MO_?P7___T'____!?___0?___\%___^!__]>`7___P'___P@@```0`````/__ +M__"````(H```((%```"@```@@@`2`*```""`@```H```((!*@`"@```@@)(` +M`*```""`4A(`H```((!*0`"@```@@%```*```""`0`@`H```((````"@```@ +M@````*```!"``"APH```((```(`````(`````````!)$2#`Z5&]O;',O161I +.=%!A9``````(`````0`` +` +end diff --git a/sys/amiga/drawer-info.uu b/sys/amiga/drawer-info.uu new file mode 100644 index 000000000..cddf5a258 --- /dev/null +++ b/sys/amiga/drawer-info.uu @@ -0,0 +1,17 @@ +begin 644 NetHack.info +MXQ```0`````!HP`/`#D`#@`&``$``0`SE&``-K,H```````````````````` +M```!`@```````````(````"``````#!?4````````!```+@`30%R`$K__P`` +M```"`!!_`#:X9@``````+N.D````````````7@!!_____P`!```````````` +M`````#D`#@`"``%O4`,`````````````````#_______Y``,```````$``@` +M`````"0`"``)_R``)``(``G5(``D``@`"``@`"0`"``'_\``)``(```````D +M``G______^0`````````!``/_______\```````````````````````_____ +M___X`#```````!@`,_______^``W_______8`#?_]@#?_]@`-__V*M__V``W +M__?_W__8`#?_^``__]@`-_______V``V```````8`#________@````````` +M```````````````````````````````Y``X``@`!<#`#```````````````` +M``_______^0`&JJJJJJJM``U5555555<`'________P`0```````!`!````` +M```&`$``"?\@``8`0``)U2``!H!```@`(``&@$``!__```:`0```````!H!_ +M_______^@`*JJJJJJJJ`/_______^``P```````8`"*JJJJJJJ@`!5555555 +M4````````````#________@`/_______^``___8`W__X`#__]BK?__@`/__W +K_]__^``___@`/__X`#________@```````````````````````````$````` +` +end diff --git a/sys/amiga/license-info.uu b/sys/amiga/license-info.uu new file mode 100644 index 000000000..398d9aed5 --- /dev/null +++ b/sys/amiga/license-info.uu @@ -0,0 +1,23 @@ +begin 644 license.info +MXQ```0``````(``4`!X`'@`&``$``0?ZD2@'^J`!X``T`) +M1X`'``````````````````````@'^``(````"`?`>`@````(!^``"`````@' +MP``(````"`>`?@@````(`^``"`````@!_^`(````"`'_``@````(`?Y_"``` +M``@`__`(````"`#\``@````8`WP7___T'^UO_!?___0?Z__\%___]!_ +MO_?P7___T'____!?___0?___\%___^!__]>`7___P'___P@@```0`````/__ +M__"````(H```((%```"@```@@@`2`*```""`@```H```((!*@`"@```@@)(` +M`*```""`4A(`H```((!*0`"@```@@%```*```""`0`@`H```((````"@```@ +M@````*```!"``"APH```((```(`````(`````````!)$2#`Z5&]O;',O161I +.=%!A9``````(`````0`` +` +end diff --git a/sys/amiga/nethack.cnf b/sys/amiga/nethack.cnf index dad37d4d5..b9083d935 100644 --- a/sys/amiga/nethack.cnf +++ b/sys/amiga/nethack.cnf @@ -1,11 +1,14 @@ -# NetHack 3.7 Amiga Configuration +# NetHack 5.0 Amiga Configuration # # For a full list of options, see the opthelp file or press '?' # then 'o' during gameplay. # *** DISPLAY MODE *** # -# Tile mode (graphical tiles, recommended): +# Tile mode (graphical tiles, recommended). Needs >=384 KB free chip +# RAM and a display mode that can open at 4 bitplanes (16 colours); on +# machines that can't, NetHack will automatically fall back to text +# mode at startup. OPTIONS=windowtype:amiv # # Text mode (uses hack.font line-drawing characters): @@ -17,6 +20,8 @@ OPTIONS=time,showexp,lit_corridor OPTIONS=boulder:0 OPTIONS=autopickup,pickup_types:$"=/!?+ OPTIONS=catname:Kaori +# Numpad for movement; '5' is the run prefix, ALT+5 the rush prefix. +OPTIONS=number_pad:1 # *** MENU COLORS *** # Colour-code inventory items by BUC status and value. @@ -42,3 +47,17 @@ MENUCOLOR="gray dragon scale"=cyan MENUCOLOR="speed boots"=magenta MENUCOLOR="luckstone"=green MENUCOLOR="unicorn horn"=green + +# *** FILE LOCATIONS *** +# NetHack: is auto-assigned to the directory the binary was launched +# from, so all game files default there. Uncomment any of these to +# relocate part of the game state to a different volume or subdir. +# +#HACKDIR=NetHack: +#LEVELDIR=NetHack: +#SAVEDIR=NetHack:save/ +#BONESDIR=NetHack:bones/ +#DATADIR=NetHack: +#SCOREDIR=NetHack: +#LOCKDIR=NetHack: +#CONFIGDIR=NetHack: diff --git a/sys/amiga/readme-info.uu b/sys/amiga/readme-info.uu new file mode 100644 index 000000000..9b819be15 --- /dev/null +++ b/sys/amiga/readme-info.uu @@ -0,0 +1,35 @@ +begin 644 README.amiga.info +MXQ```0``````#P!(`"<`(P`&``$``4`&_1A`!QW@```````````````````` +M```!!`!`!QWX!X8V<(````"``````````````````!`````````G`",``T`' +M(S`'```````````$```````%````'``$@```.``$0```\``$(```8``$$``` +M0``'^``````![```````#@`!___`!@``````!@`!____A@`0````!@`!___^ +M!@``````!@`!_\``!@``````!@``````!@`!____A@``````!@`!___\!@`0 +M````!@`!____!@``````!@`!___P!@``````!@`!___^!@``````!@`````` +M!@`!_```!@``````!@``````!@``````!@#______@#______@#____X``#_ +M___[``#_[__[@`#_W__[P`#^/__[X`#_?__[\`#____[^`#____^"`#_____ +M\@#_I*J_^@#_____^@#_BPBB>@#O____^@#_(DBE^@#_____^@#_2G__^@#_ +M____^@#_____^@#_B2J*>@#_____^@#_(E$3^@#O____^@#_F15$^@#_____ +M^@#_(DBO^@#_____^@#_-(15^@#_____^@#_____^@#^D___^@#_____^@#_ +M____^@#_____^@```````@#______@`````&```````$@```&``$0```,``$ +M(``!X``$$```P``$"``````$```````!\```````"```6U5````````````` +M=/==@```````````W;=:````````````M8``````````````````````=M5U +M@```````````W:[L````````````9NJ[````````````W;=0```````````` +MRWNJ```````````````````!;`````````````````````````````"````` +M`````````````````"<`(P`#0`Z[``(```````(!NVZT``(`` +M`````(!:P````(```````(```````(`[:KK``(```````(!NUW8``(`````` +M`(`S=5V``(```````(!NVZ@``(```````(!EO=4``(```````(```````("V +M`````(```````(```````(```````,```````````!)365,Z5&]O;',O161I +.=%!A9``````(`````0`` +` +end diff --git a/sys/amiga/txt-info.uu b/sys/amiga/txt-info.uu new file mode 100644 index 000000000..d898dec9d --- /dev/null +++ b/sys/amiga/txt-info.uu @@ -0,0 +1,23 @@ +begin 644 nethack.txt.info +MXQ```0``````(``4`!X`'@`&``$``4`)%KA`"1E8```````````````````` +M```!!`!`"3\8!X9\*````+(````&`````````````"`````````>`!X``T`) +M1$`'``````````````````````@'^``(````"`?`>`@````(!^``"`````@' +MP``(````"`>`?@@````(`^``"`````@!_^`(````"`'_``@````(`?Y_"``` +M``@`__`(````"`#\``@````8`WP7___T'^UO_!?___0?Z__\%___]!_ +MO_?P7___T'____!?___0?___\%___^!__]>`7___P'___P@@```0`````/__ +M__"````(H```((%```"@```@@@`2`*```""`@```H```((!*@`"@```@@)(` +M`*```""`4A(`H```((!*0`"@```@@%```*```""`0`@`H```((````"@```@ +M@````*```!"``"APH```((```(`````(`````````!)$2#`Z5&]O;',O161I +.=%!A9``````(`````0`` +` +end diff --git a/sys/amiga/winamenu.c b/sys/amiga/winamenu.c index d391bdec4..7a9e404ed 100644 --- a/sys/amiga/winamenu.c +++ b/sys/amiga/winamenu.c @@ -3,15 +3,9 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif /* Start building the text for a menu */ void @@ -38,8 +32,7 @@ amii_start_menu(winid window, unsigned long mbehavior UNUSED) cw->data = NULL; } - for (mip = cw->menu.items, i = 0; - (mip = cw->menu.items) && i < cw->menu.count; ++i) { + while ((mip = cw->menu.items) != NULL) { cw->menu.items = mip->next; free(mip); } @@ -47,6 +40,7 @@ amii_start_menu(winid window, unsigned long mbehavior UNUSED) cw->menu.items = 0; cw->menu.count = 0; cw->menu.chr = 'a'; + cw->menu.has_glyphs = FALSE; if (cw->morestr) free(cw->morestr); @@ -85,6 +79,8 @@ amii_add_menu(winid window, const glyph_info *glyphinfo, const anything *id, mip->attr = attr; mip->color = clr; mip->glyph = Is_rogue_level(&u.uz) ? NO_GLYPH : (glyphinfo ? glyphinfo->glyph : NO_GLYPH); + if (mip->glyph != NO_GLYPH) + cw->menu.has_glyphs = TRUE; mip->selector = 0; mip->gselector = gch; mip->count = -1; @@ -152,11 +148,13 @@ amii_end_menu(winid window, const char *morestr) cw->menu.last->next = cw->menu.items; cw->menu.items = cw->menu.last; cw->menu.last = mip; - t = cw->data[cw->cury - 1]; - for (i = cw->cury - 1; i > 0; i--) { - cw->data[i] = cw->data[i - 1]; + if (cw->cury > 0) { + t = cw->data[cw->cury - 1]; + for (i = cw->cury - 1; i > 0; i--) { + cw->data[i] = cw->data[i - 1]; + } + cw->data[0] = t; } - cw->data[0] = t; #endif } @@ -193,6 +191,8 @@ amii_menu_item * find_menu_item(struct amii_WinDesc *cw, int idx) { amii_menu_item *mip; + if (idx < 0) + return NULL; for (mip = cw->menu.items; idx > 0 && mip; mip = mip->next) --idx; @@ -212,7 +212,7 @@ make_menu_items(struct amii_WinDesc *cw, menu_item **rmip) } if (idx) { - mmip = *rmip = (menu_item *) alloc(idx * sizeof(*mip)); + mmip = *rmip = (menu_item *) alloc(idx * sizeof(menu_item)); for (mip = cw->menu.items; mip; mip = mip->next) { if (mip->selected) { mmip->item = mip->identifier; @@ -255,12 +255,9 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) /* Initial guess at window sizing values */ txwd = txwidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) - txh = max(txheight, pictdata.ysize + 3); /* interline space */ - else - txh = txheight; /* interline space */ - } else + if (WINVERS_AMIV && cw->menu.has_glyphs) + txh = max(txheight, pictdata.ysize + 3); /* interline space */ + else txh = txheight; /* interline space */ /* Check to see if we should open the window, should need to for @@ -271,19 +268,15 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) topidx = 0; if (w == NULL) { -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { PropScroll.Flags |= PROPNEWLOOK; } -#endif nw = (void *) DupNewWindow((void *) (&new_wins[cw->type].newwin)); if (!alwaysinvent || win != WIN_INVEN) { xsize = scrn->WBorLeft + scrn->WBorRight + MenuScroll.Width + 1 + (txwd * cw->maxcol); - if (WINVERS_AMIV) { - if (win == WIN_INVEN) - xsize += pictdata.xsize + 4; - } + if (WINVERS_AMIV && cw->menu.has_glyphs) + xsize += pictdata.xsize + 4; if (xsize > amiIDisplay->xpix) xsize = amiIDisplay->xpix; @@ -322,7 +315,7 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) /* Make space for the glyph to appear at the left of the * description */ - if (WINVERS_AMIV) + if (WINVERS_AMIV && cw->menu.has_glyphs) xsize += pictdata.xsize + 4; if (xsize > amiIDisplay->xpix) @@ -346,7 +339,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) nw->Screen = HackScreen; if (win == WIN_INVEN) { - sprintf(title, "%s the %s's Inventory", svp.plname, svp.pl_character); + Snprintf(title, sizeof title, "%s the %s's Inventory", + svp.plname, svp.pl_character); nw->Title = title; if (lastinvent.MaxX != 0) { nw->LeftEdge = lastinvent.MinX; @@ -370,10 +364,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) } nw->Height = min(ysize, amiIDisplay->ypix - nw->TopEdge); - if (WINVERS_AMIV || WINVERS_AMII) { - /* Make sure we are using the correct hook structure */ - nw->Extension = cw->wintags; - } + /* Make sure we are using the correct hook structure */ + nw->Extension = cw->wintags; /* Now, open the window */ w = cw->win = OpenShWindow((void *) nw); @@ -394,52 +386,36 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) SetFont(w->RPort, HackFont); #endif txwd = w->RPort->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) - txh = max(w->RPort->TxHeight, - pictdata.ysize + 3); /* interline space */ - else - txh = w->RPort->TxHeight; /* interline space */ - } else + if (WINVERS_AMIV && cw->menu.has_glyphs) + txh = max(w->RPort->TxHeight, + pictdata.ysize + 3); /* interline space */ + else txh = w->RPort->TxHeight; /* interline space */ /* subtract 2 to account for spacing away from border (1 on each side) */ wheight = (w->Height - w->BorderTop - w->BorderBottom - 2) / txh; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else { - cw->cols = - (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; - } + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } totalvis = CountLines(win); } else { txwd = w->RPort->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) - txh = max(w->RPort->TxHeight, - pictdata.ysize + 3); /* interline space */ - else - txh = w->RPort->TxHeight; /* interline space */ - } else { + if (WINVERS_AMIV && cw->menu.has_glyphs) + txh = max(w->RPort->TxHeight, + pictdata.ysize + 3); /* interline space */ + else txh = w->RPort->TxHeight; /* interline space */ - } /* subtract 2 to account for spacing away from border (1 on each side) */ wheight = (w->Height - w->BorderTop - w->BorderBottom - 2) / txh; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else - cw->cols = - (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } @@ -465,13 +441,6 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) morc = 0; oidx = -1; -#if 0 - /* Make sure there are no selections left over from last time. */ -/* XXX potential problem for preselection if this is really needed */ - for( amip = cw->menu.items; amip; amip = amip->next ) - amip->selected = 0; -#endif - DisplayData(win, topidx); /* Make the prop gadget the right size and place */ @@ -498,11 +467,13 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) mx = imsg->MouseX; my = imsg->MouseY; - /* Only do our window or VANILLAKEY from other windows */ - + /* Only do our window or VANILLAKEY from other windows. + * Background events (NEWSIZE on inventory, CLOSEWINDOW + * on overview, etc.) get routed to the main dispatcher + * so the game stays in sync. ProcessMessage ReplyMsgs. */ if (imsg->IDCMPWindow != w && class != VANILLAKEY && class != RAWKEY) { - ReplyMsg((struct Message *) imsg); + ProcessMessage(imsg); continue; } @@ -551,13 +522,9 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) totalvis = CountLines(win); wheight = (w->Height - w->BorderTop - w->BorderBottom - 2) / txh; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - - 4 - pictdata.xsize - 3) / txwd; - } else - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; @@ -572,21 +539,19 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) * amii_cl_end if window shrinks and columns decrease. */ - if (WINVERS_AMII || WINVERS_AMIV) { - amii_setfillpens(w, cw->type); - SetDrMd(w->RPort, JAM2); - x2 = w->Width - w->BorderRight; - y2 = w->Height - w->BorderBottom; - x1 = x2 - w->IFont->tf_XSize - w->IFont->tf_XSize; - y1 = w->BorderTop; - if (x1 < w->BorderLeft) - x1 = w->BorderLeft; - RectFill(w->RPort, x1, y1, x2, y2); + amii_setfillpens(w, cw->type); + SetDrMd(w->RPort, JAM2); + x2 = w->Width - w->BorderRight; + y2 = w->Height - w->BorderBottom; + x1 = x2 - w->IFont->tf_XSize - w->IFont->tf_XSize; + y1 = w->BorderTop; + if (x1 < w->BorderLeft) x1 = w->BorderLeft; - y1 = y1 - w->IFont->tf_YSize; - RectFill(w->RPort, x1, y1, x2, y2); - RefreshWindowFrame(w); - } + RectFill(w->RPort, x1, y1, x2, y2); + x1 = w->BorderLeft; + y1 = y1 - w->IFont->tf_YSize; + RectFill(w->RPort, x1, y1, x2, y2); + RefreshWindowFrame(w); /* Make the prop gadget the right size and place */ @@ -645,7 +610,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) if (how == PICK_ANY) { amip = cw->menu.items; while (amip) { - if (amip->selected) { + if (amip->canselect && amip->selector + && amip->selected) { amip->selected = FALSE; amip->count = -1; amip->str[SOFF + 2] = '-'; @@ -777,8 +743,9 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) } else { reset_counting = TRUE; } - sprintf(countString, "Count: %d", count); - pline(countString); + Snprintf(countString, sizeof countString, + "Count: %ld", count); + pline("%s", countString); } } else if (code == CTRL('D') || code == CTRL('U') || code == MENU_NEXT_PAGE @@ -800,7 +767,7 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) if (code == MENU_FIRST_PAGE) { topidx = 0; } else if (code == MENU_LAST_PAGE) { - topidx = cw->maxrow - wheight; + topidx = max(0, cw->maxrow - wheight); } else for (i = 0; i < endcnt; ++i) { if (code == CTRL('D') || code == MENU_NEXT_PAGE) { @@ -890,6 +857,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) } else { int selected = FALSE; for (amip = cw->menu.items; amip; amip = amip->next) { + if (!amip->canselect) + continue; if (amip->selector == code) { if (how == PICK_ONE) aredone = 1; @@ -944,6 +913,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) aredone = 1; for (gd = w->FirstGadget; gd && gd->GadgetID != 1;) gd = gd->NextGadget; + if (!gd) + break; pip = (struct PropInfo *) gd->SpecialInfo; totalvis = CountLines(win); @@ -956,6 +927,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) case MOUSEMOVE: for (gd = w->FirstGadget; gd && gd->GadgetID != 1;) gd = gd->NextGadget; + if (!gd) + break; pip = (struct PropInfo *) gd->SpecialInfo; totalvis = CountLines(win); @@ -1004,8 +977,8 @@ DoMenuScroll(int win, int blocking, int how, menu_item **retmip) amip->str[SOFF + 2] = '-'; } } - if (counting && amip->selected && amip->canselect - && amip->selector) { + if (amip && counting && amip->selected + && amip->canselect && amip->selector) { amip->count = count; reset_counting = TRUE; amip->str[SOFF + 2] = '#'; @@ -1126,12 +1099,9 @@ FindLine(winid win, int line) panic(winpanicstr, win, "No Window in FindLine"); } txwd = w->RPort->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } @@ -1189,12 +1159,9 @@ CountLines(winid win) } txwd = w->RPort->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } @@ -1255,7 +1222,7 @@ DisplayData(winid win, int start) rp = w->RPort; SetDrMd(rp, JAM2); - if (WINVERS_AMIV && win == WIN_INVEN) { + if (WINVERS_AMIV && cw->menu.has_glyphs) { wheight = (w->Height - w->BorderTop - w->BorderBottom - 2) / max(rp->TxHeight, pictdata.ysize + 3); } else { @@ -1265,12 +1232,9 @@ DisplayData(winid win, int start) cw->rows = wheight; txwd = rp->TxWidth; - if (WINVERS_AMIV) { - if (win == WIN_INVEN) { - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 - - pictdata.xsize - 3) / txwd; - } else - cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; + if (WINVERS_AMIV && cw->menu.has_glyphs) { + cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4 + - pictdata.xsize - 3) / txwd; } else { cw->cols = (w->Width - w->BorderLeft - w->BorderRight - 4) / txwd; } @@ -1292,7 +1256,7 @@ DisplayData(winid win, int start) for (disprow = i = start; disprow < wheight + start; i++) { /* Just erase unused lines in the window */ if (i >= cw->maxrow) { - if (WINVERS_AMIV && win == WIN_INVEN) { + if (WINVERS_AMIV && cw->menu.has_glyphs) { amii_curs(win, 0, disprow - start); amiga_print_glyph(win, 0, NO_GLYPH); } @@ -1312,7 +1276,7 @@ DisplayData(winid win, int start) * current line */ if (cw->type != NHW_MESSAGE || cw->data[i][SEL_ITEM] >= 0) { amii_curs(win, 1, disprow - start); - if (WINVERS_AMIV && win == WIN_INVEN) { + if (WINVERS_AMIV && cw->menu.has_glyphs) { if (mip) amiga_print_glyph(win, 0, mip->glyph); amii_curs(win, 1, disprow - start); @@ -1389,7 +1353,7 @@ DisplayData(winid win, int start) while (*t == ' ') ++t; amii_curs(win, 1, disprow - start - 1); - if (mip && win == WIN_INVEN && WINVERS_AMIV) { + if (mip && WINVERS_AMIV && cw->menu.has_glyphs) { /* Erase any previous glyph drawn here. */ amiga_print_glyph(win, 0, NO_GLYPH); amii_curs(win, 1, disprow - start - 1); @@ -1446,11 +1410,9 @@ SetPropInfo(struct Window *win, struct Gadget *gad, long vis, long total, long t pot = 0; mflags = AUTOKNOB | FREEVERT; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { mflags |= PROPNEWLOOK; } -#endif NewModifyProp(gad, win, NULL, mflags, 0, pot, MAXBODY, body, 1); } diff --git a/sys/amiga/winami.c b/sys/amiga/winami.c index 7770a3547..631af1771 100644 --- a/sys/amiga/winami.c +++ b/sys/amiga/winami.c @@ -3,15 +3,9 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif #include "dlb.h" @@ -38,76 +32,35 @@ long amii_scrnmode; /* Interface definition, for use by windows.c and winprocs.h to provide * the intuition interface for the amiga... */ -struct window_procs amii_procs = { - WPID(amii), - WC_COLOR | WC_HILITE_PET | WC_INVERSE, - 0L, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ - amii_init_nhwindows, - amii_player_selection, amii_askname, amii_get_nh_event, - amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows, - amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, - amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed, - amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu, - amii_select_menu, genl_message_menu, - amii_mark_synch, amii_wait_synch, -#ifdef CLIPPING - amii_cliparound, -#endif -#ifdef POSITIONBAR - donull, -#endif - amii_print_glyph, amii_raw_print, amii_raw_print_bold, amii_nhgetch, - amii_nh_poskey, amii_bell, amii_doprev_message, amii_yn_function, - amii_getlin, amii_get_ext_cmd, amii_number_pad, amii_delay_output, -#ifdef CHANGE_COLOR /* only a Mac option currently */ - amii_change_color, amii_get_color_string, -#endif - amii_outrip, genl_preference_update, - genl_getmsghistory, genl_putmsghistory, - genl_status_init, genl_status_finish, genl_status_enablefield, - genl_status_update, - genl_can_suspend_yes, - amii_update_inventory, - amii_ctrl_nhwindow, -}; +/* Both windowports share the same function table -- the AMII (text) / + * AMIV (tile) split happens at runtime based on WINVERS_AMIV checks. */ +#define AMI_WIN_PROCS_BODY \ + WC_COLOR | WC_HILITE_PET | WC_INVERSE, \ + 0L, \ + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, /* has_color */ \ + amii_init_nhwindows, \ + amii_player_selection, amii_askname, amii_get_nh_event, \ + amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows, \ + amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, \ + amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed, \ + amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu, \ + amii_select_menu, genl_message_menu, \ + amii_mark_synch, amii_wait_synch, \ + amii_cliparound, \ + amii_print_glyph, amii_raw_print, amii_raw_print_bold, amii_nhgetch,\ + amii_nh_poskey, amii_bell, amii_doprev_message, amii_yn_function, \ + amii_getlin, amii_get_ext_cmd, amii_number_pad, amii_delay_output, \ + amii_change_color, amii_get_color_string, \ + amii_outrip, genl_preference_update, \ + genl_getmsghistory, genl_putmsghistory, \ + genl_status_init, genl_status_finish, genl_status_enablefield, \ + genl_status_update, \ + genl_can_suspend_yes, \ + amii_update_inventory, \ + amii_ctrl_nhwindow -/* The view window layout uses the same function names so we can use - * a shared library to allow the executable to be smaller. - */ -struct window_procs amiv_procs = { - WPID(amiv), - WC_COLOR | WC_HILITE_PET | WC_INVERSE, - 0L, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ - amii_init_nhwindows, - amii_player_selection, amii_askname, amii_get_nh_event, - amii_exit_nhwindows, amii_suspend_nhwindows, amii_resume_nhwindows, - amii_create_nhwindow, amii_clear_nhwindow, amii_display_nhwindow, - amii_destroy_nhwindow, amii_curs, amii_putstr, genl_putmixed, - amii_display_file, amii_start_menu, amii_add_menu, amii_end_menu, - amii_select_menu, genl_message_menu, - amii_mark_synch, amii_wait_synch, -#ifdef CLIPPING - amii_cliparound, -#endif -#ifdef POSITIONBAR - donull, -#endif - amii_print_glyph, amii_raw_print, amii_raw_print_bold, amii_nhgetch, - amii_nh_poskey, amii_bell, amii_doprev_message, amii_yn_function, - amii_getlin, amii_get_ext_cmd, amii_number_pad, amii_delay_output, -#ifdef CHANGE_COLOR /* only a Mac option currently */ - amii_change_color, amii_get_color_string, -#endif - amii_outrip, genl_preference_update, - genl_getmsghistory, genl_putmsghistory, - genl_status_init, genl_status_finish, genl_status_enablefield, - genl_status_update, - genl_can_suspend_yes, - amii_update_inventory, - amii_ctrl_nhwindow, -}; +struct window_procs amii_procs = { WPID(amii), AMI_WIN_PROCS_BODY }; +struct window_procs amiv_procs = { WPID(amiv), AMI_WIN_PROCS_BODY }; unsigned short amii_initmap[AMII_MAXCOLORS]; /* Default pens used unless user overides in nethack.cnf. */ @@ -159,8 +112,7 @@ unsigned short amiv_init_map[AMII_MAXCOLORS] = { 0x0fff, /* color #31 */ }; -#if !defined(TTY_GRAPHICS) \ - || defined(SHAREDLIB) /* this should be shared better */ +#ifndef TTY_GRAPHICS char morc; /* the character typed in response to a --more-- prompt */ #endif char spaces[76] = " " @@ -207,14 +159,12 @@ int wincnt = 0; /* # of nh windows opened */ * while they are playing... like compiling... */ -#ifdef INTUI_NEW_LOOK extern struct Hook fillhook; struct TagItem tags[] = { { WA_BackFill, (ULONG) &fillhook }, { WA_PubScreenName, (ULONG) "NetHack" }, { TAG_DONE, 0 }, }; -#endif /* * The default dimensions and status values for each window type. The @@ -230,16 +180,10 @@ struct win_setup new_wins[] = { { { 0, 1, 640, 11, 0xff, 0xff, NEWSIZE | GADGETUP | GADGETDOWN | MOUSEMOVE | MOUSEBUTTONS | RAWKEY, BORDERLESS | ACTIVATE | SMART_REFRESH -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) "Messages", NULL, NULL, 320, 40, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -251,16 +195,10 @@ struct win_setup new_wins[] = { /* NHW_STATUS */ { { 0, 181, 640, 24, 0xff, 0xff, RAWKEY | MENUPICK | DISKINSERTED, BORDERLESS | ACTIVATE | SMART_REFRESH | BACKDROP -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) "Game Status", NULL, NULL, 0, 0, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -273,17 +211,11 @@ struct win_setup new_wins[] = { { { 0, 0, WIDTH, WINDOWHEIGHT, 0xff, 0xff, RAWKEY | MENUPICK | MOUSEBUTTONS | ACTIVEWINDOW | MOUSEMOVE, BORDERLESS | ACTIVATE | SMART_REFRESH | BACKDROP -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) "Dungeon Map", NULL, NULL, 64, 64, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -298,16 +230,10 @@ struct win_setup new_wins[] = { | GADGETDOWN | CLOSEWINDOW | VANILLAKEY | NEWSIZE | INACTIVEWINDOW, WINDOWSIZING | WINDOWCLOSE | WINDOWDRAG | ACTIVATE | SMART_REFRESH -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , &MenuScroll, NULL, NULL, NULL, NULL, 64, 32, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -321,17 +247,11 @@ struct win_setup new_wins[] = { RAWKEY | MENUPICK | DISKINSERTED | MOUSEMOVE | GADGETUP | CLOSEWINDOW | VANILLAKEY | NEWSIZE, WINDOWSIZING | WINDOWCLOSE | WINDOWDRAG | ACTIVATE | SMART_REFRESH -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , &MenuScroll, NULL, (UBYTE *) NULL, NULL, NULL, 100, 32, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -340,20 +260,19 @@ struct win_setup new_wins[] = { 22, 78 }, + /* NHW_PERMINVENT — placeholder; port does not implement persistent + inventory yet, but the slot must exist because new_wins[] is + indexed by NHW_* type. */ + { { 0 } }, + /* NHW_BASE */ { { 0, 0, WIDTH, WINDOWHEIGHT, 0xff, 0xff, RAWKEY | MENUPICK | MOUSEBUTTONS, BORDERLESS | ACTIVATE | SMART_REFRESH | BACKDROP -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) NULL, NULL, NULL, -1, -1, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -365,16 +284,10 @@ struct win_setup new_wins[] = { /* NHW_OVER */ { { 320, 20, 319, 179, 0xff, 0xff, RAWKEY | MENUPICK | MOUSEBUTTONS, BORDERLESS | ACTIVATE | SMART_REFRESH | BACKDROP -#ifdef INTUI_NEW_LOOK | WFLG_NW_EXTENDED -#endif , NULL, NULL, (UBYTE *) NULL, NULL, NULL, 64, 32, 0xffff, 0xffff, -#ifdef INTUI_NEW_LOOK PUBLICSCREEN, tags -#else - CUSTOMSCREEN -#endif }, 0, 0, @@ -389,7 +302,6 @@ const char winpanicstr[] = "Bad winid %d in %s()"; /* The opened windows information */ struct amii_WinDesc *amii_wins[MAXWIN + 1]; -#ifdef INTUI_NEW_LOOK /* * NUMDRIPENS varies based on headers, so don't use it * here, its value is used elsewhere. @@ -408,23 +320,14 @@ struct TagItem scrntags[] = { { TAG_DONE, 0 }, }; -#endif - struct NewScreen NewHackScreen = { 0, 0, WIDTH, SCREENHEIGHT, 3, 0, 1, /* DetailPen, BlockPen */ - HIRES, CUSTOMSCREEN -#ifdef INTUI_NEW_LOOK - | NS_EXTENDED -#endif - , + HIRES, CUSTOMSCREEN | NS_EXTENDED, &Hack80, /* Font */ NULL, /*(UBYTE *)" NetHack X.Y.Z" */ NULL, /* Gadgets */ NULL, /* CustomBitmap */ -#ifdef INTUI_NEW_LOOK - scrntags -#endif -}; + scrntags }; /* * plname is filled either by an option (-u Player or -uPlayer) or @@ -436,7 +339,7 @@ struct NewScreen NewHackScreen = { 0, 0, WIDTH, SCREENHEIGHT, 3, 0, void amii_askname(void) { - char plnametmp[300]; /* From winreq.c: sizeof(StrStringSIBuff) */ + char plnametmp[BUFSZ]; /* matches StrStringSIBuff in winreq.c */ *plnametmp = 0; do { amii_getlin("Who are you?", plnametmp); @@ -452,300 +355,8 @@ amii_askname(void) } } -/* Discarded ... -jhsa -#include "NH:sys/amiga/char.c" -*/ - /* Get the player selection character */ -#if 0 /* New function at the bottom */ -void -amii_player_selection(void) -{ - struct Window *cwin; - struct IntuiMessage *imsg; - int aredone = 0; - struct Gadget *gd; - static int once = 0; - long class, code; - - amii_clear_nhwindow( WIN_BASE ); - if (validrole(flags.initrole)) - return; - else { - flags.initrole = randrole(FALSE); - return; - } -#if 0 /* Don't query the user ... instead give random character -jhsa */ - -#if 0 /* OBSOLETE */ - if( *svp.pl_character ){ - svp.pl_character[ 0 ] = toupper( svp.pl_character[ 0 ] ); - if( strchr( pl_classes, svp.pl_character[ 0 ] ) ) - return; - } -#endif - - if( !once ){ - if( bigscreen ){ - Type_NewWindowStructure1.TopEdge = - (HackScreen->Height/2) - (Type_NewWindowStructure1.Height/2); - } - for( gd = Type_NewWindowStructure1.FirstGadget; gd; - gd = gd->NextGadget ) - { - if( gd->GadgetID != 0 ) - SetBorder( gd ); - } - once = 1; - } - - if( WINVERS_AMIV ) - { -#ifdef INTUI_NEW_LOOK - Type_NewWindowStructure1.Extension = wintags; - Type_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *)-2; - fillhook.h_SubEntry = 0; -#endif - } - - Type_NewWindowStructure1.Screen = HackScreen; - if( ( cwin = OpenShWindow( (void *)&Type_NewWindowStructure1 ) ) == NULL ) - { - return; - } -#if 0 - WindowToFront( cwin ); -#endif - - while( !aredone ) - { - WaitPort( cwin->UserPort ); - while( ( imsg = (void *) GetMsg( cwin->UserPort ) ) != NULL ) - { - class = imsg->Class; - code = imsg->Code; - gd = (struct Gadget *)imsg->IAddress; - ReplyMsg( (struct Message *)imsg ); - - switch( class ) - { - case VANILLAKEY: - if( strchr( pl_classes, toupper( code ) ) ) - { - svp.pl_character[0] = toupper( code ); - aredone = 1; - } - else if( code == ' ' || code == '\n' || code == '\r' ) - { - flags.initrole = randrole(FALSE); -#if 0 /* OBSOLETE */ - strcpy( svp.pl_character, roles[ rnd( 11 ) ] ); -#endif - aredone = 1; - amii_clear_nhwindow( WIN_BASE ); - CloseShWindow( cwin ); - RandomWindow( svp.pl_character ); - return; - } - else if( code == 'q' || code == 'Q' ) - { - CloseShWindow( cwin ); - clearlocks(); - exit_nhwindows(NULL); - nh_terminate(0); - } - else - DisplayBeep( NULL ); - break; - - case GADGETUP: - switch( gd->GadgetID ) - { - case 1: /* Random Character */ - flags.initrole = randrole(FALSE); -#if 0 /* OBSOLETE */ - strcpy( svp.pl_character, roles[ rnd( 11 ) ] ); -#endif - amii_clear_nhwindow( WIN_BASE ); - CloseShWindow( cwin ); - RandomWindow( svp.pl_character ); - return; - - default: - svp.pl_character[0] = gd->GadgetID; - break; - } - aredone = 1; - break; - - case CLOSEWINDOW: - CloseShWindow( cwin ); - clearlocks(); - exit_nhwindows(NULL); - nh_terminate(0); - break; - } - } - } - amii_clear_nhwindow( WIN_BASE ); - CloseShWindow( cwin ); -#endif /* Do not query user ... -jhsa */ -} -#endif /* Function elsewhere */ - -#if 0 /* Unused ... -jhsa */ - -#include "NH:sys/amiga/randwin.c" - -void -RandomWindow(char *name) -{ - struct MsgPort *tport; - struct timerequest *trq; - static int once = 0; - struct Gadget *gd; - struct Window *w; - struct IntuiMessage *imsg; - int ticks = 0, aredone = 0, timerdone = 0; - long mask, got; - - tport = CreateMsgPort(); - trq = (struct timerequest *)CreateIORequest( tport, sizeof( *trq ) ); - if( tport == NULL || trq == NULL ) - { -allocerr: - if( tport ) DeleteMsgPort( tport ); - if( trq ) DeleteIORequest( (struct IORequest *)trq ); - Delay( 8 * 50 ); - return; - } - - if( OpenDevice( TIMERNAME, UNIT_VBLANK, (struct IORequest *)trq, 0L ) != 0 ) - goto allocerr; - - trq->tr_node.io_Command = TR_ADDREQUEST; - trq->tr_time.tv_secs = 8; - trq->tr_time.tv_micro = 0; - - SendIO( (struct IORequest *)trq ); - - /* Place the name in the center of the screen */ - Rnd_IText5.IText = name; - Rnd_IText6.LeftEdge = Rnd_IText4.LeftEdge + - (strlen(Rnd_IText4.IText)+1)*8; - Rnd_NewWindowStructure1.Width = ( - (strlen( Rnd_IText2.IText )+1) * 8 ) + - HackScreen->WBorLeft + HackScreen->WBorRight; - Rnd_IText5.LeftEdge = (Rnd_NewWindowStructure1.Width - - (strlen(name)*8))/2; - - gd = Rnd_NewWindowStructure1.FirstGadget; - gd->LeftEdge = (Rnd_NewWindowStructure1.Width - gd->Width)/2; - /* Chose correct modifier */ - Rnd_IText6.IText = "a"; - switch( *name ) - { - case 'a': case 'e': case 'i': case 'o': - case 'u': case 'A': case 'E': case 'I': - case 'O': case 'U': - Rnd_IText6.IText = "an"; - break; - } - - if( !once ) - { - if( bigscreen ) - { - Rnd_NewWindowStructure1.TopEdge = - (HackScreen->Height/2) - (Rnd_NewWindowStructure1.Height/2); - } - for( gd = Rnd_NewWindowStructure1.FirstGadget; gd; gd = gd->NextGadget ) - { - if( gd->GadgetID != 0 ) - SetBorder( gd ); - } - Rnd_NewWindowStructure1.IDCMPFlags |= VANILLAKEY; - - once = 1; - } - - if( WINVERS_AMIV ) - { -#ifdef INTUI_NEW_LOOK - Rnd_NewWindowStructure1.Extension = wintags; - Rnd_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *)-2; - fillhook.h_SubEntry = 0; -#endif - } - - Rnd_NewWindowStructure1.Screen = HackScreen; - if( ( w = OpenShWindow( (void *)&Rnd_NewWindowStructure1 ) ) == NULL ) - { - AbortIO( (struct IORequest *)trq ); - WaitIO( (struct IORequest *)trq ); - CloseDevice( (struct IORequest *)trq ); - DeleteIORequest( (struct IORequest *) trq ); - DeleteMsgPort( tport ); - Delay( 50 * 8 ); - return; - } - - PrintIText( w->RPort, &Rnd_IntuiTextList1, 0, 0 ); - - mask = (1L << tport->mp_SigBit)|(1L << w->UserPort->mp_SigBit); - while( !aredone ) - { - got = Wait( mask ); - if( got & (1L << tport->mp_SigBit ) ) - { - aredone = 1; - timerdone = 1; - GetMsg( tport ); - } - while( w && ( imsg = (struct IntuiMessage *) GetMsg( w->UserPort ) ) ) - { - switch( (long)imsg->Class ) - { - /* Must be up for a little while... */ - case INACTIVEWINDOW: - if( ticks >= 40 ) - aredone = 1; - break; - - case INTUITICKS: - ++ticks; - break; - - case GADGETUP: - aredone = 1; - break; - - case VANILLAKEY: - if(imsg->Code=='\n' || imsg->Code==' ' || imsg->Code=='\r') - aredone = 1; - break; - } - ReplyMsg( (struct Message *)imsg ); - } - } - - if( !timerdone ) - { - AbortIO( (struct IORequest *)trq ); - WaitIO( (struct IORequest *)trq ); - } - - CloseDevice( (struct IORequest *)trq ); - DeleteIORequest( (struct IORequest *) trq ); - DeleteMsgPort( tport ); - if(w) CloseShWindow( w ); -} -#endif /* Discarded randwin ... -jhsa */ /* this should probably not be needed (or be renamed) void @@ -760,16 +371,11 @@ amii_get_ext_cmd(void) menu_item *mip; anything id; struct amii_WinDesc *cw; -#ifdef EXTMENU - winid win; - int i; - char buf[256]; -#endif int colx; int bottom = 0; struct Window *w; - char obufp[100]; + char obufp[BUFSZ]; char *bufp = obufp; int c; int com_index, oindex; @@ -782,47 +388,6 @@ amii_get_ext_cmd(void) bottom = amii_msgborder(w); colx = 3; -#ifdef EXTMENU - if (iflags.extmenu) { - win = amii_create_nhwindow(NHW_MENU); - amii_start_menu(win, MENU_BEHAVE_STANDARD); - pline("#"); - amii_putstr(WIN_MESSAGE, -1, " "); - - for (i = 0; extcmdlist[i].ef_txt != NULL; ++i) { - id.a_char = *extcmdlist[i].ef_txt; - sprintf(buf, "%-10s - %s ", extcmdlist[i].ef_txt, - extcmdlist[i].ef_desc); - amii_add_menu(win, (const glyph_info *) 0, &id, - extcmdlist[i].ef_txt[0], 0, 0, NO_COLOR, - buf, MENU_ITEMFLAGS_NONE); - } - - amii_end_menu(win, (char *) 0); - sel = amii_select_menu(win, PICK_ONE, &mip); - amii_destroy_nhwindow(win); - - if (sel == 1) { - sel = mip->item.a_char; - for (i = 0; extcmdlist[i].ef_txt != NULL; ++i) { - if (sel == extcmdlist[i].ef_txt[0]) - break; - } - - /* copy in the text */ - if (extcmdlist[i].ef_txt != NULL) { - amii_clear_nhwindow(WIN_MESSAGE); - (void) put_ext_cmd((char *) extcmdlist[i].ef_txt, 0, cw, - bottom); - return (i); - } else - DisplayBeep(NULL); - } - - return (-1); - } -#endif - amii_clear_nhwindow(WIN_MESSAGE); /* Was NHW_MESSAGE */ if (scrollmsg) { pline("#"); @@ -852,7 +417,7 @@ amii_get_ext_cmd(void) amii_start_menu(win, MENU_BEHAVE_STANDARD); for (i = 0; extcmdlist[i].ef_txt != NULL; ++i) { - id.a_char = extcmdlist[i].ef_txt[0]; + id.a_int = i; sprintf(buf, "%-10s - %s ", extcmdlist[i].ef_txt, extcmdlist[i].ef_desc); amii_add_menu(win, (const glyph_info *) 0, &id, @@ -867,16 +432,14 @@ amii_get_ext_cmd(void) if (sel == 0) { return (-1); } else { - sel = mip->item.a_char; - for (i = 0; extcmdlist[i].ef_txt != NULL; ++i) { - if (sel == extcmdlist[i].ef_txt[0]) - break; - } + i = mip->item.a_int; /* copy in the text */ if (extcmdlist[i].ef_txt != NULL) { amii_clear_nhwindow(WIN_MESSAGE); - strcpy(bufp = obufp, extcmdlist[i].ef_txt); + strncpy(obufp, extcmdlist[i].ef_txt, sizeof(obufp) - 1); + obufp[sizeof(obufp) - 1] = '\0'; + bufp = obufp; (void) put_ext_cmd(obufp, colx, cw, bottom); return (i); } else @@ -934,7 +497,8 @@ amii_get_ext_cmd(void) sel = com_index; } else { colx = put_ext_cmd(obufp, colx, cw, bottom); - if (bufp - obufp < BUFSZ - 1 && bufp - obufp < COLNO) + if (bufp - obufp < (int) sizeof obufp - 1 + && bufp - obufp < COLNO) bufp++; } } else if (c == ('X' - 64) || c == '\177') { @@ -1011,7 +575,7 @@ amii_yn_function(const char *query, const char *resp, char def) char q; char rtmp[40]; boolean digit_ok, allow_num; - char prompt[BUFSZ]; + char prompt[BUFSZ + QBUFSZ + 16]; struct amii_WinDesc *cw; if (cw = amii_wins[WIN_MESSAGE]) @@ -1026,10 +590,12 @@ amii_yn_function(const char *query, const char *resp, char def) *rb = '\0'; (void) strncpy(prompt, query, QBUFSZ - 1); prompt[QBUFSZ - 1] = '\0'; - Sprintf(eos(prompt), " [%s]", respbuf); + Snprintf(eos(prompt), sizeof prompt - strlen(prompt), + " [%s]", respbuf); if (def) - Sprintf(eos(prompt), " (%c)", def); - Strcat(prompt, " "); + Snprintf(eos(prompt), sizeof prompt - strlen(prompt), + " (%c)", def); + Snprintf(eos(prompt), sizeof prompt - strlen(prompt), " "); pline("%s", prompt); } else { amii_putstr(WIN_MESSAGE, 0, query); @@ -1046,23 +612,6 @@ amii_yn_function(const char *query, const char *resp, char def) cursor_on(WIN_MESSAGE); q = lowc(WindowGetchar()); cursor_off(WIN_MESSAGE); -#if 0 -/* fix for PL2 */ - if (q == '\020') { /* ctrl-P */ - if(!doprev) - (void) tty_doprev_message(); /* need two initially */ - (void) tty_doprev_message(); - q = (char)0; - doprev = 1; - continue; - } else if (doprev) { - tty_clear_nhwindow(WIN_MESSAGE); - cw->maxcol = cw->maxrow; - doprev = 0; - amii_addtopl(prompt); - continue; - } -#endif /*0*/ digit_ok = allow_num && isdigit(q); if (q == '\033') { if (strchr(resp, 'q')) @@ -1156,17 +705,8 @@ amii_display_file(const char *fn, boolean complain) if ((fp = dlb_fopen(fn, RDTMODE)) == (dlb *) NULL) { if (complain) { - sprintf(buf, "Can't display %s: %s", fn, -#if defined(_DCC) || defined(__GNUC__) - strerror(errno) -#else -#ifdef __SASC_60 - __sys_errlist[errno] -#else - sys_errlist[errno] -#endif -#endif - ); + Snprintf(buf, sizeof buf, + "Can't display %s: %s", fn, strerror(errno)); amii_addtopl(buf); } return; @@ -1205,11 +745,8 @@ SetBorder(struct Gadget *gd) int borders = 6; int hipen = sysflags.amii_dripens[SHINEPEN], shadowpen = sysflags.amii_dripens[SHADOWPEN]; -#ifdef INTUI_NEW_LOOK struct DrawInfo *dip; -#endif -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { if ((dip = GetScreenDrawInfo(HackScreen)) != 0) { hipen = dip->dri_Pens[SHINEPEN]; @@ -1217,7 +754,6 @@ SetBorder(struct Gadget *gd) FreeScreenDrawInfo(HackScreen, dip); } } -#endif /* Allocate two border structures one for up image and one for down * image, plus vector arrays for the border lines. */ diff --git a/sys/amiga/winami.p b/sys/amiga/winami.p deleted file mode 100644 index dfb588177..000000000 --- a/sys/amiga/winami.p +++ /dev/null @@ -1,57 +0,0 @@ -/* NetHack 3.6 winami.p $NHDT-Date: 1433806595 2015/06/08 23:36:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ -/* Copyright (c) Gregg Wonderly, Naperville, IL, 1992, 1993 */ -/* NetHack may be freely redistributed. See license for details. */ -/* winami.c */ -void amii_raw_print(const char *); -void amii_raw_print_bold(const char *); -void amii_start_menu(winid , unsigned long ); -void amii_add_menu(winid, const glyph_info *, const anything *, char, char, int, int, const char *, unsigned int); -void amii_end_menu(winid , char , const char * , const char *); -char amii_select_menu(winid ); -void amii_update_inventory(int); -void amii_mark_synch (void); -void amii_wait_synch (void); -void amii_setclipped (void); -void amii_cliparound(int , int ); -void amii_askname (void); -void amii_player_selection (void); -void flush_output (void); -void amii_destroy_nhwindow(winid ); -int amii_create_nhwindow(int ); -void amii_init_nhwindows (void); -int amii_get_ext_cmd(void); -char amii_yn_function(const char * , const char * , char ); -void amii_addtopl(const char *); -void TextSpaces(struct RastPort * , int ); -void amii_putstr(winid , int , const char *); -void amii_putsym(winid , int , int , CHAR_P ); -void amii_clear_nhwindow(winid ); -void amii_exit_nhwindows(const char *); -int amii_nh_poskey(coordxy *, coordxy *, int *); -int amii_nhgetch (void); -void amii_get_nh_event (void); -void amii_remember_topl (void); -int amii_doprev_message (void); -void amii_display_nhwindow(winid , boolean ); -void amii_display_file(const char * , boolean ); -void amii_curs(winid , int , int ); -void amii_print_glyph(winid, coordxy, coordxy, const glyph_info *, const glyph_info *); -void DoMenuScroll(int , int ); -void DisplayData(int , int , int ); -void SetPropInfo(struct Window * , struct Gadget * , long , long , long ); -void kill_nhwindows(int ); -void amii_cl_end(struct amii_WinDesc * , int ); -void cursor_off(winid ); -void cursor_on(winid ); -void amii_getret (void); -void amii_getlin(const char * , char *); -void getlind(const char * , char * , const char *); -void amii_suspend_nhwindows(char * ); -void amii_resume_nhwindows(void); -void amii_bell(void); -void EditColor(void); -void DrawCol( struct Window *, int, UWORD * ) ; -void DispCol( struct Window *w, int idx, UWORD * ) ; -void SetBorder(struct Gadget *) ; -void port_help (void); -void dismiss_nhwindow(winid) ; diff --git a/sys/amiga/winchar.c b/sys/amiga/winchar.c index 75c35c87b..ed486c70e 100644 --- a/sys/amiga/winchar.c +++ b/sys/amiga/winchar.c @@ -7,35 +7,14 @@ #include #include #include -#ifndef _DCC #include -#endif -#ifdef TESTING -#include "hack.h" -#else -#ifndef CROSS_TO_AMIGA -#include "NH:src/tile.c" -#else #include "../src/tile.c" -#endif -#endif -#ifndef CROSS_TO_AMIGA -#include "NH:win/share/tile.h" -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "tile.h" #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif - -#ifdef OPT_DISPMAP -#define DISPMAP /* use display_map() from dispmap.s */ -#endif /* NH:sys/amiga/winvchar.c */ int main(int, char **); @@ -60,10 +39,6 @@ extern int reclip; struct BitMap *MyAllocBitMap(int xsize, int ysize, int depth, long mflags); void MyFreeBitMap(struct BitMap *bmp); -#ifdef DISPMAP -extern void display_map(struct Window *); -#endif - #ifdef TILES_IN_GLYPHMAP extern int maxmontile, maxobjtile, maxothtile; /* from tile.c */ #define MAXMONTILE maxmontile @@ -96,85 +71,6 @@ struct PDAT pictdata; char *tilefile; struct BitMap *tileimg, *tile; -#ifdef TESTING -short pens[NUMDRIPENS] = { 8, 3, 15, 0, 15, 7, 7, 8, 0 }; -main(int argc, char **argv) -{ - BitMapHeader bmhd; - struct IntuiMessage *imsg; - long code, class; - char buf[100]; - int i, x, y, tbl, done = 0, num; - struct Window *w; - struct Screen *scr; - - bmhd = ReadTileImageFiles(); - - scr = OpenScreenTags( - NULL, SA_Depth, pictdata.nplanes + amii_extraplanes, SA_DisplayID, - DBLNTSC_MONITOR_ID | HIRESLACE_KEY, SA_Overscan, OSCAN_TEXT, SA_Top, - 0, SA_Left, 0, SA_Width, STDSCREENWIDTH, SA_Height, STDSCREENHEIGHT, - SA_Type, CUSTOMSCREEN, SA_DetailPen, 0, SA_BlockPen, 1, SA_Title, - "NetHack Chars", SA_Pens, pens, TAG_DONE); - if (scr == NULL) { - printf("no screen\n"); -#undef exit - exit(1); - } - - w = OpenWindowTags( - 0, WA_CustomScreen, scr, WA_Flags, - WFLG_DRAGBAR | WFLG_SIZEGADGET | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET, - WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS, - WA_Left, 0, WA_Top, scr->WBorTop + 1 + 13, WA_MinWidth, 100, - WA_MinHeight, 100, WA_MaxWidth, 700, WA_MaxHeight, 1000, WA_Width, - 640, WA_Height, 340, WA_SmartRefresh, TRUE, TAG_DONE); - if (w) { - while (!done) { - for (i = 0; i < NUMTILEIMAGES * IMGPAGESIZE; ++i) { - int dx, dy; - tbl = i / IMGPAGESIZE; - x = i % IMGPAGESIZE; - y = x / IMGCOLUMNS; - x = x % IMGCOLUMNS; - dx = i % (IMGCOLUMNS * 2); - dy = i / (IMGCOLUMNS * 2); - BltBitMapRastPort(tileimg, x * pictdata.xsize, - y * pictdata.ysize, w->RPort, - w->BorderLeft + 1 + dx * pictdata.xsize, - w->BorderTop + 1 + dy * pictdata.ysize, - pictdata.xsize, pictdata.ysize, 0xc0); - } - WaitPort(w->UserPort); - while (imsg = (struct IntuiMessage *) GetMsg(w->UserPort)) { - class = imsg->Class; - code = imsg->Code; - ReplyMsg((struct Message *) imsg); - switch (class) { - case IDCMP_MOUSEBUTTONS: { - x = imsg->MouseX - w->BorderLeft; - y = imsg->MouseY - w->BorderTop; - num = ((y / pictdata.ysize) * IMGCOLUMNS * 2) - + (x / pictdata.xsize); - sprintf(buf, "Char #%d", num); - SetWindowTitles(w, buf, buf); - } break; - case IDCMP_CLOSEWINDOW: - done = 1; - break; - } - } - } - CloseWindow(w); - CloseScreen(scr); - } - - FreeTileImageFiles(); - - return (0); -} -#endif - /* * Read a single BMAP IFF file into a BitMap. * Returns the BitMapHeader; *bmp receives the bitmap. @@ -183,44 +79,68 @@ main(int argc, char **argv) BitMapHeader ReadImageFile(const char *filename, struct BitMap **bmp) { - BitMapHeader *bmhd, bmhds; + BitMapHeader *bmhd, bmhds = { 0 }; int j, np; - struct IFFHandle *iff; + long err; + struct IFFHandle *iff = NULL; struct StoredProperty *prop; + int iff_opened = 0; + const char *errfmt = NULL; + long errcode = 0; IFFParseBase = OpenLibrary("iffparse.library", 0L); if (!IFFParseBase) panic("No iffparse.library"); iff = AllocIFF(); - if (!iff) - panic("can't start IFF processing"); + if (!iff) { + errfmt = "can't start IFF processing"; + goto cleanup; + } iff->iff_Stream = Open(filename, MODE_OLDFILE); - if (iff->iff_Stream == 0) - panic("Can't open %s", filename); + if (iff->iff_Stream == 0) { + errfmt = "Can't open %s"; + goto cleanup; + } InitIFFasDOS(iff); - OpenIFF(iff, IFFF_READ); + if ((err = OpenIFF(iff, IFFF_READ)) != 0) { + errfmt = "OpenIFF failed on %s, code %ld"; + errcode = err; + goto cleanup; + } + iff_opened = 1; + PropChunk(iff, ID_BMAP, ID_BMHD); PropChunk(iff, ID_BMAP, ID_CMAP); PropChunk(iff, ID_BMAP, ID_PDAT); StopChunk(iff, ID_BMAP, ID_PLNE); - if ((j = ParseIFF(iff, IFFPARSE_SCAN)) != 0) - panic("ParseIFF failed on %s, code %d", - filename, j); + if ((err = ParseIFF(iff, IFFPARSE_SCAN)) != 0) { + errfmt = "ParseIFF failed on %s, code %ld"; + errcode = err; + goto cleanup; + } prop = FindProp(iff, ID_BMAP, ID_BMHD); - if (!prop) - panic("No BMHD chunk in %s", filename); + if (!prop) { + errfmt = "No BMHD chunk in %s"; + goto cleanup; + } bmhd = (BitMapHeader *) prop->sp_Data; np = bmhd->nPlanes; + if (np > DEPTH) { + errfmt = "%s: too many bitplanes (code %ld)"; + errcode = np; + goto cleanup; + } + /* Load CMAP into palette arrays if present */ prop = FindProp(iff, ID_BMAP, ID_CMAP); if (prop) { unsigned char *cmap = prop->sp_Data; - for (j = 0; j < (1L << np) * 3; j += 3) { + for (j = 0; j < (1UL << np) * 3; j += 3) { amii_initmap[j / 3] = amiv_init_map[j / 3] = ((cmap[j+0] >> 4) << 8) @@ -236,18 +156,29 @@ ReadImageFile(const char *filename, struct BitMap **bmp) *bmp = MyAllocBitMap(bmhd->w, bmhd->h, np, MEMF_CHIP | MEMF_CLEAR); - if (!*bmp) - panic("Can't allocate bitmap for %s", filename); + if (!*bmp) { + errfmt = "Can't allocate bitmap for %s"; + goto cleanup; + } for (j = 0; j < np; j++) ReadChunkBytes(iff, (*bmp)->Planes[j], RASSIZE(bmhd->w, bmhd->h)); bmhds = *bmhd; - CloseIFF(iff); - Close(iff->iff_Stream); - FreeIFF(iff); + +cleanup: + if (iff_opened) + CloseIFF(iff); + if (iff && iff->iff_Stream) + Close(iff->iff_Stream); + if (iff) + FreeIFF(iff); CloseLibrary(IFFParseBase); + IFFParseBase = NULL; + + if (errfmt) + panic(errfmt, filename, errcode); return bmhds; } @@ -293,9 +224,15 @@ MyAllocBitMap(int xsize, int ysize, int depth, long mflags) if (!bm) return (NULL); + bm->mflags = mflags; bm->xsize = xsize; bm->ysize = ysize; InitBitMap(&bm->bm, depth, xsize, ysize); + /* InitBitMap does not zero Planes[]; if a later AllocRaster fails + * and MyFreeBitMap unwinds, the uninitialized entries above the + * failure would be passed to FreeRaster as garbage pointers. */ + for (j = 0; j < (int) (sizeof bm->bm.Planes / sizeof bm->bm.Planes[0]); ++j) + bm->bm.Planes[j] = NULL; for (j = 0; j < depth; ++j) { if (mflags & MEMF_CHIP) bm->bm.Planes[j] = AllocRaster(xsize, ysize); @@ -329,25 +266,6 @@ MyFreeBitMap(struct BitMap *bmp) free(bm); } -#ifdef TESTING -void -panic(char *s, long a1, long a2, long a3, long a4) -{ - printf(s, a1, a2, a3, a4); - putchar('\n'); -} -long * -alloc(unsigned int x) -{ - long *p = (long *) malloc(x); - if (!p) { - panic("malloc failed"); - exit(1); - } - return p; -} -#endif - void FreeTileImageFiles(void) { @@ -355,7 +273,6 @@ FreeTileImageFiles(void) FreeImageFile(&tile); } -#ifndef TESTING /* * Define some stuff for our special glyph drawing routines */ @@ -385,7 +302,6 @@ flush_glyph_buffer(struct Window *vw) void amiv_flush_glyph_buffer(struct Window *vw) { -#if !defined(DISPMAP) || defined(OPT_DISPMAP) int xsize, ysize, x, y; struct BitScaleArgs bsa; struct BitScaleArgs bsm; @@ -395,7 +311,6 @@ amiv_flush_glyph_buffer(struct Window *vw) int i, k; int scaling_needed; struct RastPort *rp = vw->RPort; -#endif /* If nothing is buffered, return before we do anything */ if (glyph_node_index == 0) @@ -404,20 +319,8 @@ amiv_flush_glyph_buffer(struct Window *vw) cursor_off(WIN_MAP); amiv_start_glyphout(WIN_MAP); -#ifdef OPT_DISPMAP - if (sysflags.fast_map) { -#endif -#ifdef DISPMAP - display_map(vw); -#endif -#ifdef OPT_DISPMAP - } else { -#endif -#if !defined(DISPMAP) || defined(OPT_DISPMAP) - /* XXX fix indent */ - /* This is a dynamic value based on this relationship. */ - scaling_needed = - (pictdata.xsize != mxsize || pictdata.ysize != mysize); + /* This is a dynamic value based on this relationship. */ + scaling_needed = (pictdata.xsize != mxsize || pictdata.ysize != mysize); /* If overview window is up, set up to render the correct scale there */ @@ -546,10 +449,6 @@ amiv_flush_glyph_buffer(struct Window *vw) MyFreeBitMap(imgbm); if (bm) MyFreeBitMap(bm); -#endif /* DISPMAP */ -#ifdef OPT_DISPMAP - } -#endif amii_end_glyphout(WIN_MAP); @@ -563,7 +462,7 @@ amiv_flush_glyph_buffer(struct Window *vw) void amiv_lprint_glyph(winid window, int color_index, int glyph) { - int base; + int base = 0; struct amii_WinDesc *cw; struct Window *w; int curx; @@ -625,27 +524,8 @@ amiv_lprint_glyph(winid window, int color_index, int glyph) amiv_g_nodes[glyph_node_index].dsty = min(w->BorderTop + (cury * mysize), w->Height - 1); -#ifdef OPT_DISPMAP - if (sysflags.fast_map) { -#endif /* keni */ -#ifdef DISPMAP - /* display_map() needs byte-aligned destinations, and we don't - * want to - * overwrite the window border. - */ - amiv_g_nodes[glyph_node_index].dstx = - (w->BorderLeft + 8 + (curx * mxsize)) & -8; -#endif -#ifdef OPT_DISPMAP - } else { -#endif -#if !defined(DISPMAP) || defined(OPT_DISPMAP) - amiv_g_nodes[glyph_node_index].dstx = - min(w->BorderLeft + (curx * mxsize), w->Width - 1); -#endif -#ifdef OPT_DISPMAP - } -#endif + amiv_g_nodes[glyph_node_index].dstx = + min(w->BorderLeft + (curx * mxsize), w->Width - 1); amiv_g_nodes[glyph_node_index].odsty = cw->cury; amiv_g_nodes[glyph_node_index].odstx = cw->curx; amiv_g_nodes[glyph_node_index].srcx = xoff; @@ -657,17 +537,6 @@ amiv_lprint_glyph(winid window, int color_index, int glyph) int j, k, x, y, apen; struct RastPort *rp = w->RPort; x = rp->cp_x - pictdata.xsize - 3; -#ifdef OPT_DISPMAP - if (sysflags.fast_map) { -#endif -#ifdef DISPMAP - x &= -8; - if (x == 0) - x = 8; -#endif -#ifdef OPT_DISPMAP - } -#endif y = rp->cp_y - pictdata.ysize + 1; @@ -805,21 +674,12 @@ GlyphToIcon(int glyph) glyph_info gi; map_glyphinfo(0, 0, glyph, 0, &gi); - if (glyph > 10000) + if (glyph >= 10000) return glyph; return (gi.gm.tileidx); } -#endif #ifdef AMII_GRAPHICS -#ifdef TESTING -/* - * Define some stuff for our special glyph drawing routines - */ -static unsigned short glyph_node_index, glyph_buffer_index; -#define NUMBER_GLYPH_NODES 80 -#define GLYPH_BUFFER_SIZE 512 -#endif /* TESTING */ struct amii_glyph_node { short x; @@ -837,33 +697,15 @@ static char amii_glyph_buffer[GLYPH_BUFFER_SIZE]; * See winami.c for the amiga specific colormap. */ +/* CLR_BLACK (slot 0) renders as the dim blue pen on black background, + CLR_WHITE (slot 15) uses white on black. Slots 9-14 use the inverse- + video trick (fg=black, bg=color) to fit 16 logical colors into 8 pens. */ int foreg[AMII_MAXCOLORS] = { - 0, 7, 4, 2, 6, 5, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0 + 6, 7, 4, 2, 6, 5, 3, 1, 1, 0, 0, 0, 0, 0, 0, 1 }; int backg[AMII_MAXCOLORS] = { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 1, 6, 5, 3, 1 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 4, 1, 6, 5, 3, 0 }; -#if 0 -#define CLR_BLACK 0 -#define CLR_RED 1 -#define CLR_GREEN 2 -#define CLR_BROWN 3 /* on IBM, low-intensity yellow is brown */ -#define CLR_BLUE 4 -#define CLR_MAGENTA 5 -#define CLR_CYAN 6 -#define CLR_GRAY 7 /* low-intensity white */ -#define NO_COLOR 8 -#define CLR_ORANGE 9 -#define CLR_BRIGHT_GREEN 10 -#define CLR_YELLOW 11 -#define CLR_BRIGHT_BLUE 12 -#define CLR_BRIGHT_MAGENTA 13 -#define CLR_BRIGHT_CYAN 14 -#define CLR_WHITE 15 -#define CLR_MAX 16 -#endif - -#ifndef TESTING /* * Begin Revamped Text display routines * @@ -983,7 +825,7 @@ amii_lprint_glyph(winid window, int color_index, int glyph) /* * Add it to the end of the buffer */ - amii_glyph_buffer[glyph_buffer_index++] = glyph; + amii_glyph_buffer[glyph_buffer_index++] = (char) glyph; amii_g_nodes[glyph_node_index - 1].len++; } else { /* See if we're out of glyph nodes */ @@ -1001,18 +843,14 @@ amii_lprint_glyph(winid window, int color_index, int glyph) ++glyph_node_index; } } -#endif /* !TESTING */ -#ifdef TESTING /* - * Define some variables which will be used to save context when toggling - * back and forth between low level text and console I/O. + * Variables used to save context when toggling between low level text + * and console I/O. */ static long xsave, ysave, modesave, apensave, bpensave; static int usecolor; -#endif /* TESTING */ -#ifndef TESTING /* * The function is called before any glyphs are driven to the screen. It * removes the cursor, saves internal state of the window, then returns. @@ -1049,62 +887,5 @@ amii_start_glyphout(winid window) iflags.use_color = FALSE; cw->wflags |= FLMAP_INGLYPH; } -#endif /* !TESTING */ -#if 0 -/* - * General cleanup routine -- flushes and restores cursor - */ -void -amii_end_glyphout(window) - winid window; -{ - struct amii_WinDesc *cw; - struct Window *w; - - if( ( cw = amii_wins[ window ] ) == (struct amii_WinDesc *)NULL ) - panic("bad window id %d in amii_end_glyphout()", window ); - - if( ( cw->wflags & FLMAP_INGLYPH ) == 0 ) - return; - cw->wflags &= ~(FLMAP_INGLYPH); - - if( !(w = cw->win ) ) - panic( "bad winid %d, no window ptr set", window ); - - /* - * Clean up whatever is left in the buffer - */ - iflags.use_color = usecolor; - - /* - * Reset internal data structs - */ - SetAPen(w->RPort, apensave); - SetBPen(w->RPort, bpensave); - SetDrMd(w->RPort, modesave); - - Move(w->RPort, xsave, ysave); -} #endif -#endif - -#ifndef TESTING -#ifdef OPT_DISPMAP -/* don't use dispmap unless x & y are 8,16,24,32,48 and equal */ -void -dispmap_sanity(void) -{ - if (mxsize != mysize || dispmap_sanity1(mxsize) - || dispmap_sanity1(mysize)) { - sysflags.fast_map = 0; - } -} -int -dispmap_sanity1(int x) -{ - static unsigned char valid[] = { 8, 16, 24, 32, 48, 0 }; - return !strchr((char *)valid, x); -} -#endif /* OPT_DISPMAP */ -#endif /* TESTING */ diff --git a/sys/amiga/windefs.h b/sys/amiga/windefs.h index cb6cbd3db..84faf98ff 100644 --- a/sys/amiga/windefs.h +++ b/sys/amiga/windefs.h @@ -5,9 +5,6 @@ #include #include #include -#if !defined(_DCC) && !defined(__GNUC__) -#include -#endif #include #include #include @@ -19,31 +16,10 @@ #include #include #include -/* stddef.h is included in the precompiled version of hack.h . If we include - * it here normally (through string.h) we'll get an "illegal typedef" later - * on. This is the easiest way I can think of to fix it without messing - * around with the rest of the #includes. --AMC - */ -#if defined(_DCC) && !defined(HACK_H) -#define ptrdiff_t ptrdiff_t_ -#define size_t size_t_ -#define wchar_t wchar_t_ -#endif #include #undef strcmpi #include #include -#if defined(_DCC) && !defined(HACK_H) -#undef ptrdiff_t -#undef size_t -#undef wchar_T -#endif - -#ifdef IDCMP_CLOSEWINDOW -#ifndef INTUI_NEW_LOOK -#define INTUI_NEW_LOOK -#endif -#endif #ifndef HACK_H #include "hack.h" @@ -53,7 +29,7 @@ #include "func_tab.h" #ifndef CLIPPING -CLIPPING must be defined for the AMIGA version +#error "CLIPPING must be defined for the AMIGA version" #endif #undef LI @@ -62,17 +38,6 @@ CLIPPING must be defined for the AMIGA version /*#define TOPL_GETLINE /* Don't use a window for getlin() */ /*#define WINDOW_YN /* Use a window for y/n questions */ -#ifdef AZTEC_C -#include -#else -#ifdef _DCC -#include -#include -#include -#include -#include -#include -#else #include #include #include @@ -80,40 +45,18 @@ CLIPPING must be defined for the AMIGA version #include #include #include -#endif /* kludge - see amirip for why */ #undef red #undef green #undef blue -#ifdef _DCC -#include -#else #include -#endif - -#ifdef _DCC -#define __asm /* DICE doesn't like __asm */ -#endif - -#ifdef _DCC -#include -#else #include -#endif -#endif -#ifdef SHAREDLIB -#include "NH:sys/amiga/lib/libmacs.h" -#endif - -#ifdef INTUI_NEW_LOOK #include -#endif -#define WINVERS_AMII (strcmp("amii", windowprocs.name) == 0) -#define WINVERS_AMIV (strcmp("amiv", windowprocs.name) == 0) -#define WINVERS_AMIT (strcmp("amitty", windowprocs.name) == 0) +#define WINVERS_AMII WINDOWPORT(amii) +#define WINVERS_AMIV WINDOWPORT(amiv) /* cw->data[x] contains 2 characters worth of special information. These * characters are stored at the offsets as described here. @@ -153,13 +96,10 @@ CLIPPING must be defined for the AMIGA version #define MAPFTHEIGHT 8 #define MAPFTBASELN 6 -/* If Compiling with the "New Look", redefine these now */ -#ifdef INTUI_NEW_LOOK +/* Use the OS 2.0+ "new look" Intuition structs unconditionally. */ #define NewWindow ExtNewWindow #define NewScreen ExtNewScreen -#endif -#define SIZEOF_DISKNAME 8 #define CSI '\x9b' #define NO_CHAR -1 diff --git a/sys/amiga/winext.h b/sys/amiga/winext.h index 068593337..adfd83cd6 100644 --- a/sys/amiga/winext.h +++ b/sys/amiga/winext.h @@ -18,12 +18,22 @@ extern int LI; extern int scrollmsg; extern int alwaysinvent; -#ifndef SHAREDLIB extern unsigned short amii_defpens[20]; extern struct amii_DisplayDesc *amiIDisplay; /* the Amiga Intuition descriptor */ extern struct window_procs amii_procs; extern struct window_procs amiv_procs; +/* Three similarly-named palette arrays. Note the position of the + * second underscore distinguishes them: + * amii_initmap = working/runtime palette (mutated by tile/tomb load + * and the in-game color editor). + * amii_init_map = AMII (text-mode) compile-time defaults, 8 entries. + * amiv_init_map = AMIV (tile-mode) compile-time defaults, 32 entries + * (mutated by ReadImageFile when a tile/tomb IFF + * carries its own CMAP). + * The naming is historical; sysflags.amii_curmap is yet another related + * array holding the user's saved color choices. + */ extern unsigned short amii_initmap[AMII_MAXCOLORS]; extern unsigned short amiv_init_map[AMII_MAXCOLORS]; extern unsigned short amii_init_map[AMII_MAXCOLORS]; @@ -33,21 +43,6 @@ extern long amii_scrnmode; extern winid amii_rawprwin; extern struct Screen *HackScreen; extern char Initialized; -/* These have already been defined elsewhere (and some are conflicting) - * ... going ... going once ... going twice .... - * extern const char *roles[]; - * extern struct Library *ConsoleDevice; - * extern char toplines[ TBUFSZ ]; - * extern NEARDATA winid WIN_MESSAGE; - * extern NEARDATA winid WIN_MAP; - * extern NEARDATA winid WIN_STATUS; - * extern NEARDATA winid WIN_INVEN; - * extern winid WIN_OVER; - * extern struct GfxBase *GfxBase; - * extern struct Library *DiskfontBase; - * extern struct IntuitionBase *IntuitionBase; - * extern struct Library *LayersBase; - */ extern int amii_msgAPen; extern int amii_msgBPen; extern int amii_statAPen; @@ -58,9 +53,6 @@ extern int amii_textAPen; extern int amii_textBPen; extern int amii_otherAPen; extern int amii_otherBPen; -#else -extern WinamiBASE *WinamiBase; -#endif /* All kinds of shared stuff */ extern struct TextAttr Hack160; extern struct TextAttr Hack40; @@ -71,16 +63,13 @@ extern struct Menu HackMenu[]; extern struct Menu *MenuStrip; extern struct NewMenu GTHackMenu[]; extern APTR *VisualInfo; -extern unsigned char KbdBuffered; +extern int KbdBuffered; extern struct TextFont *TextsFont; extern struct TextFont *HackFont; extern struct IOStdReq ConsoleIO; extern struct MsgPort *HackPort; extern int txwidth, txheight, txbaseline; -#ifdef SUPERBITMAP_MAP -extern struct BitMap amii_vbm; -#endif /* This gadget data is replicated for menu/text windows... */ extern struct PropInfo PropScroll; @@ -132,17 +121,9 @@ typedef enum { extern struct PDAT pictdata; extern struct Hook fillhook; extern struct TagItem wintags[]; -#ifndef SHAREDLIB -#ifndef __GNUC__ -void __asm LayerFillHook(register __a0 struct Hook *hk, - register __a2 struct RastPort *rp, - register __a1 struct FillParams *fp); -#else #ifdef __PPC__ struct EmulLibEntry LayerFillHook; #else void LayerFillHook(void); #endif -#endif -#endif extern int mxsize, mysize; diff --git a/sys/amiga/winfuncs.c b/sys/amiga/winfuncs.c index 7d451a665..c5d997ef6 100644 --- a/sys/amiga/winfuncs.c +++ b/sys/amiga/winfuncs.c @@ -3,28 +3,18 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif #include "patchlevel.h" extern struct TagItem scrntags[]; -#ifndef CROSS_TO_AMIGA -extern struct Library *ConsoleDevice; -#else extern struct Device * # ifdef __CONSTLIBBASEDECL__ __CONSTLIBBASEDECL__ # endif /* __CONSTLIBBASEDECL__ */ ConsoleDevice; -#endif static BitMapHeader amii_bmhd; static void cursor_common(struct RastPort *, int, int); @@ -136,14 +126,10 @@ ami_wininit_data(int dir) memcpy(amii_initmap, amiv_init_map, sizeof(amii_initmap)); } -#ifdef OPT_DISPMAP - dispmap_sanity(); -#endif memcpy(sysflags.amii_dripens, amii_defpens, sizeof(sysflags.amii_dripens)); } -#ifdef INTUI_NEW_LOOK struct Hook SM_FilterHook; struct Hook fillhook; struct TagItem wintags[] = { @@ -151,7 +137,6 @@ struct TagItem wintags[] = { { WA_PubScreenName, (ULONG) "NetHack" }, { TAG_END, 0 }, }; -#endif void amii_destroy_nhwindow(winid win) /* just hide */ @@ -179,23 +164,23 @@ amii_destroy_nhwindow(winid win) /* just hide */ WIN_OVER = WIN_ERR; } } else if (cw->type == NHW_OVER) { - struct Window *w = amii_wins[WIN_OVER]->win; - amii_oldover.MinX = w->LeftEdge; - amii_oldover.MinY = w->TopEdge; - amii_oldover.MaxX = w->Width; - amii_oldover.MaxY = w->Height; + struct Window *w = cw->win; + if (w) { + amii_oldover.MinX = w->LeftEdge; + amii_oldover.MinY = w->TopEdge; + amii_oldover.MaxX = w->Width; + amii_oldover.MaxY = w->Height; - if (WIN_MESSAGE != WIN_ERR && amii_wins[WIN_MESSAGE]) { - w = amii_wins[WIN_MESSAGE]->win; - amii_oldmsg.MinX = w->LeftEdge; - amii_oldmsg.MinY = w->TopEdge; - amii_oldmsg.MaxX = w->Width; - amii_oldmsg.MaxY = w->Height; - SizeWindow(amii_wins[WIN_MESSAGE]->win, - (amiIDisplay->xpix - - amii_wins[WIN_MESSAGE]->win->LeftEdge) - - amii_wins[WIN_MESSAGE]->win->Width, - 0); + if (WIN_MESSAGE != WIN_ERR && amii_wins[WIN_MESSAGE] + && (w = amii_wins[WIN_MESSAGE]->win) != NULL) { + amii_oldmsg.MinX = w->LeftEdge; + amii_oldmsg.MinY = w->TopEdge; + amii_oldmsg.MaxX = w->Width; + amii_oldmsg.MaxY = w->Height; + SizeWindow(w, + (amiIDisplay->xpix - w->LeftEdge) - w->Width, + 0); + } } } } @@ -242,9 +227,12 @@ amii_destroy_nhwindow(winid win) /* just hide */ WIN_MESSAGE = WIN_ERR; else if (win == WIN_INVEN) WIN_INVEN = WIN_ERR; + else if (win == WIN_OVER) + WIN_OVER = WIN_ERR; + else if (win == WIN_BASE) + WIN_BASE = WIN_ERR; } -#ifdef INTUI_NEW_LOOK struct FillParams { struct Layer *layer; struct Rectangle bounds; @@ -252,7 +240,6 @@ struct FillParams { WORD offsety; }; -#ifdef __GNUC__ #ifdef __PPC__ void PPC_LayerFillHook(void); struct EmulLibEntry LayerFillHook = { TRAP_LIB, 0, @@ -281,16 +268,6 @@ void LayerFillHook_impl(struct Hook *hk, struct RastPort *rp, struct FillParams *fp) { -#endif -#else -void -#ifndef _DCC - __interrupt -#endif - __saveds __asm LayerFillHook(__a0 struct Hook *hk, - __a2 struct RastPort *rp, - __a1 struct FillParams *fp) -{ #endif long x, y, xmax, ymax; @@ -334,7 +311,6 @@ void SetDrMd(&rptmp, JAM2); RectFill(&rptmp, x, y, xmax, ymax); } -#endif winid amii_create_nhwindow(int type) @@ -383,6 +359,9 @@ amii_create_nhwindow(int type) panic("no memory for msg port"); } + if (type < 0 || type > NHW_OVER) + panic("bad type %d in create_nhwindow", type); + nw = &new_wins[type].newwin; nw->Width = amiIDisplay->xpix; nw->Screen = HackScreen; @@ -444,8 +423,13 @@ amii_create_nhwindow(int type) if (nw->Width >= amiIDisplay->xpix - nw->LeftEdge) nw->Width = amiIDisplay->xpix - nw->LeftEdge; } else if (WINVERS_AMIV && type == NHW_OVER) { - nw->Flags |= WINDOWSIZING | WINDOWDRAG | WINDOWCLOSE; - nw->IDCMPFlags |= CLOSEWINDOW; + /* No window-system gadgets: BORDERLESS means there is no border + * to attach close/size/drag gadgets to. On some Kickstarts the + * phantom gadgets hit-test against unrelated input (selecting + * the overview and pressing ESC has been observed to destroy + * the window and crash the game). SHIFT-HELP toggles the + * overview cleanly via delayed_key_action; that is the + * supported close path. */ /* Bring up window as half the width of the message window, and make * the message window change to one half the width... */ @@ -519,12 +503,10 @@ amii_create_nhwindow(int type) if (nw->Height + stath + maph < HackScreen->Height - nw->TopEdge) nw->Height = HackScreen->Height - nw->TopEdge - 1 - maph - stath; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { MsgPropScroll.Flags |= PROPNEWLOOK; PropScroll.Flags |= PROPNEWLOOK; } -#endif } nw->IDCMPFlags |= MENUPICK; @@ -568,29 +550,26 @@ amii_create_nhwindow(int type) wd = (struct amii_WinDesc *) alloc(sizeof(struct amii_WinDesc)); memset(wd, 0, sizeof(struct amii_WinDesc)); - /* Both, since user may have changed the pen settings so respect those */ - if (WINVERS_AMII || WINVERS_AMIV) { - /* Special backfill for these types of layers */ - switch (type) { - case NHW_MESSAGE: - case NHW_STATUS: - case NHW_TEXT: - case NHW_MENU: - case NHW_BASE: - case NHW_OVER: - case NHW_MAP: - if (wd) { - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *) type; - fillhook.h_SubEntry = 0; - wd->hook = alloc(sizeof(fillhook)); - memcpy(wd->hook, &fillhook, sizeof(fillhook)); - memcpy(wd->wintags, wintags, sizeof(wd->wintags)); - wd->wintags[0].ti_Data = (long) wd->hook; - nw->Extension = (void *) wd->wintags; - } - break; + /* Special backfill for these types of layers */ + switch (type) { + case NHW_MESSAGE: + case NHW_STATUS: + case NHW_TEXT: + case NHW_MENU: + case NHW_BASE: + case NHW_OVER: + case NHW_MAP: + if (wd) { + fillhook.h_Entry = (void *) &LayerFillHook; + fillhook.h_Data = (void *) type; + fillhook.h_SubEntry = 0; + wd->hook = alloc(sizeof(fillhook)); + memcpy(wd->hook, &fillhook, sizeof(fillhook)); + memcpy(wd->wintags, wintags, sizeof(wd->wintags)); + wd->wintags[0].ti_Data = (long) wd->hook; + nw->Extension = (void *) wd->wintags; } + break; } /* Don't open MENU or TEXT windows yet */ @@ -828,7 +807,6 @@ amii_create_nhwindow(int type) return (newid); } -#ifdef __GNUC__ #ifdef __PPC__ int PPC_SM_Filter(void); struct EmulLibEntry SM_Filter = { TRAP_LIB, 0, @@ -857,16 +835,6 @@ int SM_Filter_impl(struct Hook *hk, ULONG modeID, struct ScreenModeRequester *smr) { -#endif -#else -int -#ifndef _DCC - __interrupt -#endif - __saveds __asm SM_Filter( - __a0 struct Hook *hk, __a1 ULONG modeID, - __a2 struct ScreenModeRequester *smr) -{ #endif struct DimensionInfo dims; struct DisplayInfo disp; @@ -886,6 +854,48 @@ int return 0; } +/* Switch from AMIV (tile) to AMII (text) and tell the player why. */ +static void +amii_fall_back(const char *why1, const char *why2) +{ + extern struct window_procs amii_procs; + + raw_print(why1); + raw_print(why2); + raw_print("Falling back to text mode. Set windowtype:amii in"); + raw_print("nethack.cnf to suppress this warning."); + windowprocs = amii_procs; + ami_wininit_data(WININIT); +} + +static void +amii_maybe_fall_back_to_text(void) +{ + if (!WINVERS_AMIV) + return; + + if (IntuitionBase->LibNode.lib_Version >= 37) { + struct Screen *wbscr; + int wb_depth = -1; + + if ((wbscr = LockPubScreen("Workbench")) != NULL) { + wb_depth = wbscr->BitMap.Depth; + UnlockPubScreen(NULL, wbscr); + } + if (wb_depth >= 0 && wb_depth < 4) { + amii_fall_back("Workbench screen is shallower than 16 colours", + "(tile mode requires depth >= 4)."); + return; + } + } + + if (AvailMem(MEMF_CHIP) < 384L * 1024L) { + amii_fall_back("Not enough chip RAM available for tile mode", + "(< 384 KB free)."); + return; + } +} + /* Initialize the windowing environment */ void @@ -908,7 +918,7 @@ amii_init_nhwindows(int *argcp, char **argv) for (t = 1; t <= lclargc; t++) { if (!strcmp("-L", *argv_in) || !strcmp("-l", *argv_in)) { - bigscreen = (*argv_in[1] == 'l') ? -1 : 1; + bigscreen = ((*argv_in)[1] == 'l') ? -1 : 1; /* and eat the flag */ (*argcp)--; } else { @@ -951,6 +961,8 @@ amii_init_nhwindows(int *argcp, char **argv) Abort(AG_OpenLib); } + amii_maybe_fall_back_to_text(); + amiIDisplay = (struct amii_DisplayDesc *) alloc(sizeof(struct amii_DisplayDesc)); memset(amiIDisplay, 0, sizeof(struct amii_DisplayDesc)); @@ -958,7 +970,6 @@ amii_init_nhwindows(int *argcp, char **argv) /* Use Intuition sizes for overscan screens... */ amiIDisplay->xpix = 0; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { if (wbscr = LockPubScreen("Workbench")) { amiIDisplay->xpix = wbscr->Width; @@ -966,7 +977,6 @@ amii_init_nhwindows(int *argcp, char **argv) UnlockPubScreen(NULL, wbscr); } } -#endif if (amiIDisplay->xpix == 0) { amiIDisplay->ypix = GfxBase->NormalDisplayRows; amiIDisplay->xpix = GfxBase->NormalDisplayColumns; @@ -1011,9 +1021,11 @@ amii_init_nhwindows(int *argcp, char **argv) */ if (DiskfontBase = OpenLibrary("diskfont.library", amii_libvers)) { - Hack80.ta_Name -= SIZEOF_DISKNAME; + extern UBYTE HackFontName[], HackFontPath[]; + + Hack80.ta_Name = HackFontPath; HackFont = OpenDiskFont(&Hack80); - Hack80.ta_Name += SIZEOF_DISKNAME; + Hack80.ta_Name = HackFontName; /* Textsfont13 is filled in with "FONT=" settings. The default is * courier/13. @@ -1024,9 +1036,9 @@ amii_init_nhwindows(int *argcp, char **argv) /* Try hack/8 for texts if no user specified font */ if (TextsFont == NULL) { - Hack80.ta_Name -= SIZEOF_DISKNAME; + Hack80.ta_Name = HackFontPath; TextsFont = OpenDiskFont(&Hack80); - Hack80.ta_Name += SIZEOF_DISKNAME; + Hack80.ta_Name = HackFontName; } /* If no fonts, make everything topaz 8 for non-view windows. @@ -1087,16 +1099,11 @@ amii_init_nhwindows(int *argcp, char **argv) NewHackScreen.Width = max(WIDTH, amiIDisplay->xpix); NewHackScreen.Height = max(SCREENHEIGHT, amiIDisplay->ypix); { - static char fname[18]; - sprintf(fname, "NetHack %d.%d.%d", VERSION_MAJOR, VERSION_MINOR, - PATCHLEVEL); + static char fname[32]; + snprintf(fname, sizeof fname, "NetHack %d.%d.%d", + VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL); NewHackScreen.DefaultTitle = fname; } -#if 0 - NewHackScreen.BlockPen = C_BLACK; - NewHackScreen.DetailPen = C_WHITE; -#endif -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { int i; struct DimensionInfo dims; @@ -1115,20 +1122,20 @@ amii_init_nhwindows(int *argcp, char **argv) if (amii_scrnmode == 0xffffffff) { struct ScreenModeRequester *SMR; -#ifdef __GNUC__ SM_FilterHook.h_Entry = (void *) &SM_Filter; -#else - SM_FilterHook.h_Entry = (ULONG (*) ()) SM_Filter; -#endif SM_FilterHook.h_Data = 0; SM_FilterHook.h_SubEntry = 0; SMR = AllocAslRequest(ASL_ScreenModeRequest, NULL); - if (AslRequestTags(SMR, ASLSM_FilterFunc, (ULONG) &SM_FilterHook, - TAG_END)) - amii_scrnmode = SMR->sm_DisplayID; - else + if (SMR) { + if (AslRequestTags(SMR, ASLSM_FilterFunc, + (ULONG) &SM_FilterHook, TAG_END)) + amii_scrnmode = SMR->sm_DisplayID; + else + amii_scrnmode = 0; + FreeAslRequest(SMR); + } else { amii_scrnmode = 0; - FreeAslRequest(SMR); + } } if (forcenobig == 0) { @@ -1209,15 +1216,14 @@ amii_init_nhwindows(int *argcp, char **argv) } } } -#endif if (WINVERS_AMIV) { extern char *tilefile; - if (amii_numcolors >= 32) { - tilefile = "NetHack:tiles/tiles32.iff"; - amii_numcolors = 32; + if (amii_numcolors >= AMIV_PALETTE_SIZE) { + tilefile = (char *) fqname("tiles/tiles32.iff", DATAPREFIX, 0); + amii_numcolors = AMIV_PALETTE_SIZE; } else { - tilefile = "NetHack:tiles/tiles16.iff"; + tilefile = (char *) fqname("tiles/tiles16.iff", DATAPREFIX, 0); } amii_bmhd = ReadTileImageFiles(); } else @@ -1226,7 +1232,7 @@ amii_init_nhwindows(int *argcp, char **argv) /* Find out how deep the screen needs to be, 32 planes is enough! */ for (i = 0; i < 32; ++i) { - if ((1L << i) >= amii_numcolors) + if ((1UL << i) >= (unsigned long) amii_numcolors) break; } @@ -1250,16 +1256,19 @@ amii_init_nhwindows(int *argcp, char **argv) if (--NewHackScreen.Depth < 3) Abort(AN_OpenScreen & ~AT_DeadEnd); } - amii_numcolors = 1L << NewHackScreen.Depth; + amii_numcolors = 1UL << NewHackScreen.Depth; + { + int palmax = WINVERS_AMIV ? AMIV_PALETTE_SIZE : AMII_PALETTE_SIZE; + if (amii_numcolors > palmax) + amii_numcolors = palmax; + } if (HackScreen->Height > 300 && forcenobig == 0) bigscreen = 1; else bigscreen = 0; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) PubScreenStatus(HackScreen, 0); -#endif amiIDisplay->ypix = HackScreen->Height; amiIDisplay->xpix = HackScreen->Width; @@ -1310,6 +1319,7 @@ amii_sethipens(struct Window *w, int type, int attr) case NHW_TEXT: SetAPen(w->RPort, attr ? C_BLACK : amii_textAPen); SetBPen(w->RPort, amii_textBPen); + break; case -2: SetBPen(w->RPort, amii_otherBPen); SetAPen(w->RPort, attr ? C_RED : amii_otherAPen); @@ -1401,7 +1411,7 @@ amii_clear_nhwindow(winid win) /* Clear the overview window too if it is displayed */ if (WINVERS_AMIV - && (cw->type == WIN_MAP && WIN_OVER != WIN_ERR && reclip == 0)) { + && (cw->type == NHW_MAP && WIN_OVER != WIN_ERR && reclip == 0)) { amii_clear_nhwindow(WIN_OVER); } @@ -1537,7 +1547,6 @@ void amii_display_nhwindow(winid win, boolean blocking) { menu_item *mip; - int cnt; static int lastwin = -1; struct amii_WinDesc *cw; @@ -1560,7 +1569,7 @@ amii_display_nhwindow(winid win, boolean blocking) } if (cw->type == NHW_MENU || cw->type == NHW_TEXT) { - cnt = DoMenuScroll(win, blocking, PICK_ONE, &mip); + (void) DoMenuScroll(win, blocking, PICK_ONE, &mip); } else if (cw->type == NHW_MAP) { amii_end_glyphout(win); /* Do more if it is time... */ @@ -1651,17 +1660,12 @@ amii_curs(winid window, int x, int y) rp = w->RPort; if (cw->type == NHW_MENU) { - if (WINVERS_AMIV) { - if (window == WIN_INVEN) { - Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1 - + pictdata.xsize + 4, - (y * max(rp->TxHeight, pictdata.ysize + 3)) - + rp->TxBaseline + pictdata.ysize - rp->TxHeight - + w->BorderTop + 4); - } else { - Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1, - (y * rp->TxHeight) + rp->TxBaseline + w->BorderTop + 1); - } + if (WINVERS_AMIV && cw->menu.has_glyphs) { + Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1 + + pictdata.xsize + 4, + (y * max(rp->TxHeight, pictdata.ysize + 3)) + + rp->TxBaseline + pictdata.ysize - rp->TxHeight + + w->BorderTop + 4); } else { Move(rp, (x * rp->TxWidth) + w->BorderLeft + 1, (y * rp->TxHeight) + rp->TxBaseline + w->BorderTop + 1); @@ -1685,11 +1689,6 @@ amii_curs(winid window, int x, int y) if (WINVERS_AMIV) { if (cw->type == NHW_MAP) { if (Is_rogue_level(&u.uz)) { -#if 0 -int qqx= (x * w->RPort->TxWidth) + w->BorderLeft; -int qqy= w->BorderTop + ( (y+1) * w->RPort->TxHeight ) + 1; -printf("pos: (%d,%d)->(%d,%d)\n",x,y,qqx,qqy); -#endif SetAPen(w->RPort, C_WHITE); /* XXX should be elsewhere (was 4)*/ Move(rp, (x * w->RPort->TxWidth) + w->BorderLeft, @@ -1745,7 +1744,7 @@ amii_set_text_font(char *name, int size) /* Look for windows to set, and change them */ - if (DiskfontBase = OpenLibrary("diskfont.library", amii_libvers)) { + if ((DiskfontBase = OpenLibrary("diskfont.library", amii_libvers))) { TextsFont = OpenDiskFont(&TextsFont13); for (i = 0; TextsFont && i < MAXWIN; ++i) { if ((cw = amii_wins[i]) && cw->win != NULL) { @@ -1764,9 +1763,9 @@ amii_set_text_font(char *name, int size) } } } + CloseLibrary(DiskfontBase); + DiskfontBase = NULL; } - CloseLibrary(DiskfontBase); - DiskfontBase = NULL; } void @@ -1893,12 +1892,7 @@ cursor_on(winid window) /* Save the current information */ -#ifdef DISPMAP - if (WINVERS_AMIV && cw->type == NHW_MAP && !Is_rogue_level(&u.uz)) - x = cw->cursx = (rp->cp_x & -8) + 8; - else -#endif - x = cw->cursx = rp->cp_x; + x = cw->cursx = rp->cp_x; y = cw->cursy = rp->cp_y; apen = rp->FgPen; bpen = rp->BgPen; @@ -1992,6 +1986,8 @@ removetopl(int cnt) void port_help(void) { + /* display_file -> dlb_fopen -> fopen_datafile already routes through + DATAPREFIX; pass the bare filename. */ display_file(PORT_HELP, 1); } #endif @@ -2036,15 +2032,6 @@ amii_print_glyph(winid win, coordxy x, coordxy y, panic(winpanicstr, win, "amii_print_glyph"); } -#if 0 -{ -static int x=-1; -if(u.uz.dlevel != x){ - fprintf(stderr,"lvlchg: %d (%d)\n",u.uz.dlevel,Is_rogue_level(&u.uz)); - x = u.uz.dlevel; -} -} -#endif if (WINVERS_AMIV && !Is_rogue_level(&u.uz)) { amii_curs(win, x, y); amiga_print_glyph(win, 0, glyph); diff --git a/sys/amiga/winkey.c b/sys/amiga/winkey.c index f2686bfde..57e47165c 100644 --- a/sys/amiga/winkey.c +++ b/sys/amiga/winkey.c @@ -2,15 +2,9 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif int amii_nh_poskey(coordxy *x, coordxy *y, int *mod) diff --git a/sys/amiga/winproto.h b/sys/amiga/winproto.h index d855e50fe..60bb1adf9 100644 --- a/sys/amiga/winproto.h +++ b/sys/amiga/winproto.h @@ -53,14 +53,13 @@ void SetPropInfo(struct Window *win, struct Gadget *gad, long vis, long total, struct Window *OpenShWindow(struct NewWindow *nw); void CloseShWindow(struct Window *win); int ConvertKey(struct IntuiMessage *message); +void ProcessMessage(struct IntuiMessage *message); int kbhit(void); int amikbhit(void); int WindowGetchar(void); WETYPE WindowGetevent(void); void amii_cleanup(void); -#ifndef SHAREDLIB -void Abort(long rc); -#endif +void Abort(long rc) NORETURN; void CleanUp(void); void flush_glyph_buffer(struct Window *w); void amiga_print_glyph(winid window, int color_index, int glyph); @@ -71,10 +70,8 @@ void FreeNewWindow(struct NewWindow *win); void bell(void); void amii_delay_output(void); void amii_number_pad(int state); -#ifndef SHAREDLIB void amiv_loadlib(void); void amii_loadlib(void); -#endif void preserve_icon(void); void clear_icon(void); @@ -114,10 +111,6 @@ BitMapHeader ReadTileImageFiles(void); void FreeTileImageFiles(void); /* winami.c */ -#ifdef SHAREDLIB -int __UserLibInit(void); -void __UserLibCleanup(void); -#endif void amii_askname(void); void amii_player_selection(void); void RandomWindow(char *name); @@ -127,16 +120,6 @@ void amii_display_file(const char *fn, boolean complain); void SetBorder(struct Gadget *gd); /* malloc/free provided by stdlib.h */ -#ifdef SHAREDLIB -/* amilib.c */ -void amii_loadlib(void); -void amiv_loadlib(void); -void CleanUp(void); -void setup_librefs(WinamiBASE *base); -#else -void Abort(long rc); -#endif - win_request_info *amii_ctrl_nhwindow(winid, int, win_request_info *); /* amirip.c */ @@ -145,7 +128,3 @@ void amii_outrip(winid tmpwin, int how, time_t when); /* winchar.c */ void SetMazeType(MazeType); int GlyphToIcon(int glyph); -#ifdef OPT_DISPMAP -void dispmap_sanity(void); -int dispmap_sanity1(int); -#endif diff --git a/sys/amiga/winreq.c b/sys/amiga/winreq.c index 910adeb86..4b3056838 100644 --- a/sys/amiga/winreq.c +++ b/sys/amiga/winreq.c @@ -2,15 +2,9 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif #define GADBLUEPEN 2 #define GADREDPEN 3 @@ -27,8 +21,8 @@ struct IntuiText IText1 = { 3, 0, JAM1, 4, 1, NULL, (UBYTE *) "Cancel", struct Gadget Gadget2 = { NULL, 9, 15, 56, 10, NULL, RELVERIFY, BOOLGADGET, (APTR) &Border1, NULL, &IText1, NULL, NULL, 1, NULL }; -UBYTE StrStringSIBuff[300]; -struct StringInfo StrStringSInfo = { StrStringSIBuff, UNDOBUFFER, 0, 300, 0, +UBYTE StrStringSIBuff[BUFSZ]; +struct StringInfo StrStringSInfo = { StrStringSIBuff, UNDOBUFFER, 0, BUFSZ, 0, 0, 0, 0, 0, 0, 0, 0, NULL }; SHORT BorderVectors2[] = { 0, 0, 439, 0, 439, 11, 0, 11, 0, 0 }; struct Border Border2 = { -1, -1, 3, 0, JAM1, 5, BorderVectors2, NULL }; @@ -45,11 +39,7 @@ struct NewWindow StrWindow = { &String, NULL, NULL, NULL, NULL, 5, 5, 0xffff, 0xffff, CUSTOMSCREEN }; -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/colorwin.c" -#else #include "colorwin.c" -#endif #define XSIZE 2 #define YSIZE 3 @@ -58,11 +48,7 @@ struct NewWindow StrWindow = { #define GADOKAY 6 #define GADCANCEL 7 -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/clipwin.c" -#else #include "clipwin.c" -#endif void ClearCol(struct Window *w); @@ -117,22 +103,16 @@ EditColor(void) svcolors[i] = colors[i] = GetRGB4(scrn->ViewPort.ColorMap, i); Col_NewWindowStructure1.Screen = scrn; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { ((struct PropInfo *) Col_BluePen.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) Col_RedPen.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) Col_GreenPen.SpecialInfo)->Flags |= PROPNEWLOOK; } -#endif - if (WINVERS_AMIV || WINVERS_AMII) { -#ifdef INTUI_NEW_LOOK - Col_NewWindowStructure1.Extension = wintags; - Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *) -2; - fillhook.h_SubEntry = 0; -#endif - } + Col_NewWindowStructure1.Extension = wintags; + Col_NewWindowStructure1.Flags |= WFLG_NW_EXTENDED; + fillhook.h_Entry = (void *) &LayerFillHook; + fillhook.h_Data = (void *) -2; + fillhook.h_SubEntry = 0; nw = OpenWindow((void *) &Col_NewWindowStructure1); @@ -207,14 +187,23 @@ EditColor(void) break; } - strcpy(oname, dirname((char *) configfile)); - if (oname[strlen(oname) - 1] != ':') { - sprintf(nname, "%s/New_NetHack.cnf", oname); - strcat(oname, "/"); - strcat(oname, "Old_NetHack.cnf"); - } else { - sprintf(nname, "%sNew_NetHack.cnf", oname); - strcat(oname, "Old_NetHack.cnf"); + { + size_t olen; + strncpy(oname, dirname((char *) configfile), + sizeof(oname) - 1); + oname[sizeof(oname) - 1] = '\0'; + olen = strlen(oname); + if (olen > 0 && oname[olen - 1] != ':') { + Snprintf(nname, sizeof nname, + "%s/New_NetHack.cnf", oname); + Snprintf(oname + olen, sizeof(oname) - olen, + "/Old_NetHack.cnf"); + } else { + Snprintf(nname, sizeof nname, + "%sNew_NetHack.cnf", oname); + Snprintf(oname + olen, sizeof(oname) - olen, + "Old_NetHack.cnf"); + } } nfp = fopen(nname, "w"); @@ -372,23 +361,17 @@ EditClipping(void) once = 1; } ClipNewWindowStructure1.Screen = scrn; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { ((struct PropInfo *) ClipXSIZE.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) ClipYSIZE.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) ClipXCLIP.SpecialInfo)->Flags |= PROPNEWLOOK; ((struct PropInfo *) ClipYCLIP.SpecialInfo)->Flags |= PROPNEWLOOK; } -#endif - if (WINVERS_AMIV || WINVERS_AMII) { -#ifdef INTUI_NEW_LOOK - ClipNewWindowStructure1.Extension = wintags; - ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *) -2; - fillhook.h_SubEntry = 0; -#endif - } + ClipNewWindowStructure1.Extension = wintags; + ClipNewWindowStructure1.Flags |= WFLG_NW_EXTENDED; + fillhook.h_Entry = (void *) &LayerFillHook; + fillhook.h_Data = (void *) -2; + fillhook.h_SubEntry = 0; nw = OpenWindow((void *) &ClipNewWindowStructure1); @@ -399,11 +382,9 @@ EditClipping(void) ShowClipValues(nw); mflags = AUTOKNOB | FREEHORIZ; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { mflags |= PROPNEWLOOK; } -#endif for (i = 0; i < 7; ++i) { if (mxsize <= sizes[i]) @@ -470,9 +451,6 @@ EditClipping(void) yclipbord = aidx + 2; } ShowClipValues(nw); -#ifdef OPT_DISPMAP - dispmap_sanity(); -#endif } else if (gd->GadgetID == GADOKAY) { done = 1; okay = 1; @@ -518,9 +496,6 @@ EditClipping(void) SetBPen(nw->RPort, amii_otherBPen); SetDrMd(nw->RPort, JAM2); Text(nw->RPort, buf, strlen(buf)); -#ifdef OPT_DISPMAP - dispmap_sanity(); -#endif break; } } @@ -540,20 +515,19 @@ EditClipping(void) char * dirname(char *str) { - char *t, c; static char dir[300]; + char *t; - t = strrchr(str, '/'); + strncpy(dir, str, sizeof(dir) - 1); + dir[sizeof(dir) - 1] = '\0'; + + t = strrchr(dir, '/'); + if (!t) + t = strrchr(dir, ':'); if (!t) - t = strrchr(str, ':'); - if (!t) { dir[0] = '\0'; - } else { - c = *t; - *t = 0; - strcpy(dir, str); - *t = c; - } + else + *t = '\0'; return (dir); } @@ -582,12 +556,9 @@ filecopy(char *from, char *to) if (buf) { sprintf(buf, "c:copy \"%s\" \"%s\" clone", from, to); -/* Check SysBase instead? Shouldn't matter */ -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) i = System(buf, NULL); else -#endif Execute(buf, NULL, NULL); free(buf); } else { @@ -716,11 +687,9 @@ DrawCol(struct Window *w, int idx, UWORD *colors) b = colors[idx] & 0x00f; mflags = AUTOKNOB | FREEHORIZ; -#ifdef INTUI_NEW_LOOK if (IntuitionBase->LibNode.lib_Version >= 37) { mflags |= PROPNEWLOOK; } -#endif NewModifyProp(&Col_RedPen, w, NULL, mflags, (r * MAXPOT) / 15, 0, MAXPOT / 15, 0, 1); NewModifyProp(&Col_GreenPen, w, NULL, mflags, (g * MAXPOT) / 15, 0, @@ -735,6 +704,9 @@ DispCol(struct Window *w, int idx, UWORD *colors) char buf[50]; char *colname, *defval; + if (idx < 0 || idx >= amii_numcolors) + return; + if (WINVERS_AMIV) { colname = amiv_colnames[idx].name; defval = amiv_colnames[idx].defval; @@ -759,7 +731,6 @@ DispCol(struct Window *w, int idx, UWORD *colors) void amii_setpens(int count) { -#ifdef INTUI_NEW_LOOK struct EasyStruct ea = { sizeof(struct EasyStruct), 0l, "NetHack Request", "Number of pens requested(%ld) not correct", "Use default pens|Use requested pens" }; @@ -768,12 +739,9 @@ amii_setpens(int count) "Number of pens requested(%ld) not\ncompatible " "with game configuration(%ld)", "Use default pens|Use requested pens" }; -#endif -/* If the pens in amii_curmap are - * more pens than in amii_numcolors, then we choose to ignore - * those pens. - */ -#ifdef INTUI_NEW_LOOK + + /* If the pens in amii_curmap are more than in amii_numcolors, ignore + * the extras. */ if (IntuitionBase && IntuitionBase->LibNode.lib_Version >= 39) { if (count != amii_numcolors) { long args[2]; @@ -791,9 +759,7 @@ amii_setpens(int count) amii_numcolors * sizeof(amii_initmap[0])); } } - } else -#endif - if (count != amii_numcolors) { + } else if (count != amii_numcolors) { memcpy(sysflags.amii_curmap, amii_initmap, amii_numcolors * sizeof(amii_initmap[0])); } @@ -848,15 +814,11 @@ getlind(const char *prompt, char *bufp, const char *dflt) once = 1; } - if (WINVERS_AMIV || WINVERS_AMII) { -#ifdef INTUI_NEW_LOOK - StrWindow.Extension = wintags; - StrWindow.Flags |= WFLG_NW_EXTENDED; - fillhook.h_Entry = (void *) &LayerFillHook; - fillhook.h_Data = (void *) -2; - fillhook.h_SubEntry = 0; -#endif - } + StrWindow.Extension = wintags; + StrWindow.Flags |= WFLG_NW_EXTENDED; + fillhook.h_Entry = (void *) &LayerFillHook; + fillhook.h_Data = (void *) -2; + fillhook.h_SubEntry = 0; if ((cwin = OpenWindow((void *) &StrWindow)) == NULL) { return; diff --git a/sys/amiga/winstr.c b/sys/amiga/winstr.c index a3801fff1..9d3e207f4 100644 --- a/sys/amiga/winstr.c +++ b/sys/amiga/winstr.c @@ -2,15 +2,9 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef CROSS_TO_AMIGA -#include "NH:sys/amiga/windefs.h" -#include "NH:sys/amiga/winext.h" -#include "NH:sys/amiga/winproto.h" -#else #include "windefs.h" #include "winext.h" #include "winproto.h" -#endif /* Put a string into the indicated window using the indicated attribute */ void @@ -131,8 +125,25 @@ amii_putstr(winid window, int attr, const char *str) p = (char *) str; if (p == str) { - /* p = (char *)&str[ cw->cols ]; */ - outmore(cw); + /* No whitespace within visible width. */ + if (cw->curx > 0) { + /* Mid-line: clear it and retry at column 0. */ + outmore(cw); + continue; + } + /* Already at line start: word is longer than one + * line, so force-break it at the column boundary. */ + i = cw->cols - 1 - fudge; + if (i <= 0) + i = 1; + if ((size_t) i > strlen(str)) + i = strlen(str); + outsubstr(cw, (char *) str, i, fudge); + cw->curx += i; + str += i; + if (*str) + amii_scrollmsg(w, cw); + amii_cl_end(cw, cw->curx); continue; } @@ -144,12 +155,6 @@ amii_putstr(winid window, int attr, const char *str) p++; str = p; -#if 0 - if( str != ostr ) { - outsubstr( cw, "+", 1, fudge ); - cw->curx+=2; - } -#endif if (*str) amii_scrollmsg(w, cw); amii_cl_end(cw, cw->curx); @@ -217,6 +222,7 @@ amii_putstr(winid window, int attr, const char *str) TextSpaces(w->RPort, cw->cols); cw->cury--; } + wrapping = 0; } amii_curs(window, cw->curx + 1, cw->cury); Text(w->RPort, (char *) str, strlen((char *) str)); diff --git a/sys/amiga/xpm2iff_host.c b/sys/amiga/xpm2iff_host.c index 589d4f56f..5a968979e 100644 --- a/sys/amiga/xpm2iff_host.c +++ b/sys/amiga/xpm2iff_host.c @@ -62,12 +62,13 @@ xpmgetline(void) /* strip trailing <",> and whitespace */ for (bp = xbuf; *bp; bp++) ; - bp--; - while (isspace((unsigned char)*bp)) + if (bp > xbuf) bp--; - if (*bp == ',') + while (bp > xbuf && isspace((unsigned char)*bp)) bp--; - if (*bp == '"') + if (bp > xbuf && *bp == ',') + bp--; + if (bp > xbuf && *bp == '"') bp--; bp++; *bp = '\0'; @@ -209,10 +210,19 @@ main(int argc, char **argv) return 1; } + if (XpmScreen.Colors < 1 || XpmScreen.Colors > 256) { + fprintf(stderr, + "xpm2iff_host: unsupported color count %d\n", + XpmScreen.Colors); + return 1; + } + /* nplanes = ceil(log2(Colors)) */ nplanes = 0; i = XpmScreen.Colors - 1; while (i > 0) { nplanes++; i >>= 1; } + if (nplanes == 0) + nplanes = 1; colors = 1 << nplanes; diff --git a/sys/libnh/README.md b/sys/libnh/README.md index b887b5730..3a9c14d1d 100644 --- a/sys/libnh/README.md +++ b/sys/libnh/README.md @@ -12,14 +12,14 @@ Generally the build is the same as the unix build: [Edit Oct 4, 2020: Use the existing Makefile and hints, hints/include system for cross-compiles] 1. `cd sys/unix` -2. `./setup.sh hints/macOS.370` +2. `./setup.sh hints/macOS.500` 3. `cd ../..` 4. For `libnethack.a`: `make WANT_LIBNH=1 all` 5. For `nethack.js`: `make CROSS_TO_WASM=1 all` [Original text was:] 1. `cd sys/lib` -2. For `libnethack.a`: `./setup.sh hints/macOS.370`; for `nethack.js`: `./setup.sh hints/wasm` +2. For `libnethack.a`: `./setup.sh hints/macOS.500`; for `nethack.js`: `./setup.sh hints/wasm` 3. `cd ../..` 4. `make` diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 44765987e..acdea170e 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 libnhmain.c $NHDT-Date: 1693359589 2023/08/30 01:39:49 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 5.0 libnhmain.c $NHDT-Date: 1693359589 2023/08/30 01:39:49 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.106 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -37,7 +37,7 @@ extern struct passwd *getpwnam(const char *); #ifdef CHDIR static void chdirx(const char *, boolean); #endif /* CHDIR */ -static boolean whoami(void); +boolean whoami(void); static void process_options(int, char **); #ifdef _M_UNIX @@ -51,7 +51,7 @@ extern void init_linux_cons(void); static void wd_message(void); static struct passwd *get_unix_pw(void); -ATTRNORETURN static void opt_terminate(void) NORETURN; +/* ATTRNORETURN static void opt_terminate(void) NORETURN; */ #ifdef __EMSCRIPTEN__ /* if WebAssembly, export this API and don't optimize it out */ @@ -516,7 +516,7 @@ chdirx(const char *dir, boolean wr) #endif /* CHDIR */ /* returns True iff we set plname[] to username which contains a hyphen */ -static boolean +boolean whoami(void) { /* @@ -769,6 +769,8 @@ sys_random_seed(void) return seed; } +#if 0 +/* now found in earlyarg.c */ /* for command-line options that perform some immediate action and then terminate the program without starting play, like 'nethack --version' or 'nethack -s Zelda'; do some cleanup before that termination */ @@ -780,7 +782,6 @@ opt_terminate(void) nh_terminate(EXIT_SUCCESS); /*NOTREACHED*/ } - /* show the sysconf file name, playground directory, run-time configuration file name, dumplog file name if applicable, and some other things */ ATTRNORETURN void @@ -794,6 +795,49 @@ after_opt_showpaths(const char *dir) opt_terminate(); /*NOTREACHED*/ } +#endif + +void +get_nhuuid(void) +{ + unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + char *uuid = (char *) &stmp[0]; +#ifndef NONHUUID +#ifdef __EMSCRIPTEN__ + int uuid_available = 0; +#endif +#endif + + if (svn.nhuuid[0]) + return; + +#ifndef NONHUUID +#ifdef __EMSCRIPTEN__ + uuid_available = emscripten_run_script_int( + "typeof crypto !== 'undefined'" + " && typeof crypto.randomUUID === 'function'"); + if (uuid_available) { + uuid = emscripten_run_script_string("crypto.randomUUID()"); + if (!uuid) { + uuid = (char *) &stmp[0]; + } + } +#endif /* __EMSCRIPTEN__ */ +#endif /* NONHUUID */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", uuid); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} #ifdef __EMSCRIPTEN__ /*** @@ -1048,6 +1092,7 @@ void js_constants_init() { SET_CONSTANT("GLYPH", GLYPH_SWALLOW_OFF); SET_CONSTANT("GLYPH", GLYPH_WARNING_OFF); SET_CONSTANT("GLYPH", GLYPH_STATUE_OFF); + SET_CONSTANT("GLYPH", GLYPH_PILETOP_OFF); SET_CONSTANT("GLYPH", GLYPH_UNEXPLORED_OFF); SET_CONSTANT("GLYPH", GLYPH_NOTHING_OFF); SET_CONSTANT("GLYPH", MAX_GLYPH); diff --git a/sys/libnh/sysconf b/sys/libnh/sysconf index 52148449d..af871c187 100644 --- a/sys/libnh/sysconf +++ b/sys/libnh/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.7 sysconf $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ +# NetHack 5.0 sysconf $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. # @@ -102,7 +102,7 @@ HIDEUSAGE=1 # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format diff --git a/sys/libnh/test/run.sh b/sys/libnh/test/run.sh index 96ead1482..f16571495 100755 --- a/sys/libnh/test/run.sh +++ b/sys/libnh/test/run.sh @@ -6,7 +6,7 @@ if [ x$1 == "xlib" ]; then make spotless fi cd sys/unix - ./setup.sh hints/macOS.370 + ./setup.sh hints/macOS.500 cd ../.. make WANT_LIBNH=1 fi @@ -25,7 +25,7 @@ if [ x$1 == "xwasm" ]; then make spotless fi cd sys/unix - ./setup.sh hints/macOS.370 + ./setup.sh hints/macOS.500 cd ../.. make CROSS_TO_WASM=1 fi @@ -38,7 +38,7 @@ if [ x$1 == "xbin" ]; then echo Doing bin... make spotless cd sys/unix - ./setup.sh hints/macOS.370 + ./setup.sh hints/macOS.500 cd ../.. make fi diff --git a/sys/msdos/Install.dos b/sys/msdos/Install.dos index e60eb72b3..7a13938a5 100644 --- a/sys/msdos/Install.dos +++ b/sys/msdos/Install.dos @@ -1,14 +1,14 @@ - Copyright (c) NetHack PC Development Team 1990-2023. + Copyright (c) NetHack PC Development Team 1990-2026. NetHack may be freely redistributed. See license for details. ============================================================== Instructions for compiling and installing - NetHack 3.7 on a DOS system + NetHack 5.0 on a DOS system ====================================================== - (or, How to make PC NetHack 3.7) + (or, How to make PC NetHack 5.0) Last revision: $NHDT-Date: 1596508786 2021/06/04 08:45:00 $ -Credit for a runnable full PC NetHack 3.7 goes to the PC Development team +Credit for a runnable full PC NetHack 5.0 goes to the PC Development team of Paul Winner, Kevin Smolkowski, Michael Allison, Yitzhak Sapir, Bill Dyer, Timo Hakulinen, Yamamoto Keizo, Mike Threepoint, Mike Stephenson, Stephen White, Ken Washikita and Janet Walz. The present port is based @@ -61,7 +61,7 @@ II. There once was a time when people built NetHack right on their DOS machine. sys/msdos/fetch-cross-compiler.sh That script won't install anything, it just does file fetches and stores - them in subfolders of lib. The linux.370 and macOS.370 hints files are + them in subfolders of lib. The linux.500 and macOS.500 hints files are configured to find the cross-compiler there if you add CROSS_TO_MSDOS=1 on your make command line. @@ -72,12 +72,12 @@ II. There once was a time when people built NetHack right on their DOS machine. On your linux host: - cd sys/unix ; sh setup.sh hints/linux.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/linux.500 ; cd ../.. make fetch-lua On your macOS host: - cd sys/unix ; sh setup.sh hints/macOS.370 ; cd ../.. + cd sys/unix ; sh setup.sh hints/macOS.500 ; cd ../.. make fetch-lua The MSDOS cross-compile can then be carried out by specifying @@ -96,11 +96,22 @@ II. There once was a time when people built NetHack right on their DOS machine. make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 WANT_DOSVGA=1 package + For the TTY interface, use NO_TILES=1 to drop support for tiles. The + resulting TTY interface can still support Unicode if that is enabled + in include/config.h. + + For the TTY interface, use NO_GRAPHICS=1 to drop all graphics support, and + build a NetHack that outputs through the standard output channel. This + configuration requires ANSI.SYS, or an equivalent driver such as NANSI.SYS. + The curses interface will still use graphics if WANT_DOSVGA=1 is set. + + NO_GRAPHICS=1 takes priority of NO_TILES=1. + Result: The "make package" target will bundle all of the necessary components to run NetHack on msdos into a folder: targets/msdos/pkg and then it zips the contents of that folder into: - targets/msdos/nh370dos.zip + targets/msdos/NH500DOS.ZIP Also note that building the msdos targets using the make command above, does not preclude you from building local linux or macOS diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 782e1cd5c..1f8107826 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -1,9 +1,9 @@ -# NetHack 3.7 Makefile.GCC $NHDT-Date: 1596498268 2020/08/03 23:44:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ +# NetHack 5.0 Makefile.GCC $NHDT-Date: 1596498268 2020/08/03 23:44:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.53 $ # Copyright (c) NetHack PC Development Team 1996-2024. -# PC NetHack 3.7 Makefile for djgpp V2 +# PC NetHack 5.0 Makefile for djgpp V2 # # Gnu gcc compiler for msdos (djgpp) -# Requires Gnu Make utility (V3.79.1 or greater) supplied with djgpp +# Requires Gnu Make utility (V5.09.1 or greater) supplied with djgpp # # For questions or comments: devteam@nethack.org # @@ -61,7 +61,7 @@ endif # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere # you'll need to specify the correct spot below in order to -# successfully build NetHack-3.7. +# successfully build NetHack-5.0. # ADD_LUA=Y LUATOP=../lib/lua$(LUAVER) @@ -288,18 +288,18 @@ VOBJ14 = $(O)muse.o $(O)music.o $(O)o_init.o $(O)objects.o $(O)objnam. VOBJ15 = $(O)options.o $(O)pickup.o $(O)pline.o $(O)polyself.o $(O)potion.o VOBJ16 = $(O)quest.o $(O)questpgr.o $(O)pager.o $(O)pray.o $(O)priest.o VOBJ17 = $(O)read.o $(O)rect.o $(O)region.o $(O)report.o $(O)restore.o -VOBJ18 = $(O)rip.o $(O)rnd.o $(O)role.o $(O)rumors.o $(O)save.o -VOBJ19 = $(O)selvar.o $(O)sfstruct.o $(O)shk.o $(O)shknam.o $(O)sit.o -VOBJ20 = $(O)sounds.o $(O)sp_lev.o $(O)spell.o $(O)stairs.o $(O)steal.o -VOBJ21 = $(O)steed.o $(O)symbols.o $(O)sys.o $(O)teleport.o $(O)strutil.o -VOBJ22 = $(O)termcap.o $(O)timeout.o $(O)topl.o $(O)topten.o $(O)trap.o -VOBJ23 = $(O)u_init.o $(O)uhitm.o $(O)utf8map.o $(O)vault.o $(O)track.o -VOBJ24 = $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o -VOBJ25 = $(O)wintty.o $(O)wizard.o $(O)wizcmds.o $(O)worm.o $(O)worn.o -VOBJ26 = $(O)write.o $(O)zap.o $(O)light.o $(O)dlb.o $(REGEX) +VOBJ18 = $(O)revision.o $(O)rip.o $(O)rnd.o $(O)role.o $(O)rumors.o +VOBJ19 = $(O)save.o $(O)selvar.o $(O)sfstruct.o $(O)shk.o $(O)shknam.o +VOBJ20 = $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o $(O)stairs.o +VOBJ21 = $(O)steal.o $(O)steed.o $(O)symbols.o $(O)sys.o $(O)teleport.o +VOBJ22 = $(O)strutil.o $(O)termcap.o $(O)timeout.o $(O)topl.o $(O)topten.o +VOBJ23 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)utf8map.o $(O)vault.o +VOBJ24 = $(O)track.o $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o +VOBJ25 = $(O)windows.o $(O)wintty.o $(O)wizard.o $(O)wizcmds.o $(O)worm.o +VOBJ26 = $(O)worn.o $(O)write.o $(O)zap.o $(O)light.o $(O)dlb.o $(REGEX) -SOBJ = $(O)msdos.o $(O)pcsys.o $(O)tty.o $(O)unix.o \ - $(O)video.o $(O)vidtxt.o $(O)pckeys.o +SOBJ = $(O)msdos.o $(O)pcsys.o $(O)tty.o $(O)unix.o \ + $(O)video.o $(O)vidtxt.o $(O)pckeys.o VVOBJ = $(O)version.o diff --git a/sys/msdos/fetch-cross-compiler.sh b/sys/msdos/fetch-cross-compiler.sh index 037d3aaf3..d9e7677ac 100755 --- a/sys/msdos/fetch-cross-compiler.sh +++ b/sys/msdos/fetch-cross-compiler.sh @@ -34,13 +34,13 @@ if [ "$(uname)" = "Darwin" ]; then #Mac DJGPP_FILE="djgpp-osx-$GCCVER.tar.bz2" if [ -z "HINTS" ]; then - export HINTS=macOS.370 + export HINTS=macOS.500 fi elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then #Linux DJGPP_FILE="djgpp-linux64-$GCCVER.tar.bz2" if [ -z "$HINTS" ]; then - export HINTS=linux.370 + export HINTS=linux.500 fi elif [ "$(expr substr $(uname -s) 1 10)" = "MINGW32_NT" ]; then #mingw diff --git a/sys/msdos/font.c b/sys/msdos/font.c index f3dfe7d10..3d2c6471f 100755 --- a/sys/msdos/font.c +++ b/sys/msdos/font.c @@ -86,7 +86,7 @@ load_font(const char *filename) bufsize = 0; i = 0; while (i < length) { - unsigned j; + /* unsigned j; */ size = fread(buf + bufsize, 1, sizeof(buf) - bufsize, fp); if (ferror(fp)) goto error; @@ -112,11 +112,27 @@ load_font(const char *filename) bufsize -= strsize; memmove(buf, buf + strsize, bufsize); } - codepoints = uni_8to32(buf2); - for (j = 0; codepoints[j] != 0; ++j) { - add_unicode_index(font, codepoints[j], i); + /* Split the individual mappings and use only single character + mappings */ + char *start = buf2; + while (*start != '\0') { + /* Mapping ends with a 0xFE byte */ + char *end = strchr(start, 0xFE); + if (end == NULL) { + end = start + strlen(start); + } else { + *end = '\0'; + ++end; + } + /* Convert this mapping */ + codepoints = uni_8to32(start); + /* Accept it if it is a single character */ + if (codepoints[0] != 0 && codepoints[1] == 0) { + add_unicode_index(font, codepoints[0], i); + } + free(codepoints); + start = end; } - free(codepoints); if (p != NULL) ++i; } diff --git a/sys/msdos/fonts/makefont.lua b/sys/msdos/fonts/makefont.lua index 78ec760dd..3d9ada65b 100755 --- a/sys/msdos/fonts/makefont.lua +++ b/sys/msdos/fonts/makefont.lua @@ -220,6 +220,9 @@ end for i = 1, next_pos-1 do glyph = font[i] for j = 1, #glyph.code do + if j ~= 1 then + outfile:write("\xFE") + end outfile:write(utf8.char(glyph.code[j])) end outfile:write("\xFF") diff --git a/sys/msdos/fonts/nh-u16b.bdf b/sys/msdos/fonts/nh-u16b.bdf index a4b9cb633..d2eb8f9e3 100644 --- a/sys/msdos/fonts/nh-u16b.bdf +++ b/sys/msdos/fonts/nh-u16b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 8 16 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u16b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 16 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP 00 00 @@ -25,8 +34,34 @@ BITMAP 00 00 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +00 +00 +3C +7E +C3 +DB +DB +C3 +7E +3C +00 +00 +00 +00 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP FF FF @@ -47,6 +82,9 @@ FF ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP 01 01 @@ -65,4 +103,50 @@ BITMAP 01 01 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +00 +00 +00 +0E +13 +61 +81 +C3 +7E +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +54 +54 +54 +54 +54 +54 +54 +54 +54 +54 +00 +00 +00 +00 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u16v.bdf b/sys/msdos/fonts/nh-u16v.bdf index 7bd2669e0..33e7af5d6 100644 --- a/sys/msdos/fonts/nh-u16v.bdf +++ b/sys/msdos/fonts/nh-u16v.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 8 16 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u16v.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 16 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP 00 00 @@ -25,8 +34,34 @@ BITMAP 00 00 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +00 +00 +3C +7E +C3 +DB +DB +C3 +7E +3C +00 +00 +00 +00 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP FF FF @@ -47,6 +82,9 @@ FF ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 BITMAP 01 01 @@ -65,4 +103,50 @@ BITMAP 01 01 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +00 +00 +00 +0E +13 +61 +81 +C3 +7E +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 8 0 +BBX 8 16 0 -4 +BITMAP +00 +00 +54 +54 +54 +54 +54 +54 +54 +54 +54 +54 +00 +00 +00 +00 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u18b.bdf b/sys/msdos/fonts/nh-u18b.bdf index 11a4b1176..ff9196e40 100644 --- a/sys/msdos/fonts/nh-u18b.bdf +++ b/sys/msdos/fonts/nh-u18b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 10 18 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u18b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 18 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP 0000 0000 @@ -27,8 +36,36 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +0000 +0000 +3C00 +7E00 +C300 +DB00 +DB00 +C300 +7E00 +3C00 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP FFC0 FFC0 @@ -51,6 +88,9 @@ FFC0 ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP 0040 0040 @@ -71,4 +111,54 @@ BITMAP 0040 0040 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0F00 +1980 +7080 +C080 +8080 +C180 +7F00 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u20b.bdf b/sys/msdos/fonts/nh-u20b.bdf index 702269414..b510e7cf6 100644 --- a/sys/msdos/fonts/nh-u20b.bdf +++ b/sys/msdos/fonts/nh-u20b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 10 20 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u20b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 20 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 10 0 +BBX 10 20 0 -4 BITMAP 0000 0000 @@ -29,8 +38,38 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +0000 +0000 +0C00 +3F00 +6180 +4080 +CCC0 +CCC0 +4080 +6180 +3F00 +0C00 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP FFC0 FFC0 @@ -55,6 +94,9 @@ FFC0 ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 BITMAP 0040 0040 @@ -77,4 +119,58 @@ BITMAP 0040 0040 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0780 +0FC0 +1CC0 +78C0 +E0C0 +C0C0 +FF80 +7F00 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 556 0 +DWIDTH 10 0 +BBX 10 18 0 -3 +BITMAP +0000 +0000 +0000 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +4900 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u22b.bdf b/sys/msdos/fonts/nh-u22b.bdf index 15de8d761..b4a87bd31 100644 --- a/sys/msdos/fonts/nh-u22b.bdf +++ b/sys/msdos/fonts/nh-u22b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 11 22 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u22b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 22 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 BITMAP 0000 0000 @@ -31,8 +40,40 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0C00 +3F00 +6180 +4080 +CCC0 +CCC0 +4080 +6180 +3F00 +0C00 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 BITMAP FFE0 FFE0 @@ -59,6 +100,9 @@ FFE0 ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 BITMAP 0060 0060 @@ -83,4 +127,62 @@ BITMAP 0060 0060 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0780 +0FC0 +1CC0 +78C0 +E0C0 +C0C0 +FF80 +7F00 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 11 0 +BBX 11 22 0 -5 +BITMAP +0000 +0000 +0000 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +0000 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u24b.bdf b/sys/msdos/fonts/nh-u24b.bdf index bea34cc68..90b6278cd 100644 --- a/sys/msdos/fonts/nh-u24b.bdf +++ b/sys/msdos/fonts/nh-u24b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 12 24 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u24b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 24 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 BITMAP 0000 0000 @@ -33,8 +42,42 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0F00 +3FC0 +70E0 +6060 +C030 +C630 +C630 +C030 +6060 +70E0 +3FC0 +0F00 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 BITMAP FFF0 FFF0 @@ -63,6 +106,9 @@ FFF0 ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 BITMAP 0030 0030 @@ -89,4 +135,66 @@ BITMAP 0030 0030 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +03C0 +07E0 +0E60 +3C60 +7060 +6060 +7FC0 +3F80 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 12 0 +BBX 12 24 0 -5 +BITMAP +0000 +0000 +0000 +0000 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +6660 +0000 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u28b.bdf b/sys/msdos/fonts/nh-u28b.bdf index 2b3954771..78aa22ced 100644 --- a/sys/msdos/fonts/nh-u28b.bdf +++ b/sys/msdos/fonts/nh-u28b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 14 28 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u28b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 28 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 BITMAP 0000 0000 @@ -37,8 +46,46 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0780 +1FE0 +3870 +6018 +6018 +C30C +C78C +C78C +C30C +6018 +6018 +3870 +1FE0 +0780 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 BITMAP FFFC FFFC @@ -71,6 +118,9 @@ FFFC ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 BITMAP 000C 000C @@ -101,4 +151,74 @@ BITMAP 000C 000C ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +01E0 +03F8 +07F8 +3F1C +7E0C +F00C +C00C +C00C +C01C +FFF8 +7FF8 +3FE0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 14 0 +BBX 14 28 0 -6 +BITMAP +0000 +0000 +0000 +0000 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +3330 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/fonts/nh-u32b.bdf b/sys/msdos/fonts/nh-u32b.bdf index e5cf7f2a8..356fa3765 100644 --- a/sys/msdos/fonts/nh-u32b.bdf +++ b/sys/msdos/fonts/nh-u32b.bdf @@ -1,12 +1,21 @@ STARTFONT 2.1 FONTBOUNDINGBOX 16 32 -STARTPROPERTIES 3 +STARTPROPERTIES 8 NOTICE "Additional characters to use with ter-u32b.bdf" -COPYRIGHT "Copyright 2022 Ray Chason." +COPYRIGHT "Copyright 2022, 2026 Ray Chason." +NOTICE "Cloud glyph adapted from the uw-ptty0 font at" +NOTICE "https://people.mpi-inf.mpg.de/~uwe/misc/uw-ttyp0/" NOTICE "NetHack may be freely redistributed. See license for details." +PIXEL_SIZE 32 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" ENDPROPERTIES +CHARS 6 STARTCHAR tripletilde ENCODING 8779 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 BITMAP 0000 0000 @@ -41,8 +50,50 @@ BITMAP 0000 0000 ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +07E0 +1FF8 +381C +6006 +6006 +C003 +C183 +C3C3 +C3C3 +C183 +C003 +6006 +6006 +381C +1FF8 +07E0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR STARTCHAR uppereighth ENCODING 9620 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 BITMAP FFFF FFFF @@ -79,6 +130,9 @@ FFFF ENDCHAR STARTCHAR righteighth ENCODING 9621 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 BITMAP 0002 0002 @@ -113,4 +167,82 @@ BITMAP 0002 0002 ENDCHAR +STARTCHAR uni2601 +ENCODING 9729 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +00F0 +01FC +03FC +1F8E +3F06 +7806 +6006 +6006 +600E +7FFC +3FFC +1FF0 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR +STARTCHAR uni2980 +ENCODING 10624 +SWIDTH 500 0 +DWIDTH 16 0 +BBX 16 32 0 -6 +BITMAP +0000 +0000 +0000 +0000 +0000 +0000 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +6318 +0000 +0000 +0000 +0000 +0000 +0000 +ENDCHAR ENDFONT diff --git a/sys/msdos/msdos.c b/sys/msdos/msdos.c index 86adbd4bb..e14210dfb 100644 --- a/sys/msdos/msdos.c +++ b/sys/msdos/msdos.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 msdos.c $NHDT-Date: 1596498269 2020/08/03 23:44:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 msdos.c $NHDT-Date: 1596498269 2020/08/03 23:44:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) NetHack PC Development Team 1990 */ /* NetHack may be freely redistributed. See license for details. */ @@ -57,10 +57,11 @@ unsigned long sys_random_seed(void); static char *getdta(void); #endif static unsigned int dos_ioctl(int, int, unsigned); -#ifdef TILES_IN_GLYPHMAP +#ifdef NO_TERMS extern boolean pckeys(unsigned char, unsigned char); /* pckeys.c */ #endif +#ifdef TTY_GRAPHICS int tgetch(void) { @@ -86,6 +87,7 @@ tgetch(void) #endif return ((ch == '\r') ? '\n' : ch); } +#endif /* TTY_GRAPHICS */ /* * Keyboard translation tables. @@ -280,7 +282,7 @@ BIOSgetch(void) else ch = kpad[scan - KEYPADLO].normal; } -#ifdef TILES_IN_GLYPHMAP +#ifdef NO_TERMS /* Check for special interface manipulation keys */ if (pckeys(scan, shift)) { ch = 0xFF; @@ -349,16 +351,6 @@ DOSgetch(void) return (ch); } -char -switchar(void) -{ - union REGS regs; - - regs.x.ax = GETSWITCHAR; - intdos(®s, ®s); - return regs.h.dl; -} - #if 0 static long freediskspace(char *path) diff --git a/sys/msdos/msdoshlp.txt b/sys/msdos/msdoshlp.txt index a56018236..b255f6f45 100644 --- a/sys/msdos/msdoshlp.txt +++ b/sys/msdos/msdoshlp.txt @@ -1,4 +1,4 @@ - MSDOS specific help file for NetHack 3.7 + MSDOS specific help file for NetHack 5.0 (Last Revision: December 4, 1999) Copyright (c) NetHack PC Development Team 1993-1999. diff --git a/sys/msdos/pckeys.c b/sys/msdos/pckeys.c index 5e5c1ee69..bc4649308 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pckeys.c $NHDT-Date: 1596498270 2020/08/03 23:44:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 pckeys.c $NHDT-Date: 1596498270 2020/08/03 23:44:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) NetHack PC Development Team 1996 */ /* NetHack may be freely redistributed. See license for details. */ @@ -8,16 +8,17 @@ #include "hack.h" -#ifdef MSDOS -#ifdef TILES_IN_GLYPHMAP +#if defined(MSDOS) && defined(NO_TERMS) #include "wintty.h" #include "pcvideo.h" boolean pckeys(unsigned char, unsigned char); -static void userpan(boolean); +#ifdef TILES_IN_GLYPHMAP +static void userpan(enum vga_pan_direction pan); static void overview(boolean); static void traditional(boolean); static void refresh(void); +#endif extern struct WinDesc *wins[MAXWIN]; /* from wintty.c */ extern boolean inmap; /* from video.c */ @@ -34,9 +35,15 @@ extern boolean inmap; /* from video.c */ boolean pckeys(unsigned char scancode, unsigned char shift) { +#ifdef TILES_IN_GLYPHMAP boolean opening_dialog; opening_dialog = svp.pl_character[0] ? FALSE : TRUE; +#endif + +#ifndef TILES_IN_GLYPHMAP + nhUse(shift); +#endif switch (scancode) { #ifdef SIMULATE_CURSOR case 0x3d: /* F3 = toggle cursor type */ @@ -47,13 +54,28 @@ pckeys(unsigned char scancode, unsigned char shift) DrawCursor(); break; #endif +#ifdef TILES_IN_GLYPHMAP case 0x74: /* Control-right_arrow = scroll horizontal to right */ if ((shift & CTRL) && iflags.tile_view && !opening_dialog) - userpan(1); + userpan(pan_right); break; case 0x73: /* Control-left_arrow = scroll horizontal to left */ if ((shift & CTRL) && iflags.tile_view && !opening_dialog) - userpan(0); + userpan(pan_left); + break; + /* Dosbox reports control-up and down arrows, but VirtualBox and QEMU + don't; accept home, end, page up and page down also */ + case 0x77: /* control-home */ + case 0x8D: /* control-up_arrow */ + case 0x84: /* control-page_up */ + if ((shift & CTRL) && iflags.tile_view && !opening_dialog) + userpan(pan_up); + break; + case 0x75: /* control-end */ + case 0x91: /* control-down_arrow */ + case 0x76: /* control-page_down */ + if ((shift & CTRL) && iflags.tile_view && !opening_dialog) + userpan(pan_down); break; case 0x3E: /* F4 = toggle overview mode */ if (iflags.tile_view && !opening_dialog && !Is_rogue_level(&u.uz)) { @@ -69,22 +91,24 @@ pckeys(unsigned char scancode, unsigned char shift) refresh(); } break; +#endif /* TILES_IN_GLYPHMAP */ default: return FALSE; } return TRUE; } +#ifdef TILES_IN_GLYPHMAP static void -userpan(boolean on) +userpan(enum vga_pan_direction pan) { #ifdef SCREEN_VGA if (iflags.usevga) - vga_userpan(on); + vga_userpan(pan); #endif #ifdef SCREEN_VESA if (iflags.usevesa) - vesa_userpan(on); + vesa_userpan(pan); #endif } @@ -127,6 +151,6 @@ refresh(void) #endif } #endif /* TILES_IN_GLYPHMAP */ -#endif /* MSDOS */ +#endif /* MSDOS && NO_TERMS */ /*pckeys.c*/ diff --git a/sys/msdos/pctiles.c b/sys/msdos/pctiles.c index 4e942e534..9103c6d61 100644 --- a/sys/msdos/pctiles.c +++ b/sys/msdos/pctiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pctiles.c $NHDT-Date: 1596498271 2020/08/03 23:44:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 pctiles.c $NHDT-Date: 1596498271 2020/08/03 23:44:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/pctiles.h b/sys/msdos/pctiles.h index eed5a87ec..44707c686 100644 --- a/sys/msdos/pctiles.h +++ b/sys/msdos/pctiles.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 pctiles.h $NHDT-Date: 1596498272 2020/08/03 23:44:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 pctiles.h $NHDT-Date: 1596498272 2020/08/03 23:44:32 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/pcvideo.h b/sys/msdos/pcvideo.h index 1d889a8b2..a3a088058 100644 --- a/sys/msdos/pcvideo.h +++ b/sys/msdos/pcvideo.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcvideo.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 pcvideo.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ /* */ @@ -237,12 +237,12 @@ extern void HideCursor(void); /* ### vidtxt.c ### */ +extern void txt_get_scr_size(void); #ifdef NO_TERMS extern void txt_backsp(void); extern void txt_clear_screen(void); extern void txt_cl_end(int, int); extern void txt_cl_eos(void); -extern void txt_get_scr_size(void); extern void txt_gotoxy(int, int); extern int txt_monoadapt_check(void); extern void txt_nhbell(void); @@ -267,7 +267,6 @@ extern void vga_show_cursor(void); extern void vga_DrawCursor(void); #endif extern void vga_Finish(void); -extern char __far *vga_FontPtrs(void); extern void vga_get_scr_size(void); extern void vga_gotoloc(int, int); #ifdef POSITIONBAR diff --git a/sys/msdos/portio.h b/sys/msdos/portio.h index 8907278b2..0e6f53515 100644 --- a/sys/msdos/portio.h +++ b/sys/msdos/portio.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 portio.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 portio.h $NHDT-Date: 1596498273 2020/08/03 23:44:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/msdos/setup.bat b/sys/msdos/setup.bat index 988de68db..f2f983ba6 100755 --- a/sys/msdos/setup.bat +++ b/sys/msdos/setup.bat @@ -1,5 +1,5 @@ @echo off -REM NetHack 3.7 setup.bat $NHDT-Date: 1596498274 2020/08/03 23:44:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ +REM NetHack 5.0 setup.bat $NHDT-Date: 1596498274 2020/08/03 23:44:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ REM Copyright (c) NetHack PC Development Team 1990 - 2019 REM NetHack may be freely redistributed. See license for details. diff --git a/sys/msdos/sysconf b/sys/msdos/sysconf index b3ef5bdca..779e437bd 100644 --- a/sys/msdos/sysconf +++ b/sys/msdos/sysconf @@ -1,5 +1,5 @@ # -# NetHack 3.7 sysconf $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.7.0 $:$NHDT-Revision: 1.22 $ +# NetHack 5.0 sysconf $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-5.0.0 $:$NHDT-Revision: 1.22 $ # Copyright (c) 2015 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -24,7 +24,7 @@ WIZARDS=* # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format diff --git a/sys/msdos/tile2bin.c b/sys/msdos/tile2bin.c index 0e90935fc..cc43bb3dc 100644 --- a/sys/msdos/tile2bin.c +++ b/sys/msdos/tile2bin.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile2bin.c $NHDT-Date: 1596498275 2020/08/03 23:44:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 tile2bin.c $NHDT-Date: 1596498275 2020/08/03 23:44:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994, 1995 */ /* NetHack may be freely redistributed. See license for details. */ @@ -185,7 +185,7 @@ main(int argc, char *argv[]) tibheader.compiler = OTHER_COMP; #endif - strncpy(tibheader.ident, "NetHack 3.7 MSDOS Port binary tile file", 80); + strncpy(tibheader.ident, "NetHack 5.0 MSDOS Port binary tile file", 80); #if !defined(NOSTRFTIME) (void) strftime(tibheader.timestamp, sizeof tibheader.timestamp, "%c", newtime); diff --git a/sys/msdos/vesa.h b/sys/msdos/vesa.h index 3056b07a0..9549a2bd1 100644 --- a/sys/msdos/vesa.h +++ b/sys/msdos/vesa.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 vesa.h $NHDT-Date: 1596498276 2020/08/03 23:44:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 vesa.h $NHDT-Date: 1596498276 2020/08/03 23:44:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ */ /* VESA structures from the VESA BIOS Specification, retrieved 15 Jan 2016 * from http://flint.cs.yale.edu/cs422/readings/hardware/vbe3.pdf diff --git a/sys/msdos/video.c b/sys/msdos/video.c index 57911edab..bb94e83b6 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 video.c $NHDT-Date: 1596498277 2020/08/03 23:44:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 5.0 video.c $NHDT-Date: 1596498277 2020/08/03 23:44:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994, 2001 */ /* NetHack may be freely redistributed. See license for details. */ @@ -89,7 +89,7 @@ get_scr_size(void) txt_get_scr_size(); } -#ifdef ENHANCED_SYMBOLS +#if defined(TTY_GRAPHICS) && defined(ENHANCED_SYMBOLS) void g_pututf8(uint8 *utf8str) { /* not implemented for msdos (yet) */ @@ -132,17 +132,17 @@ void cmov(int, int); void nocmov(int, int); static void init_ttycolor(void); -int savevmode; /* store the original video mode in here */ +#if defined(SCREEN_VGA) || defined(SCREEN_VESA) int curcol, currow; /* graphics mode current cursor locations */ +#endif int g_attribute; /* Current attribute to use */ -int monoflag; /* 0 = not monochrome, else monochrome */ +static int monoflag; /* 0 = not monochrome, else monochrome */ int inversed; int attrib_text_normal; /* text mode normal attribute */ int attrib_gr_normal; /* graphics mode normal attribute */ int attrib_text_intense; /* text mode intense attribute */ int attrib_gr_intense; /* graphics mode intense attribute */ uint32 curframecolor = NO_COLOR; /* current background text color */ -boolean traditional = FALSE; /* traditional TTY character mode */ boolean inmap = FALSE; /* in the map window */ char ttycolors[CLR_MAX]; /* also used/set in options.c */ @@ -183,8 +183,8 @@ term_curs_set(int visibility) #ifdef SCREEN_VESA } else if (iflags.usevesa) { vesa_hide_cursor(); - } #endif + } } else if (visibility) { if (!iflags.grmode) { txt_show_cursor(); @@ -195,8 +195,8 @@ term_curs_set(int visibility) #ifdef SCREEN_VESA } else if (iflags.usevesa) { vesa_show_cursor(); - } #endif + } } vis = visibility; } @@ -255,16 +255,16 @@ void cl_end(void) /* clear to end of line */ void cl_eos(void) /* clear to end of screen */ { - int cy = (int) ttyDisplay->cury + 1; - if (!iflags.grmode) { txt_cl_eos(); #ifdef SCREEN_VGA } else if (iflags.usevga) { + int cy = (int) ttyDisplay->cury + 1; vga_cl_eos(cy); #endif #ifdef SCREEN_VESA } else if (iflags.usevesa) { + int cy = (int) ttyDisplay->cury + 1; vesa_cl_eos(cy); #endif } @@ -419,7 +419,7 @@ term_start_color(int color) if (monoflag) { g_attribute = attrib_text_normal; } else { - if (color == NO_COLOR) { /* 3.7 behave like term_end_color() */ + if (color == NO_COLOR) { /* 5.0 behave like term_end_color() */ g_attribute = iflags.grmode ? attrib_gr_normal : attrib_text_normal; curframecolor = NO_COLOR; } else if (color >= 0 && color < CLR_MAX) { @@ -683,6 +683,7 @@ xputc(int ch) /* write out character (and attribute) */ } /* write out a glyph picture at current location */ +#ifdef TILES_IN_GLYPHMAP void xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo) { if (!iflags.grmode || !iflags.tile_view) { @@ -697,6 +698,7 @@ void xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo) #endif } } +#endif /* TILES_IN_GLYPHMAP */ #ifdef POSITIONBAR void @@ -731,6 +733,8 @@ adjust_cursor_flags(struct WinDesc *cw) cursor_flag = 1; } #endif /* 0 */ +#else + nhUse(cw); #endif /* SIMULATE_CURSOR */ } @@ -796,9 +800,9 @@ HideCursor(void) /* assign_videocolors() is prototyped in extern.h */ /* assign_video() is prototyped in extern.h */ -int shadeflag; /* shades are initialized */ -int colorflag; /* colors are initialized */ -const char *schoice[3] = { "dark", "normal", "light" }; +static int shadeflag; /* shades are initialized */ +static int colorflag; /* colors are initialized */ +static const char *schoice[3] = { "dark", "normal", "light" }; const char *shade[3]; #endif /* VIDEOSHADES */ @@ -1068,6 +1072,7 @@ assign_video(char *sopt) return 1; } +#ifdef TILES_IN_GLYPHMAP void tileview(boolean enable) { @@ -1080,6 +1085,7 @@ tileview(boolean enable) vesa_traditional(enable ? FALSE : TRUE); #endif } +#endif /* TILES_IN_GLYPHMAP */ #endif /* NO_TERMS */ #else /* STUBVIDEO */ diff --git a/sys/msdos/vidtxt.c b/sys/msdos/vidtxt.c index 990d6d064..a97b45b24 100644 --- a/sys/msdos/vidtxt.c +++ b/sys/msdos/vidtxt.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vidtxt.c $NHDT-Date: 1596498278 2020/08/03 23:44:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 vidtxt.c $NHDT-Date: 1596498278 2020/08/03 23:44:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ /* */ @@ -109,7 +109,7 @@ txt_get_scr_size(void) void txt_gotoxy(int, int); #if defined(SCREEN_BIOS) && !defined(PC9800) -void txt_get_cursor(int *, int *); +static void txt_get_cursor(int *, int *); #endif #ifdef SCREEN_DJGPPFAST @@ -401,7 +401,7 @@ void txt_xputc(char ch, int attr) * * This is implemented as a macro under DJGPPFAST. */ -void txt_get_cursor(int *x, int *y) +static void txt_get_cursor(int *x, int *y) { union REGS regs; diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 8a3423bc0..80247797c 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -15,12 +15,27 @@ #include "pctiles.h" #include "vesa.h" #include "wintty.h" -#include "tileset.h" #include "font.h" +#ifdef TILES_IN_GLYPHMAP +#include "tileset.h" +#else +/* For the palette */ +struct Pixel { + unsigned char r, g, b, a; +}; +#endif + #define FIRST_TEXT_COLOR 240 -extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */ +#ifdef TILES_IN_GLYPHMAP +extern int total_tiles_used, + Tile_corr, + Tile_unexplored, + Tile_delimiter, + Tile_petmark, + Tile_pilemark; /* from tile.c */ +#endif struct VesaCharacter { uint32 colour, bgcolour; uint32 chr; @@ -32,13 +47,17 @@ static unsigned long vesa_ReadPixel32(unsigned x, unsigned y); static void vesa_WritePixel32(unsigned x, unsigned y, unsigned long color); static void vesa_WritePixel(unsigned x, unsigned y, unsigned color); static void vesa_WritePixelRow(unsigned long offset, - unsigned char const *p_row, unsigned p_row_size); + unsigned char const *p_row, + unsigned char const *p_decal_row, + unsigned p_row_size); static unsigned long vesa_MakeColor(struct Pixel); static void vesa_FillRect(unsigned left, unsigned top, unsigned width, unsigned height, unsigned color); +#ifdef TILES_IN_GLYPHMAP static void vesa_redrawmap(void); static void vesa_cliparound(int, int); +#endif #if 0 static void decal_packed(const struct TileImage *tile, unsigned special); #endif @@ -47,7 +66,10 @@ static void vesa_SetViewPort(void); static boolean vesa_SetPalette(const struct Pixel *); static boolean vesa_SetHardPalette(const struct Pixel *); static boolean vesa_SetSoftPalette(const struct Pixel *); -static void vesa_DisplayCell(int, int, int); +#ifdef TILES_IN_GLYPHMAP +static void vesa_DisplayCell(int, int, int, uint8_t); +static uint8_t *add_transparent_row(uint8_t const *, uint8_t const *, unsigned, uint32_t); +#endif static unsigned vesa_FindMode(unsigned long mode_addr, unsigned bits); static void vesa_WriteChar(uint32, int, int, uint32); static void vesa_WriteCharXY(uint32, int, int, uint32); @@ -60,6 +82,10 @@ static unsigned long vesa_DoublePixels(unsigned long); static unsigned long vesa_TriplePixels(unsigned long); static void vesa_WriteStr(const char *, int, int, int, int); static unsigned char __far *vesa_FontPtrs(void); +#ifdef TILES_IN_GLYPHMAP +static unsigned char *vesa_tile(unsigned); +static unsigned char *vesa_oview_tile(unsigned); +#endif /* static void vesa_process_tile(struct TileImage *tile); */ #ifdef POSITIONBAR @@ -82,16 +108,24 @@ extern boolean inmap; /* in the map window */ static unsigned char __far *font; +#ifdef TILES_IN_GLYPHMAP static struct map_struct { int glyph; uint32 ch; uint32 attr; unsigned special; - short int tileidx; + uint16_t tileidx; + uint16_t decalnum; int framecolor; int inverse; } map[ROWNO][COLNO]; /* track the glyphs */ +enum { delimdecal, petdecal, piledecal, NUMDECALS }; +static unsigned char *vesa_decals[NUMDECALS] = { 0 }; +static unsigned char *vesa_oview_decals[NUMDECALS] = { 0 }; +static unsigned char *tmptilebuf; +static uint32_t tilebackground; + #define vesa_clearmap() \ { \ int x, y; \ @@ -103,13 +137,17 @@ static struct map_struct { map[y][x].attr = 0; \ map[y][x].special = 0; \ map[y][x].tileidx = Tile_unexplored; \ + map[y][x].decalnum = 0; \ map[y][x].inverse = 0; \ } \ } +#endif /* TILES_IN_GLYPHMAP */ #define TOP_MAP_ROW 1 +#ifdef TILES_IN_GLYPHMAP static int viewport_cols = 40; static int viewport_rows = ROWNO; +#endif static const struct Pixel defpalette[] = { /* Colors for text and the position bar */ { 0x00, 0x00, 0x00, 0xff }, /* CLR_BLACK */ @@ -156,8 +194,10 @@ static unsigned char vesa_blue_shift; static unsigned long vesa_palette[256]; static unsigned vesa_char_width = 8, vesa_char_height = 16; static unsigned vesa_oview_width, vesa_oview_height; +#ifdef TILES_IN_GLYPHMAP static unsigned char **vesa_tiles; static unsigned char **vesa_oview_tiles; +#endif static struct BitmapFont *vesa_font; #ifdef SIMULATE_CURSOR @@ -461,8 +501,22 @@ vesa_WritePixel(unsigned x, unsigned y, unsigned color) static void vesa_WritePixelRow(unsigned long offset, - unsigned char const *p_row, unsigned p_row_size) + unsigned char const *p_row, + unsigned char const *p_decal_row, + unsigned p_row_size) { +#ifdef TILES_IN_GLYPHMAP + uint8_t *p_combined_row = NULL; /* custodial */ + + if (p_decal_row != NULL) { + p_combined_row = add_transparent_row( + p_row, p_decal_row, p_row_size, tilebackground); + p_row = p_combined_row; + } +#else + nhUse(p_decal_row); +#endif + if (vesa_segment != 0) { /* Linear frame buffer in use */ movedata(_go32_my_ds(), (unsigned)p_row, vesa_segment, offset, p_row_size); @@ -481,6 +535,10 @@ vesa_WritePixelRow(unsigned long offset, } dosmemput(p_row + i, p_row_size - i, addr); } + +#ifdef TILES_IN_GLYPHMAP + free(p_combined_row); +#endif } static unsigned long @@ -531,7 +589,7 @@ vesa_FillRect(unsigned left, unsigned top, unsigned width, } for (y = 0; y < height; ++y) { - vesa_WritePixelRow(offset, p_row, p_row_size); + vesa_WritePixelRow(offset, p_row, NULL, p_row_size); offset += vesa_scan_line; } @@ -562,8 +620,10 @@ void vesa_clear_screen(int colour) { vesa_FillRect(0, 0, vesa_x_res, vesa_y_res, colour); +#ifdef TILES_IN_GLYPHMAP if (iflags.tile_view) vesa_clearmap(); +#endif vesa_gotoloc(0, 0); /* is this needed? */ } @@ -685,15 +745,58 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) uint32_t attr = (g_attribute == 0) ? attrib_gr_normal : g_attribute; int ry; + /* some decal initializations */ + if (!vesa_decals[delimdecal]) { + vesa_decals[delimdecal] = vesa_tile(Tile_delimiter); + /* The first pixel in Tile_delimiter is the background color */ + switch(vesa_pixel_bytes) { + case 1: + tilebackground = *((uint8_t *)vesa_decals[delimdecal]); + break; + + case 2: + tilebackground = *((uint16_t *)vesa_decals[delimdecal]); + break; + + case 3: + case 4: + tilebackground = *((uint32_t *)vesa_decals[delimdecal]) & 0x00FFFFFF; + break; + } + if (!vesa_decals[petdecal]) + vesa_decals[petdecal] = vesa_tile(Tile_petmark); + + if (!vesa_decals[piledecal]) + vesa_decals[piledecal] = vesa_tile(Tile_pilemark); + + if (!vesa_oview_decals[petdecal]) + vesa_oview_decals[petdecal] = vesa_oview_tile(Tile_petmark); + + if (!vesa_oview_decals[piledecal]) + vesa_oview_decals[piledecal] = vesa_oview_tile(Tile_pilemark); + } + + unsigned decalnum = ((special & MG_PET) && iflags.hilite_pet) + ? petdecal + : ((special & MG_OBJPILE) && iflags.hilite_pile) + ? piledecal : 0; + #ifdef ENHANCED_SYMBOLS if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u && glyphinfo->gm.u->utf8str) { ch = glyphinfo->gm.u->utf32ch; } #endif if (vesa_pixel_size > 8 && glyphinfo->gm.customcolor != 0) { - /* FIXME: won't display black (0,0,0) correctly, but the background - is usually black anyway */ - attr = glyphinfo->gm.customcolor | 0x80000000; + attr = glyphinfo->gm.customcolor; + if (attr & NH_BASIC_COLOR) { + attr &= 0x0F; + } else { + struct Pixel p; + p.r = (unsigned char)(attr >> 16); + p.g = (unsigned char)(attr >> 8); + p.b = (unsigned char)(attr >> 0); + attr = vesa_MakeColor(p) | 0x80000000; + } } row = currow; @@ -706,6 +809,7 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) map[ry][col].ch = ch; map[ry][col].special = special; map[ry][col].tileidx = glyphinfo->gm.tileidx; + map[ry][col].decalnum = decalnum; map[ry][col].attr = attr; map[ry][col].inverse = inversed; @@ -722,7 +826,7 @@ vesa_xputg(const glyph_info *glyphinfo, const glyph_info *bkglyphinfo UNUSED) if (!iflags.over_view && map[ry][col].special) decal_packed(packcell, special); #endif - vesa_DisplayCell(glyphinfo->gm.tileidx, col - clipx, ry - clipy); + vesa_DisplayCell(glyphinfo->gm.tileidx, col - clipx, ry - clipy, decalnum); if (bkglyphinfo->framecolor != NO_COLOR) { int curtypbak = cursor_type; int cclr = cursor_color; @@ -835,15 +939,20 @@ vesa_redrawmap(void) } } else if (iflags.over_view) { /* Overview mode */ - const unsigned char *tile; p_row_width = vesa_oview_width * vesa_pixel_bytes; y = y_top; for (cy = 0; cy < ROWNO; ++cy) { for (py = 0; py < vesa_oview_height; ++py) { for (cx = 0; cx < COLNO; ++cx) { - tile = vesa_oview_tiles[map[cy][cx].tileidx]; - vesa_WritePixelRow(offset + p_row_width * cx, tile + p_row_width * py, p_row_width); + const uint8_t *tile = vesa_oview_tile(map[cy][cx].tileidx); + const uint8_t *decal = NULL; + unsigned decalnum = map[cy][cx].decalnum; + if (decalnum != 0 && decalnum < NUMDECALS) { + decal = vesa_oview_decals[decalnum]; + decal += p_row_width * py; + } + vesa_WritePixelRow(offset + p_row_width * cx, tile + p_row_width * py, decal, p_row_width); } x = COLNO * vesa_oview_width; if (x < vesa_x_res) { @@ -855,15 +964,20 @@ vesa_redrawmap(void) } } else { /* Normal tiled mode */ - const unsigned char *tile; p_row_width = iflags.wc_tile_width * vesa_pixel_bytes; y = y_top; for (cy = clipy; cy <= (unsigned) clipymax && cy < ROWNO; ++cy) { for (py = 0; py < (unsigned) iflags.wc_tile_height; ++py) { for (cx = clipx; cx <= (unsigned) clipxmax && cx < COLNO; ++cx) { - tile = vesa_tiles[map[cy][cx].tileidx]; - vesa_WritePixelRow(offset + p_row_width * (cx - clipx), tile + p_row_width * py, p_row_width); + const uint8_t *tile = vesa_tile(map[cy][cx].tileidx); + const uint8_t *decal = NULL; + unsigned decalnum = map[cy][cx].decalnum; + if (decalnum != 0 && decalnum < NUMDECALS) { + decal = vesa_decals[decalnum]; + decal += p_row_width * py; + } + vesa_WritePixelRow(offset + p_row_width * (cx - clipx), tile + p_row_width * py, decal, p_row_width); } x = (cx - clipx) * iflags.wc_tile_width; if (x < vesa_x_res) { @@ -884,6 +998,7 @@ vesa_redrawmap(void) #endif /* TILES_IN_GLYPHMAP && CLIPPING */ +#ifdef TILES_IN_GLYPHMAP void vesa_userpan(enum vga_pan_direction pan) { @@ -1031,6 +1146,7 @@ decal_packed(const struct TileImage *gp, unsigned special) } } #endif +#endif /* TILES_IN_GLYPHMAP */ DISABLE_WARNING_FORMAT_NONLITERAL @@ -1046,9 +1162,9 @@ vesa_Init(void) { static boolean inited = FALSE; const struct Pixel *paletteptr; - unsigned i; - unsigned num_pixels, num_oview_pixels; +#ifdef TILES_IN_GLYPHMAP const char *tile_file; +#endif const char *font_name; int tilefailure = 0; @@ -1082,11 +1198,16 @@ vesa_Init(void) /* term_clear_screen() */ /* not vesa_clear_screen() */ return; } + paletteptr = get_palette(); +#else + /* This isn't actually used; it just keeps paletteptr from being NULL, + * so an 8 bit color mode will work */ + paletteptr = defpalette; #endif vesa_mode = 0xFFFF; /* might want an 8 bit mode after loading tiles */ vesa_detect(); - if (vesa_mode == 0xFFFF || (vesa_pixel_size == 8 && get_palette() == NULL)) { + if (vesa_mode == 0xFFFF || (vesa_pixel_size == 8 && paletteptr == NULL)) { raw_printf("%s (%d)", "Reverting to TTY mode, no VESA mode available.", tilefailure); wait_synch(); @@ -1101,36 +1222,26 @@ vesa_Init(void) vesa_SwitchMode(vesa_mode); vesa_SetViewPort(); +#ifdef TILES_IN_GLYPHMAP windowprocs.win_cliparound = vesa_cliparound; +#endif if (vesa_pixel_size > 8) { windowprocs.wincap2 |= WC2_EXTRACOLORS; } #ifdef TILES_IN_GLYPHMAP - paletteptr = get_palette(); iflags.tile_view = TRUE; iflags.over_view = FALSE; -#else - paletteptr = defpalette; #endif vesa_SetPalette(paletteptr); g_attribute = attrib_gr_normal; font = vesa_FontPtrs(); term_clear_screen(); +#ifdef TILES_IN_GLYPHMAP clipx = 0; clipxmax = clipx + (viewport_cols - 1); clipy = 0; clipymax = clipy + (viewport_rows - 1); - - /* Set the size of the tiles for the overview mode */ - vesa_oview_width = vesa_x_res / COLNO; - if (vesa_oview_width > (unsigned) iflags.wc_tile_width) { - vesa_oview_width = (unsigned) iflags.wc_tile_width; - } - vesa_oview_height = (vesa_y_res - (TOP_MAP_ROW + 4) * vesa_char_height) - / ROWNO; - if (vesa_oview_height > (unsigned) iflags.wc_tile_height) { - vesa_oview_height = (unsigned) iflags.wc_tile_height; - } +#endif /* Load a font of size appropriate to the screen size */ if (vesa_x_res >= 1280 && vesa_y_res >= 960) @@ -1175,33 +1286,51 @@ vesa_Init(void) vesa_char_width = vesa_char_height / 2; } + vesa_SetViewPort(); + + /* Set the size of the tiles for the overview mode */ + vesa_oview_width = vesa_x_res / COLNO; + if (vesa_oview_width > (unsigned) iflags.wc_tile_width) { + vesa_oview_width = (unsigned) iflags.wc_tile_width; + } + vesa_oview_height = (vesa_y_res - (TOP_MAP_ROW + 5) * vesa_char_height) + / ROWNO; + if (vesa_oview_height > (unsigned) iflags.wc_tile_height) { + vesa_oview_height = (unsigned) iflags.wc_tile_height; + } + /* Process tiles for the current video mode */ +#ifdef TILES_IN_GLYPHMAP vesa_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *)); + memset(vesa_tiles, 0, total_tiles_used * sizeof(void *)); vesa_oview_tiles = (unsigned char **) alloc(total_tiles_used * sizeof(void *)); - num_pixels = iflags.wc_tile_width * iflags.wc_tile_height; - num_oview_pixels = vesa_oview_width * vesa_oview_height; + memset(vesa_oview_tiles, 0, total_tiles_used * sizeof(void *)); set_tile_type(vesa_pixel_size > 8); - for (i = 0; i < (unsigned) total_tiles_used; ++i) { - const struct TileImage *tile = get_tile(i); - struct TileImage *ov_tile = stretch_tile(tile, vesa_oview_width, vesa_oview_height); +#endif +} + +RESTORE_WARNING_FORMAT_NONLITERAL + +#ifdef TILES_IN_GLYPHMAP +/* Return processed pixels for a normal tile */ +static unsigned char * +vesa_tile(unsigned index) +{ + if (vesa_tiles[index] == NULL) { + unsigned num_pixels = iflags.wc_tile_width * iflags.wc_tile_height; + const struct TileImage *tile = get_tile(index); unsigned j; unsigned char *t_img = (unsigned char *) alloc(num_pixels * vesa_pixel_bytes); - unsigned char *ot_img = (unsigned char *) alloc(num_oview_pixels * vesa_pixel_bytes); - vesa_tiles[i] = t_img; - vesa_oview_tiles[i] = ot_img; + vesa_tiles[index] = t_img; switch (vesa_pixel_bytes) { case 1: memcpy(t_img, tile->indexes, num_pixels); - memcpy(ot_img, ov_tile->indexes, num_oview_pixels); break; case 2: for (j = 0; j < num_pixels; ++j) { ((uint16_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]); } - for (j = 0; j < num_oview_pixels; ++j) { - ((uint16_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]); - } break; case 3: @@ -1211,6 +1340,42 @@ vesa_Init(void) t_img[3*j + 1] = (color >> 8) & 0xFF; t_img[3*j + 2] = (color >> 16) & 0xFF; } + break; + + case 4: + for (j = 0; j < num_pixels; ++j) { + ((uint32_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]); + } + break; + } + } + + return vesa_tiles[index]; +} + +/* Return processed pixels for an overview tile */ +static unsigned char * +vesa_oview_tile(unsigned index) +{ + if (vesa_oview_tiles[index] == NULL) { + unsigned num_oview_pixels = vesa_oview_width * vesa_oview_height; + const struct TileImage *tile = get_tile(index); + struct TileImage *ov_tile = stretch_tile(tile, vesa_oview_width, vesa_oview_height); + unsigned j; + unsigned char *ot_img = (unsigned char *) alloc(num_oview_pixels * vesa_pixel_bytes); + vesa_oview_tiles[index] = ot_img; + switch (vesa_pixel_bytes) { + case 1: + memcpy(ot_img, ov_tile->indexes, num_oview_pixels); + break; + + case 2: + for (j = 0; j < num_oview_pixels; ++j) { + ((uint16_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]); + } + break; + + case 3: for (j = 0; j < num_oview_pixels; ++j) { unsigned long color = vesa_MakeColor(ov_tile->pixels[j]); ot_img[3*j + 0] = color & 0xFF; @@ -1220,9 +1385,6 @@ vesa_Init(void) break; case 4: - for (j = 0; j < num_pixels; ++j) { - ((uint32_t *)t_img)[j] = vesa_MakeColor(tile->pixels[j]); - } for (j = 0; j < num_oview_pixels; ++j) { ((uint32_t *)ot_img)[j] = vesa_MakeColor(ov_tile->pixels[j]); } @@ -1230,15 +1392,16 @@ vesa_Init(void) } free_tile(ov_tile); } - free_tiles(); -} -RESTORE_WARNING_FORMAT_NONLITERAL + return vesa_oview_tiles[index]; +} +#endif /* TILES_IN_GLYPHMAP */ /* Set the size of the map viewport */ static void vesa_SetViewPort(void) { +#ifdef TILES_IN_GLYPHMAP unsigned y_reserved = (TOP_MAP_ROW + 5) * vesa_char_height; unsigned y_map = vesa_y_res - y_reserved; @@ -1246,6 +1409,7 @@ vesa_SetViewPort(void) viewport_rows = y_map / iflags.wc_tile_height; if (viewport_cols > COLNO) viewport_cols = COLNO; if (viewport_rows > ROWNO) viewport_rows = ROWNO; +#endif } /* @@ -1297,6 +1461,7 @@ vesa_SwitchMode(unsigned mode) void vesa_Finish(void) { +#ifdef TILES_IN_GLYPHMAP int i; for (i = 0; i < total_tiles_used; ++i) { @@ -1305,6 +1470,10 @@ vesa_Finish(void) } free(vesa_tiles); free(vesa_oview_tiles); + free_tiles(); + if (tmptilebuf) + free((genericptr_t) tmptilebuf), tmptilebuf = 0; +#endif vesa_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; g_attribute = attrib_text_normal; @@ -1739,7 +1908,7 @@ vesa_WriteTextRow(int pixx, int pixy, struct VesaCharacter const *t_row, } } } - vesa_WritePixelRow(offset, p_row, p_row_width); + vesa_WritePixelRow(offset, p_row, NULL, p_row_width); offset += vesa_scan_line; } free(p_row); @@ -1853,22 +2022,25 @@ vesa_TriplePixels(unsigned long fnt) * not the x,y pixel location. * */ +#ifdef TILES_IN_GLYPHMAP static void -vesa_DisplayCell(int tilenum, int col, int row) +vesa_DisplayCell(int tilenum, int col, int row, uint8_t decalnum) { unsigned char const *tile; unsigned t_width, t_height; unsigned char const *tptr; + int /* px, */ py, pixx, pixy; unsigned long offset; unsigned p_row_width; + unsigned char const *decal; if (iflags.over_view) { - tile = vesa_oview_tiles[tilenum]; + tile = vesa_oview_tile(tilenum); t_width = vesa_oview_width; t_height = vesa_oview_height; } else { - tile = vesa_tiles[tilenum]; + tile = vesa_tile(tilenum); t_width = iflags.wc_tile_width; t_height = iflags.wc_tile_height; } @@ -1880,15 +2052,117 @@ vesa_DisplayCell(int tilenum, int col, int row) pixx += vesa_x_center; pixy += vesa_y_center; offset = pixy * (unsigned long)vesa_scan_line + pixx * vesa_pixel_bytes; + if (decalnum != 0 && decalnum < NUMDECALS) { + if (iflags.over_view) { + decal = vesa_oview_decals[decalnum]; + } else { + decal = vesa_decals[decalnum]; + } + } else { + decal = NULL; + } tptr = tile; for (py = 0; py < (int) t_height; ++py) { - vesa_WritePixelRow(offset, tptr, p_row_width); + vesa_WritePixelRow(offset, tptr, decal, p_row_width); offset += vesa_scan_line; tptr += p_row_width; + if (decal != NULL) { + decal += p_row_width; + } } } +/* Overlay a transparent row onto the given pixel row */ +/* Return an allocated buffer containing the overlaid row */ +/* The caller is responsible for freeing the returned row */ +static uint8_t * +add_transparent_row( + uint8_t const *p_row, + uint8_t const *p_overlay, + unsigned p_row_size, + uint32_t transparent_pixel) +{ + /* + * ignore the "background" pixels in decal, + * which is identified by the delim tile in the stock + * tile set which is 100% background. + */ + uint8_t *p_combined_row = (uint8_t *) alloc(p_row_size); + switch(vesa_pixel_bytes) { + case 1: { + uint8_t *t1 = (uint8_t *) p_row, + *t2 = (uint8_t *) p_overlay, + *t3 = (uint8_t *) p_combined_row; + + for (unsigned i = 0; i < p_row_size; i += vesa_pixel_bytes) { + *t3 = (*t2 != transparent_pixel) ? *t2 : *t1; + ++t1; + ++t2; + ++t3; + } + } + break; + case 2: { + uint16_t *t1 = (uint16_t *) p_row, + *t2 = (uint16_t *) p_overlay, + *t3 = (uint16_t *) p_combined_row; + + for (unsigned i = 0; i < p_row_size; i += vesa_pixel_bytes) { + *t3 = (*t2 != transparent_pixel) ? *t2 : *t1; + ++t1; + ++t2; + ++t3; + } + } + break; + case 3: { + uint8_t *t1 = (uint8_t *) p_row, + *t2 = (uint8_t *) p_overlay, + *t3 = (uint8_t *) p_combined_row; + for (unsigned i = 0; i < p_row_size; i += vesa_pixel_bytes) { + uint32_t pix = ((uint32_t) t2[2] << 16) + | ((uint32_t) t2[1] << 8) + | ((uint32_t) t2[0] << 0); + + if (pix != transparent_pixel) { + t3[0] = t2[0]; + t3[1] = t2[1]; + t3[2] = t2[2]; + } else { + t3[0] = t1[0]; + t3[1] = t1[1]; + t3[2] = t1[2]; + } + t1 += 3; + t2 += 3; + t3 += 3; + } + } + break; + case 4: { + uint32_t *t1 = (uint32_t *) p_row, + *t2 = (uint32_t *) p_overlay, + *t3 = (uint32_t *) p_combined_row; + + for (unsigned i = 0; i < p_row_size; i += vesa_pixel_bytes) { + *t3 = ((*t2 & 0x00FFFFFF) != transparent_pixel) ? *t2 : *t1; + ++t1; + ++t2; + ++t3; + } + } + break; + default: + /* This isn't supposed to happen */ + memcpy(p_combined_row, p_row, p_row_size); + break; + } + + return p_combined_row; +} +#endif /* TILES_IN_GLYPHMAP */ + /* * Write the character string pointed to by 's', whose maximum length * is 'len' at location (x,y) using the 'colour' colour. @@ -1965,6 +2239,8 @@ vesa_SetHardPalette(const struct Pixel *palette) p2[i*4 + 1] = palette[i].g >> shift; p2[i*4 + 2] = palette[i].r >> shift; } +#else + nhUse(palette); #endif for (i = FIRST_TEXT_COLOR; i < 256; ++i) { p2[i*4 + 0] = defpalette[i-FIRST_TEXT_COLOR].b >> shift; @@ -2033,6 +2309,8 @@ vesa_SetSoftPalette(const struct Pixel *palette) ++p; } } +#else + nhUse(palette); #endif p = defpalette; for (i = FIRST_TEXT_COLOR; i < 256; ++i) { @@ -2155,17 +2433,25 @@ positionbar(void) void vesa_DrawCursor(void) { +#ifdef TILES_IN_GLYPHMAP static boolean last_inmap = FALSE; +#endif unsigned x, y, left, top, right, bottom, width, height; +#ifdef TILES_IN_GLYPHMAP boolean isrogue = Is_rogue_level(&u.uz); boolean halfwidth = (isrogue || iflags.over_view || iflags.traditional_view || !inmap); +#else + const boolean halfwidth = TRUE; +#endif int curtyp; +#ifdef TILES_IN_GLYPHMAP if (inmap && !last_inmap) { vesa_redrawmap(); } last_inmap = inmap; +#endif if (!cursor_type && inmap) return; /* CURSOR_INVIS - nothing to do */ @@ -2188,9 +2474,12 @@ vesa_DrawCursor(void) y -= clipy; } /* convert to pixels */ +#ifdef TILES_IN_GLYPHMAP if (!inmap || iflags.traditional_view) { +#endif width = vesa_char_width; height = vesa_char_height; +#ifdef TILES_IN_GLYPHMAP } else if (iflags.over_view) { width = vesa_oview_width; height = vesa_oview_height; @@ -2198,6 +2487,7 @@ vesa_DrawCursor(void) width = iflags.wc_tile_width; height = iflags.wc_tile_height; } +#endif left = x * width + vesa_x_center; top = y * height + vesa_y_center; if (y >= TOP_MAP_ROW) { @@ -2271,9 +2561,13 @@ void vesa_HideCursor(void) { unsigned x, y, left, top, width, height; +#ifdef TILES_IN_GLYPHMAP boolean isrogue = Is_rogue_level(&u.uz); boolean halfwidth = (isrogue || iflags.over_view || iflags.traditional_view || !inmap); +#else + const boolean halfwidth = TRUE; +#endif if (!cursor_type && inmap) return; /* CURSOR_INVIS - nothing to do */ @@ -2292,9 +2586,12 @@ vesa_HideCursor(void) y -= clipy; } /* convert to pixels */ +#ifdef TILES_IN_GLYPHMAP if (!inmap || iflags.traditional_view) { +#endif width = vesa_char_width; height = vesa_char_height; +#ifdef TILES_IN_GLYPHMAP } else if (iflags.over_view) { width = vesa_oview_width; height = vesa_oview_height; @@ -2302,6 +2599,7 @@ vesa_HideCursor(void) width = iflags.wc_tile_width; height = iflags.wc_tile_height; } +#endif left = x * width + vesa_x_center; top = y * height + vesa_y_center; if (y >= TOP_MAP_ROW) { diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index 140b816a5..eb32985cd 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vidvga.c $NHDT-Date: 1606765216 2020/11/30 19:40:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 5.0 vidvga.c $NHDT-Date: 1606765216 2020/11/30 19:40:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.26 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ /* @@ -10,9 +10,17 @@ #ifdef SCREEN_VGA /* this file is for SCREEN_VGA only */ #include "pcvideo.h" #include "tile.h" -#include "tileset.h" #include "font.h" +#ifdef TILES_IN_GLYPHMAP +#include "tileset.h" +#else +/* For the palette */ +struct Pixel { + unsigned char r, g, b, a; +}; +#endif + #include #include "wintty.h" @@ -109,28 +117,37 @@ void vga_backsp(void); #ifdef SCROLLMAP static void vga_scrollmap(boolean); #endif +#ifdef TILES_IN_GLYPHMAP static void vga_redrawmap(boolean); static void vga_cliparound(int, int); static void decal_planar(struct planar_cell_struct *, unsigned); +static void decal_oview_planar(struct overview_planar_cell_struct *, unsigned); +#endif #ifdef POSITIONBAR static void positionbar(void); static void vga_special(int, int, int); #endif +#ifdef TILES_IN_GLYPHMAP static void vga_DisplayCell(struct planar_cell_struct *, int, int); static void vga_DisplayCell_O(struct overview_planar_cell_struct *, int, int); +#endif static void vga_SwitchMode(unsigned int); static void vga_SetPalette(const struct Pixel *); -static void vga_WriteChar(uint32, int, int, int); +static void vga_WriteChar(uint32, int, int, int, int); static void vga_GetBitmap(uint32, unsigned char *); static void vga_WriteStr(char *, int, int, int, int); +static char __far *vga_FontPtrs(void); +#ifdef TILES_IN_GLYPHMAP +static int glyph_to_tilenum(unsigned); static void read_planar_tile(unsigned, struct planar_cell_struct *); static void read_planar_tile_O(unsigned, struct overview_planar_cell_struct *); static void read_tile_indexes(unsigned, unsigned char (*)[TILE_X]); +#endif extern int clipx, clipxmax; /* current clipping column from wintty.c */ extern boolean clipping; /* clipping on? from wintty.c */ @@ -156,6 +173,7 @@ static struct BitmapFont *psf_font; static char *screentable[SCREENHEIGHT]; static const struct Pixel *paletteptr; +#ifdef TILES_IN_GLYPHMAP static struct map_struct { int glyph; uint32 ch; @@ -163,9 +181,14 @@ static struct map_struct { unsigned special; short int tileidx; uint32 framecolor; + int inverse; } map[ROWNO][COLNO]; /* track the glyphs */ -extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */ +extern int total_tiles_used, + Tile_corr, Tile_unexplored, + Tile_delimiter, + Tile_petmark, + Tile_pilemark; /* from tile.c */ #define vga_clearmap() \ { \ @@ -178,43 +201,57 @@ extern int total_tiles_used, Tile_corr, Tile_unexplored; /* from tile.c */ map[y][x].attr = 0; \ map[y][x].special = 0; \ map[y][x].tileidx = Tile_unexplored; \ + map[y][x].inverse = 0; \ } \ } +#endif /* TILES_IN_GLYPHMAP */ #define TOP_MAP_ROW 1 -static int vgacmap[CLR_MAX] = { 1, 4, 6, 10, 5, 9, 0, 15, - 12, 3, 7, 8, 2, 9, 0, 14 }; +#ifdef TILES_IN_GLYPHMAP +static const int vgacmap[CLR_MAX] = { + 1, 4, 6, 10, 5, 9, 0, 15, + 12, 3, 7, 8, 2, 9, 0, 14 }; +#endif +static const int textcmap[CLR_MAX] = { + 1, 4, 6, 10, 5, 9, 0, 15, + 12, 3, 7, 8, 2, 11, 13, 14 }; static int viewport_size = 40; /* static char masktable[8]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01}; */ /* static char bittable[8]= {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; */ -#if 0 -static char defpalette[] = { /* Default VGA palette */ - 0x00, 0x00, 0x00, - 0x00, 0x00, 0xaa, - 0x00, 0xaa, 0x00, - 0x00, 0xaa, 0xaa, - 0xaa, 0x00, 0x00, - 0xaa, 0x00, 0xaa, - 0xaa, 0xaa, 0x00, - 0xaa, 0xaa, 0xaa, - 0x55, 0x55, 0x55, - 0xcc, 0xcc, 0xcc, - 0x00, 0x00, 0xff, - 0x00, 0xff, 0x00, - 0xff, 0x00, 0x00, - 0xff, 0xff, 0x00, - 0xff, 0x00, 0xff, - 0xff, 0xff, 0xff +/* When showing the text view, use this palette */ +static const struct Pixel text_palette[] = { + /* Permuted to mostly match the tileset */ + { 0x00, 0xaa, 0xaa, 0xff }, /* CLR_CYAN */ + { 0x00, 0x00, 0x00, 0xff }, /* CLR_BLACK */ + { 0x44, 0x44, 0xff, 0xff }, /* CLR_BRIGHT_BLUE */ + { 0xff, 0x90, 0x00, 0xff }, /* CLR_ORANGE */ + { 0xaa, 0x00, 0x00, 0xff }, /* CLR_RED */ + { 0x22, 0x22, 0xff, 0xff }, /* CLR_BLUE */ + { 0x00, 0xaa, 0x00, 0xff }, /* CLR_GREEN */ + { 0x00, 0xff, 0x00, 0xff }, /* CLR_BRIGHT_GREEN */ + { 0xff, 0xff, 0x00, 0xff }, /* CLR_YELLOW */ + { 0xaa, 0x00, 0xaa, 0xff }, /* CLR_MAGENTA */ + { 0x99, 0x40, 0x00, 0xff }, /* CLR_BROWN */ + { 0xff, 0x00, 0xff, 0xff }, /* CLR_BRIGHT_MAGENTA */ + { 0x55, 0x55, 0x55, 0xff }, /* NO_COLOR */ + { 0x00, 0xff, 0xff, 0xff }, /* CLR_BRIGHT_CYAN */ + { 0xff, 0xff, 0xff, 0xff }, /* CLR_WHITE */ + { 0xaa, 0xaa, 0xaa, 0xff }, /* CLR_GRAY */ + { 0x00, 0xff, 0xff, 0xff } /* CLR_BRIGHT_CYAN repeated */ }; -#endif #ifndef ALTERNATE_VIDEO_METHOD -int vp[SCREENPLANES] = { 8, 4, 2, 1 }; +static int vp[SCREENPLANES] = { 8, 4, 2, 1 }; #endif -int vp2[SCREENPLANES] = { 1, 2, 4, 8 }; -static struct planar_cell_struct planecell; -static struct overview_planar_cell_struct planecell_O; +#ifdef TILES_IN_GLYPHMAP +static struct planar_cell_struct **cell_cache; +static struct overview_planar_cell_struct **cell_cache_O; + +enum { delimdecal, petdecal, piledecal, NUMDECALS }; +static struct cellplane *decal_alpha[NUMDECALS] = { 0 }; +static struct overview_cellplane *decal_oview_alpha[NUMDECALS] = { 0 }; +#endif /* static int g_attribute; */ /* Current attribute to use */ @@ -255,8 +292,10 @@ vga_clear_screen(int colour) WRITE_ABSOLUTE_DWORD(&pch[j], 0x00000000); } egawriteplane(15); +#ifdef TILES_IN_GLYPHMAP if (iflags.tile_view) vga_clearmap(); +#endif vga_gotoloc(0, 0); /* is this needed? */ } @@ -271,7 +310,7 @@ void vga_cl_end(int col, int row) * mode 2 methods as did term_clear_screen() */ for (count = col; count < (CO - 1); ++count) { - vga_WriteChar(' ', count, row, BACKGROUND_VGA_COLOR); + vga_WriteChar(' ', count, row, BACKGROUND_VGA_COLOR, FALSE); } } @@ -283,7 +322,7 @@ void vga_cl_eos(int cy) cl_end(); while (cy <= LI - 2) { for (count = 0; count < (CO - 1); ++count) { - vga_WriteChar(' ', count, cy, BACKGROUND_VGA_COLOR); + vga_WriteChar(' ', count, cy, BACKGROUND_VGA_COLOR, FALSE); } cy++; } @@ -355,7 +394,7 @@ void vga_xputc(char ch, int attr) ++row; break; default: - vga_WriteChar((unsigned char) ch, col, row, attr); + vga_WriteChar((unsigned char) ch, col, row, attr, FALSE); if (col < (CO - 1)) ++col; break; @@ -402,16 +441,18 @@ vga_xputg(const glyph_info *glyphinfo, attr = (g_attribute == 0) ? attrib_gr_normal : g_attribute; map[ry][col].attr = attr; map[ry][col].tileidx = glyphinfo->gm.tileidx; + map[ry][col].inverse = inversed; if (bkglyphinfo->framecolor != NO_COLOR) { map[ry][col].framecolor = bkglyphinfo->framecolor; } if (iflags.traditional_view) { - vga_WriteChar(ch, col, row, attr); + vga_WriteChar(ch, col, row, attr, inversed); } else if (!iflags.over_view) { if ((col >= clipx) && (col <= clipxmax)) { - read_planar_tile(glyphnum, &planecell); - if (map[ry][col].special) + struct planar_cell_struct planecell; + read_planar_tile(glyph_to_tilenum(glyphnum), &planecell); + if (special) decal_planar(&planecell, special); vga_DisplayCell(&planecell, col - clipx, row); if (bkglyphinfo->framecolor != NO_COLOR) { @@ -426,7 +467,10 @@ vga_xputg(const glyph_info *glyphinfo, } } } else { - read_planar_tile_O(glyphnum, &planecell_O); + struct overview_planar_cell_struct planecell_O; + read_planar_tile_O(glyph_to_tilenum(glyphnum), &planecell_O); + if (special) + decal_oview_planar(&planecell_O, special); vga_DisplayCell_O(&planecell_O, col, row); } if (col < (CO - 1)) @@ -508,16 +552,21 @@ vga_redrawmap(boolean clearfirst) if (iflags.traditional_view) { if (!(clearfirst && map[y][x].ch == S_stone)) vga_WriteChar(map[y][x].ch, x, - y + TOP_MAP_ROW, map[y][x].attr); + y + TOP_MAP_ROW, map[y][x].attr, + map[y][x].inverse); } else { t = map[y][x].glyph; if (!iflags.over_view) { - read_planar_tile(t, &planecell); + struct planar_cell_struct planecell; + read_planar_tile(glyph_to_tilenum(t), &planecell); if (map[y][x].special) decal_planar(&planecell, map[y][x].special); vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW); } else { - read_planar_tile_O(t, &planecell_O); + struct overview_planar_cell_struct planecell_O; + read_planar_tile_O(glyph_to_tilenum(t), &planecell_O); + if (map[y][x].special) + decal_oview_planar(&planecell_O, map[y][x].special); vga_DisplayCell_O(&planecell_O, x, y + TOP_MAP_ROW); } } @@ -525,6 +574,7 @@ vga_redrawmap(boolean clearfirst) } #endif /* TILES_IN_GLYPHMAP && CLIPPING */ +#ifdef TILES_IN_GLYPHMAP void vga_userpan(enum vga_pan_direction pan) { @@ -533,9 +583,9 @@ vga_userpan(enum vga_pan_direction pan) /* pline("Into userpan"); */ if (iflags.over_view || iflags.traditional_view) return; - if (pan == pan_left) + if (pan == pan_right) x = min(COLNO - 1, clipxmax + 10); - else if (pan == pan_right) + else if (pan == pan_left) x = max(0, clipx - 10); else return; @@ -548,6 +598,7 @@ void vga_overview(boolean on) { /* vga_HideCursor(); */ + vga_SetPalette(paletteptr); if (on) { iflags.over_view = TRUE; clipx = 0; @@ -568,10 +619,12 @@ vga_traditional(boolean on) if (on) { /* switch_symbols(FALSE); */ iflags.traditional_view = TRUE; + vga_SetPalette(text_palette); clipx = 0; clipxmax = CO - 1; } else { iflags.traditional_view = FALSE; + vga_SetPalette(paletteptr); if (!iflags.over_view) { clipx = max(0, (curcol - viewport_size / 2)); if (clipx > ((CO - 1) - viewport_size)) @@ -643,8 +696,9 @@ boolean left; } for (y = 0; y < ROWNO; ++y) { for (x = i; x < j; x += 2) { + struct planar_cell_struct planecell; t = map[y][x].glyph; - read_planar_tile(t, &planecell); + read_planar_tile(glyph_to_tilenum(t), &planecell); if (map[y][x].special) decal_planar(&planecell, map[y][x].special); vga_DisplayCell(&planecell, x - clipx, y + TOP_MAP_ROW); @@ -653,66 +707,90 @@ boolean left; } #endif /* SCROLLMAP */ -static void -read_planar_tile(unsigned glyph, struct planar_cell_struct *cell) +static int +glyph_to_tilenum(unsigned glyph) { - unsigned char indexes[TILE_Y][TILE_X]; - unsigned plane, y, byte, bit; - - read_tile_indexes(glyph, indexes); - /* cell->plane[0..3].image[0..15][0..1] */ - for (plane = 0; plane < SCREENPLANES; ++plane) { - for (y = 0; y < TILE_Y; ++y) { - for (byte = 0; byte < MAX_BYTES_PER_CELL; ++byte) { - unsigned char b = 0; - for (bit = 0; bit < 8; ++bit) { - unsigned char x = byte * 8 + bit; - unsigned char i = indexes[y][x]; - b <<= 1; - if (i & (0x8 >> plane)) b |= 1; - } - cell->plane[plane].image[y][byte] = b; - } - } - } -} - -static void -read_planar_tile_O(unsigned glyph, struct overview_planar_cell_struct *cell) -{ - unsigned char indexes[TILE_Y][TILE_X]; - unsigned plane, y, bit; - - read_tile_indexes(glyph, indexes); - /* cell->plane[0..3].image[0..15][0..0] */ - for (plane = 0; plane < SCREENPLANES; ++plane) { - for (y = 0; y < TILE_Y; ++y) { - unsigned char b = 0; - for (bit = 0; bit < 8; ++bit) { - unsigned char x = bit * 2; - unsigned char i = indexes[y][x]; - b <<= 1; - if (i & (0x8 >> plane)) b |= 1; - } - cell->plane[plane].image[y][0] = b; - } - } -} - -static void -read_tile_indexes(unsigned glyph, unsigned char (*indexes)[TILE_X]) -{ - const struct TileImage *tile; - unsigned x, y; - int tilenum; - /* We don't have enough colors to show the statues */ if (glyph_is_statue(glyph)) { glyph = GLYPH_OBJ_OFF + STATUE; } + return glyphmap[glyph].tileidx; +} + +static void +read_planar_tile(unsigned tilenum, struct planar_cell_struct *cell) +{ + struct planar_cell_struct *pcell; + unsigned char indexes[TILE_Y][TILE_X]; + unsigned plane, y, byte, bit; + + /* Get the processed tile from the cache if we can */ + pcell = cell_cache[tilenum]; + if (pcell == NULL) { + /* Process the tile */ + pcell = (struct planar_cell_struct *) alloc(sizeof(*pcell)); + cell_cache[tilenum] = pcell; + read_tile_indexes(tilenum, indexes); + /* pcell->plane[0..3].image[0..15][0..1] */ + for (plane = 0; plane < SCREENPLANES; ++plane) { + for (y = 0; y < TILE_Y; ++y) { + for (byte = 0; byte < MAX_BYTES_PER_CELL; ++byte) { + unsigned char b = 0; + for (bit = 0; bit < 8; ++bit) { + unsigned char x = byte * 8 + bit; + unsigned char i = indexes[y][x]; + b <<= 1; + if (i & (0x8 >> plane)) b |= 1; + } + pcell->plane[plane].image[y][byte] = b; + } + } + } + } + + *cell = *pcell; +} + +static void +read_planar_tile_O(unsigned tilenum, struct overview_planar_cell_struct *cell) +{ + struct overview_planar_cell_struct *pcell; + unsigned char indexes[TILE_Y][TILE_X]; + unsigned plane, y, bit; + + /* Get the processed tile from the cache if we can */ + pcell = cell_cache_O[tilenum]; + if (pcell == NULL) { + /* Process the tile */ + pcell = (struct overview_planar_cell_struct *) alloc(sizeof(*pcell)); + cell_cache_O[tilenum] = pcell; + read_tile_indexes(tilenum, indexes); + /* pcell->plane[0..3].image[0..15][0..0] */ + for (plane = 0; plane < SCREENPLANES; ++plane) { + for (y = 0; y < TILE_Y; ++y) { + unsigned char b = 0; + for (bit = 0; bit < 8; ++bit) { + unsigned char x = bit * 2; + unsigned char i = indexes[y][x]; + b <<= 1; + if (i & (0x8 >> plane)) b |= 1; + } + pcell->plane[plane].image[y][0] = b; + } + } + } + + *cell = *pcell; +} + +static void +read_tile_indexes(unsigned tilenum, unsigned char (*indexes)[TILE_X]) +{ + const struct TileImage *tile; + unsigned x, y; + /* Get the tile from the image */ - tilenum = glyphmap[glyph].tileidx; tile = get_tile(tilenum); /* Map to a 16 bit palette; assume colors laid out as in default tileset */ @@ -730,16 +808,126 @@ read_tile_indexes(unsigned glyph, unsigned char (*indexes)[TILE_X]) } static void -decal_planar(struct planar_cell_struct *gpcs UNUSED, unsigned special) +decal_planar(struct planar_cell_struct *gpcs, unsigned special) { - if (special & MG_CORPSE) { - } else if (special & MG_INVIS) { - } else if (special & MG_DETECT) { - } else if (special & MG_PET) { - } else if (special & MG_RIDDEN) { + int decalnum; /* indexes decal_alpha */ + int decal_tile; /* tile index of decal */ + + /* Which decal do we use? */ + if ((special & MG_PET) != 0 && iflags.hilite_pet) { + decalnum = petdecal; + decal_tile = Tile_petmark; + } else if ((special & MG_OBJPILE) != 0 && iflags.hilite_pile) { + decalnum = piledecal; + decal_tile = Tile_pilemark; + } else { + /* No decal */ + return; + } + + /* Read the decal */ + struct planar_cell_struct decal; + read_planar_tile(decal_tile, &decal); + + /* Build the alpha channel for the decal */ + struct cellplane *alpha = decal_alpha[decalnum]; + + if (alpha == NULL) { + /* Read the delimiter to get the background color */ + struct planar_cell_struct delim; + read_planar_tile(Tile_delimiter, &delim); + + /* Allocate space for the alpha channel */ + alpha = (struct cellplane *) alloc(sizeof(*alpha)); + decal_alpha[decalnum] = alpha; + memset(alpha, 0x00, sizeof(*alpha)); + + /* Alpha channel is 0 where all planes of the decal match the + background, and 1 otherwise */ + for (unsigned i = 0; i < SCREENPLANES; ++i) { + uint8_t background = (delim.plane[i].image[0][0] & 0x80) ? 0xFF : 0x00; + for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) { + for (unsigned k = 0; k < MAX_BYTES_PER_CELL; ++k) { + /* Set alpha to 1 wherever the decal doesn't match the + background */ + alpha->image[j][k] |= decal.plane[i].image[j][k] ^ background; + } + } + } + } + + /* Apply the decal to the tile */ + for (unsigned i = 0; i < SCREENPLANES; ++i) { + for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) { + for (unsigned k = 0; k < MAX_BYTES_PER_CELL; ++k) { + uint8_t b1 = gpcs->plane[i].image[j][k]; + uint8_t b2 = decal.plane[i].image[j][k]; + uint8_t a = alpha->image[j][k]; + gpcs->plane[i].image[j][k] = (b1 & ~a) | (b2 & a); + } + } } } +static void +decal_oview_planar(struct overview_planar_cell_struct *gpcs, unsigned special) +{ + int decalnum; /* indexes decal_alpha */ + int decal_tile; /* tile index of decal */ + + /* Which decal do we use? */ + if ((special & MG_PET) != 0 && iflags.hilite_pet) { + decalnum = petdecal; + decal_tile = Tile_petmark; + } else if ((special & MG_OBJPILE) != 0 && iflags.hilite_pile) { + decalnum = piledecal; + decal_tile = Tile_pilemark; + } else { + /* No decal */ + return; + } + + /* Read the decal */ + struct overview_planar_cell_struct decal; + read_planar_tile_O(decal_tile, &decal); + + /* Build the alpha channel for the decal */ + struct overview_cellplane *alpha = decal_oview_alpha[decalnum]; + + if (alpha == NULL) { + /* Read the delimiter to get the background color */ + struct planar_cell_struct delim; /* not overview_planar_cell_struct */ + read_planar_tile(Tile_delimiter, &delim); + + /* Allocate space for the alpha channel */ + alpha = (struct overview_cellplane *) alloc(sizeof(*alpha)); + decal_oview_alpha[decalnum] = alpha; + memset(alpha, 0x00, sizeof(*alpha)); + + /* Alpha channel is 0 where all planes of the decal match the + background, and 1 otherwise */ + for (unsigned i = 0; i < SCREENPLANES; ++i) { + uint8_t background = (delim.plane[i].image[0][0] & 0x80) ? 0xFF : 0x00; + for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) { + /* Set alpha to 1 wherever the decal doesn't match the + background */ + alpha->image[j][0] |= decal.plane[i].image[j][0] ^ background; + } + } + } + + /* Apply the decal to the tile */ + for (unsigned i = 0; i < SCREENPLANES; ++i) { + for (unsigned j = 0; j < MAX_ROWS_PER_CELL; ++j) { + uint8_t b1 = gpcs->plane[i].image[j][0]; + uint8_t b2 = decal.plane[i].image[j][0]; + uint8_t a = alpha->image[j][0]; + gpcs->plane[i].image[j][0] = (b1 & ~a) | (b2 & a); + } + } +} +#endif /* TILES_IN_GLYPHMAP */ + /* * Open tile files, * initialize the SCREEN, switch it to graphics mode, @@ -782,6 +970,15 @@ vga_Init(void) /* term_clear_screen() */ /* not vga_clear_screen() */ return; } + + if (cell_cache == NULL) { + cell_cache = (struct planar_cell_struct **) alloc( + total_tiles_used * sizeof(cell_cache[0])); + memset(cell_cache, 0, total_tiles_used * sizeof(cell_cache[0])); + cell_cache_O = (struct overview_planar_cell_struct **) alloc( + total_tiles_used * sizeof(cell_cache_O[0])); + memset(cell_cache_O, 0, total_tiles_used * sizeof(cell_cache_O[0])); + } #endif if (iflags.usevga) { @@ -790,7 +987,9 @@ vga_Init(void) } } vga_SwitchMode(MODE640x480); +#ifdef TILES_IN_GLYPHMAP windowprocs.win_cliparound = vga_cliparound; +#endif /* vga_NoBorder(BACKGROUND_VGA_COLOR); */ /* Not needed after palette mod */ #ifdef TILES_IN_GLYPHMAP @@ -798,7 +997,7 @@ vga_Init(void) iflags.tile_view = TRUE; iflags.over_view = FALSE; #else - paletteptr = defpalette; + paletteptr = text_palette; #endif vga_SetPalette(paletteptr); g_attribute = attrib_gr_normal; @@ -811,7 +1010,7 @@ vga_Init(void) } free_font(psf_font); psf_font = load_font(font_name); - if (psf_font->width != 8 || psf_font->height != 16) { + if (psf_font != NULL && (psf_font->width != 8 || psf_font->height != 16)) { raw_printf("VGA mode only supports 8x16 fonts"); free_font(psf_font); psf_font = NULL; @@ -860,7 +1059,19 @@ vga_SwitchMode(unsigned int mode) void vga_Finish(void) { +#ifdef TILES_IN_GLYPHMAP + int i; + free_tiles(); + for (i = 0; i < total_tiles_used; ++i) { + free(cell_cache[i]); + free(cell_cache_O[i]); + } + free(cell_cache); + cell_cache = NULL; + free(cell_cache_O); + cell_cache_O = NULL; +#endif vga_SwitchMode(MODETEXT); windowprocs.win_cliparound = tty_cliparound; g_attribute = attrib_text_normal; @@ -900,7 +1111,7 @@ vga_NoBorder(int bc) * address of the appropriate character definition table for * the current graphics mode into interrupt vector 0x43 (0000:010C). */ -char __far * +static char __far * vga_FontPtrs(void) { USHORT __far *tmp; @@ -955,14 +1166,14 @@ extern int curframecolor; /* video.c */ * */ static void -vga_WriteChar(uint32 chr, int col, int row, int colour) +vga_WriteChar(uint32 chr, int col, int row, int colour, int inverse) { int i; int x, pixy; char __far *cp; unsigned char fnt; - int actual_colour = vgacmap[colour]; + int actual_colour = colour; int bgcolor; int vplane; unsigned char bitmap[ROWS_PER_CELL]; @@ -971,16 +1182,29 @@ vga_WriteChar(uint32 chr, int col, int row, int colour) vga_GetBitmap(chr, bitmap); if (curframecolor != NO_COLOR) - bgcolor = vgacmap[curframecolor]; + bgcolor = curframecolor; else - bgcolor = BACKGROUND_VGA_COLOR; + bgcolor = CLR_BLACK; - if (inversed) { + if (inverse) { int tmpc = actual_colour; actual_colour = bgcolor; bgcolor = tmpc; } +#ifdef TILES_IN_GLYPHMAP + if (iflags.traditional_view) { +#endif + /* A one-to-one remapping to keep black at the same index either way */ + actual_colour = textcmap[actual_colour]; + bgcolor = textcmap[bgcolor]; +#ifdef TILES_IN_GLYPHMAP + } else { + actual_colour = vgacmap[actual_colour]; + bgcolor = vgacmap[bgcolor]; + } +#endif + x = min(col, (CO - 1)); /* min() used protection from callers */ pixy = min(row, (LI - 1)) * 16; /* assumes 8 x 16 char set */ vplane = ~actual_colour & ~bgcolor & 0xF; @@ -1042,6 +1266,7 @@ vga_GetBitmap(uint32 chr, unsigned char *bitmap) } } +#ifdef TILES_IN_GLYPHMAP /* * This is the routine that displays a high-res "cell" pointed to by 'gp' * at the desired location (col,row). @@ -1105,6 +1330,7 @@ vga_DisplayCell_O(struct overview_planar_cell_struct *gpcs, int col, int row) } egawriteplane(15); } +#endif /* TILES_IN_GLYPHMAP */ /* * Write the character string pointed to by 's', whose maximum length @@ -1124,7 +1350,7 @@ vga_WriteStr(char *s, int len, int col, int row, int colour) i = 0; us = (unsigned char *) s; while ((*us != 0) && (i < len) && (col < (CO - 1))) { - vga_WriteChar((uchar) *us, col, row, colour); + vga_WriteChar((uchar) *us, col, row, colour, FALSE); ++us; ++i; ++col; @@ -1354,9 +1580,13 @@ vga_DrawCursor(void) unsigned char first, second; /* char on[2] = {0xFF,0xFF}; */ /* char off[2] = {0x00,0x00}; */ +#ifdef TILES_IN_GLYPHMAP boolean isrogue = Is_rogue_level(&u.uz); boolean singlebyte = (isrogue || iflags.over_view || iflags.traditional_view || !inmap); +#else + const boolean singlebyte = TRUE; +#endif int curtyp; if (!cursor_type && inmap) @@ -1566,9 +1796,13 @@ vga_HideCursor(void) int i, pixx, pixy, x, y; char __far *tmp1; char __far *tmp2; +#ifdef TILES_IN_GLYPHMAP boolean isrogue = Is_rogue_level(&u.uz); boolean singlebyte = (isrogue || iflags.over_view || iflags.traditional_view || !inmap); +#else + const boolean singlebyte = TRUE; +#endif int curtyp; if (inmap && !cursor_type) diff --git a/sys/share/.gitattributes b/sys/share/.gitattributes index 0ab91a6e9..f240d70ab 100644 --- a/sys/share/.gitattributes +++ b/sys/share/.gitattributes @@ -3,16 +3,16 @@ NetHack.cnf NHSUBST termcap NH_header=no Makefile.lib NH_header=no -Makefile.lib NH_filestag=(file%s_for_OS/2_version_-_untested_for_3.7) -#termcap.uu NH_filestag=(file%s_for_MSDOS_and_OS/2_versions_-_untested_for_3.7) +Makefile.lib NH_filestag=(file%s_for_OS/2_version_-_untested_for_5.0) +#termcap.uu NH_filestag=(file%s_for_MSDOS_and_OS/2_versions_-_untested_for_5.0) termcap.uu NH_filestag=>Makefile.lib -pcmain.c NH_filestag=(file_for_MSDOS,_OS/2,_Amiga,_and_Atari_versions_-_only_MSDOS_tested_for_3.7) +pcmain.c NH_filestag=(file_for_MSDOS,_Amiga_versions) -pcsys.c NH_filestag=(file%s_for_MSDOS,_OS/2_and_Atari_versions_-_only_MSDOS_tested_for_3.7) +pcsys.c NH_filestag=(file%s_for_MSDOS,_Amiga_versions) pcunix.c NH_filestag=>pcsys.c -NetHack.cnf NH_filestag=(file_for_MSDOS,_OS/2,_and_Atari_versions_-_only_MSDOS_tested_for_3.7) +NetHack.cnf NH_filestag=(file_for_MSDOS,_Amiga_versions) pctty.c NH_filestag=>NetHack.cnf ioctl.c NH_filestag=(file%s_for_UNIX_and_Be_versions) diff --git a/sys/share/Makefile.lib b/sys/share/Makefile.lib index 8118a1af7..9f2318c3c 100644 --- a/sys/share/Makefile.lib +++ b/sys/share/Makefile.lib @@ -1,4 +1,4 @@ -# NetHack 3.7 Makefile.lib $NHDT-Date: 1596498281 2020/08/03 23:44:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +# NetHack 5.0 Makefile.lib $NHDT-Date: 1596498281 2020/08/03 23:44:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.8 $ # Nethack makefile for Fred fish termlib -- Norman Meluch # CC = cl /c diff --git a/sys/share/NetHack.cnf b/sys/share/NetHack.cnf index a34c68f13..3fbfb9978 100644 --- a/sys/share/NetHack.cnf +++ b/sys/share/NetHack.cnf @@ -30,6 +30,8 @@ OPTIONS=rawio,BIOS,symset:IBMGraphics_2,roguesymset:RogueEpyx #OPTIONS=video_width:1024 #OPTIONS=video_height:768 +# To show markers for pets and piles if this is supported +OPTIONS=hilite_pet,hilite_pile # If your machine is NEC PC-9800, use: #OPTIONS=rawio,BIOS,video:default diff --git a/sys/share/cppregex.cpp b/sys/share/cppregex.cpp index 9835a1f5c..073eb8917 100644 --- a/sys/share/cppregex.cpp +++ b/sys/share/cppregex.cpp @@ -1,5 +1,5 @@ -/* NetHack 3.7 cppregex.cpp */ -/* $NHDT-Date: 1596498279 2020/08/03 23:44:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 cppregex.cpp */ +/* $NHDT-Date: 1596498279 2020/08/03 23:44:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/ioctl.c b/sys/share/ioctl.c index d6a2468c5..ec76ec740 100644 --- a/sys/share/ioctl.c +++ b/sys/share/ioctl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 ioctl.c $NHDT-Date: 1596498280 2020/08/03 23:44:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 ioctl.c $NHDT-Date: 1596498280 2020/08/03 23:44:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 39e5aec4e..d0f671930 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcmain.c $NHDT-Date: 1693359605 2023/08/30 01:40:05 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.133 $ */ +/* NetHack 5.0 pcmain.c $NHDT-Date: 1693359605 2023/08/30 01:40:05 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.133 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -12,7 +12,7 @@ #include #endif -#if !defined(AMIGA) && !defined(__DJGPP__) +#if !defined(AMIGA) && !defined(__DJGPP__) && !defined(__MINT__) #include #else #include @@ -27,14 +27,13 @@ char orgdir[PATHLEN]; /* also used in pcsys.c, amidos.c */ #ifdef TOS boolean run_from_desktop = TRUE; /* should we pause before exiting?? */ -#ifdef __GNUC__ -long _stksize = 16 * 1024; -#endif +/* _stksize is owned by sys/atari/tos.c for the 5.0 GEM build. */ #endif #ifdef AMIGA extern int bigscreen; void preserve_icon(void); +void amiga_self_assign(void); #endif static void process_options(int argc, char **argv); @@ -117,8 +116,11 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ startup(); #endif +#if defined(PC_EARLY_OPTIONS) + program_state.early_options = 1; +#endif + #ifdef TOS - long clock_time; if (*argv[0]) { /* only a CLI can give us argv[0] */ gh.hname = argv[0]; run_from_desktop = FALSE; @@ -128,7 +130,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ choose_windows(DEFAULT_WINDOW_SYS); - #if !defined(AMIGA) && !defined(GNUDOS) /* Save current directory and make sure it gets restored when * the game is exited. @@ -255,6 +256,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif } #ifdef AMIGA + /* Point NetHack: at our program directory; covers CLI and WB launch. */ + amiga_self_assign(); #ifdef CHDIR /* * If we're dealing with workbench, change the directory. Otherwise @@ -266,6 +269,12 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif ami_wininit_data(WININIT); #endif + +#if defined(PC_EARLY_OPTIONS) + early_options(&argc, &argv, &dir); + program_state.early_options = 0; +#endif + initoptions(); #ifdef NOCWD_ASSUMPTIONS @@ -339,10 +348,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ /* * It seems you really want to play. */ -#ifdef TOS - if (comp_times((long) time(&clock_time))) - error("Your clock is incorrectly set!"); -#endif if (!dlb_init()) { pline( "%s\n%s\n%s\n%s\n\nNetHack was unable to open the required file " @@ -749,6 +754,48 @@ exepath(char *str) } #endif /* EXEPATH */ +#if defined(CROSS_TO_ATARI) || defined(CROSS_TO_AMIGA) \ + || defined(CROSS_TO_MSDOS) +/* Generate an RFC 4122 v4 UUID for this game. Draw bytes from the + core's ISAAC64 RNG, which init_random() seeded before we get here. */ +void +get_nhuuid(void) +{ + uchar bytes[16]; + int i; + + if (svn.nhuuid[0]) + return; + + for (i = 0; i < 16; i++) + bytes[i] = (uchar) rn2(256); + /* RFC 4122: version=4 (random), variant=10. */ + bytes[6] = (bytes[6] & 0x0F) | 0x40; + bytes[8] = (bytes[8] & 0x3F) | 0x80; + + Snprintf(svn.nhuuid, sizeof svn.nhuuid, + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x%02x%02x%02x%02x", + bytes[0], bytes[1], bytes[2], bytes[3], + bytes[4], bytes[5], + bytes[6], bytes[7], + bytes[8], bytes[9], + bytes[10], bytes[11], bytes[12], bytes[13], + bytes[14], bytes[15]); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} +#endif + +#if defined(CROSS_TO_AMIGA) || defined(CROSS_TO_ATARI) #ifdef CROSS_TO_AMIGA void msmsg VA_DECL(const char *, fmt) @@ -760,6 +807,18 @@ VA_DECL(const char *, fmt) VA_END(); return; } +#endif +#ifdef CROSS_TO_ATARI +void +msmsg(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); +} +#endif unsigned long sys_random_seed(void) diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index 07cab8e42..9e9f9aab0 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcsys.c $NHDT-Date: 1596498283 2020/08/03 23:44:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 5.0 pcsys.c $NHDT-Date: 1596498283 2020/08/03 23:44:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) 2012 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ @@ -155,8 +155,11 @@ getreturn(const char *str) msmsg("Hit %s.", str); #endif #endif - while (pgetchar() != '\n') - ; +#if defined(PC_EARLY_OPTIONS) + if (isatty(STDOUT_FILENO)) +#endif + while (pgetchar() != '\n') + ; return; } @@ -271,7 +274,9 @@ msexit(void) restore_colors(); #endif wait_synch(); +#if !(defined(MSDOS) && !defined(TTY_GRAPHICS)) term_curs_set(1); +#endif return; } #endif /* MICRO || OS2 */ diff --git a/sys/share/pctty.c b/sys/share/pctty.c index fee616980..53f5bb45c 100644 --- a/sys/share/pctty.c +++ b/sys/share/pctty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pctty.c $NHDT-Date: 1596498284 2020/08/03 23:44:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 pctty.c $NHDT-Date: 1596498284 2020/08/03 23:44:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2005. */ /* NetHack may be freely redistributed. See license for details. */ @@ -38,7 +38,9 @@ settty(const char *s) #if defined(MSDOS) && defined(NO_TERMS) gr_finish(); #endif +#if !(defined(MSDOS) && !defined(TTY_GRAPHICS)) term_end_screen(); +#endif if (s) raw_print(s); #if !defined(TOS) @@ -50,9 +52,18 @@ settty(const char *s) void setftty(void) { +#if !(defined(MSDOS) && !defined(TTY_GRAPHICS)) term_start_screen(); +#endif } +#ifdef ENHANCED_SYMBOLS +void +tty_utf8graphics_fixup(void) +{ +} +#endif + #if defined(TIMED_DELAY) && defined(_MSC_VER) void msleep(unsigned mseconds) @@ -76,8 +87,10 @@ VA_DECL(const char *, s) VA_START(s); VA_INIT(s, const char *); /* error() may get called before tty is initialized */ +#if !(defined(MSDOS) && !defined(TTY_GRAPHICS)) if (iflags.window_inited) term_end_screen(); +#endif putchar('\n'); Vprintf(s, VA_ARGS); putchar('\n'); diff --git a/sys/share/pcunix.c b/sys/share/pcunix.c index f95a26a79..6ecd7dae9 100644 --- a/sys/share/pcunix.c +++ b/sys/share/pcunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pcunix.c $NHDT-Date: 1596498285 2020/08/03 23:44:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 5.0 pcunix.c $NHDT-Date: 1596498285 2020/08/03 23:44:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.42 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pmatchregex.c b/sys/share/pmatchregex.c index 53c5ef531..a4bf0c119 100644 --- a/sys/share/pmatchregex.c +++ b/sys/share/pmatchregex.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pmatchregex.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 pmatchregex.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/posixregex.c b/sys/share/posixregex.c index d6b3c4845..676e7dbe7 100644 --- a/sys/share/posixregex.c +++ b/sys/share/posixregex.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 posixregex.c $NHDT-Date: 1596498286 2020/08/03 23:44:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ +/* NetHack 5.0 posixregex.c $NHDT-Date: 1596498286 2020/08/03 23:44:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.7 $ */ /* Copyright (c) Sean Hunt 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/tclib.c b/sys/share/tclib.c index d9ecace06..51046a2b2 100644 --- a/sys/share/tclib.c +++ b/sys/share/tclib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tclib.c $NHDT-Date: 1596498287 2020/08/03 23:44:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 tclib.c $NHDT-Date: 1596498287 2020/08/03 23:44:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Robert Patrick Rankin, 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/unixtty.c b/sys/share/unixtty.c index 3dce02269..aa62a477d 100644 --- a/sys/share/unixtty.c +++ b/sys/share/unixtty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixtty.c $NHDT-Date: 1596498288 2020/08/03 23:44:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 5.0 unixtty.c $NHDT-Date: 1596498288 2020/08/03 23:44:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/uudecode.c b/sys/share/uudecode.c index 9d3a4802b..a59856925 100644 --- a/sys/share/uudecode.c +++ b/sys/share/uudecode.c @@ -46,7 +46,7 @@ * Modified 09 Apr 2026 to change mode variable from (int) to (unsigned int) * to match prototype of sscanf %o. * - * $NHDT-Date: 1775744389 2026/04/09 14:19:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ + * $NHDT-Date: 1775744389 2026/04/09 14:19:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ #ifndef lint diff --git a/sys/unix/Install.unx b/sys/unix/Install.unx index 60596cbed..c2230a452 100644 --- a/sys/unix/Install.unx +++ b/sys/unix/Install.unx @@ -1,4 +1,4 @@ - Instructions for installing NetHack 3.7 + Instructions for installing NetHack 5.0 on a UNIX system ======================================= NB: We are gradually replacing this process with the process documented in @@ -109,7 +109,7 @@ the file NewInstall.unx. Notes: 1. Save files and bones files from previous versions will not work with - NetHack 3.7. Don't bother trying to keep them. + NetHack 5.0. Don't bother trying to keep them. 2. To install an update of this version of NetHack after changing something, type 'make update' from the main directory. If you created the new @@ -246,11 +246,11 @@ Notes: 13. If you get a compiler warning about 'get_colors()' being implicitly declared, try uncommenting NEED_GET_COLORS_DECL in unixconf.h. - If you get a compiler complaint about tparmdecl() having conflicting - declarations, add '#define NOTPARMDECL' to unixconf.h or '-DNOTPARMDECL' - to CFLAGS in src/Makefile. (The hints files for Mac OSX already do the - latter.) + If you get a compiler warning about tparm() being implicitly + declared, add '#define TPARM_WORKAROUND' to unixconf.h or + '-DTPARM_WORKAROUND' to CFLAGS. (This should not be needed + on any modern system.) -# NetHack 3.7 Install.unx $NHDT-Date: 1577568915 2019/12/28 21:35:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ +# NetHack 5.0 Install.unx $NHDT-Date: 1577568915 2019/12/28 21:35:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ # Copyright (c) 2012 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/Makefile.check b/sys/unix/Makefile.check index 4265e5f5a..f22458ee7 100755 --- a/sys/unix/Makefile.check +++ b/sys/unix/Makefile.check @@ -1,4 +1,4 @@ -# NetHack 3.7 Makefile.check $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 +# NetHack 5.0 Makefile.check $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-5.0 SUPATH := sys/unix/ MKHINTSPATH := $(SUPATH)hints/ @@ -8,7 +8,7 @@ MKINCLPATH := $(SUPATH)hints/include/ # Expectations: # # HINTSFILE and HINTSINCLFILES are passed from the calling Makefile -# which is the case with the hints/*.370 and hints/include/*.370 +# which is the case with the hints/*.500 and hints/include/*.500 # set. # ifneq ("$(HINTSFILE)","") diff --git a/sys/unix/Makefile.dat b/sys/unix/Makefile.dat index 43c61537d..982e55e9f 100644 --- a/sys/unix/Makefile.dat +++ b/sys/unix/Makefile.dat @@ -1,4 +1,4 @@ -# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.32 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -27,10 +27,12 @@ all: $(VARDAT) spec_levs quest_levs x11tiles: ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \ ../win/share/other.txt \ - ../win/share/monsters.txt + ../win/share/monsters.txt \ + ../win/share/decals.txt ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \ ../win/share/other.txt \ - -grayscale ../win/share/monsters.txt + -grayscale ../win/share/monsters.txt \ + ../win/share/decals.txt beostiles: ../util/tile2beos ../win/share/monsters.txt \ ../win/share/objects.txt \ @@ -93,6 +95,8 @@ GEM_RSC.RSC: # cp ../win/gem/GEM_RSC.RSC GEM_RSC.RSC $(UUDECODE) ../win/gem/gem_rsc.uu +nhdat: $(DATDLB) + ( LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) data: data.base ../util/makedefs ../util/makedefs -d diff --git a/sys/unix/Makefile.doc b/sys/unix/Makefile.doc index 56d6818c3..dadbdf295 100644 --- a/sys/unix/Makefile.doc +++ b/sys/unix/Makefile.doc @@ -1,5 +1,5 @@ # NetHack Documentation Makefile. -# NetHack 3.7 Makefile.doc $NHDT-Date: 1700788000 2023/11/24 01:06:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ +# NetHack 5.0 Makefile.doc $NHDT-Date: 1700788000 2023/11/24 01:06:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -9,14 +9,24 @@ NHSROOT=.. # for Atari # SHELL=E:/GEMINI2/MUPFEL.TTP -MAKEDEFS = ../util/makedefs +MAKEDEFS ?= ../util/makedefs +# Only generate output for the current configuration: +NHGREP ?= $(MAKEDEFS) --grep --input - --output - +NEEDMAKEDEFS ?= $(MAKEDEFS) +# Generate output for all configurations: +#NHGREP ?= $(MAKEDEFS) --grep --input - --output - --grep-define ALLDOCS +#NEEDMAKEDEFS ?= $(MAKEDEFS) +# Fallback: +#NHGREP ?= cat +#NEEDMAKEDEFS ?= -#STRIPBS ?= ../util/stripbs +NROFF ?= nroff +# NROFF_FLAGS comes from a hints file, or is empty # Which version do we want to build? (XXX These are not used anywhere.) -GUIDEBOOK = Guidebook # regular ASCII file -#GUIDEBOOK = Guidebook.ps # PostScript file -#GUIDEBOOK = Guidebook.dvi # TeX device-independent file +GUIDEBOOK ?= Guidebook # regular ASCII file +#GUIDEBOOK ?= Guidebook.ps # PostScript file +#GUIDEBOOK ?= Guidebook.dvi # TeX device-independent file # Some versions of col need -x to keep them from converting spaces to tabs; # some versions of col don't do the conversion by default and don't @@ -28,39 +38,34 @@ COLCMD ?= col -bx #COLCMD ?= $(STRIPBS) # The command to use to generate a PostScript file -# PSCMD = ditroff | psdit -PSCMD = groff +# PSCMD ?= ditroff | psdit +PSCMD ?= groff +GUIDEBOOK_MN_SRC ?= Guidebook.mn +GUIDEBOOK_MN ?= $(GUIDEBOOK_MN_SRC) + +GUIDE_PREFORMAT ?= cat $(GUIDEBOOK_MN) | $(NHGREP) | tbl tmac.n - +# for Guidebook.dat, unpaginated version of Guidebook.txt +ONEPAGE_PREFORMAT ?= cat Gbk-1pg-pfx.mn $(GUIDEBOOK_MN) Gbk-1pg-sfx.mn \ + | $(NHGREP) | tbl tmac.n - +ONEPAGECMD ?= $(ONEPAGE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) | $(COLCMD) # Use the "cat" GUIDECMD if nroff and/or tbl and/or col are not installed # Not appropriate for creating Guidebook.txt. -# GUIDECMD = cat Guidebook.txt +# GUIDECMD ?= cat Guidebook.txt # # Single page. Might need adjustment to .pl value -# GUIDECMD= $(GUIDE_PREFORMAT) | perl -pe 's/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' | nroff -c -Tascii | $(COLCMD) +# PLVALUE='s/^(.mt)$$/.pl 4720v\n.in 0\n.po 8\n.ll 64m\n$$1/' +# GUIDECMD ?= $(GUIDE_PREFORMAT) | perl -pe $(PLVALUE) | $(NROFF) -c -Tascii | $(COLCMD) # -GUIDECMD = $(GUIDE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) -ONEPAGECMD = $(ONEPAGE_PREFORMAT) | nroff -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +GUIDECMD ?= $(GUIDE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) | $(COLCMD) +GUIDEBOOK_TEX_SRC ?= Guidebook.tex +GUIDEBOOK_TEX ?= $(GUIDEBOOK_TEX_SRC) -# Only generate output for the current configuration: -NHGREP = $(MAKEDEFS) --grep --input - --output - -NEEDMAKEDEFS = $(MAKEDEFS) -# Generate output for all configurations: -#NHGREP = $(MAKEDEFS) --grep --input - --output - --grep-define ALLDOCS -#NEEDMAKEDEFS = $(MAKEDEFS) -# Fallback: -#NHGREP = cat -#NEEDMAKEDEFS = - -GUIDEBOOK_MN_SRC = Guidebook.mn -GUIDEBOOK_MN = $(GUIDEBOOK_MN_SRC) -GUIDEBOOK_TEX_SRC = Guidebook.tex -GUIDEBOOK_TEX = $(GUIDEBOOK_TEX_SRC) - -GUIDE_PREFORMAT = cat $(GUIDEBOOK_MN) | $(NHGREP) | tbl tmac.n - -# for Guidebook.dat, unpaginated version of Guidebook.txt -ONEPAGE_PREFORMAT = cat Gbk-1pg-pfx.mn $(GUIDEBOOK_MN) Gbk-1pg-sfx.mn \ - | $(NHGREP) | tbl tmac.n - +#STRIPBS ?= ../util/stripbs +# STRIPBS often comes from a hints file, or is empty +# targets +# # the basic guidebook Guidebook : $(GUIDEBOOK_MN) tmac.n tmac.nh $(NEEDMAKEDEFS) $(STRIPBS) -$(GUIDECMD) > Guidebook @@ -91,20 +96,22 @@ $(MAKEDEFS) : ../util/makedefs.c ../include/config.h ../src/mdlib.c \ GAME = nethack MANDIR ?= /usr/man/man6 MANEXT = 6 -NROFF ?= nroff +MANDIRPREP ?= true # manual installation for most BSD-style systems GAMEMANCREATE = cat nethack.6 | $(NHGREP) > RCVRMANCREATE = cat recover.6 | $(NHGREP) > DLBMANCREATE = cat dlb.6 | $(NHGREP) > MDMANCREATE = cat makedefs.6 | $(NHGREP) > + # manual installation for most SYSV-style systems -# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | nroff -man - > -# RCVRMANCREATE = cat recover.6 | $(NHGREP) | nroff -man - > -# DLBMANCREATE = cat dlb.6 | $(NHGREP) | nroff -man - > -# MDMANCREATE = cat makedefs.6 | $(NHGREP) | nroff -man - > +# GAMEMANCREATE = cat nethack.6 | $(NHGREP) | $(NROFF) -man - > +# RCVRMANCREATE = cat recover.6 | $(NHGREP) | $(NROFF) -man - > +# DLBMANCREATE = cat dlb.6 | $(NHGREP) | $(NROFF) -man - > +# MDMANCREATE = cat makedefs.6 | $(NHGREP) | $(NROFF) -man - > manpages: $(PREMANPAGES) + -$(MANDIRPREP) -$(GAMEMANCREATE) $(MANDIR)/$(GAME).$(MANEXT) -$(RCVRMANCREATE) $(MANDIR)/recover.$(MANEXT) -$(DLBMANCREATE) $(MANDIR)/dlb.$(MANEXT) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 0dfa265b6..7f0660ee1 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,10 +1,11 @@ # NetHack Makefile. -# NetHack 3.7 Makefile.src $NHDT-Date: 1697316523 2023/10/14 20:48:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.164 $ +# NetHack 5.0 Makefile.src $NHDT-Date: 1697316523 2023/10/14 20:48:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.164 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # Root of source tree: -NHSROOT=.. +NHSROOT ?=.. +SRCDIR = $(NHSROOT)/src # newer makes predefine $(MAKE) to 'make' and do smarter processing of # recursive make calls if $(MAKE) is used @@ -41,37 +42,37 @@ SHELL=/bin/sh # SHELL=E:/GEMINI2/MUPFEL.TTP # Usually, the C compiler driver is used for linking: -#LINK=$(CC) +#LINK ?=$(CC) # If we're cross-compiling, a hints file will override this # to a unique target directory, but otherwise it just goes in # ../src -TARGETPFX= +TARGETPFX ?= # Pick the SYSSRC and SYSOBJ lines corresponding to your desired operating # system. # # for UNIX systems -SYSSRC = ../sys/share/ioctl.c ../sys/share/unixtty.c ../sys/unix/unixmain.c \ +SYSSRC ?= ../sys/share/ioctl.c ../sys/share/unixtty.c ../sys/unix/unixmain.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c -SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ +SYSOBJ ?= $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ $(TARGETPFX)unixunix.o $(TARGETPFX)unixres.o # # for Systos -# SYSSRC = ../sys/atari/tos.c ../sys/share/pcmain.c ../sys/share/pcsys.c \ +# SYSSRC ?= ../sys/atari/tos.c ../sys/share/pcmain.c ../sys/share/pcsys.c \ # ../sys/share/pctty.c ../sys/share/pcunix.c -# SYSOBJ = $(TARGETPFX)tos.o $(TARGETPFX)pcmain.o $(TARGETPFX)pcsys.o \ +# SYSOBJ ?= $(TARGETPFX)tos.o $(TARGETPFX)pcmain.o $(TARGETPFX)pcsys.o \ # $(TARGETPFX)pctty.o $(TARGETPFX)pcunix.o # # for BeOS -#SYSSRC = ../sys/be/bemain.c ../sys/share/unixtty.c ../sys/share/ioctl.c -#SYSOBJ = $(TARGETPFX)bemain.o $(TARGETPFX)unixtty.o $(TARGETPFX)ioctl.o +#SYSSRC ?= ../sys/be/bemain.c ../sys/share/unixtty.c ../sys/share/ioctl.c +#SYSOBJ ?= $(TARGETPFX)bemain.o $(TARGETPFX)unixtty.o $(TARGETPFX)ioctl.o -# NetHack 3.7 began introducing C99 code. +# NetHack 5.0 began introducing C99 code. # # If your compiler needs an appropriate switch to accept C99 code. -# CSTD = -std=c99 +# CSTD ?= -std=c99 # if you are using gcc as your compiler: # uncomment the CC definition below if it's not in your environment @@ -152,7 +153,7 @@ SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ # flags for Linux # compile normally # CFLAGS = -O2 -fomit-frame-pointer -I../include -# LFLAGS = -L/usr/X11R6/lib +# LFLAGS = -L/usr/lib64 # OR compile backwards compatible a.out format # CFLAGS = -O2 -b i486-linuxaout -fomit-frame-pointer -I../include # LFLAGS = -b i486-linuxaout -L/usr/X11R6/lib @@ -192,8 +193,8 @@ SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty.o \ CFLAGS ?= -I../include LINK ?= $(CC) -AR = ar -ARFLAGS = rcs +AR ?= ar +ARFLAGS ?= rcs # The Qt and Be window systems are written in C++, while the rest of # NetHack is standard C. If using Qt, uncomment the LINK line here to get @@ -210,15 +211,15 @@ MOCPATH ?= $(QTDIR)/bin/$(MOC) # The default is for the TARGET_* variables to match the defaults. # If we're cross-compiling these will get overridden elsewhere, likely via # a hints file. TARGETPFX was set above earlier. -TARGET_CC = $(CC) -TARGET_CFLAGS = $(CFLAGS) $(CSTD) -TARGET_LINK = $(LINK) -TARGET_LFLAGS = $(LFLAGS) -TARGET_CXX = $(CXX) -TARGET_CXXFLAGS = $(CXXFLAGS) -TARGET_LIBS = $(LIBS) -TARGET_AR = $(AR) -TARGET_ARFLAGS = $(ARFLAGS) +TARGET_CC ?= $(CC) +TARGET_CFLAGS ?= $(CFLAGS) $(CSTD) +TARGET_LINK ?= $(LINK) +TARGET_LFLAGS ?= $(LFLAGS) +TARGET_CXX ?= $(CXX) +TARGET_CXXFLAGS ?= $(CXXFLAGS) +TARGET_LIBS ?= $(LIBS) +TARGET_AR ?= $(AR) +TARGET_ARFLAGS ?= $(ARFLAGS) # we specify C preprocessor flags via CFLAGS; files built with default rules # might include $(CPPFLAGS) which could get a value from user's environment; @@ -227,50 +228,53 @@ CPPFLAGS = # file for regular expression matching REGEXOBJ ?= $(TARGETPFX)posixregex.o -#REGEXOBJ = $(TARGETPFX)pmatchregex.o -#REGEXOBJ = $(TARGETPFX)cppregex.o +#REGEXOBJ ?= $(TARGETPFX)pmatchregex.o +#REGEXOBJ ?= $(TARGETPFX)cppregex.o + +GENTILECFILE = $(SRCDIR)/tile.c +GENTILEOFILE ?= # Set the WINSRC, WINOBJ, and WINLIB lines to correspond to your desired # combination of windowing systems. Also set matching USE_x_GRAPHICS in -# config.h. Note that if you are building for any window system which -# uses tiles, uncomment '#$(TARGETPFX)tile.o' (by removing the '#') in that -# system's WINxOBJ (WINX11OBJ or WINQTOBJ or WINQT3OBJ). If you are building -# nethack with support for multiple window systems, only uncomment that for -# one of them to avoid duplicate tile.o. +# config.h. # # files for a straight tty port using no native windowing system -WINTTYSRC = ../win/tty/getline.c ../win/tty/termcap.c ../win/tty/topl.c \ +WINTTYSRC ?= ../win/tty/getline.c ../win/tty/termcap.c ../win/tty/topl.c \ ../win/tty/wintty.c -WINTTYOBJ = $(TARGETPFX)getline.o $(TARGETPFX)termcap.o $(TARGETPFX)topl.o \ +WINTTYOBJ ?= $(TARGETPFX)getline.o $(TARGETPFX)termcap.o $(TARGETPFX)topl.o \ $(TARGETPFX)wintty.o # # Files for curses interface -WINCURSESSRC = ../win/curses/cursmain.c ../win/curses/curswins.c \ +WINCURSESSRC ?= ../win/curses/cursmain.c ../win/curses/curswins.c \ ../win/curses/cursmisc.c ../win/curses/cursdial.c \ ../win/curses/cursstat.c ../win/curses/cursinit.c \ ../win/curses/cursmesg.c ../win/curses/cursinvt.c -WINCURSESOBJ = $(TARGETPFX)cursmain.o $(TARGETPFX)curswins.o \ +WINCURSESOBJ ?= $(TARGETPFX)cursmain.o $(TARGETPFX)curswins.o \ $(TARGETPFX)cursmisc.o $(TARGETPFX)cursdial.o \ $(TARGETPFX)cursstat.o $(TARGETPFX)cursinit.o \ $(TARGETPFX)cursmesg.o $(TARGETPFX)cursinvt.o # # files for an X11 port # (tile.c is a generated source file) -WINX11SRC = ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ +WINX11SRC ?= ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \ ../win/X11/winmap.c ../win/X11/winmenu.c ../win/X11/winmesg.c \ ../win/X11/winmisc.c ../win/X11/winstat.c ../win/X11/wintext.c \ - ../win/X11/winval.c tile.c -WINX11OBJ = $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ + ../win/X11/winval.c ../win/X11/winlabel.c \ + ../win/share/tileset.c ../win/share/bmptiles.c ../win/share/giftiles.c \ + ../win/share/pngtiles.c $(GENTILECFILE) +WINX11OBJ ?= $(TARGETPFX)Window.o $(TARGETPFX)dialogs.o $(TARGETPFX)winX.o \ $(TARGETPFX)winmap.o $(TARGETPFX)winmenu.o $(TARGETPFX)winmesg.o \ $(TARGETPFX)winmisc.o $(TARGETPFX)winstat.o $(TARGETPFX)wintext.o \ - $(TARGETPFX)winval.o #$(TARGETPFX)tile.o + $(TARGETPFX)winval.o $(TARGETPFX)winlabel.o \ + $(TARGETPFX)tileset.o $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ + $(TARGETPFX)pngtiles.o # # Files for a Qt 3 interface (renamed since nethack 3.6.x) # #WINQT3SRC = ../win/Qt3/qt3_win.cpp ../win/Qt3/qt3_clust.cpp \ # ../win/Qt3/qt3tableview.cpp #WINQT3OBJ = $(TARGETPFX)qt3_win.o $(TARGETPFX)qt3_clust.o \ -# $(TARGETPFX)qt3tableview.o #$(TARGETPFX)tile.o +# $(TARGETPFX)qt3tableview.o # empty values for 'make depend' WINQT3SRC = WINQT3OBJ = @@ -280,9 +284,9 @@ WINQT3OBJ = # # generated source files made by Qt's 'moc' program from ../win/Qt/qt_*.h; # appended to WINQTSRC for use by 'make depend' -WINQTMOC = qt_kde0.moc qt_main.moc qt_map.moc qt_menu.moc qt_msg.moc \ +WINQTMOC ?= qt_kde0.moc qt_main.moc qt_map.moc qt_menu.moc qt_msg.moc \ qt_plsel.moc qt_set.moc qt_stat.moc qt_xcmd.moc qt_yndlg.moc -WINQTSRC = ../win/Qt/qt_bind.cpp ../win/Qt/qt_click.cpp \ +WINQTSRC ?= ../win/Qt/qt_bind.cpp ../win/Qt/qt_click.cpp \ ../win/Qt/qt_clust.cpp ../win/Qt/qt_delay.cpp \ ../win/Qt/qt_glyph.cpp ../win/Qt/qt_icon.cpp ../win/Qt/qt_inv.cpp \ ../win/Qt/qt_key.cpp ../win/Qt/qt_line.cpp ../win/Qt/qt_main.cpp \ @@ -290,8 +294,8 @@ WINQTSRC = ../win/Qt/qt_bind.cpp ../win/Qt/qt_click.cpp \ ../win/Qt/qt_plsel.cpp ../win/Qt/qt_rip.cpp ../win/Qt/qt_set.cpp \ ../win/Qt/qt_stat.cpp ../win/Qt/qt_str.cpp ../win/Qt/qt_streq.cpp \ ../win/Qt/qt_svsel.cpp ../win/Qt/qt_win.cpp ../win/Qt/qt_xcmd.cpp \ - ../win/Qt/qt_yndlg.cpp $(WINQTMOC) tile.c -WINQTOBJ = $(TARGETPFX)qt_bind.o $(TARGETPFX)qt_click.o \ + ../win/Qt/qt_yndlg.cpp $(WINQTMOC) $(GENTILECFILE) +WINQTOBJ ?= $(TARGETPFX)qt_bind.o $(TARGETPFX)qt_click.o \ $(TARGETPFX)qt_clust.o $(TARGETPFX)qt_delay.o \ $(TARGETPFX)qt_glyph.o $(TARGETPFX)qt_icon.o \ $(TARGETPFX)qt_inv.o $(TARGETPFX)qt_key.o $(TARGETPFX)qt_line.o \ @@ -299,23 +303,22 @@ WINQTOBJ = $(TARGETPFX)qt_bind.o $(TARGETPFX)qt_click.o \ $(TARGETPFX)qt_msg.o $(TARGETPFX)qt_plsel.o $(TARGETPFX)qt_rip.o \ $(TARGETPFX)qt_set.o $(TARGETPFX)qt_stat.o $(TARGETPFX)qt_str.o \ $(TARGETPFX)qt_streq.o $(TARGETPFX)qt_svsel.o $(TARGETPFX)qt_win.o \ - $(TARGETPFX)qt_xcmd.o $(TARGETPFX)qt_yndlg.o #$(TARGETPFX)tile.o + $(TARGETPFX)qt_xcmd.o $(TARGETPFX)qt_yndlg.o # Files for Shim windowing interface for libnh -- doesn't do anything, # just passes along the API calls to the library # -WINSHIMSRC = ../win/shim/winshim.c -WINSHIMOBJ = winshim.o +WINSHIMSRC ?= ../win/shim/winshim.c +WINSHIMOBJ ?= winshim.o # # Files for a BeOS InterfaceKit port -- not ready for prime time -WINBESRC = -WINBEOBJ = +WINBESRC ?= +WINBEOBJ ?= #WINBESRC = ../win/BeOS/winbe.cpp ../win/BeOS/NHWindow.cpp \ -# ../win/BeOS/NHMenuWindow.cpp ../win/BeOS/NHMapWindow.cpp tile.c +# ../win/BeOS/NHMenuWindow.cpp ../win/BeOS/NHMapWindow.cpp $(GENTILECFILE) #WINBEOBJ = $(TARGETPFX)winbe.o $(TARGETPFX)NHWindow.o \ -# $(TARGETPFX)NHMenuWindow.o $(TARGETPFX)NHMapWindow.o \ -# $(TARGETPFX)tile.o +# $(TARGETPFX)NHMenuWindow.o $(TARGETPFX)NHMapWindow.o # # #WINSRC = $(WINTTYSRC) @@ -353,20 +356,20 @@ WINBEOBJ = WINQT3LIB = -L$(QTDIR)/lib -lqt # # libraries for Qt 4 -WINQT4LIB = `pkg-config QtGui --libs` +WINQT4LIB ?= `pkg-config QtGui --libs` # # libraries for Qt 5 (use with WINQTSRC and WINQTOBJ) -WINQT5LIB = `pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs` +WINQT5LIB ?= `pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs` # # libraries for KDE (with Qt) -WINKDELIB = -lkdecore -lkdeui -lXext +WINKDELIB ?= -lkdecore -lkdeui -lXext # # libraries for BeOS -WINBELIB = -lbe +WINBELIB ?= -lbe # # libraries for curses port # link with ncurses -WINCURSESLIB = -lncurses +WINCURSESLIB ?= -lncurses # link with pdcurses for SDL, installed in a separate directory #WINCURSESLIB = -L/usr/local/lib/pdcurses -lpdcurses -lSDL # same as above, for XCurses @@ -415,18 +418,18 @@ WINOBJ ?= $(WINTTYOBJ) WINLIB ?= $(WINTTYLIB) -lncurses # make NetHack -GAME = nethack +GAME ?= nethack # GAME = nethack.prg -GAMEBIN = $(GAME) +GAMEBIN ?= $(GAME) # if you defined RANDOM in unixconf.h since your system did not come # with a reasonable random number generator # RANDOBJ = $(TARGETPFX)random.o -RANDOBJ = +RANDOBJ ?= # used by `make depend' to reconstruct this Makefile; you shouldn't need this # at all but can override with 'make AWK=nawk' or 'make AWK=gawk' if necessary -AWK = awk +AWK ?= awk # when using 'makedefs -v', also force dat/gitinfo.txt to be up to date; # changing this to 0 will change the behavior to only make that file if @@ -491,22 +494,22 @@ AT = $(AT_V$(QUIETCC)) # verbosity-adjacent; these will already have 'real' values if hints have # set up cross-compiling, in which case these assignments will be no-ops -PREGAME=@true -PACKAGE=@true +PREGAME ?=@true +PACKAGE ?=@true -HACKLIBSRC = hacklib.c -HACKLIBOBJS = hacklib.o -HACKLIB = hacklib.a -TARGET_HACKLIB = $(TARGETPFX)hacklib.a +HACKLIBSRC ?= hacklib.c +HACKLIBOBJS ?= hacklib.o +HACKLIB ?= hacklib.a +TARGET_HACKLIB ?= $(TARGETPFX)hacklib.a -MAKEDEFS = ../util/makedefs +MAKEDEFS ?= ../util/makedefs # -lm required by lua LUA_VERSION ?=5.4.8 -LUABASE = liblua-$(LUA_VERSION).a -LUALIB = ../lib/lua/$(LUABASE) -LUALIBS = $(LUALIB) -lm $(DLLIB) -LUAHEADERS = lib/lua-$(LUA_VERSION)/src +LUABASE ?= liblua-$(LUA_VERSION).a +LUALIB ?= ../lib/lua/$(LUABASE) +LUALIBS ?= $(LUALIB) -lm $(DLLIB) +LUAHEADERS ?= lib/lua-$(LUA_VERSION)/src # timestamp files to reduce `make' overhead and shorten .o dependency lists CONFIG_H = ../src/config.h-t @@ -514,82 +517,81 @@ HACK_H = ../src/hack.h-t # all .c that are part of the main NetHack program and are not operating- or # windowing-system specific. Do not include date.c in this list. -HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ - botl.c calendar.c cmd.c coloratt.c dbridge.c decl.c detect.c dig.c display.c \ - dlb.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c dothrow.c \ - drawing.c dungeon.c earlyarg.c eat.c end.c engrave.c exper.c explode.c \ - extralev.c files.c fountain.c hack.c hacklib.c \ +HACKCSRC ?= allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ + botl.c calendar.c cmd.c coloratt.c dbridge.c decl.c detect.c dig.c \ + display.c dlb.c do.c do_name.c do_wear.c dog.c dogmove.c dokick.c \ + dothrow.c drawing.c dungeon.c earlyarg.c eat.c end.c engrave.c \ + exper.c explode.c extralev.c files.c fountain.c hack.c hacklib.c \ getpos.c glyphs.c iactions.c insight.c invent.c isaac64.c light.c \ lock.c mail.c makemon.c mcastu.c mdlib.c mhitm.c \ mhitu.c minion.c mklev.c mkmap.c mkmaze.c mkobj.c mkroom.c mon.c \ mondata.c monmove.c monst.c mplayer.c mthrowu.c muse.c music.c \ nhlua.c nhlsel.c nhlobj.c nhmd4.c o_init.c objects.c objnam.c \ options.c pager.c pickup.c pline.c polyself.c potion.c pray.c \ - priest.c quest.c questpgr.c read.c rect.c region.c report.c restore.c \ - rip.c rnd.c role.c rumors.c save.c selvar.c sfbase.c sfstruct.c \ - shk.c shknam.c sit.c sounds.c sp_lev.c spell.c stairs.c steal.c steed.c \ - strutil.c symbols.c sys.c teleport.c timeout.c \ - topten.c track.c trap.c twitch.c u_init.c utf8map.c \ - uhitm.c vault.c version.c vision.c weapon.c were.c wield.c \ - windows.c wizard.c wizcmds.c worm.c worn.c write.c zap.c + priest.c quest.c questpgr.c read.c rect.c region.c report.c \ + restore.c revision.c rip.c rnd.c role.c rumors.c save.c selvar.c \ + sfbase.c sfstruct.c shk.c shknam.c sit.c sounds.c sp_lev.c \ + spell.c stairs.c steal.c steed.c strutil.c symbols.c sys.c \ + teleport.c timeout.c topten.c track.c trap.c twitch.c \ + u_init.c utf8map.c uhitm.c vault.c version.c vision.c weapon.c \ + were.c wield.c windows.c wizard.c wizcmds.c worm.c worn.c write.c zap.c # all operating-system-dependent .c (for dependencies and such) -SYSCSRC = ../sys/share/pcmain.c ../sys/share/pcsys.c \ +SYSCSRC ?= ../sys/share/pcmain.c ../sys/share/pcsys.c \ ../sys/share/pctty.c ../sys/share/pcunix.c \ ../sys/share/pmatchregex.c ../sys/share/posixregex.c \ ../sys/share/random.c \ ../sys/share/ioctl.c ../sys/share/unixtty.c ../sys/unix/unixmain.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c -SYSCXXSRC = ../sys/share/cppregex.cpp - -# generated source files (tile.c is handled separately via WINxxxSRC) -GENCSRC = #tile.c +SYSCXXSRC ?= ../sys/share/cppregex.cpp # all windowing-system-dependent .c (for dependencies and such) -WINCSRC = $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINSHIMSRC) +WINCSRC ?= $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINSHIMSRC) # all windowing-system-dependent .cpp (for dependencies and such) -WINCXXSRC = $(WINQTSRC) $(WINQT3SRC) $(WINBESRC) +WINCXXSRC ?= $(WINQTSRC) $(WINQT3SRC) $(WINBESRC) # Files for window system chaining. Requires SYSCF; include via HINTSRC/HINTOBJ -CHAINSRC = ../win/chain/wc_chainin.c ../win/chain/wc_chainout.c \ +CHAINSRC ?= ../win/chain/wc_chainin.c ../win/chain/wc_chainout.c \ ../win/chain/wc_trace.c -CHAINOBJ = $(TARGETPFX)wc_chainin.o $(TARGETPFX)wc_chainout.o \ +CHAINOBJ ?= $(TARGETPFX)wc_chainin.o $(TARGETPFX)wc_chainout.o \ $(TARGETPFX)wc_trace.o # .c files for this version (for date.h) -VERSOURCES = $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC) +VERSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) # .c files for all versions using this Makefile (for lint and tags) -CSOURCES = $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC) +CSOURCES ?= $(HACKCSRC) $(HACKLIBSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) # all .h files except date.h, which would # cause dependency loops if run through "make depend" # and dgn_file.h, special level & dungeon files. # -HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \ +HACKINCL ?= align.h artifact.h artilist.h attrib.h botl.h \ color.h config.h config1.h context.h coord.h cstd.h decl.h \ defsym.h display.h dlb.h dungeon.h engrave.h extern.h flag.h \ fnamesiz.h func_tab.h global.h warnings.h hack.h lint.h mextra.h \ - mcastu.h \ - micro.h mfndpos.h mkroom.h monattk.h mondata.h monflag.h monst.h \ - monsters.h nhmd4.h obj.h objects.h objclass.h optlist.h patchlevel.h \ - pcconf.h permonst.h prop.h rect.h region.h savefile.h selvar.h sym.h \ - rm.h sp_lev.h spell.h sndprocs.h seffects.h stairs.h sys.h \ - tcap.h timeout.h tradstdc.h trap.h unixconf.h vision.h vmsconf.h \ - wintty.h wincurs.h winX.h winprocs.h wintype.h you.h youprop.h \ - weight.h + mcastu.h micro.h mfndpos.h mkroom.h monattk.h mondata.h monflag.h \ + monst.h monsters.h nhmd4.h obj.h objects.h objclass.h optlist.h \ + patchlevel.h pcconf.h permonst.h prop.h rect.h region.h revision.h \ + savefile.h selvar.h sym.h rm.h sp_lev.h spell.h sndprocs.h \ + seffects.h stairs.h sys.h tcap.h timeout.h tradstdc.h trap.h \ + unixconf.h vision.h vmsconf.h wintty.h wincurs.h winX.h winprocs.h \ + wintype.h you.h youprop.h weight.h -HSOURCES = $(HACKINCL) dgn_file.h +HSOURCES ?= $(HACKINCL) dgn_file.h # the following .o's _must_ be made before any others (for makedefs) -FIRSTOBJ = monst.o objects.o -HOSTOBJ = $(FIRSTOBJ) alloc.o drawing.o +FIRSTOBJ ?= monst.o objects.o +HOSTOBJ ?= $(FIRSTOBJ) alloc.o drawing.o + +#$(info WINOBJ=$(WINOBJ)) +#$(info GENTILEOFILE=$(GENTILEOFILE)) # # $(TARGETPFX)date.o is not included in this list # -HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ +HOBJ ?= $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)apply.o $(TARGETPFX)artifact.o $(TARGETPFX)attrib.o \ $(TARGETPFX)ball.o $(TARGETPFX)bones.o $(TARGETPFX)botl.o \ $(TARGETPFX)calendar.o $(TARGETPFX)cfgfiles.o $(TARGETPFX)cmd.o \ @@ -618,21 +620,23 @@ HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)potion.o $(TARGETPFX)pray.o $(TARGETPFX)priest.o \ $(TARGETPFX)quest.o $(TARGETPFX)questpgr.o $(TARGETPFX)read.o \ $(TARGETPFX)rect.o $(TARGETPFX)region.o $(TARGETPFX)report.o \ - $(TARGETPFX)restore.o $(TARGETPFX)rip.o $(TARGETPFX)rnd.o \ - $(TARGETPFX)role.o $(TARGETPFX)rumors.o $(TARGETPFX)save.o \ - $(TARGETPFX)selvar.o $(TARGETPFX)sfbase.o $(TARGETPFX)sfstruct.o \ - $(TARGETPFX)shk.o $(TARGETPFX)shknam.o $(TARGETPFX)sit.o \ - $(TARGETPFX)sounds.o $(TARGETPFX)sp_lev.o $(TARGETPFX)spell.o \ - $(TARGETPFX)stairs.o $(TARGETPFX)symbols.o $(TARGETPFX)sys.o \ - $(TARGETPFX)steal.o $(TARGETPFX)steed.o $(TARGETPFX)strutil.o \ - $(TARGETPFX)teleport.o $(TARGETPFX)timeout.o $(TARGETPFX)topten.o \ - $(TARGETPFX)track.o $(TARGETPFX)trap.o $(TARGETPFX)twitch.o \ - $(TARGETPFX)u_init.o $(TARGETPFX)uhitm.o $(TARGETPFX)utf8map.o \ - $(TARGETPFX)vault.o $(TARGETPFX)vision.o $(TARGETPFX)weapon.o \ - $(TARGETPFX)were.o $(TARGETPFX)wield.o $(TARGETPFX)windows.o \ - $(TARGETPFX)wizard.o $(TARGETPFX)wizcmds.o $(TARGETPFX)worm.o \ - $(TARGETPFX)worn.o $(TARGETPFX)write.o $(TARGETPFX)zap.o \ - $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) $(HINTOBJ) $(SNDLIBOBJ) \ + $(TARGETPFX)restore.o $(TARGETPFX)revision.o $(TARGETPFX)rip.o \ + $(TARGETPFX)rnd.o $(TARGETPFX)role.o $(TARGETPFX)rumors.o \ + $(TARGETPFX)save.o $(TARGETPFX)selvar.o $(TARGETPFX)sfbase.o \ + $(TARGETPFX)sfstruct.o $(TARGETPFX)shk.o $(TARGETPFX)shknam.o \ + $(TARGETPFX)sit.o $(TARGETPFX)sounds.o $(TARGETPFX)sp_lev.o \ + $(TARGETPFX)spell.o $(TARGETPFX)stairs.o $(TARGETPFX)symbols.o \ + $(TARGETPFX)sys.o $(TARGETPFX)steal.o $(TARGETPFX)steed.o \ + $(TARGETPFX)strutil.o $(TARGETPFX)teleport.o $(TARGETPFX)timeout.o \ + $(TARGETPFX)topten.o $(TARGETPFX)track.o $(TARGETPFX)trap.o \ + $(TARGETPFX)twitch.o $(TARGETPFX)u_init.o $(TARGETPFX)uhitm.o \ + $(TARGETPFX)utf8map.o $(TARGETPFX)vault.o $(TARGETPFX)vision.o \ + $(TARGETPFX)weapon.o $(TARGETPFX)were.o $(TARGETPFX)wield.o \ + $(TARGETPFX)windows.o $(TARGETPFX)wizard.o $(TARGETPFX)wizcmds.o \ + $(TARGETPFX)worm.o $(TARGETPFX)worn.o $(TARGETPFX)write.o \ + $(TARGETPFX)zap.o \ + $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) \ + $(HINTOBJ) $(SNDLIBOBJ) $(UUIDOBJ) \ $(TARGETPFX)version.o DATE_O = $(TARGETPFX)date.o @@ -643,8 +647,10 @@ DATE_O = $(TARGETPFX)date.o all: $(GAME) @echo "" -create_responsefiles: +../src/nethack_cc.rsp: echo $(CC_COMPILER_SWITCHES) >$(CC_RESPONSEFILE) + +../src/nethack_cxx.rsp: echo $(CXX_COMPILER_SWITCHES) >$(CXX_RESPONSEFILE) pregame: $(RESPONSEFILES) @@ -653,45 +659,55 @@ pregame: $(RESPONSEFILES) $(GAME): pregame $(MAKEDEFS) $(LUALIB) $(WAVS) $(SYSTEM) @echo "$(GAME) is up to date." -Sysunix: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +#$(info DATE_O=$(DATE_O)) +#$(info GENTILEOFILE=$(GENTILEOFILE)) + +Sysunix: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) $(WINLIB) \ + $(HOBJ) $(DATE_O) $(GENTILEOFILE) \ + $(TARGET_HACKLIB) $(WINLIB) \ $(TARGET_LIBS) $(LUALIBS) $(AUTOLIBS) @touch Sysunix -Sys3B2: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +Sys3B2: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) $(WINLIB) \ - $(LUALIBS) -lmalloc + $(HOBJ) $(DATE_O) $(GENTILEOFILE) \ + $(TARGET_HACKLIB) $(WINLIB) $(LUALIBS) -lmalloc @touch Sys3B2 -Sysatt: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +Sysatt: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Loading $(GAME)." $(AT)$(LD) $(TARGET_LFLAGS) /lib/crt0s.o /lib/shlib.ifile \ - -o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ - $(LUALIBS) + -o $(GAMEBIN) $(HOSTOBJ) $(HOBJ) \ + $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) $(LUALIBS) @touch Sysatt -Systos: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +Systos: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ + $(HOBJ) $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(WINLIB) $(LUALIBS) @touch Systos -SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ + $(HOBJ) $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(WINLIB) $(LUALIBS) @touch SysV-AT -SysBe: $(HOSTOBJ) $(HOBJ) $(TARGET_HACKLIB) $(DATE_O) $(BUILDMORE) Makefile +SysBe: $(HOSTOBJ) $(HOBJ) $(GENTILEOFILE) $(TARGET_HACKLIB) \ + $(DATE_O) $(BUILDMORE) Makefile @echo "Linking $(GAME)." $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAME) \ - $(HOBJ) $(DATE_O) $(TARGET_HACKLIB) \ + $(HOBJ) $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) \ $(WINLIB) $(TARGET_LIBS) $(LUALIBS) @xres -o $(GAME) ../win/BeOS/nethack.rsrc @mimeset -f $(GAME) @@ -743,7 +759,7 @@ qt3tableview.moc: ../win/Qt3/qt3tableview.h $(QTDIR)/bin/moc -o qt3tableview.moc ../win/Qt3/qt3tableview.h # build monst.o and objects.o before executing '$(MAKE) makedefs' -$(MAKEDEFS): $(FIRSTOBJ) \ +$(MAKEDEFS): $(RESPONSEFILES) $(FIRSTOBJ) \ ../util/makedefs.c ../src/mdlib.c $(CONFIG_H) \ ../include/permonst.h ../include/monsters.h \ ../include/objclass.h ../include/objects.h ../include/sym.h \ @@ -761,7 +777,7 @@ $(MAKEDEFS): $(FIRSTOBJ) \ @( cd ../util ; $(MAKE) ../include/pm.h ) # Created at build time for configurations which support tiles, # but not by makedefs so not connected to the others. -tile.c: ../win/share/tilemap.c $(HACK_H) +../src/tile.c: $(RESPONSEFILES) ../win/share/tilemap.c $(HACK_H) @( cd ../util ; $(MAKE) ../src/tile.c ) # @@ -779,7 +795,7 @@ $(TARGETPFX)sfbase.o: sfbase.c $(HACK_H) ../include/sfprocs.h ../include/sfmacro # date.c should be recompiled any time any of the source or include code # is modified. DATECFLAGS = $(TARGET_CFLAGS) $(GITHASH) $(GITBRANCH) $(GITPREFIX) -$(TARGETPFX)date.o: date.c $(HACK_H) $(HACKCSRC) $(HOBJ) $(TARGET_HACKLIB) +$(TARGETPFX)date.o: date.c $(GENTILECFILE) $(HACK_H) $(HACKCSRC) $(HOBJ) $(TARGET_HACKLIB) $(TARGET_CC) $(DATECFLAGS) -c -o $@ date.c # date.h should be remade any time any of the source or include code @@ -790,7 +806,7 @@ $(TARGETPFX)date.o: date.c $(HACK_H) $(HACKCSRC) $(HOBJ) $(TARGET_HACKLIB) # Do NOT include ../dat/gitinfo.txt as either a prerequisite or target. # 'makedefs -v' processes it when present and ignores it if not. # -../include/date.h: ../util/makedefs $(VERSOURCES) $(HACK_H) +../include/date.h: $(RESPONSEFILES) ../util/makedefs $(VERSOURCES) $(HACK_H) -$(SHELL) ../sys/unix/gitinfo.sh $(GITINFO) #before 'makedefs -v' ../util/makedefs -v @@ -820,7 +836,7 @@ spotless: clean -rm -f ../include/nhlua.h -rm -f ../include/date.h #created but no longer used, at least by core -rm -f ../include/onames.h ../include/pm.h #obsolete generated files - -rm -f tile.c *.moc Qt*.h-t + -rm -f $(GENTILECFILE) *.moc Qt*.h-t -rm -f ../win/gnome/gn_rip.h package: @@ -852,7 +868,7 @@ updatedepend-setup: echo '#include "../$(LUAHEADERS)/lualib.h"' >> $$HFILE && \ echo '#include "../$(LUAHEADERS)/lauxlib.h"' >> $$HFILE && \ echo '/*nhlua.h*/' >> $$HFILE ) - @echo "Generating bogus src/tile.c" + @echo "Generating bogus $(GENTILECFILE)" @echo '#error bogus include/nhlua.h' > ../../src/tile.c @echo "#include \"hack.h\"" >> ../../src/tile.c @@ -877,7 +893,8 @@ depend2: $(WINQTMOC) @echo '# see make depend above' >> $(MAKEFILE_NAME) - diff Makefile.bak $(MAKEFILE_NAME) @rm -f Makefile.bak - @rm -f ../include/nhlua.h tile.c + @rm -f ../include/nhlua.h $(GENTILECFILE) + # DO NOT DELETE THIS LINE OR CHANGE ANYTHING BEYOND IT @@ -896,19 +913,19 @@ $(HACK_H): $(CONFIG_H) ../include/align.h ../include/artilist.h \ ../include/decl.h ../include/defsym.h ../include/display.h \ ../include/dungeon.h ../include/engrave.h ../include/flag.h \ ../include/hack.h ../include/lint.h ../include/mextra.h \ - ../include/mcastu.h \ - ../include/mkroom.h ../include/monattk.h ../include/mondata.h \ - ../include/monflag.h ../include/monst.h ../include/monsters.h \ - ../include/nhlua.h ../include/obj.h ../include/objclass.h \ - ../include/objects.h ../include/permonst.h ../include/prop.h \ - ../include/quest.h ../include/rect.h ../include/region.h \ + ../include/mcastu.h ../include/mkroom.h ../include/monattk.h \ + ../include/mondata.h ../include/monflag.h ../include/monst.h \ + ../include/monsters.h ../include/nhlua.h ../include/obj.h \ + ../include/objclass.h ../include/objects.h \ + ../include/permonst.h ../include/prop.h ../include/quest.h \ + ../include/rect.h ../include/region.h ../include/revision.h \ ../include/rm.h ../include/savefile.h ../include/sfprocs.h \ - ../include/seffects.h ../include/selvar.h \ - ../include/skills.h ../include/sndprocs.h ../include/spell.h \ - ../include/stairs.h ../include/sym.h ../include/sys.h \ - ../include/timeout.h ../include/trap.h ../include/vision.h \ - ../include/weight.h ../include/winprocs.h \ - ../include/wintype.h ../include/you.h ../include/youprop.h + ../include/seffects.h ../include/selvar.h ../include/skills.h \ + ../include/sndprocs.h ../include/spell.h ../include/stairs.h \ + ../include/sym.h ../include/sys.h ../include/timeout.h \ + ../include/trap.h ../include/vision.h ../include/weight.h \ + ../include/winprocs.h ../include/wintype.h ../include/you.h \ + ../include/youprop.h touch $(HACK_H) # $(TARGETPFX)cppregex.o: ../sys/share/cppregex.cpp $(CONFIG_H) @@ -1070,6 +1087,8 @@ $(TARGETPFX)winX.o: ../win/X11/winX.c $(HACK_H) ../include/dlb.h \ ../include/winX.h ../include/xwindow.h ../win/X11/nh32icon \ ../win/X11/nh56icon ../win/X11/nh72icon $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winX.c +$(TARGETPFX)winlabel.o: ../win/X11/winlabel.c $(HACK_H) ../include/winX.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winlabel.c $(TARGETPFX)winmap.o: ../win/X11/winmap.c $(HACK_H) ../include/dlb.h \ ../include/tile2x11.h ../include/winX.h ../include/xwindow.h $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmap.c @@ -1089,6 +1108,18 @@ $(TARGETPFX)wintext.o: ../win/X11/wintext.c $(HACK_H) ../include/winX.h \ $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/wintext.c $(TARGETPFX)winval.o: ../win/X11/winval.c $(HACK_H) ../include/winX.h $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winval.c +$(TARGETPFX)tileset.o: ../win/share/tileset.c $(CONFIG_H) \ + ../include/objclass.h ../include/flag.h ../include/tileset.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/tileset.c +$(TARGETPFX)bmptiles.o: ../win/share/bmptiles.c $(CONFIG_H) \ + ../include/objclass.h ../include/tileset.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/bmptiles.c +$(TARGETPFX)giftiles.o: ../win/share/giftiles.c $(CONFIG_H) \ + ../include/objclass.h ../include/tileset.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/giftiles.c +$(TARGETPFX)pngtiles.o: ../win/share/pngtiles.c $(CONFIG_H) \ + ../include/objclass.h ../include/tileset.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/share/pngtiles.c $(TARGETPFX)wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H) $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_chainin.c $(TARGETPFX)wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H) @@ -1245,6 +1276,7 @@ $(TARGETPFX)rect.o: rect.c $(HACK_H) $(TARGETPFX)region.o: region.c $(HACK_H) $(TARGETPFX)report.o: report.c $(HACK_H) ../include/dlb.h ../include/nhmd4.h $(TARGETPFX)restore.o: restore.c $(HACK_H) ../include/tcap.h +$(TARGETPFX)revision.o: revision.c $(HACK_H) $(TARGETPFX)rip.o: rip.c $(HACK_H) $(TARGETPFX)rnd.o: rnd.c $(HACK_H) ../include/isaac64.h $(TARGETPFX)role.o: role.c $(HACK_H) @@ -1265,7 +1297,7 @@ $(TARGETPFX)strutil.o: strutil.c $(HACK_H) $(TARGETPFX)symbols.o: symbols.c $(HACK_H) ../include/tcap.h $(TARGETPFX)sys.o: sys.c $(HACK_H) $(TARGETPFX)teleport.o: teleport.c $(HACK_H) -$(TARGETPFX)tile.o: tile.c $(HACK_H) +$(TARGETPFX)tile.o: $(SRCDIR)/tile.c $(HACK_H) $(TARGETPFX)timeout.o: timeout.c $(HACK_H) $(TARGETPFX)topten.o: topten.c $(HACK_H) ../include/dlb.h $(TARGETPFX)track.o: track.c $(HACK_H) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index c108f3552..6cb097348 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -1,5 +1,5 @@ # NetHack Top-level Makefile. -# NetHack 3.7 Makefile.top $NHDT-Date: 1722119081 2024/07/27 22:24:41 $ $NHDT-Branch: keni-fetchlua $:$NHDT-Revision: 1.109 $ +# NetHack 5.0 Makefile.top $NHDT-Date: 1722119081 2024/07/27 22:24:41 $ $NHDT-Branch: keni-fetchlua $:$NHDT-Revision: 1.109 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -27,6 +27,7 @@ GAME = nethack # GAME = nethack.prg #GAMEUID = games #GAMEGRP = bin +TARGET_CC ?= $(CC) # Permissions - some places use setgid instead of setuid, for instance. # See also the option "SECURE" in include/config.h. @@ -121,13 +122,15 @@ DAT = $(DATNODLB) $(DATDLB) RECOVERBIN = recover # Lua -LUAHEADERS = lib/lua-$(LUA_VERSION)/src -LUATESTTARGET = $(LUAHEADERS)/lua.h +LUAHEADERS ?= lib/lua-$(LUA_VERSION)/src +LUATESTTARGET ?= $(LUAHEADERS)/lua.h LUATOP = $(LUAHEADERS) -LUAMAKEFLAGS = CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' -LUA2NHTOP = ../../.. -LUABASELIB = liblua-$(LUA_VERSION).a -TOPLUALIB = lib/lua/$(LUABASELIB) +LUAMAKEFLAGS ?= CC='$(TARGET_CC)' SYSCFLAGS='$(SYSCFLAGS)' +LUA2NHTOP ?= ../../.. +LUABASELIB ?= liblua-$(LUA_VERSION).a +LUATOPLIB ?= lib/lua/$(LUABASELIB) +LUAHPREFIX ?= ../ +LUALIBBUILT ?= $(LUATOP)/liblua.a ALLDEP = $(PRECHECK) $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb @@ -143,18 +146,18 @@ lua_support: include/nhlua.h @true $(LUATOP)/liblua.a: $(LUAHEADERS)/lua.h ( cd $(LUATOP) && make $(LUAMAKEFLAGS) a ) -$(TOPLUALIB): $(LUATOP)/liblua.a +lib/lua/$(LUABASELIB): $(LUALIBBUILT) @( if test -d lib/lua ; then true ; else mkdir -p lib/lua ; fi ) cp $(LUATOP)/liblua.a $@ -include/nhlua.h: $(TOPLUALIB) +include/nhlua.h: $(LUATOPLIB) echo '/* nhlua.h - generated by top Makefile */' > $@ - @echo '#include "../$(LUAHEADERS)/lua.h"' >> $@ + @echo '#include "$(LUAHPREFIX)$(LUAHEADERS)/lua.h"' >> $@ @sed -e '/(lua_error)/!d' \ -e '/(lua_error)/s/LUA_API/ATTRNORETURN LUA_API/1' \ -e '/(lua_error)/s/;/ NORETURN;/1' < $(LUAHEADERS)/lua.h >> $@ - @echo '#include "../$(LUAHEADERS)/lualib.h"' >> $@ - @echo '#include "../$(LUAHEADERS)/lauxlib.h"' >> $@ + @echo '#include "$(LUAHPREFIX)$(LUAHEADERS)/lualib.h"' >> $@ + @echo '#include "$(LUAHPREFIX)$(LUAHEADERS)/lauxlib.h"' >> $@ @echo '/*nhlua.h*/' >> $@ # LUATESTTARGET is this by default lib/lua-$(LUA_VERSION)/src/lua.h: @@ -275,7 +278,7 @@ check-dlb: options dlb: ( cd util ; $(MAKE) dlb ) - ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) + ( cd dat ; $(MAKE) DATDLB="$(DATDLB)" nhdat ) wasm: ( cd src ; $(MAKE) CROSS_TO_WASM=1 ../targets/wasm/nethack.js ) @@ -342,7 +345,15 @@ LUA_URL :=www.lua.org/ftp LUA_URL_MIRROR :=www.tecgraf.puc-rio.br/lua/mirror/ftp LUA_URL_NHD :=www.nethack.org/download/thirdparty LUA_URL_list:=$(LUA_URL) $(LUA_URL_MIRROR) $(LUA_URL_NHD) +# +#CURL := curl +#ask curl to return a failure code if error 404 is encountered +CURL := curl -q --fail --no-progress-meter +# Set this to 1 to bypass checksum verification. _Highly_ discouraged. +#NOCHKSUM=1 + +#debugging targets fetch-lua-mirror: LUA_URL_list:=$(LUA_URL_MIRROR) fetch-lua-mirror: fetch-Lua @true @@ -351,54 +362,90 @@ fetch-lua-nhd: LUA_URL_list:=$(LUA_URL_NHD) fetch-lua-nhd: fetch-Lua @true +# normal entry point fetch-lua: fetch-Lua @true fetch-Lua: @( \ - shac1=`command -v shasum`; \ - shac2=`command -v sha256sum`; \ - if [ ! -z $$shac1 ]; then \ - shac="$$shac1 -a 256"; elif [ ! -z $$shac2 ]; then \ - shac=$$shac2; else echo "CAUTION: no way to check integrity"; \ - fi; \ - set -- DUMMY $(LUA_URL_list); \ - luafile=lua-$(LUA_VERSION).tar.gz; \ - export curlstatus=1; \ - mkdir -p lib && cd lib && \ - while [ $$# -gt 0 ]; do \ + `: $1 = file to check`; \ + chksum_or_fail(){ \ + local shac shac1 shac2; \ + shac1=`command -v shasum`; \ + shac2=`command -v sha256sum`; \ + if [ ! -z $$shac1 ]; then \ + shac="$$shac1 -a 256"; \ + elif [ ! -z $$shac2 ]; then \ + shac=$$shac2; \ + else \ + echo "CAUTION: no way to check integrity"; \ + echo "Rerun with 'NOCHKSUM=1' to skip this check"; \ + exit 1; \ + fi; \ + echo "Checking integrity of $$1 with $$shac"; \ + $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$1; \ + if [ $$? -ne 0 ]; then \ + echo "Integrity check FAILED - STOPPING"; \ + exit 1; \ + fi; \ + echo "Integrity check passed"; \ + }; \ + `: $1 = name of tarfile`; \ + untar_and_cleanup(){ \ + echo "Unpacking $$1"; \ + tar zxf $$1; \ + if [ $$? -eq '0' ]; then \ + rm -f $$1; \ + echo "Unpacked successfully into `pwd`"; \ + return 0; \ + else \ + echo "tar failed to extract $$1 - trying next source"; \ + return 1; \ + fi; \ + }; \ + `: main`; \ + set -- $(LUA_URL_list); \ + luafile=lua-$(LUA_VERSION).tar.gz; \ + mkdir -p lib; \ + cd lib || { \ + echo "Unable to find lib directory"; \ + exit 1; \ + }; \ + while [ $$# -gt 0 ]; do \ + iter=$$1; \ shift; \ - if [ $$curlstatus -ne 0 ]; then \ - luaurl=https://$$1/$$luafile; \ - echo Trying $$luaurl; \ - curl -R -O $$luaurl; \ - curlstatus=$$?; \ - if [ $$curlstatus -eq 0 ]; then \ - if [ ! -z "$$shac" ]; then \ + luaurl=https://$$iter/$$luafile; \ + echo "Fetching $$luaurl"; \ + if $(CURL) -R -O $$luaurl ; then \ + if [ -z $(NOCHKSUM) ]; then \ + echo "Searching for known checksum"; \ CHKSUMS=../submodules/CHKSUMS; \ CHKSUMSTMP=../submodules/CHKSUMS.tmp; \ fgrep $$luafile < $$CHKSUMS > $$CHKSUMSTMP; \ if [ -z $$CHKSUMSTMP ]; then \ - echo "Cannot check $$luafile - no checksum known"; \ + echo "Cannot check $$luafile - no checksum known"; \ + echo "Rerun with 'NOCHKSUM=1' to skip this check"; \ + exit 1; \ else \ - echo Checking integrity of $$luafile with $$shac; \ - $$shac -w --ignore-missing -c $$CHKSUMSTMP < $$luafile; \ + echo "Checksum found"; \ + chksum_or_fail $$luafile; \ fi; \ - fi; \ - tar zxf $$luafile && \ - rm -f $$luafile; \ - fi; \ + fi; \ + `: If we can unpack it, we are done.`; \ + untar_and_cleanup $$luafile && exit 0; \ + `: fallthrough to next source `; \ fi; \ - done; \ - true ) - + done; \ + echo "Unable to find a valid source - STOPPING" \ + exit 1; \ + ) # remove include/nhlua.h in case it was created for some other Lua version @( if test -f include/nhlua.h ; then \ - rm -f include/nhlua.h && echo 'rm include/nhlua.h' ; fi ) + rm -f include/nhlua.h && echo 'rm include/nhlua.h' ; fi ) fetch-lua-http: ( mkdir -p lib && cd lib && \ - curl -R -O http://$(LUA_URL)/lua-$(LUA_VERSION).tar.gz && \ + $(CURL) -R -O http://$(LUA_URL)/lua-$(LUA_VERSION).tar.gz && \ tar zxf lua-$(LUA_VERSION).tar.gz && \ rm -f lua-$(LUA_VERSION).tar.gz ) diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 862a319da..fb8f32c8c 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -1,15 +1,16 @@ # Makefile for NetHack's utility programs. -# NetHack 3.7 Makefile.utl $NHDT-Date: 1693334279 2023/08/29 18:37:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.68 $ +# NetHack 5.0 Makefile.utl $NHDT-Date: 1693334279 2023/08/29 18:37:59 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.68 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # -# Note: as of nethack 3.7, 'lev_comp' and 'dgn_comp' are no longer present +# Note: as of NetHack 5.0, 'lev_comp' and 'dgn_comp' are no longer present # so use of yacc and lex to build them is no longer required. # # Root of source tree: NHSROOT=.. +SRCDIR = $(NHSROOT)/src # newer makes predefine $(MAKE) to 'make' and do smarter processing of # recursive make calls if $(MAKE) is used @@ -23,7 +24,7 @@ NHSROOT=.. # execute things like 'foo.o') # MAKE = make -# NetHack 3.7 began introducing C99 code. +# NetHack 5.0 began introducing C99 code. # # If your compiler needs an appropriate switch to accept C99 code. # CSTD = -std=c99 @@ -88,7 +89,7 @@ NHSROOT=.. # flags for Linux # compile normally # CFLAGS = -O2 -fomit-frame-pointer -I../include -# LFLAGS = -L/usr/X11R6/lib +# LFLAGS = -L/usr/lib64 # OR compile backwards compatible a.out format # CFLAGS = -O2 -b i486-linuxaout -fomit-frame-pointer -I../include # LFLAGS = -b i486-linuxaout -L/usr/X11R6/lib @@ -143,6 +144,8 @@ QUIETCC=0 CLINK=$(CC) CXXLINK=$(CXX) +CCRESP=$(CC_RESPONSEFILE) + # ---------------------------------------- # # Nothing below this line should have to be changed. @@ -222,18 +225,18 @@ DLBOBJS = dlb_main.o $(OBJDIR)/dlb.o $(OALLOC) # files or on the command line. TARGETPFX= -TARGET_CC = $(CC) -TARGET_CFLAGS = $(CFLAGS) $(CSTD) -TARGET_CLINK = $(CLINK) -TARGET_LFLAGS = $(LFLAGS) -TARGET_CXX = $(CXX) -TARGET_CXXFLAGS = $(CXXFLAGS) -TARGET_AR = $(AR) +TARGET_CC ?= $(CC) +TARGET_CFLAGS ?= $(CFLAGS) $(CSTD) +TARGET_CLINK ?= $(CLINK) +TARGET_LFLAGS ?= $(LFLAGS) +TARGET_CXX ?= $(CXX) +TARGET_CXXFLAGS ?= $(CXXFLAGS) +TARGET_AR ?= $(AR) # # dependencies for makedefs # -makedefs: $(HACKLIB) $(MAKEOBJS) mdgrep.h +makedefs: $(CCRESP) $(HACKLIB) $(MAKEOBJS) mdgrep.h $(CLINK) $(LFLAGS) -o makedefs $(MAKEOBJS) $(HACKLIB) @@ -275,9 +278,11 @@ $(HACKLIB): $(CONFIG_H) $(HACKLIBSRC) panic.o @( cd ../src ; $(MAKE) hacklib.a ) # support code used by several of the utility programs (but not makedefs) -panic.o: panic.c $(CONFIG_H) +panic.o: $(CCRESP) panic.c $(CONFIG_H) $(CC) $(CFLAGS) $(CSTD) -c panic.c -o $@ +../src/nethack_cc.rsp: + ( cd ../src; $(MAKE) ../src/nethack_cc.rsp ) # with all of extern.h's functions to complain about, we drown in # 'defined but not used' without -u @@ -288,7 +293,7 @@ lintdgn: # dependencies for recover # -recover: $(RECOVOBJS) $(HACKLIB) +recover: $(CCRESP) $(RECOVOBJS) $(HACKLIB) $(CLINK) $(LFLAGS) -o recover \ $(RECOVOBJS) $(HACKLIB) $(LIBS) @@ -324,7 +329,7 @@ SFCTOOLBIN = sfctool SFFLAGS=-DSFCTOOL -DNOPANICTRACE -DNOCRASHREPORT -DNO_CHRONICLE sfutil: $(SFCTOOLBIN) @echo '$(SFCTOOLBIN) is up to date.' -$(SFCTOOLBIN): $(SFCTOOLOBJS) $(HACKLIB) +$(SFCTOOLBIN): $(CCRESP) $(SFCTOOLOBJS) $(HACKLIB) $(TARGET_CLINK) $(TARGET_LFLAGS) -o $@ $(SFCTOOLOBJS) $(HACKLIB) $(TARGET_LIBS) $(TARGETPFX)sfctool.o: sfctool.c $(HACK_H) ../include/sfprocs.h $(TARGET_CC) $(TARGET_CFLAGS) $(SFFLAGS) -o $@ -c sfctool.c @@ -398,7 +403,7 @@ sftags: sftags.o $(HACKLIB) $(TARGETPFX)sf-alloc.o $(TARGETPFX)panic.o $(CLINK) $(LFLAGS) -o $@ sftags.o \ $(TARGETPFX)sf-alloc.o $(TARGETPFX)panic.o \ $(HACKLIB) $(LIBS) -sftags.o: sftags.c $(HACK_H) +sftags.o: $(CCRESP) sftags.c $(HACK_H) $(CC) $(CFLAGS) -c sftags.c ../include/sfproto.h: sf.tags sftags ./sftags @@ -467,13 +472,13 @@ sf.tags: $(CTAGDEP) dlb: $(DLBOBJS) $(HACKLIB) $(CLINK) $(LFLAGS) -o dlb $(DLBOBJS) $(HACKLIB) $(LIBS) -dlb_main.o: dlb_main.c $(CONFIG_H) ../include/dlb.h +dlb_main.o: $(CCRESP) dlb_main.c $(CONFIG_H) ../include/dlb.h $(CC) $(CFLAGS) $(CSTD) -c dlb_main.c -o $@ stripbs: stripbs.o $(CC) $(LFLAGS) -o stripbs stripbs.o -stripbs.o: stripbs.c +stripbs.o: $(CCRESP) stripbs.c $(CC) $(CFLAGS) -c stripbs.c # dependencies for tile utilities @@ -520,38 +525,38 @@ tilemap: tilemap.o $(OBJDIR)/objects.o $(OBJDIR)/monst.o $(OBJDIR)/drawing.o \ ../src/tile.c: tilemap ./tilemap -tiletext.o: ../win/share/tiletext.c $(CONFIG_H) ../win/share/tile.h - $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/tiletext.c -o $@ -tiletxt.o: ../win/share/tiletxt.c ../win/share/tilemap.c $(HACK_H) +tiletext.o: $(CCRESP) ../win/share/tiletext.c $(CONFIG_H) ../win/share/tile.h + $(CC) $(CFLAGS) $(NO_WARN_DISCARDED_QUALIFIERS) $(CSTD) -I../win/share -c ../win/share/tiletext.c -o $@ +tiletxt.o: $(CCRESP) ../win/share/tiletxt.c ../win/share/tilemap.c $(HACK_H) $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/tiletxt.c -o $@ -tilemap.o: ../win/share/tilemap.c $(HACK_H) +tilemap.o: $(CCRESP) ../win/share/tilemap.c $(HACK_H) $(CC) $(CFLAGS) $(CSTD) -c ../win/share/tilemap.c -o $@ -gifread.o: ../win/share/gifread.c $(CONFIG_H) ../win/share/tile.h +gifread.o: $(CCRESP) ../win/share/gifread.c $(CONFIG_H) ../win/share/tile.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/gifread.c -o $@ -ppmwrite.o: ../win/share/ppmwrite.c $(CONFIG_H) ../win/share/tile.h +ppmwrite.o: $(CCRESP) ../win/share/ppmwrite.c $(CONFIG_H) ../win/share/tile.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/ppmwrite.c -o $@ -tile2bmp.o: ../win/share/tile2bmp.c $(HACK_H) ../win/share/tile.h +tile2bmp.o: $(CCRESP) ../win/share/tile2bmp.c $(HACK_H) ../win/share/tile.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/share/tile2bmp.c -o $@ -tile2x11.o: ../win/X11/tile2x11.c $(HACK_H) ../win/share/tile.h \ +tile2x11.o: $(CCRESP) ../win/X11/tile2x11.c $(HACK_H) ../win/share/tile.h \ ../include/tile2x11.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/X11/tile2x11.c -o $@ -tile2img.o: ../win/gem/tile2img.c $(HACK_H) ../win/share/tile.h \ +tile2img.o: $(CCRESP) ../win/gem/tile2img.c $(HACK_H) ../win/share/tile.h \ ../include/bitmfile.h $(CC) $(CFLAGS) $(CSTD) -I../win/share -c ../win/gem/tile2img.c -o $@ -xpm2img.o: ../win/gem/xpm2img.c $(HACK_H) ../include/bitmfile.h +xpm2img.o: $(CCRESP) ../win/gem/xpm2img.c $(HACK_H) ../include/bitmfile.h $(CC) $(CFLAGS) $(CSTD) -c ../win/gem/xpm2img.c -o $@ -bitmfile.o: ../win/gem/bitmfile.c ../include/bitmfile.h +bitmfile.o: $(CCRESP) ../win/gem/bitmfile.c ../include/bitmfile.h $(CC) $(CFLAGS) $(CSTD) -c ../win/gem/bitmfile.c -o $@ -tile2beos.o: ../win/BeOS/tile2beos.cpp $(HACK_H) ../win/share/tile.h +tile2beos.o: $(CCRESP) ../win/BeOS/tile2beos.cpp $(HACK_H) ../win/share/tile.h $(CXX) $(CFLAGS) $(CSTD) -I../win/share -c ../win/BeOS/tile2beos.cpp -o $@ # note: tileedit.cpp was developed for Qt2 and will not compile using Qt5 -tileedit.o: ../win/Qt/tileedit.cpp +tileedit.o: $(CCRESP) ../win/Qt/tileedit.cpp $(CXX) -I../include -I$(QTDIR)/include ../win/Qt/tileedit.cpp tileedit: tileedit.o $(TEXT_IO) $(QTDIR)/bin/moc -o tileedit.moc tileedit.h @@ -559,7 +564,7 @@ tileedit: tileedit.o $(TEXT_IO) uudecode: uudecode.o $(CLINK) $(LFLAGS) -o uudecode uudecode.o $(LIBS) -uudecode.o: ../sys/share/uudecode.c +uudecode.o: $(CCRESP) ../sys/share/uudecode.c $(CC) $(CFLAGS) $(CSTD) -c -o uudecode.o ../sys/share/uudecode.c # using dependencies like @@ -576,27 +581,27 @@ uudecode.o: ../sys/share/uudecode.c # make sure host object files from src are available when needed # (note: these dependencies have been copied from Makefile.src so only come # indirectly from 'make depend', hence are subject to bit rot as src changes) -$(OBJDIR)/alloc.o: ../src/alloc.c $(CONFIG_H) ../include/nhlua.h +$(OBJDIR)/alloc.o: $(CCRESP) ../src/alloc.c $(CONFIG_H) ../include/nhlua.h $(CC) $(CFLAGS) $(CSTD) -c ../src/alloc.c -o $@ -$(OBJDIR)/drawing.o: ../src/drawing.c $(CONFIG_H) ../include/color.h \ +$(OBJDIR)/drawing.o: $(CCRESP) ../src/drawing.c $(CONFIG_H) ../include/color.h \ ../include/rm.h ../include/objclass.h ../include/defsym.h \ ../include/objects.h ../include/sym.h $(CC) $(CFLAGS) $(CSTD) -c ../src/drawing.c -o $@ -$(OBJDIR)/decl.o: ../src/decl.c $(HACK_H) +$(OBJDIR)/decl.o: $(CCRESP) ../src/decl.c $(HACK_H) $(CC) $(CFLAGS) $(CSTD) -c ../src/decl.c -o $@ -$(OBJDIR)/monst.o: ../src/monst.c $(CONFIG_H) ../include/permonst.h \ +$(OBJDIR)/monst.o: $(CCRESP) ../src/monst.c $(CONFIG_H) ../include/permonst.h \ ../include/align.h ../include/monattk.h ../include/monflag.h \ ../include/monsters.h ../include/wintype.h ../include/sym.h \ ../include/defsym.h ../include/color.h $(CC) $(CFLAGS) $(CSTD) -c ../src/monst.c -o $@ -$(OBJDIR)/objects.o: ../src/objects.c $(CONFIG_H) ../include/obj.h \ +$(OBJDIR)/objects.o: $(CCRESP) ../src/objects.c $(CONFIG_H) ../include/obj.h \ ../include/prop.h ../include/skills.h ../include/color.h \ ../include/objclass.h ../include/defsym.h ../include/objects.h $(CC) $(CFLAGS) $(CSTD) -c ../src/objects.c -o $@ -$(OBJDIR)/dlb.o: ../src/dlb.c $(CONFIG_H) ../include/dlb.h +$(OBJDIR)/dlb.o: $(CCRESP) ../src/dlb.c $(CONFIG_H) ../include/dlb.h $(CC) $(CFLAGS) $(CSTD) -c ../src/dlb.c -o $@ # this differs substantially from what Makefile.src specifies -$(OBJDIR)/date.o: ../src/date.c $(CONFIG_H) +$(OBJDIR)/date.o: $(CCRESP) ../src/date.c $(CONFIG_H) $(CC) $(CFLAGS) $(CSTD) -c ../src/date.c -o $@ ../include/nhlua.h: @( cd .. ; $(MAKE) lua_support ) @@ -612,10 +617,10 @@ tags: $(UTILSRCS) @ctags -tw $(UTILSRCS) # note: 3.6 copied tile.h from win/share/ to include/ and if someone -# switches branches from 3.6 to 3.7 without executing 'make spotless' +# switches branches from 3.6 to 5.0 without executing 'make spotless' # first, the old tile.h sticks around and gets found during compile # instead of current one; various tile utilities won't build in that -# mis-configuration so allow 'make clean' and 'make spotless' in 3.7 +# mis-configuration so allow 'make clean' and 'make spotless' in 5.0 # to fix things up by deleting the out of date file (if present) clean-fixup: -rm -f ../include/tile.h diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index e379e51f8..21666b10e 100644 --- a/sys/unix/NetHack.xcodeproj/project.pbxproj +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj @@ -209,6 +209,7 @@ F5857AA22DED026700A8CB4F /* version.c in Sources */ = {isa = PBXBuildFile; fileRef = 31B8A32721A238010055BD01 /* version.c */; }; F5857AA42DED032D00A8CB4F /* cfgfiles.c in Sources */ = {isa = PBXBuildFile; fileRef = F5857AA32DED032C00A8CB4F /* cfgfiles.c */; }; F5857AA62DED03BB00A8CB4F /* sfbase.c in Sources */ = {isa = PBXBuildFile; fileRef = F5857AA52DED03BB00A8CB4F /* sfbase.c */; }; + F5E1A4CF2FA2F74C0014D115 /* macuuid.m in Sources */ = {isa = PBXBuildFile; fileRef = F5E1A4CE2FA2F74C0014D115 /* macuuid.m */; }; F5E66A222F7D4B30000E30B7 /* earlyarg.c in Sources */ = {isa = PBXBuildFile; fileRef = F5E66A212F7D4B30000E30B7 /* earlyarg.c */; }; /* End PBXBuildFile section */ @@ -635,6 +636,7 @@ F54C1AE42E43D22A006CAA8E /* sfprocs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sfprocs.h; path = ../../include/include/sfprocs.h; sourceTree = ""; }; F5857AA32DED032C00A8CB4F /* cfgfiles.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cfgfiles.c; path = ../../src/cfgfiles.c; sourceTree = ""; }; F5857AA52DED03BB00A8CB4F /* sfbase.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = sfbase.c; path = ../../src/sfbase.c; sourceTree = ""; }; + F5E1A4CE2FA2F74C0014D115 /* macuuid.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = macuuid.m; sourceTree = ""; }; F5E66A212F7D4B30000E30B7 /* earlyarg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = earlyarg.c; path = ../../src/earlyarg.c; sourceTree = ""; }; /* End PBXFileReference section */ @@ -695,6 +697,7 @@ 3189576821A1FCC100FB2ABE = { isa = PBXGroup; children = ( + F5E1A4CE2FA2F74C0014D115 /* macuuid.m */, F5E66A212F7D4B30000E30B7 /* earlyarg.c */, F50818302F6F564300D2AAFA /* iactions.c */, F515A73B2DED0B47006E1F63 /* hacklib.c */, @@ -1883,6 +1886,7 @@ 31B8A38621A238060055BD01 /* mondata.c in Sources */, 31B8A41921A244940055BD01 /* objects.c in Sources */, 31B8A3AA21A238060055BD01 /* wizard.c in Sources */, + F5E1A4CF2FA2F74C0014D115 /* macuuid.m in Sources */, 31B8A3D021A238060055BD01 /* explode.c in Sources */, 31B8A3DE21A238060055BD01 /* sys.c in Sources */, 31B8A38021A238060055BD01 /* sit.c in Sources */, @@ -2190,6 +2194,7 @@ "DEBUG=1", "$(inherited)", ); + "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "NHUUID=1"; GCC_WARN_64_TO_32_BIT_CONVERSION = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_PEDANTIC = YES; @@ -2214,7 +2219,6 @@ ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2296,7 +2300,6 @@ NH_UTIL_DIR = "$(NH_ROOT_DIR)/util"; OTHER_CFLAGS = ( "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2318,12 +2321,15 @@ DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5J8MP36Y73; GCC_C_LANGUAGE_STANDARD = c99; + "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = ( + "DEBUG=1", + "$(inherited)", + ); INSTALL_PATH = "$(NH_INSTALL_DIR)"; MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; OTHER_CFLAGS = ( "-Wno-ambiguous-macro", "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2351,12 +2357,12 @@ DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 5J8MP36Y73; GCC_C_LANGUAGE_STANDARD = c99; + "GCC_PREPROCESSOR_DEFINITIONS[arch=*]" = "NHUUID=1"; INSTALL_PATH = "$(NH_INSTALL_DIR)"; MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; OTHER_CFLAGS = ( "-Wno-ambiguous-macro", "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2405,7 +2411,6 @@ OTHER_CFLAGS = ( "-DMINIMAL_FOR_RECOVER", "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2432,7 +2437,6 @@ OTHER_CFLAGS = ( "-DMINIMAL_FOR_RECOVER", "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2488,7 +2492,6 @@ MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; OTHER_CFLAGS = ( "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", @@ -2525,7 +2528,6 @@ MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; OTHER_CFLAGS = ( "-DNOMAIL", - "-DNOTPARMDECL", "-DDEFAULT_WINDOW_SYS=\\\"tty\\\"", "-DDLB", "-DGREPPATH=\\\"/usr/bin/grep\\\"", diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index 831b1b870..e6b276e91 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -1,5 +1,5 @@ - Instructions for installing NetHack 3.7 + Instructions for installing NetHack 5.0 using the new hints system ======================================= @@ -83,78 +83,82 @@ Note that curses, X11, and Qt will almost certainly require the installation of prerequisite packages in order to successfully build with support for additional interfaces. See below. -+----------+-------+-----------------+--------------------------------------+ -| Platform |Interf.| Build Variable | Prerequisite package | -|----------+-------+-----------------+--------------------------------------| -| MacOS | tty | WANT_WIN_TTY | none | -|----------+-------+-----------------+--------------------------------------| -| MacOS | curses| WANT_WIN_CURSES | ncurses development libraries | -|----------+-------+-----------------+--------------------------------------| -| MacOS | X11 | WANT_WIN_X11 | You will need to obtain and | -| | | | install XQuartz if you want X11 | -| | | | support in your build. | -| | | | (Attempting to run X11.app will | -| | | | describe where to get it) | -| | | | | -| | | | One possible way: | -| | | | brew install xquartz | -|----------+-------+-----------------+--------------------------------------| -| MacOS | Qt | WANT_WIN_QT | You will need to obtain and | -| | | | install Qt if you want Qt | -| | | | support in your build. | -| | | | | -| | | | One possible way: | -| | | | brew install pkg-config | -| | | | brew install Qt6 | -|----------+-------+-----------------+--------------------------------------| -| Linux | tty | WANT_WIN_TTY | | -| (Ubuntu) | | | | -|----------+-------+-----------------+--------------------------------------| -| Linux | curses|WANT_WIN_CURSES=1| If it isn't already included | -| (Ubuntu) | | | in your distribution, here is one | -| | | | possible way: | -| | | | | -| | | | sudo apt-get install libncurses-dev | -|----------+-------+-----------------+--------------------------------------| -| Linux | X11 | WANT_WIN_X11=1 | Here is one possible way to obtain | -| (Ubuntu) | | | the required packages: | -| | | | | -| | | |sudo apt-get install libx11-dev | -| | | |sudo apt-get install libmotif-dev | -| | | |sudo apt-get install libxaw7-dev | -| | | |sudo apt install xfonts-utils | -| | | |(That last one is for bdftopcf and | -| | | | mkfontdir utils) | -| | | | | -|----------+-------+-----------------+--------------------------------------| -| Linux | Qt5 | WANT_WIN_QT=1 | Here is one possible way to obtain | -| (Ubuntu) | | | the required packages: | -| | | | | -| | | |sudo apt-get install qtbase5-dev | -| | | |sudo apt-get install qtmultimedia5-dev| -| | | | | -| | | |Another odd note about Qt on Linux is | -| | | |that if you find you are getting the | -| | | |following error trying to run NetHack | -| | | |after you build it with Qt support: | -| | | |"error while loading shared | -| | | |libraries: libQt5Core.so.5: cannot | -| | | |open shared object file: No such file | -| | | |or directory", | -| | | |you may have to fix that (one-time) | -| | | |by issuing the command below: | -| | | | | -| sudo strip \ | -| --remove-section=.note.ABI-tag/usr/lib/x86_64-linux-gnu/libQt5Core.so.5 | -|----------+-------+-----------------+--------------------------------------| -| Linux | Qt6 | WANT_WIN_QT6=1 | Here is one possible way to obtain | -| (Ubuntu) | | | the required packages: | -| | | | | -| | | |sudo apt-get install qt6-base-dev | -| | | |sudo apt-get install \ | -| | | | qt6-multimedia-dev | -+----------+-------+-----------------+--------------------------------------+ ++----------+-------+------------------+-------------------------------------+ +| Platform |Interf.| make variable | Prerequisite package | +|----------+-------+------------------+-------------------------------------| +| MacOS | tty | WANT_WIN_TTY=1 | none | +|----------+-------+------------------+-------------------------------------| +| MacOS | curses| WANT_WIN_CURSES=1| ncurses development libraries | +|----------+-------+------------------+-------------------------------------| +| MacOS | X11 | WANT_WIN_X11=1 | You will need to obtain and | +| | | | install XQuartz if you want X11 | +| | | | support in your build. | +| | | | (Attempting to run X11.app will | +| | | | describe where to get it) | +| | | | | +| | | | One possible way: | +| | | | brew install xquartz | +| | | | brew install libxft | +| | | | brew install fontconfig | +| | | | brew install freetype | +|----------+-------+------------------+-------------------------------------| +| MacOS | Qt | WANT_WIN_QT=1 | You will need to obtain and | +| | | | install Qt if you want Qt | +| | | | support in your build. | +| | | | | +| | | | One possible way: | +| | | | brew install pkg-config | +| | | | brew install Qt6 | +|----------+-------+------------------+-------------------------------------| +| Linux | tty | WANT_WIN_TTY=1 | sudo apt install libncurses-dev | +| (Ubuntu) | | | | +|----------+-------+------------------+-------------------------------------| +| Linux | tty | WANT_WIN_TTY=1 | sudo dnf install make gcc g++ | +| (Fedora) | | | sudo dnf install ncurses-devel | +|----------+-------+------------------+-------------------------------------| +| Linux | curses|WANT_WIN_CURSES=1 | If it isn't already included | +| (Ubuntu) | | | in your distribution, here is one | +| | | | possible way: | +| | | | | +| | | | sudo apt install libncurses-dev | +|----------+-------+------------------+-------------------------------------| +| Linux | X11 | WANT_WIN_X11=1 | Here is one possible way to obtain | +| (Ubuntu) | | | the required packages: | +| | | | | +| | | | sudo apt install libx11-dev | +| | | | sudo apt install libmotif-dev | +| | | | sudo apt install libxaw7-dev | +| | | | sudo apt install xfonts-utils | +| | | | (That last one is for bdftopcf | +| | | | and mkfontdir utils) | +| | | | | +|----------+-------+------------------+-------------------------------------| +| Linux | X11 | WANT_WIN_X11=1 | Here is a possible way to obtain | +|(Fedora) | | | all prerequisite packages required | +| | | | (in addition to those needed for | +| | | | tty above) on a fresh installation | +| | | | of Fedora 44 workstation: | +| | | | | +| | | | sudo dnf install libX11-devel | +| | | | sudo dnf install libXt-devel | +| | | | sudo dnf install libXaw | +| | | | sudo dnf install libXaw-devel | +| | | | sudo dnf install libXft-devel | +| | | | sudo dnf install xorg-x11-font-utils| +| | | | sudo dnf install mkfontscale | +| | | | | +|----------+-------+------------------+-------------------------------------| +| Linux | Qt | WANT_WIN_QT6=1 | Here is one possible way to obtain | +| (Ubuntu) | | | the required packages: | +| | | | | +| | | |sudo apt install qt6-base-dev | +| | | |sudo apt install qt6-multimedia-dev | ++----------+-------+------------------+-------------------------------------+ -# NetHack 3.7 NewInstall.unx $NHDT-Date: 1652276817 2022/05/11 13:46:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +There are other hints file options that are meant to impact your NetHack build +in various other ways too. A reference list can be found in +sys/unix/README.hints. + +# NetHack 5.0 NewInstall.unx $NHDT-Date: 1652276817 2022/05/11 13:46:57 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/README-hints b/sys/unix/README.hints similarity index 75% rename from sys/unix/README-hints rename to sys/unix/README.hints index 03c3fd893..7856a1561 100644 --- a/sys/unix/README-hints +++ b/sys/unix/README.hints @@ -5,18 +5,18 @@ The sys/unix/hints/include subfolder contains Makefile content that is included in the distributed Makefiles. -[.370 hints] +[.500 hints] -There are two .370 series hints files provided with NetHack: - linux.370 for use on Linux - macOS.370 for use on macOS +There are two .500 series hints files provided with NetHack: + linux.500 for use on Linux + macOS.500 for use on macOS -Those will also pull in content from sys/unix/hints/include/*.370, -that is shared between the linux.370 and macOS.370 hints files. +Those will also pull in content from sys/unix/hints/include/*.500, +that is shared between the linux.500 and macOS.500 hints files. -[.370 make build options] +[.500 make build options] Here are some options that can be specified on the make command @@ -49,6 +49,8 @@ make musl=1 Build with settings appropriate for linking with musl libc, instead of glibc. This causes NOCRASHREPORT to be defined, and avoids the use of 'col' during the build. +make WANT_SYSTEM_LUA=1 Attempt to use an existing Lua package already + on the system (initially for Alpine Linux). make resp=1 Place the majority of the compiler switches into a response file to de-clutter the build compiler command lines and eliminate some of the @@ -57,9 +59,9 @@ make CROSS_TO_MSDOS=1 package Cross-compile for an MSDOS target package. make CROSS_TO_WASM=1 Cross-compile for a WASM target. make CROSS_TO_MIPS=1 Cross-compile for a mips target. -make WANT_BUNDLE=1 For macOS.370 only, place the build results into +make WANT_BUNDLE=1 For macOS.500 only, place the build results into a macOS bundle layout. -make WANT_MACSOUND=1 For macOS.370, include support for built-in macOS +make WANT_MACSOUND=1 For macOS.500, include support for built-in macOS sound libraries. make WANT_SPEECH=1 If one of the sound libraries was included, also include speech synthesis support (Recent macOS @@ -71,13 +73,23 @@ make WANT_ASAN=1 Include support for the address sanitizer in the make WANT_UBSAN=1 Include support for the undefined behaviour sanitizer in the build. -make WANT_SHARE_INSTALL=1 Place the results of the install/update portion +make WANT_SHARED_INSTALL=1 Place the results of the install/update portion of the build into a shared area on a multiuser system. - + make WANT_SOURCE_INSTALL=1 Place the results of the install/update portion of the build into a subfolder of the source tree, rather than in a system-wide shared area. + (This is now the default if WANT_SHARED_INSTALL=1 + wasn't specified) + +make WANT_NHUUID=1 Include support for a unique game identifier. + On Linux, libuuid and its headers must be installed + and available for this to build and link correctly. + sudo apt install uuid-dev on Debian/Ubuntu + or + sudo dnf install libuuid-devel on Fedora + make VIEWDEPRECATIONS=1 Turn off the suppression of -Wdeprecated and -Wdeprecated-declarations warnings diff --git a/sys/unix/depend.awk b/sys/unix/depend.awk index afe86a0ad..edb8fb4e7 100644 --- a/sys/unix/depend.awk +++ b/sys/unix/depend.awk @@ -1,6 +1,6 @@ # depend.awk -- awk script used to construct makefile dependencies # for nethack's source files (`make depend' support for Makefile.src). -# $NHDT-Date: 1709577497 2024/03/04 18:38:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ +# $NHDT-Date: 1709577497 2024/03/04 18:38:17 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ # # usage: # awk -f depend.awk ../include/*.h list-of-.c/.cpp-files @@ -54,7 +54,7 @@ FNR == 1 { output_dep() #finish previous file #[3.4.0: gnomehack headers currently aren't in include] #[3.6.2: Qt4 headers aren't in include either] #[3.6.2: curses headers likewise] - #[3.7.0: Qt headers have moved; process 'moc' files] + #[NetHack 5.0.0: Qt headers have moved; process 'moc' files] if (incl ~ /[.]h$/) { if (incl ~ "curses[.]h") incl = "" # skip "curses.h"; it should be diff --git a/sys/unix/gitinfo.sh b/sys/unix/gitinfo.sh index d087272a2..817a7f310 100755 --- a/sys/unix/gitinfo.sh +++ b/sys/unix/gitinfo.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 gitinfo.sh $NHDT-Date: 1596498289 2020/08/03 23:44:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ +# NetHack 5.0 gitinfo.sh $NHDT-Date: 1596498289 2020/08/03 23:44:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.3 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/hints/bsd.500 b/sys/unix/hints/bsd.500 new file mode 100644 index 000000000..14187680a --- /dev/null +++ b/sys/unix/hints/bsd.500 @@ -0,0 +1,87 @@ +# +# NetHack 5.0 unix $NHDT-Date: 1778708083 2026/05/13 21:34:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ +# Copyright 2026 by Anthony C Howe. +# NetHack may be freely redistributed. See license for details. +# +# This is a contributed file. The NetHack Development Team makes this +# file available so that others may benefit, but may not be able to +# support or maintain it. Use at your own risk. +# +#-PRE +# unix hints file +# This hints file provides the legacy configuration that NetHack has shipped +# with historically - this means you will most likely need to hand edit .h +# and Makefiles. +# +# note: '#-INCLUDE' is not just a comment. setup.sh inserts the contents of +# a file found in sys/unix/hints/include +#-INCLUDE whichbsd.500 + +PREFIX=/usr/local + +# Binaries and supporting data. +HACKDIR=$(PREFIX)/libexec/nethackdir + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# Careful, this directory is deleted on install. +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +INSTDIR=$(HACKDIR) + +# Save games +VARDIR=/var/games/nethackdir + +# Home for nethask.sh wrapper. If undefined, no wrapper installed. +# Suggest leaving /usr/games as-is from bsdgames.tgz. +SHELLDIR=$(PREFIX)/bin + +CFLAGS=-O -I../include -USYSV -DBSD -DHACKDIR='"$(HACKDIR)"' -DVAR_PLAYGROUND='"$(VARDIR)"' +LINK=$(CC) + +WINSRC = $(WINTTYSRC) +WINOBJ = $(WINTTYOBJ) +WINLIB = $(WINTTYLIB) + +WINTTYLIB=-ltermcap + +CHOWN=chown +CHGRP=chgrp + +GAMEUID = games +GAMEGRP = games + +GAMEPERM = 04755 +VARFILEPERM = 0644 +VARDIRPERM = 0755 + +.ifdef MAKEFILE_DOC +MAKEDEFS = ../util/makedefs +NEEDMAKEDEFS = $(MAKEDEFS) + +.if ${WHICHBSD} == "NETBSD" +.if exists (/usr/pkg/bin/groff) +NROFF = /usr/pkg/bin/groff +.else +NROFF = groff +.endif # ? Is NROFF groff or /usr/pkg/bin/groff +.else # WHICHBSD is not NETBSD +NROFF = groff +.endif # WHICHBSD + +# NROFF_FLAGS comes from a hints file +GUIDEBOOK = Guidebook # regular ASCII file +COLCMD = col -bx +PSCMD = $(NROFF) +NHGREP = $(MAKEDEFS) --grep --input - --output - +GUIDEBOOK_MN_SRC = Guidebook.mn +GUIDEBOOK_MN = $(GUIDEBOOK_MN_SRC) +GUIDE_PREFORMAT = cat $(GUIDEBOOK_MN) | $(NHGREP) | tbl tmac.n - +ONEPAGE_PREFORMAT = cat Gbk-1pg-pfx.mn $(GUIDEBOOK_MN) Gbk-1pg-sfx.mn \ + | $(NHGREP) | tbl tmac.n - +ONEPAGECMD = $(ONEPAGE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) \ + | $(COLCMD) +GUIDECMD = export GROFF_NO_SGR=1; \ + $(GUIDE_PREFORMAT) | $(NROFF) -c -Tascii $(NROFF_FLAGS) \ + | $(COLCMD) +GUIDEBOOK_TEX_SRC = Guidebook.tex +GUIDEBOOK_TEX = $(GUIDEBOOK_TEX_SRC) +.endif # MAKEFILE_DOC diff --git a/sys/unix/hints/include/compiler.370 b/sys/unix/hints/include/compiler.500 similarity index 91% rename from sys/unix/hints/include/compiler.370 rename to sys/unix/hints/include/compiler.500 index 70f9eadeb..e0f5eb466 100755 --- a/sys/unix/hints/include/compiler.370 +++ b/sys/unix/hints/include/compiler.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 compiler.370 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 compiler.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-5.0 $ # compiler flags: CCFLAGS is used to construct a value for CFLAGS with # various -I, -D, and -W settings appended below; @@ -49,7 +49,7 @@ endif #CC= clang #CXX=clang++ -std=gnu++11 -CFLAGS=$(CCFLAGS) -I../include -DNOTPARMDECL +CFLAGS=$(CCFLAGS) -I../include CFLAGS+=-Wall -Wextra \ -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings CFLAGS+=-pedantic @@ -89,7 +89,7 @@ CXX=g++ -std=gnu++11 GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9) GCCGTEQ11 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 11) GCCGTEQ12 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 12) -GCCGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14) +GCCGTEQ16 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 16) ifeq "$(GCCGTEQ9)" "1" # flags present in gcc version greater than or equal to 9 can go here CFLAGS+=-Wformat-overflow @@ -100,7 +100,8 @@ CFLAGS+=-Wimplicit-fallthrough #endif #ifeq "$(GCCGTEQ12)" "1" #endif -#ifeq "$(GCCGTEQ14)" "1" +#ifeq "$(GCCGTEQ16)" "1" +NO_WARN_DISCARDED_QUALIFIERS=-Wno-discarded-qualifiers #endif # end of gcc-specific else # gcc or clang? @@ -109,6 +110,7 @@ CXX=clang++ -std=gnu++11 CLANGGTEQ12 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 12) CLANGGTEQ14 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 14) CLANGGTEQ21 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 21) +CLANGGTEQ22 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 22) ifeq "$(CLANGGTEQ12)" "1" CFLAGS+=-Wimplicit-fallthrough endif @@ -123,12 +125,15 @@ endif ifeq "$(CLANGGTEQ21)" "1" CFLAGS+=-Wno-deprecated-octal-literals endif +ifeq "$(CLANGGTEQ22)" "1" +NO_WARN_DISCARDED_QUALIFIERS=-Wno-incompatible-pointer-types-discards-qualifiers +endif # none endif # clang-specific ends here ifdef MAKEFILE_SRC ifdef CPLUSPLUS_NEEDED -CCXXFLAGS = -g -I../include -DNOTPARMDECL +CCXXFLAGS = -g -I../include CCXXFLAGS+=-Wall -Wextra -Wno-missing-field-initializers \ -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings CCXXFLAGS+=-pedantic @@ -171,6 +176,9 @@ else # g++ version greater than or equal to 9? (no follows) CCXX=g++ -std=c++17 endif # g++ version greater than or equal to 9 endif # CPLUSPLUS_NEED20 +ifdef ADDITIONAL_NO_WARN_GPPCCX +CCXXFLAGS+=$(ADDITIONAL_NO_WARN_GPPCCX) +endif else # g++ or clang++ ? @@ -211,6 +219,9 @@ ifeq "$(CLANGPPGTEQ17)" "1" CCXX=clang++ -std=c++20 endif # clang++ greater than or equal to 17 endif # CPLUSPLUS_NEED20 +ifdef ADDITIONAL_NO_WARN_CLANGCCX +CCXXFLAGS+=$(ADDITIONAL_NO_WARN_CLANGCCX) +endif endif # end of clang++-specific section CXX=$(CCXX) endif # CPLUSPLUS_NEEDED @@ -262,5 +273,5 @@ ifneq "$(HAVECSTD)" "" CSTD = -std=$(HAVECSTD) endif -#end of compiler.370 +#end of compiler.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/cross-post.370 b/sys/unix/hints/include/cross-post.500 similarity index 84% rename from sys/unix/hints/include/cross-post.370 rename to sys/unix/hints/include/cross-post.500 index f28ec0fe1..e0a28eb43 100644 --- a/sys/unix/hints/include/cross-post.370 +++ b/sys/unix/hints/include/cross-post.500 @@ -1,10 +1,14 @@ #===============-================================================= -# NetHack 3.7 include/cross-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 include/cross-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # # Cross-compiling -POST section ifdef CROSS_TO_MSDOS # +.PHONY: tilemap +tilemap: ../util/tilemap.o $(SRCDIR)/objects.o $(SRCDIR)/monst.o $(SRCDIR)/drawing.o $(HACKLIB) +../util/tilemap.o : ../win/share/tilemap.c + (cd ../util ; make tilemap.o ; cd ../src ) $(TARGETPFX)msdos.o : ../sys/msdos/msdos.c $(HACK_H) $(TARGETPFX)font.o : ../sys/msdos/font.c ../sys/msdos/font.h $(HACK_H) $(TARGETPFX)pckeys.o : ../sys/msdos/pckeys.c $(HACK_H) @@ -18,13 +22,15 @@ $(TARGETPFX)vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ ../win/share/tile.h ../include/tileset.h ../sys/msdos/font.h $(HACK_H) $(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) -$(TARGETPFX)tile.o : tile.c +$(TARGETPFX)tile.o : $(SRCDIR)/tile.c + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $(SRCDIR)/tile.c +$(SRCDIR)/tile.c : tilemap $(TARGETPFX)exceptn.o : ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S $(TARGET_CC) -c -o $@ ../lib/djgpp/djgpp-patch/src/libc/go32/exceptn.S $(TARGET_AR) ru ../lib/djgpp/i586-pc-msdosdjgpp/lib/libc.a $(TARGETPFX)exceptn.o $(GAMEBIN) : $(HOBJ) $(TARGETPFX)date.o $(TARGET_HACKLIB) $(LUACROSSLIB) $(TARGET_LINK) $(TARGET_LFLAGS) -o $@ \ - $(HOBJ) $(TARGET_HACKLIB) $(WINLIB) $(TARGET_LIBS) + $(HOBJ) $(DATE_O) $(GENTILEOFILE) $(TARGET_HACKLIB) $(WINLIB) $(TARGET_LIBS) $(DOSFONT)/ter-u16b.psf: $(FONTTOP)/ter-u16b.bdf $(DOSFONT)/nh-u16b.bdf $(DOSFONT)/makefont.lua $(LUABIN) $(LUABIN) $(DOSFONT)/makefont.lua $(FONTTOP)/ter-u16b.bdf $(DOSFONT)/nh-u16b.bdf $@ $(DOSFONT)/ter-u16v.psf: $(FONTTOP)/ter-u16v.bdf $(DOSFONT)/nh-u16v.bdf $(DOSFONT)/makefont.lua $(LUABIN) @@ -44,7 +50,7 @@ $(DOSFONT)/ter-u32b.psf: $(FONTTOP)/ter-u32b.bdf $(DOSFONT)/nh-u32b.bdf $(DOSFON # .PHONY: dodata dospkg dosfonts dosfonts: $(FONTTARGETS) -dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp +dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe $(NHTILES) $(TARGET_STUBEDIT) $(GAMEBIN) minstack=2048K mkdir -p $(TARGETPFX)pkg cp $(GAMEBIN) $(TARGETPFX)pkg/NETHACK.EXE @@ -52,7 +58,7 @@ dospkg: dodata dosfonts $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp -cp $(SFCTOOLBIN) $(TARGETPFX)pkg/SFCTOOL.EXE cp ../dat/nhdat $(TARGETPFX)pkg/NHDAT cp ../dat/license $(TARGETPFX)pkg/LICENSE - cp ../dat/nhtiles.bmp $(TARGETPFX)pkg/NHTILES.BMP + -cp ../dat/nhtiles.bmp $(TARGETPFX)pkg/NHTILES.BMP cp ../dat/symbols $(TARGETPFX)pkg/SYMBOLS cp ../sys/share/NetHack.cnf $(TARGETPFX)pkg/NETHACK.CNF cp ../sys/msdos/sysconf $(TARGETPFX)pkg/SYSCONF @@ -90,8 +96,8 @@ else fi; ) endif -touch $(TARGETPFX)pkg/RECORD - cd $(TARGETPFX)pkg ; zip -9 ../NH370DOS.ZIP * ; cd ../../.. - @echo msdos package zip file $(TARGETPFX)NH370DOS.ZIP + cd $(TARGETPFX)pkg ; zip -9 ../NH$(NHV)DOS.ZIP * ; cd ../../.. + @echo msdos package zip file $(TARGETPFX)NH$(NHV)DOS.ZIP $(LUABIN): ( cd .. && make luabin && cd src) @@ -105,14 +111,14 @@ deploy-to-dosbox: endif .PHONY: deploytodosbox -deploytodosbox: $(TARGETPFX)NH370DOS.ZIP $(dosboxnhfolder) $(dosboxnhsrc) \ +deploytodosbox: $(TARGETPFX)NH$(NHV)DOS.ZIP $(dosboxnhfolder) $(dosboxnhsrc) \ $(dosboxnhsrc)/src $(dosboxnhsrc)/include \ $(dosboxnhsrc)/sys/msdos $(dosboxnhsrc)/sys/share \ $(dosboxnhsrc)/win/share $(dosboxnhsrc)/win/curses \ $(dosboxnhsrc)/win/tty $(dosboxnhsrc)/util \ $(dosboxnhfolder)/NETHACK.EXE @echo DOS NetHack deployed to dosbox at $(dosboxnhfolder) -$(TARGETPFX)NH370DOS.ZIP: dospkg +$(TARGETPFX)NH$(NHV)DOS.ZIP: dospkg $(dosboxnhfolder): mkdir -p $@ $(dosboxnhsrc): $(dosboxnhfolder) @@ -144,8 +150,8 @@ $(dosboxnhsrc)/util: $(dosboxnhsrc) mkdir -p $@ cp --preserve=timestamps $(FLDR)util/*.c $(dosboxnhsrc)/util cp --preserve=timestamps $(FLDR)util/*.h $(dosboxnhsrc)/util -$(dosboxnhfolder)/NETHACK.EXE: $(TARGETPFX)NH370DOS.ZIP - unzip -o $(TARGETPFX)NH370DOS.ZIP -d $(dosboxnhfolder) +$(dosboxnhfolder)/NETHACK.EXE: $(TARGETPFX)NH$(NHV)DOS.ZIP + unzip -o $(TARGETPFX)NH$(NHV)DOS.ZIP -d $(dosboxnhfolder) find $(dosboxnhfolder) -type f -name "$(dosboxconfigfile)" \ | xargs sed -i 's/#OPTIONS=video:autodetect/OPTIONS=video:autodetect/g' endif # dosbox @@ -225,21 +231,19 @@ mipspkg: dodata $(GAMEBIN) $(TARGETPFX)recover cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt -touch $(TARGETPFX)pkg/record - cd $(TARGETPFX)pkg ; zip -9 ../nh370mips.zip * ; cd ../../.. - @echo MIPS package zip file $(TARGETPFX)nh370mips.zip + cd $(TARGETPFX)pkg ; zip -9 ../nh$(NHV)mips.zip * ; cd ../../.. + @echo MIPS package zip file $(TARGETPFX)nh$(NHV)mips.zip endif # CROSS_TO_MIPS ifdef CROSS_TO_AMIGA $(TARGETPFX)amidos.o : ../sys/amiga/amidos.c $(HACK_H) -$(TARGETPFX)amigst.o : ../sys/amiga/amigst.c $(HACK_H) $(TARGETPFX)amirip.o : ../sys/amiga/amirip.c $(HACK_H) $(TARGETPFX)amistack.o : ../sys/amiga/amistack.c $(HACK_H) -$(TARGETPFX)amitty.o : ../sys/amiga/amitty.c $(HACK_H) $(TARGETPFX)amiwind.o : ../sys/amiga/amiwind.c \ ../sys/amiga/amimenu.c $(HACK_H) $(TARGETPFX)winami.o : ../sys/amiga/winami.c $(HACK_H) -$(TARGETPFX)winchar.o : ../sys/amiga/winchar.c tile.c $(HACK_H) +$(TARGETPFX)winchar.o : ../sys/amiga/winchar.c $(SRCDIR)/tile.c $(HACK_H) $(TARGETPFX)winfuncs.o : ../sys/amiga/winfuncs.c $(HACK_H) $(TARGETPFX)winkey.o : ../sys/amiga/winkey.c $(HACK_H) $(TARGETPFX)winamenu.o : ../sys/amiga/winamenu.c $(HACK_H) @@ -309,31 +313,30 @@ UUDECODE = ../util/uudecode ../util/uudecode: ../sys/share/uudecode.c $(CC) $(CFLAGS) -o $@ $< -amigapkg: $(AMITILES) ../util/uudecode - mkdir -p $(TARGETPFX)pkg/tiles $(TARGETPFX)pkg/hack - cp $(GAMEBIN) $(TARGETPFX)pkg/nethack - cp ../dat/nhdat $(TARGETPFX)pkg/nhdat - cp ../dat/license $(TARGETPFX)pkg/license - cp ../dat/symbols $(TARGETPFX)pkg/symbols - cp $(TARGETPFX)tiles16.iff $(TARGETPFX)pkg/tiles/tiles16.iff - cp $(TARGETPFX)tiles32.iff $(TARGETPFX)pkg/tiles/tiles32.iff - cp $(TARGETPFX)tomb.iff $(TARGETPFX)pkg/tomb.iff - cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf - cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt - ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/amifont8.uu && mv 8 hack/8 ) - ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/amifont.uu ) - cp $(AMISRC)/nethack.cnf $(TARGETPFX)pkg/nethack.cnf - -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/dflticon.uu && \ - ../../../util/uudecode ../../../sys/amiga/dflticon.uu ) - -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/NHinfo.uu && \ - ../../../util/uudecode ../../../sys/amiga/NHinfo.uu ) - -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/NewGame.uu && \ - ../../../util/uudecode ../../../sys/amiga/NewGame.uu ) - -( cd $(TARGETPFX)pkg && test -f ../../../sys/amiga/HackWB.uu && \ - ../../../util/uudecode ../../../sys/amiga/HackWB.uu ) - touch $(TARGETPFX)pkg/record - ( cd $(TARGETPFX)pkg && zip -9r ../NH370AMI.ZIP * ) - @echo amiga package zip file $(TARGETPFX)NH370AMI.ZIP +amigapkg: $(GAMEBIN) $(AMITILES) ../util/uudecode + mkdir -p $(TARGETPFX)pkg/NetHack/tiles $(TARGETPFX)pkg/NetHack/hack + cp $(GAMEBIN) $(TARGETPFX)pkg/NetHack/nethack + cp ../dat/nhdat $(TARGETPFX)pkg/NetHack/nhdat + cp ../dat/license $(TARGETPFX)pkg/NetHack/license + cp ../dat/symbols $(TARGETPFX)pkg/NetHack/symbols + cp $(TARGETPFX)tiles16.iff $(TARGETPFX)pkg/NetHack/tiles/tiles16.iff + cp $(TARGETPFX)tiles32.iff $(TARGETPFX)pkg/NetHack/tiles/tiles32.iff + cp $(TARGETPFX)tomb.iff $(TARGETPFX)pkg/NetHack/tomb.iff + cp ../doc/nethack.txt $(TARGETPFX)pkg/NetHack/nethack.txt + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/amifont8.uu && mv 8 hack/8 ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/amifont.uu ) + cp $(AMISRC)/nethack.cnf $(TARGETPFX)pkg/NetHack/nethack.cnf + cp $(AMISRC)/README.amiga $(TARGETPFX)pkg/NetHack/README.amiga + cp $(AMISRC)/amii.hlp $(TARGETPFX)pkg/NetHack/amii.hlp + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/NHinfo.uu ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/cnf-info.uu ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/license-info.uu ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/txt-info.uu ) + ( cd $(TARGETPFX)pkg/NetHack && ../../../../util/uudecode ../../../../sys/amiga/readme-info.uu ) + ( cd $(TARGETPFX)pkg && ../../../util/uudecode ../../../sys/amiga/drawer-info.uu ) + touch $(TARGETPFX)pkg/NetHack/record + ( cd $(TARGETPFX)pkg && zip -9r ../NH$(NHV)AMI$(AMIPKGSEQ).ZIP NetHack NetHack.info ) + @echo amiga package zip file $(TARGETPFX)NH$(NHV)AMI$(AMIPKGSEQ).ZIP endif # CROSS_TO_AMIGA ifdef CROSS_SHARED @@ -348,11 +351,15 @@ $(TARGETPFX)giftiles.o : ../win/share/giftiles.c endif # CROSS_SHARED # ifdef CROSS +ifdef MAKEFILE_TOP +# top-level liblua.a is a host-side build; keep TARGET_CC out of it +LUAMAKEFLAGS = CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' +endif # MAKEFILE_TOP $(TARGETPFX)hacklib.a: $(TARGETPFX)hacklib.o $(TARGET_AR) $(TARGET_ARFLAGS) $@ $(TARGETPFX)hacklib.o ifdef MAKEFILE_UTL $(TARGETPFX)recover.o: recover.c $(CONFIG_H) - $(TARGET_CC) $(TARGET_CFLAGS) $(CSTD) -c recover.c -o $@ + $(TARGET_CC) $(TARGET_CFLAGS) -c recover.c -o $@ ifdef CROSS_TO_MSDOS $(TARGETPFX)recover.exe : $(TARGETPFX)recover.o $(TARGETPFX)rversion.o $(TARGETPFX)hacklib.a $(TARGET_LINK) $(TARGET_LFLAGS) \ @@ -363,7 +370,7 @@ $(TARGETPFX)recover : $(TARGETPFX)recover.o $(TARGETPFX)rversion.o $(TARGETPFX)h $(TARGETPFX)recover.o $(TARGETPFX)rversion.o $(TARGETPFX)hacklib.a -o $@ endif $(TARGETPFX)rversion.o: ../src/version.c $(HACK_H) - $(TARGET_CC) $(TARGET_CFLAGS) -DMINIMAL_FOR_RECOVER $(CSTD) -c ../src/version.c -o $@ + $(TARGET_CC) $(TARGET_CFLAGS) -DMINIMAL_FOR_RECOVER -c ../src/version.c -o $@ endif # MAKEFILE_UTL endif # CROSS @@ -478,7 +485,11 @@ $(TARGETPFX)slk.o : $(PDCTOP)/pdcurses/slk.c $(TARGETPFX)termattr.o : $(PDCTOP)/pdcurses/termattr.c $(TARGETPFX)touch.o : $(PDCTOP)/pdcurses/touch.c $(TARGETPFX)util.o : $(PDCTOP)/pdcurses/util.c +# We need an explicit recipe for the creation of $(TARGETPFX)window.o +# because it will try and use the X11 version of window.c otherwise $(TARGETPFX)window.o : $(PDCTOP)/pdcurses/window.c + $(TARGET_CC) $(PDCINCL) $(PDC_TARGET_CFLAGS) \ + -Wno-sign-compare -o$@ $(PDCTOP)/pdcurses/window.c $(TARGETPFX)debug.o : $(PDCTOP)/pdcurses/debug.c $(TARGETPFX)pdcclip.o : $(PDCPORT)/pdcclip.c $(TARGETPFX)pdcdisp.o : $(PDCPORT)/pdcdisp.c diff --git a/sys/unix/hints/include/cross-pre1.370 b/sys/unix/hints/include/cross-pre1.500 similarity index 88% rename from sys/unix/hints/include/cross-pre1.370 rename to sys/unix/hints/include/cross-pre1.500 index 867886d9b..1730f5af3 100644 --- a/sys/unix/hints/include/cross-pre1.370 +++ b/sys/unix/hints/include/cross-pre1.500 @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-pre1. $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 include/cross-pre1. $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # # Cross-compiling -PRE section 1 # @@ -42,6 +42,7 @@ ifdef CROSS_TO_AMIGA CROSS=1 BUILD_TARGET_LUA=1 CROSS_SHARED=1 +HACKDIR=NetHack: override TARGET = amiga override TARGETDIR=../targets/$(TARGET) override TARGETPFX = $(TARGETDIR)/ @@ -49,6 +50,7 @@ override TARGET_LIBS= endif ifdef CROSS +CROSSCOMPILE=1 override PREGAME= override BUILDMORE= override CLEANMORE= diff --git a/sys/unix/hints/include/cross-pre2.370 b/sys/unix/hints/include/cross-pre2.500 similarity index 90% rename from sys/unix/hints/include/cross-pre2.370 rename to sys/unix/hints/include/cross-pre2.500 index 3476682ad..05803d7a9 100644 --- a/sys/unix/hints/include/cross-pre2.370 +++ b/sys/unix/hints/include/cross-pre2.500 @@ -1,5 +1,5 @@ #===============-================================================= -# NetHack 3.7 include/cross-pre2 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 include/cross-pre2 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # # Cross-compiling -PRE section 2 # @@ -134,6 +134,8 @@ override TARGET_CC = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc override TARGET_CXX = $(TOOLTOP1)/i586-pc-msdosdjgpp-g++ override TARGET_AR = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc-ar override TARGET_STUBEDIT = ../lib/djgpp/i586-pc-msdosdjgpp/bin/stubedit +override GENTILEOFILE = $(TARGETPFX)tile.o +override UUIDOBJ = ifdef MAKEFILE_SRC FLDR=../ endif @@ -146,7 +148,7 @@ ifdef DOSBOX dosbox=$(DOSBOX) endif ifdef dosbox -dosboxgameid=NH370 +dosboxgameid=NH$(NHV) dosboxtop=$(dosbox) dosboxnhfolder=$(dosboxtop)/$(dosboxgameid) dosboxnhsrc=$(dosboxnhfolder)/NHSRC @@ -175,8 +177,31 @@ MSDOS_GPP_CFLAGS = -Wall -Wextra -Wno-missing-field-initializers -Wreturn-type \ -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -pedantic \ -Wmissing-declarations -Wformat-nonliteral -Wunreachable-code \ -Wno-maybe-uninitialized +ifndef WANT_WIN_TTY + # A Curses-only configuration + MSDOS_GRAPH_CONFIG = -DNOTTYGRAPHICS + SKIP_TILES = 1 + ifndef WANT_DOSVGA + SKIP_FONTS = 1 + endif + SKIP_FONT_C = 1 +else ifdef NO_GRAPHICS + MSDOS_GRAPH_CONFIG = -DSUPPRESS_GRAPHICS + # Curses will need the fonts, but not font.c + ifndef WANT_DOSVGA + SKIP_FONTS = 1 + endif + SKIP_FONT_C = 1 + SKIP_TILES = 1 +else ifdef NO_TILES + MSDOS_GRAPH_CONFIG = + # without SKIP_FONT_C; if ENHANCED_SYMBOLS is set, we'll need the fonts + SKIP_TILES = 1 +else + MSDOS_GRAPH_CONFIG = -DTILES_IN_GLYPHMAP +endif MSDOS_TARGET_CFLAGS = -c -O $(DBGFLAGS) -I../include -I../sys/msdos -I../win/share \ - $(LUAINCL) -DDLB $(PDCURSESDEF) -DTILES_IN_GLYPHMAP \ + $(LUAINCL) -DDLB $(PDCURSESDEF) $(MSDOS_GRAPH_CONFIG) \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_MSDOS \ -D_NAIVE_DOS_REGS \ $(MSDOS_GCC_CFLAGS) $(SNDCFLAGS) @@ -188,7 +213,11 @@ MSDOS_TARGET_CXXFLAGS = -c -O $(DBGFLAGS) -I../include -I../sys/msdos -I../win/s PDCINCL += -I$(PDCPORT) PDC_TARGET_CFLAGS = $(MSDOS_TARGET_CFLAGS) -Wno-unused-parameter \ -Wno-missing-prototypes -ifndef SKIP_FONTS_IN_CI +ifdef SKIP_FONTS_IN_CI +FONTTARGETS= +else ifdef SKIP_FONTS +FONTTARGETS= +else FONTVER = terminus-font-4.49.1 FONTTOP = ../lib/$(FONTVER) DOSFONT = ../sys/msdos/fonts @@ -196,8 +225,6 @@ FONTTARGETS = $(DOSFONT)/ter-u16b.psf $(DOSFONT)/ter-u16v.psf \ $(DOSFONT)/ter-u18b.psf $(DOSFONT)/ter-u20b.psf \ $(DOSFONT)/ter-u22b.psf $(DOSFONT)/ter-u24b.psf \ $(DOSFONT)/ter-u28b.psf $(DOSFONT)/ter-u32b.psf -else -FONTTARGETS= endif LUABIN = ../lib/lua-$(LUA_VERSION)/src/lua LUA_TARGET_CFLAGS = $(MSDOS_TARGET_CFLAGS) @@ -214,22 +241,27 @@ override SYSSRC = ../sys/share/pcmain.c ../sys/msdos/msdos.c \ ../sys/share/pcsys.c ../sys/share/pctty.c \ ../sys/share/pcunix.c ../sys/msdos/video.c \ ../sys/msdos/vidtxt.c ../sys/msdos/pckeys.c \ - ../sys/msdos/vidvga.c ../sys/msdos/vidvesa.c \ - ../sys/msdos/font.c \ - ../win/share/bmptiles.c ../win/share/giftiles.c \ - ../win/share/tileset.c + ../sys/msdos/vidvga.c ../sys/msdos/vidvesa.c override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \ $(TARGETPFX)pcsys.o $(TARGETPFX)pctty.o \ $(TARGETPFX)pcunix.o $(TARGETPFX)video.o \ $(TARGETPFX)vidtxt.o $(TARGETPFX)pckeys.o \ - $(TARGETPFX)vidvga.o $(TARGETPFX)vidvesa.o \ - $(TARGETPFX)font.o \ - $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ - $(TARGETPFX)tileset.o $(TARGETPFX)tile.o + $(TARGETPFX)vidvga.o $(TARGETPFX)vidvesa.o +ifndef SKIP_FONT_C +override SYSSRC += ../sys/msdos/font.c +override SYSOBJ += $(TARGETPFX)font.o +endif +ifndef SKIP_TILES +override SYSSRC += ../win/share/bmptiles.c ../win/share/giftiles.c \ + ../win/share/tileset.c +override SYSOBJ += $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ + $(TARGETPFX)tileset.o +endif override WINLIB= override LUALIB= override LUALIBS= -override TOPLUALIB= +override LUATOPLIB= +override WINX11OBJ= override GAMEBIN = $(TARGETPFX)nethack.exe override RECOVERBIN = $(TARGETPFX)recover.exe override SFCTOOLBIN = $(TARGETPFX)sfctool.exe @@ -247,7 +279,12 @@ GDBEXE= GDBBAT= GDBCMDLINE= endif +ifndef SKIP_TILES VARDATND += nhtiles.bmp +NHTILES = ../dat/nhtiles.bmp +else +NHTILES = +endif # ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files @@ -258,6 +295,11 @@ endif # WANT_WIN_CURSES # Rule for files in sys/msdos $(TARGETPFX)%.o : ../sys/msdos/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< +# +# Rule for files in util +$(TARGETPFX)%.o : ../util/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< + endif # CROSS_TO_MSDOS #================================================================= @@ -267,6 +309,7 @@ ifdef CROSS_TO_WASM # WASM # originally from https://github.com/NetHack/NetHack/pull/385 #===============-================================================= +#also set a make variable flagging this as a crosscompile # #WASM_DEBUG = 1 WASM_DATA_DIR = $(TARGETPFX)wasm-data @@ -328,10 +371,10 @@ WASM_CFLAGS += -Wshadow # WASM_CFLAGS += -Wwrite-strings # WASM_CFLAGS += -Werror # Nethack C flags -WASM_CFLAGS += $(WINCFLAGS) #WINCFLAGS set from multiw-2.370 -WASM_CFLAGS += -DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE -#WASM_CFLAGS += -g -I../include -DNOTPARMDECL -WASM_CFLAGS += -I../include -DNOTPARMDECL +WASM_CFLAGS += $(WINCFLAGS) #WINCFLAGS set from multiw-2.500 +WASM_CFLAGS += -DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE -DNHUUID +#WASM_CFLAGS += -g -I../include +WASM_CFLAGS += -I../include # NetHack sources control WASM_CFLAGS += -DDLB WASM_CFLAGS += -DHACKDIR=\"$(HACKDIR)\" @@ -360,9 +403,10 @@ override SYSOBJ= $(TARGETPFX)libnhmain.o \ $(TARGETPFX)winshim.o override WINLIB = emranlib override LUALIB= -override TOPLUALIB= +override LUATOPLIB= override REGEXOBJ = $(TARGETPFX)posixregex.o override WINOBJ= +override UUIDOBJ= # don't bother Making regular NetHack executable override GAME= # the real VARDAT hasn't been defined yet for use in ALLDEP override @@ -442,7 +486,7 @@ override SYSOBJ = $(TARGETPFX)ioctl.o $(TARGETPFX)unixmain.o $(TARGETPFX)unixtty override WINLIB = $(NCURSESLIB) override LUALIB= override LUALIBS= -override TOPLUALIB= +override LUATOPLIB= override GAMEBIN=$(MIPS_TARGET) override RECOVERBIN = $(TARGETPFX)recover override PACKAGE = mipspkg @@ -470,7 +514,7 @@ ifdef CROSS_TO_AMIGA # # Cross-compiler: https://franke.ms/git/bebbo/amiga-gcc # Install to /opt/amiga, then: -# sys/unix/setup.sh sys/unix/hints/linux.370 +# sys/unix/setup.sh sys/unix/hints/linux.500 # make fetch-lua # make CROSS_TO_AMIGA=1 fetch-regex # make CROSS_TO_AMIGA=1 all @@ -499,8 +543,9 @@ override TARGET_CFLAGS = -c -O2 -noixemul $(TOOLARCH) \ $(LUAINCL) -DAMIGA -DNOTTYGRAPHICS -DNO_TERMS -DNO_SIGNAL \ -DTILES_IN_GLYPHMAP $(PDCURSESDEF) \ -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_AMIGA \ - -DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0"\" + -DAMIGA_VERSION_STRING=\""VER: NetHack 5.0.0"\" override TARGET_CXXFLAGS = $(TARGET_CFLAGS) +override GENTILEOFILE = $(TARGETPFX)tile.o LUA_TARGET_CFLAGS = $(TARGET_CFLAGS) ifeq "$(REGEXOBJ)" "$(TARGETPFX)cppregex.o" override TARGET_LINK = $(TARGET_CXX) @@ -510,9 +555,9 @@ endif override TARGET_LFLAGS= $(TOOLARCH) -noixemul -Wl,--allow-multiple-definition override TARGET_LIBS += $(LIBLM) VARDATND += nhtiles.bmp -override SYSSRC = ../sys/amiga/amidos.c ../sys/amiga/amigst.c \ +override SYSSRC = ../sys/amiga/amidos.c \ ../sys/amiga/amimenu.c ../sys/amiga/amirip.c \ - ../sys/amiga/amistack.c ../sys/amiga/amitty.c \ + ../sys/amiga/amistack.c \ ../sys/amiga/amiwind.c ../sys/amiga/clipwin.c \ ../sys/amiga/colorwin.c \ ../sys/amiga/winami.c ../sys/amiga/winchar.c \ @@ -521,9 +566,9 @@ override SYSSRC = ../sys/amiga/amidos.c ../sys/amiga/amigst.c \ ../sys/amiga/winstr.c ../sys/share/pcmain.c \ ../win/share/bmptiles.c ../win/share/giftiles.c \ ../win/share/tileset.c -override SYSOBJ = $(TARGETPFX)amidos.o $(TARGETPFX)amigst.o \ +override SYSOBJ = $(TARGETPFX)amidos.o \ $(TARGETPFX)amirip.o $(TARGETPFX)amistack.o \ - $(TARGETPFX)amitty.o $(TARGETPFX)amiwind.o \ + $(TARGETPFX)amiwind.o \ $(TARGETPFX)winami.o $(TARGETPFX)winchar.o \ $(TARGETPFX)winfuncs.o $(TARGETPFX)winkey.o \ $(TARGETPFX)winamenu.o $(TARGETPFX)winreq.o \ @@ -534,7 +579,7 @@ override SYSOBJ = $(TARGETPFX)amidos.o $(TARGETPFX)amigst.o \ override WINLIB= override LUALIB= override LUALIBS= -override TOPLUALIB= +override LUATOPLIB= override DLLIB= override WINOBJ= override GAMEBIN = $(TARGETPFX)nethack diff --git a/sys/unix/hints/include/dirs-perms.500 b/sys/unix/hints/include/dirs-perms.500 new file mode 100644 index 000000000..e0277f1f1 --- /dev/null +++ b/sys/unix/hints/include/dirs-perms.500 @@ -0,0 +1,123 @@ +#------------------------------------------------------------------------------ +# NetHack 5.0 directories.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-5.0 $ + +ifndef WANT_SHARED_INSTALL +PREFIX=$(abspath $(NHSROOT)) +SOURCEINSTALL=1 + +# ----------------------------------------- +# This is for the Linux source tree install +# ----------------------------------------- +ifeq "$(WHICH_OS)" "Linux" + +HACKDIR ?=$(PREFIX)/playground +INSTDIR ?=$(HACKDIR) +VARDIR ?=$(HACKDIR) + +GAMEPERM ?= 0700 +VARFILEPERM ?= 0600 +VARDIRPERM ?= 0700 + +else # macOS +# +# ----------------------------------------- +# This is for the macOS source tree install +# ----------------------------------------- +# +# The macOS setup sets things up two different +# ways, depending on whether an explicit +# WANT_SOURCE_INSTALL=1 was given, or not. +ifdef WANT_SOURCE_INSTALL + +HACKDIR ?=$(PREFIX)/playground +CHOWN ?=/usr/bin/true +CHGRP ?=/usr/bin/true + +GAMEPERM ?= 0700 +VARFILEPERM ?= 0600 +VARDIRPERM ?= 0700 +else # WANT_SOURCE_INSTALL not expressed +PREFIX:=$(wildcard ~) +SHELLDIR ?=$(PREFIX)/bin +HACKDIR ?=$(PREFIX)/nethackdir +CHOWN ?=/usr/bin/true +CHGRP ?=/usr/bin/true +GAMEPERM ?= 0700 +VARFILEPERM ?= 0600 +VARDIRPERM ?= 0700 + +endif # WANT_SOURCE_INSTALL + +INSTDIR ?=$(HACKDIR) +VARDIR ?=$(HACKDIR) + +endif # macOS +endif # not WANT_SHARED_INSTALL + +ifneq "$(SOURCEINSTALL)" "1" +ifdef WANT_SHARED_INSTALL +ifeq "$(WHICH_OS)" "Linux" +# ----------------------------------------- +# This is for the Linux system-wide install +# ----------------------------------------- + +PREFIX ?=$(wildcard ~)/nh/install +HACKDIR ?=$(PREFIX)/games/lib/nethackdir +SHELLDIR ?= $(PREFIX)/games +INSTDIR ?=$(HACKDIR) +VARDIR ?=$(HACKDIR) +MANDIR ?=/usr/share/man/man6 + +VARDIRPERM ?= 0755 +VARFILEPERM ?= 0600 +GAMEPERM ?= 0755 + +# ---------------------------------- +# End of Linux system-wide install +# ---------------------------------- + +else # macOS +# ------------------------------------------------ +# This is for the macOS system-wide shared install +# ------------------------------------------------ + +# if $GAMEUID is root, we install into roughly +# proper Mac locations, otherwise we install +# into ~/nethackdir + +ifeq ($(GAMEUID),root) +PREFIX:=/Library/NetHack +SHELLDIR ?=/usr/local/bin +HACKDIR ?=$(PREFIX)/nethackdir +MANDIR ?=/usr/local/share/man/man6 +CHOWN ?=chown +CHGRP ?=chgrp +# We run sgid so the game has access to both HACKDIR +# and user preferences +GAMEPERM ?=02755 + +else # ! root +PREFIX:=/Users/$(GAMEUID) +SHELLDIR ?=$(PREFIX)/bin +HACKDIR ?=$(PREFIX)/Library/NetHack/nethackdir +CHOWN ?=/usr/bin/true +CHGRP ?=/usr/bin/true +GAMEPERM ?= 0500 +endif # ! root + +INSTDIR ?=$(HACKDIR) +VARDIR ?=$(HACKDIR) + +VARFILEPERM ?= 0664 +VARDIRPERM ?= 0775 + +# --------------------------------------- +# End of macOS system-wide shared install +# -------------------------------------- +endif # WHICH_OS? +endif # WANT_SHARED_INSTALL +endif # SOURCEINSTALL != 1 + +#end of dirs-perms.500 +#-------------------------------------- + diff --git a/sys/unix/hints/include/gbdates-post.370 b/sys/unix/hints/include/gbdates-post.500 similarity index 80% rename from sys/unix/hints/include/gbdates-post.370 rename to sys/unix/hints/include/gbdates-post.500 index 9809a6df9..f16070c64 100755 --- a/sys/unix/hints/include/gbdates-post.370 +++ b/sys/unix/hints/include/gbdates-post.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 gbdates-post.370 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 5.0 gbdates-post.500 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ ifdef MAKEFILE_DOC ifdef GB_DATESTAMP Guidebook.dated.mn: $(GUIDEBOOK_MN_SRC) diff --git a/sys/unix/hints/include/gbdates-pre.370 b/sys/unix/hints/include/gbdates-pre.500 similarity index 82% rename from sys/unix/hints/include/gbdates-pre.370 rename to sys/unix/hints/include/gbdates-pre.500 index a9420cd6b..2c62af079 100755 --- a/sys/unix/hints/include/gbdates-pre.370 +++ b/sys/unix/hints/include/gbdates-pre.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 gbdates-pre.370 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 5.0 gbdates-pre.500 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ ifdef MAKEFILE_DOC ifneq "$(GIT)" "0" diff --git a/sys/unix/hints/include/linuxdistro.500 b/sys/unix/hints/include/linuxdistro.500 new file mode 100644 index 000000000..7ff828f1c --- /dev/null +++ b/sys/unix/hints/include/linuxdistro.500 @@ -0,0 +1,25 @@ +# ----- linuxdistro.500 -------- + +LINUX_DISTRO= +OS_ID := $(shell grep -E '^ID=' /etc/os-release 2>/dev/null | cut -d= -f2) +#$(info OS_ID=$(OS_ID)) + +ifeq ($(OS_ID),alpine) +LINUX_DISTRO=alpine +USE_SYSTEM_LUA=1 +CURSPKG = ncurses +endif +ifeq ($(OS_ID),debian) +LINUX_DISTRO=debian +USE_SYSTEM_LUA=1 +endif +ifeq ($(OS_ID),ubuntu) +LINUX_DISTRO=ubuntu +USE_SYSTEM_LUA=1 +endif +ifeq ($(OS_ID),fedora) +LINUX_DISTRO=fedora +USE_SYSTEM_LUA=1 +endif +#$(info LINUX_DIST=$(LINUX_DISTRO)) +# ----- end of linuxdistro.500 -------- diff --git a/sys/unix/hints/include/misc.370 b/sys/unix/hints/include/misc.500 similarity index 90% rename from sys/unix/hints/include/misc.370 rename to sys/unix/hints/include/misc.500 index 7f57697b4..ae7c282a0 100644 --- a/sys/unix/hints/include/misc.370 +++ b/sys/unix/hints/include/misc.500 @@ -1,11 +1,11 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 misc.370 $NHDT-Date: 1668359836 2022/11/13 17:17:16 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 misc.500 $NHDT-Date: 1668359836 2022/11/13 17:17:16 $ $NHDT-Branch: NetHack-5.0 $ # -# Further set-up for miscellaneous odds and ends (after compiler.370) +# Further set-up for miscellaneous odds and ends (after compiler.500) # # Included from: -# hints/linux.370 -# hints/macOS.370 +# hints/linux.500 +# hints/macOS.500 # # This ensures that .moc files are compatible with the version of Qt chosen. @@ -21,7 +21,7 @@ ifdef WANT_WIN_QT6 # Qt 6 builds and runs (with a couple of warnings) but needs more testing QTn_H = Qt6.h-t else -# Qt 5 is currently the default version for nethack 3.7.x's Qt interface +# Qt 5 is currently the default version for nethack NetHack 5.0.x's Qt interface QTn_H = Qt5.h-t endif $(QTn_H) :: @@ -105,6 +105,6 @@ endif # end groff less than 1.23 endif # end groff-specific endif # not USE_MANDOC -#end of hints/include/misc.370 +#end of hints/include/misc.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multisnd-post.370 b/sys/unix/hints/include/multisnd-post.500 similarity index 84% rename from sys/unix/hints/include/multisnd-post.370 rename to sys/unix/hints/include/multisnd-post.500 index 431745dab..c524db078 100644 --- a/sys/unix/hints/include/multisnd-post.370 +++ b/sys/unix/hints/include/multisnd-post.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd-post.370 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multisnd-post.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ ifeq "$(HAVE_SNDLIB)" "1" # note: one possible value for $(SNDLIBSRC) is 'macsound.m' which is written @@ -21,6 +21,6 @@ $(WAVDIR)/%.wav: ../util/uudecode $(WAVDIR)/%.uu endif # NEEDS_WAV endif # HAVE_SNDLIB -# end of multisnd-post.370 +# end of multisnd-post.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multisnd1-pre.370 b/sys/unix/hints/include/multisnd1-pre.500 similarity index 78% rename from sys/unix/hints/include/multisnd1-pre.370 rename to sys/unix/hints/include/multisnd1-pre.500 index 909a02fef..6c04f01b9 100644 --- a/sys/unix/hints/include/multisnd1-pre.370 +++ b/sys/unix/hints/include/multisnd1-pre.500 @@ -1,9 +1,9 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd1-pre.370 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multisnd1-pre.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # # If it's cross-platform it belongs in this file. -# If it's macOS-only, it belongs in macOS.370. -# If it's linux-only, it belongs in linux.370. +# If it's macOS-only, it belongs in macOS.500. +# If it's linux-only, it belongs in linux.500. # #ifdef WANT_TESTSOUND @@ -26,8 +26,8 @@ endif # HAVE_SNDLIB # HAVE_SNDLIB or NEEDS_SND_USERSOUNDS or NEEDS_SND_SEAUTOMAP # would have to be set prior to this. Any of them could have # been set just above, or they could have been set in -# multiw-2 for Qt, or they could have been set in macOS.370 -# or linux.370 for something platform-specific. +# multiw-2 for Qt, or they could have been set in macOS.500 +# or linux.500 for something platform-specific. # Regardless, if one of those is set, the related preprocessor # defines need to be added to SNDCFLAGS here. # diff --git a/sys/unix/hints/include/multisnd2-pre.370 b/sys/unix/hints/include/multisnd2-pre.500 similarity index 91% rename from sys/unix/hints/include/multisnd2-pre.370 rename to sys/unix/hints/include/multisnd2-pre.500 index 2970a4c7a..77d993333 100644 --- a/sys/unix/hints/include/multisnd2-pre.370 +++ b/sys/unix/hints/include/multisnd2-pre.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multisnd2-pre.370 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multisnd2-pre.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # ifdef NEEDS_WAV @@ -27,6 +27,6 @@ SNDWAVS = se_squeak_A se_squeak_B se_squeak_B_flat se_squeak_C se_squeak_D \ WAVS = $(addprefix $(WAVDIR)/, $(addsuffix .wav, $(SNDWAVS))) endif # NEEDS_WAV -# end of multisnd2-pre.370 +# end of multisnd2-pre.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multiw-1.370 b/sys/unix/hints/include/multiw-1.500 similarity index 76% rename from sys/unix/hints/include/multiw-1.370 rename to sys/unix/hints/include/multiw-1.500 index cd7651730..96f9173e6 100644 --- a/sys/unix/hints/include/multiw-1.370 +++ b/sys/unix/hints/include/multiw-1.500 @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multiw-1.370 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multiw-1.500 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-5.0 $ # 1. Which windowing interface(s) should be included in this binary? # One or more of these can be manually uncommented and/or can be specified @@ -19,5 +19,9 @@ #WANT_DEFAULT=Qt #WANT_DEFAULT=X11 -#end of multiw-1.370 +# Based on the NetHack version 5.0.0 +# Used to build some filenames subsequently in other include files +NHV=500 + +#end of multiw-1.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multiw-2.370 b/sys/unix/hints/include/multiw-2.500 similarity index 93% rename from sys/unix/hints/include/multiw-2.370 rename to sys/unix/hints/include/multiw-2.500 index e1cf1633d..75657d5e9 100644 --- a/sys/unix/hints/include/multiw-2.370 +++ b/sys/unix/hints/include/multiw-2.500 @@ -1,11 +1,11 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multiw-2.370 $NHDT-Date: 1599337709 2020/09/05 20:28:29 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 multiw-2.500 $NHDT-Date: 1599337709 2020/09/05 20:28:29 $ $NHDT-Branch: NetHack-5.0 $ # # Sorts out support for multiple window ports (interfaces) to included in the build. # # Included from: -# hints/linux.370 -# hints/macOS.370 +# hints/linux.500 +# hints/macOS.500 # # The following will be set appropriately following this: # - WANT_WIN_XXX (at least one will be set; default is TTY) @@ -79,8 +79,6 @@ WINCFLAGS= WINSRC = WINOBJ0 = SND_CFLAGS= -XTRASRC = -XTRAOBJ = ifdef WANT_WIN_TTY WINSRC += $(WINTTYSRC) @@ -104,8 +102,7 @@ ifdef WANT_WIN_X11 WINCFLAGS += -DX11_GRAPHICS WINSRC += $(WIINX11SRC) WINOBJ0 += $(WINX11OBJ) -XTRASRC += tile.c -XTRAOBJ += $(TARGETPFX)tile.o +GENTILECFILE = $(SRCDIR)/tile.c endif ifndef WANT_WIN_QT @@ -156,8 +153,7 @@ endif #! WANT_WIN_QT4 HAVE_SNDLIB = 1 NEEDS_SND_USERSOUNDS = 1 NEEDS_SND_SEAUTOMAP = 1 -XTRASRC += tile.c -XTRAOBJ += $(TARGETPFX)tile.o +GENTILECFILE = $(SRCDIR)/tile.c # ifndef CPLUSPLUS_NEEDED CPLUSPLUS_NEEDED = 1 @@ -213,6 +209,6 @@ ifeq "$(NOCRASHREPORT)" "1" WINCFLAGS += -DNOCRASHREPORT endif -#end of hints/include/multiw-2.370 +#end of hints/include/multiw-2.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/response.370 b/sys/unix/hints/include/response.500 similarity index 83% rename from sys/unix/hints/include/response.370 rename to sys/unix/hints/include/response.500 index 4e893ea3e..24b5d8822 100644 --- a/sys/unix/hints/include/response.370 +++ b/sys/unix/hints/include/response.500 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 response.370 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 5.0 response.500 $NHDT-Date: 1668359835 2022/11/13 17:17:15 $ $NHDT-Branch: NetHack-5.0 $ ifeq "$(RESP)" "1" USE_RESPONSEFILE=1 @@ -15,7 +15,6 @@ USE_RESPONSEFILE=1 endif ifeq "$(USE_RESPONSEFILE)" "1" -RESPONSEFILES=create_responsefiles CXXFLAGS = $(CCXXFLAGS) -I. -I$(QTDIR)/include $(QTCXXFLAGS) CC_COMPILER_SWITCHES := $(subst \,\\,$(CFLAGS)) CC_COMPILER_SWITCHES := $(subst ",\",$(CC_COMPILER_SWITCHES)) @@ -23,11 +22,12 @@ CXX_COMPILER_SWITCHES := $(subst \,\\,$(CXXFLAGS)) CXX_COMPILER_SWITCHES := $(subst ",\",$(CXX_COMPILER_SWITCHES)) CC_RESPONSEFILE=../src/nethack_cc.rsp CXX_RESPONSEFILE=../src/nethack_cxx.rsp +RESPONSEFILES=$(CC_RESPONSEFILE) $(CXX_RESPONSEFILE) CFLAGS=@$(CC_RESPONSEFILE) CXXFLAGS=@$(CXX_RESPONSEFILE) CLEAN_CC_RESPONSEFILE=rm -f $(CC_RESPONSEFILE); CLEAN_CXX_RESPONSEFILE=rm -f $(CXX_RESPONSEFILE); endif -#end of response.370 +#end of response.500 #------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/whichbsd.500 b/sys/unix/hints/include/whichbsd.500 new file mode 100644 index 000000000..86fa74ea0 --- /dev/null +++ b/sys/unix/hints/include/whichbsd.500 @@ -0,0 +1,23 @@ +#================================================================= +# NetHack 5.0 include/whichbsd.500 $NHDT-Date: 1778861905 2026/05/15 16:18:25 $ $NHDT-Branch: NetHack-5.0 $ +# +# +.ifdef WHICHBSD +.undef WHICHBSD +.endif + +OS!=uname -s + +.if ${OS} == "FreeBSD" +WHICHBSD=FREEBSD +.elif ${OS} == "OpenBSD" +WHICHBSD=OPENBSD +.elif ${OS} == "NetBSD" +WHICHBSD=NETBSD +.else +WHICHBSD=OTHERBSD +.endif + +# End of whichbsd.500 -PRE section +#================================================================= + diff --git a/sys/unix/hints/linux-minimal b/sys/unix/hints/linux-minimal index 003d69fe1..0d4b569b1 100644 --- a/sys/unix/hints/linux-minimal +++ b/sys/unix/hints/linux-minimal @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +# NetHack 5.0 linux $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.2 $ # Copyright (c) Patric Mueller # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/linux.370 b/sys/unix/hints/linux.500 similarity index 65% rename from sys/unix/hints/linux.370 rename to sys/unix/hints/linux.500 index 8b402350c..b81a37517 100755 --- a/sys/unix/hints/linux.370 +++ b/sys/unix/hints/linux.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 linux.370 $NHDT-Date: 1693519390 2023/08/31 22:03:10 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.61 $ +# NetHack 5.0 linux.500 $NHDT-Date: 1693519390 2023/08/31 22:03:10 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.61 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -12,29 +12,41 @@ # And let us know about it. # -#-PRE -# linux.370 hints file provides a single-user build for Linux (such -# as Ubuntu focal). +#-PRE xxxx -# note: '#-INCLUDE' is not just a comment -# multiw-1.370 contains sections 1 to 2 -#-INCLUDE multiw-1.370 - -HINTSVERSION := 370 +WHICH_OS=Linux +HINTSVERSION := 500 ifdef MAKEFILE_TOP +LUA_VERSION=5.4.8 ifeq ($(MAKELEVEL),0) PRECHECK+=checkmakefiles # all files included from this hints file get listed # in HINTSINCLNAMES (without suffix and without a path) -HINTSINCLNAMES := compiler cross-pre1 cross-pre2 cross-post \ +HINTSINCLNAMES := dirs-perms \ + compiler cross-pre1 cross-pre2 cross-post \ gbdates-pre gbdates-post \ + linuxdistro \ multiw-1 multiw-2 misc \ - multisnd1-pre multisnd2-pre multisnd-post + multisnd1-pre multisnd2-pre multisnd-post \ + response HINTSINCLFILES := $(addsuffix .$(HINTSVERSION), $(HINTSINCLNAMES)) endif endif +# linux.500 hints file provides a single-user build for Linux (such +# as Ubuntu focal). + +# note: '#-INCLUDE' is not just a comment +# multiw-1.500 contains sections 1 to 2 +#-INCLUDE multiw-1.500 + +# note: '#-INCLUDE' is not just a comment +# it pulls in the contents of dirs-perms.500 +#-INCLUDE dirs-perms.500 + +#-INCLUDE linuxdistro.500 + ifndef LIBXPM LIBXPM= -L/opt/X11/lib -lXpm endif @@ -52,7 +64,7 @@ USE_NOSTATICFN = 1 #USE_NONOSTATICFN = 1 #----------------------------------------------------------------------------- -#-INCLUDE cross-pre1.370 +#-INCLUDE cross-pre1.500 #----------------------------------------------------------------------------- @@ -60,12 +72,123 @@ USE_NOSTATICFN = 1 # you're reading this in Makefile augmented by hints, that may not be true). # -#-INCLUDE multiw-2.370 +#-INCLUDE multiw-2.500 -# compiler.370 contains compiler detection and adjustments common +#QT6 prior to compiler include +ifdef WANT_WIN_QT6 +CPLUSPLUS_NEED20=1 +ADDITIONAL_NO_WARN_GPPCCX=-Wno-sfinae-incomplete +ADDITIONAL_NO_WARN_CLANGCCX=-Wno-c++26-extensions +endif # WANT_WIN_QT6 + +# compiler.500 contains compiler detection and adjustments common # to both linux and macOS -#-INCLUDE compiler.370 +#-INCLUDE compiler.500 + +ifdef WANT_SYSTEM_LUA +ifndef LUA_VERSION +LUA_VERSION := 5.4.8 +endif +LUASUBDELIM := $(subst ., ,$(LUA_VERSION)) +LUASHVER := $(word 1, $(LUASUBDELIM)).$(word 2, $(LUASUBDELIM)) + +ifeq ($(LINUX_DISTRO),alpine) +# prereq: doas apk add lua5.4-dev +# doas apk add linux-headers +# doas apk add musl-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=pkg-config +LUAPKGNAME = lua-$(LUASHVER) +CURSPKG = ncurses +# +else ifeq ($(LINUX_DISTRO),debian) +# prereq: sudo apt install lua5.4 liblua5.4-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=pkg-config +LUAPKGNAME = lua-$(LUASHVER) +# +else ifeq ($(LINUX_DISTRO),ubuntu) +# prereq: sudo apt install lua5.4 liblua5.4-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=dpkg +LUAPKGNAME = lua$(LUASHVER) +# +else ifeq ($(LINUX_DISTRO),fedora) +# prereq: sudo dnf install lua lua-devel +USE_SYSTEM_LUA=1 +SHELLPKG :=rpm +LUAPKGNAME = lua-devel +# +else +USE_SYSTEM_LUA=0 +SHELLPKG := +endif # LINUX_DISTRO + +ifeq ($(USE_SYSTEM_LUA),1) +ifneq "$(SHELLPKG)" "" +# +# Two requirements must now pass: +# 1. We need to be able to check if Lua package +# is installed. We do that here. +# 2. The lua.h header file needs to be present +# where expected. We set LUATESTTARGET here, +# but the check is done later on in the top +# Makefile. +# +# Try to confirm package presence +ifeq ($(SHELLPKG),pkg-config) +PKG_EXISTS := $(shell pkg-config --exists $(LUAPKGNAME) \ + && echo yes || echo no) +# +else ifeq ($(SHELLPKG),dpkg) +PKG_EXISTS := $(shell dpkg -s $(LUAPKGNAME) > /dev/null 2>&1 \ + && echo yes || echo no) +# +else ifeq ($(SHELLPKG),rpm) +PKG_EXISTS := $(shell rpm -q $(LUAPKGNAME) > /dev/null 2>&1 \ + && echo yes || echo no) +# +else +PKG_EXISTS=no +$(info Existance of package $(LUAPKGNAME) could not be verified) +endif + +ifeq ($(PKG_EXISTS),yes) +$(info Existance of package $(LUAPKGNAME) verified) +# +ifeq ($(LINUX_DISTRO),fedora) +LUACFLAGS := $(shell pkg-config --cflags lua-$(LUASHVER)) +LUALIBS := $(shell pkg-config --libs lua-$(LUASHVER)) +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +# +else ifeq ($(LINUX_DISTRO),ubuntu) +LUACFLAGS := -I/usr/include/lua$(LUASHVER) +LUALIBS := -llua$(LUASHVER) -lm -ldl +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +# +else ifeq ($(SHELLPKG),pkg-config) +LUACFLAGS := $(shell pkg-config --cflags lua-$(LUASHVER)) +LUALIBS := $(shell pkg-config --libs lua-$(LUASHVER)) +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +endif +# +LUAHPREFIX= +#LUATOP= +#LUAMAKEFLAGS= +#LUA2NHTOP= +#LUABASELIB= +LUATOPLIB= +LUALIBBUILT= +LUALIB= +CFLAGS += $(LUACFLAGS) +endif # PKG_EXISTS? +endif # SHELLPKG has a value +endif # USE_SYSTEM_LUA +endif # WANT_SYSTEM_LUA ifdef WANT_WIN_QT ifdef WANT_WIN_QT5 @@ -80,10 +203,10 @@ endif # g++ greater than or equal to 14 endif # WANT_WIN_QT6 endif # WANT_WIN_QT -# misc.370 must come after compiler.370 +# misc.500 must come after compiler.500 # and after QTDIR is defined. # -#-INCLUDE misc.370 +#-INCLUDE misc.500 ifeq "$(USE_ASAN)" "1" CFLAGS+=-fsanitize=address @@ -96,6 +219,7 @@ LFLAGS+=-fsanitize=undefined endif ifeq "$(USE_CURSESLIB)" "1" +CURSPKG ?= ncursesw # default CURSESLIB = -lncurses -ltinfo # If CURSES_UNICODE is defined, we need ncursesw. @@ -103,8 +227,8 @@ CURSESLIB = -lncurses -ltinfo # CURSESLIB = -lncurses -ltinfo ifdef MAKEFILE_SRC comma:=, -NCURSES_LFLAGS = $(shell pkg-config ncursesw --libs) -NCURSES_CFLAGS = $(shell pkg-config ncursesw --cflags) +NCURSES_LFLAGS = $(shell pkg-config $(CURSPKG) --libs) +NCURSES_CFLAGS = $(shell pkg-config $(CURSPKG) --cflags) ifeq (,$(findstring ncursesw, $(NCURSES_LFLAGS))) ifeq (,$(findstring ncurses, $(NCURSES_LFLAGS))) #this indicates that pkg-config itself was unavailable @@ -177,7 +301,7 @@ NHCFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" #NHCFLAGS+=-DLIVELOG #NHCFLAGS+=-DCHANGE_COLOR NHCFLAGS+=-DSELF_RECOVER -ifdef WANT_WIN_CURSES +ifeq "$(USE_CURSESLIB)" "1" NHCFLAGS+=$(NCURSES_CFLAGS) ifeq "$(HAVE_NCURSESW)" "1" NHCFLAGS+=-DCURSES_UNICODE @@ -186,10 +310,10 @@ ifdef MAKEFILE_SRC $(info Attention: CURSES_UNICODE is not being defined without ncursesw) endif #MAKEFILE_SRC endif #HAVE_NCURSESW -endif #WANT_WIN_CURSES +endif #USE_CURSESLIB # -#-INCLUDE multisnd1-pre.370 +#-INCLUDE multisnd1-pre.500 # ifeq "$(CCISCLANG)" "1" @@ -197,19 +321,22 @@ ifeq "$(CCISCLANG)" "1" # clang-specific ends else # gcc-specific starts +ifndef MUSL +# __sighandler_t does not exist in musl LIBCFLAGS+=-DSIG_RET_TYPE=__sighandler_t +endif # gcc-specific ends endif -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CFLAGS+= $(WINCFLAGS) CFLAGS+= $(SNDCFLAGS) CFLAGS+= $(NHCFLAGS) CFLAGS+= $(LIBCFLAGS) -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CCXXFLAGS+= $(WINCFLAGS) CCXXFLAGS+= $(SNDCFLAGS) CCXXFLAGS+= $(NHCFLAGS) @@ -227,90 +354,106 @@ ifdef MAKEFILE_SRC ifdef CURSESLIB WINLIB += $(CURSESLIB) endif #CURSESLIB -endif #MAKEFILE_SRC + +ifneq "$(NO_NHUUID)" "1" +UUID_LIB_CHECK := $(shell echo `/sbin/ldconfig -p | grep libuuid`) +#$(info UUID_LIB_CHECK=$(UUID_LIB_CHECK)) +ifneq "$(UUID_LIB_CHECK)" "" +UUID_LIB=1 +else +UUID_LIB=0 +endif +#$(info UUID_LIB=$(UUID_LIB)) +# +# check for uuid development headers +UUID_HEADERS_CHECK := $(wildcard /usr/include/uuid/uuid.h) +#$(info UUID_HEADERS_CHECK=$(UUID_HEADERS_CHECK)) +ifneq "$(UUID_HEADERS_CHECK)" "" +UUID_HEADERS = 1 +else +UUID_HEADERS = 0 +endif +#$(info UUID_HEADERS=$(UUID_HEADERS)) + +ifeq "$(UUID_LIB)" "1" +ifeq "$(UUID_HEADERS)" "1" +ifndef WANT_NHUUID +WANT_NHUUID=1 +endif +endif +endif +else # NO_NHUUID +WANT_NHUUID=0 +endif # NO_NHUUID + +ifeq "$(WANT_NHUUID)" "1" +#$(info NHUUID support will be included) +CFLAGS+= -DNHUUID +LIBS+=-luuid +else # WANT_NHUUID +$(info Attention - No NHUUID support will be included) +endif # WANT_NHUUID +endif # MAKEFILE_SRC ifdef WANT_WIN_X11 USE_XPM=1 +USE_XFT=1 +USE_PNG=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif # -x: if built without dlb, some versions of mkfontdir think *.lev are fonts POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); # separate from CFLAGS so that we don't pass it to every file X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros +ifdef USE_XFT +CFLAGS += -DUSE_XFT +X11CFLAGS += $(shell pkg-config --cflags xft fontconfig) +WINX11LIB += $(shell pkg-config --libs xft fontconfig) +endif ifdef USE_XPM CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif +ifdef USE_PNG +CFLAGS += -DUSE_PNG +WINX11LIB += -lpng +endif WINLIB += $(WINX11LIB) LFLAGS+=-L/opt/X11/lib endif # WANT_WIN_X11 ifdef WANT_WIN_QT LINK = $(CXX) +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif +# QT4 ifdef WANT_WIN_QT4 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --cflags)) -DQT_NO_SOUND=1 WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --libs) endif # WANT_WIN_QT4 +#QT5 ifdef WANT_WIN_QT5 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags)) WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) endif # WANT_WIN_QT5 +#QT6 ifdef WANT_WIN_QT6 -ifdef QT6MANUAL -# Try some likely spots for a self-built Qt6. -# You'll have to change these manually before using the hints file -# if they don't match the installed location on your system. -ifneq "$(HOSTTYPE)" "" -QTHOST=$(HOSTTYPE) -else -QTHOST=x86_64 -endif -QTTOP=/usr/include/$(HOSTTYPE)-linux-gnu/qt6 -ifneq ($(wildcard $(QTTOP)/*),) -#we don't set QTLOCATED=1 for this -QTINCDIR=/usr/include/$(QTHOST)-linux-gnu/qt6 -QTLIBDIR=/usr/lib/$(QTHOST)-linux.gnu -QTCXXFLAGS += -DQT_WIDGETS_LIB -DQT_MULTIMEDIA_LIB -DQT_NETWORK_LIB -DQT_GUI_LIB -DQT_CORE_LIB -QTCXXFLAGS += -I$(QTINCDIR)/QtWidgets -I$(QTINCDIR) -I$(QTINCDIR)/QtMultimedia -QTCXXFLAGS += -I$(QTINCDIR)/QtNetwork -I$(QTINCDIR)/QtGui -I$(QTINCDIR)/QtCore -WINLIB += -L$(QTLIBDIR) -lQt6Widgets -lQt6Multimedia -lQt6Network -lQt6Gui -lQt6Core -MOCPATH = /usr/lib/qt6/libexec/moc -#/usr/lib/x86_64-linux-gnu/libQt6EglFSDeviceIntegration.so -endif # QTTOP/* -ifndef QTINCDIR -ifneq ($(wildcard /usr/local/Qt6/*),) -QTDIR=/usr/local/Qt6 -QTLOCATED=1 -endif # wildcard /usr/local/Qt6 -ifneq ($(wildcard /usr/local/qt6/*),) -QTDIR=/usr/local/qt6 -QTLOCATED=1 -endif # wildcard /usr/local/qt6 -endif # !QTINCDIR -ifdef QTLOCATED -QTCXXFLAGS += -I$(QTDIR)/include/QtCore -QTCXXFLAGS += -I$(QTDIR)/include/QtGui -QTCXXFLAGS += -I$(QTDIR)/include/QtMultimedia -QTCXXFLAGS += -I$(QTDIR)/include/QtWidgets -MOCPATH = $(QTDIR)/libexec/moc -WINLIB += -L$(QTDIR)/lib -lQt6Widgets -lQt6Multimedia -lQt6Network -lQt6Gui -lQt6Core -endif # QTLOCATED -else # !QT6MANUAL -MOCDIR = $(shell pkg-config Qt6Gui --variable=libexecdir) -ifneq ($(wildcard $(MOCDIR)/*),) -MOCPATH = $(MOCDIR)/moc -else -MOCPATH = /usr/lib/qt6/libexec/moc -endif # MOCDIR -QTCXXFLAGS += $(sort $(shell pkg-config Qt6Gui Qt6Widgets Qt6Multimedia --cflags)) -WINLIB += $(shell pkg-config Qt6Gui Qt6Widgets Qt6Multimedia --libs) -endif # QT6MANUAL +QTCXXFLAGS += $(shell pkg-config --cflags Qt6Multimedia) +WINLIB += $(shell pkg-config --libs Qt6Core Qt6Gui Qt6Widgets Qt6Multimedia) +MOCPATH = $(shell pkg-config --variable=libexecdir Qt6Core)/moc endif # WANT_WIN_QT6 + ifndef QTDIR +ifndef WANT_WIN_QT6 $(error QTDIR not defined in the environment or Makefile) +endif # not WANT_WIN_QT6 endif # QTDIR # XXX if /Developer/qt exists and QTDIR not set, use that # XXX make sure QTDIR points to something reasonable @@ -323,7 +466,7 @@ LINK = $(CC) endif # !WANT_WIN_QT # prevent duplicate tile.o in WINOBJ -WINOBJ = $(WINOBJ0) $(sort $(XTRAOBJ)) +WINOBJ = $(WINOBJ0) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) @@ -369,27 +512,10 @@ SYSCONFENSURE = (if ! test -f $(INSTDIR)/sysconf ; then \ chmod $(VARFILEPERM) $(INSTDIR)/sysconf; fi ); ifdef WANT_SOURCE_INSTALL -PREFIX=$(abspath $(NHSROOT)) -#SHELLDIR= -HACKDIR=$(PREFIX)/playground -GAMEPERM = 0700 -VARFILEPERM = 0600 -VARDIRPERM = 0700 CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE MOREALL=$(MAKE) install -else #!WANT_SOURCE_INSTALL -#PREFIX=/usr -PREFIX=$(wildcard ~)/nh/install -HACKDIR=$(PREFIX)/games/lib/nethackdir -SHELLDIR = $(PREFIX)/games -VARDIRPERM = 0755 -VARFILEPERM = 0600 -GAMEPERM = 0755 endif #?WANT_SOURCE_INSTALL -INSTDIR=$(HACKDIR) -VARDIR = $(HACKDIR) - ifdef MAKEFILE_TOP TESTGDBPATH=/usr/bin/gdb POSTINSTALL+= test -f $(TESTGDBPATH) || \ @@ -430,7 +556,7 @@ LFLAGS+=-rdynamic # if TTY_TILES_ESCCODES #WINSRC += tile.c -#WINOBJ += tile.o +#GENTILEOFILE = $(SRCDIR)/tile.o # endif CHOWN=true @@ -439,28 +565,28 @@ CHGRP=true # manpages directory MANDIR=/usr/share/man/man6 # -#-INCLUDE cross-pre2.370 +#-INCLUDE cross-pre2.500 # # -#-INCLUDE gbdates-pre.370 +#-INCLUDE gbdates-pre.500 # # -#-INCLUDE multisnd2-pre.370 +#-INCLUDE multisnd2-pre.500 # # -#-INCLUDE response.370 +#-INCLUDE response.500 # #-POST # -#-INCLUDE gbdates-post.370 +#-INCLUDE gbdates-post.500 # # -#-INCLUDE multisnd-post.370 +#-INCLUDE multisnd-post.500 # ifdef MAKEFILE_TOP @@ -484,6 +610,6 @@ $(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) endif # WANT_LIBNH # -#-INCLUDE cross-post.370 +#-INCLUDE cross-post.500 # diff --git a/sys/unix/hints/macOS.370 b/sys/unix/hints/macOS.500 similarity index 88% rename from sys/unix/hints/macOS.370 rename to sys/unix/hints/macOS.500 index 02e5dbba6..049666ab7 100755 --- a/sys/unix/hints/macOS.370 +++ b/sys/unix/hints/macOS.500 @@ -1,4 +1,4 @@ -# NetHack 3.7 macOS.370 $NHDT-Date: 1693359574 2023/08/30 01:39:34 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.138 $ +# NetHack 5.0 macOS.500 $NHDT-Date: 1693359574 2023/08/30 01:39:34 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.138 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -17,24 +17,32 @@ # macOS hints file # -# note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 2 -#-INCLUDE multiw-1.370 - -HINTSVERSION := 370 +WHICH_OS=macOS +HINTSVERSION := 500 ifdef MAKEFILE_TOP +LUA_VERSION=5.4.8 ifeq ($(MAKELEVEL),0) PRECHECK+=checkmakefiles # all files included from this hints file get listed # in HINTSINCLNAMES (without suffix and without a path) -HINTSINCLNAMES := compiler cross-pre1 cross-pre2 cross-post \ +HINTSINCLNAMES := dirs-perms \ + compiler cross-pre1 cross-pre2 cross-post \ gbdates-pre gbdates-post \ multiw-1 multiw-2 misc \ - multisnd1-pre multisnd2-pre multisnd-post + multisnd1-pre multisnd2-pre multisnd-post \ + response HINTSINCLFILES := $(addsuffix .$(HINTSVERSION), $(HINTSINCLNAMES)) endif endif +# note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 2 +#-INCLUDE multiw-1.500 + +# note: '#-INCLUDE' is not just a comment +# it pulls in the contents of dirs-perms.500 +#-INCLUDE dirs-perms.500 + ifneq "$(USEMACPORTS)" "1" HAVE_HOMEBREW := $(shell expr `which -s brew; echo $$?` = 0) endif @@ -55,14 +63,14 @@ endif # you're reading this in Makefile augmented by hints, that may not be true). # -#-INCLUDE cross-pre1.370 +#-INCLUDE cross-pre1.500 -#-INCLUDE multiw-2.370 +#-INCLUDE multiw-2.500 -# compiler.370 contains compiler detection and adjustments common +# compiler.500 contains compiler detection and adjustments common # to both linux and macOS -#-INCLUDE compiler.370 +#-INCLUDE compiler.500 ifdef WANT_WIN_QT ifeq "$(HAVE_HOMEBREW)" "1" @@ -94,10 +102,10 @@ CCXXFLAGS +=-Wno-c++20-attribute-extensions endif endif -# misc.370 must come after compiler.370 +# misc.500 must come after compiler.500 # and after QTDIR is defined -#-INCLUDE misc.370 +#-INCLUDE misc.500 # manpages directory MANDIR=/usr/local/share/man/man6 @@ -113,7 +121,8 @@ NHCFLAGS+=-DDLB NHCFLAGS+=-DHACKDIR=\"$(HACKDIR)\" NHCFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" NHCFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -#NHCFLAGS+=-DTIMED_DELAY +#define this after X11 timed_delay fix +NHCFLAGS+=-DTIMED_DELAY #NHCFLAGS+=-DDUMPLOG #NHCFLAGS+=-DCONFIG_ERROR_SECURE=FALSE NHCFLAGS+=-DGREPPATH=\"/usr/bin/grep\" @@ -176,8 +185,8 @@ HAVE_HOMEBREW_NCURSES := $(shell expr `brew ls --versions ncurses > /dev/null; e ifeq "$(HAVE_HOMEBREW_NCURSES)" "1" # Newer versions of ncurses are commonly installed via homebrew, but intentionally unlinked. HOMEBREW_LFLAGS := -L$(shell brew --prefix)/opt/ncurses/lib -HOMEBREW_WINLIB := -I$(shell brew --prefix)/opt/ncurses/include -HOMEBREW_CFLAGS = +HOMEBREW_WINLIB := +HOMEBREW_CFLAGS = -I$(shell brew --prefix)/opt/ncurses/include endif #HAVE_HOMEBREW_NCURSES endif #HAVE_HOMEBREW ifeq "$(HAVE_MACPORTS)" "1" @@ -215,12 +224,27 @@ LFLAGS += -framework AVFoundation #endif endif +ifdef MAKEFILE_SRC +ifndef NO_NHUUID +# macOS doesn't need any extra prerequisite libraries +# so do this unconditionally, unless NO_NHUUID=1 is +# passed on the Make command line. +WANT_NHUUID=1 +endif #NO_NHUUID + +ifdef WANT_NHUUID +CFLAGS += -DNHUUID +UUIDOBJ = macuuid.o +LFLAGS += -framework Foundation +endif +endif #MAKEFILE_SRC + # -#-INCLUDE multisnd1-pre.370 +#-INCLUDE multisnd1-pre.500 # # although not currently doing anything for macOS, this is -# kept in for consistency with layout of linux.370 +# kept in for consistency with layout of linux.500 ifeq "$(CCISCLANG)" "1" # clang-specific starts # clang-specific ends @@ -230,15 +254,15 @@ else # gcc-specific ends endif -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CFLAGS+= $(PKGCFLAGS) $(WINCFLAGS) CFLAGS+= $(SNDCFLAGS) CFLAGS+= $(NHCFLAGS) CFLAGS+= $(LIBCFLAGS) -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CCXXFLAGS+= $(WINCFLAGS) CCXXFLAGS+= $(SNDCFLAGS) CCXXFLAGS+= $(NHCFLAGS) @@ -253,26 +277,43 @@ HINTOBJ=$(CHAINOBJ) endif # WANT_WIN_CHAIN ifdef WANT_WIN_X11 +USE_XFT=1 USE_XPM=1 +USE_PNG=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif # -x: if built without dodlb, some versions of mkfontdir think *.lev are fonts POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); # separate from CFLAGS so that we don't pass it to every file X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros +ifdef USE_XFT +CFLAGS += -DUSE_XFT +X11CFLAGS += $(shell pkg-config --cflags xft fontconfig freetype2) +WINX11LIB += $(shell pkg-config --libs xft fontconfig freetype2) +endif ifdef USE_XPM CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif +ifdef USE_PNG +CFLAGS += -DUSE_PNG +WINX11LIB += -lpng +endif WINLIB += $(WINX11LIB) LFLAGS += -L/opt/X11/lib endif # WANT_WIN_X11 ifdef WANT_WIN_QT LINK = $(CXX) +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif ifdef WANT_WIN_QT5 # Qt5 requires C++11 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig \ @@ -298,8 +339,7 @@ else # !WANT_WIN_QT LINK=$(CC) endif # !WANT_WIN_QT -# prevent duplicate tile.o in WINOBJ -WINOBJ = $(WINOBJ0) $(sort $(XTRAOBJ)) +WINOBJ = $(WINOBJ0) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) @@ -330,6 +370,12 @@ LIBNHSYSOBJ = $(TARGETPFX)libnhmain.o $(TARGETPFX)ioctl.o \ #without winshim override GAME= MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) $(TARGETPFX)libnh.a ) +# With $(GAME) empty, the regular `recover: $(GAME)` chain no longer +# triggers lua_support, but recover.c still pulls in hack.h -> nhlua.h +# transitively. Make recover depend on lua_support explicitly. +ifdef MAKEFILE_TOP +recover: lua_support +endif endif # WANT_LIBNH # Lua @@ -347,31 +393,11 @@ override LUA2NHTOP = ../.. override LUAMAKEFLAGS=$(LUAFLAGS) endif # GITSUBMODULES -ifdef WANT_SHARE_INSTALL +ifdef WANT_SHARED_INSTALL #ifdef MAKEFILE_SRC -#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARE_INSTALL = $(WANT_SHARE_INSTALL)) +#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARED_INSTALL = $(WANT_SHARED_INSTALL)) #endif -# if $GAMEUID is root, we install into roughly proper Mac locations, otherwise -# we install into ~/nethackdir -ifeq ($(GAMEUID),root) -PREFIX:=/Library/NetHack -SHELLDIR=/usr/local/bin -HACKDIR=$(PREFIX)/nethackdir -CHOWN=chown -CHGRP=chgrp -# We run sgid so the game has access to both HACKDIR and user preferences. -GAMEPERM = 02755 -else # ! root -PREFIX:=/Users/$(GAMEUID) -SHELLDIR=$(PREFIX)/bin -HACKDIR=$(PREFIX)/Library/NetHack/nethackdir -CHOWN=/usr/bin/true -CHGRP=/usr/bin/true -GAMEPERM = 0500 -endif # ! root -VARFILEPERM = 0664 -VARDIRPERM = 0775 ROOTCHECK= [[ `id -u` == 0 ]] || ( echo "Must run install with sudo."; exit 1) # XXX it's nice we don't write over sysconf, but we've already erased it # make sure we have group GAMEUID and group GAMEGRP @@ -388,17 +414,8 @@ PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \ else ifdef WANT_SOURCE_INSTALL #ifdef MAKEFILE_SRC -#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARE_INSTALL = $(WANT_SHARE_INSTALL)) +#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARED_INSTALL = $(WANT_SHARED_INSTALL)) #endif -PREFIX=$(abspath $(NHSROOT)) -# suppress nethack.sh -#SHELLDIR= -HACKDIR=$(PREFIX)/playground -CHOWN=/usr/bin/true -CHGRP=/usr/bin/true -GAMEPERM = 0700 -VARFILEPERM = 0600 -VARDIRPERM = 0700 POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; # We can use "make all" to build the whole thing - but it misses some things: @@ -408,17 +425,8 @@ CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE else # !WANT_SOURCE_INSTALL #ifdef MAKEFILE_SRC -#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARE_INSTALL = $(WANT_SHARE_INSTALL)) +#$(info WANT_SOURCE_INSTALL = $(WANT_SOURCE_INSTALL), WANT_SHARED_INSTALL = $(WANT_SHARED_INSTALL)) #endif -PREFIX:=$(wildcard ~) -SHELLDIR=$(PREFIX)/bin -HACKDIR=$(PREFIX)/nethackdir -CHOWN=/usr/bin/true -CHGRP=/usr/bin/true -GAMEPERM = 0700 -VARFILEPERM = 0600 -VARDIRPERM = 0700 - ifdef ($(WANT_DEFAULT),X11) # install nethack.rc as ~/.nethackrc if no ~/.nethackrc exists PREINSTALL+= cp -n win/X11/nethack.rc ~/.nethackrc || true; @@ -430,10 +438,7 @@ POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/s $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ chmod $(VARFILEPERM) $(HACKDIR)/sysconf; -endif # !WANT_SHARE_INSTALL - -INSTDIR=$(HACKDIR) -VARDIR=$(HACKDIR) +endif # !WANT_SHARED_INSTALL SYSCONFCREATE = sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf SYSCONFINSTALL = $(SYSCONFCREATE) && \ @@ -453,16 +458,16 @@ SYSCONFENSURE = (if ! test -f $(INSTDIR)/sysconf ; then \ # Install.Qt mentions a patch for macos - it's not there (it seems to be in the Qt binary # package under the docs directory). # -#-INCLUDE cross-pre2.370 +#-INCLUDE cross-pre2.500 # # -#-INCLUDE gbdates-pre.370 +#-INCLUDE gbdates-pre.500 # # -#-INCLUDE multisnd2-pre.370 +#-INCLUDE multisnd2-pre.500 # # -#-INCLUDE response.370 +#-INCLUDE response.500 # ifdef MAKEFILE_TOP @@ -532,10 +537,10 @@ endif # MAKEFILE_SRC #-POST # -#-INCLUDE gbdates-post.370 +#-INCLUDE gbdates-post.500 # # -#-INCLUDE multisnd-post.370 +#-INCLUDE multisnd-post.500 # ifdef MAKEFILE_TOP @@ -547,9 +552,26 @@ checkmakefiles: endif endif +ifdef WANT_NHUUID +$(TARGETPFX)macuuid.o: ../sys/unix/macuuid.m + $(CC) $(CFLAGS) -c -o$@ $< +endif + ifdef WANT_LIBNH -$(TARGETPFX)libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua-$(LUA_VERSION).a - $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua-$(LUA_VERSION).a +# Build libnh.a by merging the engine objects, the shim windowport, +# date.o (separate from $(HOBJ) per Makefile.src), hacklib.a, and Lua's +# static archive. Use libtool -static rather than ar so hacklib.a and +# liblua-$(LUA_VERSION).a have their members merged in -- ar would archive +# them as opaque .a members and macOS ld can't dereference those. +# Depending on $(LUALIB) triggers the lua_support build (which generates +# include/nhlua.h); without it, $(HOBJ) won't compile. +# filter-out drops $(SYSOBJ) (which carries unixmain.o) and $(WINOBJ) (the +# tty windowport) from $(HOBJ); $(LIBNHSYSOBJ) supplies libnhmain.o and +# winshim.o in their place. +$(TARGETPFX)libnh.a: $(LUALIB) $(HOBJ) $(LIBNHSYSOBJ) $(DATE_O) $(TARGET_HACKLIB) + libtool -static -o $@ \ + $(filter-out $(SYSOBJ) $(WINOBJ),$(HOBJ)) \ + $(LIBNHSYSOBJ) $(DATE_O) $(TARGET_HACKLIB) $(LUALIB) @echo "$@ built." $(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< @@ -637,7 +659,7 @@ $(BUNDLE_INFOPLIST): @echo 'CFBundlePackageType' >>$@ @echo 'APPL' >>$@ @echo 'CFBundleGetInfoString' >>$@ - @echo '$(BUNDLE_GAMENAME) 3.7 for MacOS' >>$@ + @echo '$(BUNDLE_GAMENAME) 5.0 for MacOS' >>$@ @echo 'CFBundleIdentifier' >>$@ @echo 'org.nethack.macos' >>$@ @echo 'CFBundleExecutable' >>$@ @@ -649,11 +671,11 @@ $(BUNDLE_INFOPLIST): @echo 'CFBundleName' >>$@ @echo '$(BUNDLE_NAME)' >>$@ @echo 'CFBundleVersion' >>$@ - @echo '3.7.0b73' >>$@ + @echo 'NetHack 5.0.0b73' >>$@ @echo 'CFBundleShortVersionString' >>$@ - @echo '3.7.0' >>$@ + @echo 'NetHack 5.0.0' >>$@ @echo 'NSHumanReadableCopyright' >>$@ - @echo '©By Stichting Mathematisch Centrum and M. Stephenson 1985-2023' >>$@ + @echo '©By Stichting Mathematisch Centrum and M. Stephenson 1985-2026' >>$@ @echo 'LSApplicationCategoryType' >>$@ @echo 'public.app-category.adventure-games' >>$@ @echo '' >>$@ @@ -690,7 +712,7 @@ endif # WANT_BUNDLE # --- end of bundle --- # # -#-INCLUDE cross-post.370 +#-INCLUDE cross-post.500 # ifdef MAKEFILE_TOP diff --git a/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh index 544eefbd1..4c306e85e 100755 --- a/sys/unix/hints/macosx.sh +++ b/sys/unix/hints/macosx.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 macosx.sh $NHDT-Date: 1597332920 2020/08/13 15:35:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ +# NetHack 5.0 macosx.sh $NHDT-Date: 1597332920 2020/08/13 15:35:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.24 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/solaris b/sys/unix/hints/solaris index 1f3e22e64..6c80e5e3d 100644 --- a/sys/unix/hints/solaris +++ b/sys/unix/hints/solaris @@ -1,5 +1,5 @@ # -# NetHack 3.7 unix $NHDT-Date: 1596498426 2020/08/03 23:47:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +# NetHack 5.0 unix $NHDT-Date: 1596498426 2020/08/03 23:47:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ # Copyright (c) Kevin Smolkowski "Snivik", Elgin Oregon 2019. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/solaris-playground b/sys/unix/hints/solaris-playground index 1c75b0766..080639f50 100644 --- a/sys/unix/hints/solaris-playground +++ b/sys/unix/hints/solaris-playground @@ -1,5 +1,5 @@ # -# NetHack 3.7 unix $NHDT-Date: 1596498427 2020/08/03 23:47:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +# NetHack 5.0 unix $NHDT-Date: 1596498427 2020/08/03 23:47:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ # Copyright (c) Kevin Smolkowski "Snivik", Elgin Oregon 2019. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/streamhack b/sys/unix/hints/streamhack index b41810f5e..e4b3c184a 100755 --- a/sys/unix/hints/streamhack +++ b/sys/unix/hints/streamhack @@ -1,4 +1,4 @@ -# NetHack 3.7 linux.370 $NHDT-Date: 1693519390 2023/08/31 22:03:10 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.61 $ +# NetHack 5.0 linux.500 $NHDT-Date: 1693519390 2023/08/31 22:03:10 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.61 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -12,29 +12,41 @@ # And let us know about it. # -#-PRE -# linux.370 hints file provides a single-user build for Linux (such -# as Ubuntu focal). +#-PRE xxxx -# note: '#-INCLUDE' is not just a comment -# multiw-1.370 contains sections 1 to 2 -#-INCLUDE multiw-1.370 - -HINTSVERSION := 370 +WHICH_OS=Linux +HINTSVERSION := 500 ifdef MAKEFILE_TOP +LUA_VERSION=5.4.8 ifeq ($(MAKELEVEL),0) PRECHECK+=checkmakefiles # all files included from this hints file get listed # in HINTSINCLNAMES (without suffix and without a path) -HINTSINCLNAMES := compiler cross-pre1 cross-pre2 cross-post \ +HINTSINCLNAMES := dirs-perms \ + compiler cross-pre1 cross-pre2 cross-post \ gbdates-pre gbdates-post \ + linuxdistro \ multiw-1 multiw-2 misc \ - multisnd1-pre multisnd2-pre multisnd-post + multisnd1-pre multisnd2-pre multisnd-post \ + response HINTSINCLFILES := $(addsuffix .$(HINTSVERSION), $(HINTSINCLNAMES)) endif endif +# linux.500 hints file provides a single-user build for Linux (such +# as Ubuntu focal). + +# note: '#-INCLUDE' is not just a comment +# multiw-1.500 contains sections 1 to 2 +#-INCLUDE multiw-1.500 + +# note: '#-INCLUDE' is not just a comment +# it pulls in the contents of dirs-perms.500 +#-INCLUDE dirs-perms.500 + +#-INCLUDE linuxdistro.500 + ifndef LIBXPM LIBXPM= -L/opt/X11/lib -lXpm endif @@ -52,7 +64,7 @@ USE_NOSTATICFN = 1 #USE_NONOSTATICFN = 1 #----------------------------------------------------------------------------- -#-INCLUDE cross-pre1.370 +#-INCLUDE cross-pre1.500 #----------------------------------------------------------------------------- @@ -60,12 +72,123 @@ USE_NOSTATICFN = 1 # you're reading this in Makefile augmented by hints, that may not be true). # -#-INCLUDE multiw-2.370 +#-INCLUDE multiw-2.500 -# compiler.370 contains compiler detection and adjustments common +#QT6 prior to compiler include +ifdef WANT_WIN_QT6 +CPLUSPLUS_NEED20=1 +ADDITIONAL_NO_WARN_GPPCCX=-Wno-sfinae-incomplete +ADDITIONAL_NO_WARN_CLANGCCX=-Wno-c++26-extensions +endif # WANT_WIN_QT6 + +# compiler.500 contains compiler detection and adjustments common # to both linux and macOS -#-INCLUDE compiler.370 +#-INCLUDE compiler.500 + +ifdef WANT_SYSTEM_LUA +ifndef LUA_VERSION +LUA_VERSION := 5.4.8 +endif +LUASUBDELIM := $(subst ., ,$(LUA_VERSION)) +LUASHVER := $(word 1, $(LUASUBDELIM)).$(word 2, $(LUASUBDELIM)) + +ifeq ($(LINUX_DISTRO),alpine) +# prereq: doas apk add lua5.4-dev +# doas apk add linux-headers +# doas apk add musl-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=pkg-config +LUAPKGNAME = lua-$(LUASHVER) +CURSPKG = ncurses +# +else ifeq ($(LINUX_DISTRO),debian) +# prereq: sudo apt install lua5.4 liblua5.4-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=pkg-config +LUAPKGNAME = lua-$(LUASHVER) +# +else ifeq ($(LINUX_DISTRO),ubuntu) +# prereq: sudo apt install lua5.4 liblua5.4-dev +USE_SYSTEM_LUA=1 +SHELLPKG :=dpkg +LUAPKGNAME = lua$(LUASHVER) +# +else ifeq ($(LINUX_DISTRO),fedora) +# prereq: sudo dnf install lua lua-devel +USE_SYSTEM_LUA=1 +SHELLPKG :=rpm +LUAPKGNAME = lua-devel +# +else +USE_SYSTEM_LUA=0 +SHELLPKG := +endif # LINUX_DISTRO + +ifeq ($(USE_SYSTEM_LUA),1) +ifneq "$(SHELLPKG)" "" +# +# Two requirements must now pass: +# 1. We need to be able to check if Lua package +# is installed. We do that here. +# 2. The lua.h header file needs to be present +# where expected. We set LUATESTTARGET here, +# but the check is done later on in the top +# Makefile. +# +# Try to confirm package presence +ifeq ($(SHELLPKG),pkg-config) +PKG_EXISTS := $(shell pkg-config --exists $(LUAPKGNAME) \ + && echo yes || echo no) +# +else ifeq ($(SHELLPKG),dpkg) +PKG_EXISTS := $(shell dpkg -s $(LUAPKGNAME) > /dev/null 2>&1 \ + && echo yes || echo no) +# +else ifeq ($(SHELLPKG),rpm) +PKG_EXISTS := $(shell rpm -q $(LUAPKGNAME) > /dev/null 2>&1 \ + && echo yes || echo no) +# +else +PKG_EXISTS=no +$(info Existance of package $(LUAPKGNAME) could not be verified) +endif + +ifeq ($(PKG_EXISTS),yes) +$(info Existance of package $(LUAPKGNAME) verified) +# +ifeq ($(LINUX_DISTRO),fedora) +LUACFLAGS := $(shell pkg-config --cflags lua-$(LUASHVER)) +LUALIBS := $(shell pkg-config --libs lua-$(LUASHVER)) +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +# +else ifeq ($(LINUX_DISTRO),ubuntu) +LUACFLAGS := -I/usr/include/lua$(LUASHVER) +LUALIBS := -llua$(LUASHVER) -lm -ldl +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +# +else ifeq ($(SHELLPKG),pkg-config) +LUACFLAGS := $(shell pkg-config --cflags lua-$(LUASHVER)) +LUALIBS := $(shell pkg-config --libs lua-$(LUASHVER)) +LUAHEADERS := /usr/include/lua$(LUASHVER) +LUATESTTARGET := $(LUAHEADERS)/lua.h +endif +# +LUAHPREFIX= +#LUATOP= +#LUAMAKEFLAGS= +#LUA2NHTOP= +#LUABASELIB= +LUATOPLIB= +LUALIBBUILT= +LUALIB= +CFLAGS += $(LUACFLAGS) +endif # PKG_EXISTS? +endif # SHELLPKG has a value +endif # USE_SYSTEM_LUA +endif # WANT_SYSTEM_LUA ifdef WANT_WIN_QT ifdef WANT_WIN_QT5 @@ -80,10 +203,10 @@ endif # g++ greater than or equal to 14 endif # WANT_WIN_QT6 endif # WANT_WIN_QT -# misc.370 must come after compiler.370 +# misc.500 must come after compiler.500 # and after QTDIR is defined. # -#-INCLUDE misc.370 +#-INCLUDE misc.500 ifeq "$(USE_ASAN)" "1" CFLAGS+=-fsanitize=address @@ -96,6 +219,7 @@ LFLAGS+=-fsanitize=undefined endif ifeq "$(USE_CURSESLIB)" "1" +CURSPKG ?= ncursesw # default CURSESLIB = -lncurses -ltinfo # If CURSES_UNICODE is defined, we need ncursesw. @@ -103,8 +227,8 @@ CURSESLIB = -lncurses -ltinfo # CURSESLIB = -lncurses -ltinfo ifdef MAKEFILE_SRC comma:=, -NCURSES_LFLAGS = $(shell pkg-config ncursesw --libs) -NCURSES_CFLAGS = $(shell pkg-config ncursesw --cflags) +NCURSES_LFLAGS = $(shell pkg-config $(CURSPKG) --libs) +NCURSES_CFLAGS = $(shell pkg-config $(CURSPKG) --cflags) ifeq (,$(findstring ncursesw, $(NCURSES_LFLAGS))) ifeq (,$(findstring ncurses, $(NCURSES_LFLAGS))) #this indicates that pkg-config itself was unavailable @@ -175,12 +299,11 @@ NHCFLAGS+=-DTTY_TILES_ESCCODES #NHCFLAGS+=-DTTY_SOUND_ESCCODES #NHCFLAGS+=-DNO_CHRONICLE #NHCFLAGS+=-DLIVELOG -NHCFLAGS+=-DDUMPLOG +#NHCFLAGS+=-DCHANGE_COLOR NHCFLAGS+=-DDUMPHTML NHCFLAGS+=-DUSE_GENERAL_ALTAR_COLORS -#NHCFLAGS+=-DCHANGE_COLOR NHCFLAGS+=-DSELF_RECOVER -ifdef WANT_WIN_CURSES +ifeq "$(USE_CURSESLIB)" "1" NHCFLAGS+=$(NCURSES_CFLAGS) ifeq "$(HAVE_NCURSESW)" "1" NHCFLAGS+=-DCURSES_UNICODE @@ -189,10 +312,10 @@ ifdef MAKEFILE_SRC $(info Attention: CURSES_UNICODE is not being defined without ncursesw) endif #MAKEFILE_SRC endif #HAVE_NCURSESW -endif #WANT_WIN_CURSES +endif #USE_CURSESLIB # -#-INCLUDE multisnd1-pre.370 +#-INCLUDE multisnd1-pre.500 # ifeq "$(CCISCLANG)" "1" @@ -200,19 +323,22 @@ ifeq "$(CCISCLANG)" "1" # clang-specific ends else # gcc-specific starts +ifndef MUSL +# __sighandler_t does not exist in musl LIBCFLAGS+=-DSIG_RET_TYPE=__sighandler_t +endif # gcc-specific ends endif -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CFLAGS+= $(WINCFLAGS) CFLAGS+= $(SNDCFLAGS) CFLAGS+= $(NHCFLAGS) CFLAGS+= $(LIBCFLAGS) -# WINCFLAGS set from multiw-2.370 -# SNDCFLAGS set from multisnd-pre.370 +# WINCFLAGS set from multiw-2.500 +# SNDCFLAGS set from multisnd-pre.500 CCXXFLAGS+= $(WINCFLAGS) CCXXFLAGS+= $(SNDCFLAGS) CCXXFLAGS+= $(NHCFLAGS) @@ -230,90 +356,106 @@ ifdef MAKEFILE_SRC ifdef CURSESLIB WINLIB += $(CURSESLIB) endif #CURSESLIB -endif #MAKEFILE_SRC + +ifneq "$(NO_NHUUID)" "1" +UUID_LIB_CHECK := $(shell echo `/sbin/ldconfig -p | grep libuuid`) +#$(info UUID_LIB_CHECK=$(UUID_LIB_CHECK)) +ifneq "$(UUID_LIB_CHECK)" "" +UUID_LIB=1 +else +UUID_LIB=0 +endif +#$(info UUID_LIB=$(UUID_LIB)) +# +# check for uuid development headers +UUID_HEADERS_CHECK := $(wildcard /usr/include/uuid/uuid.h) +#$(info UUID_HEADERS_CHECK=$(UUID_HEADERS_CHECK)) +ifneq "$(UUID_HEADERS_CHECK)" "" +UUID_HEADERS = 1 +else +UUID_HEADERS = 0 +endif +#$(info UUID_HEADERS=$(UUID_HEADERS)) + +ifeq "$(UUID_LIB)" "1" +ifeq "$(UUID_HEADERS)" "1" +ifndef WANT_NHUUID +WANT_NHUUID=1 +endif +endif +endif +else # NO_NHUUID +WANT_NHUUID=0 +endif # NO_NHUUID + +ifeq "$(WANT_NHUUID)" "1" +#$(info NHUUID support will be included) +CFLAGS+= -DNHUUID +LIBS+=-luuid +else # WANT_NHUUID +$(info Attention - No NHUUID support will be included) +endif # WANT_NHUUID +endif # MAKEFILE_SRC ifdef WANT_WIN_X11 USE_XPM=1 +USE_XFT=1 +USE_PNG=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif # -x: if built without dlb, some versions of mkfontdir think *.lev are fonts POSTINSTALL += bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); # separate from CFLAGS so that we don't pass it to every file X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros +ifdef USE_XFT +CFLAGS += -DUSE_XFT +X11CFLAGS += $(shell pkg-config --cflags xft fontconfig) +WINX11LIB += $(shell pkg-config --libs xft fontconfig) +endif ifdef USE_XPM CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif +ifdef USE_PNG +CFLAGS += -DUSE_PNG +WINX11LIB += -lpng +endif WINLIB += $(WINX11LIB) LFLAGS+=-L/opt/X11/lib endif # WANT_WIN_X11 ifdef WANT_WIN_QT LINK = $(CXX) +ifndef CROSSCOMPILE +GENTILEOFILE = $(SRCDIR)/tile.o +endif +# QT4 ifdef WANT_WIN_QT4 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --cflags)) -DQT_NO_SOUND=1 WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config QtGui --libs) endif # WANT_WIN_QT4 +#QT5 ifdef WANT_WIN_QT5 QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags)) WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) endif # WANT_WIN_QT5 +#QT6 ifdef WANT_WIN_QT6 -ifdef QT6MANUAL -# Try some likely spots for a self-built Qt6. -# You'll have to change these manually before using the hints file -# if they don't match the installed location on your system. -ifneq "$(HOSTTYPE)" "" -QTHOST=$(HOSTTYPE) -else -QTHOST=x86_64 -endif -QTTOP=/usr/include/$(HOSTTYPE)-linux-gnu/qt6 -ifneq ($(wildcard $(QTTOP)/*),) -#we don't set QTLOCATED=1 for this -QTINCDIR=/usr/include/$(QTHOST)-linux-gnu/qt6 -QTLIBDIR=/usr/lib/$(QTHOST)-linux.gnu -QTCXXFLAGS += -DQT_WIDGETS_LIB -DQT_MULTIMEDIA_LIB -DQT_NETWORK_LIB -DQT_GUI_LIB -DQT_CORE_LIB -QTCXXFLAGS += -I$(QTINCDIR)/QtWidgets -I$(QTINCDIR) -I$(QTINCDIR)/QtMultimedia -QTCXXFLAGS += -I$(QTINCDIR)/QtNetwork -I$(QTINCDIR)/QtGui -I$(QTINCDIR)/QtCore -WINLIB += -L$(QTLIBDIR) -lQt6Widgets -lQt6Multimedia -lQt6Network -lQt6Gui -lQt6Core -MOCPATH = /usr/lib/qt6/libexec/moc -#/usr/lib/x86_64-linux-gnu/libQt6EglFSDeviceIntegration.so -endif # QTTOP/* -ifndef QTINCDIR -ifneq ($(wildcard /usr/local/Qt6/*),) -QTDIR=/usr/local/Qt6 -QTLOCATED=1 -endif # wildcard /usr/local/Qt6 -ifneq ($(wildcard /usr/local/qt6/*),) -QTDIR=/usr/local/qt6 -QTLOCATED=1 -endif # wildcard /usr/local/qt6 -endif # !QTINCDIR -ifdef QTLOCATED -QTCXXFLAGS += -I$(QTDIR)/include/QtCore -QTCXXFLAGS += -I$(QTDIR)/include/QtGui -QTCXXFLAGS += -I$(QTDIR)/include/QtMultimedia -QTCXXFLAGS += -I$(QTDIR)/include/QtWidgets -MOCPATH = $(QTDIR)/libexec/moc -WINLIB += -L$(QTDIR)/lib -lQt6Widgets -lQt6Multimedia -lQt6Network -lQt6Gui -lQt6Core -endif # QTLOCATED -else # !QT6MANUAL -MOCDIR = $(shell pkg-config Qt6Gui --variable=libexecdir) -ifneq ($(wildcard $(MOCDIR)/*),) -MOCPATH = $(MOCDIR)/moc -else -MOCPATH = /usr/lib/qt6/libexec/moc -endif # MOCDIR -QTCXXFLAGS += $(sort $(shell pkg-config Qt6Gui Qt6Widgets Qt6Multimedia --cflags)) -WINLIB += $(shell pkg-config Qt6Gui Qt6Widgets Qt6Multimedia --libs) -endif # QT6MANUAL +QTCXXFLAGS += $(shell pkg-config --cflags Qt6Multimedia) +WINLIB += $(shell pkg-config --libs Qt6Core Qt6Gui Qt6Widgets Qt6Multimedia) +MOCPATH = $(shell pkg-config --variable=libexecdir Qt6Core)/moc endif # WANT_WIN_QT6 + ifndef QTDIR +ifndef WANT_WIN_QT6 $(error QTDIR not defined in the environment or Makefile) +endif # not WANT_WIN_QT6 endif # QTDIR # XXX if /Developer/qt exists and QTDIR not set, use that # XXX make sure QTDIR points to something reasonable @@ -326,7 +468,7 @@ LINK = $(CC) endif # !WANT_WIN_QT # prevent duplicate tile.o in WINOBJ -WINOBJ = $(WINOBJ0) $(sort $(XTRAOBJ)) +WINOBJ = $(WINOBJ0) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) @@ -372,27 +514,10 @@ SYSCONFENSURE = (if ! test -f $(INSTDIR)/sysconf ; then \ chmod $(VARFILEPERM) $(INSTDIR)/sysconf; fi ); ifdef WANT_SOURCE_INSTALL -PREFIX=$(abspath $(NHSROOT)) -#SHELLDIR= -HACKDIR=$(PREFIX)/playground -GAMEPERM = 0700 -VARFILEPERM = 0600 -VARDIRPERM = 0700 CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE MOREALL=$(MAKE) install -else #!WANT_SOURCE_INSTALL -#PREFIX=/usr -PREFIX=$(wildcard ~)/nh/install -HACKDIR=$(PREFIX)/games/lib/nethackdir -SHELLDIR = $(PREFIX)/games -VARDIRPERM = 0755 -VARFILEPERM = 0600 -GAMEPERM = 0755 endif #?WANT_SOURCE_INSTALL -INSTDIR=$(HACKDIR) -VARDIR = $(HACKDIR) - ifdef MAKEFILE_TOP TESTGDBPATH=/usr/bin/gdb POSTINSTALL+= test -f $(TESTGDBPATH) || \ @@ -418,7 +543,7 @@ endif SYSCFLAGS=-DLUA_USE_LINUX ifdef GITSUBMODULES LUAFLAGS=CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' -ifneq "$(CCISCLANG)" "" +ifeq "$(CCISCLANG)" "1" # clang LUAFLAGS +=CWARNGCC='' endif # clang @@ -433,7 +558,7 @@ LFLAGS+=-rdynamic # if TTY_TILES_ESCCODES WINSRC += tile.c -WINOBJ += tile.o +GENTILEOFILE = $(SRCDIR)/tile.o # endif CHOWN=true @@ -442,28 +567,28 @@ CHGRP=true # manpages directory MANDIR=/usr/share/man/man6 # -#-INCLUDE cross-pre2.370 +#-INCLUDE cross-pre2.500 # # -#-INCLUDE gbdates-pre.370 +#-INCLUDE gbdates-pre.500 # # -#-INCLUDE multisnd2-pre.370 +#-INCLUDE multisnd2-pre.500 # # -#-INCLUDE response.370 +#-INCLUDE response.500 # #-POST # -#-INCLUDE gbdates-post.370 +#-INCLUDE gbdates-post.500 # # -#-INCLUDE multisnd-post.370 +#-INCLUDE multisnd-post.500 # ifdef MAKEFILE_TOP @@ -487,6 +612,6 @@ $(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) endif # WANT_LIBNH # -#-INCLUDE cross-post.370 +#-INCLUDE cross-post.500 # diff --git a/sys/unix/hints/unix b/sys/unix/hints/unix index 7b937c45f..e6d9da942 100644 --- a/sys/unix/hints/unix +++ b/sys/unix/hints/unix @@ -1,5 +1,5 @@ # -# NetHack 3.7 unix $NHDT-Date: 1596498428 2020/08/03 23:47:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ +# NetHack 5.0 unix $NHDT-Date: 1596498428 2020/08/03 23:47:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/macuuid.m b/sys/unix/macuuid.m new file mode 100644 index 000000000..26b86e3b6 --- /dev/null +++ b/sys/unix/macuuid.m @@ -0,0 +1,36 @@ +/* macuuid.m */ +/* Copyright Michael Allison, 2023 */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" + +void get_macos_uuid(char *); + +#ifdef DEBUG +#undef DEBUG +#endif + +/* #import */ +#import + +void +get_macos_uuid(char *target) +{ + NSString *uuidString = [[NSUUID UUID] UUIDString]; + const char *str_uuid; + int i; + + /* str_uuid = [uuidString cStringUsingEncoding:NSUTF8StringEncoding]; */ + str_uuid = [uuidString cStringUsingEncoding:NSASCIIStringEncoding]; + + if (str_uuid && target) { + for (i = 0; i < (NHUUIDSZ -1 ); ++i) { + target[i] = str_uuid[i]; + } + target[(NHUUIDSZ - 1)] = '\0'; + } + return; +} + + +/* end of macuuid.m */ diff --git a/sys/unix/mkmkfile.sh b/sys/unix/mkmkfile.sh index 12894305b..82e8b91d0 100755 --- a/sys/unix/mkmkfile.sh +++ b/sys/unix/mkmkfile.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 mkmkfile.sh $NHDT-Date: 1597332770 2020/08/13 15:32:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ +# NetHack 5.0 mkmkfile.sh $NHDT-Date: 1597332770 2020/08/13 15:32:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. @@ -10,6 +10,7 @@ # $3 install path # $4 hints file (path) # $5 hints file (as given by user) +# $6 gnu or bsd echo "#" > $3 echo "# This file is generated automatically. Do not edit." >> $3 @@ -20,6 +21,37 @@ echo "" >> $3 echo "HINTSFILE=$5" >> $3 echo "" >> $3 +echo "###" >> $3 +echo "### add check for builder include file $6-style" >> $3 +echo "###" >> $3 +echo "" >> $3 +BUILDERINCL=make.prefs +echo "" >> $3 +case "$6" in + "gnu") + echo "ifdef MAKEFILE_TOP" >> $3 + echo "NHSROOT=." >> $3 + echo "else" >> $3 + echo "NHSROOT=.." >> $3 + echo "endif" >> $3 + echo "ifneq (\"\$(wildcard \$(NHSROOT)/$BUILDERINCL))\",\"\")" >> $3 + echo "-include \$(NHSROOT)/$BUILDERINCL" >> $3 + echo "endif" >> $3 + ;; + "bsd") + echo ".ifdef MAKEFILE_TOP" >> $3 + echo "NHSROOT=." >> $3 + echo ".else" >> $3 + echo "NHSROOT=.." >> $3 + echo ".endif" >> $3 + echo ".if exists(\$(NHSROOT)/$BUILDERINCL)" >> $3 + echo ".include \"\$(NHSROOT)/$BUILDERINCL\"" >> $3 + echo ".endif" >> $3 + ;; + *) +esac +echo "" >> $3 + echo "###" >> $3 echo "### Start $5 PRE" >> $3 echo "###" >> $3 diff --git a/sys/unix/nethack.sh b/sys/unix/nethack.sh index 9ce743494..6e49a1da0 100755 --- a/sys/unix/nethack.sh +++ b/sys/unix/nethack.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 nethack.sh $NHDT-Date: 1596498294 2020/08/03 23:44:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ +# NetHack 5.0 nethack.sh $NHDT-Date: 1596498294 2020/08/03 23:44:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/setup.sh b/sys/unix/setup.sh index 69595fd00..6731a12d2 100755 --- a/sys/unix/setup.sh +++ b/sys/unix/setup.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 setup.sh $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ +# NetHack 5.0 setup.sh $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.17 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -31,8 +31,15 @@ x) hints=/dev/null ;; esac -/bin/sh ./mkmkfile.sh Makefile.top TOP ../../Makefile $hints $hfile -/bin/sh ./mkmkfile.sh Makefile.dat DAT ../../dat/Makefile $hints $hfile -/bin/sh ./mkmkfile.sh Makefile.doc DOC ../../doc/Makefile $hints $hfile -/bin/sh ./mkmkfile.sh Makefile.src SRC ../../src/Makefile $hints $hfile -/bin/sh ./mkmkfile.sh Makefile.utl UTL ../../util/Makefile $hints $hfile +# is make gnu or bsd? +if make --version 2>/dev/null | grep -q "GNU"; then + whichmake=gnu +else + whichmake=bsd +fi + +/bin/sh ./mkmkfile.sh Makefile.top TOP ../../Makefile $hints $hfile $whichmake +/bin/sh ./mkmkfile.sh Makefile.dat DAT ../../dat/Makefile $hints $hfile $whichmake +/bin/sh ./mkmkfile.sh Makefile.doc DOC ../../doc/Makefile $hints $hfile $whichmake +/bin/sh ./mkmkfile.sh Makefile.src SRC ../../src/Makefile $hints $hfile $whichmake +/bin/sh ./mkmkfile.sh Makefile.utl UTL ../../util/Makefile $hints $hfile $whichmake diff --git a/sys/unix/sysconf b/sys/unix/sysconf index 34926903b..2d9676601 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.7 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.44 $ +# NetHack 5.0 sysconf $NHDT-Date: 1777240863 2026/04/26 22:01:03 $ $NHDT-Branch: to500 $:$NHDT-Revision: 1.47 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. # @@ -55,6 +55,10 @@ GENERICUSERS=play player game games nethack nethacker ec2-user # letter and "lock" (eg. alock, block, ...) MAXPLAYERS=10 +# Limit the number of rerolls per second when using the reroll option. +# 0 means that there is no limit on how quickly the user can reroll. +MAX_REROLL_RATE=0 + # If not null, added to string "To get local support, " in the support # information help. #SUPPORT=call Izchak at extension 42. @@ -130,7 +134,7 @@ MAXPLAYERS=10 # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "NetHack 5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format @@ -164,7 +168,7 @@ PANICTRACE_GDB=1 PANICTRACE_LIBC=2 # URL loaded for creating reports to the NetHack DevTeam -#CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html +#CRASHREPORTURL=https://nethack.org/links/cr-5.0.0.html # 'portable_device_paths' is only supported for Windows. Starting with # 3.6.3, nethack on Windows treats the folder containing nethack.exe and diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index ad2cef7de..7a0354d17 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixmain.c $NHDT-Date: 1711213891 2024/03/23 17:11:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 5.0 unixmain.c $NHDT-Date: 1711213891 2024/03/23 17:11:31 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.127 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -15,6 +15,13 @@ #include #endif +#ifdef NHUUID +/* for uuid */ +#ifdef LINUX +#include +#endif +#endif /* NHUUID */ + #if !defined(_BULL_SOURCE) && !defined(__sgi) && !defined(_M_UNIX) #if !defined(SUNOS4) && !(defined(ULTRIX) && defined(__GNUC__)) #if defined(POSIX_TYPES) || defined(SVR4) || defined(HPUX) @@ -125,7 +132,6 @@ main(int argc, char *argv[]) program_state.early_options = 1; /* handle -dalthackdir, -s , --version, --showpaths */ early_options(&argc, &argv, &dir); - program_state.early_options = 0; #ifdef CHDIR /* * Change directories before we initialize the window system so @@ -139,6 +145,7 @@ main(int argc, char *argv[]) #ifdef __linux__ check_linux_console(); #endif + program_state.early_options = 0; initoptions(); #ifdef PANICTRACE @@ -321,7 +328,7 @@ main(int argc, char *argv[]) static void process_options(int argc, char *argv[]) { - char *arg, *origarg; + char *arg, *origarg = 0; int i, l; config_error_init(FALSE, "command line", FALSE); @@ -447,22 +454,8 @@ process_options(int argc, char *argv[]) } } - if (argc > 1) { - int mxplyrs = atoi(argv[1]); - boolean mx_ok = (mxplyrs > 0); -#ifdef SYSCF - config_error_add("%s%s%s", - mx_ok ? "MAXPLAYERS are set in sysconf file" - : "Expected MAXPLAYERS, found \"", - mx_ok ? "" : argv[1], mx_ok ? "" : "\""); -#else - /* XXX This is deprecated in favor of SYSCF with MAXPLAYERS */ - if (mx_ok) - gl.locknum = mxplyrs; - else - config_error_add("Invalid MAXPLAYERS \"%s\"", argv[1]); -#endif - } + if (argc > 1 && origarg) + config_error_add("Unknown option: %.60s", origarg); #ifdef MAX_NR_OF_PLAYERS /* limit to compile-time limit */ if (!gl.locknum || gl.locknum > MAX_NR_OF_PLAYERS) @@ -834,4 +827,42 @@ sys_random_seed(void) return seed; } +#if defined(MACOS) && defined(NHUUID) +extern void get_macos_uuid(char *); /* sys/unix/macuuid.m */ +#endif + +void +get_nhuuid(void) +{ +#if defined(NHUUID) + char struuid[NHUUIDSZ] = { 0 }; +#if defined(LINUX) && defined(NHUUID) + uuid_t binuuid; +#endif + + if (svn.nhuuid[0]) + return; + +#if defined(MACOS) + get_macos_uuid(&struuid[0]); +#elif defined(LINUX) + uuid_generate_random(binuuid); + uuid_unparse(binuuid, struuid); +#endif /* MACOS || LINUX */ + + if (struuid[0]) + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", struuid); + +#endif /* NHUUID */ +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} /*unixmain.c*/ diff --git a/sys/unix/unixres.c b/sys/unix/unixres.c index 538d8bdcc..e5a376fae 100644 --- a/sys/unix/unixres.c +++ b/sys/unix/unixres.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixres.c $NHDT-Date: 1596498298 2020/08/03 23:44:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 unixres.c $NHDT-Date: 1596498298 2020/08/03 23:44:58 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Slash'EM development team, 2001. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index 8450da5f8..a7fb3f92e 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixunix.c $NHDT-Date: 1711213894 2024/03/23 17:11:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ +/* NetHack 5.0 unixunix.c $NHDT-Date: 1778886716 2026/05/15 15:11:56 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -379,10 +379,14 @@ child(int wt) linux_mapon(); #endif if ((f = fork()) == 0) { /* child */ +#ifdef CHDIR + const char *home = getenv("HOME"); +#endif (void) setgid(getgid()); (void) setuid(getuid()); #ifdef CHDIR - (void) chdir(getenv("HOME")); + if (home) + (void) chdir(home); #endif return 1; } diff --git a/sys/vms/Install.vms b/sys/vms/Install.vms index 5b0b7e184..6f73e6739 100644 --- a/sys/vms/Install.vms +++ b/sys/vms/Install.vms @@ -1,11 +1,11 @@ - Instructions for Building and Installing NetHack 3.7.0 + Instructions for Building and Installing NetHack 5.0.0 on a VMS (aka OpenVMS) system ========================================= 0. Please read this entire file before trying to build or install NetHack, then read it again! -1. NetHack 3.7 was built and tested on OpenVMS on both the Integrity +1. NetHack 5.0 was built and tested on OpenVMS on both the Integrity and Alpha platform using the HP C V7.3 for OpenVMS compiler. While not tested, older versions of DEC C will most likely work as compatibility with older systems is a goal of the VMS porting team. Unfortunately, @@ -145,7 +145,7 @@ Notes: 0. Version 3.5.x was never publicly released. 1. Save files and bones files from 3.6.x and earlier versions will not - work with 3.7.0. The scoreboard file (RECORD) from 3.6.x or 3.4.x or + work with 5.0.0. The scoreboard file (RECORD) from 3.6.x or 3.4.x or 3.3.x will work. 2. Ancient C libs will not work; vsnprintf is required. @@ -510,6 +510,6 @@ minimally updated 9-NOV-2015... and again 5-MAY-2019... and yet again 26-JAN-2020... -# NetHack 3.7 Install.vms $NHDT-Date: 1575245132 2019/12/02 00:05:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ +# NetHack 5.0 Install.vms $NHDT-Date: 1575245132 2019/12/02 00:05:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ # Copyright (c) 2003 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Install370.vms b/sys/vms/Install370.vms index edca9e9d0..b6c406e68 100644 --- a/sys/vms/Install370.vms +++ b/sys/vms/Install370.vms @@ -1,8 +1,8 @@ - Instructions for Building and Installing NetHack 3.7.0 + Instructions for Building and Installing NetHack 5.0.0 on a VSI openVMS 9.2 system ========================================= -This contains a description of how to build NetHack-3.7.0 on VSI OpenVMS 9.2. +This contains a description of how to build NetHack-5.0.0 on VSI OpenVMS 9.2. This process uses Gnu Make 4.1 (minimum) for VMS to carry out the build. Last tested with VSI C x86-64 V7.5-009 (GEM 50XBR) on OpenVMS x86_64 V9.2-2. @@ -26,7 +26,7 @@ Last tested with VSI C x86-64 V7.5-009 (GEM 50XBR) on OpenVMS x86_64 V9.2-2. [.win.tty] -- "window" routines for ordinary terminals (including terminal windows on workstations) -2. From the top of the NetHack 3.7 distribution, issue the following +2. From the top of the NetHack 5.0 distribution, issue the following pair of commands to distribute the GNU make Makefile.vms files to their working locations for building NetHack: $ set def [.sys.vms] @@ -76,7 +76,7 @@ Last tested with VSI C x86-64 V7.5-009 (GEM 50XBR) on OpenVMS x86_64 V9.2-2. Notes: 1. Save files and bones files from 3.6.x and earlier versions will not - work with 3.7.0. The scoreboard file (RECORD) from 3.6.x or 3.4.x or + work with 5.0.0. The scoreboard file (RECORD) from 3.6.x or 3.4.x or 3.3.x should work. 2. To specify user-preference options in your environment, define the @@ -360,5 +360,5 @@ Notes: make utility used. 8-March-2024 -# NetHack 3.7 Install370.vms $NHDT-Date: 1575245132 2019/12/02 00:05:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ +# NetHack 5.0 Install370.vms $NHDT-Date: 1575245132 2019/12/02 00:05:32 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.dat b/sys/vms/Makefile.dat index efe363297..e1787896b 100644 --- a/sys/vms/Makefile.dat +++ b/sys/vms/Makefile.dat @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - data files: special levels and other data. -# NetHack 3.7 Makefile.dat $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ +# NetHack 5.0 Makefile.dat $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ # Copyright (c) 2015 by Mike Stephenson # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.doc b/sys/vms/Makefile.doc index d728620d4..cb54314de 100644 --- a/sys/vms/Makefile.doc +++ b/sys/vms/Makefile.doc @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for the [Unix] documentation. -# NetHack 3.7 Makefile.doc $NHDT-Date: 1596498301 2020/08/03 23:45:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 Makefile.doc $NHDT-Date: 1596498301 2020/08/03 23:45:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.src b/sys/vms/Makefile.src index 20ee1643f..b810ad946 100644 --- a/sys/vms/Makefile.src +++ b/sys/vms/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for building nethack itself. -# NetHack 3.7 Makefile.src $NHDT-Date: 1683748060 2023/05/10 19:47:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ +# NetHack 5.0 Makefile.src $NHDT-Date: 1683748060 2023/05/10 19:47:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.60 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. @@ -136,7 +136,7 @@ RANDOBJ = isaac64.obj,random.obj # Other things that have to be reconfigured are in vmsconf.h, # and config.h -VERSION = 3.7.0 +VERSION = 5.0.0 MAKEDEFS = $(UTL)makedefs.exe; @@ -157,12 +157,12 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ monmove.c monst.c mplayer.c mthrowu.c muse.c music.c o_init.c \ objects.c objnam.c options.c pager.c pickup.c pline.c polyself.c \ potion.c pray.c priest.c quest.c questpgr.c read.c rect.c \ - region.c report.c restore.c rip.c rnd.c role.c rumors.c save.c \ - selvar.c sfstruct.c shk.c shknam.c sit.c sounds.c sp_lev.c \ - spell.c stairs.c steal.c steed.c strutil.c sys.c teleport.c \ - timeout.c topten.c track.c trap.c u_init.c uhitm.c vault.c \ - version.c vision.c weapon.c were.c wield.c windows.c wizard.c \ - wizcmds.c worm.c worn.c write.c zap.c + region.c report.c restore.c revision.c rip.c rnd.c role.c \ + rumors.c save.c selvar.c sfstruct.c shk.c shknam.c sit.c sounds.c \ + sp_lev.c spell.c stairs.c steal.c steed.c strutil.c sys.c \ + teleport.c timeout.c topten.c track.c trap.c u_init.c uhitm.c \ + vault.c version.c vision.c weapon.c were.c wield.c windows.c \ + wizard.c wizcmds.c worm.c worn.c write.c zap.c #-# generated source files (vis_tab.c is gone; tile.c is handled separately #-# via WINxxxSRC) @@ -180,11 +180,11 @@ HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \ fnamesiz.h func_tab.h global.h warnings.h hack.h lint.h mextra.h \ micro.h mkroom.h monattk.h mondata.h monflag.h monst.h monsters.h \ mfndpos.h nhmd4.h obj.h objects.h objclass.h optlist.h patchlevel.h \ - pcconf.h permonst.h prop.h rect.h region.h savefile.h selvar.h sym.h \ - rm.h sp_lev.h spell.h sndprocs.h seffects.h stairs.h sys.h \ - tcap.h timeout.h tradstdc.h trap.h unixconf.h vision.h vmsconf.h \ - wintty.h wincurs.h winX.h winprocs.h wintype.h you.h youprop.h \ - weight.h + pcconf.h permonst.h prop.h rect.h region.h revision.h savefile.h \ + selvar.h sym.h rm.h sp_lev.h spell.h sndprocs.h seffects.h \ + stairs.h sys.h tcap.h timeout.h tradstdc.h trap.h unixconf.h \ + vision.h vmsconf.h wintty.h wincurs.h winX.h winprocs.h wintype.h \ + you.h youprop.h weight.h #HSOURCES = $(HACKINCL) date.h onames.h pm.h @@ -575,6 +575,7 @@ read.obj : read.c $(HACK_H) rect.obj : rect.c $(HACK_H) region.obj : region.c $(HACK_H) restore.obj : restore.c $(HACK_H) $(INC)tcap.h +revision.obj : revision.c $(HACK_H) rip.obj : rip.c $(HACK_H) rnd.obj : rnd.c $(HACK_H) role.obj : role.c $(HACK_H) diff --git a/sys/vms/Makefile.top b/sys/vms/Makefile.top index c12946959..d02dd4016 100644 --- a/sys/vms/Makefile.top +++ b/sys/vms/Makefile.top @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - top level for making & installing everything. -# NetHack 3.7 Makefile.top $NHDT-Date: 1596498303 2020/08/03 23:45:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ +# NetHack 5.0 Makefile.top $NHDT-Date: 1596498303 2020/08/03 23:45:03 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile.utl b/sys/vms/Makefile.utl index 22224c245..a9105ef11 100644 --- a/sys/vms/Makefile.utl +++ b/sys/vms/Makefile.utl @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for utility programs. -# NetHack 3.7 Makefile.utl $NHDT-Date: 1609347482 2020/12/30 16:58:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ +# NetHack 5.0 Makefile.utl $NHDT-Date: 1609347482 2020/12/30 16:58:02 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile_dat.vms b/sys/vms/Makefile_dat.vms index 09979bb63..23c59d41f 100644 --- a/sys/vms/Makefile_dat.vms +++ b/sys/vms/Makefile_dat.vms @@ -1,4 +1,4 @@ -# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.32 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile_doc.vms b/sys/vms/Makefile_doc.vms index 64184d092..762df59d8 100644 --- a/sys/vms/Makefile_doc.vms +++ b/sys/vms/Makefile_doc.vms @@ -1,5 +1,5 @@ # NetHack Documentation Makefile. -# NetHack 3.7 Makefile.doc $NHDT-Date: 1596498290 2020/08/03 23:44:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ +# NetHack 5.0 Makefile.doc $NHDT-Date: 1596498290 2020/08/03 23:44:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/Makefile_src.vms b/sys/vms/Makefile_src.vms index 74f22ea55..31a4963af 100644 --- a/sys/vms/Makefile_src.vms +++ b/sys/vms/Makefile_src.vms @@ -1,4 +1,4 @@ -# NetHack 3.7 Makefile.src $NHDT-Date: 1654287121 2022/06/03 20:12:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ +# NetHack 5.0 Makefile.src $NHDT-Date: 1654287121 2022/06/03 20:12:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.145 $ # Copyright (c) 2024 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -102,7 +102,7 @@ CONFIGBASEH := color config config1 patchlevel tradstdc hacklib integer \ HACKBASEH := hack lint align dungeon wintype sym defsym \ mkroom artilist objclass objects youprop \ prop permonst monattk monflag monsters \ - mondata context rm botl rect region trap \ + mondata context rm botl rect region revision trap \ display vision seffects selvar sndprocs stairs decl \ quest spell obj engrave you attrib monst \ mextra skills timeout flag winprocs sys @@ -800,6 +800,7 @@ $(TARGETPFX)rect.obj: rect.c $(HACK_H) $(TARGETPFX)region.obj: region.c $(HACK_H) $(TARGETPFX)report.obj: report.c $(HACK_H) $(TARGETPFX)restore.obj: restore.c $(HACK_H) $(INCL)tcap.h +$(TARGETPFX)revision.obj: revision.c $(HACK_H) $(TARGETPFX)rip.obj: rip.c $(HACK_H) $(TARGETPFX)rnd.obj: rnd.c $(HACK_H) $(INCL)isaac64.h $(TARGETPFX)role.obj: role.c $(HACK_H) diff --git a/sys/vms/Makefile_top.vms b/sys/vms/Makefile_top.vms index 47028c80d..274f2207e 100644 --- a/sys/vms/Makefile_top.vms +++ b/sys/vms/Makefile_top.vms @@ -1,5 +1,5 @@ # NetHack Top-level Makefile. -# NetHack 3.7 Makefile.vms $NHDT-Date: 1642630921 2022/01/19 22:22:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.72 $ +# NetHack 5.0 Makefile.vms $NHDT-Date: 1642630921 2022/01/19 22:22:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.72 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -21,7 +21,7 @@ NHSROOT=[] # MAKE = make -# NetHack 3.7 Makefile.vms $NHDT-Date: 1654287121 2022/06/03 20:12:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ +# NetHack 5.0 Makefile.vms $NHDT-Date: 1654287121 2022/06/03 20:12:01 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.145 $ # Copyright (c) 2023 by Michael Allison # NetHack may be freely redistributed. See license for details. # diff --git a/sys/vms/Makefile_utl.vms b/sys/vms/Makefile_utl.vms index c17283d13..6d62d51e4 100644 --- a/sys/vms/Makefile_utl.vms +++ b/sys/vms/Makefile_utl.vms @@ -1,12 +1,12 @@ # Makefile for NetHack's utility programs. -# NetHack 3.7 util Makefile.vms $NHDT-Date: 1602258295 2020/10/09 15:44:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ +# NetHack 5.0 util Makefile.vms $NHDT-Date: 1602258295 2020/10/09 15:44:55 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.53 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # Root of source tree relative to here: NHSROOT=[-] -# NetHack 3.7 began introducing C99 code. +# NetHack 5.0 began introducing C99 code. # # If your compiler needs an appropriate switch to accept C99 code. # CSTD = -std=c99 diff --git a/sys/vms/oldcrtl.c b/sys/vms/oldcrtl.c index 2753c7755..1ffb6d210 100644 --- a/sys/vms/oldcrtl.c +++ b/sys/vms/oldcrtl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 oldcrtl.c $NHDT-Date: 1596498304 2020/08/03 23:45:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 oldcrtl.c $NHDT-Date: 1596498304 2020/08/03 23:45:04 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ */ /* Pat Rankin May'90 */ /* VMS NetHack support, not needed for vms 4.6,4.7,5.x,or later */ diff --git a/sys/vms/sysconf b/sys/vms/sysconf index 8fb357e3c..8fe0fb3eb 100644 --- a/sys/vms/sysconf +++ b/sys/vms/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.7 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.7 $ +# NetHack 5.0 sysconf $NHDT-Date: 1704043695 2023/12/31 17:28:15 $ $NHDT-Branch: keni-luabits2 $:$NHDT-Revision: 1.7 $ # Copyright (c) 2015 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # @@ -110,7 +110,7 @@ HIDEUSAGE=1 # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format diff --git a/sys/vms/vmsbuild.com b/sys/vms/vmsbuild.com index 6146cd5f1..971573bd1 100755 --- a/sys/vms/vmsbuild.com +++ b/sys/vms/vmsbuild.com @@ -1,6 +1,6 @@ -$ ! vms/vmsbuild.com -- compile and link NetHack 3.7.* [pr] -$ version_number = "3.7.0" -$ ! $NHDT-Date: 1687541093 2023/06/23 17:24:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ +$ ! vms/vmsbuild.com -- compile and link NetHack 5.0.* [pr] +$ version_number = "5.0.0" +$ ! $NHDT-Date: 1687541093 2023/06/23 17:24:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ $ ! Copyright (c) 2018 by Robert Patrick Rankin $ ! NetHack may be freely redistributed. See license for details. $ ! @@ -10,7 +10,7 @@ $ ! $ @[-.sys.vms]vmsbuild [compiler-option] [link-option] [cc-switches] - $ ! [linker-switches] [interface] $ ! options: $ ! compiler-option : either "VSIC", "VAXC", "DECC", -$ ! "GNUC" or "" or "fetchlua" !default in 3.7 is VSIC +$ ! "GNUC" or "" or "fetchlua" !default in 5.0 is VSIC $ ! link-option : either "SHARE[able]" or "LIB[rary]" !default SHARE $ ! cc-switches : optional qualifiers for CC (such as "/noOpt/Debug") $ ! linker-switches : optional qualifiers for LINK (/Debug or /noTraceback) @@ -291,7 +291,7 @@ $ if f$search("[-.include]nhlua.h").nes."" then - $ milestone " (wiped existing [-.include]nhlua.h)" $ exit $! -$! 3.7 runtime LUA level parser/loader +$! 5.0 runtime LUA level parser/loader $! $buildlua: $ if f$search("[-.lib]lua.dir;").eqs."" then - @@ -406,7 +406,7 @@ $ gosub compile_list $ link makedefs.obj,[-.src]panic.obj,'nethacklib'/Lib,[-.src]ident.opt/Opt,[-.src]crtl/Opt $ milestone "makedefs" $! create some build-time files -$! 3.7 does not require these +$! 5.0 does not require these $! makedefs -p !pm.h $! makedefs -o !onames.h $! makedefs -v !date.h @@ -431,7 +431,7 @@ $ c_list = "hack,hacklib,iactions,insight,invent,light,lock,mail,makemon" - + ",music" $ gosub compile_list $! -$! Files added in 3.7 for Lua glue +$! Files added in 5.0 for Lua glue $! $ c_list = "nhlua,nhlobj,nhlsel" $ gosub compile_list diff --git a/sys/vms/vmsfiles.c b/sys/vms/vmsfiles.c index 38a80b9a8..cc05e1030 100644 --- a/sys/vms/vmsfiles.c +++ b/sys/vms/vmsfiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsfiles.c $NHDT-Date: 1685522046 2023/05/31 08:34:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ */ +/* NetHack 5.0 vmsfiles.c $NHDT-Date: 1685522046 2023/05/31 08:34:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2007. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsmail.c b/sys/vms/vmsmail.c index 24f9ad5fa..87685fd7e 100644 --- a/sys/vms/vmsmail.c +++ b/sys/vms/vmsmail.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsmail.c $NHDT-Date: 1685522048 2023/05/31 08:34:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 vmsmail.c $NHDT-Date: 1685522048 2023/05/31 08:34:08 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) Robert Patrick Rankin, 1991. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index f540d3190..23d80025f 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsmain.c $NHDT-Date: 1693359633 2023/08/30 01:40:33 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.57 $ */ +/* NetHack 5.0 vmsmain.c $NHDT-Date: 1693359633 2023/08/30 01:40:33 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.57 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -513,4 +513,28 @@ sys_random_seed(void) return seed; } +void +get_nhuuid(void) +{ + unsigned char stmp[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + if (svn.nhuuid[0]) + return; + + /* FIXME: fill in a useful valie UUID somehow */ + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + /*vmsmain.c*/ diff --git a/sys/vms/vmsmisc.c b/sys/vms/vmsmisc.c index fa705161c..83210662a 100644 --- a/sys/vms/vmsmisc.c +++ b/sys/vms/vmsmisc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsmisc.c $NHDT-Date: 1685522049 2023/05/31 08:34:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 5.0 vmsmisc.c $NHDT-Date: 1685522049 2023/05/31 08:34:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) 2011 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmssetup.com b/sys/vms/vmssetup.com index b841bb882..3f3a3764b 100644 --- a/sys/vms/vmssetup.com +++ b/sys/vms/vmssetup.com @@ -1,6 +1,6 @@ $ ! vmssetup.com -- place GNU Makefiles in their target directories -$ version_number = "3.7.0" -$ ! $NHDT-Date: 1687541093 2024/03/08 17:24:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ +$ version_number = "5.0.0" +$ ! $NHDT-Date: 1687541093 2024/03/08 17:24:53 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ $ ! NetHack may be freely redistributed. See license for details. $ ! $ relsrc = "" diff --git a/sys/vms/vmstty.c b/sys/vms/vmstty.c index 9b0051c0a..8d9b5bf74 100644 --- a/sys/vms/vmstty.c +++ b/sys/vms/vmstty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmstty.c $NHDT-Date: 1596498309 2020/08/03 23:45:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 vmstty.c $NHDT-Date: 1596498309 2020/08/03 23:45:09 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/vms/vmsunix.c b/sys/vms/vmsunix.c index 89b18a174..c44819092 100644 --- a/sys/vms/vmsunix.c +++ b/sys/vms/vmsunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsunix.c $NHDT-Date: 1685522050 2023/05/31 08:34:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 vmsunix.c $NHDT-Date: 1685522050 2023/05/31 08:34:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/GNUmakefile b/sys/windows/GNUmakefile index 4bc3df970..43de44671 100644 --- a/sys/windows/GNUmakefile +++ b/sys/windows/GNUmakefile @@ -1,4 +1,4 @@ -# NetHack 3.7 GNUmakefile +# NetHack 5.0 GNUmakefile # Copyright (c) 2022 by Feiyun Wang #-Copyright (c) 2022 by Michael Allison # NetHack may be freely redistributed. See license for details. @@ -172,7 +172,7 @@ $(info GIT=1) $(info or modify your Makefile to set the following:) $(info INTERNET_AVAILABLE=Y) $(info GIT_AVAILABLE=Y) -$(error Stopping because NetHack 3.7 requires Lua for its build.) +$(error Stopping because NetHack 5.0 requires Lua for its build.) endif # LUA_MAY_PROCEED # Now, pdcurses @@ -206,7 +206,7 @@ endif # ADD_CURSES == Y endif # INTERNET_AVAILABLE ifneq "$(ADD_CURSES)" "Y" -$(info NetHack 3.7 will be built without support for the curses window-port.) +$(info NetHack 5.0 will be built without support for the curses window-port.) endif ifeq "$(INTERNET_AVAILABLE)" "Y" @@ -229,7 +229,7 @@ endif #============================================================================== # The version of the game this Makefile was designed for -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" # A brief version for use in macros NHV1=$(subst .,,$(NETHACK_VERSION)) @@ -357,7 +357,7 @@ endif ifeq "$(GCC_EXTRA_WARNINGS)" "Y" # -# These match the warnings enabled on the linux.370 and macOS.370 hints builds +# These match the warnings enabled on the linux.500 and macOS.500 hints builds # CFLAGSXTRA = -Wall -Wextra -Wreturn-type -Wunused -Wswitch -Wshadow \ -Wwrite-strings -pedantic -Wmissing-declarations \ @@ -800,8 +800,8 @@ HACK_H = $(CONFIG_H) ../include/align.h ../include/artilist.h \ ../include/nhlua.h ../include/obj.h ../include/objclass.h \ ../include/objects.h ../include/permonst.h ../include/prop.h \ ../include/quest.h ../include/rect.h ../include/region.h \ - ../include/rm.h ../include/savefile.h ../include/sfprocs.h \ - ../include/seffects.h ../include/selvar.h \ + ../include/revision.h ../include/rm.h ../include/savefile.h \ + ../include/sfprocs.h ../include/seffects.h ../include/selvar.h \ ../include/skills.h ../include/sndprocs.h ../include/spell.h \ ../include/stairs.h ../include/sym.h ../include/sys.h \ ../include/timeout.h ../include/trap.h ../include/vision.h \ @@ -1238,7 +1238,7 @@ COREOBJS = $(addsuffix .o, allmain alloc apply artifact attrib ball bones botl \ mon mondata monmove monst mplayer mthrowu muse music \ nhlobj nhlsel nhlua windsound o_init objects objnam options \ pager pickup pline polyself potion pray priest quest questpgr \ - random read rect region report restore rip rnd role rumors \ + random read rect region report restore revision rip rnd role rumors \ save sfbase sfstruct shk shknam sit selvar sounds sp_lev \ spell stairs steal steed strutil \ symbols sys teleport timeout topten track trap u_init uhitm utf8map \ @@ -1282,13 +1282,13 @@ $(GAMEDIR)/NetHackW.exe: $(NHWOBJS) $(NHWRES) $(DATEW_O) \ $(ONHW)/%.o: $(SRC)/%.c $(NHLUAH) | $(ONHW) $(cc) $(CFLAGSW) $< -o$@ -# In NetHack 3.7, date.c must be recompiled after any other file is compiled, +# In NetHack 5.0, date.c must be recompiled after any other file is compiled, # otherwise the game internal build timestamp (and potentially git hash) # will not be accurate. # Therefore, date must not be included in COREOBJS (and by extension # NHWOBJS, NHWONLY). That allows those to be listed as explicit dependencies # to ensure that date.c is always recompiled again after anything else that -# was just recompiled. date.h is not used in the build of NetHack 3.7. +# was just recompiled. date.h is not used in the build of NetHack 5.0. # $(ONHW)/date.o: $(SRC)/date.c $(NHWOBJS) | $(ONHW) $(cc) $(CFLAGSW) $(GITHASH) $(GITBRANCH) $(GITPREFIX) $< -o$@ @@ -1388,9 +1388,8 @@ TARGET_CPU = x86 endif endif -NHV=370 PKGFILES = nethackrc.template Guidebook.txt license NetHack.exe NetHack.txt \ - NetHackW.exe opthelp nhdat370 record symbols sysconf.template $(notdir $(LUADLL)) + NetHackW.exe opthelp nhdat$(NHV) record symbols sysconf.template $(notdir $(LUADLL)) FILESTOZIP = $(addprefix $(GAMEDIR)/, $(PKGFILES)) MAINZIP = $(PkgDir)/nethack-$(NHV)-win-$(TARGET_CPU)-msys2.zip @@ -1408,13 +1407,13 @@ $(PkgDir): CLEAN_DIR += $(PkgDir) CLEAN_FILE += $(MAINZIP) -# In NetHack 3.7, date.c must be recompiled after any other file is compiled, +# In NetHack 5.0, date.c must be recompiled after any other file is compiled, # otherwise the game internal build timestamp (and potentially git hash) # will not be accurate. # Therefore, date must not be included in COREOBJS (and by extension # NHOBJS). That allows those to be listed as explicit dependencies of date.o # to ensure that date.c is always recompiled again after anything else that -# was just recompiled. date.h is not used in the build of NetHack 3.7. +# was just recompiled. date.h is not used in the build of NetHack 5.0. # $(ONH)/date.o: $(SRC)/date.c $(NHOBJS) $(NHRES) | $(ONH) $(cc) $(CFLAGSNH) $(GITHASH) $(GITBRANCH) $(GITPREFIX) $< -o$@ diff --git a/sys/windows/Install.windows b/sys/windows/Install.windows index 3b677e464..cff81c687 100644 --- a/sys/windows/Install.windows +++ b/sys/windows/Install.windows @@ -1,10 +1,10 @@ Copyright (c) NetHack Development Team 1990-2024 NetHack may be freely redistributed. See license for details. ============================================================== - Instructions for compiling NetHack 3.7 on a Windows system + Instructions for compiling NetHack 5.0 on a Windows system (only tested on Windows 10/11 or later) ============================================================== -Last revision: $NHDT-Date: 1594155895 2020/07/07 21:04:55 $ +Last revision: $NHDT-Date: 1782065703 2026/06/21 18:15:03 $ See file dat\History for credits and history of NetHack for Windows. @@ -12,8 +12,9 @@ See file dat\History for credits and history of NetHack for Windows. | Download a prebuilt package of NetHack for Windows from NetHack.org | \----------------------------------------------------------- -----------/ - FIXME: - + In your web browser, navigate to + https://www.nethack.org/v500/ports/download-win.html + and follow the instructions there. /-----------------------------------------------------------------------\ | Build and package NetHack for Windows yourself | diff --git a/sys/windows/Makefile.nmake b/sys/windows/Makefile.nmake index f4be7a51c..a49ba992f 100644 --- a/sys/windows/Makefile.nmake +++ b/sys/windows/Makefile.nmake @@ -1,15 +1,15 @@ -# NetHack 3.7 Makefile.nmake +# NetHack 5.0 Makefile.nmake # Copyright (c) NetHack Development Team 1993-2026 # #============================================================================== # Build Tools Environment # -# NetHack 3.7 Work-in-progress Makefile for +# NetHack 5.0 Work-in-progress Makefile for # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: -# - Microsoft Visual Studio Community 2022 v 17.14.30 -# - Microsoft Visual Studio Community 2026 v 18.5.0 +# - Microsoft Visual Studio Community 2022 v 17.14.40 +# - Microsoft Visual Studio Community 2026 v 18.10.0 # #============================================================================== # This is used for building two distinct executables of NetHack: @@ -54,27 +54,30 @@ SOUND_LIBRARIES = windsound #------------------------------------------------------------------------------ # Curses options. # + +WANT_CURSES=Y + # Do you want console curses included? -CURSES_CONSOLE = Y +CURSES_CONSOLE=Y # Do you want graphical curses included? -CURSES_GRAPHICAL = Y +CURSES_GRAPHICAL=Y # #------------------------------------------------------------------------------ # Do you want debug information available to the executable? # -DEBUGINFO = Y +DEBUGINFO=Y # #------------------------------------------------------------------------------ # Do you want to include the address sanitizer? # -#WANT_ASAN = Y +#WANT_ASAN=Y #------------------------------------------------------------------------------ # Do you have a connection to the internet available that you want @@ -82,13 +85,13 @@ DEBUGINFO = Y # pdcursesmod source code? # Default is now Y. Set it to N if that won't work for you. -INTERNET_AVAILABLE = Y +INTERNET_AVAILABLE=1 #------------------------------------------------------------------------------ # # Do you have git commands available and NetHack in a git repository? -GIT_AVAILABLE = N +GIT_AVAILABLE=1 # If not, because you obtained the NetHack sources in a zip file download, # set GIT_AVAILABLE = N @@ -147,18 +150,30 @@ LUAVER=$(LUA_VERSION) # if GIT=1 is passed on the make command, allow use of git and internet !IF "$(GIT)" == "1" -INTERNET_AVAILABLE=Y -GIT_AVAILABLE=Y +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 !ENDIF !IF "$(git)" == "1" -INTERNET_AVAILABLE=Y -GIT_AVAILABLE=Y +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 +!ENDIF +!IF "$(GIT)" == "Y" +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 +!ENDIF +!IF "$(git)" == "y" +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 +!ENDIF +!IF "$(git)" == "Y" +INTERNET_AVAILABLE=1 +GIT_AVAILABLE=1 !ENDIF #============================================================================== # # The version of the game this Makefile was designed for -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" # A brief version for use in macros NHV=$(NETHACK_VERSION:.=) @@ -252,8 +267,8 @@ LUA_MAY_PROCEED=N ADD_CURSES=N # First, Lua -!IF "$(INTERNET_AVAILABLE)" == "Y" -!IF "$(GIT_AVAILABLE)" == "Y" +!IF "$(INTERNET_AVAILABLE)" == "1" +!IF "$(GIT_AVAILABLE)" == "1" R_LUATOP=$(SUBM)lua LUATOP=$(SUBM)lua$(BACKSLASH) R_LUASRC=$(R_LUATOP) @@ -302,16 +317,16 @@ LUA_MAY_PROCEED=Y #!MESSAGE LUASRC=$(LUASRC) !IF "$(LUA_MAY_PROCEED)" != "Y" -!IF "$(INTERNET_AVAILABLE)" != "Y" +!IF "$(INTERNET_AVAILABLE)" != "1" !MESSAGE Your Makefile settings do not allow use of the internet to obtain Lua !ENDIF # INTERNET_AVAILABLE !MESSAGE and no copy of Lua was found in either $(SUBM)lua or $(LIBDIR)lua-$(LUAVER). !MESSAGE Change your nmake command line to include: !MESSAGE GIT=1 !MESSAGE or modify your Makefile to set the following: -!MESSAGE INTERNET_AVAILABLE=Y -!MESSAGE GIT_AVAILABLE=Y -!ERROR Stopping because NetHack 3.7 requires Lua for its build. +!MESSAGE INTERNET_AVAILABLE=1 +!MESSAGE GIT_AVAILABLE=1 +!ERROR Stopping because NetHack 5.0 requires Lua for its build. !ENDIF # LUA_MAY_PROCEED # Now, pdcursesmod @@ -334,8 +349,8 @@ ADD_CURSES=N R_PDCDIST=pdcursesmod PDCDIST=$(R_PDCDIST)$(BACKSLASH) #U_PDCDIST=$(PDCDIST:\=/) -! IF "$(INTERNET_AVAILABLE)" == "Y" -! IF "$(GIT_AVAILABLE)" == "Y" +! IF "$(INTERNET_AVAILABLE)" == "1" +! IF "$(GIT_AVAILABLE)" == "1" #!MESSAGE debug spot1 R_PDCURSES_TOP=$(SUBM)$(R_PDCDIST) PDCURSES_TOP=$(R_PDCURSES_TOP)$(BACKSLASH) @@ -349,7 +364,7 @@ PDCURSES_TOP=$(R_PDCURSES_TOP)$(BACKSLASH) ADD_CURSES=Y ! ENDIF # GIT_AVAILABLE ! ELSE # NO internet available -# Your Makefile settings do not allow $(PDCDIST) to be obtained by +# Your Makefile settings do not allow $(R_PDCDIST) to be obtained by # git or by download. Check to see if it is available at one of # the expected locations already, with precedence given to ../submodules, # then ../lib. @@ -385,7 +400,7 @@ ADD_CURSES = N !ENDIF # WANT_CURSES !IF "$(ADD_CURSES)" != "Y" -!MESSAGE NetHack 3.7 will be built without support for the curses window-port. +!MESSAGE NetHack 5.0 will be built without support for the curses window-port. !ENDIF #These will be in the environment variables with one of the Visual Studio @@ -548,8 +563,8 @@ GITPREFIX = -DNETHACK_GIT_PREFIX=\"$(GIT_PREFIX)\" # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere # you'll need to specify the correct spot below in order to -# successfully build NetHack-3.7. You cannot build a functional -# version of NetHack-3.7 Work-in-progress without including Lua. +# successfully build NetHack-5.0. You cannot build a functional +# version of NetHack-5.0 Work-in-progress without including Lua. # !IFNDEF LUAVER @@ -671,17 +686,17 @@ HACKCSRC = \ $(SRC)objnam.c $(SRC)options.c $(SRC)pager.c $(SRC)pickup.c \ $(SRC)pline.c $(SRC)polyself.c $(SRC)potion.c $(SRC)pray.c \ $(SRC)priest.c $(SRC)quest.c $(SRC)questpgr.c $(SRC)read.c \ - $(SRC)rect.c $(SRC)region.c $(SRC)restore.c $(SRC)rip.c \ - $(SRC)rnd.c $(SRC)role.c $(SRC)rumors.c $(SRC)save.c \ - $(SRC)selvar.c $(SRC)sfbase.c $(SRC)sfstruct.c $(SRC)shk.c \ - $(SRC)shknam.c $(SRC)sit.c $(SRC)sounds.c $(SRC)sp_lev.c \ - $(SRC)spell.c $(SRC)stairs.c $(SRC)steal.c $(SRC)steed.c \ - $(SRC)symbols.c $(SRC)sys.c $(SRC)teleport.c $(SRC)timeout.c \ - $(SRC)topten.c $(SRC)track.c $(SRC)trap.c $(SRC)u_init.c \ - $(SRC)uhitm.c $(SRC)utf8map.c $(SRC)vault.c $(SRC)version.c \ - $(SRC)vision.c $(SRC)weapon.c $(SRC)were.c $(SRC)wield.c \ - $(SRC)windows.c $(SRC)wizard.c $(SRC)worm.c $(SRC)worn.c \ - $(SRC)write.c $(SRC)zap.c + $(SRC)rect.c $(SRC)region.c $(SRC)restore.c $(SRC)revision.c \ + $(SRC)rip.c $(SRC)rnd.c $(SRC)role.c $(SRC)rumors.c \ + $(SRC)save.c $(SRC)selvar.c $(SRC)sfbase.c $(SRC)sfstruct.c \ + $(SRC)shk.c $(SRC)shknam.c $(SRC)sit.c $(SRC)sounds.c \ + $(SRC)sp_lev.c $(SRC)spell.c $(SRC)stairs.c $(SRC)steal.c \ + $(SRC)steed.c $(SRC)symbols.c $(SRC)sys.c $(SRC)teleport.c \ + $(SRC)timeout.c $(SRC)topten.c $(SRC)track.c $(SRC)trap.c \ + $(SRC)u_init.c $(SRC)uhitm.c $(SRC)utf8map.c $(SRC)vault.c \ + $(SRC)version.c $(SRC)vision.c $(SRC)weapon.c $(SRC)were.c \ + $(SRC)wield.c $(SRC)windows.c $(SRC)wizard.c $(SRC)worm.c \ + $(SRC)worn.c $(SRC)write.c $(SRC)zap.c # all .h files except date.h HACKINCL = \ @@ -700,15 +715,16 @@ HACKINCL = \ $(INCL)obj.h $(INCL)objects.h $(INCL)objclass.h \ $(INCL)optlist.h $(INCL)patchlevel.h $(INCL)pcconf.h \ $(INCL)permonst.h $(INCL)prop.h $(INCL)rect.h \ - $(INCL)region.h $(INCL)savefile.h $(INCL)selvar.h \ - $(INCL)sfprocs.h $(INCL)sym.h $(INCL)rm.h \ - $(INCL)sp_lev.h $(INCL)spell.h $(INCL)sndprocs.h \ - $(INCL)seffects.h $(INCL)stairs.h $(INCL)sys.h \ - $(INCL)tcap.h $(INCL)timeout.h $(INCL)tradstdc.h \ - $(INCL)trap.h $(INCL)unixconf.h $(INCL)vision.h \ - $(INCL)vmsconf.h $(INCL)wintty.h $(INCL)wincurs.h \ - $(INCL)winX.h $(INCL)winprocs.h $(INCL)wintype.h \ - $(INCL)you.h $(INCL)youprop.h $(INCL)weight.h + $(INCL)region.h $(INCL)revision.h $(INCL)savefile.h \ + $(INCL)selvar.h $(INCL)sfprocs.h $(INCL)sym.h \ + $(INCL)rm.h $(INCL)sp_lev.h $(INCL)spell.h \ + $(INCL)sndprocs.h $(INCL)seffects.h $(INCL)stairs.h \ + $(INCL)sys.h $(INCL)tcap.h $(INCL)timeout.h \ + $(INCL)tradstdc.h $(INCL)trap.h $(INCL)unixconf.h \ + $(INCL)vision.h $(INCL)vmsconf.h $(INCL)wintty.h \ + $(INCL)wincurs.h $(INCL)winX.h $(INCL)winprocs.h \ + $(INCL)wintype.h $(INCL)you.h $(INCL)youprop.h \ + $(INCL)weight.h LUA_FILES = $(DAT)asmodeus.lua $(DAT)baalz.lua $(DAT)bigrm-1.lua \ $(DAT)bigrm-10.lua $(DAT)bigrm-11.lua $(DAT)bigrm-12.lua \ @@ -778,7 +794,7 @@ RECOVOBJS = $(OUTL)recover.o TILEFILES = $(WSHR)monsters.txt $(WSHR)objects.txt $(WSHR)other.txt # -# These are not invoked during a normal game build in 3.7 +# These are not invoked during a normal game build in 5.0 # TEXT_IO = $(OUTL)tiletext.o $(OUTL)tiletxt.o $(OUTL)drawing$(HOST).o \ @@ -873,17 +889,17 @@ COREOBJTTY = \ $(OTTY)pickup.o $(OTTY)pline.o $(OTTY)polyself.o $(OTTY)potion.o \ $(OTTY)pray.o $(OTTY)priest.o $(OTTY)quest.o $(OTTY)questpgr.o \ $(OTTY)read.o $(OTTY)rect.o $(OTTY)region.o $(OTTY)report.o \ - $(OTTY)restore.o $(OTTY)rip.o $(OTTY)rnd.o $(OTTY)role.o \ - $(OTTY)rumors.o $(OTTY)save.o $(OTTY)selvar.o $(OTTY)sfbase.o \ - $(OTTY)sfstruct.o $(OTTY)shk.o $(OTTY)shknam.o $(OTTY)sit.o \ - $(OTTY)sounds.o $(OTTY)sp_lev.o $(OTTY)spell.o $(OTTY)stairs.o \ - $(OTTY)steal.o $(OTTY)steed.o $(OTTY)strutil.o $(OTTY)symbols.o \ - $(OTTY)sys.o $(OTTY)teleport.o $(OTTY)timeout.o $(OTTY)topten.o \ - $(OTTY)track.o $(OTTY)trap.o $(OTTY)u_init.o $(OTTY)uhitm.o \ - $(OTTY)utf8map.o $(OTTY)vault.o $(OTTY)vision.o $(OTTY)weapon.o \ - $(OTTY)were.o $(OTTY)wield.o $(OTTY)windows.o $(OTTY)wizard.o \ - $(OTTY)wizcmds.o $(OTTY)worm.o $(OTTY)worn.o $(OTTY)write.o \ - $(OTTY)zap.o + $(OTTY)restore.o $(OTTY)revision.o $(OTTY)rip.o $(OTTY)rnd.o \ + $(OTTY)role.o $(OTTY)rumors.o $(OTTY)save.o $(OTTY)selvar.o \ + $(OTTY)sfbase.o $(OTTY)sfstruct.o $(OTTY)shk.o $(OTTY)shknam.o \ + $(OTTY)sit.o $(OTTY)sounds.o $(OTTY)sp_lev.o $(OTTY)spell.o \ + $(OTTY)stairs.o $(OTTY)steal.o $(OTTY)steed.o $(OTTY)strutil.o \ + $(OTTY)symbols.o $(OTTY)sys.o $(OTTY)teleport.o $(OTTY)timeout.o \ + $(OTTY)topten.o $(OTTY)track.o $(OTTY)trap.o $(OTTY)u_init.o \ + $(OTTY)uhitm.o $(OTTY)utf8map.o $(OTTY)vault.o $(OTTY)vision.o \ + $(OTTY)weapon.o $(OTTY)were.o $(OTTY)wield.o $(OTTY)windows.o \ + $(OTTY)wizard.o $(OTTY)wizcmds.o $(OTTY)worm.o $(OTTY)worn.o \ + $(OTTY)write.o $(OTTY)zap.o OBJSTTY = $(MDLIBTTY) $(COREOBJTTY) $(REGEXTTY) $(RANDOMTTY) @@ -936,17 +952,17 @@ COREOBJGUI = \ $(OGUI)pickup.o $(OGUI)pline.o $(OGUI)polyself.o $(OGUI)potion.o \ $(OGUI)pray.o $(OGUI)priest.o $(OGUI)quest.o $(OGUI)questpgr.o \ $(OGUI)read.o $(OGUI)rect.o $(OGUI)region.o $(OGUI)report.o \ - $(OGUI)restore.o $(OGUI)rip.o $(OGUI)rnd.o $(OGUI)role.o \ - $(OGUI)rumors.o $(OGUI)save.o $(OGUI)selvar.o $(OGUI)sfbase.o \ - $(OGUI)sfstruct.o $(OGUI)shk.o $(OGUI)shknam.o $(OGUI)sit.o \ - $(OGUI)sounds.o $(OGUI)sp_lev.o $(OGUI)spell.o $(OGUI)stairs.o \ - $(OGUI)steal.o $(OGUI)steed.o $(OGUI)strutil.o $(OGUI)symbols.o \ - $(OGUI)sys.o $(OGUI)teleport.o $(OGUI)timeout.o $(OGUI)topten.o \ - $(OGUI)track.o $(OGUI)trap.o $(OGUI)u_init.o $(OGUI)uhitm.o \ - $(OGUI)utf8map.o $(OGUI)vault.o $(OGUI)vision.o $(OGUI)weapon.o \ - $(OGUI)were.o $(OGUI)wield.o $(OGUI)windows.o $(OGUI)wizard.o \ - $(OGUI)wizcmds.o $(OGUI)worm.o $(OGUI)worn.o $(OGUI)write.o \ - $(OGUI)zap.o + $(OGUI)restore.o $(OGUI)revision.o $(OGUI)rip.o $(OGUI)rnd.o \ + $(OGUI)role.o $(OGUI)rumors.o $(OGUI)save.o $(OGUI)selvar.o \ + $(OGUI)sfbase.o $(OGUI)sfstruct.o $(OGUI)shk.o $(OGUI)shknam.o \ + $(OGUI)sit.o $(OGUI)sounds.o $(OGUI)sp_lev.o $(OGUI)spell.o \ + $(OGUI)stairs.o $(OGUI)steal.o $(OGUI)steed.o $(OGUI)strutil.o \ + $(OGUI)symbols.o $(OGUI)sys.o $(OGUI)teleport.o $(OGUI)timeout.o \ + $(OGUI)topten.o $(OGUI)track.o $(OGUI)trap.o $(OGUI)u_init.o \ + $(OGUI)uhitm.o $(OGUI)utf8map.o $(OGUI)vault.o $(OGUI)vision.o \ + $(OGUI)weapon.o $(OGUI)were.o $(OGUI)wield.o $(OGUI)windows.o \ + $(OGUI)wizard.o $(OGUI)wizcmds.o $(OGUI)worm.o $(OGUI)worn.o \ + $(OGUI)write.o $(OGUI)zap.o OBJSGUI = $(MDLIBGUI) $(COREOBJGUI) $(REGEXGUI) $(RANDOMGUI) @@ -1187,8 +1203,8 @@ rc=Rc.exe # is too old or untested. # # Recently tested versions: -TESTEDVS2022 = 14.44.35225.0 -TESTEDVS2026 = 14.50.35729.0 +TESTEDVS2022 = 14.44.35228.0 +TESTEDVS2026 = 14.51.36257.0 VS20261ST = 1450000000 VS2026CUR = $(TESTEDVS2026:.=) @@ -1591,8 +1607,8 @@ DLB = all : package -!IF "$(INTERNET_AVAILABLE)" == "Y" -!IF "$(GIT_AVAILABLE)" == "Y" +!IF "$(INTERNET_AVAILABLE)" == "1" +!IF "$(GIT_AVAILABLE)" == "1" $(LUASRC)lua.h: git submodule init $(SUBM)lua git submodule update $(SUBM)lua @@ -1827,7 +1843,7 @@ $(OUTL)makedefs.o: $(U)makedefs.c $(SRC)mdlib.c $(CONFIG_H) $(INCL)permonst.h \ # # This is awful, but it allows the GITHASH, GITBRANCH and GITPREFIX macros to be -# defined and utilized, using only build-in Windows and nmake commands, +# defined and utilized, using only built-in Windows and nmake commands, # as well as the necessary git commands. # # We build a temporary Makefile on-the-fly for compiling date.c and @@ -1837,44 +1853,42 @@ $(OTTY)date.o: $(HACKINCL) $(HACKSRC) $(HACKOBJ) $(ALLOBJTTY) $(CURSESOBJ) !IF "$(GIT_AVAILABLE)" == "1" @git rev-parse --verify HEAD 2>&1 >$(OTTY)date1.tmp @git rev-parse --abbrev-ref HEAD 2>&1 >$(OTTY)date2.tmp - @git config nethack.substprefix 2>&1 >$(OTTY)date3.tmp - @echo.>date.nmk - @echo OBJ = $(OBJTTY)>>date.nmk - @echo O = ^$(OBJTTY)^^^\>>date.nmk - @echo cc = $(cc)>>date.nmk - @echo CFLAGS = $(CFLAGS) ^\>>date.nmk - @for /F "usebackq" %%A IN ("$(OTTY)date1.tmp") DO @echo. -DNETHACK_GIT_SHA=\"%%A\" ^\>>date.nmk - @for /F "usebackq" %%A IN ("$(OTTY)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\">>date.nmk - @for /F "usebackq" %%A IN ("$(OTTY)date3.tmp") DO @echo. -DNETHACK_GIT_PREFIX=\"%%A\">>date.nmk - @echo.>>date.nmk - @echo default: ^$(OTTY)date.o>>date.nmk - @echo.>>date.nmk - @echo ^$(OTTY)date.o: >>date.nmk - @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date.nmk - @echo.>>date.nmk - @$(MAKE) /NOLOGO /A -f date.nmk +# @git config nethack.substprefix 2>&1 >$(OTTY)date3.tmp + @echo.>date-tty.nmk + @echo cc = $(cc)>>date-tty.nmk + @echo CFLAGS = $(CFLAGS) ^\>>date-tty.nmk + @for /F "usebackq" %%A IN ("$(OTTY)date1.tmp") DO @echo. -DNETHACK_GIT_SHA=\"%%A\" ^\>>date-tty.nmk + @for /F "usebackq" %%A IN ("$(OTTY)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\">>date-tty.nmk +# @for /F "usebackq" %%A IN ("$(OTTY)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\" ^\>>date-tty.nmk +# @for /F "usebackq" %%A IN ("$(OTTY)date3.tmp") DO @echo. -DNETHACK_GIT_PREFIX=\"%%A\">>date-tty.nmk + @echo.>>date-tty.nmk + @echo default: ^$(OTTY)date.o>>date-tty.nmk + @echo.>>date-tty.nmk + @echo ^$(OTTY)date.o: >>date-tty.nmk + @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date-tty.nmk + @echo.>>date-tty.nmk + @$(MAKE) /NOLOGO /A OTTY=$(OTTY) -f date-tty.nmk !ENDIF $(OGUI)date.o: $(HACKINCL) $(HACKSRC) $(HACKOBJ) $(ALLOBJGUI) !IF "$(GIT_AVAILABLE)" == "1" @git rev-parse --verify HEAD 2>&1 >$(OGUI)date1.tmp @git rev-parse --abbrev-ref HEAD 2>&1 >$(OGUI)date2.tmp - @git config nethack.substprefix 2>&1 >$(OTTY)date3.tmp - @echo.>date.nmk - @echo OBJ = $(OBJGUI)>>date.nmk - @echo O = ^$(OBJGUI)^^^\>>date.nmk - @echo cc = $(cc)>>date.nmk - @echo CFLAGS = $(CFLAGS) ^\>>date.nmk - @for /F "usebackq" %%A IN ("$(OGUI)date1.tmp") DO @echo. -DNETHACK_GIT_SHA=\"%%A\" ^\>>date.nmk - @for /F "usebackq" %%A IN ("$(OGUI)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\">>date.nmk - @for /F "usebackq" %%A IN ("$(OTTY)date3.tmp") DO @echo. -DNETHACK_GIT_PREFIX=\"%%A\">>date.nmk - @echo.>>date.nmk - @echo default: ^$(OGUI)date.o>>date.nmk - @echo.>>date.nmk - @echo ^$(OGUI)date.o: >>date.nmk - @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date.nmk - @echo.>>date.nmk - @$(MAKE) /NOLOGO /A -f date.nmk +# @git config nethack.substprefix 2>&1 >$(OGUI)date3.tmp + @echo.>date-gui.nmk + @echo cc = $(cc)>>date-gui.nmk + @echo CFLAGS = $(CFLAGS) ^\>>date-gui.nmk + @for /F "usebackq" %%A IN ("$(OGUI)date1.tmp") DO @echo. -DNETHACK_GIT_SHA=\"%%A\" ^\>>date-gui.nmk + @for /F "usebackq" %%A IN ("$(OGUI)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\">>date-gui.nmk +# @for /F "usebackq" %%A IN ("$(OGUI)date2.tmp") DO @echo. -DNETHACK_GIT_BRANCH=\"%%A\" ^\>>date-gui.nmk +# @for /F "usebackq" %%A IN ("$(OGUI)date3.tmp") DO @echo. -DNETHACK_GIT_PREFIX=\"%%A\">>date-gui.nmk + @echo.>>date-gui.nmk + @echo default: ^$(OGUI)date.o>>date-gui.nmk + @echo.>>date-gui.nmk + @echo ^$(OGUI)date.o: >>date-gui.nmk + @echo. ^$(cc) ^$(CFLAGS) -Fo^$@ date.c>>date-gui.nmk + @echo.>>date-gui.nmk + @$(MAKE) /NOLOGO /A OGUI=$(OGUI) -f date-gui.nmk !ENDIF $(OGUI)sfbase.o: sfbase.c $(HACK_H) $(INCL)sfmacros.h @@ -1886,9 +1900,9 @@ $(OTTY)sfbase.o: sfbase.c $(HACK_H) $(INCL)sfmacros.h $(Q)$(CC) $(CFLAGS) -Fo$@ $(@B).c # -# date.h is not used with NetHack 3.7 -# onames.h is not used with NetHack 3.7 -# pm.h is not used with NetHack 3.7 +# date.h is not used with NetHack 5.0 +# onames.h is not used with NetHack 5.0 +# pm.h is not used with NetHack 5.0 $(INCL)date.h $(OPTIONS_FILE) : $(U)makedefs.exe $(U)makedefs -v @@ -2785,11 +2799,11 @@ $(SndWavDir)sa2_xplevelup.wav: $(SndWavDir)sa2_xplevelup.uu $(U)uudecode.exe #=============================================================================== PKGFILES = nethackrc.template Guidebook.txt license NetHack.exe NetHack.txt \ - NetHackW.exe opthelp nhdat370 record symbols \ + NetHackW.exe opthelp nhdat$(NHV) record symbols \ sysconf.template $(SFCTOOLBASENAM) FILESTOZIP = $(BinDir)nethackrc.template $(BinDir)Guidebook.txt $(BinDir)license \ $(BinDir)NetHack.exe $(BinDir)NetHack.txt $(BinDir)NetHackW.exe \ - $(BinDir)opthelp $(BinDir)nhdat370 $(BinDir)record \ + $(BinDir)opthelp $(BinDir)nhdat$(NHV) $(BinDir)record \ $(BinDir)symbols $(BinDir)sysconf.template $(SFCTOOLPKG) DBGSYMS = NetHack.PDB NetHackW.PDB $(SFCTOOLPDBNAM) @@ -3328,6 +3342,7 @@ $(OTTY)rect.o: rect.c $(HACK_H) $(OTTY)region.o: region.c $(HACK_H) $(OTTY)report.o: report.c $(HACK_H) $(INCL)dlb.h $(INCL)nhmd4.h $(OTTY)restore.o: restore.c $(HACK_H) $(INCL)tcap.h +$(OTTY)revision.o: revision.c $(HACK_H) $(OTTY)rip.o: rip.c $(HACK_H) $(OTTY)rnd.o: rnd.c $(HACK_H) $(INCL)isaac64.h $(OTTY)role.o: role.c $(HACK_H) @@ -3708,6 +3723,7 @@ $(OGUI)rect.o: rect.c $(HACK_H) $(OGUI)region.o: region.c $(HACK_H) $(OGUI)report.o: report.c $(HACK_H) $(INCL)dlb.h $(INCL)nhmd4.h $(OGUI)restore.o: restore.c $(HACK_H) $(INCL)tcap.h +$(OGUI)revision.o: revision.c $(HACK_H) $(OGUI)rip.o: rip.c $(HACK_H) $(OGUI)rnd.o: rnd.c $(HACK_H) $(INCL)isaac64.h $(OGUI)role.o: role.c $(HACK_H) diff --git a/sys/windows/build-msys2.txt b/sys/windows/build-msys2.txt index 06938bfaa..ee4d4a11f 100644 --- a/sys/windows/build-msys2.txt +++ b/sys/windows/build-msys2.txt @@ -46,7 +46,7 @@ Required components that are not bundled in the NetHack repository, but are required to build NetHack yourself. Lua - NetHack 3.7 for Windows requires 3rd party Lua source that is not part + NetHack 5.0 for Windows requires 3rd party Lua source that is not part of the NetHack distribution or repository. A bash shell script for fetching prerequisite @@ -55,7 +55,7 @@ Lua sh sys/windows/fetch.sh lua Curses - If you want to include curses interface support in NetHack 3.7 for + If you want to include curses interface support in NetHack 5.0 for 3rd part pdcursesmod source code is required and is not part of the NetHack distribution or repository. @@ -82,7 +82,7 @@ architectures have evolved and you can now choose whether to build a 32-bit x86 version, or a 64-bit x64 version. The default Makefile is set up for a 32-bit x86 version, but that's only because it will run on the largest number of existing Windows environments. Change it if you -want. Be aware that NetHack's save files and bones files in the 3.7.0 +want. Be aware that NetHack's save files and bones files in the 5.0.0 release are not interchangeable between the 32-bit version and the 64-bit version (or between different platforms). diff --git a/sys/windows/build-nmake.txt b/sys/windows/build-nmake.txt index 35c339e7e..f96dd769e 100644 --- a/sys/windows/build-nmake.txt +++ b/sys/windows/build-nmake.txt @@ -6,23 +6,7 @@ Prerequisite Requirements: A copy of Microsoft Visual Studio Community needs to be installed on your machine. See: https://visualstudio.microsoft.com/vs/community/ - o Lua - NetHack 3.7 for Windows requires 3rd party Lua source that is not part - of the NetHack distribution or repository. - A windows cmd command procedure for fetching prerequisite sources - is available, and can be run as follows from the top of the - NetHack source tree to obtain lua: - sys\windows\fetch.cmd lua - o pdcursesmod (Only required if curses interface support is desired) - If you want to include curses interface support in NetHack 3.7 for - 3rd part pdcursesmod source code is required and is not part of the - NetHack distribution or repository. - - A windows cmd command procedure for fetching prerequisite - sources is available, and can be run as follows from the top of - the NetHack source tree to obtain pdcursesmod: - sys\windows\fetch.cmd pdcursesmod The build Makefiles and procedures produce two executables: a. A TTY and curses version of NetHack in nethack.exe @@ -44,9 +28,9 @@ You can use one of the following build environments: | | | | | | | | | | | | | | | | lua-5.4.8 pdcursesmod share windows tty win32 lua pdcursesmod - | - vs - | + | + vs + | +----------+-------+--------+--------+-----------+-------+-----+------+ | | | | | | | | | makedefs NetHack NetHackW PDCurses PDCursesGui tile2bmp tilemap tiles uudecode @@ -75,7 +59,7 @@ architectures have evolved and you can now choose whether to build a 32-bit x86 version, or a 64-bit x64 version. The default Makefile is set up for a 32-bit x86 version, but that's only because it will run on the most number of existing Windows environments. Change it if you -want. Be aware that NetHack's save files and bones files in the 3.7.0 +want. Be aware that NetHack's save files and bones files in the 5.0.0 release have not yet evolved enough to allow them to interchange between the 32-bit version and the 64-bit version (or between different platforms). That may change in future. @@ -99,19 +83,32 @@ Setting Up source tree, if you are at the top of the NetHack source tree. cd sys\windows. -2. Execute .\nhsetup.bat to place copies of the Makefiles in +2. Execute + .\nhsetup.bat + to place copies of the Makefiles in the src subfolder. The file sys\windows\Makefile.nmake will copied to a file src\Makefile. .\nhsetup.bat +3. Execute + .\fetch.bat lua + to place a copy of Lua into the lib subfolder of the NetHack source + tree. NetHack 5.0 for Windows requires 3rd party Lua source that is not part + of the NetHack distribution or repository. -3. Change your current directory to the src subfolder of the nethack +4. If you want to include support of the optional curses interface in your + build, execute + .\fetch.cmd pdcursesmod + to place a copy pdcursesmod into the lib subfolder of the NetHack + tree. + +5. Change your current directory to the src subfolder of the nethack source tree. The following command assumes you are still in the sys\windows folder from steps #1 and #2 above: cd ..\..\src Compiling -4. Now that everything is set up, you should be ready to start the +6. Now that everything is set up, you should be ready to start the process. Your current directory should be the NetHack src directory. @@ -125,13 +122,13 @@ Compiling Notes: -1. To rebuild NetHack after changing something, change your current directory +N1. To rebuild NetHack after changing something, change your current directory to src and issue the appropriate command for your compiler: For Microsoft compiler: nmake package -2. Depending on the build and compiler and tools used above, the +N2. Depending on the build and compiler and tools used above, the package produced by the build will be either contain: - a 32-bit (x86) .exe file, which should run on any recent Win32 environment. diff --git a/sys/windows/build-vs.txt b/sys/windows/build-vs.txt index bd939a81b..0b3c7d12a 100644 --- a/sys/windows/build-vs.txt +++ b/sys/windows/build-vs.txt @@ -31,7 +31,7 @@ Prerequisite Requirements: See: https://visualstudio.microsoft.com/vs/community/ o Lua - NetHack 3.7 for Windows requires 3rd party Lua source that is not part + NetHack 5.0 for Windows requires 3rd party Lua source that is not part of the NetHack distribution or repository. A windows cmd command procedure for fetching prerequisite sources @@ -39,7 +39,7 @@ Prerequisite Requirements: NetHack source tree to obtain lua: sys\windows\fetch.cmd lua o pdcursesmod (Only required if curses interface support is desired) - If you want to include curses interface support in NetHack 3.7 for + If you want to include curses interface support in NetHack 5.0 for 3rd part pdcursesmod source code is required and is not part of the NetHack distribution or repository. diff --git a/sys/windows/console.rc b/sys/windows/console.rc index 598c0e2ff..81a21b2ca 100644 --- a/sys/windows/console.rc +++ b/sys/windows/console.rc @@ -1,4 +1,4 @@ -/* NetHack 3.7 console.rc $NHDT-Date: 1596498311 2020/08/03 23:45:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 console.rc $NHDT-Date: 1596498311 2020/08/03 23:45:11 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Yitzhak Sapir, 2002. */ /* NetHack may be freely redistributed. See license for details. */ @@ -12,8 +12,8 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,7,0,0 - PRODUCTVERSION 3,7,0,0 + FILEVERSION 5,0,0,0 + PRODUCTVERSION 5,0,0,0 FILEFLAGSMASK 0x1fL #ifdef _DEBUG FILEFLAGS 0x9L @@ -29,13 +29,13 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "NetHack for Windows - TTY Interface\0" - VALUE "FileVersion", "3.7.0\0" + VALUE "FileVersion", "5.0.0\0" VALUE "InternalName", "NetHack\0" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2023. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" + VALUE "LegalCopyright", "Copyright (C) 1985 - 2026. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" VALUE "OriginalFilename", "NetHack.exe\0" VALUE "PrivateBuild", "050107\0" VALUE "ProductName", "NetHack\0" - VALUE "ProductVersion", "3.7.0\0" + VALUE "ProductVersion", "5.0.0\0" END END BLOCK "VarFileInfo" diff --git a/sys/windows/consoletty.c b/sys/windows/consoletty.c index c048a65b6..62b5cf28a 100644 --- a/sys/windows/consoletty.c +++ b/sys/windows/consoletty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 consoletty.c $NHDT-Date: 1596498316 2020/08/03 23:45:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.117 $ */ +/* NetHack 5.0 consoletty.c $NHDT-Date: 1596498316 2020/08/03 23:45:16 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.117 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ @@ -162,6 +162,8 @@ extern void (*ibmgraphics_mode_callback)(void); /* symbols.c */ extern void (*utf8graphics_mode_callback)(void); /* symbols.c */ #endif /* VIRTUAL_TERMINAL_SEQUENCES */ +static boolean OnWindows95_98_Me(void); + static void init_custom_colors(void); static void free_custom_colors(void); @@ -343,160 +345,13 @@ WHITE 255,255,255 242,242,242 */ #ifdef VIRTUAL_TERMINAL_SEQUENCES -long customcolors[CLR_MAX]; +int32 customcolors[CLR_MAX]; const char *esc_seq_colors[CLR_MAX] = { 0 }; const char *esc_seq_bkcolors[CLR_MAX] = { 0 }; -struct rgbvalues { - int idx; - const char *name; - const char *hexval; - long r, gn, b; -} rgbtable[] = { - { 0, "maroon", "#800000", 128, 0, 0 }, - { 1, "dark red", "#8B0000", 139, 0, 0 }, - { 2, "brown", "#A52A2A", 165, 42, 42 }, - { 3, "firebrick", "#B22222", 178, 34, 34 }, - { 4, "crimson", "#DC143C", 220, 20, 60 }, - { 5, "red", "#FF0000", 255, 0, 0 }, - { 6, "tomato", "#FF6347", 255, 99, 71 }, - { 7, "coral", "#FF7F50", 255, 127, 80 }, - { 8, "indian red", "#CD5C5C", 205, 92, 92 }, - { 9, "light coral", "#F08080", 240, 128, 128 }, - { 10, "dark salmon", "#E9967A", 233, 150, 122 }, - { 11, "salmon", "#FA8072", 250, 128, 114 }, - { 12, "light salmon", "#FFA07A", 255, 160, 122 }, - { 13, "orange red", "#FF4500", 255, 69, 0 }, - { 14, "dark orange", "#FF8C00", 255, 140, 0 }, - { 15, "orange", "#FFA500", 255, 165, 0 }, - { 16, "gold", "#FFD700", 255, 215, 0 }, - { 17, "dark golden rod", "#B8860B", 184, 134, 11 }, - { 18, "golden rod", "#DAA520", 218, 165, 32 }, - { 19, "pale golden rod", "#EEE8AA", 238, 232, 170 }, - { 20, "dark khaki", "#BDB76B", 189, 183, 107 }, - { 21, "khaki", "#F0E68C", 240, 230, 140 }, - { 22, "olive", "#808000", 128, 128, 0 }, - { 23, "yellow", "#FFFF00", 255, 255, 0 }, - { 24, "yellow green", "#9ACD32", 154, 205, 50 }, - { 25, "dark olive green", "#556B2F", 85, 107, 47 }, - { 26, "olive drab", "#6B8E23", 107, 142, 35 }, - { 27, "lawn green", "#7CFC00", 124, 252, 0 }, - { 28, "chart reuse", "#7FFF00", 127, 255, 0 }, - { 29, "green yellow", "#ADFF2F", 173, 255, 47 }, - { 30, "dark green", "#006400", 0, 100, 0 }, - { 31, "green", "#008000", 0, 128, 0 }, - { 32, "forest green", "#228B22", 34, 139, 34 }, - { 33, "lime", "#00FF00", 0, 255, 0 }, - { 34, "lime green", "#32CD32", 50, 205, 50 }, - { 35, "light green", "#90EE90", 144, 238, 144 }, - { 36, "pale green", "#98FB98", 152, 251, 152 }, - { 37, "dark sea green", "#8FBC8F", 143, 188, 143 }, - { 38, "medium spring green", "#00FA9A", 0, 250, 154 }, - { 39, "spring green", "#00FF7F", 0, 255, 127 }, - { 40, "sea green", "#2E8B57", 46, 139, 87 }, - { 41, "medium aqua marine", "#66CDAA", 102, 205, 170 }, - { 42, "medium sea green", "#3CB371", 60, 179, 113 }, - { 43, "light sea green", "#20B2AA", 32, 178, 170 }, - { 44, "dark slate gray", "#2F4F4F", 47, 79, 79 }, - { 45, "teal", "#008080", 0, 128, 128 }, - { 46, "dark cyan", "#008B8B", 0, 139, 139 }, - { 47, "aqua", "#00FFFF", 0, 255, 255 }, - { 48, "cyan", "#00FFFF", 0, 255, 255 }, - { 49, "light cyan", "#E0FFFF", 224, 255, 255 }, - { 50, "dark turquoise", "#00CED1", 0, 206, 209 }, - { 51, "turquoise", "#40E0D0", 64, 224, 208 }, - { 52, "medium turquoise", "#48D1CC", 72, 209, 204 }, - { 53, "pale turquoise", "#AFEEEE", 175, 238, 238 }, - { 54, "aqua marine", "#7FFFD4", 127, 255, 212 }, - { 55, "powder blue", "#B0E0E6", 176, 224, 230 }, - { 56, "cadet blue", "#5F9EA0", 95, 158, 160 }, - { 57, "steel blue", "#4682B4", 70, 130, 180 }, - { 58, "corn flower blue", "#6495ED", 100, 149, 237 }, - { 59, "deep sky blue", "#00BFFF", 0, 191, 255 }, - { 60, "dodger blue", "#1E90FF", 30, 144, 255 }, - { 61, "light blue", "#ADD8E6", 173, 216, 230 }, - { 62, "sky blue", "#87CEEB", 135, 206, 235 }, - { 63, "light sky blue", "#87CEFA", 135, 206, 250 }, - { 64, "midnight blue", "#191970", 25, 25, 112 }, - { 65, "navy", "#000080", 0, 0, 128 }, - { 66, "dark blue", "#00008B", 0, 0, 139 }, - { 67, "medium blue", "#0000CD", 0, 0, 205 }, - { 68, "blue", "#0000FF", 0, 0, 255 }, - { 69, "royal blue", "#4169E1", 65, 105, 225 }, - { 70, "blue violet", "#8A2BE2", 138, 43, 226 }, - { 71, "indigo", "#4B0082", 75, 0, 130 }, - { 72, "dark slate blue", "#483D8B", 72, 61, 139 }, - { 73, "slate blue", "#6A5ACD", 106, 90, 205 }, - { 74, "medium slate blue", "#7B68EE", 123, 104, 238 }, - { 75, "medium purple", "#9370DB", 147, 112, 219 }, - { 76, "dark magenta", "#8B008B", 139, 0, 139 }, - { 77, "dark violet", "#9400D3", 148, 0, 211 }, - { 78, "dark orchid", "#9932CC", 153, 50, 204 }, - { 79, "medium orchid", "#BA55D3", 186, 85, 211 }, - { 80, "purple", "#800080", 128, 0, 128 }, - { 81, "thistle", "#D8BFD8", 216, 191, 216 }, - { 82, "plum", "#DDA0DD", 221, 160, 221 }, - { 83, "violet", "#EE82EE", 238, 130, 238 }, - { 84, "magenta / fuchsia", "#FF00FF", 255, 0, 255 }, - { 85, "orchid", "#DA70D6", 218, 112, 214 }, - { 86, "medium violet red", "#C71585", 199, 21, 133 }, - { 87, "pale violet red", "#DB7093", 219, 112, 147 }, - { 88, "deep pink", "#FF1493", 255, 20, 147 }, - { 89, "hot pink", "#FF69B4", 255, 105, 180 }, - { 90, "light pink", "#FFB6C1", 255, 182, 193 }, - { 91, "pink", "#FFC0CB", 255, 192, 203 }, - { 92, "antique white", "#FAEBD7", 250, 235, 215 }, - { 93, "beige", "#F5F5DC", 245, 245, 220 }, - { 94, "bisque", "#FFE4C4", 255, 228, 196 }, - { 95, "blanched almond", "#FFEBCD", 255, 235, 205 }, - { 96, "wheat", "#F5DEB3", 245, 222, 179 }, - { 97, "corn silk", "#FFF8DC", 255, 248, 220 }, - { 98, "lemon chiffon", "#FFFACD", 255, 250, 205 }, - { 99, "light golden rod yellow", "#FAFAD2", 250, 250, 210 }, - { 100, "light yellow", "#FFFFE0", 255, 255, 224 }, - { 101, "saddle brown", "#8B4513", 139, 69, 19 }, - { 102, "sienna", "#A0522D", 160, 82, 45 }, - { 103, "chocolate", "#D2691E", 210, 105, 30 }, - { 104, "peru", "#CD853F", 205, 133, 63 }, - { 105, "sandy brown", "#F4A460", 244, 164, 96 }, - { 106, "burly wood", "#DEB887", 222, 184, 135 }, - { 107, "tan", "#D2B48C", 210, 180, 140 }, - { 108, "rosy brown", "#BC8F8F", 188, 143, 143 }, - { 109, "moccasin", "#FFE4B5", 255, 228, 181 }, - { 110, "navajo white", "#FFDEAD", 255, 222, 173 }, - { 111, "peach puff", "#FFDAB9", 255, 218, 185 }, - { 112, "misty rose", "#FFE4E1", 255, 228, 225 }, - { 113, "lavender blush", "#FFF0F5", 255, 240, 245 }, - { 114, "linen", "#FAF0E6", 250, 240, 230 }, - { 115, "old lace", "#FDF5E6", 253, 245, 230 }, - { 116, "papaya whip", "#FFEFD5", 255, 239, 213 }, - { 117, "sea shell", "#FFF5EE", 255, 245, 238 }, - { 118, "mint cream", "#F5FFFA", 245, 255, 250 }, - { 119, "slate gray", "#708090", 112, 128, 144 }, - { 120, "light slate gray", "#778899", 119, 136, 153 }, - { 121, "light steel blue", "#B0C4DE", 176, 196, 222 }, - { 122, "lavender", "#E6E6FA", 230, 230, 250 }, - { 123, "floral white", "#FFFAF0", 255, 250, 240 }, - { 124, "alice blue", "#F0F8FF", 240, 248, 255 }, - { 125, "ghost white", "#F8F8FF", 248, 248, 255 }, - { 126, "honeydew", "#F0FFF0", 240, 255, 240 }, - { 127, "ivory", "#FFFFF0", 255, 255, 240 }, - { 128, "azure", "#F0FFFF", 240, 255, 255 }, - { 129, "snow", "#FFFAFA", 255, 250, 250 }, - { 130, "black", "#000000", 0, 0, 0 }, - { 131, "dim gray / dim grey", "#696969", 105, 105, 105 }, - { 132, "gray / grey", "#808080", 128, 128, 128 }, - { 133, "dark gray / dark grey", "#A9A9A9", 169, 169, 169 }, - { 134, "silver", "#C0C0C0", 192, 192, 192 }, - { 135, "light gray / light grey", "#D3D3D3", 211, 211, 211 }, - { 136, "gainsboro", "#DCDCDC", 220, 220, 220 }, - { 137, "white smoke", "#F5F5F5", 245, 245, 245 }, - { 138, "white", "#FFFFFF", 255, 255, 255 }, -}; - void buffer_fill_to_end(cell_t * buffer, cell_t * fill, int x, int y); void buffer_write(cell_t * buffer, cell_t * cell, COORD pos); -static long rgbtable_to_long(struct rgbvalues *); +static int32 rgbtable_to_int32(const struct nethack_color *tbl); void term_start_256color(int idx); void set_cp_map(void); #ifdef PORT_DEBUG @@ -504,34 +359,37 @@ void win32con_debug_keystrokes(void); void win32con_toggle_cursor_info(void); #endif -static long -rgbtable_to_long(struct rgbvalues *tbl) +/* GDI typically represents color as BGR (Blue-Green-Red) in memory */ +static int32 +colortable_to_bgr_int32(const struct nethack_color *tbl) { - long rgblong = (tbl->r << 0) | (tbl->gn << 8) | (tbl->b << 16); - return rgblong; + int32 bgrint32 = (tbl->r << 0) | (tbl->g << 8) | (tbl->b << 16); + return bgrint32; } +#define rgbtable_offset 16 + static void init_custom_colors(void) { char bkcolorbuf[32]; - customcolors[CLR_BLACK] = rgbtable_to_long(&rgbtable[131]); - customcolors[CLR_RED] = rgbtable_to_long(&rgbtable[5]); - customcolors[CLR_GREEN] = rgbtable_to_long(&rgbtable[31]); - customcolors[CLR_BROWN] = rgbtable_to_long(&rgbtable[104]); - customcolors[CLR_BLUE] = rgbtable_to_long(&rgbtable[58]); - customcolors[CLR_MAGENTA] = rgbtable_to_long(&rgbtable[76]); - customcolors[CLR_CYAN] = rgbtable_to_long(&rgbtable[48]); - customcolors[CLR_GRAY] = rgbtable_to_long(&rgbtable[73]); - customcolors[NO_COLOR] = rgbtable_to_long(&rgbtable[137]); - customcolors[CLR_ORANGE] = rgbtable_to_long(&rgbtable[15]); - customcolors[CLR_BRIGHT_GREEN] = rgbtable_to_long(&rgbtable[34]); - customcolors[CLR_YELLOW] = rgbtable_to_long(&rgbtable[18]); - customcolors[CLR_BRIGHT_BLUE] = rgbtable_to_long(&rgbtable[69]); - customcolors[CLR_BRIGHT_MAGENTA] = rgbtable_to_long(&rgbtable[84]); - customcolors[CLR_BRIGHT_CYAN] = rgbtable_to_long(&rgbtable[49]); - customcolors[CLR_WHITE] = rgbtable_to_long(&rgbtable[138]); + customcolors[CLR_BLACK] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 131]); + customcolors[CLR_RED] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 5]); + customcolors[CLR_GREEN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 31]); + customcolors[CLR_BROWN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 104]); + customcolors[CLR_BLUE] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 58]); + customcolors[CLR_MAGENTA] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 76]); + customcolors[CLR_CYAN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 48]); + customcolors[CLR_GRAY] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 73]); + customcolors[NO_COLOR] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 137]); + customcolors[CLR_ORANGE] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 15]); + customcolors[CLR_BRIGHT_GREEN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 34]); + customcolors[CLR_YELLOW] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 18]); + customcolors[CLR_BRIGHT_BLUE] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 69]); + customcolors[CLR_BRIGHT_MAGENTA] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 84]); + customcolors[CLR_BRIGHT_CYAN] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 49]); + customcolors[CLR_WHITE] = colortable_to_bgr_int32(&colortable[rgbtable_offset + 138]); /* esc_seq_colors[CLR_BLACK] = "\x1b[30m"; */ esc_seq_colors[CLR_BLACK] = "\x1b[38;2;47;79;79m"; @@ -1036,6 +894,12 @@ void buffer_write(cell_t * buffer, cell_t * cell, COORD pos) back_buffer_flip(); } +static boolean +OnWindows95_98_Me(void) +{ + return ((GetVersion() & 0x80000000) != 0); +} + /* * Called after returning from ! or ^Z */ @@ -1098,7 +962,7 @@ tty_number_pad(int state UNUSED) void term_shutdown(void) { - consoletty_exit(); + console_exit(); } #ifdef ASCIIGRAPH @@ -1188,14 +1052,19 @@ consoletty_open(int mode UNUSED) extern void set_emergency_io(void); void -consoletty_exit(void) +console_exit(void) { free_custom_colors(); - free((genericptr_t) console.front_buffer); - free((genericptr_t) console.back_buffer); + if (console.front_buffer) + free((genericptr_t) console.front_buffer); + if (console.back_buffer) + free((genericptr_t) console.back_buffer); console.front_buffer = console.back_buffer = 0; - free((genericptr_t) console.localestr); - free((genericptr_t) console.orig_localestr); + if (console.localestr) + free((genericptr_t) console.localestr), console.localestr = 0; + if (console.orig_localestr) + free((genericptr_t) console.orig_localestr), + console.orig_localestr = 0; set_emergency_io(); } @@ -2577,7 +2446,7 @@ void nethack_enter_consoletty(void) */ width = csbi.srWindow.Right - csbi.srWindow.Left + 1; #ifdef DEBUG - if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) + if (wizard && NH_DEVEL_STATUS != NH_STATUS_RELEASED) fprintf(stdout, "width = %d\n", width); #endif } @@ -2657,14 +2526,15 @@ void nethack_enter_consoletty(void) /* setup front and back buffers */ int buffer_size_bytes = sizeof(cell_t) * console.buffer_size; - console.front_buffer = (cell_t *)malloc(buffer_size_bytes); + console.front_buffer = (cell_t *)alloc(buffer_size_bytes); buffer_fill_to_end(console.front_buffer, &undefined_cell, 0, 0); - console.back_buffer = (cell_t *)malloc(buffer_size_bytes); + console.back_buffer = (cell_t *)alloc(buffer_size_bytes); buffer_fill_to_end(console.back_buffer, &clear_cell, 0, 0); /* determine whether OS version has unicode support */ - console.has_unicode = (IsWindows8OrGreater()); + /* console.has_unicode = (IsWindows8OrGreater()); */ + console.has_unicode = !OnWindows95_98_Me(); #ifdef VIRTUAL_TERMINAL_SEQUENCES /* store the original code page*/ @@ -2782,6 +2652,18 @@ void nethack_enter_consoletty(void) nhUse(apisuccess); } +int +get_approx_display_cols(void) +{ + return console.width; +} + +int +get_approx_display_rows(void) +{ + return console.height; +} + RESTORE_WARNING_CONDEXPR_IS_CONSTANT #endif /* TTY_GRAPHICS */ @@ -3241,7 +3123,8 @@ default_checkinput( DWORD dwWait; #endif int ch = 0; - boolean valid = 0, done = 0; + boolean valid = 0, done = 0, done_a_checkpoint = FALSE; + DWORD how_many_milliseconds = 0; #ifdef QWERTZ_SUPPORT if (numberpad & 0x10) { @@ -3251,54 +3134,78 @@ default_checkinput( qwertz = FALSE; } #endif + done_a_checkpoint = FALSE; + how_many_milliseconds = (iflags.idlecheckpoint) + ? (IDLECHECKPOINT_WAIT_TIME * 1000) + : INFINITE; while (!done) { -#if defined(SAFERHANGUP) dwWait = WaitForSingleObjectEx(hConIn, // event object to wait for - INFINITE, // waits indefinitely + how_many_milliseconds, TRUE); // alertable wait enabled +#if defined(SAFERHANGUP) if (dwWait == WAIT_FAILED) return '\033'; #endif - ReadConsoleInput(hConIn, ir, 1, count); - if (mode == 0) { - if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { - ch = default_processkeystroke(hConIn, ir, &valid, numberpad, 0); - done = valid; - } - } else { - if (*count > 0) { - if (ir->EventType == KEY_EVENT + if (iflags.idlecheckpoint + && dwWait == WAIT_TIMEOUT && !done_a_checkpoint) { + /* no input for 30 seconds, so let's take + * advantage and do a game checkpoint, + * then resume the wait. + */ +#ifdef INSURANCE + save_currentstate(); +#endif /* INSURANCE */ + done_a_checkpoint = TRUE; + } else + { + ReadConsoleInput(hConIn, ir, 1, count); + if (mode == 0) { + if ((ir->EventType == KEY_EVENT) && ir->Event.KeyEvent.bKeyDown) { + ch = default_processkeystroke(hConIn, ir, &valid, + numberpad, 0); + done = valid; + } + } else { + if (*count > 0) { + if (ir->EventType == KEY_EVENT + && ir->Event.KeyEvent.bKeyDown) { #ifdef QWERTZ_SUPPORT - if (qwertz) - numberpad |= 0x10; + if (qwertz) + numberpad |= 0x10; #endif - ch = default_processkeystroke(hConIn, ir, &valid, numberpad, 0); + ch = default_processkeystroke(hConIn, ir, &valid, + numberpad, 0); #ifdef QWERTZ_SUPPORT - numberpad &= ~0x10; + numberpad &= ~0x10; #endif - if (valid) - return ch; - } else if (ir->EventType == MOUSE_EVENT) { - if ((ir->Event.MouseEvent.dwEventFlags == 0) - && (ir->Event.MouseEvent.dwButtonState & MOUSEMASK)) { - cc->x = ir->Event.MouseEvent.dwMousePosition.X + 1; - cc->y = ir->Event.MouseEvent.dwMousePosition.Y - 1; + if (valid) + return ch; + } else if (ir->EventType == MOUSE_EVENT) { + if ((ir->Event.MouseEvent.dwEventFlags == 0) + && (ir->Event.MouseEvent.dwButtonState + & MOUSEMASK)) { + cc->x = + ir->Event.MouseEvent.dwMousePosition.X + 1; + cc->y = + ir->Event.MouseEvent.dwMousePosition.Y - 1; - if (ir->Event.MouseEvent.dwButtonState & LEFTBUTTON) - *mod = CLICK_1; - else if (ir->Event.MouseEvent.dwButtonState - & RIGHTBUTTON) - *mod = CLICK_2; + if (ir->Event.MouseEvent.dwButtonState + & LEFTBUTTON) + *mod = CLICK_1; + else if (ir->Event.MouseEvent.dwButtonState + & RIGHTBUTTON) + *mod = CLICK_2; #if 0 /* middle button */ else if (ir->Event.MouseEvent.dwButtonState & MIDBUTTON) *mod = CLICK_3; #endif - return 0; + return 0; + } } - } - } else - done = 1; + } else + done = 1; + } } } return mode ? 0 : ch; diff --git a/sys/windows/fetch.cmd b/sys/windows/fetch.cmd index a508ad8dc..4df517a24 100644 --- a/sys/windows/fetch.cmd +++ b/sys/windows/fetch.cmd @@ -1,30 +1,41 @@ -@echo off -if not exist lib\* mkdir lib +@echo on + +if exist %cd%\..\sys\windows\Makefile.nmake set LIBDIR=..\lib +if exist %cd%\Makefile.nmake set LIBDIR=..\..\lib +if exist %cd%\sys\windows\Makefile.nmake set LIBDIR=lib + +set LUA_VERSION=5.4.8 +set LUASRC=%LIBDIR%/lua +set CURLLUASRC=http://www.lua.org/ftp/lua-%LUA_VERSION%.tar.gz +set CURLLUADST=lua-%LUA_VERSION%.tar.gz + +set PDCVERSION=4.5.4 +set CURLPDCSRC=https://github.com/Bill-Gray/PDCursesMod/archive/refs/tags/v%PDCVERSION%.zip +set CURLPDCDST=pdcursesmod.zip + +:proceed + +if not exist %LIBDIR%\* mkdir lib if [%1] == [lua] ( - set LUA_VERSION=5.4.8 - set LUASRC=../lib/lua - set CURLLUASRC=http://www.lua.org/ftp/lua-%LUA_VERSION%.tar.gz - set CURLLUADST=lua-%LUA_VERSION%.tar.gz - if NOT exist lib/lua.h ( - cd lib + if NOT exist %LIBDIR%\lua.h ( + pushd %LIBDIR% curl -L %CURLLUASRC% -o %CURLLUADST% tar -xvf %CURLLUADST% - cd .. + popd ) - echo Lua placed in lib/lua-%LUA_VERSION%.tar.gz + echo Lua placed in %LIBDIR%\lua-%LUA_VERSION%.tar.gz ) if [%1] == [pdcursesmod] ( - set PDCVERSION=4.4.0 - set CURLPDCSRC=https://github.com/Bill-Gray/PDCursesMod/archive/refs/tags/v%PDCVERSION%.zip - set CURLPDCDST=pdcursesmod.zip - if NOT exist lib/pdcursesmod/curses.h ( - cd lib + if NOT exist %LIBDIR%\pdcursesmod\curses.h ( + pushd %LIBDIR% curl -L %CURLPDCSRC% -o %CURLPDCDST% - tar -xvf %CURLPDCDST% mkdir pdcursesmod tar -C pdcursesmod --strip-components=1 -xvf %CURLPDCDST% - cd .. + popd ) + echo pdcursesmod placed in %LIBDIR%\pdcursesmod ) + +:done diff --git a/sys/windows/nethack.def b/sys/windows/nethack.def index 3bb31c60a..2695cecb9 100644 --- a/sys/windows/nethack.def +++ b/sys/windows/nethack.def @@ -1,5 +1,5 @@ NAME NETHACK -DESCRIPTION 'NetHack 3.7.0 for Windows' +DESCRIPTION 'NetHack 5.0.0 for Windows' EXETYPE WINDOWS STUB 'WINSTUB.EXE' CODE PRELOAD MOVEABLE DISCARDABLE diff --git a/sys/windows/nethackrc.template b/sys/windows/nethackrc.template index 6529b1505..8e2ce9c68 100644 --- a/sys/windows/nethackrc.template +++ b/sys/windows/nethackrc.template @@ -1,4 +1,4 @@ -# NetHack 3.7 defaults.nh $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.32 $ +# NetHack 5.0 defaults.nh $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.32 $ # Copyright (c) 2006 by Michael Allison # NetHack may be freely redistributed. See license for details. @@ -146,22 +146,22 @@ OPTIONS=hilite_pet,!toptenwin # point at must exist. NetHack will not create them for you. # # The location that documentation and helps files are placed -#HACKDIR=c:\User\USERNAME\NetHack\3.6 +#HACKDIR=c:\User\USERNAME\NetHack\5.0 # # The location that level files in progress are stored (writeable) -#LEVELDIR=c:\User\USERNAME\AppData\Local\NetHack\3.6 +#LEVELDIR=c:\User\USERNAME\AppData\Local\NetHack\5.0 # # The location where saved games are kept (writeable) -#SAVEDIR=c:\User\USERNAME\AppData\Local\NetHack\3.6 +#SAVEDIR=c:\User\USERNAME\AppData\Local\NetHack\5.0 # # The location that bones files are kept (writeable) -#BONESDIR=c:\ProgramData\NetHack\3.6 +#BONESDIR=c:\ProgramData\NetHack\5.0 # # The location that score files are kept (writeable) -#SCOREDIR=c:\ProgramData\NetHack\3.6 +#SCOREDIR=c:\ProgramData\NetHack\5.0 # # The location that file synchronization locks are stored (writeable) -#LOCKDIR=c:\ProgramData\NetHack\3.6 +#LOCKDIR=c:\ProgramData\NetHack\5.0 # # Finnish keyboards might need these modifications uncommented. diff --git a/sys/windows/nhsetup.bat b/sys/windows/nhsetup.bat index ed41d2361..684b81bb6 100755 --- a/sys/windows/nhsetup.bat +++ b/sys/windows/nhsetup.bat @@ -1,4 +1,4 @@ -@REM NetHack 3.7 nhsetup.bat $NHDT-Date: 1596498315 2020/08/03 23:45:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +@REM NetHack 5.0 nhsetup.bat $NHDT-Date: 1596498315 2020/08/03 23:45:15 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.40 $ */ @REM Copyright (c) NetHack Development Team 1993-2024 @REM NetHack may be freely redistributed. See license for details. @REM Win32 setup batch file, see Install.windows for details diff --git a/sys/windows/porthelp b/sys/windows/porthelp index 7861b4062..cce6549a5 100644 --- a/sys/windows/porthelp +++ b/sys/windows/porthelp @@ -1,4 +1,4 @@ - Microsoft Windows specific help file for NetHack 3.7 + Microsoft Windows specific help file for NetHack 5.0 Copyright (c) NetHack PC Development Team 1993-2025. NetHack may be freely distributed. See license for details. (Last Revision: August 19, 2025) diff --git a/sys/windows/sysconf.template b/sys/windows/sysconf.template index 90095dc1b..4b00865c3 100644 --- a/sys/windows/sysconf.template +++ b/sys/windows/sysconf.template @@ -1,5 +1,5 @@ # -# NetHack 3.7 sysconf $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.7.0 $:$NHDT-Revision: 1.22 $ +# NetHack 5.0 sysconf $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-5.0.0 $:$NHDT-Revision: 1.22 $ # Copyright (c) 2015 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -28,7 +28,7 @@ WIZARDS=* # Only available if NetHack was compiled with DUMPLOG # Allows following placeholders: # %% literal '%' -# %v version (eg. "3.7.0-0") +# %v version (eg. "5.0.0-0") # %u game UID # %t game start time, UNIX timestamp format # %T current time, UNIX timestamp format @@ -106,25 +106,25 @@ HIDEUSAGE=1 # # The location that a record of game aborts and self-diagnosed game problems # is kept (default=HACKDIR, writeable) -#TROUBLEDIR=%USERPROFILE%\NetHack\3.7 +#TROUBLEDIR=%USERPROFILE%\NetHack\5.0 # # The location that documentation and helps files are placed -#HACKDIR=%USERPROFILE%\NetHack\3.7 +#HACKDIR=%USERPROFILE%\NetHack\5.0 # # The location that level files in progress are stored (writeable) -#LEVELDIR=%USERPROFILE%\AppData\Local\NetHack\3.7 +#LEVELDIR=%USERPROFILE%\AppData\Local\NetHack\5.0 # # The location where saved games are kept (writeable) -#SAVEDIR=%USERPROFILE%\AppData\Local\NetHack\3.7 +#SAVEDIR=%USERPROFILE%\AppData\Local\NetHack\5.0 # # The location that bones files are kept (writeable) -#BONESDIR=c:\ProgramData\NetHack\3.7 +#BONESDIR=c:\ProgramData\NetHack\5.0 # # The location that score files are kept (writeable) -#SCOREDIR=c:\ProgramData\NetHack\3.7 +#SCOREDIR=c:\ProgramData\NetHack\5.0 # # The location that file synchronization locks are stored (writeable) -#LOCKDIR=c:\ProgramData\NetHack\3.7 +#LOCKDIR=c:\ProgramData\NetHack\5.0 # URL loaded for creating reports to the NetHack DevTeam -#CRASHREPORTURL=https://nethack.org/links/cr-37BETA.html +#CRASHREPORTURL=https://nethack.org/links/cr-5.0.0.html diff --git a/sys/windows/vs/FetchPrereq/fetchprereq.nmake b/sys/windows/vs/FetchPrereq/fetchprereq.nmake index 2d4f69913..2d89c381f 100644 --- a/sys/windows/vs/FetchPrereq/fetchprereq.nmake +++ b/sys/windows/vs/FetchPrereq/fetchprereq.nmake @@ -1,8 +1,8 @@ -# NetHack 3.7 fetchprereq.nmake +# NetHack 5.0 fetchprereq.nmake #============================================================================== # # The version of the game this Makefile was designed for -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" # A brief version for use in macros NHV=$(NETHACK_VERSION:.=) diff --git a/sys/windows/vs/NetHack/NetHack.vcxproj b/sys/windows/vs/NetHack/NetHack.vcxproj index c6f2df87c..2d76aa0b3 100644 --- a/sys/windows/vs/NetHack/NetHack.vcxproj +++ b/sys/windows/vs/NetHack/NetHack.vcxproj @@ -3,6 +3,9 @@ + + + @@ -78,7 +81,7 @@ stdclatest - hacklib.lib;lualib.lib;kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;UserEnv.lib;bcrypt.lib;%(AdditionalDependencies) + hacklib.lib;lualib.lib;kernel32.lib;dbghelp.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;winmm.lib;Winmm.lib;UserEnv.lib;Rpcrt4.lib;bcrypt.lib;%(AdditionalDependencies) $(SndWavDir);$(SysWindDir);%(AdditionalIncludeDirectories) @@ -231,6 +234,7 @@ + @@ -309,6 +313,7 @@ + diff --git a/sys/windows/vs/NetHackPackage.appxmanifest b/sys/windows/vs/NetHackPackage.appxmanifest index 54140a413..51aed7360 100644 --- a/sys/windows/vs/NetHackPackage.appxmanifest +++ b/sys/windows/vs/NetHackPackage.appxmanifest @@ -2,7 +2,7 @@ - NetHack 3.7 + NetHack 5.0 NetHack DevTeam Images\StoreLogo.png @@ -15,7 +15,7 @@ - + diff --git a/sys/windows/vs/NetHackProperties.props b/sys/windows/vs/NetHackProperties.props index 164cc760e..80ac3b7ab 100644 --- a/sys/windows/vs/NetHackProperties.props +++ b/sys/windows/vs/NetHackProperties.props @@ -2,8 +2,8 @@ - 3 - 7 + 5 + 0 0 $(VERSION_MAJOR).$(VERSION_MINOR).$(PATCHLEVEL) 5 diff --git a/sys/windows/vs/NetHackW/NetHackW.vcxproj b/sys/windows/vs/NetHackW/NetHackW.vcxproj index cc3ec2563..c3f17f6ea 100644 --- a/sys/windows/vs/NetHackW/NetHackW.vcxproj +++ b/sys/windows/vs/NetHackW/NetHackW.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + @@ -100,7 +103,7 @@ Windows - hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;UserEnv.lib;bcrypt.lib;%(AdditionalDependencies) + hacklib.lib;lualib.lib;dbghelp.lib;comctl32.lib;winmm.lib;UserEnv.lib;Rpcrt4.lib;bcrypt.lib;%(AdditionalDependencies) $(WinWin32Dir)NethackW.exe.manifest;%(AdditionalManifestFiles) @@ -278,6 +281,7 @@ + @@ -383,6 +387,7 @@ + diff --git a/sys/windows/vs/PDCurses/PDCurses.vcxproj b/sys/windows/vs/PDCurses/PDCurses.vcxproj index 10f9712ec..e849ca497 100644 --- a/sys/windows/vs/PDCurses/PDCurses.vcxproj +++ b/sys/windows/vs/PDCurses/PDCurses.vcxproj @@ -35,6 +35,9 @@ 10.0 + + + diff --git a/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj b/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj index e709ade6d..fef23ab69 100644 --- a/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj +++ b/sys/windows/vs/PDCursesGui/pdcursesgui.vcxproj @@ -35,6 +35,9 @@ 10.0 + + + diff --git a/sys/windows/vs/Package.StoreAssociation.xml b/sys/windows/vs/Package.StoreAssociation.xml index 24422d2fd..a33a607d2 100644 --- a/sys/windows/vs/Package.StoreAssociation.xml +++ b/sys/windows/vs/Package.StoreAssociation.xml @@ -363,7 +363,7 @@ 30485NetHackDevTeam.NetHack3.6 - NetHack 3.7 + NetHack 5.0 diff --git a/sys/windows/vs/dlb/dlb.vcxproj b/sys/windows/vs/dlb/dlb.vcxproj index 44a1dad6a..a0a29af68 100644 --- a/sys/windows/vs/dlb/dlb.vcxproj +++ b/sys/windows/vs/dlb/dlb.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/fetchctags/fetchctags.nmake b/sys/windows/vs/fetchctags/fetchctags.nmake index 70023ce1d..f11449433 100644 --- a/sys/windows/vs/fetchctags/fetchctags.nmake +++ b/sys/windows/vs/fetchctags/fetchctags.nmake @@ -1,8 +1,8 @@ -# NetHack 3.7 fetchctags.nmake +# NetHack 5.0 fetchctags.nmake #============================================================================== # # The version of the game this Makefile was designed for -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" # A brief version for use in macros NHV=$(NETHACK_VERSION:.=) diff --git a/sys/windows/vs/hacklib/hacklib.vcxproj b/sys/windows/vs/hacklib/hacklib.vcxproj index 3c7241496..c6921c542 100644 --- a/sys/windows/vs/hacklib/hacklib.vcxproj +++ b/sys/windows/vs/hacklib/hacklib.vcxproj @@ -75,7 +75,7 @@ StaticLibrary true Unicode - v145 + $(DefaultPlatformToolset) StaticLibrary @@ -87,7 +87,7 @@ false true Unicode - v145 + $(DefaultPlatformToolset) StaticLibrary @@ -230,4 +230,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/lualib/lualib.vcxproj b/sys/windows/vs/lualib/lualib.vcxproj index 0849b2893..9b8bb3667 100644 --- a/sys/windows/vs/lualib/lualib.vcxproj +++ b/sys/windows/vs/lualib/lualib.vcxproj @@ -90,22 +90,22 @@ Unicode - v143 + $(DefaultPlatformToolset) - v143 + $(DefaultPlatformToolset) - v145 + $(DefaultPlatformToolset) - v143 + $(DefaultPlatformToolset) - v143 + $(DefaultPlatformToolset) - v145 + $(DefaultPlatformToolset) @@ -239,4 +239,4 @@ - \ No newline at end of file + diff --git a/sys/windows/vs/makedefs/makedefs.vcxproj b/sys/windows/vs/makedefs/makedefs.vcxproj index b832056f9..cced77ffd 100644 --- a/sys/windows/vs/makedefs/makedefs.vcxproj +++ b/sys/windows/vs/makedefs/makedefs.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/nhlua_h/nhlua_h.vcxproj b/sys/windows/vs/nhlua_h/nhlua_h.vcxproj index 842f541d8..1a516d3fb 100644 --- a/sys/windows/vs/nhlua_h/nhlua_h.vcxproj +++ b/sys/windows/vs/nhlua_h/nhlua_h.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + @@ -44,13 +47,14 @@ - - - - - - - + + + + + + + + diff --git a/sys/windows/vs/package/package.nmake b/sys/windows/vs/package/package.nmake index 55b3e8e02..31855f752 100644 --- a/sys/windows/vs/package/package.nmake +++ b/sys/windows/vs/package/package.nmake @@ -1,10 +1,10 @@ -# NetHack 3.7 package.nmake +# NetHack 5.0 package.nmake #============================================================================== # # The version of the game this Makefile was designed for !IFNDEF NETHACK_VERSION -NETHACK_VERSION="3.7.0" +NETHACK_VERSION="5.0.0" !MESSAGE NETHACK_VERSION set to $(NETHACK_VERSION). !ELSE !MESSAGE NETHACK_VERSION set to $(NETHACK_VERSION) by caller. @@ -65,12 +65,13 @@ default: packageall # packaging #=============================================================================== +NHDATFILEBASE=nhdat$(NHV) PKGFILES=Guidebook.txt license NetHack.exe NetHack.txt \ - NetHackW.exe opthelp nhdat370 record symbols.template sysconf.template \ - nethackrc.template + NetHackW.exe opthelp $(NHDATFILEBASE) record symbols.template \ + sysconf.template nethackrc.template FILESTOZIP=$(VSBINDIR)\Guidebook.txt $(VSBINDIR)\license \ $(VSBINDIR)\NetHack.exe $(VSBINDIR)\NetHack.txt $(VSBINDIR)\NetHackW.exe \ - $(VSBINDIR)\opthelp $(VSBINDIR)\nhdat370 $(VSBINDIR)\record \ + $(VSBINDIR)\opthelp $(VSBINDIR)\$(NHDATFILEBASE) $(VSBINDIR)\record \ $(VSBINDIR)\symbols.template $(VSBINDIR)\sysconf.template $(VSBINDIR)\nethackrc.template DBGSYMS = NetHack.PDB NetHackW.PDB PDBTOZIP = ..\NetHack\symbols\$(Configuration)\$(Platform)\NetHack.PDB \ diff --git a/sys/windows/vs/recover/recover.vcxproj b/sys/windows/vs/recover/recover.vcxproj index 1fe6f0a16..a15b4c17b 100644 --- a/sys/windows/vs/recover/recover.vcxproj +++ b/sys/windows/vs/recover/recover.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/sfctool/sfctool.vcxproj b/sys/windows/vs/sfctool/sfctool.vcxproj index ad1971969..c6485a0e6 100644 --- a/sys/windows/vs/sfctool/sfctool.vcxproj +++ b/sys/windows/vs/sfctool/sfctool.vcxproj @@ -87,39 +87,39 @@ Application true - v143 + $(DefaultPlatformToolset) Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode Application true - v143 + $(DefaultPlatformToolset) Unicode Application true - v143 + $(DefaultPlatformToolset) Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode diff --git a/sys/windows/vs/sftags/sftags.vcxproj b/sys/windows/vs/sftags/sftags.vcxproj index 52c63d47a..a712fd925 100644 --- a/sys/windows/vs/sftags/sftags.vcxproj +++ b/sys/windows/vs/sftags/sftags.vcxproj @@ -35,6 +35,8 @@ + + 17.0 @@ -47,39 +49,39 @@ Application true - v143 + $(DefaultPlatformToolset) Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode Application true - v143 + $(DefaultPlatformToolset) Unicode Application true - v143 + $(DefaultPlatformToolset) Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode Application false - v143 + $(DefaultPlatformToolset) true Unicode diff --git a/sys/windows/vs/tile2bmp/tile2bmp.vcxproj b/sys/windows/vs/tile2bmp/tile2bmp.vcxproj index 6ed724f2b..0c94bf9f7 100644 --- a/sys/windows/vs/tile2bmp/tile2bmp.vcxproj +++ b/sys/windows/vs/tile2bmp/tile2bmp.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/tilemap/tilemap.vcxproj b/sys/windows/vs/tilemap/tilemap.vcxproj index 70ce0296b..a21a17a72 100644 --- a/sys/windows/vs/tilemap/tilemap.vcxproj +++ b/sys/windows/vs/tilemap/tilemap.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/vs/tiles/tiles.vcxproj b/sys/windows/vs/tiles/tiles.vcxproj index e6b52ad78..4481d9b81 100644 --- a/sys/windows/vs/tiles/tiles.vcxproj +++ b/sys/windows/vs/tiles/tiles.vcxproj @@ -26,22 +26,22 @@ Makefile false - v120 + $(DefaultPlatformToolset) Makefile false - v120 + $(DefaultPlatformToolset) Makefile false - v120 + $(DefaultPlatformToolset) Makefile false - v120 + $(DefaultPlatformToolset) diff --git a/sys/windows/vs/uudecode/uudecode.vcxproj b/sys/windows/vs/uudecode/uudecode.vcxproj index 296d97ab8..e1eba7dc8 100644 --- a/sys/windows/vs/uudecode/uudecode.vcxproj +++ b/sys/windows/vs/uudecode/uudecode.vcxproj @@ -33,6 +33,9 @@ 10.0 + + + diff --git a/sys/windows/win10.c b/sys/windows/win10.c index 7eeaab811..70b7859d8 100644 --- a/sys/windows/win10.c +++ b/sys/windows/win10.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 win10.c $NHDT-Date: 1596498318 2020/08/03 23:45:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 win10.c $NHDT-Date: 1596498318 2020/08/03 23:45:18 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* Copyright (C) 2018 by Bart House */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/win10.h b/sys/windows/win10.h index cc8a0bf48..64ba6b27b 100644 --- a/sys/windows/win10.h +++ b/sys/windows/win10.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 win10.h $NHDT-Date: 1596498319 2020/08/03 23:45:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ +/* NetHack 5.0 win10.h $NHDT-Date: 1596498319 2020/08/03 23:45:19 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.8 $ */ /* Copyright (C) 2018 by Bart House */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/win32api.h b/sys/windows/win32api.h index 1089f8b45..1aee5df18 100644 --- a/sys/windows/win32api.h +++ b/sys/windows/win32api.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 win32api.h $NHDT-Date: 1596498320 2020/08/03 23:45:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 win32api.h $NHDT-Date: 1596498320 2020/08/03 23:45:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (c) NetHack PC Development Team 1996 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/windows/windmain.c b/sys/windows/windmain.c index 99567f9d2..fb21f8271 100644 --- a/sys/windows/windmain.c +++ b/sys/windows/windmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 windmain.c $NHDT-Date: 1693359653 2023/08/30 01:40:53 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.189 $ */ +/* NetHack 5.0 windmain.c $NHDT-Date: 1693359653 2023/08/30 01:40:53 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.189 $ */ /* Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -59,6 +59,7 @@ void windows_nhbell(void); int windows_nh_poskey(int *, int *, int *); void windows_raw_print(const char *); char windows_yn_function(const char *, const char *, char); +boolean portable = FALSE; /* static void windows_getlin(const char *, char *); */ #ifdef WIN32CON @@ -191,8 +192,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #endif #endif - set_emergency_io(); #ifndef MSWIN_GRAPHICS + set_emergency_io(); early_init(argc, argv); /* already in WinMain for MSWIN_GRAPHICS */ #endif @@ -206,8 +207,11 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ } gh.hname = "NetHack"; /* used for syntax messages */ set_default_prefix_locations( - argv[0]); /* must be re-done after initoptions_init() - * which clears out gp.fqn_prefix[] */ + argv[0]); /* must be re-done again after initoptions_init() + * because that function clears out gp.fqn_prefix[] */ + allopt_array_init(); /* we do this here, so allopt doesn't get cleared + after we disregard some */ + copy_sysconf_content(); copy_symbols_content(); /* Now that sysconf has had a chance to set the TROUBLEPREFIX, don't @@ -219,6 +223,8 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ // windowtype = gc.chosen_windowtype; // windowtype = gc.chosen_windowtype; + program_state.early_options = 1; + #if !defined(MSWIN_GRAPHICS) nethack_enter_consoletty(); consoletty_open(1); @@ -237,6 +243,15 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ windowtype = "tty"; #endif } +#ifdef MSWIN_GRAPHICS + if (!strcmp(windowtype, "tty")) + windowtype = "mswin"; +#endif +#ifdef TTY_GRAPHICS + if (!strcmp(windowtype, "mswin")) + windowtype = "tty"; +#endif + choose_windows( windowtype); /* sets all the window port function pointers */ @@ -248,17 +263,19 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ error("NetHack: current directory path too long"); #endif getreturn_enabled = TRUE; +#ifdef MSWIN_GRAPHICS + disregard_some_mswin_options(); +#endif initoptions_init(); // This allows OPTIONS in syscf on Windows. set_default_prefix_locations( argv[0]); /* must be re-done after initoptions_init() * which clears out gp.fqn_prefix[] */ // iflags.windowtype_deferred = TRUE; - program_state.early_options = 1; /* if (GUILaunched || IsDebuggerPresent()) */ early_options(&argc, &argv, &dir); - program_state.early_options = 0; + program_state.early_options = 0; initoptions(); #if defined(CHDIR) && !defined(NOCWD_ASSUMPTIONS) @@ -272,6 +289,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ nethack_exit(EXIT_FAILURE); } + genl_prag(argc, argv); /* command line options for profession, race, + * alignment, gender */ + /* Finished processing options, lock all directory paths */ for (int i = 0; i < PREFIX_COUNT; i++) fqn_prefix_locked[i] = TRUE; @@ -295,12 +315,14 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #ifdef WINCHAIN commit_windowchain(); #endif + init_nhwindows(&argc, argv); + #ifdef TTY_GRAPHICS if WINDOWPORT(tty) { int i; - for (i = 0; i < 20; ++i) { + for (i = 0; i < 5; ++i) { nh_delay_output(); } @@ -325,7 +347,9 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ #elif defined(SND_LIB_WINDSOUND) assign_soundlib(soundlib_windsound); #endif - +#ifdef MSWIN_GRAPHICS + rcfile_only_some_mswin_options(); +#endif u.uhp = 1; /* prevent RIP on early quits */ u.ux = 0; /* prevent flush_screen() */ @@ -375,8 +399,6 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ setting of renameallowed; when False, player_selection() won't resent renaming as an option */ iflags.renameallowed = FALSE; - /* Obtain the name of the logged on user and incorporate - * it into the name. */ Sprintf(fnamebuf, "%s", svp.plname); (void) fname_encode( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.", '%', @@ -797,15 +819,19 @@ copy_symbols_content(void) void copy_sysconf_content(void) { - /* Using the SYSCONFPREFIX path, lock it so that it does not change */ - fqn_prefix_locked[SYSCONFPREFIX] = TRUE; + if (sysopt.portable_device_paths) { + portable = TRUE; + } else { + /* Using the SYSCONFPREFIX path, lock it so that it does not change */ + fqn_prefix_locked[SYSCONFPREFIX] = TRUE; - update_file(gf.fqn_prefix[SYSCONFPREFIX], SYSCF_TEMPLATE, - gf.fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); + update_file(gf.fqn_prefix[SYSCONFPREFIX], SYSCF_TEMPLATE, + gf.fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); - /* If the required early game file does not exist, copy it */ - copy_file(gf.fqn_prefix[SYSCONFPREFIX], SYSCF_FILE, - gf.fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); + /* If the required early game file does not exist, copy it */ + copy_file(gf.fqn_prefix[SYSCONFPREFIX], SYSCF_FILE, + gf.fqn_prefix[DATAPREFIX], SYSCF_TEMPLATE, FALSE); + } } void @@ -1251,7 +1277,11 @@ other_self_recover_prompt(void) int c, ci, ct, pl, retval = 0; boolean ismswin = WINDOWPORT(mswin), iscurses = WINDOWPORT(curses); + int save_popupdialog = iflags.wc_popup_dialog; + if (WINDOWPORT(curses)) { + iflags.wc_popup_dialog = TRUE; + } pl = 1; c = 'n'; ct = 0; @@ -1302,6 +1332,9 @@ other_self_recover_prompt(void) else retval = 1; /* yes, do recover the old game */ } + if (WINDOWPORT(curses)) { + iflags.wc_popup_dialog = save_popupdialog; + } return retval; } diff --git a/sys/windows/windsys.c b/sys/windows/windsys.c index 83e63d608..91dc8eb40 100644 --- a/sys/windows/windsys.c +++ b/sys/windows/windsys.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 windsys.c $NHDT-Date: 1710949760 2024/03/20 15:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.95 $ */ +/* NetHack 5.0 windsys.c $NHDT-Date: 1710949760 2024/03/20 15:49:20 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.95 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ @@ -28,6 +28,7 @@ #include #ifdef WIN32 +#include #include #include @@ -43,10 +44,11 @@ * */ -static char portable_device_path[MAX_PATH]; +char portable_device_path[_MAX_PATH]; static boolean path_buffer_set = FALSE; static char path_buffer[MAX_PATH]; +extern boolean portable; #ifndef SFCTOOL /* runtime cursor display control switch */ @@ -87,9 +89,7 @@ int build_known_folder_path(const KNOWNFOLDERID *folder_id, char *path, void build_environment_path(const char *env_str, const char *folder, char *path, size_t path_size); boolean folder_file_exists(const char *folder, const char *file_name); -boolean test_portable_config(const char *executable_path, - char *portable_device_path, - size_t portable_device_path_size); + /* The function pointer nt_kbhit contains a kbhit() equivalent * which varies depending on which window port is active. * For the tty port it is tty_kbhit() [from consoletty.c] @@ -517,7 +517,7 @@ nethack_exit(int code) * GUILaunched is defined and set in consoletty.c. */ - if (getreturn_enabled) { + if (getreturn_enabled && !program_state.exiting) { raw_print("\n"); if (iflags.window_inited) wait_synch(); @@ -526,10 +526,47 @@ nethack_exit(int code) genl_status_finish(); #ifdef MSWIN_GRAPHICS free_winmain_stuff(); +#endif +#ifdef WIN32CON +#ifdef CURSES_GRAPHICS + if (WINDOWPORT(curses)) { + console_exit(); + } +#endif #endif exit(code); } +void +get_nhuuid(void) +{ + UUID binuuid; + unsigned char *stmp; + RPC_STATUS rpcstatus; + + if (svn.nhuuid[0]) + return; + + rpcstatus = UuidCreate(&binuuid); + if (rpcstatus == RPC_S_OK) { + rpcstatus = UuidToStringA(&binuuid, &stmp); + if (rpcstatus == RPC_S_OK) { + Snprintf(svn.nhuuid, sizeof svn.nhuuid, "%s", (char *) stmp); + RpcStringFree(&stmp); + } + } +} + +void +free_nhuuid(void) +{ + int i; + + for (i = 0; i < SIZE(svn.nhuuid); i++) { + svn.nhuuid[i] = 0; + } +} + #ifdef WIN32CON #undef kbhit #include @@ -647,7 +684,7 @@ BOOL winos_font_support_cp437(HFONT hFont) DWORD size = (size_t) GetFontUnicodeRanges(hdc, NULL); if (size) { - GLYPHSET *glyphSet = (GLYPHSET *) malloc((size_t) size); + GLYPHSET *glyphSet = (GLYPHSET *) alloc((size_t) size); if (glyphSet != NULL) { #ifdef _MSC_VER #pragma warning( push ) @@ -1011,9 +1048,8 @@ set_default_prefix_locations(const char *programPath UNUSED) append_slash(executable_path); #ifndef SFCTOOL - if (test_portable_config(executable_path, portable_device_path, - sizeof portable_device_path)) { - gf.fqn_prefix[SYSCONFPREFIX] = executable_path; + if (portable || (portable = check_for_portable_config())) { + gf.fqn_prefix[SYSCONFPREFIX] = portable_device_path; gf.fqn_prefix[CONFIGPREFIX] = portable_device_path; gf.fqn_prefix[HACKPREFIX] = portable_device_path; gf.fqn_prefix[SAVEPREFIX] = portable_device_path; @@ -1022,7 +1058,7 @@ set_default_prefix_locations(const char *programPath UNUSED) gf.fqn_prefix[SCOREPREFIX] = portable_device_path; gf.fqn_prefix[LOCKPREFIX] = portable_device_path; gf.fqn_prefix[TROUBLEPREFIX] = portable_device_path; - gf.fqn_prefix[DATAPREFIX] = executable_path; + gf.fqn_prefix[DATAPREFIX] = portable_device_path; } else { #endif /* SFCTOOL */ if (!build_known_folder_path(&FOLDERID_Profile, profile_path, @@ -1079,53 +1115,6 @@ append_slash(char *name) } void set_default_prefix_locations(const char *programPath); -boolean -test_portable_config(const char *executable_path, char *portable_device_path, - size_t portable_device_path_size) -{ - int lth = 0; - const char *sysconf = "sysconf"; - char tmppath[MAX_PATH]; - boolean retval = FALSE, - save_initoptions_noterminate = iflags.initoptions_noterminate; - - if (portable_device_path - && folder_file_exists(executable_path, "sysconf")) { - /* - There is a sysconf file (not just sysconf.template) present in - the exe path, which is not the way NetHack is initially - distributed, so assume it means that the admin/installer wants to - override something, perhaps set up for a fully-portable - configuration that leaves no traces behind elsewhere on this - computer's hard drive - delve into that... - */ - - *portable_device_path = '\0'; - lth = sizeof tmppath - strlen(sysconf); - (void) strncpy(tmppath, executable_path, lth - 1); - tmppath[lth - 1] = '\0'; - (void) strcat(tmppath, sysconf); - - iflags.initoptions_noterminate = 1; - /* assure_syscf_file(); */ - config_error_init(TRUE, tmppath, FALSE); - /* ... and _must_ parse correctly. */ - if (read_config_file(tmppath, set_in_sysconf) - && sysopt.portable_device_paths) - retval = TRUE; - (void) config_error_done(); - iflags.initoptions_noterminate = save_initoptions_noterminate; - sysopt_release(); /* the real sysconf processing comes later */ - } - if (retval) { - lth = strlen(executable_path); - if (lth <= (int) portable_device_path_size - 1) - Strcpy(portable_device_path, executable_path); - else - retval = FALSE; - } - return retval; -} const char * get_portable_device(void) diff --git a/sys/windows/winos.h b/sys/windows/winos.h index aed062035..9847dd28b 100644 --- a/sys/windows/winos.h +++ b/sys/windows/winos.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winos.h $NHDT-Date: 1596498322 2020/08/03 23:45:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 winos.h $NHDT-Date: 1596498322 2020/08/03 23:45:22 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.0 $ */ /* Copyright (c) NetHack PC Development Team 2018 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/util/dlb_main.c b/util/dlb_main.c index 1926b871d..238734980 100644 --- a/util/dlb_main.c +++ b/util/dlb_main.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dlb_main.c $NHDT-Date: 1706213798 2024/01/25 20:16:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 5.0 dlb_main.c $NHDT-Date: 1706213798 2024/01/25 20:16:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ */ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland, 1993. */ /* NetHack may be freely redistributed. See license for details. */ @@ -9,7 +9,7 @@ #include "dlb.h" #include "hacklib.h" -#if !defined(O_WRONLY) && !defined(MAC) && !defined(AZTEC_C) +#if !defined(O_WRONLY) && !defined(MAC68K) && !defined(AZTEC_C) #include #endif #if defined(__DJGPP__) diff --git a/util/makedefs.c b/util/makedefs.c index 53c90c151..f18623e2e 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 makedefs.c $NHDT-Date: 1702948590 2023/12/19 01:16:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.233 $ */ +/* NetHack 5.0 makedefs.c $NHDT-Date: 1702948590 2023/12/19 01:16:30 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.233 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ @@ -23,15 +23,15 @@ #include "dlb.h" #include "hacklib.h" -#ifdef MAC +#ifdef MAC68K #if defined(__SC__) || defined(__MRC__) /* MPW compilers */ #define MPWTOOL #include #include -#else /* MAC without MPWTOOL */ +#else /* MAC68K without MPWTOOL */ #define MACsansMPWTOOL #endif -#endif /* MAC */ +#endif /* MAC68K */ #ifndef MPWTOOL #define SpinCursor(x) @@ -78,7 +78,7 @@ #define DGN_TEMPLATE "NH:dat/%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ #else /* not AMIGA */ -#if defined(MAC) && !defined(__MACH__) +#if defined(MAC68K) && !defined(__MACH__) /* MacOS 9 or earlier */ #define SOURCE_TEMPLATE ":src:%s" #if __SC__ || __MRC__ @@ -91,7 +91,7 @@ #define INCLUDE_TEMPLATE ":include:%s" #define DGN_TEMPLATE ":dat:%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ -#else /* neither AMIGA nor MAC */ +#else /* neither AMIGA nor MAC68K */ #ifdef OS2 #define SOURCE_TEMPLATE "..\\src\\%s" #define DATA_TEMPLATE "..\\dat\\%s" @@ -100,7 +100,7 @@ #define INCLUDE_TEMPLATE "..\\include\\%s" #define DGN_TEMPLATE "..\\dat\\%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ -#else /* not AMIGA, MAC, or OS2 */ +#else /* not AMIGA, MAC68K, or OS2 */ #define SOURCE_TEMPLATE "../src/%s" #define DATA_TEMPLATE "../dat/%s" #define DATA_IN_TEMPLATE "../dat/%s" @@ -109,7 +109,7 @@ #define DGN_TEMPLATE "../dat/%s" /* where dungeon.pdf file goes */ #endif /* OLD_MAKEDEFS_OPTIONS */ #endif /* else !OS2 */ -#endif /* else !MAC */ +#endif /* else !MAC68K */ #endif /* else !AMIGA */ static const char @@ -257,7 +257,7 @@ main(void) return 0; } -#else /* ! MAC */ +#else /* ! MAC68K */ DISABLE_WARNING_UNREACHABLE_CODE @@ -1551,7 +1551,7 @@ do_oracles(void) break; if (!(ok = (fscanf(ofp, "%5lx", &offset) == 1))) break; -#ifdef MAC +#ifdef MAC68K #ifdef __MWERKS__ /* MetroWerks CodeWarrior Pro 1's (AKA CW12) version of MSL @@ -1590,7 +1590,7 @@ do_oracles(void) /* Read one line from input, up to and including the next newline * character. Returns a pointer to the heap-allocated string, or a * null pointer if no characters were read. - * 3.7: redone to use nethack's alloc() rather than libc's malloc() + * 5.0: redone to use nethack's alloc() rather than libc's malloc() * and realloc(). */ static char * diff --git a/util/mdgrep.h b/util/mdgrep.h index 335f018b1..2de58266a 100644 --- a/util/mdgrep.h +++ b/util/mdgrep.h @@ -1,5 +1,5 @@ /* - * NetHack 3.7 mdgrep.h $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ + * NetHack 5.0 mdgrep.h $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ * Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008 * NetHack may be freely redistributed. See license for details. * diff --git a/util/mdgrep.pl b/util/mdgrep.pl index 785a2c185..888820a4c 100644 --- a/util/mdgrep.pl +++ b/util/mdgrep.pl @@ -1,5 +1,5 @@ #!perl -# NetHack 3.7 mdgrep.pl $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ +# NetHack 5.0 mdgrep.pl $NHDT-Date: 1710949914 2024/03/20 15:51:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -51,7 +51,7 @@ $specials = { # TIMED_DELAY DEF_MAILREADER DEF_PAGER NO_SIGNAL PC_LOCKING LATTICE __GO32__ # msleep NO_FILE_LINKS bsdi HPUX AMIFLUSH # SCREEN_BIOS SCREEN_DJGPPFAST SCREEN_VGA SCREEN_8514 -# EXEPATH NOTSTDC SELECTSAVED NOTPARMDECL +# EXEPATH NOTSTDC SELECTSAVE # constants @const_true = qw/1 TRUE/; @@ -61,7 +61,7 @@ $outfile = "mdgrep.h"; sub start_file { ($rev) = ('$NHDT-Revision: 1.26 $') =~ m/: (.*) .$/; my $date = '$NHDT-Date: 1710949915 2024/03/20 15:51:55 $'; - my $branch = '$NHDT-Branch: NetHack-3.7 $'; + my $branch = '$NHDT-Branch: NetHack-5.0 $'; my $revision = '$NHDT-Revision: 1.26 $'; open(OUT, ">$outfile") || die "open $outfile: $!"; # NB: Date and Revision below will be modified when mdgrep.h is written to @@ -69,7 +69,7 @@ sub start_file { # before generating mdgrep.h and committing that file). print OUT <lwc(); @@ -332,38 +345,38 @@ winid NetHackQtBind::qt_create_nhwindow(int type) { winid id; for (id = 0; id < (winid) id_to_window.size(); id++) { - if ( !id_to_window[(int)id] ) - break; + if ( !id_to_window[(int)id] ) + break; } if ( id == (winid) id_to_window.size() ) - id_to_window.resize(id+1); + id_to_window.resize(id+1); NetHackQtWindow* window=0; switch (type) { case NHW_MAP: { - NetHackQtMapWindow2* w=new NetHackQtMapWindow2(clickbuffer); - main->AddMapWindow(w); - window=w; + NetHackQtMapWindow2* w=new NetHackQtMapWindow2(clickbuffer); + main->AddMapWindow(w); + window=w; break; } case NHW_MESSAGE: { - NetHackQtMessageWindow* w=new NetHackQtMessageWindow; - main->AddMessageWindow(w); - window=w; + NetHackQtMessageWindow* w=new NetHackQtMessageWindow; + main->AddMessageWindow(w); + window=w; break; } case NHW_STATUS: { - NetHackQtStatusWindow* w=new NetHackQtStatusWindow; - main->AddStatusWindow(w); - window=w; + NetHackQtStatusWindow* w=new NetHackQtStatusWindow; + main->AddStatusWindow(w); + window=w; break; } case NHW_MENU: - window=new NetHackQtMenuOrTextWindow(mainWidget()); + window=new NetHackQtMenuOrTextWindow(mainWidget()); break; case NHW_TEXT: - window=new NetHackQtTextWindow(mainWidget()); + window=new NetHackQtTextWindow(mainWidget()); break; } @@ -374,11 +387,11 @@ winid NetHackQtBind::qt_create_nhwindow(int type) #if QT_VERSION >= 300 && !main->isHidden() #else - && main->isVisible() + && main->isVisible() #endif - ) { - delete splash; - splash = 0; + ) { + delete splash; + splash = 0; } id_to_window[(int)id] = window; @@ -440,30 +453,30 @@ void NetHackQtBind::qt_display_file(const char *filename, boolean must_exist) bool complain = false; { - dlb *f; - char buf[BUFSZ]; - char *cr; + dlb *f; + char buf[BUFSZ]; + char *cr; - window->Clear(); - f = dlb_fopen(filename, "r"); - if (!f) { - complain = must_exist; - } else { - while (dlb_fgets(buf, BUFSZ, f)) { - if ((cr = strchr(buf, '\n')) != 0) *cr = 0; + window->Clear(); + f = dlb_fopen(filename, "r"); + if (!f) { + complain = must_exist; + } else { + while (dlb_fgets(buf, BUFSZ, f)) { + if ((cr = strchr(buf, '\n')) != 0) *cr = 0; #ifdef MSDOS - if ((cr = strchr(buf, '\r')) != 0) *cr = 0; + if ((cr = strchr(buf, '\r')) != 0) *cr = 0; #endif - window->PutStr(ATR_NONE, tabexpand(buf)); - } - window->Display(false); - (void) dlb_fclose(f); - } + window->PutStr(ATR_NONE, tabexpand(buf)); + } + window->Display(false); + (void) dlb_fclose(f); + } } if (complain) { - QString message = nh_qsprintf("File not found: %s\n",filename); - QMessageBox::warning(NULL, "File Error", message, QMessageBox::Ignore); + QString message = nh_qsprintf("File not found: %s\n",filename); + QMessageBox::warning(NULL, "File Error", message, QMessageBox::Ignore); } } @@ -498,7 +511,7 @@ int NetHackQtBind::qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list) void NetHackQtBind::qt_update_inventory(int arg UNUSED) { if (main) - main->updateInventory(); // update the paper doll inventory subset + main->updateInventory(); // update the paper doll inventory subset /* doesn't work yet if (program_state.something_worth_saving && iflags.perm_invent) @@ -623,7 +636,7 @@ const QPen NetHackQtBind::nhcolor_to_pen(uint32_t c) int NetHackQtBind::qt_nhgetch() { if (main) - main->fadeHighlighting(true); + main->fadeHighlighting(true); // Process events until a key arrives. // @@ -653,11 +666,58 @@ QCoreApplication::exec: The event loop is already running return keybuffer.GetAscii(); } +#ifdef IDLECHECKPOINT +void +NetHackQtBind::free_qt_input_timer(void) +{ + if (qt_input_timer) { + if (qt_input_timer->isActive()) + qt_input_timer->stop(); + if (qt_input_timer) + delete qt_input_timer; + qt_input_timer = 0; + } +} + +static void +qt_timer_fire(void) +{ + if (iflags.idlecheckpoint) { + /* no input for 30 seconds, so let's take + * advantage and do a game checkpoint, + * then resume the wait. + */ +#if defined(INSURANCE) + save_currentstate(); +#endif /* INSURANCE */ + } + if (qt_input_timer->isActive()) + qt_input_timer->stop(); +} + +//void +//cancel_qt_input_timer(void) +//{ +// +//} +#endif /* IDLECHECKPOINT */ + int NetHackQtBind::qt_nh_poskey(coordxy *x, coordxy *y, int *mod) { if (main) - main->fadeHighlighting(true); + main->fadeHighlighting(true); +#ifdef IDLECHECKPOINT + if (iflags.idlecheckpoint) { + if (!qt_input_timer) { + qt_input_timer = new QTimer(); + qt_input_timer->setSingleShot(true); + connect(qt_input_timer, &QTimer::timeout, &qt_timer_fire); + } + if (!qt_input_timer->isActive()) + qt_input_timer->start(IDLECHECKPOINT_WAIT_TIME * 1000); + } +#endif // Process events until a key or map-click arrives. // while (keybuffer.Empty() && clickbuffer.Empty()) { @@ -672,13 +732,21 @@ int NetHackQtBind::qt_nh_poskey(coordxy *x, coordxy *y, int *mod) main->fadeHighlighting(false); if (!keybuffer.Empty()) { - return keybuffer.GetAscii(); +#ifdef IDLECHECKPOINT + if (qt_input_timer->isActive()) + qt_input_timer->stop(); +#endif + return keybuffer.GetAscii(); } else { - *x=clickbuffer.NextX(); - *y=clickbuffer.NextY(); - *mod=clickbuffer.NextMod(); - clickbuffer.Get(); - return 0; + *x=clickbuffer.NextX(); + *y=clickbuffer.NextY(); + *mod=clickbuffer.NextMod(); + clickbuffer.Get(); +#ifdef IDLECHECKPOINT + if (qt_input_timer->isActive()) + qt_input_timer->stop(); +#endif + return 0; } } @@ -724,10 +792,10 @@ char NetHackQtBind::qt_more() int complain = 0; do { ch = NetHackQtBind::qt_nhgetch(); - if (::program_state.savefile_completed) { - retry = false; - break; - } + if (::program_state.savefile_completed) { + retry = false; + break; + } switch (ch) { case '\0': // hypothetical ch = '\033'; @@ -808,26 +876,26 @@ char NetHackQtBind::qt_yn_function(const char *question_, !::iflags.wc_popup_dialog #endif && WIN_MESSAGE != WIN_ERR) { - // Similar to X11 windowport `slow' feature. + // Similar to X11 windowport `slow' feature. char cbuf[20]; cbuf[0] = '\0'; // add the prompt to the message window - NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); + NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); - while (result < 0) { + while (result < 0) { cbuf[0] = '\0'; - char ch=NetHackQtBind::qt_nhgetch(); - if (ch=='\033') { - result=yn_esc_map; + char ch=NetHackQtBind::qt_nhgetch(); + if (ch=='\033') { + result=yn_esc_map; Strcpy(cbuf, "ESC"); - } else if (choices && !strchr(choices,ch)) { - if (def && (ch==' ' || ch=='\r' || ch=='\n')) { - result=def; + } else if (choices && !strchr(choices,ch)) { + if (def && (ch==' ' || ch=='\r' || ch=='\n')) { + result=def; Strcpy(cbuf, visctrl(def)); - } else { - NetHackQtBind::qt_nhbell(); + } else { + NetHackQtBind::qt_nhbell(); // typing anything caused the most recent message line // (which happens to our prompt) from having highlighting // be removed; put that back @@ -835,13 +903,13 @@ char NetHackQtBind::qt_yn_function(const char *question_, *mesgwin = main ? main->GetMessageWindow() : NULL; if (mesgwin) mesgwin->RehighlightPrompt(); - // and try again... - } - } else { - result=ch; + // and try again... + } + } else { + result=ch; Strcpy(cbuf, visctrl(ch)); - } - } + } + } // update the prompt message line to include the response if (cbuf[0]) { diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index d0c71759c..17dad758c 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -23,78 +23,78 @@ class NetHackQtClickBuffer; class NetHackQtBind : NetHackQtBindBase { private: - // Single-instance preservation... - NetHackQtBind(int& argc, char** argv); + // Single-instance preservation... + NetHackQtBind(int& argc, char** argv); - static NetHackQtBind* instance; + static NetHackQtBind* instance; - static NetHackQtKeyBuffer keybuffer; - static NetHackQtClickBuffer clickbuffer; + static NetHackQtKeyBuffer keybuffer; + static NetHackQtClickBuffer clickbuffer; - static QFrame* splash; - static NetHackQtMainWindow* main; + static QFrame* splash; + static NetHackQtMainWindow* main; public: static void qt_Splash(); /* window interface */ - static void qt_init_nhwindows(int* argc, char** argv); - static void qt_player_selection(); - static void qt_askname(); - static void qt_get_nh_event(); - static void qt_exit_nhwindows(const char *); - static void qt_suspend_nhwindows(const char *); - static void qt_resume_nhwindows(); - static winid qt_create_nhwindow(int type); - static void qt_clear_nhwindow(winid wid); - static void qt_display_nhwindow(winid wid, boolean block); - static void qt_destroy_nhwindow(winid wid); - static void qt_curs(winid wid, int x, int y); - static void qt_putstr(winid wid, int attr, const char *text); - static void qt_putstr(winid wid, int attr, const std::string& text); - static void qt_putstr(winid wid, int attr, const QString& text); - static void qt_display_file(const char *filename, boolean must_exist); - static void qt_start_menu(winid wid, unsigned long mbehavior); - static void qt_add_menu(winid wid, const glyph_info *glyphinfo, - const ANY_P * identifier, char ch, char gch, int attr, int clr, - const char *str, unsigned int itemflags); + static void qt_init_nhwindows(int* argc, char** argv); + static void qt_player_selection(); + static void qt_askname(); + static void qt_get_nh_event(); + static void qt_exit_nhwindows(const char *); + static void qt_suspend_nhwindows(const char *); + static void qt_resume_nhwindows(); + static winid qt_create_nhwindow(int type); + static void qt_clear_nhwindow(winid wid); + static void qt_display_nhwindow(winid wid, boolean block); + static void qt_destroy_nhwindow(winid wid); + static void qt_curs(winid wid, int x, int y); + static void qt_putstr(winid wid, int attr, const char *text); + static void qt_putstr(winid wid, int attr, const std::string& text); + static void qt_putstr(winid wid, int attr, const QString& text); + static void qt_display_file(const char *filename, boolean must_exist); + static void qt_start_menu(winid wid, unsigned long mbehavior); + static void qt_add_menu(winid wid, const glyph_info *glyphinfo, + const ANY_P * identifier, char ch, char gch, int attr, int clr, + const char *str, unsigned int itemflags); static void qt_end_menu(winid wid, const char *prompt); - static int qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list); - static void qt_mark_synch(); - static void qt_wait_synch(); + static int qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list); + static void qt_mark_synch(); + static void qt_wait_synch(); - static void qt_cliparound(int x, int y); - static void qt_cliparound_window(winid wid, int x, int y); + static void qt_cliparound(int x, int y); + static void qt_cliparound_window(winid wid, int x, int y); static void qt_print_glyph(winid wid, coordxy x, coordxy y, const glyph_info *glyphingo, - const glyph_info *bkglyphinfo); - static void qt_raw_print(const char *str); - static void qt_raw_print_bold(const char *str); - static const QPen nhcolor_to_pen(uint32_t c); + const glyph_info *bkglyphinfo); + static void qt_raw_print(const char *str); + static void qt_raw_print_bold(const char *str); + static const QPen nhcolor_to_pen(uint32_t c); static void qt_change_color(int color, long rgb, int reverse UNUSED); static char *qt_get_color_string(void); - static int qt_nhgetch(); - static int qt_nh_poskey(coordxy *x, coordxy *y, int *mod); - static void qt_nhbell(); - static int qt_doprev_message(); + static int qt_nhgetch(); + static int qt_nh_poskey(coordxy *x, coordxy *y, int *mod); + static void qt_nhbell(); + static int qt_doprev_message(); static char qt_more(); static char qt_yn_function(const char *question, const char *choices, char def); - static void qt_getlin(const char *prompt, char *line); - static int qt_get_ext_cmd(); - static void qt_number_pad(int); - static void qt_delay_output(); + static void qt_getlin(const char *prompt, char *line); + static int qt_get_ext_cmd(); + static void qt_number_pad(int); + static void qt_delay_output(); static void qt_preference_update(const char *optname); static char *qt_getmsghistory(boolean init); static void qt_putmsghistory(const char *msg, boolean is_restoring); - static void qt_outrip(winid wid, int how, time_t when); - static int qt_kbhit(); - static void qt_update_inventory(int); + static void qt_outrip(winid wid, int how, time_t when); + static int qt_kbhit(); + static void qt_update_inventory(int); static win_request_info *qt_ctrl_nhwindow(winid, int, win_request_info *); - static QWidget *mainWidget() { return main; } + static QWidget *mainWidget() { return main; } #if defined(SND_LIB_QTSOUND) && !defined(QT_NO_SOUND) /* sound interface */ static void qtsound_init_nhsound(void); @@ -106,9 +106,12 @@ public: static void qtsound_ambience(int32_t, int32_t, int32_t); static void qtsound_verbal(char *text, int32_t gender, int32_t tone, int32_t vol, int32_t moreinfo); #endif +#ifdef IDLECHECKPOINT + static void free_qt_input_timer(void); +#endif private: - virtual bool notify(QObject *receiver, QEvent *event); + virtual bool notify(QObject *receiver, QEvent *event); static QStringList *msgs_strings; static boolean msgs_saved; diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 01cf2039f..76bc06cff 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -172,7 +172,7 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) // W wielded two-handed weapon // X wielded secondary weapon // - // 3.7: use a different layout (also different legend for it, above): + // 5.0: use a different layout (also different legend for it, above): // invert so grid is facing player, with right hand on screen left; // show gloves in only one slot; // move alternate weapon to former right hand glove slot; diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 93a9064f6..f61833dcf 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -165,7 +165,7 @@ NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) : { // setFont() was in SelectMenu(), in time to be rendered but too late // when measuring the width and height that will be needed - QFont tablefont(qt_settings->normalFixedFont()); + QFont tablefont(qt_settings->normalFont()); table->setFont(tablefont); QGridLayout *grid = new QGridLayout(); @@ -400,9 +400,8 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) continue; // determine column widths of sub-fields within description QStringList columns = itemlist[row].str.split("\t"); - for (int fld = 0; fld < (int) columns.size(); ++fld) { - bool lastcol = (fld == (int) columns.size() - 1); - int w = fm.QFM_WIDTH(columns[fld] + (lastcol ? "" : " ")); + for (int fld = 0; fld < (int) columns.size() - 1; ++fld) { + int w = fm.QFM_WIDTH(columns[fld] + " "); if (fld >= (int) col_widths.size()) { col_widths.push_back(w); // add another element } else if (col_widths[fld] < w) { @@ -432,12 +431,21 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) continue; QString text = twi->text(); if (split_descr) { + static const QChar u_200A(0x200A); // U+200A HAIR SPACE QStringList columns = text.split("\t"); + int spc0020_width = fm.QFM_WIDTH(" "); + int spc200A_width = fm.QFM_WIDTH(u_200A); + // Track errors in column widths and adjust subsequent columns so + // that these errors do not accumulate across a row + int error = 0; for (int fld = 0; fld < (int) columns.size() - 1; ++fld) { //columns[fld] += "\t"; /* (used to pad with tabs) */ int width = col_widths[fld]; - while (fm.QFM_WIDTH(columns[fld]) < width) + while (fm.QFM_WIDTH(columns[fld]) + error + spc0020_width <= width) columns[fld] += " "; //"\t"; + while (fm.QFM_WIDTH(columns[fld]) + error + spc200A_width/2 < width) + columns[fld] += u_200A; + error += fm.QFM_WIDTH(columns[fld]) - width; } text = columns.join(""); twi->setText(text); @@ -1133,7 +1141,7 @@ void NetHackQtTextWindow::Display(bool block UNUSED) void NetHackQtTextWindow::PutStr(int attr UNUSED, const QString& text) { #if 1 - // 3.7: Always render text windows with fixed-width font. The majority + // 5.0: Always render text windows with fixed-width font. The majority // of text files we'll ever display including ('license' and 'history') // happen to have some lines with four spaces anyway and/or they have // been pre-formatted to fit within less than 80 columns. For data.base diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index a280f07fc..b646d347b 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -358,8 +358,13 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector( genderbox->layout()->addWidget(gender[i]); gendergroup->addButton(gender[i], i); } +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) + connect(gendergroup, SIGNAL(idClicked(int)), + this, SLOT(selectGender(int))); +#else connect(gendergroup, SIGNAL(buttonClicked(int)), this, SLOT(selectGender(int))); +#endif QLabel *alignlabel = new QLabel("Alignment"); alignbox->layout()->addWidget(alignlabel); @@ -369,8 +374,13 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector( alignbox->layout()->addWidget(alignment[i]); aligngroup->addButton(alignment[i], i); } +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) + connect(aligngroup, SIGNAL(idClicked(int)), + this, SLOT(selectAlignment(int))); +#else connect(aligngroup, SIGNAL(buttonClicked(int)), this, SLOT(selectAlignment(int))); +#endif l->addWidget(rand_btn, 4, 2); connect(rand_btn, SIGNAL(clicked()), this, SLOT(Randomize())); @@ -559,7 +569,10 @@ void NetHackQtPlayerSelector::plnamePlayVsQuit() // the line edit widget for the name field has received input void NetHackQtPlayerSelector::selectName(const QString& n) { - const char *name_str = n.toLatin1().constData(); + // the QByteArray has to outlive name_str; calling constData() on + // the temporary returned by toLatin1() leaves it dangling + QByteArray name_bytes = n.toLatin1(); + const char *name_str = name_bytes.constData(); // skip any leading spaces // (it would be better to set up a validator that rejects leading spaces) while (*name_str == ' ') diff --git a/win/Qt/qt_post.h b/win/Qt/qt_post.h index 7c9724473..a73f9f3a3 100644 --- a/win/Qt/qt_post.h +++ b/win/Qt/qt_post.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 qt_post.h $NHDT-Date: 1597276832 2020/08/13 00:00:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 qt_post.h $NHDT-Date: 1781973096 2026/06/20 16:31:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.5 $ */ /* * qt_post.h -- reverse part of qt_pre.h. diff --git a/win/Qt/qt_pre.h b/win/Qt/qt_pre.h index 22d988297..dc5cdfbdf 100644 --- a/win/Qt/qt_pre.h +++ b/win/Qt/qt_pre.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 qt_pre.h $NHDT-Date: 1597276835 2020/08/13 00:00:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 5.0 qt_pre.h $NHDT-Date: 1781973096 2026/06/20 16:31:36 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* * qt_pre.h -- undefine some nethack macros which conflict with Qt headers. diff --git a/win/Qt/qt_svsel.cpp b/win/Qt/qt_svsel.cpp index 882fabce7..f08c0aa25 100644 --- a/win/Qt/qt_svsel.cpp +++ b/win/Qt/qt_svsel.cpp @@ -6,7 +6,7 @@ // // Popup's layout: //---- -// NetHack 3.7.x (literal text w/ dynamic version number) +// NetHack 5.0.x (literal text w/ dynamic version number) // /----------------------\ (text to prevent multi-line comment warning) // | | // | | diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 1f356399c..db66579f6 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -2,7 +2,7 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// Qt Windowing interface for NetHack 3.7 +// Qt Windowing interface for NetHack 5.0 // // Copyright (C) 1996-2001 by Warwick W. Allison (warwick@troll.no) // diff --git a/win/Qt/qt_win.h b/win/Qt/qt_win.h index 9dce3baec..8edb91974 100644 --- a/win/Qt/qt_win.h +++ b/win/Qt/qt_win.h @@ -2,7 +2,7 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// Qt Binding for NetHack 3.7 +// Qt Binding for NetHack 5.0 // // [original comment from Warwick] // Unfortunately, this doesn't use Qt as well as I would like, diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 57e2f212f..a7dea6b68 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -292,7 +292,13 @@ char NetHackQtYnDialog::Exec() bgroup->addButton(button, i); } - connect(bgroup, SIGNAL(buttonClicked(int)), this, SLOT(doneItem(int))); +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) + connect(bgroup, SIGNAL(idClicked(int)), this, + SLOT(doneItem(int))); +#else + connect(bgroup, SIGNAL(buttonClicked(int)), this, + SLOT(doneItem(int))); +#endif QLabel *lb = 0; if (allow_count) { diff --git a/win/X11/NetHack.ad b/win/X11/NetHack.ad index c10d1360f..10f1e7a73 100644 --- a/win/X11/NetHack.ad +++ b/win/X11/NetHack.ad @@ -1,4 +1,4 @@ -! $NHDT-Date: 1750598195 2025/06/22 05:16:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ +! $NHDT-Date: 1750598195 2025/06/22 05:16:35 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.27 $ ! Copyright (c) 2017 by Pasi Kallinen ! NetHack may be freely redistributed. See license for details. @@ -27,6 +27,18 @@ NetHack*tombstone*font: NETHACK_FONT NetHack*text*rip*font: -*-times-medium-r-*-*-12-*-*-*-*-*-*-* NetHack*text*borderWidth: 0 +! Vector font to be used if Xft support is enabled +! These correspond to the .nethackrc settings font_map, font_menu, +! font_message, font_status and font_text +NetHack.font_map: mono-10 +NetHack.font_menu: sans-10 +NetHack.font_message: sans-10 +NetHack.font_status: sans-10 +NetHack.font_text: mono-10 + +! No .nethackrc setting for this, but it gets the right size +NetHack.font_rip: sans-9 + ! tile_file names a file containing full-color tiles for the map. ! If you use a 100dpi (or greater) monitor you may wish to double the ! tile size so you can see the figures. If NetHack was compiled to diff --git a/win/X11/Window.c b/win/X11/Window.c index 82cb5a1c6..401caaa2d 100644 --- a/win/X11/Window.c +++ b/win/X11/Window.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 Window.c $NHDT-Date: 1596498371 2020/08/03 23:46:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 Window.c $NHDT-Date: 1781973108 2026/06/20 16:31:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.17 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -168,6 +168,7 @@ WindowClassRec windowClassRec = { WidgetClass windowWidgetClass = (WidgetClass) &windowClassRec; +#ifndef USE_XFT Font WindowFont(Widget w) { @@ -179,3 +180,4 @@ WindowFontStruct(Widget w) { return ((WindowWidget) w)->window.font; } +#endif diff --git a/win/X11/dialogs.c b/win/X11/dialogs.c index 11664c198..48047852d 100644 --- a/win/X11/dialogs.c +++ b/win/X11/dialogs.c @@ -132,6 +132,7 @@ CreateDialog(Widget parent, String name, XtCallbackProc okay_callback, XtSetArg(args[num_args], nhStr(XtNborderWidth), 0); num_args++; prompt = XtCreateManagedWidget("prompt", labelWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(prompt, NHW_MENU); num_args = 0; #ifdef SPECIAL_CMAP @@ -169,6 +170,7 @@ CreateDialog(Widget parent, String name, XtCallbackProc okay_callback, XtParseAcceleratorTable(okay_accelerators)); num_args++; okay = XtCreateManagedWidget("okay", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(okay, NHW_MENU); XtAddCallback(okay, XtNcallback, okay_callback, form); XtSetArg(args[0], XtNwidth, &owidth); XtGetValues(okay, args, ONE); @@ -193,6 +195,7 @@ CreateDialog(Widget parent, String name, XtCallbackProc okay_callback, XtParseAcceleratorTable(cancel_accelerators)); num_args++; cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(cancel, NHW_MENU); XtAddCallback(cancel, XtNcallback, cancel_callback, form); XtInstallAccelerators(response, cancel); XtSetArg(args[0], XtNwidth, &cwidth); @@ -241,6 +244,7 @@ SetDialogPrompt(Widget w, String newprompt) label = XtNameToWidget(w, "prompt"); XtSetArg(args[0], nhStr(XtNlabel), newprompt); XtSetValues(label, args, ONE); + X11_update_label_if_Xft(label); } /* get what the user typed; caller must free the response */ diff --git a/win/X11/nh32icon b/win/X11/nh32icon index cdacc920b..adc4f24f5 100644 --- a/win/X11/nh32icon +++ b/win/X11/nh32icon @@ -1,4 +1,4 @@ -/* NetHack 3.7 nh32icon $NHDT-Date: 1597001766 2020/08/09 19:36:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 nh32icon $NHDT-Date: 1597001766 2020/08/09 19:36:06 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 1993,1995,2015 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/nh56icon b/win/X11/nh56icon index 5de4aa8bf..d845ddbe7 100644 --- a/win/X11/nh56icon +++ b/win/X11/nh56icon @@ -1,4 +1,4 @@ -/* NetHack 3.7 nh56icon $NHDT-Date: 1597001767 2020/08/09 19:36:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 nh56icon $NHDT-Date: 1597001767 2020/08/09 19:36:07 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) 1993,1995,2015 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/nh72icon b/win/X11/nh72icon index 60043a5f2..3f1e28da7 100644 --- a/win/X11/nh72icon +++ b/win/X11/nh72icon @@ -1,4 +1,4 @@ -/* NetHack 3.7 nh72icon $NHDT-Date: 1596498370 2020/08/03 23:46:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 nh72icon $NHDT-Date: 1596498370 2020/08/03 23:46:10 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.9 $ */ /* Copyright (c) 1993 by M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/X11/winX.c b/win/X11/winX.c index f74408269..e66172f5b 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winX.c $NHDT-Date: 1717967337 2024/06/09 21:08:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ +/* NetHack 5.0 winX.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.150 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -98,7 +98,7 @@ void (*input_func)(Widget, XEvent *, String *, Cardinal *); int click_x, click_y, click_button; /* Click position on a map window * (filled by set_button_values()). */ int updated_inventory; /* used to indicate perm_invent updating */ -color_attr X11_menu_promptstyle = { NO_COLOR, ATR_NONE }; +static color_attr X11_menu_promptstyle = { NO_COLOR, ATR_NONE }; /* X11/Intrinsic.h prototype has an issue if [[NORETURN]] is used * rather than the old __attribute((noreturn)) under c23 */ @@ -112,6 +112,9 @@ static void X11_error_handler(String) __attribute__((noreturn)); ATTRNORETURN static XtErrorHandler X11_error_handler(String); #endif +boolean X11_blink; +static unsigned blink_interval = 500; /* milliseconds */ + static int X11_io_error_handler(Display *); static int (*old_error_handler)(Display *, XErrorEvent *); @@ -125,6 +128,40 @@ static XtSignalId X11_sig_id; #endif #endif +static void init_menu_nhcolors(struct xwindow *); +static Boolean nhCvtStringToPixel(Display *, XrmValuePtr, Cardinal *, + XrmValuePtr, XrmValuePtr, XtPointer *); +static void get_window_frame_extents(Widget, long *, long *, long *, long *); +#ifndef USE_XFT +static char *fontname_boldify(const char *); +#endif +static void msgkey(Widget, XtPointer, XEvent *, Boolean *); +static void nh_keyscroll(Widget, XEvent *, String *, Cardinal *); +static char *X11_getmsghistory(boolean); +static void X11_putmsghistory(const char *, boolean); +static void X11_init_nhwindows(int *, char **); +static void X11_askname(void); +static void X11_get_nh_event(void); +static void X11_suspend_nhwindows(const char *); +static void X11_resume_nhwindows(void); +static void X11_clear_nhwindow(winid); +static void X11_display_nhwindow(winid, boolean); +static void X11_curs(winid, int, int); +static void X11_putstr(winid, int, const char *); +static void X11_display_file(const char *, boolean); +static void X11_mark_synch(void); +static void X11_wait_synch(void); +static void X11_raw_print_bold(const char *); +static int X11_nhgetch(void); +static int X11_nh_poskey(coordxy *, coordxy *, int *); +static int X11_doprev_message(void); +static char X11_yn_function(const char *, const char *, char); +static void X11_number_pad(int); +static void X11_delay_output(void); +static void X11_outrip(winid, int, time_t); +static void X11_preference_update(const char *); +static win_request_info *X11_ctrl_nhwindow(winid, int, win_request_info *); + /* Interface definition, for windows.c */ struct window_procs X11_procs = { WPID(X11), @@ -135,6 +172,7 @@ struct window_procs X11_procs = { #ifdef STATUS_HILITES | WC2_RESET_STATUS | WC2_HILITE_STATUS #endif + | WC2_EXTRASTATUS | WC2_HITPOINTBAR | WC2_MENU_SHIFT ), {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ X11_init_nhwindows, @@ -199,6 +237,7 @@ static void release_yn_widgets(void); static int input_event(int); static void win_visible(Widget, XtPointer, XEvent *, Boolean *); static void init_standard_windows(void); +static void blink_callback(XtPointer client_data, XtIntervalId *timer); /* * Local variables. @@ -209,7 +248,7 @@ static winid message_win = WIN_ERR, /* These are the winids of the message, */ status_win = WIN_ERR; /* are created in init_windows(). */ static Pixmap icon_pixmap = None; /* Pixmap for icon. */ -void +static void X11_putmsghistory(const char *msg, boolean is_restoring) { if (WIN_MESSAGE != WIN_ERR) { @@ -220,7 +259,7 @@ X11_putmsghistory(const char *msg, boolean is_restoring) } } -char * +static char * X11_getmsghistory(boolean init) { if (WIN_MESSAGE != WIN_ERR) { @@ -303,7 +342,7 @@ get_nhcolor(struct xwindow *wp, int clr) return wp->nh_colors[0]; } -void +static void init_menu_nhcolors(struct xwindow *wp) { static const char *mapCLR_to_res[CLR_MAX] = { @@ -387,7 +426,7 @@ init_menu_nhcolors(struct xwindow *wp) * allocate the exact color, they puke and give you something stupid. * This is an attempt to find some close readonly cell and use it. */ -XtConvertArgRec const nhcolorConvertArgs[] = { +static XtConvertArgRec const nhcolorConvertArgs[] = { { XtWidgetBaseOffset, (XtPointer) (ptrdiff_t) XtOffset(Widget, core.screen), sizeof (Screen *) }, @@ -496,7 +535,7 @@ nhApproxColor( return True; } -Boolean +static Boolean nhCvtStringToPixel( Display *dpy, XrmValuePtr args, Cardinal *num_args, @@ -589,7 +628,7 @@ nhCvtStringToPixel( } /* Ask the WM for window frame size */ -void +static void get_window_frame_extents( Widget w, long *top, long *bottom, @@ -665,8 +704,9 @@ get_widget_window_geometry( *y -= top; } +#ifndef USE_XFT /* Change the full font name string so the weight is "bold" */ -char * +static char * fontname_boldify(const char *fontname) { static char buf[BUFSZ]; @@ -714,6 +754,7 @@ load_boldfont(struct xwindow *wp, Widget w) fontname = fontname_boldify(XGetAtomName(dpy, (Atom)ret)); wp->boldfs = XLoadQueryFont(dpy, fontname); } +#endif /* !USE_XFT */ /* ARGSUSED */ static void @@ -747,29 +788,43 @@ nhFreePixel( * assumption of ascent + descent is not always valid. */ Dimension -nhFontHeight(Widget w) +nhFontHeight(Widget w, int win_type) { +#ifdef USE_XFT + + XftFont *font = X11_new_font(w, 0, win_type); + Dimension height = X11_font_height(font); + X11_release_font(w, font); + return height; + +#else /* !USE_XFT */ + + Arg args[1]; + XFontStruct *fs; + + nhUse(win_type); + #ifdef _XawTextSink_h - Widget sink; + Widget sink = NULL; XawTextPosition pos = 0; int resWidth, resHeight; - Arg args[1]; XtSetArg(args[0], XtNtextSink, &sink); XtGetValues(w, args, 1); - XawTextSinkFindPosition(sink, pos, 0, 0, 0, &pos, &resWidth, &resHeight); - return resHeight; -#else - XFontStruct *fs; - Arg args[1]; + if (sink != NULL) { + XawTextSinkFindPosition(sink, pos, 0, 0, 0, &pos, &resWidth, &resHeight); + return resHeight; + } +#endif XtSetArg(args[0], XtNfont, &fs); XtGetValues(w, args, 1); /* Assume font height is ascent + descent. */ - return = fs->ascent + fs->descent; -#endif + return fs->ascent + fs->descent; + +#endif /* ?USE_XFT */ } static String *default_resource_data = 0, /* NULL-terminated arrays */ @@ -941,13 +996,13 @@ X11_raw_print(const char *str) (void) puts(str); } -void +static void X11_raw_print_bold(const char *str) { (void) puts(str); } -void +static void X11_curs(winid window, int x, int y) { check_winid(window); @@ -965,7 +1020,7 @@ X11_curs(winid window, int x, int y) window_list[window].cursy = y; } -void +static void X11_putstr(winid window, int attr, const char *str) { winid new_win; @@ -1013,19 +1068,19 @@ X11_putstr(winid window, int attr, const char *str) } /* We do event processing as a callback, so this is a null routine. */ -void +static void X11_get_nh_event(void) { return; } -int +static int X11_nhgetch(void) { return input_event(EXIT_ON_KEY_PRESS); } -int +static int X11_nh_poskey(coordxy *x, coordxy *y, int *mod) { int val = input_event(EXIT_ON_KEY_OR_BUTTON_PRESS); @@ -1105,8 +1160,10 @@ X11_create_nhwindow(int type) wp->pixel_height = 0; wp->keep_window = FALSE; wp->nh_colors_inited = FALSE; +#ifndef USE_XFT wp->boldfs = (XFontStruct *) 0; wp->boldfs_dpy = (Display *) 0; +#endif wp->title = (char *) 0; switch (type) { @@ -1132,7 +1189,7 @@ X11_create_nhwindow(int type) return window; } -void +static void X11_clear_nhwindow(winid window) { struct xwindow *wp; @@ -1158,7 +1215,7 @@ X11_clear_nhwindow(winid window) } } -void +static void X11_display_nhwindow(winid window, boolean blocking) { struct xwindow *wp; @@ -1248,11 +1305,13 @@ X11_destroy_nhwindow(winid window) WIN_INVEN = WIN_ERR; } +#ifndef USE_XFT if (wp->boldfs) { XFreeFont(wp->boldfs_dpy, wp->boldfs); wp->boldfs = (XFontStruct *) 0; wp->boldfs_dpy = (Display *) 0; } +#endif if (wp->title) { free(wp->title); @@ -1309,7 +1368,7 @@ X11_update_inventory(int arg) return; } -win_request_info * +static win_request_info * X11_ctrl_nhwindow( winid window UNUSED, int request UNUSED, @@ -1332,7 +1391,7 @@ X11_ctrl_nhwindow( } /* The current implementation has all of the saved lines on the screen. */ -int +static int X11_doprev_message(void) { return 0; @@ -1355,7 +1414,7 @@ X11_nhbell(void) } } -void +static void X11_mark_synch(void) { if (x_inited) { @@ -1372,7 +1431,7 @@ X11_mark_synch(void) } } -void +static void X11_wait_synch(void) { if (x_inited) { @@ -1382,13 +1441,13 @@ X11_wait_synch(void) } /* Both resume_ and suspend_ are called from ioctl.c and unixunix.c. */ -void +static void X11_resume_nhwindows(void) { return; } /* ARGSUSED */ -void +static void X11_suspend_nhwindows(const char *str) { nhUse(str); @@ -1398,7 +1457,7 @@ X11_suspend_nhwindows(const char *str) /* Under X, we don't need to initialize the number pad. */ /* ARGSUSED */ -void +static void X11_number_pad(int state) /* called from options.c */ { nhUse(state); @@ -1407,7 +1466,7 @@ X11_number_pad(int state) /* called from options.c */ } #ifdef GRAPHIC_TOMBSTONE -void +static void X11_outrip(winid window, int how, time_t when) { struct xwindow *wp; @@ -1507,6 +1566,22 @@ static XtResource resources[] = { { nhStr("pilemark_color"), nhStr("Pilemark_color"), XtRPixel, sizeof(XtRPixel), XtOffset(AppResources *, pilemark_color), XtRString, nhStr("Green") }, +#ifdef USE_XFT + { nhStr("font_map"), nhStr("Font_map"), XtRString, sizeof(String), + XtOffset(AppResources *, font_map), XtRString, nhStr("mono-10") }, + { nhStr("font_menu"), nhStr("Font_menu"), XtRString, sizeof(String), + XtOffset(AppResources *, font_menu), XtRString, nhStr("sans-10") }, + { nhStr("font_message"), nhStr("Font_message"), XtRString, sizeof(String), + XtOffset(AppResources *, font_message), XtRString, nhStr("sans-10") }, + { nhStr("font_status"), nhStr("Font_status"), XtRString, sizeof(String), + XtOffset(AppResources *, font_status), XtRString, nhStr("sans-10") }, + { nhStr("font_text"), nhStr("Font_text"), XtRString, sizeof(String), + XtOffset(AppResources *, font_text), XtRString, nhStr("mono-10") }, +#ifdef GRAPHIC_TOMBSTONE + { nhStr("font_rip"), nhStr("Font_rip"), XtRString, sizeof(String), + XtOffset(AppResources *, font_rip), XtRString, nhStr("sans-9") }, +#endif +#endif #ifdef GRAPHIC_TOMBSTONE { nhStr("tombstone"), nhStr("Tombstone"), XtRString, sizeof(String), XtOffset(AppResources *, tombstone), XtRString, nhStr("rip.xpm") }, @@ -1562,7 +1637,7 @@ X11_io_error_handler(Display *display) return 0; } -void +static void X11_init_nhwindows(int *argcp, char **argv) { int i; @@ -1570,6 +1645,9 @@ X11_init_nhwindows(int *argcp, char **argv) Arg args[4]; uid_t savuid; + /* Request tabbed menu columns */ + iflags.menu_tab_sep = TRUE; + /* Init windows to nothing. */ for (i = 0; i < MAX_WINDOWS; i++) window_list[i].type = NHW_NONE; @@ -1609,6 +1687,7 @@ X11_init_nhwindows(int *argcp, char **argv) (ArgList) args, num_args); XtOverrideTranslations(toplevel, XtParseTranslationTable("WM_PROTOCOLS: X11_hangup()")); + XtAppAddTimeOut(app_context, blink_interval, blink_callback, NULL); /* We don't need to realize the top level widget. */ @@ -1665,6 +1744,20 @@ X11_init_nhwindows(int *argcp, char **argv) X11_putstr(WIN_MESSAGE, 0, copyright_banner_line(i)); } +static void +blink_callback(XtPointer client_data, XtIntervalId *timer) +{ + nhUse(timer); +#ifdef STATUS_HILITES + X11_tty_status_blink(); +#endif + X11_blink_labels(); + + X11_blink = !X11_blink; + /* Do it again */ + XtAppAddTimeOut(app_context, blink_interval, blink_callback, client_data); +} + /* * All done. */ @@ -1750,6 +1843,7 @@ d_timeout(XtPointer client_data, XtIntervalId *id) mesg->type = ClientMessage; mesg->message_type = XA_STRING; mesg->format = 8; + mesg->data.b[0] = DELAY_EVENT_ID; XSendEvent(XtDisplay(window_list[WIN_MAP].w), XtWindow(window_list[WIN_MAP].w), False, NoEventMask, (XEvent *) mesg); @@ -1761,16 +1855,18 @@ d_timeout(XtPointer client_data, XtIntervalId *id) * function will send an event to the map window which will be waiting * for a sent event. */ -void +static void X11_delay_output(void) { if (!x_inited) return; - - (void) XtAppAddTimeOut(app_context, 30L, d_timeout, (XtPointer) 0); - - /* The timeout function will enable the event loop exit. */ - (void) x_event(EXIT_ON_SENT_EVENT); +#ifdef TIMED_DELAY + if (flags.nap && !iflags.debug_fuzzer) { + (void) XtAppAddTimeOut(app_context, 50L, d_timeout, (XtPointer) 0); + /* The timeout function will enable the event loop exit. */ + (void) x_event(EXIT_ON_SENT_EVENT); + } +#endif } /* X11_hangup ------------------------------------------------------------- */ @@ -1849,7 +1945,7 @@ askname_done(Widget w, XtPointer client_data, XtPointer call_data) /* ask player for character's name to replace generic name "player" (or other values; see config.h) after 'nethack -u player' or OPTIONS=name:player */ -void +static void X11_askname(void) { Widget popup, dialog; @@ -2067,17 +2163,14 @@ X11_getlin( /* uses a menu (with no selectors specified) rather than a text window to allow previous_page and first_menu actions to move backwards */ -void +static void X11_display_file(const char *str, boolean complain) { dlb *fp; winid newwin; struct xwindow *wp; - anything any; - menu_item *menu_list; #define LLEN 128 char line[LLEN]; - int clr = 0; /* Use the port-independent file opener to see if the file exists. */ fp = dlb_fopen(str, RDTMODE); @@ -2087,14 +2180,11 @@ X11_display_file(const char *str, boolean complain) return; /* it doesn't exist, ignore */ } - newwin = X11_create_nhwindow(NHW_MENU); + newwin = X11_create_nhwindow(NHW_TEXT); wp = &window_list[newwin]; - X11_start_menu(newwin, MENU_BEHAVE_STANDARD); - any = cg.zeroany; while (dlb_fgets(line, LLEN, fp)) { - X11_add_menu(newwin, &nul_glyphinfo, &any, 0, 0, ATR_NONE, - clr, line, MENU_ITEMFLAGS_NONE); + X11_putstr(newwin, 0, line); } (void) dlb_fclose(fp); @@ -2102,9 +2192,7 @@ X11_display_file(const char *str, boolean complain) if (str) wp->title = dupstr(str); - wp->menu_information->permi = FALSE; - wp->menu_information->disable_mcolors = TRUE; - (void) X11_select_menu(newwin, PICK_NONE, &menu_list); + (void) X11_display_nhwindow(newwin, TRUE); X11_destroy_nhwindow(newwin); } @@ -2393,6 +2481,7 @@ X11_yn_function_core( (void) memset(buf2, 'X', 25), buf2[25] = '\0'; /* 25 'X's */ yn_minwidth = (Dimension) XTextWidth(yn_font, buf2, (int) strlen(buf2)); + X11_wrap_widget_if_Xft(yn_label, NHW_MESSAGE); } } @@ -2401,6 +2490,7 @@ X11_yn_function_core( num_args = 0; XtSetArg(args[num_args], XtNlabel, buf); num_args++; XtSetValues(yn_label, args, num_args); + X11_update_label_if_Xft(yn_label); /* for !slow, pop up the prompt+response widget */ if (!appResources.slow) { @@ -2444,6 +2534,7 @@ X11_yn_function_core( num_args = 0; XtSetArg(args[num_args], XtNlabel, " "); num_args++; XtSetValues(yn_label, args, num_args); + X11_update_label_if_Xft(yn_label); input_func = 0; /* keystrokes now belong to the map */ highlight_yn(FALSE); /* disguise yn_label as part of map */ @@ -2462,7 +2553,7 @@ X11_yn_function_core( /* X11-specific edition of yn_function(), the routine called by the core to show a prompt and get a single key answer, often 'y' vs 'n' */ -char +static char X11_yn_function( const char *ques, /* prompt text */ const char *choices, /* allowed response chars; any char if Null */ @@ -2475,7 +2566,7 @@ X11_yn_function( /* used when processing window-capability-specific run-time options; we support toggling tiles on and off via iflags.wc_tiled_map */ -void +static void X11_preference_update(const char *pref) { if (!strcmp(pref, "tiled_map")) { @@ -2506,7 +2597,7 @@ input_event(int exit_condition) } /*ARGSUSED*/ -void +static void msgkey(Widget w, XtPointer data, XEvent *event, Boolean *continue_to_dispatch) { Cardinal num = 0; @@ -2567,6 +2658,7 @@ highlight_yn(boolean init) XtSetArg(args[0], XtNforeground, vals.foreground); XtSetArg(args[1], XtNbackground, vals.background); XtSetValues(yn_label, args, TWO); + X11_update_label_if_Xft(yn_label); } } else swap_fg_bg(yn_label); @@ -2634,6 +2726,7 @@ init_standard_windows(void) XtSetArg(args[num_args], nhStr(XtNresizable), True); num_args++; XtSetArg(args[num_args], nhStr(XtNlabel), " "); num_args++; XtSetValues(yn_label, args, num_args); + X11_wrap_widget_if_Xft(yn_label, NHW_MESSAGE); } /* @@ -2699,7 +2792,7 @@ init_standard_windows(void) * Resize to at most full-screen. */ { -#define TITLEBAR_SPACE 18 /* Leave SOME screen for window decorations */ +#define TITLEBAR_SPACE 100 /* Leave SOME screen for window decorations and task bar */ int screen_width = WidthOfScreen(XtScreen(wp->w)); int screen_height = HeightOfScreen(XtScreen(wp->w)) - TITLEBAR_SPACE; @@ -2835,7 +2928,7 @@ find_scrollbars( * Scroll a viewport, using standard NH 1,2,3,4,6,7,8,9 directions. */ /*ARGSUSED*/ -void +static void nh_keyscroll(Widget viewport, XEvent *event, String *params, Cardinal *num_params) { @@ -2922,4 +3015,319 @@ nh_keyscroll(Widget viewport, XEvent *event, String *params, } } +/* Convert CP437 or DECgraphics to Unicode */ +X11_map_symbol +X11_glyph_char(const glyph_info *glyphinfo) +{ +#ifdef ENHANCED_SYMBOLS + /* CP437 to Unicode mapping according to the Unicode Consortium */ + static const uint16 cp437[256] = { + 0x0020, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, + 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302, + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 + }; + /* Display DECgraphics as Unicode */ + static const uint16 decgraphics[128] = { + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x2192, 0x2190, 0x2191, 0x2193, 0x002F, + 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, + 0x2666, 0x2592, 0x0062, 0x0063, 0x0064, 0x0065, 0x00B0, 0x00B1, + 0x2591, 0x00A4, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA, + 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C, + 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F + }; + X11_map_symbol och; + + if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u != NULL && glyphinfo->gm.u->utf8str != NULL) { + och = glyphinfo->gm.u->utf32ch; + } else { + och = (uchar) glyphinfo->ttychar; + if (SYMHANDLING(H_IBM)) { + och = cp437[och]; + } else if ((SYMHANDLING(H_DEC) || SYMHANDLING(H_CURS)) && och >= 0x80) { + och = decgraphics[och & 0x7F]; + } + } + + return och; +#else + return (char) glyphinfo->ttychar; +#endif +} + +#ifndef USE_XFT +/* Given an XFontStruct, return a corresponding bold font */ +XFontStruct * +X11_bold_font(Display *display, XFontStruct *font) +{ + Atom font_atom; + if (!XGetFontProperty(font, XA_FONT, &font_atom)) { + return NULL; + } + + const char *font_name = XGetAtomName(display, font_atom); + if (font_name == NULL) { + return NULL; + } + + char *bold_font = fontname_boldify(font_name); + XFontStruct *font2 = XLoadQueryFont(display, bold_font); + + return font2; +} + +/* Given an XFontStruct, return a corresponding italic font */ +XFontStruct * +X11_italic_font(Display *display, XFontStruct *font) +{ + Atom font_atom; + if (!XGetFontProperty(font, XA_FONT, &font_atom)) { + return NULL; + } + + const char *font_name = XGetAtomName(display, font_atom); + if (font_name == NULL) { + return NULL; + } + + /* Proceed to the slant */ + unsigned dashes = 4; + const char *p = font_name; + while (dashes != 0) { + const char *q = strchr(p, '-'); + if (q == NULL) { + break; + } + p = q + 1; + --dashes; + } + + /* Try substituting "i" for the slant */ + char italic_font[BUFSZ]; + int pre = (int)(p - font_name); + p += strcspn(p, "-"); + Snprintf(italic_font, sizeof(italic_font), "%.*sI%s", pre, font_name, p); + XFontStruct *font2 = XLoadQueryFont(display, italic_font); + if (font2 != NULL) { + return font2; + } + + /* Try substituting "o" */ + Snprintf(italic_font, sizeof(italic_font), "%.*sO%s", pre, font_name, p); + font2 = XLoadQueryFont(display, italic_font); + + return font2; +} + +#ifdef ENHANCED_SYMBOLS +/* Given an XFontStruct, return a corresponding font that supports Unicode */ +XFontStruct * +X11_unicode_font(Display *display, XFontStruct *font) +{ + Atom font_atom; + if (!XGetFontProperty(font, XA_FONT, &font_atom)) { + return NULL; + } + + const char *font_name = XGetAtomName(display, font_atom); + if (font_name == NULL) { + return NULL; + } + + /* Proceed to the registry name */ + unsigned dashes = 13; + const char *p = font_name; + while (dashes != 0) { + const char *q = strchr(p, '-'); + if (q == NULL) { + break; + } + p = q + 1; + --dashes; + } + + /* Substitute "iso10646-1" for the registry name and encoding */ + size_t len = (size_t) (p - font_name); + char unicode_font[BUFSZ]; + if (dashes != 0 || len + 11 > sizeof(unicode_font)) { + return NULL; + } + + memcpy(unicode_font, font_name, len); + strcpy(unicode_font + len, "iso10646-1"); + font_name = unicode_font; + + XFontStruct *unifont = XLoadQueryFont(display, font_name); + return unifont; +} +#endif /* ENHANCED_SYMBOLS */ +#endif /* !USE_XFT */ + +#ifdef USE_XFT + +/* Open a vector font for the given widget */ + +extern XftFont * +X11_new_font(Widget w, unsigned attrs, int win_type) +{ + const char *font_name = NULL; + const char *iflags_font_name = NULL; + int font_size = 0; + char name[512]; + + switch (win_type) { + case NHW_MESSAGE: + font_name = appResources.font_message; + iflags_font_name = iflags.wc_font_message; + font_size = iflags.wc_fontsiz_message; + break; + + case NHW_STATUS: + font_name = appResources.font_status; + iflags_font_name = iflags.wc_font_status; + font_size = iflags.wc_fontsiz_status; + break; + + case NHW_MAP: + font_name = appResources.font_map; + iflags_font_name = iflags.wc_font_map; + font_size = iflags.wc_fontsiz_map; + break; + + case NHW_MENU: + case NHW_PERMINVENT: + font_name = appResources.font_menu; + iflags_font_name = iflags.wc_font_menu; + font_size = iflags.wc_fontsiz_menu; + break; + + case NHW_TEXT: + font_name = appResources.font_text; + iflags_font_name = iflags.wc_font_text; + font_size = iflags.wc_fontsiz_text; + break; + + default: + break; + } + + if (font_name == NULL) { + font_name = "mono-10"; + } + + /* Override the font name if specified in the configuration file */ + if (iflags_font_name != NULL) { + font_name = iflags_font_name; + } + + /* + * Specify font size as follows: + * * Use any font size specified in the configuration file + * * If no such size is specified, use the one in the font name; + * e.g., "Courier-14" specifies 14 points + * * If still no size, use 10 points + */ + size_t name_len = strlen(font_name); + const char *dash = strrchr(font_name, '-'); + if (dash) { + char *end; + long size = strtol(dash + 1, &end, 10); + if (*end == '\0') { + /* The name ends in a size */ + name_len = (size_t) (dash - font_name); + /* Use font_size if specified; + else use the size from font_name */ + if (font_size <= 0) { + font_size = (int) size; + } + } + } + + /* Use 10 if no size specified */ + if (font_size <= 0) { + font_size = 10; + } + + /* Set reasonable bounds on the font size */ + font_size = min(max(font_size, 6), 50); + + Snprintf(name, sizeof(name), "%.*s-%d%s%s", + (int) name_len, font_name, font_size, + (attrs & HL_BOLD) ? ":bold" : "", + (attrs & HL_ITALIC) ? ":italic" : ""); + + Display *display = XtDisplay(w); + XftFont *font = XftFontOpenName(display, DefaultScreen(display), name); + + return font; +} + +/* Free the font returned by X11_new_font */ + +void +X11_release_font(Widget w, XftFont *font) +{ + Display *display = XtDisplay(w); + XftFontClose(display, font); +} + +/* Assign a new color having the given RGB components */ + +void +X11_new_color(Widget w, Pixel pixel, XftColor *color) +{ + XRenderColor rcolor; + rcolor.red = ((pixel >> 16) & 0xFF) * 0x0101; + rcolor.green = ((pixel >> 8) & 0xFF) * 0x0101; + rcolor.blue = ((pixel >> 0) & 0xFF) * 0x0101; + rcolor.alpha = 0xFFFF; + + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + + XftColorAllocValue(display, visual, cmap, &rcolor, color); +} + +#endif /* USE_XFT */ + /*winX.c*/ diff --git a/win/X11/winlabel.c b/win/X11/winlabel.c new file mode 100644 index 000000000..5842ef49f --- /dev/null +++ b/win/X11/winlabel.c @@ -0,0 +1,779 @@ +/* NetHack 5.0 winlabel.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.50 $ */ +/* Copyright (c) Ray Chason, 2026 */ +/* NetHack may be freely redistributed. See license for details. */ + +#include +#include +#include + +#include + +#ifdef PRESERVE_NO_SYSV +#ifdef SYSV +#undef SYSV +#endif +#undef PRESERVE_NO_SYSV +#endif + +#include "hack.h" +#include "winX.h" + +/* Declarations depending on Xft support or none */ +static int X11_text_width(Display *, X11_Font *, const char *, size_t, + const int *, unsigned); + +/* Data attached to a wrapped widget */ +typedef struct WidgetData { + /* Displayed text */ + Pixmap pixmap; + + /* Attributes */ + unsigned attrs; + boolean highlight; + + /* Fonts for italic, bold and bold-italic */ + X11_Font *font[4]; /* To use the fonts */ +#ifdef USE_XFT + int win_type; +#else /* !USE_XFT */ + X11_Font *font_ptr[4]; /* To free the fonts */ +#endif /* ?USE_XFT */ + + /* Percentage bar */ + unsigned percent; + Pixel bar_color; + + /* Columns */ + int *columns; + unsigned num_cols; +} WidgetData; + +/* Bits for WidgetData::font */ +enum { font_bold = 1, font_italic = 2 }; + +static boolean check_label(Widget); +static void delete_callback(Widget, XtPointer, XtPointer); +static void update_label(Widget, WidgetData *); +static void set_tab_stops(Widget, WidgetData *, const char *); +static void allocate_font(Widget, WidgetData *, unsigned); +static void free_fonts(Widget, WidgetData *); + +static WidgetData *add_widget(Widget w); +static void delete_widget(Widget w); +static WidgetData *get_widget_data(Widget w); + +/* + * Create a wrapper for labelWidgetClass and its descendant classes. + * + * A table is maintained to associate each widget with a data block. + * The block contains additional fonts for italic, bold and bold-italic, + * attribute flags and a percentage bar. + */ +void +X11_wrap_widget(Widget w, int win_type) +{ + /* We shouldn't use this for anything other than labels and subclasses + of labels */ + if (!check_label(w)) { + impossible("Widget is not a Label or of a class derived from Label"); + return; + } + + /* Only wrap once */ + if (get_widget_data(w)) { + impossible("Tried to wrap a widget twice"); + return; + } + + /* Attach a destroy callback to reclaim resources attached to the widget */ + XtAddCallback(w, XtNdestroyCallback, delete_callback, NULL); + + /* Create the structure with its initial settings */ + WidgetData *data = add_widget(w); + + /* Copy resources from the created widget */ +#ifdef USE_XFT + data->win_type = win_type; + allocate_font(w, data, 0); +#else /* !USE_XFT */ + Cardinal num_args2 = 0; + Arg args2[1]; + XtSetArg(args2[num_args2], XtNfont, &data->font[0]); num_args2++; + XtGetValues(w, args2, num_args2); + nhUse(win_type); +#endif /* ?USE_XFT */ + + /* Create the pixmap for the first time */ + update_label(w, data); +} + +/* Callback when the widget is deleted */ +static void +delete_callback(Widget w, XtPointer client_data, XtPointer call_data) +{ + nhUse(client_data); + nhUse(call_data); + + /* + * We shouldn't get here with any widget for which check_label returns + * false, because such widgets will not have this callback set + */ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + Display *display = XtDisplay(w); + if (data->pixmap != 0) { + XFreePixmap(display, data->pixmap); + } + free_fonts(w, data); + free(data->columns); + free(data); + } + + delete_widget(w); +} + +/* Return true if the widget is a Label or of a class derived from Label */ +static boolean +check_label(Widget w) +{ + return XtIsSubclass(w, labelWidgetClass); +} + +/* Update the label's pixmap */ +void +X11_update_label(Widget w) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + update_label(w, data); + } +} + +void +X11_set_attrs(Widget w, unsigned attrs) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + data->attrs = attrs; + update_label(w, data); + } +} + +void +X11_set_highlight(Widget w, boolean highlight) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + data->highlight = highlight; + update_label(w, data); + } +} + +void +X11_set_percent(Widget w, unsigned percent, Pixel color) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + data->percent = percent; + data->bar_color = color; + update_label(w, data); + } +} + +void +X11_set_column_widths(Widget w, const int *col_widths, unsigned num_cols) +{ + WidgetData *data = get_widget_data(w); + if (data != NULL) { + free(data->columns); + data->columns = (int *) alloc(sizeof(data->columns[0]) * (num_cols + 1)); + data->columns[0] = 0; + if (num_cols != 0) { + for (unsigned i = 0; i < num_cols; ++i) { + data->columns[i+1] = data->columns[i] + col_widths[i]; + } + } + data->num_cols = num_cols; + update_label(w, data); + } +} + +/* Update the label's pixmap */ +/* This is called from functions that have altered the data block, and already + have a pointer to it */ +static void +update_label(Widget w, WidgetData *data) +{ + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + int depth = DefaultDepthOfScreen(screen); + + Pixmap new_pixmap = 0; + Cardinal num_args; + Arg args[10]; + + /* Select the font */ + unsigned font_idx = 0; + if (data->attrs & HL_BOLD) { + font_idx |= font_bold; + allocate_font(w, data, font_idx); + } + if (data->attrs & HL_ITALIC) { + font_idx |= font_italic; + allocate_font(w, data, font_idx); + } + X11_Font *font = data->font[font_idx]; + + String label; + Boolean sens; /* Make dim if not sensitive */ + XtJustify justify; /* Left, center, right */ + Pixel fgpixel; /* Colors for the first pass */ + Pixel bgpixel; + Boolean resize; /* Resizable? */ + num_args = 0; + XtSetArg(args[num_args], XtNlabel, &label); num_args++; + XtSetArg(args[num_args], XtNsensitive, &sens); num_args++; + XtSetArg(args[num_args], XtNjustify, &justify); num_args++; + XtSetArg(args[num_args], XtNforeground, &fgpixel); num_args++; + XtSetArg(args[num_args], XtNbackground, &bgpixel); num_args++; + XtSetArg(args[num_args], XtNresize, &resize); num_args++; + XtGetValues(w, args, num_args); + unsigned attrs = data->attrs; + if (!sens) { + attrs |= HL_DIM; + } + + /* Set the tab stops if needed */ + if (data->columns == NULL && strchr(label, '\t') != NULL) { + set_tab_stops(w, data, label); + } + + /* Dimensions of pixmap */ + Dimension width; + Dimension height; + if (resize) { + /* Render the widest width and the total height of the lines */ + size_t i = 0; + width = 0; + height = 0; + while (label[i] != '\0') { + size_t line1 = strcspn(label + i, "\n"); + size_t line2 = line1; + /* Exclude \r from the rendering */ + if (line2 != 0 && label[i + line2 - 1] == '\r') { + --line2; + } + + /* Get the width of the line */ + int lwidth = X11_text_width(display, font, label + i, line2, + data->columns, data->num_cols); + + /* Update pixmap dimensions */ + width = max(lwidth, width); + ++height; + + /* Advance to next line */ + i += line1; + if (label[i] == '\n') { + ++i; + } + } + + /* Always size for at least one line */ + height = max(height, 1); + + /* Convert height to pixels */ + height *= X11_font_height(font); + } else { + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &width); num_args++; + XtSetArg(args[num_args], XtNheight, &height); num_args++; + XtGetValues(w, args, num_args); + } + if (width < 2 || height < 2) { + /* Pixmap must not have zero size, or a crash will ensue; + minimum size 2 simplifies border logic */ + width = max(width, 2); + height = max(height, 2); + fgpixel = bgpixel; + } + + /* Use the full width of the widget if a percentage bar is set or inverse + is in effect */ + if (data->percent != 0 || (attrs & HL_INVERSE) != 0 || data->highlight) { + Dimension wwidth, iwidth; + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtSetArg(args[num_args], XtNinternalWidth, &iwidth); num_args++; + XtGetValues(w, args, num_args); + width = max(width, wwidth - iwidth*2); + } + + /* Create the pixmap */ + new_pixmap = XCreatePixmap(display, RootWindowOfScreen(screen), + width, height, depth); + + /* If a percent bar is specified, make two passes over the text and render + the percent bar in the second pass */ + for (unsigned pass = 0; pass < 2; ++pass) { + XGCValues values; + + if (!!(attrs & HL_INVERSE) ^ !!data->highlight) { + values.foreground = bgpixel; + values.background = fgpixel; + } else { + values.foreground = fgpixel; + values.background = bgpixel; + } + if (attrs & HL_DIM) { + values.foreground = (values.foreground & 0xFEFEFE) >> 1; + values.background = (values.background & 0xFEFEFE) >> 1; + } + if ((attrs & HL_BLINK) && X11_blink) { + values.foreground = values.background; + } + +#ifdef USE_XFT + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, new_pixmap, visual, cmap); + XftColor fgcolor, bgcolor; + X11_new_color(w, values.foreground, &fgcolor); + X11_new_color(w, values.background, &bgcolor); +#else /* !USE_XFT */ + values.font = font->fid; + values.function = GXcopy; + GC ggc = XtGetGC(w, + GCFunction | GCForeground | GCBackground | GCFont, + &values); +#endif /* ?USE_XFT */ + if (pass == 1) { + /* Percent bar will occupy this area */ + XRectangle clip = { + .x = 0, + .y = 0, + .width = width * data->percent / 100, + .height = height + }; +#ifdef USE_XFT + XftDrawSetClipRectangles(draw, 0, 0, &clip, 1); +#else /* !USE_XFT */ + XSetClipRectangles(display, ggc, 0, 0, &clip, 1, Unsorted); +#endif /* ?USE_XFT */ + } + + /* Draw a border for inverse and highlight together */ + /* Otherwise, fill with the background color */ +#ifdef USE_XFT + if (!((attrs & HL_INVERSE) && data->highlight)) { + XftDrawRect(draw, &bgcolor, 0, 0, width, height); + } else { + XftDrawRect(draw, &fgcolor, 0, 0, width, height); + } +#else /* !USE_XFT */ + if (!((attrs & HL_INVERSE) && data->highlight)) { + XSetForeground(display, ggc, values.background); + } + XFillRectangle(display, new_pixmap, ggc, 0, 0, width, height); + XSetForeground(display, ggc, values.foreground); +#endif /* ?USE_XFT */ + + int y = font->ascent; + size_t i = 0; + while (label[i] != '\0') { + size_t line1 = strcspn(label + i, "\n"); + size_t line2 = line1; + /* Exclude \r from the rendering */ + if (line2 != 0 && label[i + line2 - 1] == '\r') { + --line2; + } + + /* Get the width of the line */ + int lwidth = X11_text_width(display, font, label + i, line2, + data->columns, data->num_cols); + + /* Place the line horizontally */ + int x = 0; + switch (justify) { + case XtJustifyLeft: + x = 0; + break; + + case XtJustifyCenter: + x = (width - lwidth) / 2; + break; + + case XtJustifyRight: + x = width - lwidth; + break; + } + + /* Render the line */ +#ifdef USE_XFT + XftDrawRect(draw, &bgcolor, x, y - font->ascent, lwidth, X11_font_height(font)); +#else + XSetForeground(display, ggc, values.background); + XFillRectangle(display, new_pixmap, ggc, x, y - font->ascent, lwidth, X11_font_height(font)); + XSetForeground(display, ggc, values.foreground); +#endif + size_t j = 0; + unsigned col = 0; + while (j < line2) { + size_t line3; + int pos; + if (data->num_cols == 0) { + /* Columns not set */ + line3 = line2; + pos = 0; + } else { + line3 = min(strcspn(label + i + j, "\t\n"), line2); + pos = data->columns[min(col, data->num_cols)]; + } +#ifdef USE_XFT + XftDrawString8(draw, &fgcolor, font, x + pos, y, + (const FcChar8 *) (label + i + j), line3); +#else + XDrawString(display, new_pixmap, ggc, + x + pos, y, + label + i + j, line3); +#endif + j += line3; + if (j < line2) { + ++j; + } + ++col; + } + + /* Draw the underline if requested */ + if (attrs & HL_ULINE) { +#ifdef USE_XFT + XftDrawRect(draw, &fgcolor, x, y, lwidth, 1); +#else + XDrawLine(display, new_pixmap, ggc, + x, y, + x + lwidth - 1, y); +#endif + } + + y += X11_font_height(font); + + /* Advance to next line */ + i += line1; + if (label[i] == '\n') { + ++i; + } + } + + /* Ensure a one-pixel border if both inverse and highlight */ + if ((attrs & HL_INVERSE) && data->highlight) { +#ifdef USE_XFT + XftDrawRect(draw, &fgcolor, 0, 0, width, 1); + XftDrawRect(draw, &fgcolor, 0, height-1, width, 1); + XftDrawRect(draw, &fgcolor, 0, 0, 1, height); + XftDrawRect(draw, &fgcolor, width-1, 0, 1, height); +#else + XDrawRectangle(display, new_pixmap, ggc, 0, 0, width-1, height-1); +#endif + } + +#ifdef USE_XFT + XftColorFree(display, visual, cmap, &fgcolor); + XftColorFree(display, visual, cmap, &bgcolor); + XftDrawDestroy(draw); +#else + XtReleaseGC(w, ggc); +#endif + + /* Set up to display the percent bar on the second pass */ + if (data->percent == 0) { + break; + } + fgpixel = bgpixel; + bgpixel = data->bar_color; + } + + /* Update the pixmap */ + num_args = 0; + XtSetArg(args[num_args], XtNbitmap, new_pixmap); num_args++; + XtSetValues(w, args, num_args); + if (data->pixmap != 0) { + XFreePixmap(display, data->pixmap); + } + data->pixmap = new_pixmap; +} + +/* Set tab stops for text window */ +static void +set_tab_stops(Widget w, WidgetData *data, const char *label) +{ + /* Count columns */ + unsigned col = 0; + unsigned num_cols = 0; + size_t i = 0; + while (label[i] != '\0') { + size_t len = strcspn(label + i, "\t\n"); + ++col; + i += len; + if (label[i] != '\t') { + /* The last column on its line */ + num_cols = max(num_cols, col); + col = 0; + } + if (label[i] != '\0') { + ++i; + } + } + + int *columns = (int *) alloc(num_cols * sizeof(columns[0])); + memset(columns, 0, num_cols * sizeof(columns[0])); + + /* Determine column sizes */ + col = 0; + i = 0; + Display *display = XtDisplay(w); + while (label[i] != '\0') { + size_t len = strcspn(label + i, "\t\n"); + if (label[i+len] == '\t') { + /* A column from label+i to label+i+len */ + int width = X11_column_width(display, data->font[0], label + i, len); + columns[col] = max(columns[col], width); + ++col; + } else { + /* Last column of the line */ + /* This does not participate in sizing the column */ + col = 0; + } + i += len; + if (label[i] != '\0') { + ++i; + } + } + + /* Convert to column positions */ + int pos = 0; + for (unsigned j = 0; j < num_cols; ++j) { + int rpos = pos + columns[j]; + columns[j] = pos; + pos = rpos; + } + + free(data->columns); + data->columns = columns; + data->num_cols = num_cols; +} + +/* Allocate a bold or italic font */ +static void +allocate_font(Widget w, WidgetData *data, unsigned font_idx) +{ +#ifdef USE_XFT + static const unsigned attrs[4] = { + 0, HL_BOLD, HL_ITALIC, HL_BOLD | HL_ITALIC + }; + data->font[font_idx] = X11_new_font(w, attrs[font_idx], data->win_type); +#else + Display *display = XtDisplay(w); + X11_Font *font1 = (font_idx == (font_bold | font_italic)) + ? data->font[font_bold] + : data->font[0]; + data->font_ptr[font_idx] = (font_idx == font_bold) + ? X11_bold_font(display, font1) + : X11_italic_font(display, font1); + data->font[font_idx] = data->font_ptr[font_idx] + ? data->font_ptr[font_idx] + : font1; +#endif +} + +/* Free any allocated fonts */ +static void +free_fonts(Widget w, WidgetData *data) +{ + Display *display = XtDisplay(w); + for (unsigned i = 0; i < 4; ++i) { +#ifdef USE_XFT + if (data->font[i] != NULL) { + XftFontClose(display, data->font[i]); + } + data->font[i] = NULL; +#else + if (data->font_ptr[i] != NULL) { + XFreeFont(display, data->font_ptr[i]); + } + data->font[i] = NULL; + data->font_ptr[i] = NULL; +#endif + } +} + +static int +X11_text_width(Display *display, X11_Font *font, const char *text, size_t length, + const int *columns, unsigned num_cols) +{ + if (num_cols == 0) { + /* Columns have not been set */ + return X11_column_width(display, font, text, length); + } + + /* Width is the position of the last column, plus the width of the string + in the last column */ + + unsigned col = 0; + size_t i = 0; + while (col < num_cols) { + size_t len = strcspn(text + i, "\t\n"); + if (i+len >= length || text[i+len] != '\t') { + break; + } + ++col; + i += len + 1; + } + + int pos = columns[col] + X11_column_width(display, font, text + i, length - i); + + return pos; +} + +////////////////////////////////////////////////////////////////////////////// +// Functions that depend on the font rendering API // +////////////////////////////////////////////////////////////////////////////// + +#ifdef USE_XFT +int +X11_column_width(Display *display, X11_Font *font, const char *text, size_t length) +{ + XGlyphInfo extents; + XftTextExtents8(display, font, (const FcChar8*) text, length, &extents); + return extents.width - extents.x; +} + +int +X11_font_height(X11_Font *font) +{ + return max(font->height, font->ascent + font->descent); +} +#else /* !USE_XFT */ +int +X11_column_width(Display *display, X11_Font *font, const char *text, size_t length) +{ + nhUse(display); + return XTextWidth(font, text, length); +} + +int +X11_font_height(X11_Font *font) +{ + return font->ascent + font->descent; +} +#endif /* !USE_XFT */ + +////////////////////////////////////////////////////////////////////////////// +// A table of widgets and their data blocks // +////////////////////////////////////////////////////////////////////////////// + +typedef struct WidgetBucket { + Widget w; + WidgetData *data; +} WidgetBucket; + +static WidgetBucket *widget_table = NULL; +static unsigned num_widgets = 0; +static unsigned max_widgets = 0; + +/* bsearch compare function to search widget-table */ +static int +widget_compare(const void *key_, const void *value_) +{ + const Widget *key = key_; + const WidgetBucket *value = value_; + + if ((uintptr_t)key < (uintptr_t)value->w) { + return -1; + } + if ((uintptr_t)key > (uintptr_t)value->w) { + return +1; + } + return 0; +} + +/* Given the widget, return the entry in widget_table, or NULL if not found */ +static WidgetBucket * +find_widget_bucket(Widget w) +{ + WidgetBucket *bucket = + bsearch(w, widget_table, num_widgets, sizeof(WidgetBucket), + widget_compare); + return bucket; +} + +/* Given the widget, return the WidgetData structure, or NULL if not found */ +static WidgetData * +get_widget_data(Widget w) +{ + WidgetBucket *bucket = find_widget_bucket(w); + return (bucket != NULL) ? bucket->data : NULL; +} + +/* Add a widget to the table, set its normal and bold fonts and provide for + its removal from the table */ +static WidgetData * +add_widget(Widget w) +{ + /* If the array is full (or unallocated), add some new space to it */ + if (num_widgets >= max_widgets) { + max_widgets = num_widgets + 1024; + widget_table = (WidgetBucket *) re_alloc( + (long *) widget_table, + max_widgets * sizeof(widget_table[0])); + } + + /* Insert the widget into the table, maintaining its order */ + unsigned i; + for (i = num_widgets; + i != 0 && (uintptr_t)widget_table[i-1].w > (uintptr_t)w; + --i) { + widget_table[i] = widget_table[i-1]; + } + ++num_widgets; + widget_table[i].w = w; + + /* Create the data block */ + WidgetData *data = (WidgetData *)alloc(sizeof(*data)); + memset(data, 0, sizeof(*data)); + widget_table[i].data = data; + + return data; +} + +/* Remove the widget from the table */ +static void +delete_widget(Widget w) +{ + /* Find its location in the table */ + WidgetBucket *bucket = find_widget_bucket(w); + if (bucket == NULL) { + return; + } + + /* Remove the widget from the table */ + for (unsigned i = (unsigned)(bucket - widget_table); + i + 1 < num_widgets; + ++i) { + widget_table[i] = widget_table[i+1]; + } + --num_widgets; +} + +////////////////////////////////////////////////////////////////////////////// + +/* Call every time the blink flag changes */ +void +X11_blink_labels(void) +{ + for (unsigned i = 0; i < num_widgets; ++i) { + WidgetBucket *bucket = &widget_table[i]; + if (bucket->data->attrs & HL_BLINK) { + update_label(bucket->w, bucket->data); + } + } +} diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 39b980b28..0d2c6b709 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winmap.c $NHDT-Date: 1682206649 2023/04/22 23:37:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ */ +/* NetHack 5.0 winmap.c $NHDT-Date: 1781973109 2026/06/20 16:31:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.77 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -39,6 +39,7 @@ #include "hack.h" #include "dlb.h" #include "winX.h" +#include "tileset.h" #ifdef USE_XPM #include @@ -59,32 +60,50 @@ extern int total_tiles_used, Tile_corr; #define NH_INVERSE_COLOR 0x40000000 #define NH_ENHANCED_COLOR 0x80000000 -static X11_map_symbol glyph_char(const glyph_info *glyphinfo); +#ifdef USE_XFT +static void X11_get_color(struct xwindow *wp, X11_color nhcolor, XftColor *color); +static void X11_draw_image_string(XftDraw *draw, XftFont *font, + XftColor *fgcolor, XftColor *bgcolor, + int x, int y, + const X11_map_symbol *string, int length); +#else /* !USE_XFT */ static GC X11_make_gc(struct xwindow *wp, struct text_map_info_t *text_map, X11_color color, boolean inverted); -#ifdef ENHANCED_SYMBOLS static void X11_free_gc(struct xwindow *wp, GC gc, X11_color color); -#endif -#ifdef ENHANCED_SYMBOLS -static void X11_set_map_font(struct xwindow *wp); -#endif static void X11_draw_image_string(Display *display, Drawable d, GC ggc, int x, int y, const X11_map_symbol *string, int length); +#ifdef ENHANCED_SYMBOLS +static void X11_set_map_font(struct xwindow *wp); +#endif +#endif /* ?USE_XFT */ static Font X11_get_map_font(struct xwindow *wp); +#ifndef USE_XFT static XFontStruct *X11_get_map_font_struct(struct xwindow *wp); +#endif +static void get_text_gc(struct xwindow *, Font); static boolean init_tiles(struct xwindow *); +static unsigned long color_to_rgb(unsigned, unsigned, unsigned, + const Visual *); +static unsigned long shift_color(unsigned color, unsigned long mask); static void set_button_values(Widget, int, int, unsigned); static void map_check_size_change(struct xwindow *); static void map_update(struct xwindow *, int, int, int, int, boolean); static void init_text(struct xwindow *); +static void report_callback(Widget, XtPointer, XtPointer); static void map_exposed(Widget, XtPointer, XtPointer); static void set_gc(Widget, Font, const char *, Pixel, GC *, GC *); -static void get_text_gc(struct xwindow *, Font); static void map_all_unexplored(struct map_info_t *); static void get_char_info(struct xwindow *); static void display_cursor(struct xwindow *); +static boolean read_any_tiles(const char *tile_file); +#ifdef USE_XPM +static boolean read_xpm_tiles(const char *tile_file); +#else +static boolean read_binary_tiles(const char *tile_file); +#endif + /* Global functions ======================================================= */ void @@ -136,7 +155,7 @@ X11_print_glyph( color = glyphinfo->gm.sym.color; special = glyphinfo->gm.glyphflags; - ch = glyph_char(glyphinfo); + ch = X11_glyph_char(glyphinfo); if (glyphinfo->gm.customcolor != 0) { if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) != 0) { @@ -196,83 +215,6 @@ X11_print_glyph( } } -static X11_map_symbol -glyph_char(const glyph_info *glyphinfo) -{ -#ifdef ENHANCED_SYMBOLS - /* CP437 to Unicode mapping according to the Unicode Consortium */ - static const uint16 cp437[256] = { - 0x0020, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, - 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, - 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, - 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, - 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, - 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302, - 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, - 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, - 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, - 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, - 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, - 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, - 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, - 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, - 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, - 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, - 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, - 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, - 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, - 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, - 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, - 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0 - }; - /* Display DECgraphics as Unicode */ - static const uint16 decgraphics[128] = { - 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, - 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, - 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, - 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, - 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, - 0x0028, 0x0029, 0x002A, 0x2192, 0x2190, 0x2191, 0x2193, 0x002F, - 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, - 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, - 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, - 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, - 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, - 0x2666, 0x2592, 0x0062, 0x0063, 0x0064, 0x0065, 0x00B0, 0x00B1, - 0x2591, 0x00A4, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA, - 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C, - 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F - }; - X11_map_symbol och; - - if (SYMHANDLING(H_UTF8) && glyphinfo->gm.u != NULL && glyphinfo->gm.u->utf8str != NULL) { - och = glyphinfo->gm.u->utf32ch; - } else { - och = (uchar) glyphinfo->ttychar; - if (SYMHANDLING(H_IBM)) { - och = cp437[och]; - } else if ((SYMHANDLING(H_DEC) || SYMHANDLING(H_CURS)) && och >= 0x80) { - och = decgraphics[och & 0x7F]; - } - } - - return och; -#else - return (char) glyphinfo->ttychar; -#endif -} - #ifdef CLIPPING /* * The is the tty clip call. Since X can resize at any time, we can't depend @@ -385,22 +327,6 @@ post_process_tiles(void) static boolean init_tiles(struct xwindow *wp) { -#ifdef USE_XPM - XpmAttributes attributes; - int errorcode; -#else - FILE *fp = (FILE *) 0; - x11_header header; - unsigned char *cp, *colormap = (unsigned char *) 0; - unsigned char *tb, *tile_bytes = (unsigned char *) 0; - int size; - XColor *colors = (XColor *) 0; - unsigned i; - int x, y; - int bitmap_pad; - int ddepth; -#endif - char buf[BUFSZ]; Display *dpy = XtDisplay(toplevel); Screen *screen = DefaultScreenOfDisplay(dpy); struct map_info_t *map_info = (struct map_info_t *) 0; @@ -409,53 +335,285 @@ init_tiles(struct xwindow *wp) boolean result = TRUE; XGCValues values; XtGCMask mask; + const char *tile_file; /* already have tile information */ if (tile_pixmap != None) goto tiledone; + /* honor the user's tile file setting */ + if (iflags.wc_tile_file != NULL && iflags.wc_tile_file[0] != '\0') { + tile_file = iflags.wc_tile_file; + } else { + tile_file = appResources.tile_file; + } + map_info = wp->map_information; tile_info = &map_info->tile_map; (void) memset((genericptr_t) tile_info, 0, sizeof (struct tile_map_info_t)); /* no tile file name, no tile information */ - if (!appResources.tile_file[0]) { + if (!tile_file[0]) { result = FALSE; goto tiledone; } + result = read_any_tiles(tile_file); + if (!result) { #ifdef USE_XPM + result = read_xpm_tiles(tile_file); + #else + result = read_binary_tiles(tile_file); +#endif + } + + if (!result) + goto tiledone; + + /* fake an inverted tile by drawing a border around the edges */ +#ifdef USE_WHITE + /* use white or black as the border */ + mask = GCFunction | GCForeground | GCGraphicsExposures; + values.graphics_exposures = False; + values.foreground = WhitePixelOfScreen(screen); + values.function = GXcopy; + tile_info->white_gc = XtGetGC(wp->w, mask, &values); + values.graphics_exposures = False; + values.foreground = BlackPixelOfScreen(screen); + values.function = GXcopy; + tile_info->black_gc = XtGetGC(wp->w, mask, &values); +#else + /* + * Use xor so we don't have to check for special colors. Xor white + * against the upper left pixel of the corridor so that we have a + * white rectangle when in a corridor. + */ + mask = GCFunction | GCForeground | GCGraphicsExposures; + values.graphics_exposures = False; + values.foreground = + WhitePixelOfScreen(screen) + ^ XGetPixel(tile_image, 0, + tile_height * T_corr); + values.function = GXxor; + tile_info->white_gc = XtGetGC(wp->w, mask, &values); + + mask = GCFunction | GCGraphicsExposures; + values.function = GXCopy; + values.graphics_exposures = False; + tile_info->black_gc = XtGetGC(wp->w, mask, &values); +#endif /* USE_WHITE */ + + tiledone: + if (result) { /* succeeded */ + tile_info->square_height = tile_height; + tile_info->square_width = tile_width; + tile_info->square_ascent = 0; + tile_info->square_lbearing = 0; + tile_info->image_width = image_width; + tile_info->image_height = image_height; + } + + return result; +} + +static boolean +read_any_tiles(const char *tile_file) +{ + Display *dpy = XtDisplay(toplevel); + int ddepth = DefaultDepth(dpy, DefaultScreen(dpy)); + + /* Read the image */ + struct TileSetImage image; + boolean result = read_tile_image(&image, tile_file, ddepth >= 15); + if (!result) { + /* Format not recognized */ + return FALSE; + } + + /* Set the tile dimensions */ + unsigned image_width = image.width; + unsigned image_height = image.height; + tile_width = (iflags.wc_tile_width != 0) + ? iflags.wc_tile_width + : (int) image.tile_width; + tile_height = (iflags.wc_tile_height != 0) + ? iflags.wc_tile_height + : (int) image.tile_height; + + /* Set the tile count */ + int tile_cols = image.width / tile_width; + int tile_rows = image.height / tile_height; + tile_count = tile_cols * tile_rows; + + /* Double the size if requested */ + if (appResources.double_tile_size) { + tile_width *= 2; + tile_height *= 2; + image_height *= 2; + image_width *= 2; + } + + /* calculate bitmap_pad */ + int bitmap_pad; + if (ddepth > 16) + bitmap_pad = 32; + else if (ddepth > 8) + bitmap_pad = 16; + else + bitmap_pad = 8; + + /* Convert to XImage */ + Screen *screen = DefaultScreenOfDisplay(dpy); + Visual *visual = DefaultVisualOfScreen(screen); + tile_image = XCreateImage( + dpy, visual, + ddepth, /* depth */ + ZPixmap, /* format */ + 0, /* offset */ + (char *) 0, /* data */ + image_width, /* width */ + image_height, /* height */ + bitmap_pad, /* bit pad */ + 0); /* bytes_per_line */ + + if (tile_image == NULL) { + X11_raw_print("Failed to allocate XImage"); + goto tile_error; + } + + /* now we know the physical memory requirements, we can allocate space */ + tile_image->data = + (char *) alloc((unsigned) tile_image->bytes_per_line * image_height); + + unsigned char *tile_bytes = image.indexes; + XColor colors[256]; + if (tile_bytes != NULL) { /* tileset uses a palette */ + size_t size = (size_t) image.width * (size_t) image.height; + unsigned num_colors = 0; + for (unsigned j = 0; j < size; ++j) { + num_colors = max(num_colors, tile_bytes[j] + 1U); + } + for (unsigned i = 0; i < num_colors; i++) { + struct Pixel *cp = &image.palette[i]; + colors[i].red = cp->r * 256; + colors[i].green = cp->g * 256; + colors[i].blue = cp->b * 256; + colors[i].flags = 0; + colors[i].pixel = 0; + + if (!XAllocColor(dpy, DefaultColormapOfScreen(screen), &colors[i]) + && !nhApproxColor(screen, DefaultColormapOfScreen(screen), + (char *) 0, &colors[i])) { + char buf[BUFSZ]; + Snprintf(buf, sizeof (buf), "%dth of %u color allocation failed", i, + num_colors); + X11_raw_print(buf); + goto tile_error; + } + } + } + + /* Convert the pixels */ + unsigned char *tb = image.indexes; + struct Pixel *cp = image.pixels; + for (unsigned y = 0; y < image.height; y++) { + for (unsigned x = 0; x < image.width; x++) { + unsigned long pixel; + if (tb == NULL) { + pixel = color_to_rgb(cp->r, cp->g, cp->b, visual); + ++cp; + } else { + pixel = colors[*tb++].pixel; + } + if (appResources.double_tile_size) { + XPutPixel(tile_image, x * 2 + 0, y * 2 + 0, pixel); + XPutPixel(tile_image, x * 2 + 1, y * 2 + 0, pixel); + XPutPixel(tile_image, x * 2 + 0, y * 2 + 1, pixel); + XPutPixel(tile_image, x * 2 + 1, y * 2 + 1, pixel); + } else { + XPutPixel(tile_image, x, y, pixel); + } + } + } + + free_tile_image(&image); + return TRUE; + +tile_error: + free_tile_image(&image); + return FALSE; +} + +static unsigned long +color_to_rgb(unsigned red, unsigned green, unsigned blue, const Visual *visual) +{ + return shift_color(red, visual->red_mask ) + | shift_color(green, visual->green_mask) + | shift_color(blue, visual->blue_mask ); +} + +static unsigned long +shift_color(unsigned color, unsigned long mask) +{ + unsigned long mask1; + unsigned long color1; + + /* Shift color to match mask */ + mask1 = mask; + color1 = color; + while (mask1 > 0xFF) { + mask1 >>= 1; + color1 <<= 1; + } + while (mask1 < 0x80) { + mask1 <<= 1; + color1 >>= 1; + } + + return mask & color1; +} + +#ifdef USE_XPM +static boolean +read_xpm_tiles(const char *tile_file) +{ + XpmAttributes attributes; + int errorcode; + + char buf[BUFSZ]; + Display *dpy = XtDisplay(toplevel); + unsigned int image_height = 0, image_width = 0; + attributes.valuemask = XpmCloseness; attributes.closeness = 25000; - errorcode = XpmReadFileToImage(dpy, appResources.tile_file, &tile_image, + errorcode = XpmReadFileToImage(dpy, tile_file, &tile_image, 0, &attributes); if (errorcode == XpmColorFailed) { Sprintf(buf, "Insufficient colors available to load %s.", - appResources.tile_file); + tile_file); X11_raw_print(buf); X11_raw_print("Try closing other colorful applications and restart."); X11_raw_print("Attempting to load with inferior colors."); attributes.closeness = 50000; - errorcode = XpmReadFileToImage(dpy, appResources.tile_file, + errorcode = XpmReadFileToImage(dpy, tile_file, &tile_image, 0, &attributes); } if (errorcode != XpmSuccess) { if (errorcode == XpmColorFailed) { Sprintf(buf, "Insufficient colors available to load %s.", - appResources.tile_file); + tile_file); X11_raw_print(buf); } else { - Sprintf(buf, "Failed to load %s: %s", appResources.tile_file, + Sprintf(buf, "Failed to load %s: %s", tile_file, XpmGetErrorString(errorcode)); X11_raw_print(buf); } - result = FALSE; X11_raw_print("Switching to text-based mode."); - goto tiledone; + return FALSE; } /* assume a fixed number of tiles per row */ @@ -463,12 +621,11 @@ init_tiles(struct xwindow *wp) || tile_image->width <= TILES_PER_ROW) { Sprintf(buf, "%s is not a multiple of %d (number of tiles/row) pixels wide", - appResources.tile_file, TILES_PER_ROW); + tile_file, TILES_PER_ROW); X11_raw_print(buf); XDestroyImage(tile_image); tile_image = 0; - result = FALSE; - goto tiledone; + return FALSE; } /* infer tile dimensions from image size and TILES_PER_ROW */ @@ -481,25 +638,47 @@ init_tiles(struct xwindow *wp) } tile_width = image_width / TILES_PER_ROW; tile_height = image_height / (tile_count / TILES_PER_ROW); + + return TRUE; +} + #else /* !USE_XPM */ + +static boolean +read_binary_tiles(const char *tile_file) +{ + FILE *fp = (FILE *) 0; + x11_header header; + unsigned char *cp, *colormap = (unsigned char *) 0; + unsigned char *tb, *tile_bytes = (unsigned char *) 0; + int size; + XColor *colors = (XColor *) 0; + unsigned i; + int x, y; + int bitmap_pad; + int ddepth; + + char buf[BUFSZ]; + Display *dpy = XtDisplay(toplevel); + Screen *screen = DefaultScreenOfDisplay(dpy); + unsigned int image_height = 0, image_width = 0; + boolean result = FALSE; + /* any less than 16 colours makes tiles useless */ ddepth = DefaultDepthOfScreen(screen); if (ddepth < 4) { X11_raw_print("need a screen depth of at least 4"); - result = FALSE; goto tiledone; } - fp = fopen_datafile(appResources.tile_file, RDBMODE, FALSE); + fp = fopen_datafile(tile_file, RDBMODE, FALSE); if (!fp) { X11_raw_print("can't open tile file"); - result = FALSE; goto tiledone; } if ((int) fread((char *) &header, sizeof(header), 1, fp) != 1) { X11_raw_print("read of header failed"); - result = FALSE; goto tiledone; } @@ -507,7 +686,6 @@ init_tiles(struct xwindow *wp) Sprintf(buf, "Wrong tile file version, expected 2, got %lu", header.version); X11_raw_print(buf); - result = FALSE; goto tiledone; } #ifdef VERBOSE @@ -523,7 +701,6 @@ ntiles %ld\n", colormap = (unsigned char *) alloc((unsigned) size); if ((int) fread((char *) colormap, 1, size, fp) != size) { X11_raw_print("read of colormap failed"); - result = FALSE; goto tiledone; } @@ -542,7 +719,6 @@ ntiles %ld\n", Sprintf(buf, "%dth out of %ld color allocation failed", i, header.ncolors); X11_raw_print(buf); - result = FALSE; goto tiledone; } } @@ -560,7 +736,6 @@ ntiles %ld\n", if ((int) fread((char *) tile_bytes, size, tile_count, fp) != tile_count) { X11_raw_print("read of tile bytes failed"); - result = FALSE; goto tiledone; } @@ -568,7 +743,6 @@ ntiles %ld\n", Sprintf(buf, "tile file incomplete, expecting %d tiles, found %lu", total_tiles_used, header.ntiles); X11_raw_print(buf); - result = FALSE; goto tiledone; } @@ -604,7 +778,6 @@ ntiles %ld\n", if (!tile_image) { impossible("init_tiles: insufficient memory to create image"); X11_raw_print("Resorting to text map."); - result = FALSE; goto tiledone; } @@ -636,47 +809,10 @@ ntiles %ld\n", for (x = 0; x < (int) image_width; x++, tb++) XPutPixel(tile_image, x, y, colors[*tb].pixel); } -#endif /* ?USE_XPM */ - /* fake an inverted tile by drawing a border around the edges */ -#ifdef USE_WHITE - /* use white or black as the border */ - mask = GCFunction | GCForeground | GCGraphicsExposures; - values.graphics_exposures = False; - values.foreground = WhitePixelOfScreen(screen); - values.function = GXcopy; - tile_info->white_gc = XtGetGC(wp->w, mask, &values); - values.graphics_exposures = False; - values.foreground = BlackPixelOfScreen(screen); - values.function = GXcopy; - tile_info->black_gc = XtGetGC(wp->w, mask, &values); -#else - /* - * Use xor so we don't have to check for special colors. Xor white - * against the upper left pixel of the corridor so that we have a - * white rectangle when in a corridor. - */ - mask = GCFunction | GCForeground | GCGraphicsExposures; - values.graphics_exposures = False; - values.foreground = - WhitePixelOfScreen(screen) - ^ XGetPixel(tile_image, 0, -#if 0 - tile_height * glyph2tile[cmap_to_glyph(S_corr)]); -#else - tile_height * T_corr); -#endif - values.function = GXxor; - tile_info->white_gc = XtGetGC(wp->w, mask, &values); - - mask = GCFunction | GCGraphicsExposures; - values.function = GXCopy; - values.graphics_exposures = False; - tile_info->black_gc = XtGetGC(wp->w, mask, &values); -#endif /* USE_WHITE */ + result = TRUE; tiledone: -#ifndef USE_XPM if (fp) (void) fclose(fp); if (colormap) @@ -685,20 +821,12 @@ ntiles %ld\n", free((genericptr_t) tile_bytes); if (colors) free((genericptr_t) colors); -#endif - - if (result) { /* succeeded */ - tile_info->square_height = tile_height; - tile_info->square_width = tile_width; - tile_info->square_ascent = 0; - tile_info->square_lbearing = 0; - tile_info->image_width = image_width; - tile_info->image_height = image_height; - } return result; } +#endif /* ?USE_XPM */ + /* * Make sure the map's cursor is always visible. */ @@ -916,7 +1044,11 @@ set_gc( GC *regular, GC *inverse) { XGCValues values; +#ifdef USE_XFT + XtGCMask mask = GCFunction | GCForeground | GCBackground; +#else XtGCMask mask = GCFunction | GCForeground | GCBackground | GCFont; +#endif Pixel curpixel; Arg arg[1]; @@ -1109,6 +1241,16 @@ clear_map_window(struct xwindow *wp) static void get_char_info(struct xwindow *wp) { +#ifdef USE_XFT + struct map_info_t *map_info = wp->map_information; + struct text_map_info_t *text_map = &map_info->text_map; + XftFont *font = X11_new_font(wp->w, 0, NHW_MAP); + text_map->square_width = font->max_advance_width; + text_map->square_height = X11_font_height(font); + text_map->square_ascent = 0; + text_map->square_lbearing = 0; + X11_release_font(wp->w, font); +#else /* !USE_XFT */ XFontStruct *fs; struct map_info_t *map_info = wp->map_information; struct text_map_info_t *text_map = &map_info->text_map; @@ -1140,6 +1282,7 @@ get_char_info(struct xwindow *wp) if (fs->min_bounds.width != fs->max_bounds.width) X11_raw_print("Warning: map font is not monospaced!"); +#endif /* ?USE_XFT */ } /* @@ -1278,6 +1421,21 @@ set_button_values(Widget w, int x, int y, unsigned int button) click_button = (button == Button1) ? CLICK_1 : CLICK_2; } +/* This ensures that the cursor is visible when we first see the map */ +static void +report_callback(Widget w, XtPointer client_data, + XtPointer widget_data) +{ + nhUse(w); + XawPannerReport *report = (XawPannerReport *) widget_data; + if (report->changed & (XawPRSliderWidth | XawPRSliderHeight)) { + struct xwindow *wp = (struct xwindow *) client_data; + if (wp->map_information != NULL) { + check_cursor_visibility(wp); + } + } +} + /* * Map window expose callback. */ @@ -1478,48 +1636,142 @@ map_update(struct xwindow *wp, int start_row, int stop_row, int start_col, int s } else { struct text_map_info_t *text_map = &map_info->text_map; - { - X11_color *c_ptr; - X11_map_symbol *t_ptr; - int cur_col, win_ystart; - X11_color color; - GC ggc; +#ifdef USE_XFT + /* Set up font and background color */ + Display *display = XtDisplay(wp->w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); - for (row = start_row; row <= stop_row; row++) { - win_ystart = - text_map->square_ascent + (row * text_map->square_height); + Pixel bgpixel; + Arg arg[1]; + XtSetArg(arg[0], XtNbackground, &bgpixel); + XtGetValues(wp->w, arg, 1); - t_ptr = &(text_map->text[row][start_col]); - c_ptr = &(text_map->colors[row][start_col]); - cur_col = start_col; - while (cur_col <= stop_col) { - color = *c_ptr++; - count = 1; - while ((cur_col + count) <= stop_col && *c_ptr == color) { - count++; - c_ptr++; - } + XftDraw *draw = XftDrawCreate(display, XtWindow(wp->w), visual, cmap); + XftFont *font = X11_new_font(wp->w, 0, NHW_MAP); + XftColor bgcolor; + X11_new_color(wp->w, bgpixel, &bgcolor); +#endif /* USE_XFT */ - ggc = X11_make_gc(wp, text_map, color, inverted); - X11_draw_image_string(XtDisplay(wp->w), XtWindow(wp->w), - ggc, - text_map->square_lbearing - + (text_map->square_width - * (cur_col - COL0_OFFSET)), - win_ystart, t_ptr, count); -#ifdef ENHANCED_SYMBOLS - X11_free_gc(wp, ggc, color); -#endif + for (row = start_row; row <= stop_row; row++) { + int win_ystart = + text_map->square_ascent + (row * text_map->square_height); - /* move text pointer and column count */ - t_ptr += count; - cur_col += count; - } /* col loop */ - } /* row loop */ - } + X11_map_symbol *t_ptr = &(text_map->text[row][start_col]); + X11_color *c_ptr = &(text_map->colors[row][start_col]); + int cur_col = start_col; + while (cur_col <= stop_col) { + X11_color color = *c_ptr++; + count = 1; + while ((cur_col + count) <= stop_col && *c_ptr == color) { + count++; + c_ptr++; + } + +#ifdef USE_XFT + XftColor fgcolor; + X11_get_color(wp, color, &fgcolor); + boolean cur_inv = !!inverted ^ ((color & NH_INVERSE_COLOR) != 0); + X11_draw_image_string(draw, font, + cur_inv ? &bgcolor : &fgcolor, + cur_inv ? &fgcolor : &bgcolor, + text_map->square_lbearing + + (text_map->square_width + * (cur_col - COL0_OFFSET)), + win_ystart, t_ptr, count); + XftColorFree(display, visual, cmap, &fgcolor); +#else /* !USE_XFT */ + GC ggc = X11_make_gc(wp, text_map, color, inverted); + X11_draw_image_string(XtDisplay(wp->w), XtWindow(wp->w), + ggc, + text_map->square_lbearing + + (text_map->square_width + * (cur_col - COL0_OFFSET)), + win_ystart, t_ptr, count); + X11_free_gc(wp, ggc, color); +#endif /* ?USE_XFT */ + + /* move text pointer and column count */ + t_ptr += count; + cur_col += count; + } /* col loop */ + } /* row loop */ + +#ifdef USE_XFT + /* Free resources from Xft */ + XftColorFree(display, visual, cmap, &bgcolor); + X11_release_font(wp->w, font); + XftDrawDestroy(draw); +#endif /* USE_XFT */ } } +#ifdef USE_XFT +static void +X11_get_color(struct xwindow *wp, X11_color nhcolor, XftColor *color) +{ + Pixel pixel; + + if ((nhcolor & NH_ENHANCED_COLOR) != 0) { + pixel = COLORVAL(nhcolor); + } else { + static struct { + const char *name; + Pixel rgb; + } map_colors[] = { + { XtNblack, 0xFFFFFFFF }, /* CLR_BLACK */ + { XtNred, 0xFFFFFFFF }, /* CLR_RED */ + { XtNgreen, 0xFFFFFFFF }, /* CLR_GREEN */ + { XtNbrown, 0xFFFFFFFF }, /* CLR_BROWN */ + { XtNblue, 0xFFFFFFFF }, /* CLR_BLUE */ + { XtNmagenta, 0xFFFFFFFF }, /* CLR_MAGENTA */ + { XtNcyan, 0xFFFFFFFF }, /* CLR_CYAN */ + { XtNgray, 0xFFFFFFFF }, /* CLR_GRAY */ + { XtNforeground, 0xFFFFFFFF }, /* NO_COLOR */ + { XtNorange, 0xFFFFFFFF }, /* CLR_ORANGE */ + { XtNbright_green, 0xFFFFFFFF }, /* CLR_BRIGHT_GREEN */ + { XtNyellow, 0xFFFFFFFF }, /* CLR_YELLOW */ + { XtNbright_blue, 0xFFFFFFFF }, /* CLR_BRIGHT_BLUE */ + { XtNbright_magenta, 0xFFFFFFFF }, /* CLR_BRIGHT_MAGENTA */ + { XtNbright_cyan, 0xFFFFFFFF }, /* CLR_BRIGHT_CYAN */ + { XtNwhite, 0xFFFFFFFF }, /* CLR_WHITE */ + }; + pixel = map_colors[nhcolor & 0xF].rgb; + if (pixel == 0xFFFFFFFF) { + /* Retrieve resource */ + Arg arg[1]; + XtSetArg(arg[0], (char *) map_colors[nhcolor & 0xF].name, &pixel); + XtGetValues(wp->w, arg, 1); + map_colors[nhcolor & 0xF].rgb = pixel; + } + } + + X11_new_color(wp->w, pixel, color); +} + +static void +X11_draw_image_string( + XftDraw *draw, XftFont *font, + XftColor *fgcolor, XftColor *bgcolor, + int x, int y, + const X11_map_symbol *string, int length) +{ + XftDrawRect(draw, bgcolor, x, y, + length * font->max_advance_width, + X11_font_height(font)); + + int xt = x; + int yt = y + font->ascent; +#ifdef ENHANCED_SYMBOLS + XftDrawString32(draw, fgcolor, font, xt, yt, string, length); +#else /* !ENHANCED_SYMBOLS */ + XftDrawString8(draw, fgcolor, font, xt, yt, string, length); +#endif /* ?ENHANCED_SYMBOLS */ +} + +#else /* !USE_XFT */ + static GC X11_make_gc( struct xwindow *wp UNUSED, @@ -1554,10 +1806,16 @@ X11_make_gc( values.background = bgpixel; } values.function = GXcopy; +#ifdef USE_XFT + ggc = XtGetGC(wp->w, + GCFunction | GCForeground | GCBackground, + &values); +#else values.font = X11_get_map_font(wp); ggc = XtGetGC(wp->w, GCFunction | GCForeground | GCBackground | GCFont, &values); +#endif } else { ggc = (cur_inv ? text_map->inv_copy_gc : text_map->copy_gc); } @@ -1581,16 +1839,16 @@ X11_make_gc( return ggc; } -#ifdef ENHANCED_SYMBOLS static void X11_free_gc(struct xwindow *wp, GC ggc, X11_color color) { +#ifdef ENHANCED_SYMBOLS if ((color & NH_ENHANCED_COLOR) != 0 && iflags.use_color) { /* X11_make_gc allocated a new GC */ XtReleaseGC(wp->w, ggc); } -} #endif +} static void X11_draw_image_string( @@ -1624,6 +1882,8 @@ X11_draw_image_string( #endif /* ?ENHANCED_SYMBOLS */ } +#endif /* ?USE_XFT */ + /* Adjust the number of rows and columns on the given map window */ void set_map_size(struct xwindow *wp, Dimension cols, Dimension rows) @@ -1746,10 +2006,11 @@ create_map_window( num_args); /* number of values to set */ XtAddCallback(map, XtNexposeCallback, map_exposed, (XtPointer) 0); + XtAddCallback(viewport, XtNreportCallback, report_callback, wp); map_info = wp->map_information = (struct map_info_t *) alloc(sizeof (struct map_info_t)); -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) X11_set_map_font(wp); #endif @@ -1800,68 +2061,38 @@ create_map_window( map_all_unexplored(map_info); } -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) static void X11_set_map_font(struct xwindow *wp) { struct map_info_t *map_info = wp->map_information; XFontStruct *fs; - Atom font_atom; - const char *font_name; - unsigned dashes; - const char *p; - size_t len; - char unicode_font[BUFSZ]; - Font font_id; /* Query the configured font for the map */ fs = WindowFontStruct(wp->w); - map_info->text_map.font = fs; - if (!XGetFontProperty(fs, XA_FONT, &font_atom)) { - return; - } - font_name = XGetAtomName(XtDisplay(wp->w), font_atom); - if (font_name == NULL) { - return; - } - /* Proceed to the registry name */ - dashes = 13; - p = font_name; - while (dashes != 0) { - const char *q = strchr(p, '-'); - if (q == NULL) { - break; - } - p = q + 1; - --dashes; - } - - /* Substitute "iso10646-1" for the registry name and encoding */ - len = (size_t) (p - font_name); - if (dashes != 0 || len + 11 > sizeof(unicode_font)) { - return; - } - - memcpy(unicode_font, font_name, len); - strcpy(unicode_font + len, "iso10646-1"); - font_name = unicode_font; - - font_id = XLoadFont(XtDisplay(wp->w), font_name); - map_info->text_map.font = XQueryFont(XtDisplay(wp->w), font_id); - if (map_info->text_map.font == NULL) { + XFontStruct *unifont = X11_unicode_font(XtDisplay(wp->w), fs); + if (unifont != NULL) { + map_info->text_map.font = unifont; + } else { /* Fallback in case no iso10646 */ map_info->text_map.font = fs; } } -#endif +#endif /* ENHANCED_SYMBOLS && !USE_XFT */ static Font X11_get_map_font(struct xwindow *wp) { +#ifdef USE_XFT + nhUse(wp); + return 0; +#else /* !USE_XFT */ return X11_get_map_font_struct(wp)->fid; +#endif /* ?USE_XFT */ } +#ifndef USE_XFT static XFontStruct * X11_get_map_font_struct(struct xwindow *wp) { @@ -1877,6 +2108,7 @@ X11_get_map_font_struct(struct xwindow *wp) return WindowFontStruct(wp->w); #endif } +#endif /* USE_XFT */ /* * Destroy this map window. @@ -1901,7 +2133,7 @@ destroy_map_window(struct xwindow *wp) } /* Free the font structure if we allocated one */ -#ifdef ENHANCED_SYMBOLS +#if defined(ENHANCED_SYMBOLS) && !defined(USE_XFT) XFreeFont(XtDisplay(wp->w), text_map->font); #endif @@ -1969,9 +2201,9 @@ x_event(int exit_condition) try_test: switch (exit_condition) { case EXIT_ON_SENT_EVENT: { - XAnyEvent *any = (XAnyEvent *) &event; + XClientMessageEvent *cle = (XClientMessageEvent *) &event; - if (any->send_event) { + if (cle->send_event && cle->data.b[0] == DELAY_EVENT_ID) { retval = 0; keep_going = FALSE; } diff --git a/win/X11/winmenu.c b/win/X11/winmenu.c index d4188ac22..4d0c71c2f 100644 --- a/win/X11/winmenu.c +++ b/win/X11/winmenu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winmenu.c $NHDT-Date: 1644531504 2022/02/10 22:18:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.50 $ */ +/* NetHack 5.0 winmenu.c $NHDT-Date: 1781973109 2026/06/20 16:31:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.64 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -60,6 +60,7 @@ static unsigned menu_scrollmask(struct xwindow *); static void menu_unscroll(struct xwindow *); static Widget menu_create_buttons(struct xwindow *, Widget, Widget); static void menu_create_entries(struct xwindow *, struct menu *); +static unsigned get_col_widths(Widget, X11_Font *, const char *, int **); static void destroy_menu_entry_widgets(struct xwindow *); static void create_menu_translation_tables(void); @@ -77,6 +78,10 @@ static const char menu_translations[] = "#override\n\ Right: scroll(6)\n\ Up: scroll(8)\n\ Down: scroll(2)\n\ + Prior: menu_key(<)\n\ + Next: menu_key(>)\n\ + Home: menu_key(^)\n\ + End: menu_key(|)\n\ : scroll(8)\n\ : scroll(2)\n\ : menu_key()"; @@ -85,9 +90,9 @@ static const char menu_entry_translations[] = "#override\n\ : scroll(8)\n\ : scroll(2)"; -XtTranslations menu_entry_translation_table = (XtTranslations) 0; -XtTranslations menu_translation_table = (XtTranslations) 0; -XtTranslations menu_del_translation_table = (XtTranslations) 0; +static XtTranslations menu_entry_translation_table = (XtTranslations) 0; +static XtTranslations menu_translation_table = (XtTranslations) 0; +static XtTranslations menu_del_translation_table = (XtTranslations) 0; static void create_menu_translation_tables(void) @@ -168,6 +173,7 @@ menu_select(Widget w, XtPointer client_data, XtPointer call_data) XtSetArg(args[0], nhStr(XtNlabel), curr->str); XtSetValues(w, args, ONE); + X11_update_label(w); if (menu_info->how == PICK_ONE) menu_popdown(wp); @@ -214,6 +220,7 @@ invert_line(struct xwindow *wp, x11_menu_item *curr, int which, long how_many) XtSetValues(curr->w, args, ONE); curr->pick_count = -1L; } + X11_update_label(curr->w); } static XEvent fake_perminv_event; @@ -233,14 +240,14 @@ menu_key(Widget w, XEvent *event, String *params, Cardinal *num_params) int count; boolean selected_something, perminv_scrolling = (event == &fake_perminv_event); - - nhUse(params); - nhUse(num_params); + Cardinal in_nparams = (num_params ? *num_params : 0); wp = find_widget(w); menu_info = wp->menu_information; - if (!perminv_scrolling) + if (in_nparams) { + ch = get_menu_cmd_key(*params[0]); + } else if (!perminv_scrolling) ch = key_event_to_char((XKeyEvent *) event); else ch = (char) fake_perminv_event.type; @@ -256,10 +263,14 @@ menu_key(Widget w, XEvent *event, String *params, Cardinal *num_params) overridden if it happens to duplicate a mapped menu command (':' to look inside a container vs ':' to select via search string); check for group accelerator match too */ - for (curr = menu_info->curr_menu.base; curr; curr = curr->next) - if (curr->identifier.a_void != 0 - && (curr->selector == ch || curr->gselector == ch)) - goto make_selection; + for (curr = menu_info->curr_menu.base; curr; curr = curr->next) { + if (curr->identifier.a_void != 0) { + if (curr->selector == ch) + goto make_selection; + if (curr->gselector == ch) + goto group_accel; + } + } ch = map_menu_cmd(ch); if (ch == '\033') { /* quit */ @@ -612,6 +623,8 @@ menu_popdown(struct xwindow *wp) wp->w = wp->popup = (Widget) 0; if (wp->menu_information->is_active) exit_x_event = TRUE; /* exit our event handler */ + if (wp->menu_information->permi) + iflags.perm_invent = FALSE; wp->menu_information->is_up = FALSE; /* menu is down */ } @@ -841,7 +854,7 @@ X11_add_menu(winid window, impossible("Menu item too long (%d).", len); len = BUFSZ - 1; } - Sprintf(buf, "%c %c ", ch ? ch : ' ', preselected ? '+' : '-'); + Sprintf(buf, "%c\t%c\t", ch ? ch : ' ', preselected ? '+' : '-'); (void) strncpy(buf + 4, str, len); buf[4 + len] = '\0'; item->str = copy_of(buf); @@ -1013,6 +1026,9 @@ X11_select_menu(winid window, int how, menu_item **menu_list) labelWidgetClass, form, args, num_args) : (Widget) 0; + if (label) { + X11_wrap_widget_if_Xft(label, NHW_MENU); + } all = menu_create_buttons(wp, form, label); @@ -1062,13 +1078,14 @@ X11_select_menu(winid window, int how, menu_item **menu_list) menu_create_entries(wp, &menu_info->curr_menu); /* if viewport will be bigger than the screen, limit its height */ + XtRealizeWidget(wp->popup); /* need to realize before we get size/pos */ num_args = 0; XtSetArg(args[num_args], XtNwidth, &v_pixel_width); num_args++; XtSetArg(args[num_args], XtNheight, &v_pixel_height); num_args++; XtGetValues(wp->w, args, num_args); if ((Dimension) XtScreen(wp->w)->height * 5 / 6 < v_pixel_height) { - /* scrollbar is 14 pixels wide. Widen the form to accommodate it. */ - v_pixel_width += 14; + /* scrollbar is 17 pixels wide. Widen the form to accommodate it. */ + v_pixel_width += 17; /* shrink to fit vertically */ v_pixel_height = XtScreen(wp->w)->height * 5 / 6; @@ -1076,9 +1093,8 @@ X11_select_menu(winid window, int how, menu_item **menu_list) num_args = 0; XtSetArg(args[num_args], XtNwidth, v_pixel_width); num_args++; XtSetArg(args[num_args], XtNheight, v_pixel_height); num_args++; - XtSetValues(wp->w, args, num_args); + XtSetValues(wp->popup, args, num_args); } - XtRealizeWidget(wp->popup); /* need to realize before we position */ /* if menu is not up, position it */ if (!menu_info->is_up) { @@ -1182,6 +1198,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; ok = XtCreateManagedWidget("OK", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(ok, NHW_MENU); XtAddCallback(ok, XtNcallback, menu_ok, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[0]); XtGetValues(lblwidget[0] = ok, args, ONE); @@ -1200,6 +1217,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(cancel, NHW_MENU); XtAddCallback(cancel, XtNcallback, menu_cancel, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[1]); XtGetValues(lblwidget[1] = cancel, args, ONE); @@ -1217,6 +1235,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; all = XtCreateManagedWidget("all", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(all, NHW_MENU); XtAddCallback(all, XtNcallback, menu_all, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[2]); XtGetValues(lblwidget[2] = all, args, ONE); @@ -1233,6 +1252,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; none = XtCreateManagedWidget("none", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(none, NHW_MENU); XtAddCallback(none, XtNcallback, menu_none, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[3]); XtGetValues(lblwidget[3] = none, args, ONE); @@ -1249,6 +1269,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; invert = XtCreateManagedWidget("invert", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(invert, NHW_MENU); XtAddCallback(invert, XtNcallback, menu_invert, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[4]); XtGetValues(lblwidget[4] = invert, args, ONE); @@ -1266,6 +1287,7 @@ menu_create_buttons(struct xwindow *wp, Widget form, Widget under) XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++; search = XtCreateManagedWidget("search", commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(search, NHW_MENU); XtAddCallback(search, XtNcallback, menu_search, (XtPointer) wp); XtSetArg(args[0], XtNwidth, &lblwidth[5]); XtGetValues(lblwidget[5] = search, args, ONE); @@ -1296,13 +1318,46 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) Cardinal num_args; Dimension cwidth, maxwidth = 0; + /* Does any line have a selector? */ + boolean any_canpick = FALSE; + for (curr = curr_menu->base; curr; curr = curr->next) { + if (curr->identifier.a_void != NULL) { + any_canpick = TRUE; + break; + } + } + + int *col_widths = NULL; + unsigned num_cols = 0; + X11_Font *font; +#ifdef USE_XFT + font = X11_new_font(wp->w, 0, NHW_MENU); +#endif + for (curr = curr_menu->base; curr; curr = curr->next) { char tmpbuf[BUFSZ]; Widget linewidget; String str = (String) curr->str; int attr = ATR_NONE; int color = NO_COLOR; - boolean canpick = (how != PICK_NONE && curr->identifier.a_void); + boolean canpick = curr->identifier.a_void != NULL; + + /* Add tabs if needed to align non-selector lines with selector lines */ + if (any_canpick && !canpick) { + char *buf; + if (strncmp(str, " ", 4) == 0) { + size_t buf_len = strlen(str); + buf = (char *) alloc(buf_len); + Snprintf(buf, buf_len, "\t\t%s", str + 4); + } else { + size_t buf_len = strlen(str) + 3; + buf = (char *) alloc(buf_len); + Snprintf(buf, buf_len, "\t\t%s", str); + } + free(curr->str); + curr->str = buf; + str = buf; + } num_args = 0; XtSetArg(args[num_args], nhStr(XtNlabel), str); num_args++; @@ -1345,25 +1400,54 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) menulineidx++; Sprintf(tmpbuf, "menuline_%s", (canpick) ? "command" : "label"); - curr->w = linewidget = XtCreateManagedWidget(tmpbuf, - canpick - ? commandWidgetClass - : labelWidgetClass, - wp->w, args, num_args); - - if (attr == ATR_BOLD) { - load_boldfont(wp, curr->w); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfont), - wp->boldfs); num_args++; - XtSetValues(curr->w, args, num_args); - } + /* Need to create the widget unmanaged, set up the pixmap, and then + manage it, or else items in the inventory window get the wrong + size */ + curr->w = linewidget = XtCreateWidget(tmpbuf, + canpick + ? commandWidgetClass + : labelWidgetClass, + wp->w, args, num_args); + X11_wrap_widget(curr->w, NHW_MENU); + X11_set_attrs(curr->w, 0x1 << attr); if (canpick) XtAddCallback(linewidget, XtNcallback, menu_select, (XtPointer) curr); prevlinewidget = linewidget; +#ifndef USE_XFT /* If Xft, the font is acquired at the start of the loop */ + num_args = 0; + XtSetArg(args[num_args], XtNfont, &font); num_args++; + XtGetValues(curr->w, args, num_args); +#endif + /* Get column widths for this line */ + if (strchr(str, '\t') != NULL) { /* Might be a header if no tab */ + int *col_widths0; + unsigned num_cols0 = get_col_widths(curr->w, font, str, &col_widths0); + if (num_cols0 > num_cols) { + col_widths = (int *) re_alloc((long *) col_widths, num_cols0 * sizeof(col_widths[0])); + memset(col_widths + num_cols, 0, sizeof(col_widths[0]) * (num_cols0 - num_cols)); + num_cols = num_cols0; + } + for (unsigned i = 0; i < num_cols0; ++i) { + col_widths[i] = max(col_widths[i], col_widths0[i]); + } + free(col_widths0); + } + } +#ifdef USE_XFT + X11_release_font(wp->w, font); +#endif + + /* Set the column widths */ + for (curr = curr_menu->base; curr; curr = curr->next) { + if (strchr(curr->str, '\t') != NULL) { /* Might be a header if no tab */ + X11_set_column_widths(curr->w, col_widths, num_cols); + } + XtManageChild(curr->w); + + boolean canpick = (how != PICK_NONE && curr->identifier.a_void); if (canpick) { /* get the current line width */ XtSetArg(args[0], XtNwidth, &cwidth); @@ -1373,6 +1457,8 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) } } + free(col_widths); + /* set all selectable menu entries to the maximum width */ if (how != PICK_NONE) { XtSetArg(args[0], XtNwidth, maxwidth); @@ -1382,6 +1468,52 @@ menu_create_entries(struct xwindow *wp, struct menu *curr_menu) } } +/* Determine widths of columns */ +/* The last column is deemed to extend to the right margin, and is not included + in the returned array */ +static unsigned +get_col_widths(Widget w, X11_Font *font, const char *str, int **col_widths) +{ + int col_spacing = X11_column_width(XtDisplay(w), font, "# ", 2); + + /* Determine the number of columns */ + unsigned num_cols = 0; + size_t i = 0; + while (str[i] != '\0') { + size_t len = strcspn(str + i, "\t"); + if (str[i+len] == '\0') { + break; + } + ++num_cols; + i += len + 1; + } + + /* Allocate width array */ + int *cwidths = (int *) alloc(sizeof(cwidths[0]) * num_cols); + memset(cwidths, 0, sizeof(cwidths[0]) * num_cols); + + /* Get the widths of the columns */ + unsigned col = 0; + i = 0; + while (str[i] != '\0') { + size_t len = strcspn(str + i, "\t"); + if (str[i+len] == '\0') { + break; + } + cwidths[col] = X11_column_width(XtDisplay(w), font, str + i, len); + if (len > 1) { + col_spacing = X11_font_height(font) * 2; + } + cwidths[col] += col_spacing; + ++col; + i += len + 1; + } + + /* Return */ + *col_widths = cwidths; + return num_cols; +} + static void destroy_menu_entry_widgets(struct xwindow *wp) { diff --git a/win/X11/winmesg.c b/win/X11/winmesg.c index 6c5c01f35..1678e5da7 100644 --- a/win/X11/winmesg.c +++ b/win/X11/winmesg.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winmesg.c $NHDT-Date: 1596498373 2020/08/03 23:46:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 winmesg.c $NHDT-Date: 1781973109 2026/06/20 16:31:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -37,7 +37,7 @@ static struct line_element *get_previous(struct line_element *); static void set_circle_buf(struct mesg_info_t *, int); -static char *split(char *, XFontStruct *, Dimension); +static char *split(char *, struct xwindow *, Dimension); static void add_line(struct mesg_info_t *, const char *); static void redraw_message_window(struct xwindow *); static void mesg_check_size_change(struct xwindow *); @@ -83,7 +83,9 @@ create_message_window(struct xwindow *wp, /* window pointer */ wp->mesg_information = mesg_info = (struct mesg_info_t *) alloc(sizeof (struct mesg_info_t)); +#ifndef USE_XFT mesg_info->fs = 0; +#endif mesg_info->num_lines = 0; mesg_info->head = mesg_info->line_here = mesg_info->last_pause = mesg_info->last_pause_head = (struct line_element *) 0; @@ -151,30 +153,49 @@ create_message_window(struct xwindow *wp, /* window pointer */ * is appResources.message_lines high and DEFAULT_MESSAGE_WIDTH wide. */ + /* Save character information for fast use later. */ +#ifdef USE_XFT + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); + XGlyphInfo extents; + mesg_info->char_width = font->max_advance_width; + mesg_info->char_height = X11_font_height(font); + mesg_info->char_ascent = font->ascent; + mesg_info->char_lbearing = 0; + /* Xft seems to offer no direct way to distinguish proportional from + monospaced fonts. Assume that "!" will be narrower than maximum. */ + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) "!", 1, &extents); + int min_width = extents.width - extents.x; + /* "Maximum" is likely to include things like Chinese characters that + * display at double width. Use the width of "M". */ + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) "M", 1, &extents); + int max_width = extents.width - extents.x; + X11_release_font(wp->w, font); +#else /* Get the font information. */ num_args = 0; XtSetArg(args[num_args], XtNfont, &mesg_info->fs); num_args++; XtGetValues(wp->w, args, num_args); - /* Save character information for fast use later. */ mesg_info->char_width = mesg_info->fs->max_bounds.width; mesg_info->char_height = mesg_info->fs->max_bounds.ascent + mesg_info->fs->max_bounds.descent; mesg_info->char_ascent = mesg_info->fs->max_bounds.ascent; mesg_info->char_lbearing = -mesg_info->fs->min_bounds.lbearing; + int min_width = mesg_info->fs->min_bounds.width; + int max_width = mesg_info->fs->max_bounds.width; +#endif get_gc(wp->w, mesg_info); wp->pixel_height = ((int) iflags.msg_history) * mesg_info->char_height; /* If a variable spaced font, only use 2/3 of the default size */ - if (mesg_info->fs->min_bounds.width != mesg_info->fs->max_bounds.width) { + if (min_width != max_width) { wp->pixel_width = ((2 * DEFAULT_MESSAGE_WIDTH) / 3) - * mesg_info->fs->max_bounds.width; + * max_width; } else - wp->pixel_width = - (DEFAULT_MESSAGE_WIDTH * mesg_info->fs->max_bounds.width); + wp->pixel_width = (DEFAULT_MESSAGE_WIDTH * max_width); /* Set the new width and height. */ num_args = 0; @@ -250,7 +271,7 @@ append_message(struct xwindow *wp, const char *str) remainder = buf; do { mark = remainder; - remainder = split(mark, wp->mesg_information->fs, wp->pixel_width); + remainder = split(mark, wp, wp->pixel_width); add_line(wp->mesg_information, mark); } while (remainder); } @@ -357,10 +378,16 @@ set_circle_buf(struct mesg_info_t *mesg_info, int count) * not, back up from the end by words until we find a place to split. */ static char * -split(char *s, - XFontStruct *fs, /* Font for the window. */ +split( + char *s, + struct xwindow *wp, Dimension pixel_width) { +#ifdef USE_XFT + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); +#else + XFontStruct *fs = wp->mesg_information->fs; /* Font for the window. */ +#endif char save, *end, *remainder; save = '\0'; @@ -368,7 +395,18 @@ split(char *s, end = eos(s); /* point to null at end of string */ /* assume that if end == s, XXXXXX returns 0) */ - while ((Dimension) XTextWidth(fs, s, (int) strlen(s)) > pixel_width) { + while (TRUE) { +#ifdef USE_XFT + XGlyphInfo extents; + XftTextExtents8(XtDisplay(wp->w), font, (const FcChar8*) s, strlen(s), &extents); + if (extents.width - extents.x < pixel_width) { + break; + } +#else + if ((Dimension) XTextWidth(fs, s, (int) strlen(s)) < pixel_width) { + break; + } +#endif *end-- = save; while (*end != ' ') { if (end == s) @@ -379,6 +417,9 @@ split(char *s, *end = '\0'; remainder = end + 1; } +#ifdef USE_XFT + X11_release_font(wp->w, font); +#endif return remainder; } @@ -466,21 +507,77 @@ redraw_message_window(struct xwindow *wp) } /* For now, just update the whole shootn' match. */ +#ifdef USE_XFT + Display *display = XtDisplay(wp->w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, XtWindow(wp->w), visual, cmap); + XftFont *font = X11_new_font(wp->w, 0, NHW_MESSAGE); + XftColor fgcolor; + X11_new_color(wp->w, mesg_info->fgpixel, &fgcolor); +#endif /* USE_XFT */ + for (y_base = row = 0, curr = mesg_info->head; row < mesg_info->num_lines; row++, y_base += mesg_info->char_height, curr = curr->next) { + if (curr->line == NULL) { + continue; + } + /* Deal with any tabs in the output. These will just be single strings, + * not needing to align columns, so just convert to spaces */ + const char *str = curr->line; + int str_length = curr->str_length; + char buf[BUFSZ]; + if (memchr(str, '\t', str_length) != NULL) { + int i2 = 0; + for (int i1 = 0; i1 < str_length; ++i1) { + if (str[i1] == '\t') { + if (i2 + 4 > BUFSZ) { + break; + } + memcpy(buf + i2, " ", 4); + i2 += 4; + } else { + if (i2 >= BUFSZ) { + break; + } + buf[i2++] = str[i1]; + } + } + /* buf does not need to be null terminated */ + str = buf; + str_length = i2; + } +#ifdef USE_XFT + XftDrawString8(draw, &fgcolor, font, + mesg_info->char_lbearing, mesg_info->char_ascent + y_base, + (const FcChar8 *) str, str_length); +#else /* !USE_XFT */ XDrawString(XtDisplay(wp->w), XtWindow(wp->w), mesg_info->gc, mesg_info->char_lbearing, mesg_info->char_ascent + y_base, - curr->line, curr->str_length); + str, str_length); +#endif /* ?USE_XFT */ /* * This draws a line at the _top_ of the line of text pointed to by * mesg_info->last_pause. */ if (appResources.message_line && curr == mesg_info->line_here) { +#ifdef USE_XFT + XftDrawRect(draw, &fgcolor, 0, + y_base, wp->pixel_width, y_base); +#else /* !USE_XFT */ XDrawLine(XtDisplay(wp->w), XtWindow(wp->w), mesg_info->gc, 0, y_base, wp->pixel_width, y_base); +#endif /* ?USE_XFT */ } } +#ifdef USE_XFT + XftColorFree(display, visual, cmap, &fgcolor); + XftFontClose(display, font); + XftDrawDestroy(draw); +#endif /* USE_XFT */ + mesg_info->dirty = False; } @@ -549,6 +646,12 @@ mesg_exposed(Widget w, static void get_gc(Widget w, struct mesg_info_t *mesg_info) { +#ifdef USE_XFT + Arg arg[1]; + + XtSetArg(arg[0], XtNforeground, &mesg_info->fgpixel); + XtGetValues(w, arg, ONE); +#else /* !USE_XFT */ XGCValues values; XtGCMask mask = GCFunction | GCForeground | GCBackground | GCFont; Pixel fgpixel, bgpixel; @@ -563,6 +666,7 @@ get_gc(Widget w, struct mesg_info_t *mesg_info) values.function = GXcopy; values.font = WindowFont(w); mesg_info->gc = XtGetGC(w, mask, &values); +#endif /* ?USE_XFT */ } /* diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index 1fcdf471c..0a4bb4d09 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winmisc.c $NHDT-Date: 1596498374 2020/08/03 23:46:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ */ +/* NetHack 5.0 winmisc.c $NHDT-Date: 1781973109 2026/06/20 16:31:49 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.68 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -124,13 +124,13 @@ static Widget make_menu(const char *, const char *, const char *, const char *, const char **, Widget **, XtCallbackProc, Widget *); /* Bad Hack alert. Using integers instead of XtPointers */ -XtPointer +static XtPointer i2xtp(int i) { return (XtPointer) (ptrdiff_t) i; } -int +static int xtp2i(XtPointer x) { return (int) (ptrdiff_t) x; @@ -328,15 +328,15 @@ algn_key(Widget w, XEvent *event, String *params, Cardinal *num_params) exit_x_event = TRUE; } -int plsel_n_races, plsel_n_roles; -Widget *plsel_race_radios = (Widget *) 0; -Widget *plsel_role_radios = (Widget *) 0; -Widget *plsel_gend_radios = (Widget *) 0; -Widget *plsel_align_radios = (Widget *) 0; +static int plsel_n_races, plsel_n_roles; +static Widget *plsel_race_radios = (Widget *) 0; +static Widget *plsel_role_radios = (Widget *) 0; +static Widget *plsel_gend_radios = (Widget *) 0; +static Widget *plsel_align_radios = (Widget *) 0; -Widget plsel_name_input; +static Widget plsel_name_input; -Widget plsel_btn_play; +static Widget plsel_btn_play; static void plsel_dialog_acceptvalues(void) @@ -416,6 +416,7 @@ plsel_set_play_button(boolean state) XtSetArg(args[0], nhStr(XtNsensitive), !state); XtSetValues(plsel_btn_play, args, ONE); + X11_update_label_if_Xft(plsel_btn_play); } static void @@ -441,6 +442,7 @@ plsel_set_sensitivities(boolean setcurr) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_role_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_role_radios[j]); if (valid < 0 && v) valid = j; } @@ -459,6 +461,7 @@ plsel_set_sensitivities(boolean setcurr) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_race_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_race_radios[j]); if (valid < 0 && v) valid = j; } @@ -566,6 +569,7 @@ X11_player_selection_setupOthers(void) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_gend_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_gend_radios[j]); if (valid < 0 && v) valid = j; } @@ -583,6 +587,7 @@ X11_player_selection_setupOthers(void) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_align_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_align_radios[j]); if (valid < 0 && v) valid = j; } @@ -619,6 +624,7 @@ racetoggleCallback(Widget w, XtPointer client, XtPointer call) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_role_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_role_radios[j]); if (valid < 0 && v) valid = j; } @@ -658,6 +664,7 @@ roletoggleCallback(Widget w, XtPointer client, XtPointer call) c = j; XtSetArg(args[0], nhStr(XtNsensitive), v); XtSetValues(plsel_race_radios[j], args, ONE); + X11_update_label_if_Xft(plsel_race_radios[j]); if (valid < 0 && v) valid = j; } @@ -688,6 +695,7 @@ gendertoggleCallback(Widget w, XtPointer client, XtPointer call) XtSetArg(args[0], XtNlabel, (r < 1) ? roles[i].name.m : roles[i].name.f); XtSetValues(plsel_role_radios[i], args, ONE); + X11_update_label_if_Xft(plsel_role_radios[i]); } } } @@ -770,6 +778,7 @@ X11_create_player_selection_name(Widget form) namelabel = XtCreateManagedWidget("name_label", labelWidgetClass, name_form, args, num_args); + X11_wrap_widget_if_Xft(namelabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNfromVert), namelabel); num_args++; @@ -899,6 +908,7 @@ X11_player_selection_dialog(void) racelabel = XtCreateManagedWidget("race_label", labelWidgetClass, race_form, args, num_args); + X11_wrap_widget_if_Xft(racelabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; @@ -939,6 +949,7 @@ X11_player_selection_dialog(void) toggleWidgetClass, race_form2, args, num_args); + X11_wrap_widget_if_Xft(racewidget, NHW_MENU); XtAddCallback(racewidget, XtNcallback, racetoggleCallback, i2xtp(i)); tmpwidget = racewidget; plsel_race_radios[i] = racewidget; @@ -963,6 +974,7 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNlabel), "Role"); num_args++; rolelabel = XtCreateManagedWidget("role_label", labelWidgetClass, role_form, args, num_args); + X11_wrap_widget_if_Xft(rolelabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; @@ -998,9 +1010,11 @@ X11_player_selection_dialog(void) plsel_role_radios[0]); num_args++; } XtSetArg(args[num_args], nhStr(XtNradioData), (i + 1)); num_args++; + XtSetArg(args[num_args], nhStr(XtNresizable), True); num_args++; rolewidget = XtCreateManagedWidget(roles[i].name.m, toggleWidgetClass, role_form2, args, num_args); + X11_wrap_widget_if_Xft(rolewidget, NHW_MENU); XtAddCallback(rolewidget, XtNcallback, roletoggleCallback, i2xtp(i)); tmpwidget = rolewidget; plsel_role_radios[i] = rolewidget; @@ -1027,6 +1041,7 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNlabel), "Gender"); num_args++; gendlabel = XtCreateManagedWidget("gender_label", labelWidgetClass, gend_form, args, num_args); + X11_wrap_widget_if_Xft(gendlabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; @@ -1048,6 +1063,7 @@ X11_player_selection_dialog(void) plsel_gend_radios[0] = gend_radio_m = XtCreateManagedWidget("Male", toggleWidgetClass, gend_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_gend_radios[0], NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNfromVert), gend_radio_m); num_args++; XtSetArg(args[num_args], XtNwidth, cwid); num_args++; @@ -1057,6 +1073,7 @@ X11_player_selection_dialog(void) plsel_gend_radios[1] = gend_radio_f = XtCreateManagedWidget("Female", toggleWidgetClass, gend_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_gend_radios[1], NHW_MENU); XawToggleUnsetCurrent(plsel_gend_radios[0]); @@ -1086,6 +1103,7 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNlabel), "Alignment"); num_args++; alignlabel = XtCreateManagedWidget("align_label", labelWidgetClass, align_form, args, num_args); + X11_wrap_widget_if_Xft(alignlabel, NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; @@ -1106,6 +1124,7 @@ X11_player_selection_dialog(void) plsel_align_radios[0] = align_radio_l = XtCreateManagedWidget("Lawful", toggleWidgetClass, align_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_align_radios[0], NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNfromVert), align_radio_l); num_args++; XtSetArg(args[num_args], XtNwidth, cwid); num_args++; @@ -1115,6 +1134,7 @@ X11_player_selection_dialog(void) plsel_align_radios[1] = align_radio_n = XtCreateManagedWidget("Neutral", toggleWidgetClass, align_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_align_radios[1], NHW_MENU); num_args = 0; XtSetArg(args[num_args], nhStr(XtNfromVert), align_radio_n); num_args++; XtSetArg(args[num_args], XtNwidth, cwid); num_args++; @@ -1124,6 +1144,7 @@ X11_player_selection_dialog(void) plsel_align_radios[2] = align_radio_c = XtCreateManagedWidget("Chaotic", toggleWidgetClass, align_form2, args, num_args); + X11_wrap_widget_if_Xft(plsel_align_radios[2], NHW_MENU); XawToggleUnsetCurrent(plsel_align_radios[0]); @@ -1159,10 +1180,13 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++; XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++; XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++; - XtSetArg(args[num_args], XtNwidth, cwid); num_args++; XtSetArg(args[num_args], nhStr(XtNlabel), "Random"); num_args++; random_btn = XtCreateManagedWidget("random", commandWidgetClass, btn_form, args, num_args); + X11_wrap_widget_if_Xft(random_btn, NHW_MENU); + num_args = 0; + XtSetArg(args[num_args], XtNwidth, cwid); num_args++; + XtSetValues(random_btn, args, num_args); XtAddCallback(random_btn, XtNcallback, plsel_random_btn_callback, form); /* "Play" button */ @@ -1171,11 +1195,14 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNfromVert), random_btn); num_args++; XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++; XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++; - XtSetArg(args[num_args], XtNwidth, cwid); num_args++; XtSetArg(args[num_args], nhStr(XtNlabel), "Play"); num_args++; plsel_btn_play = play_btn = XtCreateManagedWidget("play", commandWidgetClass, btn_form, args, num_args); + X11_wrap_widget_if_Xft(play_btn, NHW_MENU); + num_args = 0; + XtSetArg(args[num_args], XtNwidth, cwid); num_args++; + XtSetValues(play_btn, args, num_args); XtAddCallback(play_btn, XtNcallback, plsel_play_btn_callback, form); /* "Quit" button */ @@ -1185,10 +1212,13 @@ X11_player_selection_dialog(void) XtSetArg(args[num_args], nhStr(XtNbottom), XtChainBottom); num_args++; XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++; XtSetArg(args[num_args], nhStr(XtNright), XtChainRight); num_args++; - XtSetArg(args[num_args], XtNwidth, cwid); num_args++; XtSetArg(args[num_args], nhStr(XtNlabel), "Quit"); num_args++; quit_btn = XtCreateManagedWidget("quit", commandWidgetClass, btn_form, args, num_args); + X11_wrap_widget_if_Xft(quit_btn, NHW_MENU); + num_args = 0; + XtSetArg(args[num_args], XtNwidth, cwid); num_args++; + XtSetValues(quit_btn, args, num_args); XtAddCallback(quit_btn, XtNcallback, plsel_quit_btn_callback, form); /********************************************/ @@ -2039,6 +2069,7 @@ make_menu(const char *popup_name, const char *popup_label, XtSetArg(args[num_args], XtNborderWidth, 0); num_args++; label = XtCreateManagedWidget(popup_label, labelWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(label, NHW_MENU); cumulative_height = 0; XtSetArg(args[0], XtNheight, &height); @@ -2058,6 +2089,7 @@ make_menu(const char *popup_name, const char *popup_label, Sprintf(btnname, "btn_%s", left_name); left = XtCreateManagedWidget(btnname, commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(left, NHW_MENU); XtAddCallback(left, XtNcallback, left_callback, (XtPointer) 0); skip = (distance < 4) ? 8 : 2 * distance; @@ -2081,6 +2113,7 @@ make_menu(const char *popup_name, const char *popup_label, Sprintf(btnname, "btn_%s", right_name); right = XtCreateManagedWidget(btnname, commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(right, NHW_MENU); XtAddCallback(right, XtNcallback, right_callback, (XtPointer) 0); XtInstallAccelerators(form, left); @@ -2106,6 +2139,7 @@ make_menu(const char *popup_name, const char *popup_label, *curr = XtCreateManagedWidget(widget_names[i], commandWidgetClass, form, args, num_args); + X11_wrap_widget_if_Xft(*curr, NHW_MENU); XtAddCallback(*curr, XtNcallback, name_callback, (XtPointer) (ptrdiff_t) i); above = *curr++; diff --git a/win/X11/winstat.c b/win/X11/winstat.c index 4e520203c..5224522b3 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winstat.c $NHDT-Date: 1649269127 2022/04/06 18:18:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ +/* NetHack 5.0 winstat.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.50 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -94,22 +94,28 @@ #define F_HALLU 40 #define F_VERS 41 /* version info */ -#define NUM_STATS 42 + +#define F_WEAPON 42 +#define F_ARMOR 43 +#define F_TERRAIN 44 +#define F_BAREH 45 +#define F_GLOWHANDS 46 +#define F_ICY 47 +#define F_BUSY 48 +#define F_PARALYZED 49 +#define F_SLEEPING 50 +#define F_UNCONSCIOUS 51 +#define F_IRON 52 +#define F_SLIPPERY 53 +#define F_SUBMERGED 54 +#define F_WOUNDEDL 55 +#define NUM_STATS 56 static int condcolor(long, unsigned long *); static int condattr(long, unsigned long *); -static void HiliteField(Widget, int, int, int, XFontStruct **); -static void PrepStatusField(int, Widget, const char *); -static void DisplayCond(int, unsigned long *); -static int render_conditions(int, int); -#ifdef STATUS_HILITES -static void tt_reset_color(int, int, unsigned long *); -#endif -static void tt_status_fixup(void); -static Widget create_tty_status_field(int, int, Widget, Widget); static Widget create_tty_status(Widget, Widget); static void stat_resized(Widget, XtPointer, XtPointer); -static void update_fancy_status_field(int, int, int); +static void update_fancy_status_field(int, const char *, int, int); static void update_fancy_status(boolean); static Widget create_fancy_status(Widget, Widget); static void destroy_fancy_status(struct xwindow *); @@ -117,33 +123,40 @@ static void create_status_window_fancy(struct xwindow *, boolean, Widget); static void create_status_window_tty(struct xwindow *, boolean, Widget); static void destroy_status_window_fancy(struct xwindow *); static void destroy_status_window_tty(struct xwindow *); +#ifndef STATUS_HILITES static void adjust_status_fancy(struct xwindow *, const char *); static void adjust_status_tty(struct xwindow *, const char *); - -extern const char *status_fieldfmt[MAXBLSTATS]; -extern char *status_vals[MAXBLSTATS]; -extern boolean status_activefields[MAXBLSTATS]; +#endif +static void set_percent(int, int, int); +static void tty_status_exposed(Widget, XtPointer, XtPointer); +static void tty_status_redraw(Widget); +static int tty_render_field(Widget, int, int, int, enum statusfields); +static void tty_status_colors(Widget, int, int, Pixel *, Pixel *); +static int tty_render_text(Widget, const XRectangle *, int, int, const char *, + int, int, enum statusfields); static unsigned long X11_condition_bits, old_condition_bits; static int X11_status_colors[MAXBLSTATS], old_field_colors[MAXBLSTATS], old_cond_colors[32]; static int hpbar_percent, hpbar_color; -/* Number of conditions displayed during this update and last update. - When the last update had more, the excess need to be erased. */ -static int next_cond_indx = 0, prev_cond_indx = 0; -/* TODO: support statuslines:3 in addition to 2 for the tty-style status */ -#define X11_NUM_STATUS_LINES 2 -#define X11_NUM_STATUS_FIELD 16 - -static enum statusfields X11_fieldorder[][X11_NUM_STATUS_FIELD] = { +static enum statusfields X11_fieldorder_2[][18] = { { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_ALIGN, BL_SCORE, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, - BL_FLUSH, BL_FLUSH }, + BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH }, { BL_LEVELDESC, BL_GOLD, BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, - BL_AC, BL_XP, BL_EXP, BL_HD, BL_TIME, BL_HUNGER, - BL_CAP, BL_CONDITION, BL_VERS, BL_FLUSH } + BL_AC, BL_XP, BL_EXP, BL_HD, BL_TIME, BL_HUNGER, BL_CAP, + BL_CONDITION, BL_WEAPON, BL_ARMOR, BL_TERRAIN, BL_VERS } +}; + +static enum statusfields X11_fieldorder_3[][13] = { + { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_SCORE, BL_FLUSH }, + { BL_ALIGN, BL_GOLD, BL_HP, BL_HPMAX, BL_ENE, BL_ENEMAX, + BL_AC, BL_XP, BL_EXP, BL_HD, BL_HUNGER, BL_CAP, + BL_FLUSH }, + { BL_LEVELDESC, BL_TIME, BL_CONDITION, BL_WEAPON, BL_ARMOR, BL_TERRAIN, + BL_VERS, BL_FLUSH } }; /* condition list for tty-style display, roughly in order of importance */ @@ -191,13 +204,25 @@ static const char *const fancy_status_hilite_colors[] = { "white", }; -static Widget X11_status_widget; -static Widget X11_status_labels[MAXBLSTATS]; -static Widget X11_cond_labels[32]; /* Ugh */ -static XFontStruct *X11_status_font; -static Pixel X11_status_fg, X11_status_bg; +struct tty_status_field { + char *text; + int color; + unsigned attrs; + int chg; + int percent; +}; -struct xwindow *xw_status_win; +struct tty_cond_field { + const char *text; + int color; + unsigned attrs; +}; + +static Widget X11_status_widget; +static struct tty_status_field X11_status_labels[MAXBLSTATS]; +static struct tty_cond_field X11_cond_labels[32]; /* Ugh */ + +static struct xwindow *xw_status_win; static int condcolor(long bm, unsigned long *bmarray) @@ -274,6 +299,11 @@ void X11_status_enablefield(int fieldidx, const char *nm, const char *fmt, boolean enable) { + if (X11_status_widget && !enable && 0 <= fieldidx && fieldidx < MAXBLSTATS) { + free(X11_status_labels[fieldidx].text); + X11_status_labels[fieldidx].text = NULL; + tty_status_redraw(X11_status_widget); + } genl_status_enablefield(fieldidx, nm, fmt, enable); } @@ -290,367 +320,6 @@ cond_bm2idx(unsigned long bm) } #endif -/* highlight a tty-style status field (or condition) */ -static void -HiliteField(Widget label, - int fld, int cond, int colrattr, - XFontStruct **font_p) -{ -#ifdef STATUS_HILITES - static Pixel grayPxl, blackPxl, whitePxl; - Arg args[6]; - Cardinal num_args; - XFontStruct *font = X11_status_font; - Pixel px, fg = X11_status_fg, bg = X11_status_bg; - struct xwindow *xw = xw_status_win; - int colr, attr; - - if ((colrattr & 0x00ff) >= CLR_MAX) - colrattr = (colrattr & ~0x00ff) | NO_COLOR; - colr = colrattr & 0x00ff; /* guaranteed to be >= 0 and < CLR_MAX */ - attr = (colrattr >> 8) & 0x00ff; - - if (!grayPxl) {/* one-time init */ - grayPxl = get_nhcolor(xw, CLR_GRAY).pixel; - blackPxl = get_nhcolor(xw, CLR_BLACK).pixel; - whitePxl = get_nhcolor(xw, CLR_WHITE).pixel; - } - /* [shouldn't be necessary; setting up gray will set up all colors] */ - if (colr != NO_COLOR && !xw->nh_colors[colr].pixel) - (void) get_nhcolor(xw, colr); - - /* handle highlighting if caller has specified that; set foreground, - background, and font even if not specified this time in case they - used modified values last time (which would stick if not reset) */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - if (colr != NO_COLOR) - fg = xw->nh_colors[colr].pixel; - if ((attr & HL_INVERSE) != 0) { - px = fg; - fg = bg; - bg = px; - } - /* foreground and background might both default to black, so we - need to force one to be different if/when they're the same - (actually, tt_status_fixup() takes care of that nowadays); - using gray to implement 'dim' only works for black and white - (or color+'inverse' when former background was black or white) */ - if (fg == bg - || ((attr & HL_DIM) != 0 && (fg == whitePxl || fg == blackPxl))) - fg = (fg != grayPxl) ? grayPxl - : (fg != blackPxl) ? blackPxl - : whitePxl; - XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; - XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; - if (attr & HL_BOLD) { - load_boldfont(xw_status_win, label); - if (xw_status_win->boldfs) - font = xw_status_win->boldfs; - } - XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++; - XtSetValues(label, args, num_args); - - /* return possibly modified font to caller so that text width - measurement can use it */ - if (font_p) - *font_p = font; -#else /*!STATUS_HILITES*/ - nhUse(label); - nhUse(font_p); -#endif /*?STATUS_HILITES*/ - if (fld != BL_CONDITION) - old_field_colors[fld] = colrattr; - else - old_cond_colors[cond] = colrattr; -} - -/* set up a specific field other than 'condition'; its general location - was specified during widget creation but it might need adjusting */ -static void -PrepStatusField(int fld, Widget label, const char *text) -{ - Arg args[6]; - Cardinal num_args; - Dimension lbl_wid; - XFontStruct *font = X11_status_font; - int colrattr = X11_status_colors[fld]; - struct status_info_t *si = xw_status_win->Win_info.Status_info; - - /* highlight if color and/or attribute(s) are different from last time */ - if (colrattr != old_field_colors[fld]) - HiliteField(label, fld, 0, colrattr, &font); - - num_args = 0; - (void) memset((genericptr_t) args, 0, sizeof args); - /* set up the current text to be displayed */ - if (text && *text) { - lbl_wid = 2 * si->in_wd + XTextWidth(font, text, (int) strlen(text)); - } else { - text = ""; - lbl_wid = 1; - } - XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++; - /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/ - XtSetValues(label, args, num_args); - XtResizeWidget(label, lbl_wid, si->ht, si->brd); -} - -/* set up one status condition for tty-style status display */ -static void -DisplayCond( - int c_idx, /* index into tt_condorder[] */ - unsigned long *colormasks) -{ - Widget label; - Arg args[6]; - Cardinal num_args; - Dimension lbl_wid; - XFontStruct *font = X11_status_font; - int coloridx, attrmask, colrattr, idx; - unsigned long bm = tt_condorder[c_idx].mask; - const char *text = tt_condorder[c_idx].text; - struct status_info_t *si = xw_status_win->Win_info.Status_info; - - if ((X11_condition_bits & bm) == 0) - return; - - /* widgets have been created for every condition; we allocate them - from left to right rather than keeping their original assignments */ - idx = next_cond_indx; - label = X11_cond_labels[idx]; - - /* handle highlighting if caller requests it */ - coloridx = condcolor(bm, colormasks); - attrmask = condattr(bm, colormasks); - colrattr = (attrmask << 8) | coloridx; - if (colrattr != old_cond_colors[c_idx]) - HiliteField(label, BL_CONDITION, c_idx, colrattr, &font); - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - /* set the condition text and its width; this widget might have - been displaying a different condition last time around */ - XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++; - /* measure width after maybe changing font [HiliteField()] */ - lbl_wid = 2 * si->in_wd + XTextWidth(font, text, (int) strlen(text)); - /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/ - - /* make this condition widget be ready for display */ - XtSetValues(label, args, num_args); - XtResizeWidget(label, lbl_wid, si->ht, si->brd); - - ++next_cond_indx; -} - -/* display the tty-style status conditions; the number shown varies and - we might be showing more, same, or fewer than during previous status */ -static int -render_conditions(int row, int dx) -{ - Widget label; - Arg args[6]; - Cardinal num_args; - Position lbl_x; - int i, gap = 5; - struct status_info_t *si = xw_status_win->Win_info.Status_info; - Dimension lbl_wid, brd_wid = si->brd; - - for (i = 0; i < next_cond_indx; i++) { - label = X11_cond_labels[i]; - - /* width of this widget was set in DisplayCond(); fetch it */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; - XtGetValues(label, args, num_args); - - /* figure out where to draw this widget and place it there */ - lbl_x = (Position) (dx + 1 + gap); - - XtConfigureWidget(label, lbl_x, si->y[row], lbl_wid, si->ht, brd_wid); - - /* keep track of where the end of our text appears */ - dx = (int) lbl_x + (int) (lbl_wid + 2 * brd_wid) - 1; - } - - /* if we have fewer conditions shown now than last time, set the - excess ones to blank; unlike the set drawn above, these haven't - been prepared in advance by DisplayCond because they aren't - being displayed; they might have been highlighted last time so - we need to specify more than just an empty text string */ - if (next_cond_indx < prev_cond_indx) { - XFontStruct *font = X11_status_font; - Pixel fg = X11_status_fg, bg = X11_status_bg; - - lbl_x = dx + 1; - lbl_wid = 1 + 2 * brd_wid; - for (i = next_cond_indx; i < prev_cond_indx; ++i) { - label = X11_cond_labels[i]; - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++; - XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++; - XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; - XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; - /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/ - /*XtSetArg(args[num_args], nhStr(XtNx), lbl_x); num_args++;*/ - XtSetValues(label, args, num_args); - old_cond_colors[i] = NO_COLOR; /* fg, bg, font were just reset */ - XtConfigureWidget(label, lbl_x, si->y[row], lbl_wid, si->ht, 0); - /* don't advance 'dx' here */ - } - } - - return dx; -} - -#ifdef STATUS_HILITES -/* reset status_hilite for BL_RESET; if highlighting has been disabled or - this field is disabled, clear highlighting for this field or condition */ -static void -tt_reset_color( - int fld, - int cond, - unsigned long *colormasks) -{ - Widget label; - int colrattr = NO_COLOR; - - if (fld != BL_CONDITION) { - if (iflags.hilite_delta != 0L && status_activefields[fld]) - colrattr = X11_status_colors[fld]; - cond = 0; - label = X11_status_labels[fld]; - } else { - unsigned long bm = tt_condorder[cond].mask; - - if (iflags.hilite_delta != 0L && (X11_condition_bits & bm) != 0) { - /* BL_RESET before first BL_CONDITION will have colormasks==Null - but condcolor() and condattr() can cope with that */ - colrattr = condcolor(bm, colormasks); - colrattr |= (condattr(bm, colormasks) << 8); - } - label = X11_cond_labels[cond]; - } - HiliteField(label, fld, cond, colrattr, (XFontStruct **) 0); -} -#endif - -/* make sure foreground, background, and font have reasonable values, - then explicitly set them for all the status widgets; - also cache some geometry settings in (*xw_status_win).Status_info */ -static void -tt_status_fixup(void) -{ - Arg args[6]; - Cardinal num_args; - Widget w; - Position lbl_y; - int x, y, ci, fld; - XFontStruct *font = 0; - Pixel fg = 0, bg = 0; - struct status_info_t *si = xw_status_win->Win_info.Status_info; - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfont), &font); num_args++; - XtSetArg(args[num_args], nhStr(XtNforeground), &fg); num_args++; - XtSetArg(args[num_args], nhStr(XtNbackground), &bg); num_args++; - XtGetValues(X11_status_widget, args, num_args); - if (fg == bg) { - XColor black = get_nhcolor(xw_status_win, CLR_BLACK), - white = get_nhcolor(xw_status_win, CLR_WHITE); - - fg = (bg == white.pixel) ? black.pixel : white.pixel; - } - X11_status_fg = si->fg = fg, X11_status_bg = si->bg = bg; - - if (!font) { - w = X11_status_widget; - XtSetArg(args[0], nhStr(XtNfont), &font); - do { - XtGetValues(w, args, ONE); - } while (!font && (w = XtParent(w)) != 0); - - if (!font) { - /* trial and error time -- this is where we've actually - been obtaining the font even though we aren't setting - it for any of the field widgets (until for(y,x) below) */ - XtGetValues(X11_status_labels[0], args, ONE); - - if (!font) { /* this bit is untested... */ - /* write some text and hope Xaw sets up font for us */ - XtSetArg(args[0], nhStr(XtNlabel), "NetHack"); - XtSetValues(X11_status_labels[0], args, ONE); - (void) XFlush(XtDisplay(X11_status_labels[0])); - - XtSetArg(args[0], nhStr(XtNfont), &font); - XtGetValues(X11_status_labels[0], args, ONE); - - /* if still Null, XTextWidth() would crash so bail out */ - if (!font) - panic("X11 status can't determine font."); - } - } - } - X11_status_font = si->fs = font; - - /* amount of space to advance a widget's location by one space; - increase width a tiny bit beyond the actual space */ - si->spacew = XTextWidth(X11_status_font, " ", 1) + (Dimension) 1; - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNfont), font); num_args++; - XtSetArg(args[num_args], nhStr(XtNforeground), fg); num_args++; - XtSetArg(args[num_args], nhStr(XtNbackground), bg); num_args++; - XtSetValues(X11_status_widget, args, num_args); - - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { - for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { - fld = X11_fieldorder[y][x]; /* next field to handle */ - if (fld <= BL_FLUSH) - continue; /* skip fieldorder[][] padding */ - - XtSetValues(X11_status_labels[fld], args, num_args); - old_field_colors[fld] = NO_COLOR; - - if (fld == BL_CONDITION) { - for (ci = 0; ci < SIZE(X11_cond_labels); ++ci) { /* 0..31 */ - XtSetValues(X11_cond_labels[ci], args, num_args); - old_cond_colors[ci] = NO_COLOR; - } - } - } - } - - /* cache the y coordinate of each row for XtConfigureWidget() */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[0], nhStr(XtNy), &lbl_y); num_args++; - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { - fld = X11_fieldorder[y][0]; - XtGetValues(X11_status_labels[fld], args, num_args); - si->y[y] = lbl_y; - } - - /* cache height, borderWidth, and internalWidth for XtResizeWidget() */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNheight), &si->ht); num_args++; - XtSetArg(args[num_args], nhStr(XtNborderWidth), &si->brd); num_args++; - XtSetArg(args[num_args], nhStr(XtNinternalWidth), &si->in_wd); num_args++; - XtGetValues(X11_status_labels[0], args, num_args); - - /* X11_status_update_tty() wants this in order to right justify 'vers' */ - if (!xw_status_win->pixel_width) { - XtSetArg(args[0], nhStr(XtNwidth), &xw_status_win->pixel_width); - XtGetValues(xw_status_win->w, args, ONE); - } -} - DISABLE_WARNING_FORMAT_NONLITERAL /* core requests updating one status field (or is indicating that it's time @@ -659,179 +328,70 @@ static void X11_status_update_tty( int fld, genericptr_t ptr, - int chg UNUSED, + int chg, int percent, int color, unsigned long *colormasks) /* bitmask of highlights for conditions */ { - static int xtra_space[MAXBLSTATS]; - static unsigned long *cond_colormasks = (unsigned long *) 0; +#ifndef STATUS_HILITES + nhUse(colormasks); +#endif - Arg args[6]; - Cardinal num_args; - Position lbl_x; - Dimension lbl_wid, brd_wid; - Widget label; + switch (fld) { + case BL_RESET: + case BL_FLUSH: + tty_status_redraw(X11_status_widget); + break; - struct status_info_t *si; - char goldbuf[40]; - const char *fmt; - const char *text; - unsigned long *condptr; - int f, x, y, dx; - - if (X11_status_fg == X11_status_bg || !X11_status_font) - tt_status_fixup(); - - if (fld == BL_RESET) { -#ifdef STATUS_HILITES - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { - for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { - f = X11_fieldorder[y][x]; - if (f <= BL_FLUSH) - continue; /* skip padding in the fieldorder[][] layout */ - if (f != BL_CONDITION) { - tt_reset_color(f, 0, (unsigned long *) 0); + case BL_CONDITION: + { + unsigned long cond = *(unsigned long const *)ptr; + for (unsigned j = 0; j < SIZE(tt_condorder); ++j) { + struct tty_cond_field *fldp = &X11_cond_labels[j]; + fldp->color = NO_COLOR; + fldp->attrs = 0; + if ((cond & tt_condorder[j].mask) != 0) { + fldp->text = tt_condorder[j].text; } else { - int c_i; - - for (c_i = 0; c_i < SIZE(tt_condorder); ++c_i) - tt_reset_color(f, c_i, cond_colormasks); + fldp->text = NULL; } } - } -#endif - fld = BL_FLUSH; - } - - if (fld == BL_CONDITION) { - condptr = (unsigned long *) ptr; - X11_condition_bits = *condptr; - cond_colormasks = colormasks; /* expected to be non-Null */ - - prev_cond_indx = next_cond_indx; - next_cond_indx = 0; - /* if any conditions are active, set up their widgets */ - if (X11_condition_bits) - for (f = 0; f < SIZE(tt_condorder); ++f) - DisplayCond(f, cond_colormasks); - return; - - } else if (fld != BL_FLUSH) { - /* set up a specific field other than 'condition' */ - text = (char *) ptr; - if (fld == BL_GOLD) - text = decode_mixed(goldbuf, text); - xtra_space[fld] = 0; - if (status_activefields[fld]) { - fmt = (fld == BL_TITLE && iflags.wc2_hitpointbar) ? "%-30s" - : status_fieldfmt[fld] ? status_fieldfmt[fld] : "%s"; - if (*fmt == ' ') { - ++xtra_space[fld]; - ++fmt; - } - Sprintf(status_vals[fld], fmt, text); - } else { - /* don't expect this since core won't call status_update() - for a field which isn't active */ - *status_vals[fld] = '\0'; - } #ifdef STATUS_HILITES - if (!iflags.hilite_delta) - color = NO_COLOR; + for (unsigned i = 0; i < CLR_MAX; ++i) { + unsigned long mask = colormasks[i]; + for (unsigned j = 0; j < SIZE(tt_condorder); ++j) { + if ((mask & tt_condorder[j].mask) != 0) { + struct tty_cond_field *fldp = &X11_cond_labels[j]; + fldp->color = i; + } + } + } + for (unsigned i = CLR_MAX; i < BL_ATTCLR_MAX; ++i) { + unsigned long mask = colormasks[i]; + for (unsigned j = 0; j < SIZE(tt_condorder); ++j) { + if ((mask & tt_condorder[j].mask) != 0) { + struct tty_cond_field *fldp = &X11_cond_labels[j]; + fldp->attrs |= 0x1 << (i - HL_ATTCLR_NONE); + } + } + } #endif - X11_status_colors[fld] = color; - if (iflags.wc2_hitpointbar && fld == BL_HP) { - hpbar_percent = percent; - hpbar_color = color; } + break; - label = X11_status_labels[fld]; - text = status_vals[fld]; - PrepStatusField(fld, label, text); - return; + default: + if (0 <= fld && fld < SIZE(X11_status_labels)) { + struct tty_status_field *fldp = &X11_status_labels[fld]; + const char *str = (const char *) ptr; + free(fldp->text); + fldp->text = dupstr(str); + fldp->chg = chg; + fldp->percent = percent; + fldp->color = color & 0xFF; + fldp->attrs = color >> 8; + } + break; } - - /* - * BL_FLUSH: draw all the status fields. - */ - si = xw_status_win->Win_info.Status_info; /* for cached geometry */ - - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { /* row */ - dx = 0; /* no pixels written to this row yet */ - - for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { /* 'column' */ - f = X11_fieldorder[y][x]; - if (f <= BL_FLUSH) - continue; /* skip padding in the fieldorder[][] layout */ - - if (f == BL_CONDITION) { - if (next_cond_indx > 0 || prev_cond_indx > 0) - dx = render_conditions(y, dx); - continue; - } - - label = X11_status_labels[f]; - text = status_vals[f]; - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNwidth), &lbl_wid); num_args++; - XtGetValues(label, args, num_args); - brd_wid = si->brd; - - /* for a field which shouldn't be shown, we can't just skip - it because we might need to remove its previous content - if it has just been toggled off */ - if (!status_activefields[f]) { - if (lbl_wid <= 1) - continue; - text = ""; - lbl_wid = (Dimension) 1; - brd_wid = (Dimension) 0; - } else if (xtra_space[f]) { - /* if this field was to be formatted with a leading space - to separate it from the preceding field, we suppressed - that space during formatting; insert separation between - fields here; this prevents inverse video highlighting - from inverting the separating space along with the text */ - dx += xtra_space[f] * si->spacew; - } - - /* where to display the current widget */ - lbl_x = (Position) (dx + 1); - if (f == BL_VERS) { - Dimension win_wid = xw_status_win->pixel_width, - fld_wid = lbl_wid + 2 * brd_wid; - - /* in case the doodad for resizing the window via click and - drag is in the lower right corner; justifying all the way - to the edge results in the last character being obscured; - avoid that by treating the 'vers' widget as one char - bigger than it actually is (an implicit trailing space) */ - fld_wid += si->spacew; - /* right justify if there's room */ - if (dx < win_wid - fld_wid) - lbl_x = win_wid - fld_wid; - } - - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - XtSetArg(args[num_args], nhStr(XtNlabel), text); num_args++; - /*XtSetArg(args[num_args], nhStr(XtNwidth), lbl_wid); num_args++;*/ - /*XtSetArg(args[num_args], nhStr(XtNx), lbl_x); num_args++;*/ - XtSetValues(label, args, num_args); - XtConfigureWidget(label, lbl_x, si->y[y], - lbl_wid, si->ht, brd_wid); - - /* track the right-most pixel written so far */ - dx = (int) lbl_x + (int) (lbl_wid + 2 * brd_wid) - 1; - } /* [x] fields/columns in current row */ - } /* [y] rows */ - - /* this probably doesn't buy us anything but it isn't a sure thing - that nethack will immediately ask for input (triggering auto-flush) */ - (void) XFlush(XtDisplay(X11_status_labels[0])); } RESTORE_WARNING_FORMAT_NONLITERAL @@ -841,7 +401,7 @@ static void X11_status_update_fancy( int fld, genericptr_t ptr, - int chg UNUSED, int percent UNUSED, + int chg UNUSED, int percent, int colrattr, unsigned long *colormasks UNUSED) { @@ -869,6 +429,9 @@ X11_status_update_fancy( { BL_HPMAX, F_MAXHP }, { BL_LEVELDESC, F_DLEVEL }, { BL_VERS, F_VERS }, + { BL_WEAPON, F_WEAPON }, + { BL_ARMOR, F_ARMOR }, + { BL_TERRAIN, F_TERRAIN }, { BL_EXP, F_EXP_PTS } }; static const struct mask_to_ff { @@ -893,6 +456,17 @@ X11_status_update_fancy( { BL_MASK_TETHERED, F_TETHERED }, { BL_MASK_LEV, F_LEV }, { BL_MASK_FLY, F_FLY }, + { BL_MASK_BAREH, F_BAREH }, + { BL_MASK_GLOWHANDS, F_GLOWHANDS }, + { BL_MASK_ICY, F_ICY }, + { BL_MASK_BUSY, F_BUSY }, + { BL_MASK_PARLYZ, F_PARALYZED }, + { BL_MASK_SLEEPING, F_SLEEPING }, + { BL_MASK_UNCONSC, F_UNCONSCIOUS }, + { BL_MASK_ELF_IRON, F_IRON }, + { BL_MASK_SLIPPERY, F_SLIPPERY }, + { BL_MASK_SUBMERGED, F_SUBMERGED }, + { BL_MASK_WOUNDEDL, F_WOUNDEDL }, { BL_MASK_RIDE, F_RIDE } }; int i; @@ -914,6 +488,7 @@ X11_status_update_fancy( for (i = 0; i < SIZE(mask_to_fancyfield); i++) if ((changed_bits & mask_to_fancyfield[i].mask) != 0L) update_fancy_status_field(mask_to_fancyfield[i].ff, + NULL, condcolor(mask_to_fancyfield[i].mask, colormasks), condattr(mask_to_fancyfield[i].mask, colormasks)); old_condition_bits = X11_condition_bits; /* remember 'On' bits */ @@ -928,9 +503,15 @@ X11_status_update_fancy( for (i = 0; i < SIZE(bl_to_fancyfield); i++) if (bl_to_fancyfield[i].bl == fld) { - update_fancy_status_field(bl_to_fancyfield[i].ff, colr, attr); + update_fancy_status_field(bl_to_fancyfield[i].ff, + (const char *) ptr, colr, attr); break; } + + /* Hit point bar */ + if (fld == BL_HP) { + set_percent(F_NAME, iflags.wc2_hitpointbar ? percent : 0, colr); + } } } @@ -951,57 +532,14 @@ X11_status_update( X11_status_update_tty(fld, ptr, chg, percent, color, colormasks); } -/* create a widget for a particular status field or potential condition */ -static Widget -create_tty_status_field(int fld, int condindx, Widget above, Widget left) -{ - Arg args[16]; - Cardinal num_args; - char labelname[40]; - int gap = condindx ? 5 : 0; - - if (!condindx) - Sprintf(labelname, "label_%s", bl_idx_to_fldname(fld)); - else - Sprintf(labelname, "cond_%02d", condindx); - - /* set up widget attributes which (mostly) aren't going to be changing */ - (void) memset((genericptr_t) args, 0, sizeof args); - num_args = 0; - if (above) { - XtSetArg(args[num_args], nhStr(XtNfromVert), above); num_args++; - } - if (left) { - XtSetArg(args[num_args], nhStr(XtNfromHoriz), left); num_args++; - } - - XtSetArg(args[num_args], nhStr(XtNhorizDistance), gap); num_args++; - XtSetArg(args[num_args], nhStr(XtNvertDistance), 0); num_args++; - - XtSetArg(args[num_args], nhStr(XtNtopMargin), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNbottomMargin), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNleftMargin), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNrightMargin), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNjustify), XtJustifyLeft); num_args++; - /* internalWidth: default is 4; cut that it half and adjust regular - width to have it on both left and right instead of just on the left */ - XtSetArg(args[num_args], nhStr(XtNinternalWidth), 2); num_args++; - XtSetArg(args[num_args], nhStr(XtNborderWidth), 0); num_args++; - XtSetArg(args[num_args], nhStr(XtNlabel), ""); num_args++; - return XtCreateManagedWidget(labelname, labelWidgetClass, - X11_status_widget, args, num_args); -} - /* create an overall status widget (X11_status_widget) and also separate widgets for all status fields and potential conditions */ static Widget create_tty_status(Widget parent, Widget top) { Widget form; /* viewport that holds the form that surrounds everything */ - Widget w, over_w, prev_w; Arg args[6]; Cardinal num_args; - int x, y, i, fld; (void) memset((genericptr_t) args, 0, sizeof args); num_args = 0; @@ -1019,33 +557,517 @@ create_tty_status(Widget parent, Widget top) num_args = 0; XtSetArg(args[num_args], XtNwidth, 400); num_args++; XtSetArg(args[num_args], XtNheight, 100); num_args++; - X11_status_widget = XtCreateManagedWidget("status_form", formWidgetClass, + X11_status_widget = XtCreateManagedWidget("status_form", windowWidgetClass, form, args, num_args); - for (y = 0; y < X11_NUM_STATUS_LINES; y++) { - fld = (y > 0) ? X11_fieldorder[y - 1][0] : 0; /* temp, for over_w */ - /* for row(s) beyond the first, pick a widget in the previous - row to put this one underneath (in 'y' terms; 'x' is fluid) */ - over_w = (y > 0) ? X11_status_labels[fld] : (Widget) 0; - /* widget on current row to put the next one to the right of ('x') */ - prev_w = (Widget) 0; - for (x = 0; x < X11_NUM_STATUS_FIELD; x++) { - fld = X11_fieldorder[y][x]; /* next field to handle */ - if (fld <= BL_FLUSH) - continue; /* skip fieldorder[][] padding */ + int height = nhFontHeight(X11_status_widget, NHW_STATUS) * 3; + num_args = 0; + XtSetArg(args[num_args], XtNheight, height); num_args++; + XtSetValues(form, args, num_args); + XtSetValues(X11_status_widget, args, num_args); - w = create_tty_status_field(fld, 0, over_w, prev_w); - X11_status_labels[fld] = prev_w = w; + XtAddCallback(X11_status_widget, XtNexposeCallback, tty_status_exposed, + (XtPointer) 0); - if (fld == BL_CONDITION) { - for (i = 1; i <= SIZE(X11_cond_labels); ++i) { /* 1..32 */ - w = create_tty_status_field(fld, i, over_w, prev_w); - X11_cond_labels[i - 1] = prev_w = w; + return X11_status_widget; +} + +/* + * TTY status window expose callback. + */ +/*ARGSUSED*/ +static void +tty_status_exposed(Widget w, XtPointer client_data, /* unused */ + XtPointer widget_data) /* expose event from Window widget */ +{ + tty_status_redraw(w); + nhUse(client_data); + nhUse(widget_data); +} + +#ifdef STATUS_HILITES +void +X11_tty_status_blink(void) +{ + /* Do we have any active blink attributes? */ + boolean have_blink = FALSE; + for (unsigned i = 0; i < SIZE(X11_status_labels) && !have_blink; ++i) { + have_blink = (X11_status_labels[i].attrs & HL_BLINK) != 0; + } + for (unsigned i = 0; i < SIZE(X11_cond_labels) && !have_blink; ++i) { + have_blink = (X11_cond_labels[i].attrs & HL_BLINK) != 0; + } + + if (have_blink) { + tty_status_redraw(X11_status_widget); + } +} +#endif /* STATUS_HILITES */ + +static void +tty_status_redraw(Widget w) +{ + Arg args[5]; + int num_args; + Dimension width; + + /* Name is placed here */ + int name_x = 0; + int name_y = 0; + int name_width = 0; + + /* Get the height of the font and the width of the widget */ + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &width); num_args++; + XtGetValues(w, args, num_args); + int height = nhFontHeight(w, NHW_STATUS); + + /* Space between fields. For now, this is equal to one half the height. */ + int spacing = height/2; + + int x = 0; + int y = 0; + XClearWindow(XtDisplay(w), XtWindow(w)); + if (iflags.wc2_statuslines <= 2) { + for (unsigned row = 0; row < SIZE(X11_fieldorder_2); ++row) { + for (unsigned i = 0; i < SIZE(X11_fieldorder_2[0]); ++i) { + enum statusfields fld = X11_fieldorder_2[row][i]; + if (fld == BL_FLUSH) { + break; + } + int wid = tty_render_field(w, x, y, spacing, fld); + if (fld == BL_TITLE) { + name_x = x; + name_y = y; + name_width = wid; + } + x += wid; + } + x = 0; + y += height; + } + } else { + for (unsigned row = 0; row < SIZE(X11_fieldorder_3); ++row) { + for (unsigned i = 0; i < SIZE(X11_fieldorder_3[0]); ++i) { + enum statusfields fld = X11_fieldorder_3[row][i]; + if (fld == BL_FLUSH) { + break; + } + int wid = tty_render_field(w, x, y, spacing, fld); + if (fld == BL_TITLE) { + name_x = x; + name_y = y; + name_width = wid; + } + x += wid; + } + x = 0; + y += height; + } + } + + /* + * Draw the hit point bar using: + * * the colors for hit points + * * the opposite of the HL_INVERSE bit for the title + * * the font for the title + */ + if (name_width != 0 && iflags.wc2_hitpointbar) { + XRectangle clip = { + .x = name_x, + .y = name_y, + .width = name_width * X11_status_labels[BL_HP].percent / 100, + .height = height + }; + struct tty_status_field const *title = &X11_status_labels[BL_TITLE]; + struct tty_status_field const *hitp = &X11_status_labels[BL_HP]; + int attrs = ((title->attrs & ~HL_DIM) ^ HL_INVERSE) + | (hitp->attrs & HL_DIM); + tty_render_text(w, &clip, name_x, name_y, + title->text, hitp->color, attrs, + BL_TITLE); + } +} + +/* Render one field of the TTY status */ +static int +tty_render_field(Widget w, int x, int y, int spacing, enum statusfields fld) +{ + static struct stat_fmt { + const char *pre; + const char *post; + } formats[MAXBLSTATS] = { + [BL_TITLE] = { NULL, NULL }, + [BL_STR] = { "St:", NULL }, + [BL_DX] = { "Dx:", NULL }, + [BL_CO] = { "Co:", NULL }, + [BL_IN] = { "In:", NULL }, + [BL_WI] = { "Wi:", NULL }, + [BL_CH] = { "Ch:", NULL }, + [BL_ALIGN] = { NULL, NULL }, + [BL_SCORE] = { "S:", NULL }, + [BL_CAP] = { NULL, NULL }, + [BL_GOLD] = { NULL, NULL }, + [BL_ENE] = { "Pw:", NULL }, + [BL_ENEMAX] = { "(", ")" }, + [BL_XP] = { "Xp:", NULL }, + [BL_AC] = { "AC:", NULL }, + [BL_HD] = { "HD:", NULL }, + [BL_TIME] = { "T:", NULL }, + [BL_HUNGER] = { NULL, NULL }, + [BL_HP] = { "HP:", NULL }, + [BL_HPMAX] = { "(", ")" }, + [BL_LEVELDESC] = { NULL, NULL }, + [BL_EXP] = { "/", NULL }, + [BL_CONDITION] = { NULL, NULL }, + [BL_WEAPON] = { NULL, NULL }, + [BL_ARMOR] = { NULL, NULL }, + [BL_TERRAIN] = { NULL, NULL }, + [BL_VERS] = { NULL, NULL }, + }; + + int width = 0; + + switch (fld) { + case BL_FLUSH: + break; + + case BL_CONDITION: + for (unsigned j = 0; j < SIZE(X11_cond_labels); ++j) { + struct tty_cond_field const *fldp = &X11_cond_labels[j]; + if (fldp->text != NULL) { + width += spacing; + width += tty_render_text(w, NULL, x + width, y, fldp->text, fldp->color, fldp->attrs, BL_FLUSH); + } + } + break; + + default: + { + struct tty_status_field const *fldp = &X11_status_labels[fld]; + if (fldp->text != NULL && fldp->text[0] != '\0') { + if (x != 0 && (formats[fld].pre == NULL || strchr("(/", formats[fld].pre[0]) == NULL)) { + width += spacing; + } + if (formats[fld].pre != NULL) { + width += tty_render_text(w, NULL, x + width, y, formats[fld].pre, NO_COLOR, 0, BL_FLUSH); + } + width += tty_render_text(w, NULL, x + width, y, fldp->text, fldp->color, + fldp->attrs, fld); + if (formats[fld].post != NULL) { + width += tty_render_text(w, NULL, x + width, y, formats[fld].post, NO_COLOR, 0, BL_FLUSH); } } } + break; } - return X11_status_widget; + + return width; +} + +/* Render text as part of the TTY status */ +static int +tty_render_text(Widget w, const XRectangle *clip, int x, int y, + const char *text, int color, int attr, enum statusfields fld) +{ +#ifndef STATUS_HILITES + nhUse(color); + nhUse(attr); +#endif + + int goldwidth = 0; + + /* Get the colors */ + Pixel fgpixel, bgpixel; + tty_status_colors(w, color, attr, &fgpixel, &bgpixel); + +#ifdef USE_XFT + + /* Get the font */ + XftFont *font = X11_new_font(w, attr, NHW_STATUS); + int height = X11_font_height(font); + + /* Get the drawing resources */ + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, XtWindow(w), visual, cmap); + + /* Convert the colors to Xft form */ + XftColor fgcolor, bgcolor; + X11_new_color(w, fgpixel, &fgcolor); + X11_new_color(w, bgpixel, &bgcolor); + + /* If drawing a hitpoint bar, we'll need a clipping rectangle */ + if (clip != NULL) { + XftDrawSetClipRectangles(draw, 0, 0, clip, 1); + } + + /* Gold will begin with a glyph string. Convert this to the proper + character, which might possibly be Unicode */ + if (fld == BL_GOLD && memcmp(text, "\\G", 2) == 0) { + char *end; + unsigned long glyphcode = strtoul(text+2, &end, 16); + if ((glyphcode >> 16) == (unsigned) svc.context.rndencode && *end == ':') { + /* We have a proper glyph code */ + glyph_info glyphinfo; + glyphcode &= 0xFFFF; + map_glyphinfo(0, 0, glyphcode, 0, &glyphinfo); + X11_map_symbol goldsym = X11_glyph_char(&glyphinfo); + + /* Get the width of the gold symbol */ + XGlyphInfo extents; +#ifdef ENHANCED_SYMBOLS + FcChar32 goldch = goldsym; + XftTextExtents32(display, font, &goldch, 1, &extents); +#else /* !ENHANCED_SYMBOLS */ + FcChar8 goldch = goldsym; + XftTextExtents8(display, font, &goldch, 1, &extents); +#endif /* ?ENHANCED_SYMBOLS */ + goldwidth = extents.width - extents.x; + + /* Render the gold symbol */ + XftDrawRect(draw, &bgcolor, x, y, goldwidth, height); +#ifdef ENHANCED_SYMBOLS + XftDrawString32(draw, &fgcolor, font, x, y + font->ascent, &goldch, 1); +#else /* !ENHANCED_SYMBOLS */ + XftDrawString8(draw, &fgcolor, font, x, y + font->ascent, &goldch, 1); +#endif /* ?ENHANCED_SYMBOLS */ + + text = end; + } + } + + /* Get the width of the rendered string, not including goldwidth */ + XGlyphInfo extents; + XftTextExtents8(display, font, (const FcChar8 *) text, strlen(text), &extents); + int width = extents.width - extents.x; + + /* Place version on the right */ + if (fld == BL_VERS) { + Cardinal num_args = 0; + Arg args[1]; + Dimension wwidth; + XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtGetValues(w, args, num_args); + int x2 = wwidth - width; + if (x2 > x) { + x = x2; + } + } + + /* Render the string */ + XftDrawRect(draw, &bgcolor, x + goldwidth, y, width, height); + XftDrawString8(draw, &fgcolor, font, + x + goldwidth, y + font->ascent, + (const FcChar8 *) text, strlen(text)); + width += goldwidth; + +#ifdef STATUS_HILITES + /* Implement underline */ + if (attr & HL_ULINE) { + XftDrawRect(draw, &fgcolor, x, y + font->ascent, width, 1); + } +#endif /* STATUS_HILITES */ + + /* Release resources */ + + XftColorFree(display, visual, cmap, &fgcolor); + XftColorFree(display, visual, cmap, &bgcolor); + XftDrawDestroy(draw); + X11_release_font(w, font); + +#else /* !USE_XFT */ + + Arg args[5]; + Cardinal num_args; + XGCValues values; + XFontStruct *font; + XFontStruct *font_italic = NULL; /* custodial */ + + values.foreground = fgpixel; + values.background = bgpixel; + + /* Get the font */ + num_args = 0; + XtSetArg(args[num_args], XtNfont, &font); num_args++; + XtGetValues(w, args, num_args); + + /* Implement bold font */ + if (attr & HL_BOLD) { + struct xwindow *wp = find_widget(w); + load_boldfont(wp, w); + font = wp->boldfs; + } + + /* Implement italic font */ + if (attr & HL_ITALIC) { + /* font may also be bold */ + font_italic = X11_italic_font(XtDisplay(w), font); + if (font_italic != NULL) { + font = font_italic; + } + } + + /* Get a graphics context */ + values.font = font->fid; + values.function = GXcopy; + GC ggc = XtGetGC(w, + GCFunction | GCForeground | GCBackground | GCFont, + &values); + + /* If drawing a hitpoint bar, we'll need a clipping rectangle */ + if (clip != NULL) { + /* @#$% non-const-correct Xlib functions */ + XRectangle clip2 = *clip; + XSetClipRectangles(XtDisplay(w), ggc, 0, 0, &clip2, 1, Unsorted); + } + + /* Gold will begin with a glyph string. Convert this to the proper + character, which might possibly be Unicode */ + if (fld == BL_GOLD && memcmp(text, "\\G", 2) == 0) { + char *end; + unsigned long glyphcode = strtoul(text+2, &end, 16); + if ((glyphcode >> 16) == (unsigned) svc.context.rndencode && *end == ':') { + /* We have a proper glyph code */ + glyph_info glyphinfo; + glyphcode &= 0xFFFF; + map_glyphinfo(0, 0, glyphcode, 0, &glyphinfo); + X11_map_symbol goldsym = X11_glyph_char(&glyphinfo); +#ifdef ENHANCED_SYMBOLS + if (goldsym > 0xFFFF) { + /* No support for supplementary planes */ + goldsym = GOLD_SYM; + } + if (goldsym > 0x7F) { + XFontStruct *unifont = X11_unicode_font(XtDisplay(w), font); + + if (unifont != NULL) { + XChar2b goldstr[1]; + values.font = unifont->fid; + GC ggc2 = XtGetGC(w, + GCFunction | GCForeground | GCBackground | GCFont, + &values); + + goldstr[0].byte1 = goldsym >> 8; + goldstr[0].byte2 = goldsym & 0xFF; + goldwidth = XTextWidth16(font, goldstr, 1); + + /* Render the string */ + XDrawImageString16(XtDisplay(w), XtWindow(w), ggc, + x, y + font->max_bounds.ascent, + goldstr, 1); + + XFreeFont(XtDisplay(w), unifont); + XtReleaseGC(w, ggc2); + } + } +#endif + if (goldwidth == 0) { + char goldstr[1]; + goldstr[0] = (char) goldsym; + goldwidth = XTextWidth(font, goldstr, 1); + + /* Render the string */ + XDrawImageString(XtDisplay(w), XtWindow(w), ggc, + x, y + font->max_bounds.ascent, + goldstr, 1); + } + + text = end; + } + } + + /* Get the width of the rendered string */ + int width = XTextWidth(font, text, strlen(text)) + goldwidth; + + /* Place version on the right */ + if (fld == BL_VERS) { + num_args = 0; + Dimension wwidth; + XtSetArg(args[num_args], XtNwidth, &wwidth); num_args++; + XtGetValues(w, args, num_args); + int x2 = wwidth - width; + if (x2 > x) { + x = x2; + } + } + + /* Render the string */ + XDrawImageString(XtDisplay(w), XtWindow(w), ggc, + x + goldwidth, y + font->max_bounds.ascent, + text, strlen(text)); + +#ifdef STATUS_HILITES + /* Implement underline */ + if (attr & HL_ULINE) { + XDrawLine(XtDisplay(w), XtWindow(w), ggc, + x, y + font->max_bounds.ascent, + x + width - 1, y + font->max_bounds.ascent); + } +#endif /* STATUS_HILITES */ + + /* Release resources */ + XtReleaseGC(w, ggc); + if (font_italic != NULL) { + XFreeFont(XtDisplay(w), font_italic); + } +#endif /* ?USE_XFT */ + + /* Caller will advance x by the width */ + return width; +} + +static void +tty_status_colors(Widget w, int color, int attr, Pixel *fgpixel, Pixel *bgpixel) +{ + Cardinal num_args; + Arg args[5]; + + /* Get the default colors */ + num_args = 0; + XtSetArg(args[num_args], XtNforeground, fgpixel); num_args++; + XtSetArg(args[num_args], XtNbackground, bgpixel); num_args++; + XtGetValues(w, args, num_args); + + /* Implement color if requested */ +#ifdef STATUS_HILITES + if (color != NO_COLOR) { + XrmValue source; + XrmValue dest; + Pixel pixel; + const char *cname = fancy_status_hilite_colors[color]; + source.addr = (XPointer) cname; + source.size = (unsigned int) strlen(cname) + 1; + dest.size = (unsigned int) sizeof (Pixel); + dest.addr = (XPointer) &pixel; + if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) + *fgpixel = pixel; + } + + /* Implement dim text */ + if (attr & HL_DIM) { + *fgpixel = (*fgpixel & 0xFEFEFE) >> 1; + *bgpixel = (*bgpixel & 0xFEFEFE) >> 1; + } + + /* Implement blink */ + if ((attr & HL_BLINK) && X11_blink) { + *fgpixel = *bgpixel; + } + + /* Get a graphics context */ + if (attr & HL_INVERSE) { + Pixel swap; + swap = *fgpixel; + *fgpixel = *bgpixel; + *bgpixel = swap; + } +#else + nhUse(color); + nhUse(attr); +#endif } /*ARGSUSED*/ @@ -1076,6 +1098,7 @@ destroy_status_window_tty(struct xwindow *wp) wp->type = NHW_NONE; } +#ifndef STATUS_HILITES /*ARGSUSED*/ void adjust_status_tty(struct xwindow *wp UNUSED, const char *str UNUSED) @@ -1083,6 +1106,7 @@ adjust_status_tty(struct xwindow *wp UNUSED, const char *str UNUSED) /* nothing */ return; } +#endif void create_status_window( @@ -1146,6 +1170,7 @@ destroy_status_window(struct xwindow *wp) destroy_status_window_tty(wp); } +#ifndef STATUS_HILITES void adjust_status(struct xwindow *wp, const char *str) { @@ -1154,6 +1179,7 @@ adjust_status(struct xwindow *wp, const char *str) else adjust_status_tty(wp, str); } +#endif void create_status_window_fancy(struct xwindow *wp, /* window pointer */ @@ -1224,7 +1250,7 @@ create_status_window_fancy(struct xwindow *wp, /* window pointer */ &right_margin); num_args++; XtGetValues(wp->w, args, num_args); - wp->pixel_height = 2 * nhFontHeight(wp->w) + top_margin + bottom_margin; + wp->pixel_height = 2 * nhFontHeight(wp->w, NHW_STATUS) + top_margin + bottom_margin; wp->pixel_width = COLNO * fs->max_bounds.width + left_margin + right_margin; @@ -1254,6 +1280,7 @@ destroy_status_window_fancy(struct xwindow *wp) wp->type = NHW_NONE; } +#ifndef STATUS_HILITES /* * This assumes several things: * + Status has only 2 lines @@ -1284,6 +1311,7 @@ adjust_status_fancy(struct xwindow *wp, const char *str) wp->status_information->text.text); num_args++; XtSetValues(wp->w, args, num_args); } +#endif /* Fancy ================================================================== */ extern const char *const hu_stat[]; /* from eat.c */ @@ -1321,11 +1349,10 @@ struct f_overload { static const struct f_overload *ff_ovld_from_mask(unsigned long); static const struct f_overload *ff_ovld_from_indx(int); -static void hilight_label(Widget); -static void update_val(struct X_status_value *, long); +static void update_val(struct X_status_value *, long, const char *); static void skip_cond_val(struct X_status_value *); static void update_color(struct X_status_value *, int); -static boolean name_widget_has_label(struct X_status_value *); +static Pixel color_to_pixel(Widget, int); static void apply_hilite_attributes(struct X_status_value *, int); static const char *width_string(int); static void create_widget(Widget, struct X_status_value *, int); @@ -1410,6 +1437,20 @@ static struct X_status_value shown_stats[NUM_STATS] = { { "Hallucinat", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, /* F_VERS; optionally shown, generally treated as a pseudo-condition */ { "Version 1.2.3", SV_LABEL, W0, 0L, 0, FALSE, FALSE, FALSE, P0, 0, 0 }, + { "Weapon", SV_NAME, W0, -1L, 0, FALSE, FALSE, FALSE, P0, 0, 0 }, + { "Armor", SV_NAME, W0, -1L, 0, FALSE, FALSE, FALSE, P0, 0, 0 }, + { "Terrain", SV_NAME, W0, -1L, 0, FALSE, FALSE, FALSE, P0, 0, 0 }, + { "BareHands", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "GlowHands", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Icy", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Busy", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Paralyzed", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Sleeping", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Unconsc", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "ElfIron", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Slippery", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "Submerged", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, + { "HurtLegs", SV_NAME, W0, 0L, 0, FALSE, TRUE, FALSE, P0, 0, 0 }, }; #undef W0 #undef P0 @@ -1442,14 +1483,12 @@ static const struct f_overload cond_ovl[] = { { { BL_MASK_HELD, F_HELD }, { BL_MASK_HOLDING, F_HOLDING } }, }, -#if 0 /* not yet implemented */ - { (BL_MASK_BUSY | BL_MASK_PARALYZ | BL_MASK_SLEEPING | BL_MASK_UNCONSC), + { (BL_MASK_BUSY | BL_MASK_PARLYZ | BL_MASK_SLEEPING | BL_MASK_UNCONSC), { { BL_MASK_BUSY, F_BUSY }, /* can't move but none of the below... */ - { BL_MASK_PARALYZ, F_PARALYZED } - { BL_MASK_SLEEPING, F_SLEEPING } + { BL_MASK_PARLYZ, F_PARALYZED }, + { BL_MASK_SLEEPING, F_SLEEPING }, { BL_MASK_UNCONSC, F_UNCONSCIOUS } }, }, -#endif }; static const struct f_overload * @@ -1502,6 +1541,7 @@ null_out_status(void) case SV_NAME: XtSetArg(args[0], XtNlabel, ""); XtSetValues(sv->w, args, ONE); + X11_update_label(sv->w); break; default: @@ -1511,22 +1551,10 @@ null_out_status(void) } } -/* this is almost an exact duplicate of hilight_value() */ -static void -hilight_label(Widget w) /* label widget */ -{ - /* - * This predates STATUS_HILITES. - * It is used to show any changed item in inverse and gets - * reset on the next turn. - */ - swap_fg_bg(w); -} - DISABLE_WARNING_FORMAT_NONLITERAL static void -update_val(struct X_status_value *attr_rec, long new_value) +update_val(struct X_status_value *attr_rec, long new_value, const char *new_valuestr) { static boolean Exp_shown = TRUE, time_shown = TRUE, score_shown = TRUE, Xp_was_HD = FALSE; @@ -1577,9 +1605,13 @@ update_val(struct X_status_value *attr_rec, long new_value) Strcpy((char *) attr_rec->name, buf); XtSetArg(args[0], XtNlabel, buf); XtSetValues(attr_rec->w, args, ONE); + X11_update_label(attr_rec->w); } else if (attr_rec->type == SV_NAME) { - if (attr_rec->last_value == new_value) + boolean direct = attr_rec == &shown_stats[F_ARMOR] + || attr_rec == &shown_stats[F_WEAPON] + || attr_rec == &shown_stats[F_TERRAIN]; + if (!direct && attr_rec->last_value == new_value) return; /* no change */ attr_rec->last_value = new_value; @@ -1592,12 +1624,19 @@ update_val(struct X_status_value *attr_rec, long new_value) Strcpy(buf, enc_stat[new_value]); } else if (new_value) { Strcpy(buf, attr_rec->name); /* condition name On */ + /* Special cases: weapon, armor and terrain */ + } else if (direct) { + if (new_valuestr == NULL) { + return; + } + Strcpy(buf, new_valuestr); } else { *buf = '\0'; /* condition name Off */ } XtSetArg(args[0], XtNlabel, buf); XtSetValues(attr_rec->w, args, ONE); + X11_update_label(attr_rec->w); } else { /* a value pair */ boolean force_update = FALSE; @@ -1663,7 +1702,7 @@ update_val(struct X_status_value *attr_rec, long new_value) /* core won't call status_update() for Exp when it hasn't changed so do so ourselves (to get Exp_shown flag to match display) */ if (force_update) - update_fancy_status_field(F_EXP_PTS, NO_COLOR, HL_UNDEF); + update_fancy_status_field(F_EXP_PTS, NULL, NO_COLOR, HL_UNDEF); } if (attr_rec->last_value == new_value && !force_update) /* same */ @@ -1714,7 +1753,7 @@ update_val(struct X_status_value *attr_rec, long new_value) * it's being set to blank (where that item should be reset now instead * of showing highlighted blank until the next expiration check). * - * 3.7: highlight non-labelled 'name' items (conditions plus hunger + * 5.0: highlight non-labelled 'name' items (conditions plus hunger * and encumbrance) when they come On. For all conditions going Off, * or changing to not-hungry or not-encumbered, there's nothing to * highlight because the field becomes blank. @@ -1724,21 +1763,20 @@ update_val(struct X_status_value *attr_rec, long new_value) already highlighted and being set to blank */ if (attr_rec != &shown_stats[F_TIME] && attr_rec != &shown_stats[F_VERS] + && attr_rec != &shown_stats[F_TERRAIN] && !attr_rec->set ^ !*buf) { - /* But don't hilite if inverted from status_hilite since - it will already be hilited by apply_hilite_attributes(). */ - if (!attr_rec->inverted_hilite) { - if (attr_rec->type == SV_VALUE) - hilight_value(attr_rec->w); - else - hilight_label(attr_rec->w); - } + if (attr_rec->type == SV_VALUE) + X11_set_highlight(get_value_widget(attr_rec->w), TRUE); + else + X11_set_highlight(attr_rec->w, TRUE); attr_rec->set = !attr_rec->set; } attr_rec->turn_count = 0; } else { + Widget w = (attr_rec->type == SV_LABEL || attr_rec->type == SV_NAME) ? attr_rec->w + : get_value_widget(attr_rec->w); XtSetArg(args[0], XtNforeground, &attr_rec->default_fg); - XtGetValues(attr_rec->w, args, ONE); + XtGetValues(w, args, ONE); attr_rec->after_init = TRUE; } } @@ -1756,7 +1794,7 @@ skip_cond_val(struct X_status_value *sv) also requested to be highlighted, it used its own copy of 'set' but the same widget so the highlighting got toggled off; this will turn in back on in that exceptional case */ - hilight_label(sv->w); + X11_set_highlight(sv->w, FALSE); sv->set = FALSE; } } @@ -1766,8 +1804,6 @@ update_color(struct X_status_value *sv, int color) { Pixel pixel = 0; Arg args[1]; - XrmValue source; - XrmValue dest; Widget w = (sv->type == SV_LABEL || sv->type == SV_NAME) ? sv->w : get_value_widget(sv->w); @@ -1776,54 +1812,55 @@ update_color(struct X_status_value *sv, int color) pixel = sv->default_fg; sv->colr = NO_COLOR; } else { + pixel = color_to_pixel(w, color); + sv->colr = color; + } + if (pixel != 0) { + XtSetArg(args[0], XtNforeground, pixel); + XtSetValues(w, args, ONE); + X11_update_label(w); + } +} + +static Pixel +color_to_pixel(Widget w, int color) +{ + Pixel pixel; + + if (fancy_status_hilite_colors[color][0] != '\0') { + XrmValue source; + XrmValue dest; source.addr = (XPointer) fancy_status_hilite_colors[color]; source.size = (unsigned int) strlen((const char *) source.addr) + 1; dest.size = (unsigned int) sizeof (Pixel); dest.addr = (XPointer) &pixel; - if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) - sv->colr = color; + if (XtConvertAndStore(w, XtRString, &source, XtRPixel, &dest)) { + return pixel; + } } - if (pixel != 0) { - char *arg_name = (sv->set || sv->inverted_hilite) ? XtNbackground - : XtNforeground; - XtSetArg(args[0], arg_name, pixel); - XtSetValues(w, args, ONE); - } -} - -static boolean -name_widget_has_label(struct X_status_value *sv) -{ + pixel = 0xFFFFFF; Arg args[1]; - const char *label; - - XtSetArg(args[0], XtNlabel, &label); - XtGetValues(sv->w, args, ONE); - return (*label != '\0'); + XtSetArg(args[0], XtNforeground, &pixel); + XtGetValues(toplevel, args, ONE); + return pixel; } static void apply_hilite_attributes(struct X_status_value *sv, int attributes) { - boolean attr_inversion = ((HL_INVERSE & attributes) - && (sv->type != SV_NAME - || name_widget_has_label(sv))); - - if (sv->inverted_hilite != attr_inversion) { - sv->inverted_hilite = attr_inversion; - if (!sv->set) { - if (sv->type == SV_VALUE) - hilight_value(sv->w); - else - hilight_label(sv->w); - } + Widget w = sv->w; + if (sv->type == SV_VALUE) { + w = get_value_widget(w); } - sv->attr = attributes; - /* Could possibly add more attributes here: HL_ATTCLR_DIM, - HL_ATTCLR_BLINK, HL_ATTCLR_ULINE, and HL_ATTCLR_BOLD. If so, - extract the above into its own function apply_hilite_inverse() - and each other attribute into its own to keep the code clean. */ + X11_set_attrs(w, attributes); +} + +static void +set_percent(int index, int percent, int color) +{ + Widget w = shown_stats[index].w; + X11_set_percent(w, percent, color_to_pixel(w, color)); } /* @@ -1845,7 +1882,7 @@ apply_hilite_attributes(struct X_status_value *sv, int attributes) * [***] version is optional, right-justified after conditions */ static void -update_fancy_status_field(int i, int color, int attributes) +update_fancy_status_field(int i, const char *valstr, int color, int attributes) { struct X_status_value *sv = &shown_stats[i]; unsigned long condmask = 0L; @@ -1945,6 +1982,39 @@ update_fancy_status_field(int i, int color, int attributes) case F_HALLU: condmask = BL_MASK_HALLU; break; + case F_BAREH: + condmask = BL_MASK_BAREH; + break; + case F_GLOWHANDS: + condmask = BL_MASK_GLOWHANDS; + break; + case F_ICY: + condmask = BL_MASK_ICY; + break; + case F_BUSY: + condmask = BL_MASK_BUSY; + break; + case F_PARALYZED: + condmask = BL_MASK_PARLYZ; + break; + case F_SLEEPING: + condmask = BL_MASK_SLEEPING; + break; + case F_UNCONSCIOUS: + condmask = BL_MASK_UNCONSC; + break; + case F_IRON: + condmask = BL_MASK_ELF_IRON; + break; + case F_SLIPPERY: + condmask = BL_MASK_SLIPPERY; + break; + case F_SUBMERGED: + condmask = BL_MASK_SUBMERGED; + break; + case F_WOUNDEDL: + condmask = BL_MASK_WOUNDEDL; + break; /* pseudo-condition */ case F_VERS: @@ -1996,6 +2066,11 @@ update_fancy_status_field(int i, int color, int attributes) val = 0L; #endif break; + case F_WEAPON: + case F_ARMOR: + case F_TERRAIN: + /* valstr is the value */ + break; default: { /* * There is a possible infinite loop that occurs with: @@ -2029,7 +2104,7 @@ update_fancy_status_field(int i, int color, int attributes) return; } } - update_val(sv, val); + update_val(sv, val, valstr); if (color != sv->colr) update_color(sv, color); if (attributes != sv->attr) @@ -2057,7 +2132,7 @@ update_fancy_status(boolean force_update) the no longer displayed field; we're a bit more conservative than that and do this when toggling on as well as off */ for (i = 0; i < NUM_STATS; i++) - update_fancy_status_field(i, NO_COLOR, HL_UNDEF); + update_fancy_status_field(i, NULL, NO_COLOR, HL_UNDEF); old_condition_bits = X11_condition_bits; old_upolyd = Upolyd; @@ -2087,14 +2162,10 @@ check_turn_events(void) continue; if (sv->turn_count++ >= hilight_time) { - /* unhighlights by toggling a highlighted item back off again, - unless forced inverted by a status_hilite rule */ - if (!sv->inverted_hilite) { - if (sv->type == SV_VALUE) - hilight_value(sv->w); - else - hilight_label(sv->w); - } + if (sv->type == SV_VALUE) + X11_set_highlight(get_value_widget(sv->w), FALSE); + else + X11_set_highlight(sv->w, FALSE); sv->set = FALSE; } } @@ -2143,6 +2214,17 @@ width_string(int sv_index) case F_STUN: case F_CONF: case F_HALLU: + case F_BAREH: + case F_GLOWHANDS: + case F_BUSY: + case F_PARALYZED: + case F_SLEEPING: + case F_UNCONSCIOUS: + case F_IRON: + case F_SLIPPERY: + case F_SUBMERGED: + case F_WOUNDEDL: + case F_ICY: return shown_stats[sv_index].name; case F_NAME: @@ -2168,6 +2250,12 @@ width_string(int sv_index) return "123456789"; /* a tenth digit will still fit legibly */ case F_ALIGN: return "Neutral"; + case F_WEAPON: + return "Dual+joust"; + case F_ARMOR: + return "GCAUHBS"; + case F_TERRAIN: + return "Portcullis"; } impossible("width_string: unknown index %d\n", sv_index); return ""; @@ -2198,6 +2286,7 @@ create_widget(Widget parent, struct X_status_value *sv, int sv_index) : "dlevel", labelWidgetClass, parent, args, num_args); + X11_wrap_widget(sv->w, NHW_STATUS); break; case SV_NAME: { char buf[BUFSZ]; @@ -2234,6 +2323,7 @@ create_widget(Widget parent, struct X_status_value *sv, int sv_index) XtSetArg(args[num_args], XtNinternalHeight, 0); num_args++; sv->w = XtCreateManagedWidget(sv->name, labelWidgetClass, parent, args, num_args); + X11_wrap_widget(sv->w, NHW_STATUS); break; } default: @@ -2348,7 +2438,7 @@ init_column( * indicates the end of the column. The two numbers after that are used * to store widths that are calculated at run-time. * - * 3.7: changed so that all 6 columns have 8 rows, but a few entries + * 5.0: changed so that all 6 columns have 8 rows, but a few entries * are left blank <>. Exp-points, Score, and Time are optional depending * on run-time settings; Xp-level is replaced by Hit-Dice (and Exp-points * suppressed) when the hero is polymorphed. Title and Dungeon-Level span @@ -2356,41 +2446,53 @@ init_column( * Version is optional, right justified, and much wider than the others. * Title ("Plname the Rank") <> <> <> <> - Dungeon-Branch-and-Level <> Hunger Grabbed Held - Hit-points Max-HP Strength Encumbrance Petrifying Blind - Power-points Max-Power Dexterity Trapped Slimed Deaf - Armor-class Alignment Constitution Levitation Strangled Stunned - Xp-level [Exp-points] Intelligence Flying Food-Pois Confused - Gold [Score] Wisdom Riding Term-Ill Hallucinat - <> [Time] Charisma <> Sinking Version + Dungeon-Branch-and-Level <> <> <> <> + Hit-points Max-HP Strength Hunger Grabbed Held + Power-points Max-Power Dexterity Encumbrance Petrifying Blind + Armor-class Alignment Constitution Trapped Slimed Deaf + Xp-level [Exp-points] Intelligence Levitation Strangled Stunned + Gold [Score] Wisdom Flying Food-Pois Confused + <> [Time] Charisma Riding Term-Ill Hallucinat + BareHands <> <> HurtLegs Sinking GlowHands + Weapon Armor Terrain Elf-Iron Busy Icy + <> <> <> Slippery Submerged Version * * A seventh column is going to be needed to fit in more conditions. */ -/* including F_DUMMY makes the three status condition columns evenly +/* including F_DUMMY makes the status condition columns evenly spaced with regard to the adjacent characteristics (Str,Dex,&c) column; we lose track of the Widget pointer for F_DUMMY, each use clobbering the one before, leaving the one from leftover_indices[]; since they're never updated, that shouldn't matter */ -static int status_indices[3][11] = { +static int status_indices[][13] = { { F_DUMMY, F_HUNGER, F_ENCUMBER, F_TRAPPED, - F_LEV, F_FLY, F_RIDE, F_DUMMY, -1, 0, 0 }, + F_LEV, F_FLY, F_RIDE, F_WOUNDEDL, F_IRON, F_SLIPPERY, + -1, 0, 0 }, { F_DUMMY, F_GRABBED, F_STONE, F_SLIME, F_STRNGL, - F_FOODPOIS, F_TERMILL, F_IN_LAVA, -1, 0, 0 }, + F_FOODPOIS, F_TERMILL, F_IN_LAVA, F_BUSY, F_SUBMERGED, + -1, 0, 0 }, { F_DUMMY, F_HELD, F_BLIND, F_DEAF, F_STUN, - F_CONF, F_HALLU, F_VERS, -1, 0, 0 }, + F_CONF, F_HALLU, F_GLOWHANDS, F_ICY, F_VERS, + -1, 0, 0 }, }; -/* used to fill up the empty space to right of 3rd status condition column */ +/* used to fill up the empty space to right of last status condition column */ static int leftover_indices[] = { F_DUMMY, -1, 0, 0 }; /* -2: top two rows of these columns are reserved for title and location */ -static int col1_indices[11 - 2] = { - F_HP, F_POWER, F_AC, F_XP_LEVL, F_GOLD, F_DUMMY, -1, 0, 0 +static int col1_indices[13 - 2] = { + F_HP, F_POWER, F_AC, F_XP_LEVL, F_GOLD, F_DUMMY, + F_BAREH, F_WEAPON, F_DUMMY, + -1 }; -static int col2_indices[11 - 2] = { - F_MAXHP, F_MAXPOWER, F_ALIGN, F_EXP_PTS, F_SCORE, F_TIME, -1, 0, 0 +static int col2_indices[13 - 2] = { + F_MAXHP, F_MAXPOWER, F_ALIGN, F_EXP_PTS, F_SCORE, F_TIME, + F_DUMMY, F_ARMOR, F_DUMMY, + -1 }; -static int characteristics_indices[11 - 2] = { - F_STR, F_DEX, F_CON, F_INT, F_WIS, F_CHA, -1, 0, 0 +static int characteristics_indices[13 - 2] = { + F_STR, F_DEX, F_CON, F_INT, F_WIS, F_CHA, + F_DUMMY, F_TERRAIN, F_DUMMY, + -1 }; /* @@ -2398,10 +2500,10 @@ static int characteristics_indices[11 - 2] = { * * title * location - * col1_indices[0] col2_indices[0] col3_indices[0] - * col1_indices[1] col2_indices[1] col3_indices[1] - * ... ... ... - * col1_indices[5] col2_indices[5] col3_indices[5] + * col1_indices[0] col2_indices[0] col3_indices[0] col4_indices[0] + * col1_indices[1] col2_indices[1] col3_indices[1] col4_indices[1] + * ... ... ... ... + * col1_indices[5] col2_indices[5] col3_indices[5] col4_indices[5] * * The status conditions are managed separately and appear to the right * of this form. @@ -2440,7 +2542,7 @@ init_info_form(Widget parent, Widget top, Widget left) XtSetArg(args[num_args], nhStr(XtNfromVert), sv_name->w); num_args++; XtSetValues(sv_dlevel->w, args, num_args); - /* there are 3 columns beneath but top 2 rows are centered over first 2 */ + /* there are 4 columns beneath but top 2 rows are centered over first 2 */ col1 = init_column("name_col1", form, sv_dlevel->w, (Widget) 0, col1_indices, 0); col2 = init_column("name_col2", form, sv_dlevel->w, col1, @@ -2466,7 +2568,7 @@ init_info_form(Widget parent, Widget top, Widget left) return form; } -/* give the three status condition columns the same width */ +/* give the status condition columns the same width */ static void fixup_cond_widths(void) { @@ -2474,7 +2576,7 @@ fixup_cond_widths(void) w1 = w2 = 0; for (pass = 1; pass <= 2; ++pass) { /* two passes... */ - for (i = 0; i < 3; i++) { /* three columns */ + for (i = 0; i < SIZE(status_indices); i++) { for (ip = status_indices[i]; *ip != -1; ++ip) { /* X fields */ /* pass 1: find -1; pass 2: update field widths, find -1 */ if (pass == 2) @@ -2504,7 +2606,7 @@ fixup_cond_widths(void) Dimension vers_width = 0; struct X_status_value *sv = &shown_stats[F_VERS]; - if (sv) { + if (sv->w) { XtSetArg(args[0], XtNwidth, &vers_width); XtGetValues(sv->w, args, ONE); if (vers_width) { @@ -2547,15 +2649,15 @@ create_fancy_status(Widget parent, Widget top) w = init_column("status_characteristics", form, (Widget) 0, w, characteristics_indices, 15); #endif - for (i = 0; i < 3; i++) { + for (i = 0; i < SIZE(status_indices); i++) { Sprintf(buf, "status_condition%d", i + 1); w = init_column(buf, form, (Widget) 0, w, status_indices[i], 0); } - fixup_cond_widths(); /* make all 3 status_conditionN columns same width + fixup_cond_widths(); /* make all status_conditionN columns same width * (actually, the slot for F_VERS is much wider) */ /* TODO: * Calculate and set the width of the F_VERS widjet to be from the - * start of the third condition column through the right edge and + * start of the last condition column through the right edge and * get rid of the dummy column. */ diff --git a/win/X11/wintext.c b/win/X11/wintext.c index e401b7018..a80b6540d 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintext.c $NHDT-Date: 1597967808 2020/08/20 23:56:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 5.0 wintext.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.35 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include @@ -43,17 +44,23 @@ */ static const char text_translations[] = "#override\n\ - : dismiss_text()\n\ + : dismiss_text()\n\ + : scroll(8)\n\ + : scroll(2)\n\ : key_dismiss_text()"; #ifdef GRAPHIC_TOMBSTONE static const char rip_translations[] = "#override\n\ - : rip_dismiss_text()\n\ + : rip_dismiss_text()\n\ + : scroll(8)\n\ + : scroll(2)\n\ : rip_dismiss_text()"; static Widget create_ripout_widget(Widget); #endif +static void free_text_buffer(struct text_buffer *); + /*ARGSUSED*/ void delete_text(Widget w, XEvent *event, String *params, Cardinal *num_params) @@ -129,16 +136,10 @@ add_to_text_window(struct xwindow *wp, int attr, /* currently unused */ const char *str) { struct text_info_t *text_info = wp->text_information; - int width; nhUse(attr); append_text_buffer(&text_info->text, str, FALSE); - - /* Calculate text width and save longest line */ - width = XTextWidth(text_info->fs, str, (int) strlen(str)); - if (width > text_info->max_width) - text_info->max_width = width; } void @@ -147,42 +148,13 @@ display_text_window(struct xwindow *wp, boolean blocking) struct text_info_t *text_info; Arg args[8]; Cardinal num_args; - Dimension width, height, font_height; - int nlines; text_info = wp->text_information; - width = text_info->max_width + text_info->extra_width; text_info->blocked = blocking; text_info->destroy_on_ack = FALSE; - font_height = nhFontHeight(wp->w); - - /* - * Calculate the number of lines to use. First, find the number of - * lines that would fit on the screen. Next, remove four of these - * lines to give room for a possible window manager titlebar (some - * wm's put a titlebar on transient windows). Make sure we have - * _some_ lines. Finally, use the number of lines in the text if - * there are fewer than the max. - */ - nlines = (XtScreen(wp->w)->height - text_info->extra_height) / font_height; - nlines -= 4; - - if (nlines > text_info->text.num_lines) - nlines = text_info->text.num_lines; - if (nlines <= 0) - nlines = 1; - - height = nlines * font_height + text_info->extra_height; num_args = 0; - if (nlines < text_info->text.num_lines) { - /* add on width of scrollbar. Really should look this up, - * but can't until the window is realized. Chicken-and-egg problem. - */ - width += 20; - } - #ifdef GRAPHIC_TOMBSTONE if (text_info->is_rip) { Widget rip = create_ripout_widget(XtParent(wp->w)); @@ -195,18 +167,10 @@ display_text_window(struct xwindow *wp, boolean blocking) } #endif - if (width > (Dimension) XtScreen(wp->w)->width) { /* too wide for screen */ - /* Back off some amount - we really need to back off the scrollbar */ - /* width plus some extra. */ - width = XtScreen(wp->w)->width - 20; - } - XtSetArg(args[num_args], XtNstring, text_info->text.text); - num_args++; - XtSetArg(args[num_args], XtNwidth, width); - num_args++; - XtSetArg(args[num_args], XtNheight, height); + XtSetArg(args[num_args], XtNlabel, text_info->text.text); num_args++; XtSetValues(wp->w, args, num_args); + X11_update_label(wp->w); #ifdef TRANSIENT_TEXT XtRealizeWidget(wp->popup); @@ -217,22 +181,6 @@ display_text_window(struct xwindow *wp, boolean blocking) nh_XtPopup(wp->popup, (int) XtGrabNone, wp->w); - /* Kludge alert. Scrollbars are not sized correctly by the Text widget */ - /* if added before the window is displayed, so do it afterward. */ - num_args = 0; - if (nlines < text_info->text.num_lines) { /* add vert scrollbar */ - XtSetArg(args[num_args], nhStr(XtNscrollVertical), - XawtextScrollAlways); - num_args++; - } - if (width >= (Dimension)(XtScreen(wp->w)->width - 20)) { /* too wide */ - XtSetArg(args[num_args], nhStr(XtNscrollHorizontal), - XawtextScrollAlways); - num_args++; - } - if (num_args) - XtSetValues(wp->w, args, num_args); - /* We want the user to acknowledge. */ if (blocking) { (void) x_event(EXIT_ON_EXIT); @@ -246,7 +194,6 @@ create_text_window(struct xwindow *wp) struct text_info_t *text_info; Arg args[8]; Cardinal num_args; - Position top_margin, bottom_margin, left_margin, right_margin; Widget form; wp->type = NHW_TEXT; @@ -255,9 +202,6 @@ create_text_window(struct xwindow *wp) (struct text_info_t *) alloc(sizeof(struct text_info_t)); init_text_buffer(&text_info->text); - text_info->max_width = 0; - text_info->extra_width = 0; - text_info->extra_height = 0; text_info->blocked = FALSE; text_info->destroy_on_ack = TRUE; /* Ok to destroy before display */ #ifdef GRAPHIC_TOMBSTONE @@ -280,46 +224,42 @@ create_text_window(struct xwindow *wp) wp->popup, XtParseTranslationTable("WM_PROTOCOLS: delete_text()")); + /* Create the viewport */ + num_args = 0; + XtSetArg(args[num_args], XtNallowVert, True); + num_args++; + XtSetArg(args[num_args], XtNallowHoriz, True); + num_args++; + XtSetArg(args[num_args], XtNtranslations, + XtParseTranslationTable(text_translations)), num_args++; + Widget viewport = XtCreateManagedWidget( + "text_viewport", /* name */ + viewportWidgetClass, /* widget class from Window.h */ + wp->popup, /* parent widget */ + args, /* set some values */ + num_args); /* number of values to set */ + num_args = 0; XtSetArg(args[num_args], XtNallowShellResize, True), num_args++; XtSetArg(args[num_args], XtNtranslations, XtParseTranslationTable(text_translations)), num_args++; - form = XtCreateManagedWidget("form", formWidgetClass, wp->popup, args, + form = XtCreateManagedWidget("form", formWidgetClass, viewport, args, num_args); num_args = 0; - XtSetArg(args[num_args], nhStr(XtNdisplayCaret), False); - num_args++; - XtSetArg(args[num_args], XtNresize, XawtextResizeBoth); - num_args++; XtSetArg(args[num_args], XtNtranslations, XtParseTranslationTable(text_translations)); num_args++; + XtSetArg(args[num_args], XtNjustify, XtJustifyLeft); num_args++; wp->w = XtCreateManagedWidget(svk.killer.name[0] && WIN_MAP == WIN_ERR ? "tombstone" : "text_text", /* name */ - asciiTextWidgetClass, + labelWidgetClass, form, /* parent widget */ args, /* set some values */ num_args); /* number of values to set */ - - /* Get the font and margin information. */ - num_args = 0; - XtSetArg(args[num_args], XtNfont, &text_info->fs); - num_args++; - XtSetArg(args[num_args], nhStr(XtNtopMargin), &top_margin); - num_args++; - XtSetArg(args[num_args], nhStr(XtNbottomMargin), &bottom_margin); - num_args++; - XtSetArg(args[num_args], nhStr(XtNleftMargin), &left_margin); - num_args++; - XtSetArg(args[num_args], nhStr(XtNrightMargin), &right_margin); - num_args++; - XtGetValues(wp->w, args, num_args); - - text_info->extra_width = left_margin + right_margin; - text_info->extra_height = top_margin + bottom_margin; + X11_wrap_widget(wp->w, NHW_TEXT); } void @@ -432,7 +372,7 @@ clear_text_buffer(struct text_buffer *tb) } /* Free up allocated memory. */ -void +static void free_text_buffer(struct text_buffer *tb) { free(tb->text); @@ -537,12 +477,16 @@ rip_exposed(Widget w, XtPointer client_data UNUSED, XDestroyImage(rip_image); /* data bytes free'd also */ } - mask = GCFunction | GCForeground | GCGraphicsExposures | GCFont; values.graphics_exposures = False; XtSetArg(args[0], XtNforeground, &values.foreground); XtGetValues(w, args, 1); values.function = GXcopy; +#ifdef USE_XFT + mask = GCFunction | GCForeground | GCGraphicsExposures; +#else + mask = GCFunction | GCForeground | GCGraphicsExposures | GCFont; values.font = WindowFont(w); +#endif ggc = XtGetGC(w, mask, &values); if (rip_pixmap != None) { @@ -552,6 +496,33 @@ rip_exposed(Widget w, XtPointer client_data UNUSED, x = appResources.tombtext_x; y = appResources.tombtext_y; +#ifdef USE_XFT + Display *display = XtDisplay(w); + Screen *screen = DefaultScreenOfDisplay(display); + Visual *visual = DefaultVisualOfScreen(screen); + Colormap cmap = DefaultColormapOfScreen(screen); + XftDraw *draw = XftDrawCreate(display, XtWindow(w), visual, cmap); + XftFont *font = XftFontOpenName(display, DefaultScreen(display), + appResources.font_rip); + XftColor foreground; + X11_new_color(w, values.foreground, &foreground); + for (i = 0; i <= YEAR_LINE; i++) { + size_t len = strlen(rip_line[i]); + XGlyphInfo extents; + XftTextExtents8(display, font, + (const FcChar8 *) rip_line[i], len, + &extents); + int width = extents.width - extents.x; + + XftDrawString8(draw, &foreground, font, x - width / 2, y, + (const FcChar8 *) rip_line[i], len); + x += appResources.tombtext_dx; + y += appResources.tombtext_dy; + } + XftFontClose(display, font); + XftDrawDestroy(draw); + XftColorFree(display, visual, cmap, &foreground); +#else /* !USE_XFT */ for (i = 0; i <= YEAR_LINE; i++) { int len = strlen(rip_line[i]); XFontStruct *font = WindowFontStruct(w); @@ -561,6 +532,7 @@ rip_exposed(Widget w, XtPointer client_data UNUSED, x += appResources.tombtext_dx; y += appResources.tombtext_dy; } +#endif /* ?USE_XFT */ XtReleaseGC(w, ggc); } diff --git a/win/X11/winval.c b/win/X11/winval.c index 651ba2cbb..65bdeb312 100644 --- a/win/X11/winval.c +++ b/win/X11/winval.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winval.c $NHDT-Date: 1611697183 2021/01/26 21:39:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 winval.c $NHDT-Date: 1781973110 2026/06/20 16:31:50 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -57,6 +57,7 @@ create_value(Widget parent, const char *name_value) num_args++; name = XtCreateManagedWidget(WNAME, labelWidgetClass, form, args, num_args); + X11_wrap_widget(name, NHW_STATUS); num_args = 0; XtSetArg(args[num_args], XtNjustify, XtJustifyRight); @@ -67,8 +68,9 @@ create_value(Widget parent, const char *name_value) num_args++; XtSetArg(args[num_args], XtNinternalHeight, 0); num_args++; - (void) XtCreateManagedWidget(WVALUE, labelWidgetClass, form, args, - num_args); + Widget value = XtCreateManagedWidget(WVALUE, labelWidgetClass, form, args, + num_args); + X11_wrap_widget(value, NHW_STATUS); return form; } @@ -81,6 +83,7 @@ set_name(Widget w, const char *new_label) name = XtNameToWidget(w, WNAME); XtSetArg(args[0], XtNlabel, new_label); XtSetValues(name, args, ONE); + X11_update_label(name); } void @@ -122,6 +125,7 @@ set_value(Widget w, const char *new_value) val = get_value_widget(w); XtSetArg(args[0], XtNlabel, new_value); XtSetValues(val, args, ONE); + X11_update_label(val); } void @@ -148,14 +152,6 @@ get_value_width(Widget w) return (int) width; } -/* Swap foreground and background colors (this is the best I can do with */ -/* a label widget, unless I can get some init hook in there). */ -void -hilight_value(Widget w) -{ - swap_fg_bg(get_value_widget(w)); -} - /* Swap the foreground and background colors of the given widget */ void swap_fg_bg(Widget w) @@ -170,4 +166,5 @@ swap_fg_bg(Widget w) XtSetArg(args[0], XtNforeground, bg); XtSetArg(args[1], XtNbackground, fg); XtSetValues(w, args, TWO); + X11_update_label(w); } diff --git a/win/chain/wc_chainin.c b/win/chain/wc_chainin.c index ab63cf3c7..7b83ffd17 100644 --- a/win/chain/wc_chainin.c +++ b/win/chain/wc_chainin.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wc_chainin.c $NHDT-Date: 1596498323 2020/08/03 23:45:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 wc_chainin.c $NHDT-Date: 1781973093 2026/06/20 16:31:33 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.28 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/chain/wc_chainout.c b/win/chain/wc_chainout.c index 72459b883..a1d4d511c 100644 --- a/win/chain/wc_chainout.c +++ b/win/chain/wc_chainout.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wc_chainout.c $NHDT-Date: 1596498324 2020/08/03 23:45:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 wc_chainout.c $NHDT-Date: 1781973094 2026/06/20 16:31:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.29 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/chain/wc_trace.c b/win/chain/wc_trace.c index 7287e82a4..fffbc3961 100644 --- a/win/chain/wc_trace.c +++ b/win/chain/wc_trace.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wc_trace.c $NHDT-Date: 1596498324 2020/08/03 23:45:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 wc_trace.c $NHDT-Date: 1781973094 2026/06/20 16:31:34 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.29 $ */ /* Copyright (c) Kenneth Lorber, 2012 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/Readme.txt b/win/curses/Readme.txt index a9ae0be7b..1cec52e6e 100644 --- a/win/curses/Readme.txt +++ b/win/curses/Readme.txt @@ -29,7 +29,7 @@ sys/unix/Install.unx. By default, the Makefile is setup to compile against ncurses. Edit Makefile.src if you wish to compile against a different curses library, such as PDCurses for SDL. See sys/unix/NewInstall.unx for more information about building -NetHack 3.7 and above. +NetHack 5.0 and above. Windows build instructions: diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index b6a51eb2a..e2bb44066 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursdial.c */ +/* NetHack 5.0 cursdial.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ @@ -205,10 +205,8 @@ curses_line_input_dialog( /* Get a single character response from the player, such as a y/n prompt */ int -curses_character_input_dialog( - const char *prompt, - const char *choices, - char def) +curses_character_input_dialog(const char *prompt, const char *choices, + char def) { WINDOW *askwin = NULL; #ifdef PDCURSES @@ -222,12 +220,15 @@ curses_character_input_dialog( int prompt_height = 1; boolean any_choice = FALSE; boolean accept_count = FALSE; +#ifdef PDCURSES + int x, y; +#endif /* if messages were being suppressed for the remainder of the turn, re-activate them now that input is being requested */ curses_got_input(); - if (svm.moves > 0) { + if (svm.moves > 0 || !program_state.beyond_savefile_load) { curses_get_window_size(MAP_WIN, &map_height, &map_width); } else { map_height = term_rows; @@ -260,10 +261,10 @@ curses_character_input_dialog( choicestr[count + 5] = def; choicestr[count + 6] = ')'; choicestr[count + 7] = '\0'; - } else { /* No usable default choice */ + } else { /* No usable default choice */ choicestr[count + 3] = '\0'; - def = '\0'; /* Mark as no default */ + def = '\0'; /* Mark as no default */ } strcpy(askstr, prompt); strcat(askstr, choicestr); @@ -281,7 +282,8 @@ curses_character_input_dialog( } if (iflags.wc_popup_dialog /*|| curses_stupid_hack*/) { - askwin = curses_create_window(TEXT_WIN, prompt_width, prompt_height, UP); + askwin = + curses_create_window(TEXT_WIN, prompt_width, prompt_height, UP); activemenu = askwin; for (count = 0; count < prompt_height; count++) { @@ -291,6 +293,11 @@ curses_character_input_dialog( } curses_set_wid_colors(TEXT_WIN, askwin); +#ifdef PDCURSES + getyx(askwin, y, x); + wmove(askwin, y, x); + curs_set(1); +#endif wrefresh(askwin); } else { /* TODO: add SUPPRESS_HISTORY flag, then after getting a response, @@ -299,11 +306,15 @@ curses_character_input_dialog( } /*curses_stupid_hack = 0; */ - +#ifndef PDCURSES curs_set(1); +#endif while (1) { #ifdef PDCURSES - answer = wgetch(message_window); + if (WIN_MESSAGE != WIN_ERR) + answer = wgetch(message_window); + else + answer = wgetch(askwin); #else answer = curses_read_char(); #endif @@ -321,7 +332,7 @@ curses_character_input_dialog( } answer = def; for (count = 0; choices[count] != '\0'; count++) { - if (choices[count] == 'q') { /* q is preferred over n */ + if (choices[count] == 'q') { /* q is preferred over n */ answer = 'q'; } else if ((choices[count] == 'n') && answer != 'q') { answer = 'n'; diff --git a/win/curses/cursdial.h b/win/curses/cursdial.h index 167ec793e..de3d512fa 100644 --- a/win/curses/cursdial.h +++ b/win/curses/cursdial.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursdial.h */ +/* NetHack 5.0 cursdial.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursinit.c b/win/curses/cursinit.c index 529b46182..523ae92d3 100644 --- a/win/curses/cursinit.c +++ b/win/curses/cursinit.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursinit.c */ +/* NetHack 5.0 cursinit.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ @@ -7,6 +7,7 @@ #include "hack.h" #include "wincurs.h" #include "cursinit.h" +#include "cursmisc.h" /* Initialization and startup functions for curses interface */ @@ -334,18 +335,18 @@ curses_init_nhcolors(void) /* COLOR_foo + 8 means COLOR | A_BOLD when COLORS < 16 */ /* otherwise assume the terminal has least 16 different colors */ /* these map to the NetHack CLR_ defines */ - static const int fg_clr[16] = { + static const int basic_fg_clr[16] = { COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE, -1, COLOR_RED + 8, COLOR_GREEN + 8, COLOR_YELLOW + 8, COLOR_BLUE + 8, COLOR_MAGENTA + 8, COLOR_CYAN + 8, COLOR_WHITE + 8 }; - static const int bg_clr[8] = { + static const int bg_clr[CURSES_NUM_BACKGROUND_COLORS] = { -1, COLOR_RED, COLOR_GREEN, COLOR_YELLOW, COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE }; int bg, nhclr; - int maxc = (COLORS >= 16) ? 16 : 8; + int maxc = curses_has_256color() ? 256 : (COLORS >= 16) ? 16 : 8; if (!has_colors()) return; @@ -353,8 +354,9 @@ curses_init_nhcolors(void) use_default_colors(); for (nhclr = CLR_BLACK; nhclr < maxc; nhclr++) { - for (bg = 0; bg < 8; bg++) { - init_pair((maxc * bg) + nhclr + 1, fg_clr[nhclr], bg_clr[bg]); + for (bg = 0; bg < CURSES_NUM_BACKGROUND_COLORS; bg++) { + int fg_color = (nhclr < 16) ? basic_fg_clr[nhclr] : nhclr; + init_pair((maxc * bg) + nhclr + 1, fg_color, bg_clr[bg]); } } @@ -744,6 +746,12 @@ curses_character_dialog(const char **choices, const char *prompt) void curses_init_options(void) { +#ifdef PDCURSES + int display_height = 0, display_width = 0; +#if defined(WIN32) && !defined(WIN32CON) + int alt_display_height = 0, alt_display_width = 0; +#endif +#endif /* change these from set_gameview to set_in_game */ set_wc_option_mod_status(WC_ALIGN_MESSAGE | WC_ALIGN_STATUS, set_in_game); @@ -761,11 +769,18 @@ curses_init_options(void) terminal size programmatically. If the user does not specify a size in the config file, we will set it to a nice big 32x110 to take advantage of some of the nice features of this windowport. */ - if (iflags.wc2_term_cols == 0) - iflags.wc2_term_cols = 110; - if (iflags.wc2_term_rows == 0) - iflags.wc2_term_rows = 32; + getmaxyx(base_term, display_height, display_width); +#if defined(WIN32) && !defined(WIN32CON) + alt_display_width = get_approx_display_cols(); + alt_display_height = get_approx_display_rows(); + display_width = min(230, alt_display_width); + display_height = min(66, alt_display_height); +#endif + if (iflags.wc2_term_cols == 0) + iflags.wc2_term_cols = display_width; + if (iflags.wc2_term_rows == 0) + iflags.wc2_term_rows = display_height; resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols); getmaxyx(base_term, term_rows, term_cols); diff --git a/win/curses/cursinit.h b/win/curses/cursinit.h index fbc9abe08..f51f1a681 100644 --- a/win/curses/cursinit.h +++ b/win/curses/cursinit.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursinit.h */ +/* NetHack 5.0 cursinit.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursinvt.c b/win/curses/cursinvt.c index 1aadad9f9..3369b2d8c 100644 --- a/win/curses/cursinvt.c +++ b/win/curses/cursinvt.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursinvt.c */ +/* NetHack 5.0 cursinvt.c */ /* Copyright (c) Fredrik Ljungdahl, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursinvt.h b/win/curses/cursinvt.h index 569b1ccb6..e644c193d 100644 --- a/win/curses/cursinvt.h +++ b/win/curses/cursinvt.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursinvt.h */ +/* NetHack 5.0 cursinvt.h */ /* Copyright (c) Fredrik Ljungdahl, 2017. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 4d1923eda..f6b5e3013 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmain.c */ +/* NetHack 5.0 cursmain.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ @@ -7,6 +7,7 @@ #include "hack.h" #include "color.h" #include "wincurs.h" +#include "curswins.h" #ifdef CURSES_UNICODE #include #endif @@ -122,7 +123,7 @@ struct window_procs curses_procs = { curses_delay_output, #ifdef CHANGE_COLOR curses_change_color, -#ifdef MAC /* old OS 9, not OSX */ +#ifdef MAC68K /* old OS 9, not OSX */ (void (*)(int)) 0, (short (*)(winid, char *)) 0, #endif @@ -924,7 +925,7 @@ print_glyph(window, x, y, glyphinfo, bkglyphinfo) int ttychar; the character mapping for the original tty interface. Most or all window ports wanted and used this for various things so it is - provided in 3.7+ + provided in 5.0+ short int symidx; offset into syms array unsigned glyphflags; more detail about the entity @@ -939,15 +940,16 @@ curses_print_glyph( { int glyph; int ch; - int color; - int nhcolor = 0; + struct glyph_attributes attr; unsigned int special; - int attr = -1; + attr.attribute_flags = -1; glyph = glyphinfo->glyph; special = glyphinfo->gm.glyphflags; ch = glyphinfo->ttychar; - color = glyphinfo->gm.sym.color; + attr.basic_color = glyphinfo->gm.sym.color; + attr.color256 = 0; + attr.framecolor = bkglyphinfo->framecolor; /* Extra color handling * FIQ: The curses library does not support truecolor, only the more limited 256 * color mode. On top of this, the windowport only supports 16 color mode. @@ -956,19 +958,17 @@ curses_print_glyph( if (glyphinfo->gm.customcolor != 0 && (curses_procs.wincap2 & WC2_EXTRACOLORS) != 0) { if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) != 0) { - color = COLORVAL(glyphinfo->gm.customcolor); -#if 0 + attr.basic_color = COLORVAL(glyphinfo->gm.customcolor); } else { /* 24-bit color, NH_BASIC_COLOR == 0 */ - nhcolor = COLORVAL(glyphinfo->gm.customcolor); -#endif + attr.color256 = glyphinfo->gm.color256idx; } } if ((special & MG_PET) && iflags.hilite_pet) { - attr = curses_convert_attr(iflags.wc2_petattr); + attr.attribute_flags = curses_convert_attr(iflags.wc2_petattr); } if ((special & MG_DETECT) && iflags.use_inverse) { - attr = A_REVERSE; + attr.attribute_flags = A_REVERSE; } if (SYMHANDLING(H_DEC)) ch = curses_convert_glyph(ch, glyph); @@ -981,9 +981,9 @@ curses_print_glyph( */ if ((special & MG_OBJPILE) && iflags.hilite_pile) { if (iflags.wc_color) - color = get_framecolor(color, CLR_BLUE); + attr.framecolor = CLR_BLUE; else /* if (iflags.use_inverse) */ - attr = A_REVERSE; + attr.attribute_flags = A_REVERSE; } /* water and lava look the same except for color; when color is off (checked by core), render lava in inverse video so that it looks @@ -992,11 +992,11 @@ curses_print_glyph( if ((special & (MG_BW_LAVA | MG_BW_ICE | MG_BW_SINK | MG_BW_ENGR)) != 0 && iflags.use_inverse) { /* reset_glyphmap() only sets MG_BW_foo if color is off */ - attr = A_REVERSE; + attr.attribute_flags = A_REVERSE; } /* highlight female monsters (wizard mode option) */ if ((special & MG_FEMALE) && wizard && iflags.wizmgender) { - attr = A_REVERSE; + attr.attribute_flags = A_REVERSE; } } @@ -1004,10 +1004,9 @@ curses_print_glyph( #ifdef ENHANCED_SYMBOLS (SYMHANDLING(H_UTF8) && glyphinfo->gm.u && glyphinfo->gm.u->utf8str) - ? glyphinfo->gm.u : NULL, + ? glyphinfo->gm.u : NULL, #endif - (nhcolor != 0) ? nhcolor : color, - bkglyphinfo->framecolor, attr); + &attr); } diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index adc039f52..892369f63 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmesg.c */ +/* NetHack 5.0 cursmesg.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursmesg.h b/win/curses/cursmesg.h index 6653532db..897170b4f 100644 --- a/win/curses/cursmesg.h +++ b/win/curses/cursmesg.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmesg.h */ +/* NetHack 5.0 cursmesg.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 4b4fe97c1..30e782411 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmisc.c */ +/* NetHack 5.0 cursmisc.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ @@ -34,16 +34,40 @@ int curses_getch(void) { int ch; + boolean timeoutset = FALSE; - if (iflags.debug_fuzzer) + if (iflags.debug_fuzzer) { ch = randomkey(); - else + } else if (iflags.idlecheckpoint) { + boolean done_a_checkpoint = FALSE; + + timeout(IDLECHECKPOINT_WAIT_TIME * 1000); + timeoutset = TRUE; + + while (1) { + ch = getch(); + if (ch == ERR && !done_a_checkpoint) { +#ifdef INSURANCE + save_currentstate(); +#endif /* INSURANCE */ + done_a_checkpoint = TRUE; + timeout(-1); + timeoutset = FALSE; + } else { + if (timeoutset) { + timeout(-1); + timeoutset = FALSE; + } + break; + } + } + } else { ch = getch(); + } return ch; } /* Read a character of input from the user */ - int curses_read_char(void) { @@ -67,6 +91,12 @@ curses_read_char(void) return ch; } +boolean +curses_has_256color(void) +{ + return (COLORS >= 256) && (COLOR_PAIRS >= 256 * CURSES_NUM_BACKGROUND_COLORS); +} + /* Turn on or off the specified color and / or attribute */ void @@ -123,7 +153,7 @@ curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff) if (use_bold) { wattron(win, A_BOLD); } - wattron(win, COLOR_PAIR(curses_color)); + wcolor_set(win, curses_color, &curses_color); } if (attr != NONE) { diff --git a/win/curses/cursmisc.h b/win/curses/cursmisc.h index 8d5becb28..81c34135d 100644 --- a/win/curses/cursmisc.h +++ b/win/curses/cursmisc.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursmisc.h */ +/* NetHack 5.0 cursmisc.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ @@ -8,8 +8,11 @@ /* Global declarations */ +#define CURSES_NUM_BACKGROUND_COLORS 8 + int curses_getch(void); int curses_read_char(void); +boolean curses_has_256color(void); void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff); void curses_menu_color_attr(WINDOW *win, int color, int attr, int onoff); void curses_bail(const char *mesg); diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index b44fae883..0abcecdc7 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursstat.c */ +/* NetHack 5.0 cursstat.c */ /* Copyright (c) Andy Thomson, 2018. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/cursstat.h b/win/curses/cursstat.h index 1f2179e7e..4d4ce2ac5 100644 --- a/win/curses/cursstat.h +++ b/win/curses/cursstat.h @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 cursstat.h */ +/* NetHack 5.0 cursstat.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/curses/curswins.c b/win/curses/curswins.c index 52e21db37..92ef4baa9 100644 --- a/win/curses/curswins.c +++ b/win/curses/curswins.c @@ -1,5 +1,5 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 curswins.c */ +/* NetHack 5.0 curswins.c */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ @@ -40,7 +40,8 @@ typedef struct nhwd { typedef struct nhchar { int ch; /* character */ - int color; /* color info for character */ + int color; /* basic color info for character */ + int color256; /* extended color for the character, 0 if none */ int framecolor; /* background color info for character */ int attr; /* attributes of character */ struct unicode_representation *unicode_representation; @@ -532,7 +533,7 @@ curses_putch(winid wid, int x, int y, int ch, #ifdef ENHANCED_SYMBOLS struct unicode_representation *unicode_representation, #endif - int color, int framecolor, int attr) + const struct glyph_attributes *attr) { static boolean map_initted = FALSE; int sx, sy, ex, ey; @@ -554,9 +555,10 @@ curses_putch(winid wid, int x, int y, int ch, --x; /* map column [0] is not used; draw column [1] in first screen col */ map[y][x].ch = ch; - map[y][x].color = color; - map[y][x].framecolor = framecolor; - map[y][x].attr = attr; + map[y][x].color = attr->basic_color; + map[y][x].color256 = attr->color256; + map[y][x].framecolor = attr->framecolor; + map[y][x].attr = attr->attribute_flags; #ifdef ENHANCED_SYMBOLS map[y][x].unicode_representation = unicode_representation; #endif @@ -763,22 +765,27 @@ is_main_window(winid wid) coordinates without a refresh. Currently only used for the map. */ /* convert nhcolor (fg) and framecolor (bg) to curses colorpair */ -int -get_framecolor(int nhcolor, int framecolor) +static int +get_framecolor(const nethack_char *nch) { + int bgcolor = (nch->framecolor != NO_COLOR) ? nch->framecolor : 0; /* curses_toggle_color_attr() adds the +1 and takes care of COLORS < 16 */ - return (16 * (framecolor % 8)) + (nhcolor % 16); + if (curses_has_256color()) { + int color = nch->color256 ? nch->color256 : nch->color; + return (256 * (bgcolor % CURSES_NUM_BACKGROUND_COLORS)) + (color % 256); + } else + return (16 * (bgcolor % CURSES_NUM_BACKGROUND_COLORS)) + (nch->color % 16); } static void write_char(WINDOW * win, int x, int y, nethack_char nch) { - int curscolor = nch.color, cursattr = nch.attr; + int curscolor; + int cursattr = nch.attr; - if (nch.framecolor != NO_COLOR) { - curscolor = get_framecolor(nch.color, nch.framecolor); - if (nch.attr == A_REVERSE) - cursattr = A_NORMAL; /* hilited pet looks odd otherwise */ + curscolor = get_framecolor(&nch); + if ((nch.framecolor != NO_COLOR) && (nch.attr == A_REVERSE)) { + cursattr = A_NORMAL; /* hilited pet looks odd otherwise */ } curses_toggle_color_attr(win, curscolor, cursattr, ON); #if defined(CURSES_UNICODE) && defined(ENHANCED_SYMBOLS) @@ -876,21 +883,25 @@ curses_draw_map(int sx, int sy, int ex, int ey) #ifdef MAP_SCROLLBARS hsb_back.ch = '-'; hsb_back.color = SCROLLBAR_BACK_COLOR; + hsb_back.color256 = 0; hsb_back.framecolor = NO_COLOR; hsb_back.attr = A_NORMAL; hsb_back.unicode_representation = NULL; hsb_bar.ch = '*'; hsb_bar.color = SCROLLBAR_COLOR; + hsb_bar.color256 = 0; hsb_bar.framecolor = NO_COLOR; hsb_bar.attr = A_NORMAL; hsb_bar.unicode_representation = NULL; vsb_back.ch = '|'; vsb_back.color = SCROLLBAR_BACK_COLOR; + vsb_back.color256 = 0; vsb_back.framecolor = NO_COLOR; vsb_back.attr = A_NORMAL; vsb_back.unicode_representation = NULL; vsb_bar.ch = '*'; vsb_bar.color = SCROLLBAR_COLOR; + vsb_bar.color256 = 0; vsb_bar.framecolor = NO_COLOR; vsb_bar.attr = A_NORMAL; vsb_bar.unicode_representation = NULL; @@ -958,6 +969,8 @@ clear_map(void) for (y = 0; y < ROWNO; y++) { map[y][x].ch = ' '; map[y][x].color = NO_COLOR; + map[y][x].color256 = 0; + map[y][x].framecolor = NO_COLOR; map[y][x].attr = A_NORMAL; map[y][x].unicode_representation = NULL; } diff --git a/win/curses/curswins.h b/win/curses/curswins.h index 5842f52ed..13985ce1b 100644 --- a/win/curses/curswins.h +++ b/win/curses/curswins.h @@ -1,11 +1,17 @@ /* vim:set cin ft=c sw=4 sts=4 ts=8 et ai cino=Ls\:0t0(0 : -*- mode:c;fill-column:80;tab-width:8;c-basic-offset:4;indent-tabs-mode:nil;c-file-style:"k&r" -*-*/ -/* NetHack 3.7 curswins.h */ +/* NetHack 5.0 curswins.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ #ifndef CURSWIN_H # define CURSWIN_H +struct glyph_attributes { + int basic_color; // basic color + int color256; // extended color (0 if not defined), used when supported + int framecolor; + int attribute_flags; +}; /* Global declarations */ @@ -27,11 +33,11 @@ void curses_del_wid(winid wid); void curs_destroy_all_wins(void); #ifdef ENHANCED_SYMBOLS void curses_putch(winid wid, int x, int y, int ch, - struct unicode_representation *ur, int color, - int framecolor, int attrs); + struct unicode_representation *ur, + const struct glyph_attributes *attr); #else -void curses_putch(winid wid, int x, int y, int ch, int color, - int framecolor, int attrs); +void curses_putch(winid wid, int x, int y, int ch, + const struct glyph_attributes *attr); #endif void curses_get_window_xy(winid wid, int *x, int *y); boolean curses_window_has_border(winid wid); diff --git a/win/macosx/NetHackGuidebook.applescript b/win/macosx/NetHackGuidebook.applescript index 71f59f031..6006623fe 100644 --- a/win/macosx/NetHackGuidebook.applescript +++ b/win/macosx/NetHackGuidebook.applescript @@ -1,5 +1,5 @@ #!/usr/bin/osascript -# NetHack 3.7 NetHackGuidebook.applescript $NHDT-Date: 1596498328 2020/08/03 23:45:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ +# NetHack 5.0 NetHackGuidebook.applescript $NHDT-Date: 1596498328 2020/08/03 23:45:28 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2011 # NetHack may be freely redistributed. See license for details. diff --git a/win/macosx/NetHackRecover.applescript b/win/macosx/NetHackRecover.applescript index 097894e76..72544864b 100644 --- a/win/macosx/NetHackRecover.applescript +++ b/win/macosx/NetHackRecover.applescript @@ -1,5 +1,5 @@ #!/usr/bin/osascript -# NetHack 3.7 NetHackRecover.applescript $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 5.0 NetHackRecover.applescript $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009 # NetHack may be freely redistributed. See license for details. diff --git a/win/macosx/recover.pl b/win/macosx/recover.pl index ba9df67c0..5fb4535f2 100755 --- a/win/macosx/recover.pl +++ b/win/macosx/recover.pl @@ -1,6 +1,6 @@ #!/usr/bin/perl -# NetHack 3.7 recover.pl $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ +# NetHack 5.0 recover.pl $NHDT-Date: 1596498329 2020/08/03 23:45:29 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2009 # NetHack may be freely redistributed. See license for details. diff --git a/win/share/bmptiles.c b/win/share/bmptiles.c index 31ea391bb..43d1bf814 100644 --- a/win/share/bmptiles.c +++ b/win/share/bmptiles.c @@ -1,8 +1,11 @@ -/* NetHack 3.7 bmptiles.c $NHDT-Date: 1596498334 2020/08/03 23:45:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 bmptiles.c $NHDT-Date: 1781973097 2026/06/20 16:31:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ #include "config.h" + +#ifdef TILES_IN_GLYPHMAP + #include "tileset.h" /* First BMP file header */ @@ -592,3 +595,5 @@ pixel_element(uint32 mask, uint32 color) color &= mask; return color * 255 / mask; } + +#endif /* TILES_IN_GLYPHMAP */ diff --git a/win/share/decals.txt b/win/share/decals.txt new file mode 100644 index 000000000..bc1094912 --- /dev/null +++ b/win/share/decals.txt @@ -0,0 +1,95 @@ +# decals.txt - definitions for 'decals' +# to merge over top of another tile +# +# Note: lines beginning with '# tile ' are not comments; other +# lines beginning with '#' are. +. = (71, 108, 108) +A = (0, 0, 0) +B = (0, 182, 255) +C = (255, 108, 0) +D = (255, 0, 0) +E = (0, 0, 255) +F = (0, 145, 0) +G = (108, 255, 0) +H = (255, 255, 0) +I = (255, 0, 255) +J = (145, 71, 0) +K = (204, 79, 0) +L = (255, 182, 145) +M = (237, 237, 237) +N = (255, 255, 255) +O = (215, 215, 215) +P = (108, 145, 182) +Q = (18, 18, 18) +R = (54, 54, 54) +S = (73, 73, 73) +T = (82, 82, 82) +U = (205,205,205) +V = (104, 104, 104) +W = (131, 131, 131) +X = (140, 140, 140) +Y = (149, 149, 149) +Z = (195, 195, 195) +0 = (100, 100, 100) +1 = (72, 108, 108) +2 = (0, 255, 0) +# tile 0 (decal_delimiter) +{ + ................ + AAAAAAAAAAAAAAAA + 2222222222222222 + EEEEEEEEEEEEEEEE + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# decals that can be overlayed +# onto an object tile +# +# tile 1 (decal_pet) +{ + ............D.D. + ...........DDDDD + ............DDD. + .............D.. + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# tile 2 (decal_pile) +{ + ..N............. + ..N............. + NNNNN........... + ..N............. + ..N.N........... + .....N.......... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} diff --git a/win/share/giftiles.c b/win/share/giftiles.c index bb2db7972..cccf206fd 100644 --- a/win/share/giftiles.c +++ b/win/share/giftiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 giftiles.c $NHDT-Date: 1596498335 2020/08/03 23:45:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ */ +/* NetHack 5.0 giftiles.c $NHDT-Date: 1781973097 2026/06/20 16:31:37 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.4 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -7,6 +7,9 @@ * http://www.w3.org/Graphics/GIF/spec-gif89a.txt */ #include "config.h" + +#ifdef TILES_IN_GLYPHMAP + #include "tileset.h" #define MIN_LZW_BITS 3 @@ -497,3 +500,5 @@ free_data_block(struct DataBlock *block) block->size = 0; block->data = NULL; } + +#endif /* TILES_IN_GLYPHMAP */ diff --git a/win/share/objects.txt b/win/share/objects.txt index 53ebdcf13..f150a9e8b 100644 --- a/win/share/objects.txt +++ b/win/share/objects.txt @@ -4808,7 +4808,7 @@ Z = (195, 195, 195) ...........AJ... ..........KJA... .........KJA.... - ........JJA..... + ........KJA..... .......JJA...... ......KJA....... .....JJA........ @@ -5000,8 +5000,8 @@ Z = (195, 195, 195) ....OOOOOOOO.... ...OOOOOOOOOO... ...LOOOOOOOOLAA. - ...LKOOOOOOJLAA. - ...KKLKKKKLJJAA. + ...LKOOOOOOJLAAA + ...KKLKKKKLJJAAA ...JKLKKKKLJJAA. ....JKKKKKKJAA.. .....JJJJJJAA... diff --git a/win/share/pngtiles.c b/win/share/pngtiles.c new file mode 100644 index 000000000..0c77d399f --- /dev/null +++ b/win/share/pngtiles.c @@ -0,0 +1,150 @@ +#include "config.h" +#include "tileset.h" + +#ifdef USE_PNG + +#include + +boolean +read_png_tiles(const char *filename, struct TileSetImage *image) +{ + png_structp read_png_ptr = NULL; /* custodial */ + png_infop read_info_ptr = NULL; /* custodial */ + png_infop read_end_info = NULL; /* custodial */ + + FILE *fp; + unsigned char header[8]; + size_t size, num_pixels; + unsigned x, y; + png_bytepp pixels; + png_byte color_type; + int palette_size = 0; + png_textp text_chunks; + int num_text_chunks, i; + + image->width = 0; + image->height = 0; + image->indexes = NULL; /* custodial, returned */ + image->pixels = NULL; /* custodial, returned */ + image->image_desc = NULL; /* custodial, returned */ + image->tile_width = 0; + image->tile_height = 0; + + /* Open the file */ + fp = fopen(filename, "rb"); + if (fp == NULL) goto error; + + /* Check for PNG format */ + memset(header, 0, sizeof(header)); + size = fread(header, 1, sizeof(header), fp); + if (size < sizeof(header)) goto error; + if (png_sig_cmp(header, 0, sizeof(header)) != 0) goto error; + + /* Create read info structures */ + read_png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, + NULL, NULL); + if (read_png_ptr == NULL) goto error; + if (setjmp(png_jmpbuf(read_png_ptr)) != 0) goto error; + read_info_ptr = png_create_info_struct(read_png_ptr); + read_end_info = png_create_info_struct(read_png_ptr); + + /* Link the file we opened to the read info */ + png_init_io(read_png_ptr, fp); + png_set_sig_bytes(read_png_ptr, sizeof(header)); + + /* Read the image */ + png_read_png(read_png_ptr, read_info_ptr, + PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_16, NULL); + + pixels = png_get_rows(read_png_ptr, read_info_ptr); + image->width = png_get_image_width(read_png_ptr, read_info_ptr); + image->height = png_get_image_height(read_png_ptr, read_info_ptr); + color_type = png_get_color_type(read_png_ptr, read_info_ptr); + + /* Read the palette, if there is one */ + if (color_type & PNG_COLOR_MASK_PALETTE) { + png_colorp palette = NULL; + png_bytep trans_alpha; + int num_trans; + + png_get_PLTE(read_png_ptr, read_info_ptr, &palette, &palette_size); + for (i = 0; i < 256; ++i) { + image->palette[i].r = palette[i].red; + image->palette[i].g = palette[i].green; + image->palette[i].b = palette[i].blue; + image->palette[i].a = 255; + } + if (png_get_tRNS(read_png_ptr, read_info_ptr, &trans_alpha, &num_trans, + NULL) != 0) { + for (i = 0; i < num_trans; ++i) { + image->palette[i].a = trans_alpha[i]; + } + } + } + + /* Allocate pixel area; watch out for overflow */ + num_pixels = (size_t) image->width * (size_t) image->height; + if (num_pixels / image->width != image->height) goto error; /* overflow */ + size = num_pixels * sizeof(image->pixels[0]); + if (size / sizeof(image->pixels[0]) != num_pixels) goto error; /* overflow */ + image->pixels = (struct Pixel *) alloc(size); + if (color_type & PNG_COLOR_MASK_PALETTE) { + image->indexes = (unsigned char *) alloc(num_pixels); + } + + /* Convert the pixels */ + for (y = 0; y < image->height; ++y) { + png_bytep png_row = pixels[y]; + size_t index = y * image->width; + for (x = 0; x < image->width; ++x) { + if (color_type & PNG_COLOR_MASK_PALETTE) { + png_byte b = *png_row++; + image->indexes[index] = b; + image->pixels[index] = image->palette[b]; + } else { + if (color_type & PNG_COLOR_MASK_COLOR) { + image->pixels[index].r = *png_row++; + image->pixels[index].g = *png_row++; + image->pixels[index].b = *png_row++; + } else { + image->pixels[index].r = *png_row++; + image->pixels[index].g = image->pixels[index].r; + image->pixels[index].b = image->pixels[index].r; + } + if (color_type & PNG_COLOR_MASK_ALPHA) { + image->pixels[index].a = *png_row++; + } else { + image->pixels[index].a = 255; + } + } + ++index; + } + } + + /* Look for the tile information */ + png_get_text(read_png_ptr, read_info_ptr, &text_chunks, &num_text_chunks); + for (i = 0; i < num_text_chunks; ++i) { + if (strcmp(text_chunks[i].key, "NH_image_desc") == 0) { + image->image_desc = (char *) alloc(text_chunks[i].text_length + 1); + memcpy(image->image_desc, text_chunks[i].text, text_chunks[i].text_length); + text_chunks[i].text[text_chunks[i].text_length] = '\0'; + } + } + + png_destroy_read_struct(&read_png_ptr, &read_info_ptr, &read_end_info); + return 1; + +error: + if (read_png_ptr) { + png_destroy_read_struct(&read_png_ptr, &read_info_ptr, &read_end_info); + } + free(image->indexes); + image->indexes = NULL; + free(image->pixels); + image->pixels = NULL; + free(image->image_desc); + image->image_desc = NULL; + return 0; +} + +#endif diff --git a/win/share/ppmwrite.c b/win/share/ppmwrite.c index 8cd7a09cc..44d181f7e 100644 --- a/win/share/ppmwrite.c +++ b/win/share/ppmwrite.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 ppmwrite.c $NHDT-Date: 1596498336 2020/08/03 23:45:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ */ +/* NetHack 5.0 ppmwrite.c $NHDT-Date: 1781973098 2026/06/20 16:31:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.10 $ */ /* this produces a raw ppm file, with a 15-character header of * "P6 3-digit-width 3-digit-height 255\n" */ diff --git a/win/share/thintile.c b/win/share/thintile.c index 32b2cfa8b..f9d85aaea 100644 --- a/win/share/thintile.c +++ b/win/share/thintile.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 thintile.c $NHDT-Date: 1596498337 2020/08/03 23:45:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 thintile.c $NHDT-Date: 1781973098 2026/06/20 16:31:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) NetHack Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tile.doc b/win/share/tile.doc index fabc6f295..4e70c960b 100644 --- a/win/share/tile.doc +++ b/win/share/tile.doc @@ -1,4 +1,4 @@ -NetHack 3.7 tile.doc $NHDT-Date: 1596498338 2020/08/03 23:45:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +NetHack 5.0 tile.doc $NHDT-Date: 1596498338 2020/08/03 23:45:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.8 $ Window ports can optionally make use of the tiles (pictures for NetHack symbols) found in this directory. They are distributed in a text format diff --git a/win/share/tile.h b/win/share/tile.h index 54d1e2a6d..c348a72dc 100644 --- a/win/share/tile.h +++ b/win/share/tile.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile.h $NHDT-Date: 1596498339 2020/08/03 23:45:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 5.0 tile.h $NHDT-Date: 1781973098 2026/06/20 16:31:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.17 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/share/tile2bmp.c b/win/share/tile2bmp.c index 4b7312aff..d58c4402d 100644 --- a/win/share/tile2bmp.c +++ b/win/share/tile2bmp.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile2bmp.c $NHDT-Date: 1737281026 2025/01/19 02:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ */ +/* NetHack 5.0 tile2bmp.c $NHDT-Date: 1781973098 2026/06/20 16:31:38 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.53 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ @@ -114,12 +114,9 @@ static void build_bmptile(pixel(*) [TILE_X]); #define TILESETS 1 static const char *const relative_tiledir = "../win/share/"; /* monsters must be first because main uses it twice */ -const char *const tilefilenames[TILESETS][3] = { - {"monsters.txt", "objects.txt", "other.txt"}, -#if 0 - {"mon32.txt", "obj32.txt", "oth32.txt"}, - {"mon64.txt", "obj64.txt", "oth64.txt"}, -#endif +const char *const tilefilenames[TILESETS][5] = { + { "monsters.txt", "objects.txt", "other.txt", + "monsters.txt", "decals.txt" }, }; int tilecnt[SIZE(tilefilenames[0])]; @@ -191,8 +188,8 @@ main(int argc, char *argv[]) printf("Error creating tile file %s, aborting.\n", bmpname); exit(EXIT_FAILURE); } - while (pass < 4) { - filenum = pass % SIZE(tilefilenames[tilefileset]); + filenum = 0; + while (pass < SIZE(tilefilenames[tilefileset])) { if (!set_tilefile_path(relative_tiledir, tilefilenames[tilefileset][filenum], tilefile_full_path, sizeof tilefile_full_path)) { @@ -248,6 +245,7 @@ main(int argc, char *argv[]) } (void) fclose_text_file(); ++pass; + ++filenum; } fwrite(newbmp, bmpsize, 1, fp); fclose(fp); diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 41583dfa0..0fbfcb045 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tilemap.c $NHDT-Date: 1737720923 2025/01/24 04:15:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 5.0 tilemap.c $NHDT-Date: 1781973099 2026/06/20 16:31:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.93 $ */ /* Copyright (c) 2016 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ @@ -101,9 +101,9 @@ const char *zap_texts[] = { "death", "lightning", "poison gas", "acid", }; -enum tilesrc { monsters_file, objects_file, other_file, generated }; +enum tilesrc { monsters_file, objects_file, other_file, generated, decals_file }; const char *tilesrc_texts[] = { - "monsters.txt", "objects.txt", "other.txt", "generated", + "monsters.txt", "objects.txt", "other.txt", "generated", "decals.txt" }; struct tilemap_t { @@ -129,7 +129,11 @@ struct tiles_used *tilelist[2500] = { 0 }; int TILE_stone = 0, /* will get set to correct tile later */ TILE_unexplored = 0, /* will get set to correct tile later */ TILE_nothing = 0, /* will get set to correct tile later */ - TILE_corr = 0; /* will get set to correct tile later; X11 uses it */ + TILE_corr = 0, /* will get set to correct tile later; X11 uses it */ + TILE_delimiter = 0, /* reference tile to indicate the two below exist */ + TILE_petmark = 0, /* tile to overlay on another tile to mark pet */ + TILE_pilemark = 0, /* tile to overlay on another tile to mark piletop */ + TILE_very_last_tile = 0; /* prototypes for functions in this file */ const char *tilename(int, const int, int); @@ -195,6 +199,7 @@ tilename(int set, const int file_entry, int gend UNUSED) { int i, k, cmap, condnum, tilenum; static char buf[BUFSZ]; + boolean decal_flag = FALSE; #if 0 int offset, gendnum; #endif @@ -203,6 +208,10 @@ tilename(int set, const int file_entry, int gend UNUSED) tilenum = 0; buf[0] = '\0'; + if (set == 3) + set = MON_GLYPH; + else if (set == 4) + decal_flag = TRUE; if (set == MON_GLYPH) { for (i = 0; i < NUMMONS; i++) { if (tilenum == file_entry) { @@ -530,9 +539,28 @@ tilename(int set, const int file_entry, int gend UNUSED) } } } /* OTH_GLYPH */ + if (decal_flag) { + tilenum = 0; /* set-relative number */ + for (i = 0; i < 3; i++) { + if (tilenum == file_entry) + switch(i) { + case 0: + return "decal_delimiter"; + break; + case 1: + return "decal_pet"; + break; + case 2: + return "decal_pile"; + break; + } + tilenum++; + } + } /* DECALS */ Sprintf(buf, "unknown %d %d", set, file_entry); - return buf; + return buf; } + #endif /* TILETEXT || OBTAIN_TILEMAP */ #ifndef TILETEXT @@ -541,7 +569,7 @@ tilename(int set, const int file_entry, int gend UNUSED) #define SOURCE_TEMPLATE "NH:src/%s" #define INCLUDE_TEMPLATE "NH:include/t.%s" #else -#ifdef MAC +#ifdef MAC68K #define SOURCE_TEMPLATE ":src:%s" #define INCLUDE_TEMPLATE ":include:%s" #else @@ -1282,16 +1310,31 @@ init_tilemap(void) tilenum++; file_entry++; } + laststatuetile = tilenum - 1; +#endif /* STATUES_DONT_LOOK_LIKE_MONSTERS */ /* go beyond NUMMONS to cover off the invisible tile at the end of monsters.txt so that the tile mapping matches things in the .bmp file (for example) */ - file_entry = 0; #if defined(OBTAIN_TILEMAP) - add_tileref(tilenum, NO_GLYPH, monsters_file, file_entry, + file_entry = 0; + add_tileref(tilenum, NO_GLYPH, generated, file_entry, "invisible statue", ""); #endif - laststatuetile = tilenum - 1; -#endif /* STATUES_DONT_LOOK_LIKE_MONSTERS */ + tilenum++; + + file_entry = 0; + TILE_delimiter = tilenum++; /* Used to init nul_glyphinfo tileidx entry */ + TILE_petmark = tilenum++; + TILE_pilemark = tilenum++; +#if defined(OBTAIN_TILEMAP) + add_tileref(TILE_delimiter, NO_GLYPH, decals_file, file_entry++, + "decal_delimiter",""); + add_tileref(TILE_petmark, NO_GLYPH, decals_file, file_entry++, + "decal_petmark",""); + add_tileref(TILE_pilemark, NO_GLYPH, decals_file, file_entry++, + "decal_pilemark",""); +#endif + TILE_very_last_tile = tilenum; #if defined(OBTAIN_TILEMAP) for (i = 0; i < MAX_GLYPH; ++i) { @@ -1347,12 +1390,18 @@ main(int argc, char *argv[]) Fprintf(ofp, "\nenum special_tiles {\n"); Fprintf(ofp, " TILE_CORR = %d,\n", TILE_corr); Fprintf(ofp, " TILE_STONE = %d,\n", TILE_stone); - Fprintf(ofp, " TILE_UNEXPLORED = %d\n", TILE_unexplored); + Fprintf(ofp, " TILE_UNEXPLORED = %d,\n", TILE_unexplored); + Fprintf(ofp, " TILE_DELIMITER = %d,\n", TILE_delimiter); + Fprintf(ofp, " TILE_PETMARK = %d,\n", TILE_petmark); + Fprintf(ofp, " TILE_PILEMARK = %d\n", TILE_pilemark); Fprintf(ofp, "};\n"); - Fprintf(ofp, "\nint total_tiles_used = %d,\n", laststatuetile + 1); + Fprintf(ofp, "\nint total_tiles_used = %d,\n", TILE_very_last_tile); Fprintf(ofp, "%sTile_corr = TILE_CORR,\n", indent); /* X11 uses it */ - Fprintf(ofp, "%sTile_stone = TILE_STONE,\n", indent); - Fprintf(ofp, "%sTile_unexplored = TILE_UNEXPLORED,\n", indent); + Fprintf(ofp, "%sTile_stone = TILE_STONE,\n", indent); + Fprintf(ofp, "%sTile_unexplored = TILE_UNEXPLORED,\n", indent); + Fprintf(ofp, "%sTile_delimiter = TILE_DELIMITER,\n", indent); + Fprintf(ofp, "%sTile_petmark = TILE_PETMARK,\n", indent); + Fprintf(ofp, "%sTile_pilemark = TILE_PILEMARK,\n", indent); Fprintf(ofp, "%smaxmontile = %d,\n", indent, lastmontile); Fprintf(ofp, "%smaxobjtile = %d,\n", indent, lastobjtile); Fprintf(ofp, "%smaxothtile = %d;\n\n", indent, lastothtile); diff --git a/win/share/tileset.c b/win/share/tileset.c index ce32d6ffa..355b6b210 100644 --- a/win/share/tileset.c +++ b/win/share/tileset.c @@ -1,16 +1,24 @@ -/* NetHack 3.7 tileset.c $NHDT-Date: 1596498341 2020/08/03 23:45:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 5.0 tileset.c $NHDT-Date: 1781973099 2026/06/20 16:31:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) Ray Chason, 2016. */ /* NetHack may be freely redistributed. See license for details. */ #include "config.h" + +#ifdef TILES_IN_GLYPHMAP + #include "objclass.h" #include "flag.h" #include "tileset.h" +/* Define this for systems that use the tile-splitting functions */ +#if defined(MSDOS) +#define USE_TILE_SPLITTING +#endif + static void get_tile_map(const char *); +#ifdef USE_TILE_SPLITTING static unsigned gcd(unsigned, unsigned); static void split_tiles(const struct TileSetImage *); -static void free_image(struct TileSetImage *); static struct TileImage *tiles; static unsigned num_tiles; @@ -21,23 +29,58 @@ static struct Pixel palette[256]; boolean read_tiles(const char *filename, boolean true_color) +{ + struct TileSetImage image; + + if (tiles != NULL) + return TRUE; + + if (!read_tile_image(&image, filename, true_color)) { + return FALSE; + } + + /* Save the palette if present */ + have_palette = image.indexes != NULL; + memcpy(palette, image.palette, sizeof(palette)); + + /* Set the tile dimensions if the user has not done so */ + if (iflags.wc_tile_width == 0) { + iflags.wc_tile_width = image.tile_width; + } + if (iflags.wc_tile_height == 0) { + iflags.wc_tile_height = image.tile_height; + } + + /* Split the image into tiles */ + split_tiles(&image); + + free_tile_image(&image); + return TRUE; +} +#endif /* USE_TILE_SPLITTING */ + +boolean +read_tile_image(struct TileSetImage *image, const char *filename, boolean true_color) { static const unsigned char png_sig[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; - struct TileSetImage image; FILE *fp; char header[16]; boolean ok; /* Fill the image structure with known values */ - image.width = 0; - image.height = 0; - image.pixels = NULL; /* custodial */ - image.indexes = NULL; /* custodial */ - image.image_desc = NULL; /* custodial */ - image.tile_width = 0; - image.tile_height = 0; + image->width = 0; + image->height = 0; + image->pixels = NULL; /* custodial, returned */ + image->indexes = NULL; /* custodial, returned */ + image->image_desc = NULL; /* custodial, returned */ + image->tile_width = 0; + image->tile_height = 0; + + if (filename == NULL || filename[0] == '\0') { + filename = "nhtiles.bmp"; + } /* Identify the image type */ fp = fopen(filename, "rb"); @@ -49,12 +92,12 @@ read_tiles(const char *filename, boolean true_color) /* Call the loader appropriate for the image */ if (memcmp(header, "BM", 2) == 0) { - ok = read_bmp_tiles(filename, &image); + ok = read_bmp_tiles(filename, image); } else if (memcmp(header, "GIF87a", 6) == 0 || memcmp(header, "GIF89a", 6) == 0) { - ok = read_gif_tiles(filename, &image); + ok = read_gif_tiles(filename, image); } else if (memcmp(header, png_sig, sizeof(png_sig)) == 0) { - ok = read_png_tiles(filename, &image); + ok = read_png_tiles(filename, image); } else { ok = FALSE; } @@ -63,44 +106,30 @@ read_tiles(const char *filename, boolean true_color) /* Reject if the interface cannot handle direct color and the image does not use a palette */ - if (!true_color && image.indexes == NULL) + if (!true_color && image->indexes == NULL) goto error; - /* Save the palette if present */ - have_palette = image.indexes != NULL; - memcpy(palette, image.palette, sizeof(palette)); + /* Parse the tile map */ + get_tile_map(image->image_desc); /* Set defaults for tile metadata */ - if (image.tile_width == 0) { - image.tile_width = image.width / 40; + if (image->tile_width == 0) { + image->tile_width = image->width / 40; } - if (image.tile_height == 0) { - image.tile_height = image.tile_width; - } - /* Set the tile dimensions if the user has not done so */ - if (iflags.wc_tile_width == 0) { - iflags.wc_tile_width = image.tile_width; - } - if (iflags.wc_tile_height == 0) { - iflags.wc_tile_height = image.tile_height; + if (image->tile_height == 0) { + image->tile_height = image->tile_width; } - /* Parse the tile map */ - get_tile_map(image.image_desc); - - /* Split the image into tiles */ - split_tiles(&image); - - free_image(&image); return TRUE; error: if (fp) fclose(fp); - free_image(&image); + free_tile_image(image); return FALSE; } +#ifdef USE_TILE_SPLITTING /* Free tile memory not required by the chosen display mode */ void set_tile_type(boolean true_color) @@ -128,6 +157,7 @@ get_palette(void) { return have_palette ? palette : NULL; } +#endif /* USE_TILE_SPLITTING */ /* TODO: derive tile_map from image_desc */ static void @@ -136,6 +166,7 @@ get_tile_map(const char *image_desc UNUSED) return; } +#ifdef USE_TILE_SPLITTING void free_tiles(void) { @@ -155,9 +186,10 @@ free_tiles(void) if (blank_tile.indexes) free((genericptr_t) blank_tile.indexes), blank_tile.indexes = NULL; } +#endif /* USE_TILE_SPLITTING */ -static void -free_image(struct TileSetImage *image) +void +free_tile_image(struct TileSetImage *image) { if (image->pixels) free((genericptr_t) image->pixels), image->pixels = NULL; @@ -167,6 +199,7 @@ free_image(struct TileSetImage *image) free((genericptr_t) image->image_desc), image->image_desc = NULL; } +#ifdef USE_TILE_SPLITTING const struct TileImage * get_tile(unsigned tile_index) { @@ -283,13 +316,13 @@ split_tiles(const struct TileSetImage *image) { unsigned tile_rows, tile_cols; size_t tile_size, i, j; - unsigned x1, y1, x2, y2; + unsigned x1, y1, y2; /* Get the number of tiles */ - tile_rows = image->height / iflags.wc_tile_height; - tile_cols = image->width / iflags.wc_tile_width; + tile_rows = image->height / image->tile_height; + tile_cols = image->width / image->tile_width; num_tiles = tile_rows * tile_cols; - tile_size = (size_t) iflags.wc_tile_height * (size_t) iflags.wc_tile_width; + tile_size = (size_t) image->tile_height * (size_t) image->tile_width; /* Allocate the tile array */ tiles = (struct TileImage *) alloc(num_tiles * sizeof(tiles[0])); @@ -300,32 +333,31 @@ split_tiles(const struct TileSetImage *image) for (x1 = 0; x1 < tile_cols; ++x1) { struct TileImage *tile = &tiles[y1 * tile_cols + x1]; - tile->width = iflags.wc_tile_width; - tile->height = iflags.wc_tile_height; + tile->width = image->tile_width; + tile->height = image->tile_height; tile->pixels = (struct Pixel *) alloc(tile_size * sizeof (struct Pixel)); if (image->indexes != NULL) { tile->indexes = (unsigned char *) alloc(tile_size); } - for (y2 = 0; y2 < (unsigned) iflags.wc_tile_height; ++y2) { - for (x2 = 0; x2 < (unsigned) iflags.wc_tile_width; ++x2) { - unsigned x = x1 * iflags.wc_tile_width + x2; - unsigned y = y1 * iflags.wc_tile_height + y2; - - i = y * image->width + x; - j = y2 * tile->width + x2; - tile->pixels[j] = image->pixels[i]; - if (image->indexes != NULL) { - tile->indexes[j] = image->indexes[i]; - } + for (y2 = 0; y2 < (unsigned) image->tile_height; ++y2) { + unsigned y = y1 * image->tile_height + y2; + unsigned x = x1 * image->tile_width; + i = y * image->width; + j = y2 * tile->width; + memcpy(tile->pixels + j, image->pixels + i + x, + sizeof(tile->pixels[0]) * image->tile_width); + if (image->indexes != NULL) { + memcpy(tile->indexes + j, image->indexes + i + x, + image->tile_width); } } } } /* Create a blank tile for use when the tile index is invalid */ - blank_tile.width = iflags.wc_tile_width; - blank_tile.height = iflags.wc_tile_height; + blank_tile.width = image->tile_width; + blank_tile.height = image->tile_height; blank_tile.pixels = (struct Pixel *) alloc(tile_size * sizeof (struct Pixel)); for (i = 0; i < tile_size; ++i) { @@ -339,10 +371,15 @@ split_tiles(const struct TileSetImage *image) memset(blank_tile.indexes, 0, tile_size); } } +#endif /* USE_TILE_SPLITTING */ +#ifndef USE_PNG boolean read_png_tiles(const char *filename UNUSED, struct TileSetImage *image UNUSED) { /* stub */ return FALSE; } +#endif /* !USE_PNG */ + +#endif /* TILES_IN_GLYPHMAP */ diff --git a/win/share/tiletext.c b/win/share/tiletext.c index ac9a8afd7..47e3bbebe 100644 --- a/win/share/tiletext.c +++ b/win/share/tiletext.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 tiletext.c $NHDT-Date: 1596498342 2020/08/03 23:45:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 tiletext.c $NHDT-Date: 1781973099 2026/06/20 16:31:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ @@ -20,9 +20,9 @@ static FILE *tile_file; static int tile_set, tile_set_indx; static const char *const text_sets[] = { #if (TILE_X == 8) - "monthin.txt", "objthin.txt", "oththin.txt" + "monthin.txt", "objthin.txt", "oththin.txt", "monthin.txt", "decthin.txt" #else - "monsters.txt", "objects.txt", "other.txt" + "monsters.txt", "objects.txt", "other.txt", "monsters.txt", "decals.txt" #endif }; @@ -36,7 +36,7 @@ static boolean write_text_colormap(FILE *); static boolean read_txttile(FILE *, pixel (*)[TILE_X]); static void write_txttile(FILE *, pixel (*)[TILE_X]); -enum { MONSTER_SET, OBJECT_SET, OTHER_SET}; +enum { MONSTER_SET, OBJECT_SET, OTHER_SET, STATUE_SET, DECAL_SET }; /* Ugh. DICE doesn't like %[A-Z], so we have to spell it out... */ #define FORMAT_STRING \ @@ -189,7 +189,7 @@ read_txttile(FILE *txtfile, pixel (*pixels)[TILE_X]) gend[0] = '\0'; reslt = 0; if (get_next_line(txtfile, FALSE)) { - if (tile_set == MONSTER_SET) + if (tile_set == MONSTER_SET || tile_set == STATUE_SET) reslt = sscanf(inbuf, "# %255s %d (%255[^,],%255[^)])", ttype, &i, buf, gend); else @@ -202,7 +202,7 @@ read_txttile(FILE *txtfile, pixel (*pixels)[TILE_X]) ttype[sizeof ttype - 1] = '\0'; buf[sizeof buf - 1] = '\0'; - if (tile_set == MONSTER_SET && gend[0] == 'f') + if ((tile_set == MONSTER_SET || tile_set == STATUE_SET) && gend[0] == 'f') gidx = 1; ph = strcmp(ttype, "placeholder") == 0; diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 5e701c332..6ec7c0266 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 winshim.c $NHDT-Date: 1596498345 2020/08/03 23:45:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.259 $ */ +/* NetHack 5.0 winshim.c $NHDT-Date: 1781973099 2026/06/20 16:31:39 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.34 $ */ /* Copyright (c) Adam Powers, 2020 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/tty/getline.c b/win/tty/getline.c index acb3f7f14..459491864 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 getline.c $NHDT-Date: 1701285885 2023/11/29 19:24:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ */ +/* NetHack 5.0 getline.c $NHDT-Date: 1781973100 2026/06/20 16:31:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -7,7 +7,7 @@ #ifdef TTY_GRAPHICS -#if !defined(MAC) +#if !defined(MAC68K) #define NEWAUTOCOMP #endif diff --git a/win/tty/termcap.c b/win/tty/termcap.c index ad8e25764..95dd0b27c 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 termcap.c $NHDT-Date: 1701946349 2023/12/07 10:52:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ */ +/* NetHack 5.0 termcap.c $NHDT-Date: 1781973100 2026/06/20 16:31:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.81 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -27,6 +27,9 @@ void term_end_extracolor(void); #if (!defined(UNIX) || !defined(TERMINFO)) && !defined(TOS) static void analyze_seq(char *, int *, int *); #endif +#if defined(UNIX) && defined(TERMINFO) +static int indexed_color_count(void); +#endif #endif #if (defined(TERMLIB) || defined(ANSI_DEFAULT)) static void init_hilite(void); @@ -39,9 +42,18 @@ struct tc_lcl_data tc_lcl_data = { 0, 0, 0, 0, 0, 0, 0, FALSE }; static char *nh_VI = (char *) 0; /* cursor_invisible */ static char *nh_VE = (char *) 0; /* cursor_normal */ /*static char *nh_VS = (char *) 0;*/ /* cursor_visible (highlighted cursor) */ +#if defined(TERMLIB) || defined(CHANGE_COLOR) static char *nh_Ic = (char *) 0; /* initialize_color */ +#endif -static char *HO, *CL, *CE, *UP, *XD, *BC, *SO, *SE, *TI, *TE; +#if !defined(__NetBSD__) +static char *UP, *BC; +#ifdef TERMLIB +static char PC = '\0'; +#endif +#endif + +static char *HO, *CL, *CE, *XD, *SO, *SE, *TI, *TE; static char *VS, *VE; static char *ME, *MR, *MB, *MH, *MD; static char *ZH, *ZR; @@ -49,7 +61,6 @@ static char *ZH, *ZR; #ifdef TERMLIB boolean dynamic_HIHE = FALSE; static int SG; -static char PC = '\0'; static char tbuf[512]; #endif /*TERMLIB*/ @@ -890,7 +901,7 @@ cl_eos(void) /* free after Robert Viduya */ #include -#if !defined(LINUX) && !defined(__FreeBSD__) && !defined(NOTPARMDECL) +#if defined(TPARM_WORKAROUND) extern char *tparm(); #endif @@ -942,6 +953,15 @@ init_hilite(void) colors = tgetnum(nhStr("Co")); iflags.colorcount = colors; +#ifdef NCURSES_VERSION + /* The standard ncurses terminfo entries that support 24-bit colors + (*-direct) map the standard 8/16/256 colors onto the beginning + of the 24-bit color range. For example, rgb(0,0,1) appears as red + instead of nearly black. iflags.colorcount should retain the actual + supported color count, while for default color initialization we + take the available indexed colors into consieration. */ + colors = indexed_color_count(); +#endif int md_len = 0; if (colors < 8 || !MD || !*MD @@ -973,10 +993,10 @@ init_hilite(void) if (colors >= 16) { for (c = 0; c < SIZE(ti_map); c++) { /* system colors */ - scratch = tparm(setf, ti_map[c].nh_color); + scratch = tparm2(setf, ti_map[c].nh_color); hilites[ti_map[c].nh_color] = dupstr(scratch); /* bright colors */ - scratch = tparm(setf, ti_map[c].nh_bright_color); + scratch = tparm2(setf, ti_map[c].nh_bright_color); hilites[ti_map[c].nh_bright_color] = dupstr(scratch); } } else { @@ -987,7 +1007,7 @@ init_hilite(void) while (c--) { char *work; - scratch = tparm(setf, ti_map[c].ti_color); + scratch = tparm2(setf, ti_map[c].ti_color); work = (char *) alloc(strlen(scratch) + md_len + 1); Strcpy(work, MD); hilites[ti_map[c].nh_bright_color] = work; @@ -998,10 +1018,10 @@ init_hilite(void) } if (colors >= 16) { - scratch = tparm(setf, COLOR_WHITE | BRIGHT); + scratch = tparm2(setf, COLOR_WHITE | BRIGHT); hilites[CLR_WHITE] = dupstr(scratch); } else { - scratch = tparm(setf, COLOR_WHITE); + scratch = tparm2(setf, COLOR_WHITE); hilites[CLR_WHITE] = (char *) alloc(strlen(scratch) + md_len + 1); Strcpy(hilites[CLR_WHITE], MD); Strcat(hilites[CLR_WHITE], scratch); @@ -1012,7 +1032,7 @@ init_hilite(void) if (iflags.wc2_darkgray) { if (colors >= 16) { - scratch = tparm(setf, COLOR_BLACK|BRIGHT); + scratch = tparm2(setf, COLOR_BLACK|BRIGHT); hilites[CLR_BLACK] = dupstr(scratch); } else { /* On many terminals, esp. those using classic PC CGA/EGA/VGA @@ -1020,7 +1040,7 @@ init_hilite(void) * produces a dark shade of gray that is visible against a * black background. We can use it to represent black objects. */ - scratch = tparm(setf, COLOR_BLACK); + scratch = tparm2(setf, COLOR_BLACK); hilites[CLR_BLACK] = (char *) alloc(strlen(scratch) + md_len + 1); Strcpy(hilites[CLR_BLACK], MD); Strcat(hilites[CLR_BLACK], scratch); @@ -1049,7 +1069,7 @@ kill_hilite(void) if (hilites[CLR_BLACK] != hilites[CLR_BLUE]) free(hilites[CLR_BLACK]), hilites[CLR_BLACK] = NULL; } - if (tgetnum(nhStr("Co")) >= 16) { + if (indexed_color_count() >= 16) { if (hilites[CLR_BLUE]) free(hilites[CLR_BLUE]); if (hilites[CLR_GREEN]) @@ -1091,6 +1111,21 @@ kill_hilite(void) hilites[c] = NULL; } +static int +indexed_color_count(void) +{ +#ifdef NCURSES_VERSION + /* ncurses adds the non-standard attribute CO for "number of indexed + colors overlaying RGB space". */ + int idx_colors = tgetnum(nhStr("CO")); + if (idx_colors > 0) { + return idx_colors; + } +#endif + + return tgetnum(nhStr("Co")); +} + #else /* UNIX && TERMINFO */ #ifndef TOS @@ -1551,13 +1586,7 @@ tty_change_color(int color, long rgb, int reverse UNUSED) #ifndef SEP2 #define tcfmtstr "\033[38;2;%ld;%ld;%ldm" -#ifdef UNIX -#define tcfmtstr24bit "\033[38;2;%u;%u;%um" #define tcfmtstr256 "\033[38;5;%dm" -#else -#define tcfmtstr24bit "\033[38;2;%lu;%lu;%lum" -#define tcfmtstr256 "\033[38:5:%lum" -#endif #endif static void emit24bit(long mcolor); diff --git a/win/tty/topl.c b/win/tty/topl.c index c20dfa288..e3b154c86 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 topl.c $NHDT-Date: 1717967339 2024/06/09 21:08:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 5.0 topl.c $NHDT-Date: 1781973100 2026/06/20 16:31:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.94 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -261,7 +261,8 @@ update_topl(const char *bp) n0 = strlen(bp); if ((ttyDisplay->toplin == TOPLINE_NEED_MORE || skip) && cw->cury == 0 - && n0 + (int) strlen(gt.toplines) + 3 < CO - 8 /* room for --More-- */ + /* room for --More-- */ + && n0 + (int) strlen(gt.toplines) + 3 < min(CO - 8, TBUFSZ) && (notdied = strncmp(bp, "You die", 7)) != 0) { Strcat(gt.toplines, " "); Strcat(gt.toplines, bp); diff --git a/win/tty/wintty.c b/win/tty/wintty.c index b2c6a5c42..9b545d8fd 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintty.c $NHDT-Date: 1737691300 2025/01/23 20:01:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.420 $ */ +/* NetHack 5.0 wintty.c $NHDT-Date: 1781973100 2026/06/20 16:31:40 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.438 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -20,7 +20,7 @@ /* leave this undefined; it produces bad screen output with rxvt-unicode */ /*#define DECgraphicsOptimization*/ -#ifdef MAC +#ifdef MAC68K #define MICRO /* The Mac is a MICRO only for this file, not in general! */ #ifdef THINK_C extern void msmsg(const char *, ...); @@ -143,7 +143,7 @@ struct window_procs tty_procs = { tty_getlin, tty_get_ext_cmd, tty_number_pad, tty_delay_output, #ifdef CHANGE_COLOR /* the Mac uses a palette device */ tty_change_color, -#ifdef MAC +#ifdef MAC68K tty_change_background, set_tty_font_name, #endif tty_get_color_string, @@ -182,7 +182,7 @@ static const char winpanicstr[] = "Bad window Id %d (%s)"; char defmorestr[] = "--More--"; #ifdef CLIPPING -#if defined(TILES_IN_GLYPHMAP) && defined(MSDOS) +#if (defined(TILES_IN_GLYPHMAP) || defined(ENHANCED_SYMBOLS)) && defined(MSDOS) boolean clipping = FALSE; /* clipping on? */ int clipx = 0, clipxmax = 0; int clipy = 0, clipymax = 0; @@ -193,7 +193,7 @@ static int clipy = 0, clipymax = 0; #endif #endif /* CLIPPING */ -#if defined(TILES_IN_GLYPHMAP) && defined(MSDOS) +#if defined(NO_TERMS) && defined(MSDOS) extern void adjust_cursor_flags(struct WinDesc *); #endif @@ -766,6 +766,8 @@ getret(void) #if defined(MICRO) || defined(WIN32CON) getreturn("to continue"); #else + if (!isatty(STDIN_FILENO) || program_state.early_options) + return; HUPSKIP(); xputs("\n"); if (flags.standout) @@ -2070,7 +2072,7 @@ tty_curs( print_vt_code2(AVTC_SELECT_WINDOW, window); -#if defined(TILES_IN_GLYPHMAP) && defined(MSDOS) +#if defined(NO_TERMS) && defined(MSDOS) adjust_cursor_flags(cw); #endif @@ -3895,18 +3897,17 @@ tty_print_glyph( if (ttyDisplay->color != NO_COLOR) term_end_color(); } - /* we don't link with termcap.o if NO_TERMS is defined */ - if ((tty_procs.wincap2 & WC2_EXTRACOLORS) - && glyphinfo->gm.customcolor != 0 - && iflags.colorcount >= 256 + if (glyphinfo->gm.customcolor != 0 && !calling_from_update_inventory) { - if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) == 0) { + if ((glyphinfo->gm.customcolor & NH_BASIC_COLOR) != 0) { + /* NH_BASIC_COLOR */ + color = COLORVAL(glyphinfo->gm.customcolor); + } else if ((tty_procs.wincap2 & WC2_EXTRACOLORS) + && iflags.colorcount >= 256) { term_start_extracolor(glyphinfo->gm.customcolor, glyphinfo->gm.color256idx); ttyDisplay->colorflags = 0; colordone = TRUE; - } else { - color = COLORVAL(glyphinfo->gm.customcolor); } } if (!colordone) { diff --git a/win/win32/NetHackW.c b/win/win32/NetHackW.c index 5a945af5c..431e5ee99 100644 --- a/win/win32/NetHackW.c +++ b/win/win32/NetHackW.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 NetHackW.c $NHDT-Date: 1693359674 2023/08/30 01:41:14 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.79 $ */ +/* NetHack 5.0 NetHackW.c $NHDT-Date: 1693359674 2023/08/30 01:41:14 $ $NHDT-Branch: keni-crashweb2 $:$NHDT-Revision: 1.79 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ @@ -216,6 +216,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, windowprocs.win_raw_print_bold = mswin_raw_print_bold; windowprocs.win_nhgetch = mswin_nhgetch; windowprocs.win_wait_synch = mswin_wait_synch; + windowprocs.win_number_pad = mswin_number_pad; /* let nethackw_main do the argument processing */ nethackw_main(argc, argv); diff --git a/win/win32/NetHackW.rc b/win/win32/NetHackW.rc index 7f4317b2b..0a555c803 100644 --- a/win/win32/NetHackW.rc +++ b/win/win32/NetHackW.rc @@ -75,7 +75,7 @@ BEGIN MENUITEM "&Lock Windows", IDM_SETTING_LOCKWINDOWS END POPUP "&Help" - // 3.7: HELP_LONG and HELP_OPTIONS_LONG both used to specify &L as their + // 5.0: HELP_LONG and HELP_OPTIONS_LONG both used to specify &L as their // accelator. Typing 'L' or 'l' highlighted one of the two, then // would execute it or typing another 'l' or 'L' would unhighlight the // currently highlit one and highlight the other. All other accelerators @@ -334,8 +334,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,7,0,0 - PRODUCTVERSION 3,7,0,0 + FILEVERSION 5,0,0,0 + PRODUCTVERSION 5,0,0,0 FILEFLAGSMASK 0x1fL #ifdef _DEBUG FILEFLAGS 0x9L @@ -351,13 +351,13 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "NetHack for Windows - Graphical Interface" - VALUE "FileVersion", "3.7.0" + VALUE "FileVersion", "5.0.0" VALUE "InternalName", "NetHackW" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2021. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." + VALUE "LegalCopyright", "Copyright (C) 1985 - 2026. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." VALUE "OriginalFilename", "NetHackW.exe" VALUE "PrivateBuild", "140606" VALUE "ProductName", "NetHack" - VALUE "ProductVersion", "3.7.0" + VALUE "ProductVersion", "5.0.0" END END BLOCK "VarFileInfo" diff --git a/win/win32/mhaskyn.c b/win/win32/mhaskyn.c index b510c064f..d958f3ff8 100644 --- a/win/win32/mhaskyn.c +++ b/win/win32/mhaskyn.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhaskyn.c $NHDT-Date: 1596498346 2020/08/03 23:45:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhaskyn.c $NHDT-Date: 1781973101 2026/06/20 16:31:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhaskyn.h b/win/win32/mhaskyn.h index 2591f34dd..9790fc3bd 100644 --- a/win/win32/mhaskyn.h +++ b/win/win32/mhaskyn.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhaskyn.h $NHDT-Date: 1596498347 2020/08/03 23:45:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 5.0 mhaskyn.h $NHDT-Date: 1781973101 2026/06/20 16:31:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.11 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhdlg.c b/win/win32/mhdlg.c index 94a7ecf3e..4650a25a5 100644 --- a/win/win32/mhdlg.c +++ b/win/win32/mhdlg.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhdlg.c $NHDT-Date: 1596498347 2020/08/03 23:45:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ +/* NetHack 5.0 mhdlg.c $NHDT-Date: 1781973101 2026/06/20 16:31:41 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.48 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhdlg.h b/win/win32/mhdlg.h index 7eb0b8eb9..a83d0680f 100644 --- a/win/win32/mhdlg.h +++ b/win/win32/mhdlg.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhdlg.h $NHDT-Date: 1596498348 2020/08/03 23:45:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 5.0 mhdlg.h $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.15 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhfont.c b/win/win32/mhfont.c index 291acacbc..9230accde 100644 --- a/win/win32/mhfont.c +++ b/win/win32/mhfont.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhfont.c $NHDT-Date: 1596498349 2020/08/03 23:45:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ */ +/* NetHack 5.0 mhfont.c $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.34 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhfont.h b/win/win32/mhfont.h index 5c4c8f4e1..53a5f4337 100644 --- a/win/win32/mhfont.h +++ b/win/win32/mhfont.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhfont.h $NHDT-Date: 1596498350 2020/08/03 23:45:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 mhfont.h $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.19 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhinput.c b/win/win32/mhinput.c index 9ad6c32f0..64a3bc213 100644 --- a/win/win32/mhinput.c +++ b/win/win32/mhinput.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhinput.c $NHDT-Date: 1596498350 2020/08/03 23:45:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 5.0 mhinput.c $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.21 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhinput.h b/win/win32/mhinput.h index e94e3dbda..4ab0d4f9a 100644 --- a/win/win32/mhinput.h +++ b/win/win32/mhinput.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhinput.h $NHDT-Date: 1596498351 2020/08/03 23:45:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhinput.h $NHDT-Date: 1781973102 2026/06/20 16:31:42 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.14 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index f3eae350c..83ce94b4d 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmain.c $NHDT-Date: 1596498352 2020/08/03 23:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ +/* NetHack 5.0 mhmain.c $NHDT-Date: 1781973103 2026/06/20 16:31:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.101 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ @@ -1193,6 +1193,13 @@ mswin_select_map_mode(int mode) data = (PNHMainWindow) GetWindowLongPtr(GetNHApp()->hMainWnd, GWLP_USERDATA); + if (!data) { +#if (NH_DEVEL_STATUS != NH_STATUS_RELEASED && NH_DEVEL_STATUS != NH_STATUS_POSTRELEASE) + impossible("data is null in %s:%d", __func__, __LINE__); +#endif + return; + } + /* override for Rogue level */ if (Is_rogue_level(&u.uz) && !IS_MAP_ASCII(mode)) return; @@ -1354,6 +1361,19 @@ nh_compose_ascii_screenshot(void) return retval; } +int +get_approx_display_cols(void) +{ + return GetSystemMetrics(SM_CXSCREEN) / 8; +} + +int +get_approx_display_rows(void) +{ + return GetSystemMetrics(SM_CYSCREEN) / 12; +} + + #ifdef ENHANCED_SYMBOLS // returns malloc() created pointer - callee assumes the ownership static WCHAR * diff --git a/win/win32/mhmain.h b/win/win32/mhmain.h index c4aea5ce2..a50fac0bb 100644 --- a/win/win32/mhmain.h +++ b/win/win32/mhmain.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmain.h $NHDT-Date: 1596498352 2020/08/03 23:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 mhmain.h $NHDT-Date: 1781973103 2026/06/20 16:31:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 46a7ee1d0..263e33bd4 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmap.c $NHDT-Date: 1596498353 2020/08/03 23:45:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ */ +/* NetHack 5.0 mhmap.c $NHDT-Date: 1781973103 2026/06/20 16:31:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.115 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ @@ -989,7 +989,8 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) rgbcolor = nhcolor_to_RGB(color); } } - if (((data->map[i][j].gm.glyphflags & MG_PET) && iflags.hilite_pet) + if ((((data->map[i][j].gm.glyphflags & MG_PET) && iflags.hilite_pet) + || ((data->map[i][j].gm.glyphflags & MG_OBJPILE) && iflags.hilite_pile)) || ((data->map[i][j].gm.glyphflags & (MG_DETECT | MG_BW_LAVA | MG_BW_ICE | MG_BW_SINK | MG_BW_ENGR)) != 0)) { diff --git a/win/win32/mhmap.h b/win/win32/mhmap.h index 679e16297..4ca2fadf9 100644 --- a/win/win32/mhmap.h +++ b/win/win32/mhmap.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmap.h $NHDT-Date: 1596498354 2020/08/03 23:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 5.0 mhmap.h $NHDT-Date: 1781973103 2026/06/20 16:31:43 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.20 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmenu.c b/win/win32/mhmenu.c index d39bdc1b4..47204025f 100644 --- a/win/win32/mhmenu.c +++ b/win/win32/mhmenu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmenu.c $NHDT-Date: 1596498354 2020/08/03 23:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 5.0 mhmenu.c $NHDT-Date: 1781973104 2026/06/20 16:31:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.96 $ */ /* Copyright (c) Alex Kompel, 2002 */ /* NetHack may be freely redistributed. See license for details. */ @@ -35,6 +35,7 @@ typedef struct mswin_menu_item { int color; char str[NHMENU_STR_SIZE]; boolean presel; + boolean group_accelerator_collision; unsigned int itemflags; int count; BOOL has_focus; @@ -191,7 +192,18 @@ mswin_menu_window_select_menu(HWND hWnd, int how, MENU_ITEM_P **_selected, /* collect group accelerators */ for (i = 0; i < data->menui.menu.size; i++) { if (data->how != PICK_NONE) { - if (data->menui.menu.items[i].group_accel + /* Check for conflict between a specific selectable + * menu item and its group accelerator. + */ + if (NHMENU_IS_SELECTABLE(data->menui.menu.items[i]) + && data->menui.menu.items[i].group_accel + == data->menui.menu.items[i].accelerator) { + /* collision between specific menu item + and its group accelerator */ + data->menui.menu.items[i].group_accelerator_collision = TRUE; + } + if (!data->menui.menu.items[i].group_accelerator_collision + && data->menui.menu.items[i].group_accel && !strchr(data->menui.menu.gacc, data->menui.menu.items[i].group_accel)) { *ap++ = data->menui.menu.items[i].group_accel; @@ -651,6 +663,7 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) /* prevent & being interpreted as a mnemonic start */ strNsubst(data->menui.menu.items[new_item].str, "&", "&&", 0); data->menui.menu.items[new_item].presel = msg_data->presel; + data->menui.menu.items[new_item].group_accelerator_collision = FALSE; data->menui.menu.items[new_item].itemflags = msg_data->itemflags; /* calculate tabstop size */ @@ -671,11 +684,16 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) DrawText(hDC, NH_A2W(p1, wbuf, BUFSZ), strlen(p1), &drawRect, DT_CALCRECT | DT_LEFT | DT_VCENTER | DT_EXPANDTABS | DT_SINGLELINE); - data->menui.menu.tab_stop_size[column] = - max(data->menui.menu.tab_stop_size[column], - drawRect.right - drawRect.left); - - menuitemwidth += data->menui.menu.tab_stop_size[column]; + int width = drawRect.right - drawRect.left; + /* The last column overhangs any subsequent columns in other + lines */ + if (p != NULL) { + data->menui.menu.tab_stop_size[column] = + max(data->menui.menu.tab_stop_size[column], width); + menuitemwidth += data->menui.menu.tab_stop_size[column]; + } else { + menuitemwidth += width; + } if (p != NULL) *p = '\t'; @@ -1169,7 +1187,8 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) p = strchr(item->str, '\t'); column = 0; SetRect(&drawRect, x, lpdis->rcItem.top, - min(x + data->menui.menu.tab_stop_size[0], lpdis->rcItem.right), + p != NULL ? x + data->menui.menu.tab_stop_size[0] + : lpdis->rcItem.right, lpdis->rcItem.bottom); for (;;) { TCHAR wbuf2[BUFSZ]; @@ -1186,8 +1205,8 @@ onDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam) p = strchr(p1, '\t'); drawRect.left = drawRect.right + TAB_SEPARATION; ++column; - drawRect.right = min(drawRect.left + data->menui.menu.tab_stop_size[column], - lpdis->rcItem.right); + drawRect.right = p != NULL ? drawRect.left + data->menui.menu.tab_stop_size[column] + : lpdis->rcItem.right; } /* draw focused item */ diff --git a/win/win32/mhmenu.h b/win/win32/mhmenu.h index 42efb30c8..c12aa87d2 100644 --- a/win/win32/mhmenu.h +++ b/win/win32/mhmenu.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmenu.h $NHDT-Date: 1596498355 2020/08/03 23:45:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhmenu.h $NHDT-Date: 1781973104 2026/06/20 16:31:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 54a2e4c3d..a80630143 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmsg.h $NHDT-Date: 1596498356 2020/08/03 23:45:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 5.0 mhmsg.h $NHDT-Date: 1781973104 2026/06/20 16:31:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.31 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index e4d62b5ab..c5ee2841f 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmsgwnd.c $NHDT-Date: 1596498357 2020/08/03 23:45:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 5.0 mhmsgwnd.c $NHDT-Date: 1781973104 2026/06/20 16:31:44 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.52 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhmsgwnd.h b/win/win32/mhmsgwnd.h index 37a68abc8..d9ff67ae9 100644 --- a/win/win32/mhmsgwnd.h +++ b/win/win32/mhmsgwnd.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhmsgwnd.h $NHDT-Date: 1596498358 2020/08/03 23:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhmsgwnd.h $NHDT-Date: 1781973105 2026/06/20 16:31:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhrip.c b/win/win32/mhrip.c index 28036307b..f80736707 100644 --- a/win/win32/mhrip.c +++ b/win/win32/mhrip.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhrip.c $NHDT-Date: 1596498358 2020/08/03 23:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 5.0 mhrip.c $NHDT-Date: 1781973105 2026/06/20 16:31:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.35 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhrip.h b/win/win32/mhrip.h index 54a74fff5..7b4bdfaa0 100644 --- a/win/win32/mhrip.h +++ b/win/win32/mhrip.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhrip.h $NHDT-Date: 1596498359 2020/08/03 23:45:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 5.0 mhrip.h $NHDT-Date: 1781973105 2026/06/20 16:31:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.13 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhsplash.c b/win/win32/mhsplash.c index 5609bab89..f6af47ed5 100644 --- a/win/win32/mhsplash.c +++ b/win/win32/mhsplash.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhsplash.c $NHDT-Date: 1596498360 2020/08/03 23:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ +/* NetHack 5.0 mhsplash.c $NHDT-Date: 1781973105 2026/06/20 16:31:45 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.45 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhstatus.c b/win/win32/mhstatus.c index eee9047f8..f4eb8578d 100644 --- a/win/win32/mhstatus.c +++ b/win/win32/mhstatus.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhstatus.c $NHDT-Date: 1596498360 2020/08/03 23:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.35 $ */ +/* NetHack 5.0 mhstatus.c $NHDT-Date: 1781973106 2026/06/20 16:31:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.45 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhstatus.h b/win/win32/mhstatus.h index ec3473334..2197a8f31 100644 --- a/win/win32/mhstatus.h +++ b/win/win32/mhstatus.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhstatus.h $NHDT-Date: 1596498361 2020/08/03 23:46:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 5.0 mhstatus.h $NHDT-Date: 1781973106 2026/06/20 16:31:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.18 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhtext.c b/win/win32/mhtext.c index 8463a187e..e84ee3af1 100644 --- a/win/win32/mhtext.c +++ b/win/win32/mhtext.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhtext.c $NHDT-Date: 1596498362 2020/08/03 23:46:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 5.0 mhtext.c $NHDT-Date: 1781973106 2026/06/20 16:31:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.39 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mhtext.h b/win/win32/mhtext.h index bacc47643..d3c34a399 100644 --- a/win/win32/mhtext.h +++ b/win/win32/mhtext.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhtext.h $NHDT-Date: 1596498363 2020/08/03 23:46:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 5.0 mhtext.h $NHDT-Date: 1781973106 2026/06/20 16:31:46 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.12 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 55ba2f696..976b8d765 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mswproc.c $NHDT-Date: 1717967341 2024/06/09 21:09:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */ +/* NetHack 5.0 mswproc.c $NHDT-Date: 1781973107 2026/06/20 16:31:47 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.208 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */ @@ -881,8 +881,10 @@ mswin_display_nhwindow(winid wid, boolean block) if (!block) { UpdateWindow(GetNHApp()->windowlist[wid].win); } else { - if (GetNHApp()->windowlist[wid].type == NHW_MAP) { - (void) mswin_nhgetch(); + if ((GetNHApp()->windowlist[wid].type == NHW_MAP) + || (GetNHApp()->windowlist[wid].type == NHW_MESSAGE)) { + if (!program_state.savefile_completed) + (void) mswin_nhgetch(); } } } @@ -2070,6 +2072,11 @@ mswin_preference_update(const char *pref) return; } + if (stricmp(pref, "hilite_pile") == 0) { + InvalidateRect(mswin_hwnd_from_winid(WIN_MAP), NULL, TRUE); + return; + } + if (stricmp(pref, "align_message") == 0 || stricmp(pref, "align_status") == 0) { mswin_layout_main_window(NULL); @@ -2365,7 +2372,7 @@ logDebug(const char *fmt, ...) /* Reading and writing settings from the registry. */ #define CATEGORYKEY "Software" #define COMPANYKEY "NetHack" -#define PRODUCTKEY "NetHack 3.7.0" +#define PRODUCTKEY "NetHack 5.0.0" #define SETTINGSKEY "Settings" #define MAINSHOWSTATEKEY "MainShowState" #define MAINMINXKEY "MainMinX" diff --git a/win/win32/nethack.rc b/win/win32/nethack.rc index 6f14e3328..4c167d047 100644 --- a/win/win32/nethack.rc +++ b/win/win32/nethack.rc @@ -60,8 +60,8 @@ IDI_ICON1 ICON "nethack.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,7,0,0 - PRODUCTVERSION 3,7,0,0 + FILEVERSION 5,0,0,0 + PRODUCTVERSION 5,0,0,0 FILEFLAGSMASK 0x1fL #ifdef _DEBUG FILEFLAGS 0x9L @@ -77,12 +77,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "NetHack for Windows - TTY Interface" - VALUE "FileVersion", "3.7.0" + VALUE "FileVersion", "5.0.0" VALUE "InternalName", "NetHack" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2021. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." + VALUE "LegalCopyright", "Copyright (C) 1985 - 2026. By Stichting Mathematisch Centrum and M. Stephenson. See license for details." VALUE "OriginalFilename", "NetHack.exe" VALUE "ProductName", "NetHack" - VALUE "ProductVersion", "3.7.0" + VALUE "ProductVersion", "5.0.0" END END BLOCK "VarFileInfo" diff --git a/win/win32/winMS.h b/win/win32/winMS.h index 1de3db042..080cdb10a 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 winMS.h $NHDT-Date: 1596498367 2020/08/03 23:46:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ */ +/* NetHack 5.0 winMS.h $NHDT-Date: 1781973108 2026/06/20 16:31:48 $ $NHDT-Branch: NetHack-5.0 $:$NHDT-Revision: 1.71 $ */ /* Copyright (C) 2001 by Alex Kompel */ /* NetHack may be freely redistributed. See license for details. */